Hub r4 architecture (milestone 1)
This is the shared brief for everyone building the redesigned Hub. The design authority is the generic model in contracts/model.json (73 elements, 71 vocabulary axes, version 10 — the counts live in the model and its generated files, read them with node tools/show-element.ts --list and --vocab). Read an element with node tools/show-element.ts B01 A03 (prints definition, fields and rules). When this brief and the model disagree, the model wins; report the disagreement in your package README.
1. What milestone 1 delivers
A person in Circle (a terminal coding agent, unmodified apart from generic MCP-client improvements) connects the Hub as an ordinary MCP server and has a model review a real test mind map:
- The model lists task packs, starts a run on an agile-platform mind map (an external object id, read-only), reads the expected sources (command catalog of one build, manual sections, linked story and bug text), judges each case, and submits.
- The Hub never generates content. It parses, resolves exact values to references, re-runs the pack’s checks in a sandbox, computes the terminal state of every (item, requirement, layer), partitions the items, and returns a receipt. Unknown stays unknown.
- A console (read-only HTML) shows runs, the knowledge tree, task packs and admin data. Every call is logged. (Owner decision 122, 2026-10-31: administrators also manage the Hub from the console; see
hub/server/README.md.) - The Hub runs persistently on one Mac, listening on loopback only, with backups.
Out of scope for milestone 1 (kept in the contracts, not implemented; the later capabilities are in section 6a): effects, dispositions and requests, dynamic layer checks, triggers, hypothesis sets, writing candidates, browser/device executors, xlsx and zip parsing. Two items of the original list came in by the owner’s later decisions (progress page): the knowledge sync as the one standing obligation (decision 9) and booking leases held by lineage in the device management pack (decision 16). Under decision 35, the repetition policy (V07), the rulings ledger (W04) and the criterion change declaration (W10) are implementation tasks. Static checks need no repetition. Implement W04 rather than assuming fixed decision shapes for every pack: shapes outside the ledger are marked “判定形状未裁定”.
2. Hard rules
- Use scripted models and synthetic fixtures in every test and in Git. Real systems are reached only by the scripts under
scripts/real/and by the deployed Hub, never by tests. Fixtures mirror the structure of the real systems (section 8), never their content. Addresses in fixtures use 192.0.2.0/24. - Never commit credentials, internal host names or addresses, real business data, or local absolute paths. Never open the owner’s environment file yourself: only the scripts under
scripts/real/read it, at run time, and print key names, presence and lengths, never values; secrets enter the Hub only as named secrets, throughcircle-hub secret set(standard input) orsecret import; each version is sent only to the consumers registered when it was entered. - Product knowledge lives in packs, never in the core. The core code must not contain a product name, a command name or a customer name. FAMX and FAMY are one product with two names (section 8).
- No coined terms. Labels come from
labelOf(axis, code)incontracts/generated/vocabulary.ts; enumerations are never written by hand anywhere; use the generated types and zod enums. User-facing text is Chinese (labels, error messages, fixes); tool and schema descriptions for models are English; code comments are English and short. - Code is TypeScript run directly by Node 24 (type stripping): erasable syntax only (no
enum, no parameter properties, no namespaces), imports end in.ts, ESM. Dependencies are exactly those inpackage.json; do not add any. If you need one, write the request in your package README and work around it. - Read-only toward business systems: only GET and the explicitly allow-listed read POST routes; never a login retry after a failure; no write routes.
- Append-only history: records are never updated or deleted; derived state is recomputed from records. Applied database migrations never change; add a new migration instead.
- Work in your task’s own worktree and branch, which the integrator opens from
hub-redesigntogether with a task page underdocs/hub-r4-tasks/listing the paths you may change (decision 14 ofdocs/hub-r4-progress.md; this replaced the shared worktree of phases 1 to 3). Commit there withgit commit -sand explicit paths, merge other branches withgit merge --signoff, never commit tohub-redesignand never push: the integrator reviews and merges. Do not touch files outside the paths of your task page. Do not runnpm install: the integrator preparesnode_modules. - Tests:
node --testwith files next to the code (*.test.ts); a temporary PostgreSQL throughhub/testing/postgres.ts(provided by the records package) for anything that needs a database. Never weaken or delete a failing test; fix the code or explain why the test is wrong. Say exactly which commands you ran.
3. Shape of the system
Circle (MCP client) ──streamable HTTP, Bearer token──▶ hub/server
│ six tools, console, CLI
┌───────────────┬─────────────┬───────────────────┼──────────────┐
hub/runs hub/knowledge hub/connectors hub/records hub/platform
packs, runs, tree, roots, resources, route records, objects, key files, launchd,
validation, producers, allow-list, login, vault, users, pg lifecycle,
partitions placement read plugins tokens, call log backup/restore
│ │ │ ▲
└──── hub/rules (interpreters, sandbox) ─── hub/refs (references, parsers)
contracts/ (model, vocabulary, zod shapes)
Dependency rule (arrows point to what may be imported): server → runs, knowledge, connectors, records, platform, refs, rules, health; health → records(types); runs → knowledge(api), rules, refs, records; knowledge → rules(sandbox), refs, records; connectors → rules(sandbox), refs, records; rules → refs(types); refs → contracts; records → contracts; everything → contracts. No cycles. Cross-package calls go through the package’s api.ts only, never through its internals. One exception: hub/telemetry/usage.ts depends on Node and on types only, and records, refs and rules import it directly; what is above records goes through hub/telemetry/api.ts, which depends on records.
Data that exists
- Records (append-only table
records: id, kind, schema, digest, provenance, created_at, body, plus a small index table for lookups) and objects (content-addressed bytes on disk). Record kinds:claim, source_artifact, authorization, action, effect, request, call_log, run, submission, validation_result, pack_version, tree_node, tree_root, root_pointer. Milestone 1 writes all of these except effect and request. - Mutable state is limited to: users, tokens (hashed), the current-root pointers (compare-and-swap), and vault entries (one per secret version, plus the resources’ login sessions and stops). Everything else is derived from records.
- Digest of a record = SHA-256 of the RFC 8785 canonical JSON of
{kind, schema, provenance, created_at, body}.
The six tools (contracts/src/tools.ts)
list_task_packs, upload_file, start_run, get_nodes, resolve_reference, submit_result. Annotations are derived by annotationsFor. isError is true only for protocol errors and for a submission, upload or effect write that is not accepted. Unknown is never an error. A caller who may not read something, or asks for something that does not exist, gets the same neutral SOURCE_UNAVAILABLE (“对你不可用”) and the same empty shape.
4. Work packages and ownership
Each package owns exactly the paths listed. It publishes api.ts (types and the functions other packages may call) and README.md (decisions, limits, how to test). The model elements to implement are listed with each package.
| Package | Owns | Model elements | Depends on |
|---|---|---|---|
| contracts | contracts/**, tools/gen-contracts*, tools/show-element.ts |
all (vocabulary, shapes) | none |
| records | hub/records/**, hub/testing/**, hub/config/** |
B01 B02 B04 B05 B08, R01, R02 (visibility) | contracts |
| refs | hub/refs/** |
B03, T04 (parsers, quote check) | contracts |
| rules | hub/rules/**, contracts/src/tables.ts |
C03 C04 C05 C06 C07 C08, T03 (checks), sandbox | contracts, refs |
| platform | hub/platform/**, scripts/** (not scripts/real/), bin/** |
deployment, D01 R[6] | contracts |
| knowledge | hub/knowledge/**, contracts/src/knowledge.ts |
K01 K02 K03 K04 K05 | records, refs, rules |
| runs | hub/runs/**, contracts/src/pack.ts |
W01 W02 W03 W05 W06 W07 W08, V01 V03 V04 V05 V06 V07, T01 T02 T03, A01 A02 A03 | records, refs, rules, knowledge(api) |
| connectors | hub/connectors/**, contracts/src/resources.ts |
D01 D02 D03 (read part) D07 (resources only) | records, refs, rules |
| health | hub/health/** |
B08 (resources and process events, decision 146) | contracts, records(api) |
| server | hub/server/** |
D05 D06 B08 R01 R02 R03 (bot out of scope) | all |
| telemetry | hub/telemetry/** |
B08 (traces, usage, retention) | contracts, records (usage.ts depends on neither) |
| packs | packs/**, tests/fixtures/** |
T01 T02 | contracts, runs(api) |
| acceptance | tests/acceptance/** |
all scenarios in section 9 | all |
| docs | docs/** (except this file), root *.md, .github/** |
n/a | none |
If you need something from a package you do not own, do not edit it: use its api.ts; if it is missing, write a precise request in your README under “Needs from other packages” and use a local fake in your tests.
5. Conventions
- Ids:
idOf(prefix)incontracts/src/common.ts(run_,usr_,tok_,rcd_+ 26-char lowercase base-32 ULID). Time is ISO 8601 UTC withZ. Hashes are lowercase hex SHA-256. - Canonical JSON: RFC 8785 (
canonicalizeinhub/records), used for every digest. - Errors: protocol codes from
PROTOCOL_CODES, core violation codes fromCORE_VIOLATION_CODES, pack codes under the pack name (case-review.<code>). Code that can fail for a caller throws a typed error carrying a registered code; the server maps it to theerrorsarray. Never invent a code outside the registry; add it tocontracts/model.jsonorcontracts/codes.jsonby asking the contracts owner (README request). - Visibility: a user sees their own runs and uploads; admins see all runs; packs, knowledge trees and their entries are visible to users with the pack assigned; system packs are never assigned to users. Absent and forbidden look the same.
- Logging: one JSON line per MCP call (
call_logrecord and$DATA/logs/calls-YYYY-MM-DD.jsonl), W3C trace id, client session id from theCircle-Session-Idheader, argument digest and size only (never case text), no secrets. - Configuration: environment variables are
CIRCLE_HUB_*only (data dir, port, database socket). A process that sees any retiredCIRCLE_SERVER_*variable, or the retiredCIRCLE_HUB_KEYCHAIN_SERVICEorCIRCLE_HUB_KEYCHAIN_ACCOUNT, refuses to start (reuse the earlier guard). - Keys: the vault master key and the operator token are private files under
<data root>/keyson every platform (directory 0700, files 0600, never backed up); the Hub no longer uses the macOS keychain (decision 137, 2026-11-03). Deployment values are admin-written named variables and secrets (circle-hub var,circle-hub secret), referenced as whole-value${var:NAME}/${secret:NAME}in resource settings and credentials, in an executor definition’s expected values and credential, and in product packs’ sync options and producer parameters. A variable is deployment data, not a secret. Neither is ever a process environment variable:CIRCLE_HUB_*stays process configuration only, and the Hub never resolves references in client input. - Pack functions are pure TypeScript modules (
export default function (input: unknown): unknown) run in a sandboxed child process (Node permission model: no file writes, no child processes, read access only to the extracted pack), with a time and memory limit and size-capped JSON in and out. Verified on this machine (Node 24.17): the permission model does NOT restrict network access, so the child process additionally runs under macOSsandbox-execwith(deny network*); a test must connect to a really listening loopback server to prove the denial (a connection to a closed port fails anyway and proves nothing). The same function code is the only implementation of a parser, projection, producer or renderer. - Reuse of the earlier implementation: read it with
git show ca66002:<path>; copy and adapt, do not import. Useful:packages/storage/src/index.ts(forward-only migrator),packages/knowledge/src/objects.ts(content-addressed objects),packages/assets/src/vault.ts(AES-256-GCM vault),packages/tasks/src/auth.ts(hashed tokens),packages/contracts/src/hub-environment.ts(retired-name guard),packages/contracts/src/index.ts(canonical JSON),tests/acceptance/harness.tsandscripts/postgres-process.ts(temporary PostgreSQL),packages/connectors/src/{readonly-sdk,query-mirror,build-site,documents,structure,source-cache,private-http}.ts,packages/methods/src/command-tree.ts,packages/knowledge/src/zip.ts,packages/mcp/src/index.ts,packs/famx/methods/mindmap.ts.
6. The case-review scenario (what the packs and the engine must make work)
Pack kinds: a product pack (names, version lines, build families, catalog producers), a workflow pack (case-review: requirement templates, checks, slots, procedure), system packs (agile platform, PLM, build site, manual store: resource declarations, route lists, request templates, projections). The administrator instantiates system packs as resources in the deployment database; users are assigned workflow packs.
Input: a KityMinder mind map. External id agile:mindmap:<documentId> (read by the agile system pack) or an uploaded export (application/json).
Items: the pack’s projection function turns the parsed mind map into items. A case is a node with a non-empty resource tag array or the team template’s case marks (progress decision 18; a parameter keeps the tag-only rule); its children are the expected results; a tag negative (any case) marks a negative case. Item id = <documentId>:<data.id> when the node carries a data.id that is unique in the document; otherwise the packs number by position (#n, @index), a recorded deviation from the planned fallback of ancestor texts plus a subtree digest (progress, 2026-10-23). Item fields: ancestor path (texts), title, priority, tags, expected texts, optional autoid, negative. Group nodes (priority, no resource) are not items. A document with no case node is a projection failure: the whole start_run is refused with a fix.
Method (ported from the earlier skill, not invented). The earlier test-list-review skill and its independent review-verifier define how the team reviews test cases; the Hub reproduces that method with machine-checked evidence. Do not add review dimensions, finding names or levels that are not in the list below; any change goes through the owner.
- Target gate: the reviewed target is pinned by an explicit input (a document id, or a defect or requirement id); a missing target is asked for, never guessed.
- Evidence in six groups, bound to the run as sources: (a) the defect or requirement (what development changed: parameters, behaviours, affected versions, the command), read from the defect system by the ids found in the target’s title or given by the caller; (b) product design documents (feature position, coupling, design boundaries); (c) the CLI manual of the version (parameter table, legal values, defaults, dependencies, examples) and the build’s command catalog; (d) test strategy documents (dimensions and methods used for similar features); (e) historical test lists of similar features (coverage, design approach, module partition); (f) the target itself, read in full, plus verified test facts about the command (footprint; not available in milestone 1, so it is disclosed as an evidence gap). Source roles (A03): (a)-(c) are
expected, (d) and (e) arehint(they may shape what coverage to expect but never ground a claim about product behaviour: product semantics come only from product documents, manuals and catalogs, never from test lists), (f) issubject. Evidence gaps are listed explicitly (unknown, never silently skipped). - Draft: findings, each with a location in the target, a description, evidence (verbatim quotations with references) and a severity band; plus a draft level. Severity bands: critical (levels P6-P7), major (P3-P5), minor (P0-P2).
- Levels P0-P7 (a ranking, stated once for the whole target): P0 covers all functional details with very rich compatibility, negative, stress and corner cases and extreme scenarios; P1 all functional details with rich compatibility, negative, stress; P2 all functional details with fairly rich compatibility, negative, stress; P3 all functional details with some compatibility, negative, stress; P4 all functional details with some negative and stress but insufficient compatibility; P5 all functions with some negative and stress but lacking depth in functional details; P6 basic functions with negative and stress types but incomplete functional-detail coverage; P7 fails to cover the basic functions and has no negative or stress types.
- Independent verification by a different session and model (the drafter can never sign the conclusion): it re-reads the target in full, checks every draft finding (does the location exist, does the description match the content, is the severity reasonable: verified, refuted or partially correct, each with a location and quotation), looks for what the draft missed with these probes only - literal issues (duplicate lines, empty fields, typos, inconsistent field formats), coverage gaps (a feature or parameter introduced by the defect is untested), differentiation gaps (two features tested only positively and never against each other), edge cases (empty values, very long strings, unicode, upper and lower case), negative tests (an error path the defect fixed is not covered), block structure (section titles versus described behaviour), business self-contradictions - challenges the draft level, and issues the verdict PASS (draft essentially correct, nothing major added), PARTIAL (essentially correct but issues were missed or the level is too loose or too tight) or FAIL (major factual errors: misjudgments, wrong locations, inverted product semantics) and the final level. Any unfamiliar command is checked against the product documents; a PASS needs at least one independent check against the target.
- Report: composed by the drafting side in Chinese from the verifier’s material: every verified and new finding, the improvement suggestions (which cases to add, why, expected result) and the verifier’s verdict and level adopted as they are. The Hub stores the runs, claims and results; the console shows them.
- Large targets are split into independent blocks (the earlier skill splits at about 500 lines per sheet and verifies blocks concurrently); the overall verdict is the worst case of the blocks (FAIL over PARTIAL over PASS).
How the Hub carries it: items are the target’s cases; finding locations are references into the target (src: with the KityMinder selector) and into sources (tree:, src:); the Hub verifies that every location exists and every quotation is verbatim, that the commands resolve against the build’s catalog, and the literal issues mechanically (a fact requirement). The findings, the level and the verification are judgments with a declared producer. The verification is a second run in the same lineage (predecessor) whose input is the draft’s validation result handed over by a Hub record reference (rec:; the receiver inherits the selected items and references, not the judgments, and re-checks on its own boundary); its slots hold, per draft finding, verified, refuted or partially correct with evidence, new findings, the level challenge, improvement suggestions, the verdict and the level. The Hub enforces what the earlier chain enforced with its review gate: the verification requirement is only satisfied by a session and a declared model different from the draft’s (independence judge_not_author, A04); the verdict must be consistent with the dispositions (PASS is refused when the verification lists a refuted finding or a new finding); a PASS needs at least one evidence reference of its own that resolves in the target; every claim carries a location and quotation. A fundamental principle of review is that review only raises findings; revisions are made by the author locally in their own Circle workspace, and the Hub never modifies the material under review (评审只提出问题,修改由作者在本地完成,Hub 不修改被评审材料). Therefore, repair routing applies only to checks judging the artifact under verification; refutations of the reviewed subject remain violations attributed to the author’s input and consume no repair rounds.
Requirement templates (static layer only; the dynamic layer is “not applicable”): in the draft pack literal (fact, core structure@1: the literal issues above), catalog (fact, core catalog@1 against the locked build’s catalog: every command a finding cites is resolved and its parameters checked, and an assertion that a command exists or does not exist is verified against the catalog; scanning the target’s own free text for command phrases exists only as an optional advisory check, OFF by default, because measured on real documents it is noisy: shorthand such as on/off, list numbering, context prefixes and typos made 15-70% of the cases that contain commands look wrong; an expected-negative case expects refutation), findings (independent judgment, finding codes are exactly the probe names: literal_issue, coverage_gap, differentiation_gap, edge_case_gap, negative_gap, block_structure_mismatch, self_contradiction; ranks critical, major, minor) and level (judgment over the whole target, ranking P0-P7); in the verification pack verification (independent judgment, slots as above) and final (the verdict PASS, PARTIAL, FAIL and the level, ranking P0-P7, as a cross-item claim). Verdict and level values are ranking labels declared by the packs; the platform-wide verdict vocabulary is unchanged.
Knowledge sync (owner requirement, 10-21): the knowledge base must be built from BOTH name families and EVERY version, not from one build. A standing obligation executed by the Hub (knowledge sync) walks the build-site listing pages of the whole product (the mainline pages of the FAMX and FAMY families; platform and customer branch pages are opt-in), reads the command tree of every released build on the main platform that is not yet in the knowledge base, reads the manuals and specs the product pack maps to each version line, produces one root per build, and moves each version’s current-root pointer. It is idempotent (unchanged source digests are skipped), resumable and reports produced, skipped and failed per build. FAMX-named and FAMY-named documents of the same version line belong to the same line.
6a. Capabilities beyond the first review (owner’s list, 10-22)
The same three foundations (cases as items, the version knowledge tree, the validation engine) carry seven capabilities; each later one is a pack, not core code. Order of work: milestone 1 delivers 1; the next milestone 2-4 and 6; then 5; then 7 (needs devices, last).
- Review (milestone 1): section 6.
- Template gap check: a coverage fact per document against the team’s case template (per CLI command: add/delete/modify/query,
showat maximum configuration,no/clear, operation log, audit log, configuration sync, save/restore/clear configuration, upgrade compatibility, security, database; types Configuration, Integration, Compatibility, Functional, Negative, Stress). A requirement of the draft pack (coverage@1 over a table authored from the template). - Case location: case or document id -> product line, version line, release train, module, build candidates (both name families, aliases resolved) and the linked requirements and defects. A fact-only workflow pack.
- Regression scope and maintenance sweep: the knowledge tree gets entries of kind case (K02: the kinds are declared by the producer: definition, behaviour, case, defect, observation) filed under the commands they exercise, produced from the mind-map documents by the product pack (commands resolved by code; the rest stay unplaced at the root — the Hub calls no model; proposals stay on the client per the owner’s decision of 2026-10-23, and the Hub’s placement checks are verified through contribution runs). Regression scope = the diff of two builds’ trees intersected with the case entries; maintenance sweep = for a new build, the cases whose commands were removed or whose signatures or ranges changed, with the evidence. Fact-only workflow packs.
- Defect to case: a draft workflow: from a defect (symptom, fix description) the model drafts regression cases in the team’s format; the Hub checks that commands and parameters exist and are in range for the target build, that every expected result is grounded verbatim in the fix description or the manual, that the shape matches the case structure, and that it is not a duplicate of an indexed case.
- Traceability and quality: defect or requirement <-> case documents (ids in titles, PLM status), cases without expected results, vague expected results, negative-case share, template coverage by version and module; read-only console pages computed from records.
- Automation (last, needs the device test bed): compile reviewed cases into the execution workbook and run them through the lab gateway; the dynamic layer. The compile half runs on a synthetic contract and a synthetic bed since 2026-10-23 (
docs/hub-r4-compile-design.md); the owner has since confirmed the bed, the account and the allowed command classes for the real-bed round (decision 35, recorded on the progress page; the bed’s addresses and accounts exist only as deployment data, and real devices are shared lab hardware).
Production runs. A pack whose requirements are all fact producers (location, regression scope, maintenance sweep, traceability) needs no model input: start_run computes and stores its validation result immediately (execution host hub for scheduled sweeps), the result comes back in the run summary and stays readable by reference; submit_result is optional and only adds model commentary as judgments.
6b. Correct results (acceptance of each capability)
“It runs” is not the acceptance; each capability is accepted when it gives the expected answer on inputs whose answer is known independently of the Hub. Two kinds of gold, both written down before the check runs: synthetic gold in tests (invented fixtures with injected defects or known answers, part of CI) and real gold in the integrator’s scripts under scripts/real/ (real documents and builds, never in CI, results and transcripts kept outside Git).
- Review: inject known defects into real documents (a duplicated case, an empty or contradictory expected result, a command that does not exist in the build, a case moved under the wrong module, a removed negative group). The Hub’s own mechanical requirements (structure, catalog, quotation and location checks) must flag 100% of the injected defects they are able to see and nothing in the untouched document; the model’s findings are scored for recall on the injected defects and for precision on the rest, and a finding with a missing location or a non-verbatim quotation must never be accepted. An untouched document is also run, and its findings are listed for the owner to judge.
- Template gap check: metamorphic cases: removing every case of a category must make that category missing, adding one case of it must make it present, and the report of a document is independent of the order of its cases.
- Case location: exhaustive over the sampled agile tree: every document’s line, release train and module equals the path convention; spot checks of the build candidates (both name families) and of the linked ids against the defect system, by hand.
- Regression scope and maintenance sweep: the Hub’s diff of two builds equals a command-level diff computed by a separate script on the raw command trees; the cases the scope names are exactly those whose indexed commands are in the diff.
- Defect to case: the drafted cases of defects that already have a regression document are compared with that document (commands and parameters), and every expected result of a draft must be a verbatim quotation of the fix description or the manual.
- Traceability: the matrix equals an independent join of closed defects and the case documents’ ids.
- Every capability is finally exercised through the real Circle client in Otty against the deployed Hub, with the transcript kept as evidence.
7. Phases of the build
- contracts completion, records, refs, rules, platform, docs (parallel)
- knowledge, runs, connectors (parallel; code against the real phase 1 packages)
- server, packs (parallel)
- acceptance and integration; independent review of the whole against the model
- persistent deployment and the real-system scripts (done by the integrator)
Each phase ends with independent review (against the model and this brief) and a fix round before the next phase starts.
8. Real systems (structure only; verified by read-only sampling on 2026-10-21)
FAMX and FAMY are one product with two names. Product line famx has names [FAMX, FAMY]. Versions and builds exist under both names. Everything below must treat the two as one line.
- Agile test platform (roles
agile-oauth,agile-api). LoginPOST /oauth/login/with{username, password}where password is Base64(SHA-512(plaintext)); envelope{code, msg, data}, code 1000 is success, HTTP status is always 200; a wrong password answers code 1005 and repeated failures may lock the account, so a failed login is never retried.data.token(about 30 days,data.expireis epoch seconds) goes in theAuthorizationheader without a prefix.POST /agile/get_root_node/ {page}returns 10 roots per page andtotal; pages past the end repeat page 1.POST /agile/get_child_node_task/ {id}returns the whole subtree of a root[{label, id, cases:[ids], children}]; a leaf id is a mind-map document id.POST /agile/get_case_data/ {id}returns{code, msg, data:"<JSON string>"}, double-encoded KityMinder:{root:{data:{id, created, text, priority?, degree?, resource?[], autoid?, auto?, note?}, children}, template, theme, version}. Two roots belong to the product: the one titled with the first name of the product (a dozen nodes, no versions) and the one titled with the second name (thousands of nodes; the real versioned maps). Tree convention under the second root: a project folder → version lineNNN:<line>→ release trainNNN: <line>-R2-<year>/<month>→ module → document; document titles carry ZenTao ids (bug to case 900123 ...,900456-...; synthetic examples of the real forms). Root ids and hosts are deployment data, never committed. - PLM query service (role
plm-api; the same login token works). Envelope{code, msg, data}, code 1000 ok, HTTP always 200, headerAuthorization: <token>. Reads includeGET /plmquery/product/all/,GET /plmquery/build/?product=(a plain array, not paginated),POST /plmquery/bug/detail/ {bug_ids},POST /plmquery/story/detail/ {story_ids}. The product record of the line (its name lists both families) has about 1,100 builds named in both families (shapes likeRel_FAMY_10_6_2_17,Rel_FAMX-<platform>_10_6_2_8_4_129,Beta_FAMX_10_7_1_101; the numbers here are synthetic). Ids are numbers in some answers and strings in others, dates have three spellings, steps and specs are HTML. A write route (/plmquery/testtask/edit/) shares the prefix with the reads and reads also use POST: the transport must allow-list routes one by one (method and path template), never by prefix or method. - Build site (role
build-site, anonymous, plain HTTP, ISO-8859-1). An index page links listing pages for both families (rel_famx_*,rel_famy_*, others). A listing page has entries likeRel_FAMX_10_6_0_179 (build on 2026-06-26 12:06:23 ): Released on 2026-06-27(synthetic numbers) (released ones in a red font element) followed by links with unquoted attributes: the image (with size and SHA-256 in the text), the MIB text,command_tree-<build>.xml,Bugs_Fixed_with_<build>.html. The command tree is about 1.4 MB XML:commands > scope > menu[name] > item[name] > arguments > arg[name, type, length, limit, optional, default_value], with stray attributes in some help strings; the full command is the menu path plus the item name; one path can have several argument lists (overloads). -
Manual store (role
manual-store, WebDAV, anonymous read, plain HTTP).PROPFINDdepth 1; the collection URL needs a trailing slash./spec/(about 1,000 Markdown files converted from Word),/product/,/qa/,/cli/rel_famx_<line>/cli_cn/cli_cn.md(about 2.7 MB, contains NUL bytes that PostgreSQL text rejects: strip them from stored text, keep the original bytes as the object),/app/rel_famx_<line>/app_cn/app_cn.md. - FAMY builds are aliases of FAMX builds. FAMY listing entries have no command tree of their own; each reads like
Rel_FAMY_10_6_2_196 (build on 2026-01-12 12:53:31 ): based on Rel_FAMX_10_6_2_196 Released on 2026-01-19(synthetic numbers) (the “based on” text sits between the build time and “Released on”; unreleased builds have no “Released on”). In the mainline FAMY pages all but one of 235 entries resolve to an FAMX build that has a tree, and the numbers differ in about half of them (for example an FAMY build numbered 37 is based on an FAMX build numbered 110). The knowledge root of a build is keyed by the product line and the BASE FAMX build; every FAMY-named build is stored as an alias of its base build (alias name, base name, FAMY release date, platform), so a run started with an FAMY build name locks the same root as the FAMX build it is based on. Platform and customer pages follow the same pattern with platform-specific base names. - Two regimes for FAMY builds. For the two newest lines (the mainline pages
rel_famx_<line>andrel_famy_<line>) the FAMY entries have their OWN command tree and no “based on” text; verified on one same-numbered FAMX/FAMY pair of each of these lines: the same 3841 and 3838 commands with identical signatures (the files differ by one byte), so their content-addressed roots coincide. For the older lines the FAMY entries have no tree and say “based on”. The product pack must handle both: use an FAMY-named build’s own tree when it has one, otherwise the tree of its base FAMX build. - Hub pages. The index page links some listing pages directly (older lines) and, for the newest lines, hub pages named after the line,
famx_<line>.html(about 1 KB each), that link the listing pages of the line:rel_famy_<line>,rel_famx_<line>, brand variants, platform variants and special-customer pages. Some hub links point to pages that do not exist (404). Walking the site is index -> hub pages -> listing pages (depth 2), tolerant of dead links. - Scale of the build site (counted on the index page): 57
rel_famx_*and 31rel_famy_*listing pages: the mainline lines of both families plus many platform and customer branches, POC and patch pages. One mainline page lists hundreds of builds, a few tens of them released. - OpenKM (role
openkm, WebDAV with Basic authentication, its WebDAV root is deployment data; the document library the manual mirror is produced from): a system pack for it is read-only like the others; credentials come from the vault; access with the configured account answered 401 when first tried, so until the owner supplies a working account milestone 1 reads the anonymous mirror. The mirror’s CLI and application manuals exist only for three version lines (rel_famx_<line>folders); itsspec/has about 1,070 files with FAMX in 354 names and FAMY in 47.
9. Acceptance scenarios (synthetic, in tests/acceptance)
Scenarios 1–16 below were the initial set written with this brief; later scenarios were added as the build grew and live only in tests/acceptance/ (numbered files, with the added ones recorded on the progress page).
- A normal review: all items delivered; per-requirement terminal states and satisfaction counts correct; the dynamic layer shows “not applicable”.
- A quotation that does not match: the whole submission is not accepted, stored verbatim, the receipt carries the fix and the rounds left; a corrected resubmission is accepted and the first cause stays visible.
- A statement that a command does not exist while the catalog has it: that finding is a violation routed through the error table into repair, not a whole-submission rejection.
- A negative case with an out-of-range parameter: the catalog check refutes as expected, shown at advisory tier.
- A cross-item fact plus a judgment that rests on it: listed separately, not counted in partitions.
- A user to whom a team pack is not assigned gets “X 存在,你没有读取权限” with who can assign it and no pack content; another member’s personal pack, like a credential or login failure, gets “对你不可用” and the same empty shape; the real reason is only in the admin log (D05 R[3], model 37; the code follows in consolidation step 4).
- Call log: one line per call with trace id and session id; argument digest and size only.
- A second, non-FAMX synthetic product pack reviews with the same workflow pack and the core code does not change.
- Connectors: a route outside the allow-list is refused; an expired token logs in once and a second failure stops; originals are stored by SHA-256.
- Changing one case re-judges one case (items unchanged by content digest are reused).
- No judgment in the Hub: the production assembly has no placer; entries the code cannot place stay at the root marked unplaced with no judgment and no candidate, the production records placement.spans 0, and no outbound call reaches the judgment service.
- Console and API: a wrong Host or Origin is refused; a request without a token is refused.
- Idempotence: repeating
submit_resultfor the same (run, submission digest) returns the stored result without re-running anything; repeatingstart_runwith the same client key inside its window returns the same run; an expired key starts a new run. - Independent verification: a second run with
predecessor= the draft run and the draft’s result handed over by arec:reference; its submission from the SAME session or the same declared model is not accepted as independent (the requirement stays unsatisfied: independence unknown); from a different session and model it is accepted. - Verdict consistency: a PASS that lists a refuted draft finding or a new finding is refused with a fix; a PASS without an evidence reference of its own that resolves in the target is refused; FAIL, PARTIAL and PASS with consistent dispositions are accepted; the overall verdict of a target split into blocks is the worst case of the blocks.
- Evidence discipline: a finding whose location does not exist in the target or whose quotation is not verbatim in the cited source is not accepted (whole submission, QUOTE_MISMATCH or REFERENCE_UNRESOLVED); a claim about product behaviour grounded only in a
hintsource (a historical test list) is flagged and does not satisfy the requirement.
10. Definition of done for any package
api.tsandREADME.mdexist; the README lists decisions, limits, how to run the tests and “Needs from other packages”.npx tsc --noEmitreports no error in your files (errors in other packages mid-edit are not yours).- Your tests pass: say the exact command. Positive and negative cases for every rule you implement; adversarial inputs for parsers and the sandbox.
- No hand-written enumeration of a vocabulary axis; no product name in core code; no secrets, hosts or absolute paths in files.
- A final report: what you built, commands run with results, deviations from this brief with the reason, open questions.