amanuensis

Subsystem · B-03

Knowledge tools and workflow API

Scope, structure, boundaries, defects, and the survey record for Knowledge tools and workflow API.

Branch  main Checked  ec5824bceb9c As of  2026-10-07 22:54:09 Stale: 0 with a survey obligation, 65 exempt, of 655 scoped files Survey depth  Adversarial

Status: Adversarial Layer: Runtime

§Scope

No purpose statement is recorded for this subsystem; the scope below states what it covers.

mcp-server/src/tools/** — the tool surface a survey writes and reads through

§Start here

src/tools/evidence.ts; src/tools/dispositions.ts; src/tools/git.ts; src/tools/carried.ts

§Structure

What the survey recorded as claims about this subsystem, grouped by what each one states. Every claim is bound to the revision it was asserted at and to the evidence attached to it; a superseded claim is not shown here.

§State containers

structure
ClaimSubjectStatementEpistemic kindAsserted at
B-03/state-container/eight-unshared-git-probesmcp-server/src/tools/xrefs.ts:resolvesInWorkspaceRevision resolution is implemented eight times across this tool surface rather than once. xrefs.ts names itself the eighth copy and records that they are deliberately unshared because each owns a different failure policy. The consequence the comment does not name is that a property added to one — such as the wall-clock bound B02-R1 and B02-R2 ask for — has to be added to all eight, and nothing in the build compares them.Inferencec0734040022f

§Other claims

structure
ClaimSubjectStatementEpistemic kindAsserted at
B-03/atomicity/every-durable-write-is-one-transactionB-03Every tool in this surface that writes more than one row writes them inside one ctx.db.transaction, so the invariant the pair expresses cannot be observed half-true. set_disposition writes the disposition and its attachments together; detect_changes writes the staleness marks, the scope_gaps rewrite, the git_state update and the append-only reconciliation row together; carry_finding writes the carried record and its archived-terminal pre-record together; add_finding writes the finding and its opening resolution event together.Observationc0734040022f
B-03/trust/a-worker-report-is-never-the-verdictB-03Wherever this surface accepts a report from something it did not run, the report is landed and then scored by a separate call that re-reads durable state rather than believing the label. score_composition_item re-resolves the commit, re-reads the artifact registry's content hash, and requires a terminal review aggregation; score_integral_verification compares the reported checkout HEAD and tree against the manifest and requires zero dirty paths; record_carried_outcome requires a post-repair reading whose revision is a descendant of, or equal to, the claimed repair.Inferencec0734040022f
B-03/verification/an-unanswerable-check-refuses-separately-from-a-failed-onemcp-server/src/tools/findings.ts:requireAncestorverify_finding_fix's lineage check separates the two ways it can decline. requireAncestor branches on the exit status of git merge-base --is-ancestor: 0 returns, 1 refuses because the verification evidence genuinely predates or sits outside the repair lineage, and any other status refuses with a distinct message carrying git's own stderr. Because the second and third branches are never merged, a repository the server cannot read produces "cannot compare repair and evidence commits" rather than the lineage refusal — and neither produces a pass. The check has no path on which an unanswerable question is recorded as an answer.Observation20839da454b0

§Vocabulary

  • verification object — What a composition item was verified over — either one unit subject at its own target commit, or the whole assembled HEAD in a clean worktree — recorded on the item so a unit pass can never be read as an integral one.
  • wire budget — The 8192-byte ceiling a list tool's response must fit, measured on the doubled envelope — the indented text block plus the structuredContent that repeats it — not on the payload.

§Known defects here

5 defects here are open or awaiting verification. Each one's full record, with its evidence, is on Open findings.

  • A subsystem can report status 'mapped' with zero unledgered paths, zero absent files and zero stale entries while most of its scoped files have never been examined. Nothing in the server measures examination within the ledger, so the store's own census cannot distinguish a subsystem that was read from one that was inventoried. — B03-R1 · High · Open
  • A finding can be promoted to verified-fixed while its recorded fix_sha names a commit at which the repair does not exist, so the resolution record misattributes the repair to the wrong commit and nothing in the custody chain detects it. — B03-R2 · Medium · Open
  • When a file's content moves but every claim written against it still holds, the conspectus has no action that records the move. A citation whose line range has shifted keeps pointing at lines that now hold something else, and a range that lands on unrelated prose in the same document reads as correct — it makes the conspectus look wrong where it is right. — B03-R3 · Medium · Open
  • A finding's severity cannot be amended after it is filed, so an adversarial pass that re-grades one can record the re-grade in a resolution note, a disposition and the survey artifact while the findings.severity column keeps the original grade — leaving the published index and the store's own column disagreeing about the same finding. — B03-R4 · Medium · Open
  • An evidence row's locating coordinates are stored unchecked, so a disposition can be evidence-backed by a citation no reader can open. Measured in this store: 13 of the 35 evidence rows that carry a line_range name a range past the end of the file they cite, at the revision they cite it at — mcp-server/src/tools/findings.ts:verify_finding_fix at 1792-1798 of a 486-line file, mcp-server/src/tools/dashboard.ts:get_dashboard at 102-121 and again at 141-148 of an 85-line file, mcp-server/src/tools/stale.ts:clear_staleness at 1107-1120 of a 135-line file, mcp-server/src/tools/carried.ts:record_carried_outcome at 3512-3639 of a 735-line file, and nine more across mcp-server, materializer and the skill references. Every one of those rows is attached to a disposition and reads as evidence-backed. — B03-R5 · Medium · Open

§Standing

Adversarial — Candidate conclusions are being challenged; treat them as provisional. It cannot justify that the challenge pass has finished.

Files read
43 of 43 ledger rows
Files in scope, not yet read
0 of 43
Files excluded from the survey obligation
0 of 43
Ledger rows the repository has changed under
0 of 43
Active concerns with a disposition recorded here
12 of 12 — 1 confirmed-bug, 9 confirmed-acceptable, 2 out-of-scope
Findings by resolution state
5 open
Seams assessable from both sides
no seam names this subsystem

§Survey record

§File ledger

survey record
PathClassificationWhy in scopeExamined at
mcp-server/src/tools/artifacts.tsexaminedregister_artifact's lexical and realpath containment checks on the storage-relative path, and the content hash the materializer's diff reads.c0734040
mcp-server/src/tools/carried.tsexaminedThe carry's five writes and two reads, the archived-terminal pre-record, the three outcome authority rules, and the 8192-byte wire budget list_carried_findings measures on the doubled envelope.a521e28
mcp-server/src/tools/chorusmith-adapter.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/claims.tsexaminedClaim custody: the file-anchored evidence rule enforced in insertClaim for both doors, the challenge-outcome vocabulary and its 24-character floor, invalidation and supersession.c0734040
mcp-server/src/tools/codebase-brief.tsexaminedThe immutable brief source and its mode projections, with deterministic selection and zero model calls.c0734040
mcp-server/src/tools/compare.tsexaminedStructural diff of two stores opened read-only, with signature-based finding overlap and Kendall tau over shared priorities.c0734040
mcp-server/src/tools/composition.tsexaminedThe fan-in manifest: expected items scored independently of the worker's own success label, the integral lane gated on exact unit fan-in, and reconciliation that is red on any missing work.c0734040
mcp-server/src/tools/concerns.tsexaminedThe calibrated checklist's writers; retire_concern records a final state rather than deleting, so historical dispositions stay readable.c0734040
mcp-server/src/tools/contradictions.tsexaminedresolve_contradiction requires evidence from the active session attached to one of the two findings, and appends the resolution event in the same transaction.c0734040
mcp-server/src/tools/crosswalk.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/dashboard.tsexaminedget_dashboard's single-round-trip census, and staleness_measured carrying the denominator so an empty ledger cannot read as a fresh conspectus.c0734040
mcp-server/src/tools/decisions.tsexaminedDecision custody: immutable revisions, explicit human or owning-system acceptance authority, and the projection read-back on three axes.c0734040
mcp-server/src/tools/design-session.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/diagnosticity.tsexaminedThe ACH matrix: concerns and evidence enrolled first, one verdict per cell, and resolved requiring a leading concern that is in the matrix.c0734040
mcp-server/src/tools/dispatch.tsexaminedThe sub-agent dispatch log.c0734040
mcp-server/src/tools/dispositions.tsexaminedset_disposition's ordered refusals: depth, concern existence, revision resolution, evidence_ids, batched reachability, the quality ceiling, then one transaction for the row and its attachments.c0734040
mcp-server/src/tools/evaluation.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/evidence.tsexaminedadd_evidence resolves ref_sha at ingress and stores it resolved; the two attach tools carry the role vocabularies the resolution rules read.c0734040
mcp-server/src/tools/field-notes.tsexaminedField notes and their follow_up resolution, which the review session reads as unverified suspicions.c0734040
mcp-server/src/tools/files.tsexaminedThe ledger writers: add_files_to_scope's validated batch upsert inside one transaction, and update_file_classification.c0734040
mcp-server/src/tools/findings.tsexaminedadd_finding's opening resolution event, update_finding_status's overturn-evidence rule, and verify_finding_fix's ancestry requirement between repair and verification.c0734040
mcp-server/src/tools/git.tsexamineddetect_changes: the whole reconciliation — tree at the resolved revision, unledgered/absent/exempt, duplicate ownership, staleness re-derived both ways, scope_gaps rebuilt, and one append-only scope_reconciliations row with both digests.a521e28
mcp-server/src/tools/impact.tsexaminedpredict/apply change impact: rename-aware diff, the explicit relation graph over xrefs and seams, reason paths, and the unaffected-control set.c0734040
mcp-server/src/tools/learning.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/locks.tsexaminedThe write-lock table with TTL expiry cleared on every acquire.c0734040
mcp-server/src/tools/locus.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/logging.tsexaminedAccess and query logging, and the default field-demand priority used before any query_log evidence exists.c0734040
mcp-server/src/tools/materialize.tsexaminedThe publication preflight that refuses on an incomplete reconciliation before anything renders, and the projection read-back recorded as an auditable run.ec5824bc
mcp-server/src/tools/open-questions.tsexaminedThe autoprogress contract: record_open_question with what_assumed, and get_autoprogress_mode echoing the raw env value.c0734040
mcp-server/src/tools/project.tsexaminedSession lifecycle and the end_session auto-commit that checkpoints the WAL before committing storage.a521e28
mcp-server/src/tools/refresh.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/research.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/resolution.tsexaminedaudit_resolution_invariants over findings, claims, contradictions and obligations — it reports violations and never repairs.c0734040
mcp-server/src/tools/revalidation.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/review-analysis.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/review-session.tsexaminedThe decision surface compiled from a reconciled composition run, the actionable-items-need-evidence refusal, and the export read-back on state, coverage and content.c0734040
mcp-server/src/tools/review.tsexaminedThe knowledge tools and the workflow API the survey writes through.410d769b
mcp-server/src/tools/seams.tsexaminedSeam records and get_seam_assessability, which gates SC-N concerns on both parties being mapped.c0734040
mcp-server/src/tools/stale.tsexaminedThe stale backlog over the ledger, clear_staleness refusing an absent file, and retire_ledger_file refusing a still-tracked one.c0734040
mcp-server/src/tools/storage-history.tsexaminedcommit_phase_gate: the second caller of checkpointDatabaseForStorageCommit, and the storage log reader.c0734040
mcp-server/src/tools/subsystems.tsexaminedStatus writers and the finding rollup over finding_state_current.c0734040
mcp-server/src/tools/vocabulary.tsexamineddefine_term's three-step anchor resolution — parse, resolve the revision, require the path in that tree — the scope join that stops a re-definition revoking another subsystem's discharge, and decline_domain_vocabulary.c0734040
mcp-server/src/tools/xrefs.tsexaminedadd_xref requires a citation token in the context prose whose revision resolves; the eighth local copy of the git probe, kept local for its own failure policy.c0734040

§Concern review

AT-1

Verdict
Accepted behavior
Evidence
Code verified
Linchpin dependency
🔗

Rationale

Every multi-row mutation read in this pass is wrapped in one ctx.db.transaction, and the pairs are exactly the invariants: disposition with attachments, reconciliation with its gap rewrite and both digests, carried record with its pre-record, finding with its opening event, reset with its five deletes and the ladder rung. Acceptable rather than ruled out on two counts: the pattern is a convention at 30-odd call sites with nothing enforcing it, and 11 of the 43 modules are unread at this pass, so the claim is over what was read.

AT-2

Verdict
Accepted behavior
Evidence
Code verified
Linchpin dependency
🔗

Rationale

This surface holds both callers of commitStorage — commit_phase_gate and end_session — and both call checkpointDatabaseForStorageCommit immediately before it, so the recoverability invariant B02-1 is about is upheld here. Acceptable rather than ruled out for the same reason it is in B-02: the obligation is a convention at two call sites in this subsystem rather than a property of the function in B-02 that publishes the commit, and a third tool that wanted to commit storage would have to know to checkpoint.

CC-1

Verdict
Accepted behavior
Evidence
Code verified
Linchpin dependency
🔗

Rationale

The derived surfaces here are answered through shared generated predicates rather than restated per reader: OPEN_FINDING_SQL over finding_state_current is what the dashboard, the subsystem rollup and get_finding_summary all count, which is the repair for F9/codex — a repaired finding that stayed open on one surface and closed on the others. OBLIGATION_BEARING_SQL plays the same role for the stale split. Acceptable rather than ruled out because scope_gaps is rebuilt only by detect_changes, so between a ledger write and the next reconciliation the dashboard's unclassified_paths is a count of the last reading rather than of the tree — which is exactly why §3 requires the standing reconciliation, not the gap rows, to license a coverage fraction.

CR-1

Verdict
Accepted behavior
Evidence
Code verified
Linchpin dependency
🔗

Rationale

Handlers are synchronous end to end, so two calls cannot interleave inside one process, and the multi-row writes are transactional against a second process. The write_locks table is an advisory coordinator-level lock over artifact paths, not a database lock: acquire_lock clears expired holders and refuses a live one, but nothing in the tool surface requires a writer to hold it, so it serializes only sub-agents that agree to use it. Acceptable rather than ruled out on exactly that: the mechanism is sound and its use is voluntary.

EP-1

Verdict
Accepted behavior
Evidence
Code verified
Linchpin dependency
🔗

Rationale

Refusals run before the transaction opens, so a refused call leaves no partial row: every guard in set_disposition, add_finding, carry_finding and detect_changes throws or returns before the transaction body. Inside a transaction, better-sqlite3 rolls back on a throw. Acceptable rather than ruled out for one asymmetry the code makes visible: two error styles coexist — ToolError (surfaced as {ok:false,error}) and a returned {ok:false,error} object — and which a handler uses is a per-handler choice, so a caller distinguishing a refusal from a failure has to read the message rather than the shape.

IF-1

Verdict
Out of scope
Evidence
Code verified

Rationale

This surface passes --force-full and --clean-publish through to the materializer and records the read-back it returns; it implements neither path. Whether incremental, full and clean-publish renders agree from identical state is a property of materializer/ (B-04), where the probe can be run. What this side does own is the preflight that refuses to render at all over an unreconciled store, which is disposed under CC-1 and SC-1.

RL-1

Verdict
Accepted behavior
Evidence
Code verified
Linchpin dependency
🔗

Rationale

The two resources this surface opens on its own are foreign database handles and child processes. compare_conspectuses opens two read-only handles and closes both in a finally, which is the right shape. Every child process is spawnSync or execFileSync and so cannot outlive its call. Acceptable rather than ruled out because materialize_docs spawns the Python materializer with no timeout: an unresponsive renderer blocks the server's only thread indefinitely, which is the same unbounded-subprocess family as B02-R1 and is recorded there rather than duplicated as a second finding.

SC-1

Verdict
Accepted behavior
Evidence
Code verified
Linchpin dependency
🔗

Rationale

The seams this surface publishes twice are held together by generated sources rather than by prose: every enum a schema advertises comes from ../vocabulary.js, the citation grammar a schema's pattern publishes is CITATION_TOKEN_SOURCE — the same source the handler enforces — and the open-findings predicate is one generated SQL string. Acceptable rather than ruled out because one seam is compared only by a checker outside this subsystem: the advertised tool set against DEVELOPMENT.md, reconciled by scripts/gen-tool-inventory.mjs (B-05). Nothing inside these modules would notice a tool added without its inventory entry.

SI-1

Verdict
Out of scope
Evidence
Code verified

Rationale

Project-key and workspace-binding derivation is B-02's (project.ts), and nothing in this surface re-derives either: every handler reads ctx.project, which the dispatcher has already re-asserted. What these modules own is the narrower containment question — that a path a caller supplies cannot escape the bound storage root — and resolveArtifactPath and resolveStorageOutputPath both enforce it lexically and through realpath. Recorded out-of-scope so the identity concern stays owned where the derivation is.

SI-2

Verdict
Accepted behavior
Evidence
Code verified
Linchpin dependency
🔗

Rationale

Every revision this surface accepts is resolved at the write and re-resolved at the read, and the strongest case — define_term's anchor — goes further, requiring the path to exist in that revision's tree because parsing a citation cannot see an absent file. Acceptable rather than ruled out because the resolution is implemented eight times with eight failure policies and nothing compares them: xrefs.ts:581 names itself the eighth copy. A property added to one, such as a wall-clock bound, reaches the other seven only by hand.

TB-1

Verdict
Confirmed defect
Evidence
Code verified

Rationale

Not one of the eight spawnSync git probes in this surface carries a timeout or a killSignal, and each runs on the server's only thread inside a synchronous handler. The repository already states the rule — codex-host.ts declares STARTUP_PROBE_TIMEOUT_MS and names the hang it prevents — and applies it to three sites, all of them on the startup path. The write path, which runs a probe on every durable write, is unbounded everywhere. Recorded as B02-R1 against the shared helper and B02-R2 against index.ts:gitRoot; this disposition is the same defect counted over its full surface.

TR-1

Verdict
Accepted behavior
Evidence
Code verified

Rationale

The model-facing boundary is treated as untrusted throughout: a worker's success label is landed and then independently scored against durable state; a carried finding cannot be ruled out without evidence collected in this session; a claim cannot be overturned without new contradictory evidence; artifact paths are contained lexically and by realpath; and add_xref refuses prose carrying no resolvable citation. The one asymmetry is deliberate and documented: the symbol half of a citation is not checked for reachability, because deciding whether a symbol exists at a revision needs a parser the server does not have, and the description says a citation records where the edge was read rather than a symbol the server confirmed.

§Survey artifact

§B-03 — Knowledge tools and workflow API

Structural account, read at c073404. Scope: mcp-server/src/tools/** — 43 modules, the surface a survey is written and read through.

§Observed

One shape, repeated. Every module exports a ToolDefinition[]: a name, a description that is the agent-facing contract, a JSON Schema the dispatcher validates against with Ajv in strict mode, and a synchronous handler taking (args, ctx). There is no shared base class and no middleware; the guards are ordinary calls at the top of each handler — requireActiveSession, requireSubsystemStatus, requireWorkspaceSourcePath, resolveWorkspaceCommit — in an order each handler chooses.

Refusal order is deliberate. set_disposition checks session, then depth, then the concern's existence, then resolves its revision, then the evidence ids, then their reachability, then the quality ceiling. The comments say why: a caller who got the depth wrong is better told that than told about its revision, and a refused write should not spawn a git subprocess first.

Multi-row writes are transactional. set_disposition (row + attachments), detect_changes (staleness + scope_gaps + git_state + the reconciliation row), carry_finding (record + archived-terminal pre-record), add_finding (finding + opening resolution event), reset_subsystem (five deletes + the status write + the ladder rung).

A report is landed, then scored. Composition never reads a worker's success label as a verdict: land_composition_item stores the observation, and score_composition_item re-resolves the commit, re-reads the artifact registry's hash, checks the test's identity, SHA and exit code, and requires a terminal review aggregation. The integral lane is the same shape one level up.

Revision resolution is eight local copies. xrefs.ts:581 names itself the eighth and records that they are unshared on purpose, each owning a different failure policy — return false, throw ToolError, return null. None carries a timeout.

§State containers

ctx.db (one better-sqlite3 handle), ctx.sessionId (mutable, set by start_session and cleared by end_session), and ctx.project (frozen at startup). No module holds state of its own between calls.

§Seam contracts from this side
  • the tables — this surface is the only writer; the materializer (B-04) reads them mode=ro. Schema ownership is B-02's.
  • tools/list — read by every host and by scripts/gen-tool-inventory.mjs, which reconciles the advertised set against DEVELOPMENT.md (B-05).
  • the skill references — .claude/skills/amanuensis/** (B-01) instructs the calls these handlers refuse; check-refusal-parity compares the two.
§Open

Eleven of the 43 modules — revalidation, design-session, refresh, chorusmith-adapter, research, learning, evaluation, crosswalk, review, review-analysis, locus — are scoped and unread at this pass and remain candidate in the ledger. They are the long-tail research and review machinery rather than the survey write path; the concern review below are taken over the 32 modules that were read, and say so.