Skip to content

Replace the verb CLI with the graph handle (ADR-014) - #1

Open
darko-mijic wants to merge 213 commits into
mainfrom
experiment/annotation-fleet
Open

Replace the verb CLI with the graph handle (ADR-014)#1
darko-mijic wants to merge 213 commits into
mainfrom
experiment/annotation-fleet

Conversation

@darko-mijic

@darko-mijic darko-mijic commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Replace the verb CLI and the PatternGraphAPI facade with one frozen graph handle

The 24-verb architect CLI is deleted, not deprecated. The 29-method PatternGraphAPI facade is gone with it, including g.api, createPatternGraphAPI, CliContext.api, PipelineSession.api, and the QueryResult success/error envelope helpers. Agents script the live graph with pnpm architect:q '<js>'. Programmatic callers import @libar-dev/architect-core/graph. Named CLI commands are demos over that handle. dangling --strict is the one CLI contract CI still consumes. MCP stays at exactly 21 tools with unchanged names, inputs, and payloads.

There is no compatibility shim. No alias, no @deprecated re-export, no feature flag, no parallel facade.

This branch is experiment/annotation-fleet against main: 212 commits, 905 files, +58,117 / -36,104 on the committed range. The branch name undersells it. Annotation re-enablement is here. So is the projection pipeline, the playground that proved the handle, ADR-014, and the No-BC query-API replacement.

Why this direction

The old agent CLI was a verb wall: 24 pre-baked commands, a 29-method query passthrough, and an 11-subcommand arch family, each returning a precomputed envelope. Almost all of that surface existed to serve dogfood tests. Outside those tests, one invocation was operationally load-bearing: architect dangling --baseline <path> --strict in ci:verify.

A byte-level audit found roughly 89% of a full PatternGraph snapshot was precomputed views shaped for markdown, the lowest-priority sink. The playground experiment showed the other shape: an agent scripting ad-hoc cuts over the raw graph, in process, returning only the conclusion. That path spends about one fifth of the context of the verb API or of grep.

The verb logic already lived in architect-projection functions that MCP consumes directly. The CLI was never MCP's dependency. Deleting the verbs did not require inventing a new read model. It required stopping the CLI from pretending it was one.

The facade was the second copy of the same mistake. PatternGraphAPI wrapped the canonical graph in { success, data, error, metadata } envelopes and froze 29 thin methods (getStatusCounts, getCurrentWork, getPatternsByRole, …) as if those were the architecture. They were not. They were groupBy with a public name. Keeping them next to g.graph would have rebuilt the verb wall inside the handle.

ADR-014 records the replacement. ADR-006 still names PatternGraph as the single read model. This PR makes both true in code.

PatternGraph vs the Graph handle

These are not two graphs. They are a value and a way to ask it questions.

PatternGraph is the canonical read-model value (ADR-006). One pass over annotated source produces patterns, counts, status/role/package indexes, the relationship index, tag registry, and parse failures. Codecs, validators, MCP tools, and generated docs already consume this object. This PR does not slim it. Projection-used precomputed views stay.

Graph (g in q, createGraph in code) is the scriptable handle over that value (ADR-014). It is two surfaces that must not be merged:

  • Curated / authored: the annotated PatternGraph. Editorial sparsity is the point. An @architect-uses edge is a claim about architecture, not a restatement of an import.
  • Mechanical: a TypeScript walk of packages/*/src. Exhaustiveness is the point. It feeds impact, blast radius, and curation assistance.

Divergence between the two is curation, not drift. Dark imports default to no action. Jaccard overlap on this repo is 29% (714 mechanical edges, 395 authored, 250 shared, 464 dark, 145 aspirational). That number is a description of selection, not a quota to close.

q injects g, inspect, execFileSync, and REPO_ROOT. It compiles the caller's own JS (node:vm). Same trust level as the shell that launched it, like node -e. It is not a sandbox. Git refs that reach blast are resolved to a verified commit SHA at the boundary.

Frozen @libar-dev/architect-core/graph contract

The published pure contract is the ./graph subpath of @libar-dev/architect-core (2.0.0-pre.1). It exports Graph, createGraph, need-shaped types, decode schemas, and the trusted pure views. Construction performs no source, config, git, or filesystem IO. typescript is a core devDependency only. The TypeScript walker, loadGraph, q, git-ref validation, and named CLI commands stay in @libar-dev/architect-cli.

There is no @libar-dev/architect-graph package. The bin-only CLI package does not publish a public handle export.

Trusted views, the joins that actually cross sources, live in core and hang off Graph:

View Job
findByConcept fuzzy concept → ranked curated patterns
byFile file → owner + neighborhood, including dark files
bySymbol exported symbol → defining files + importedByPatterns
invariantsOf Gherkin Rule blocks, labeled executable vs authored
specsReverifying at-risk specs for a change set
blastRadius exhaustive mechanical impact, plus at-risk specs
fanInCandidates high-fan-in unmapped modules, barrels excluded
graphDiff shared / dark / aspirational partition
driftFlags dangling uses / orphaned source
census raw package percentages as a labeled diagnostic

Empty-vs-empty graphDiff is Jaccard 100, not NaN. Graph-handle tests pin the GraphHandle sentinel, not a > 300 pattern-count threshold.

Every reachable public value is deep-frozen: g, g.graph, g.authored, g.mech, every PatternNode, nested relationship arrays, FSM results, and view results. Mutating g.graph.patterns[0].name in q leaves g.pattern("GraphHandle")?.name as GraphHandle.

deferred derives maturity plan. Live check: every deferred pattern on this graph reports maturity === "plan".

g.graph, g.fsm, and the pure kernels

g keys are graph, fsm, authored, mech, patterns. There is no api.

g.graph is the complete, deeply frozen PatternGraph. Live keys: patterns, counts, byStatus, byNormalizedStatus, byMaturity, byRole, byProductArea, bySourceType, relationshipIndex, tagRegistry, archIndex, roleCount, featureParseFailures.

g.fsm is four operations that delegate to the existing validation/fsm functions and freeze their results:

Method Meaning
isValidTransition(from, to) boolean
validateTransition(from, to) { valid, from, to, … }
getValidTransitionsFrom(status) copied array
getProtectionSummary(status) protection info

Live: roadmap → active is true. active → deferred is false. completed may reopen to active or roadmap. Protection for completed is hard.

Thin filters stay scripts. g.graph.counts, g.graph.byStatus.active, g.graph.relationshipIndex[name], Object.keys(g.graph.archIndex?.byPackage ?? {}).sort() replace the old named methods. Freezing those as handle verbs is how the wall comes back.

Reusable algorithms that need a caller-supplied PatternGraph remain named pure exports from @libar-dev/architect-core, not handle methods:

  • getDependencyContext(graph, name, options)
  • getRulesForPattern
  • findPatternByName / findPatternParseFailure
  • decision resolution (resolveDecisionPattern, listDecisionPatterns)
  • resolveRoleDefinition

Accessors return plain values. They do not wrap { success, data }. Envelope branching in callers should be deleted, not rebuilt.

Dependency context

The cycle-safe upstream/downstream forest moved out of the facade into packages/architect-core/src/read-api/dependency-context.ts. Projection calls that function directly (dependency-context.internal.ts). The decision-only seeAlso graft stays local to the projection, where it belongs.

Behavior kept, then re-proven:

  • chain walk and reverse traversal
  • max-depth truncation
  • cycle emits no duplicate node
  • isolated pattern returns an empty forest
  • unknown name ("Ghost") returns undefined
  • seeAlso is not traversed as a dependency

Live on this repo: getDependencyContext(g.graph, "GraphHandle") focal GraphHandle, upstreamDirect = 2 (AuthoredCoreBuilder, MechanicalSubstrateExtractor), upstreamTransitive = 21, downstreamDirect = 1, downstreamTransitive = 4. Default maxDepth is 10.

MCP architect_dep_tree still returns kind DependencyContext with the same root keys (downstream, focal, kind, options, summary, upstream). That payload did not change.

PatternGraphAPI retirement (No-BC)

Deleted, with no remaining production or test import except negative assertions and the migration table:

Gone Replacement
packages/architect-core/src/read-api/pattern-graph-api.ts @libar-dev/architect-core/graph + pure kernels
PatternGraphAPI, createPatternGraphAPI Graph, createGraph
g.api g.graph / g.fsm / kernels
CliContext.api CliContext is { build, graph }
PipelineSession.api PipelineSession has dataset; handoff uses findPatternByName(session.dataset, name)
CLI-local handle/schema.ts and handle/views.ts core Graph schemas and views
Envelope runtime exports QueryResult, QuerySuccess, QueryError, QueryApiError, createSuccess, createError direct values; throw or undefined per named contract

QueryErrorCode and QueryMetadataExtra remain type-only. Live payload types stay public: DependencyContext, DependencyContextNode, PatternRelationships, TransitionCheck, ProtectionInfo, and the rest of the read-api contracts that MCP and projection still serialize.

Facade-owned tests were not dropped. Invariants moved:

  • graph-field consistency → pattern-graph-consistency.feature
  • handle / FSM / immutability → core graph.feature + fsm-transitions.feature
  • rules, decisions, packages → read-kernels.feature
  • public freeze → tests/features/cli/public-contract.feature now asserts @libar-dev/architect-core/graph plus kernels, and asserts the eight legacy runtime keys are absent
  • MCP internals → mcp-pipeline-session-no-facade.feature

Identities removed with the facade: PatternGraphApi, PatternGraphApiConsistencyExecutableTests, PatternGraphApiReverseLookup, GraphHandleShapes, GraphHandleViews. Replacement test identities: PatternGraphConsistencyExecutableTests, ReadKernelExecutableTests, MCPPipelineSessionDatasetLookupExecutableTests. Live graph contains zero PatternGraphApi uses or usedBy edges.

CLI and MCP

CLI

architect is the graph-handle CLI.

pnpm architect:q '<js>'          # argv
pnpm architect:q < script.js     # stdin
pnpm architect:graph <cmd>       # named demos + dangling

--conditions=source is already in the pnpm scripts.

Named demos, frozen help order: census, diff, blast, fan-in, drift, maturity, find, file, symbol, invariants, specs. Help text calls census "curation candidates, then diagnostic node/edge coverage per package". Unknown commands reprint USAGE and exit 1.

q happy paths on this tree:

g.pattern("GraphHandle")?.name                    → GraphHandle
g.graph.counts.total                              → 349
g.fsm.isValidTransition("roadmap","active")       → true
"api" in g                                        → false
Object.isFrozen(g.graph)                          → true

Stdin and multi-statement bodies work. import / export fail compile. require('fs') is a ReferenceError. return g.api.getStatusCounts() is TypeError: Cannot read properties of undefined.

Never call architect:q bare in automation. With a non-TTY stdin and no argument it waits. Pass an argument or pipe input.

Dangling gate

Unchanged JSON and exit-code contract. CI still runs:

pnpm architect:graph dangling --baseline packages/architect-guard/src/lint/dangling-baseline.json --strict

Exact ordered fields: baselinePath, written, strict, drift, baselineCount, currentCount, addedCount, removedCount, added, removed, current.

Live: written=false, strict=true, drift=false, all counts 0, arrays empty, exit 0. The unused facade construction was removed from shared CLI context. The comparison itself did not change.

MCP, exactly 21 tools

MCP is a different sink (Studio + burst-mode). ADR-014 point 5 stands: retiring CLI verbs and the facade does not migrate MCP onto agent scripting.

Frozen order, API and stdio identical:

  1. architect_overview
  2. architect_coverage
  3. architect_context
  4. architect_files
  5. architect_dep_tree
  6. architect_scope_validate
  7. architect_handoff
  8. architect_status
  9. architect_pattern
  10. architect_bundle
  11. architect_list
  12. architect_open_questions
  13. architect_search
  14. architect_rules
  15. architect_taxonomy
  16. architect_arch_neighborhood
  17. architect_arch_blocking
  18. architect_rebuild
  19. architect_config
  20. architect_documentation
  21. architect_help

Payload kinds checked live: AnnotationCoverage still has coveragePercentage; DependencyContext forest keys unchanged; HandoffRecord keys unchanged. Extra input keys still fail Zod (Unrecognized key). Unknown tool is still Unknown Architect MCP tool. Unknown handoff pattern is still PATTERN_NOT_FOUND. Stdio survived a malformed JSON line and then answered tools/list with the same 21 names.

architect_overview no longer tells agents to run deleted verbs. Those strings point at architect_arch_blocking, architect_documentation, and the handle.

Annotation-integrity detectors

Space-separated @architect-uses A B C used to fail PatternReferenceSchema and drop the whole pattern node with every gate still green. That silent drop is now an error on the existing validate:all / anti-pattern path. Comma form (A, B, C) remains the authored form. The scanner still splits on comma only. The new detectors refuse the space form before it can vanish.

Three error-level IDs in packages/architect-guard/src/validation/ts-annotation-integrity.ts, wired beside gherkin-tag-space-form:

ID Catches
ts-missing-architect-marker JSDoc with @architect-pattern and no leading bare @architect
ts-tags-after-prose Architect tags after description prose
ts-uses-space-form TypeScript @architect-uses values separated by spaces instead of commas

Valid near-misses stay clean: marker-first blocks, comma-form uses, single-target uses, prose after tags. Fixtures pin one error each (marker line 2, prose line 3, uses line 5). No new CLI, no autofix that guesses intent, no coverage-percentage rule.

This closes the old PR note that listed space-separated uses as leftover. It is gated.

Curated nodes, contexts, edges, leave-dark

Curation is a ledger, not a percentage. A live audit ran first. Then only the approved seams landed.

Five new code-originated nodes

All completed, marker-first, comma-form, local how/when prose only.

Pattern File Role Context Uses
CLIContextBuilder packages/architect-cli/src/cli/cli-runtime.ts service cli CLIContextTypes, ConfigLoader, ArchitectWorkspaceSources, BuildPipeline
ArchitectWorkspaceSources packages/architect-core/src/config/self-hosting.ts contract configuration TagRegistrySchemas
ValidationOutputSchemas packages/architect-core/src/validation-schemas/output-schemas.ts contract validation-schemas ExtractionDiagnostics, LintViolationContract
DanglingBaseline packages/architect-guard/src/lint/dangling-baseline.ts service validation PipelineDatasetContract
StepLintContract packages/architect-guard/src/lint/steps/types.ts contract lint LintViolationContract

Two bounded-context corrections

Existing identities, not new names. ErrorFactoryTypes (packages/architect-core/src/types/errors.ts) and ResultMonadTypes (packages/architect-core/src/types/result.ts) now carry @architect-bounded-context:domain. Each identity remains unique.

21 authored forward pairs

Reverse usedBy is derived. No reverse tags were written. No second @architect-uses line on any scoped identity.

DocExtractor, AstParser, ExtractedPattern
  → ExportInfoContract

DualSourceExtractor, GherkinExtractor, GherkinAstParser,
GherkinScanner, SessionStateReader, AntiPatternDetector
  → GherkinScanResultContract

GherkinAstParser, RegistryBuilder, DualSourceSchemas, LintRules
  → HierarchyLevelDomain

LintPatternsCLI, LintEngine, LintRules,
ValidationOutputSchemas, StepLintContract
  → LintViolationContract

OpenQuestionListProjection → OpenQuestionList
ArchitectureGraphProjection → ArchitectureGraphSupport, ProjectionContext

Leave dark, on purpose

These files stay unmapped. Generic utility bags, barrels, one-caller wrappers, and raw fan-in are not architecture.

  • packages/architect-core/src/utils/runtime-helpers.ts
  • packages/architect-core/src/utils/string-utils.ts
  • packages/architect-guard/src/cli/shared.ts
  • packages/architect-projection/src/projections/documentation-composition/documentation-bundle.internal.ts
  • packages/architect-projection/src/projections/governance/taxonomy-digest.internal.ts

ProjectionError was already mapped. It did not get a second identity.

Live totals after this batch: 349 patterns (143 completed, 178 active, 14 planned, 14 candidate). Arithmetic from the pre-edit 346: minus 5 retired facade identities, plus 3 replacement tests, plus 5 curated nodes.

Census is diagnostic, not a quota

pnpm architect:graph census leads with "significance candidates (curation assistance)", then "package coverage (diagnostic-only)". Barrels are excluded. There is no targetPercentage. There is no significanceCensus() method. Empty mechanical/authored fixtures produce zero candidate lists and finite percentage fields.

MCP architect_coverage still returns coveragePercentage as a payload field on AnnotationCoverage. That is the frozen fragment contract. It is not a process gate and was not used as one here.

Dark imports default to no action. The graph-handle skill and recipes say so.

Durable records, changeset, generated docs

Edited in place after the code proved the replacement (bootstrap / pre-1.0, no amend-chain):

  • architect/decisions/adr-014-agent-read-surface.feature point 3 now names g.graph / g.fsm / pure kernels. Point 3 no longer names g.api. There is no facade or query-envelope layer.
  • architect/decisions/adr-006-single-read-model-architecture.feature examples name Graph consumers and pure read kernels, not the facade.

Hand-authored current guidance retargeted off g.api / createPatternGraphAPI / deleted verbs: AGENTS.md, docs/CLI.md, docs/SESSION-GUIDES.md, docs/INDEX.md, package PRDs, MIGRATION.md, graph-handle skill and recipes, plus present-tense leftovers in annotation/taxonomy/validation docs and formal-spec pages that still claimed the old path. Historical dated review notes (for example formal-spec/REVIEW-2026-05-17-FINDINGS.md) keep their original architect:query citations. Those are records of a past review, not instructions.

Changeset: .changeset/retire-pattern-graph-facade.md. One file. Major on the fixed 2.0.0-pre.1 group:

  • @libar-dev/architect
  • @libar-dev/architect-core
  • @libar-dev/architect-projection
  • @libar-dev/architect-guard
  • @libar-dev/architect-cli
  • @libar-dev/architect-mcp

pnpm changeset status --verbose resolves each to 2.0.0. No extra package.

docs-live/ is generated. pnpm docs:all wrote it. Nobody hand-edited it. pnpm docs:check reports 49 generated files, no drift.

Skills: architect-data-api is gone. architect-graph-handle is the operational guide. architect-base and architect-sessions point at pnpm architect:q, not the verb CLI.

Breaking changes and migration

No-BC on two stacked removals:

  1. Verb CLI. architect overview, pnpm architect:query, arch neighborhood, arch blocking, arch workable, the REPL, and the CLI-vs-MCP parity suite are unknown commands. No alias.
  2. Query facade. PatternGraphAPI / g.api / envelope helpers do not exist at runtime.

MCP tools are the typed alternative when you need a stable verb. The handle is the alternative when you need a cut no verb pre-baked.

Handle mapping (full table in MIGRATION.md):

Removed Use instead
g.api.getStatusCounts() g.graph.counts
g.api.getPatternsByStatus(status) g.graph.byStatus[status]
g.api.getPatternsByNormalizedStatus(status) g.graph.byNormalizedStatus[status]
g.api.getPattern(name) g.pattern(name) or g.graph.patterns.find(...)
g.api.getPatternParseFailure(name) g.graph.featureParseFailures?.find(...)
g.api.getPatternRelationships(name) g.graph.relationshipIndex[name]
g.api.getCurrentWork() g.patterns.filter(p => p.status === "active")
g.api.getRoadmapItems() g.graph.byStatus.roadmap
g.api.getCompletedPatterns() g.graph.byStatus.completed
g.api.listPackages() Object.keys(g.graph.archIndex?.byPackage ?? {}).sort()
g.api.isValidTransition(from, to) g.fsm.isValidTransition(from, to)
g.api.checkTransition(from, to) g.fsm.validateTransition(from, to)
g.api.getValidTransitionsFrom(status) g.fsm.getValidTransitionsFrom(status)
g.api.getProtectionInfo(status) g.fsm.getProtectionSummary(status)
g.api.getDependencyContext(name) getDependencyContext(g.graph, name)
g.api.getRulesForPattern(name) getRulesForPattern(g.graph, name)
g.api.getStatusDistribution() / getCompletionPercentage() script over g.graph.counts; no named replacement
g.api.getPatternGraph() g.graph

Programmatic:

import { createGraph } from '@libar-dev/architect-core/graph';
import { getDependencyContext, getRulesForPattern } from '@libar-dev/architect-core';

const g = createGraph(patternGraph, mechanicalCore);
const counts = g.graph.counts;
const canStart = g.fsm.isValidTransition('roadmap', 'active');
const dependencies = getDependencyContext(g.graph, 'MyPattern');

Use CLI q when you need live source/config IO. createGraph wants values you already built.

The v1 monolith → v2 split (bin-only meta package, colliding BusinessRule names, no JS import from @libar-dev/architect) is also in MIGRATION.md. That split is on this branch vs main. It is older than the facade retirement and still applies.

Testing and QA

Final pnpm ci:verify exit 0 (2026-08-20T12:41:01Z .. 12:43:17Z). Members, all green:

  • pnpm build (core, guard, projection, mcp, cli)
  • pnpm format:check
  • pnpm lint (core, guard, projection, mcp, cli)
  • pnpm typecheck and pnpm typecheck:dogfood
  • pnpm test
    • core 32 files / 1163
    • guard 5 / 65
    • projection 44 / 1862
    • cli 5 / 32
    • mcp 3 / 188
    • 7 bins smoke (architect, architect-generate, architect-guard, architect-lint-patterns, architect-lint-steps, architect-validate, architect-mcp)
  • pnpm test:dogfood 13 files / 582
  • pnpm validate:all (no anti-patterns; 6 pre-existing deprecated projection tag warnings unchanged)
  • pnpm guard:no-suppressions
  • pnpm check:skills (5 canonical skills, no dangling links)
  • strict dangling, JSON as above
  • pnpm audit:subtractive (informational; no facade finding)

Independent of ci:verify: pnpm docs:check exit 0, 49 files, no drift. Root public-contract + graph-handle: 44 tests, including 38 graph-handle scenarios. MCP no-facade + integration: 186 tests on those two files.

Real surfaces exercised, not mocked:

pnpm architect:graph --help
pnpm architect:q "g.pattern('GraphHandle')?.name"
pnpm architect:q 'return g.fsm.isValidTransition("roadmap","active")'
pnpm architect:q 'return g.api.getStatusCounts()'          # exit 1
pnpm architect:q "import x from 'y'"                       # exit 1
pnpm architect:graph census
pnpm architect:graph dangling --baseline packages/architect-guard/src/lint/dangling-baseline.json --strict

MCP package API and stdio packages/architect-mcp/bin/architect-mcp.js both listed 21 tools in frozen order, returned coverage / dep-tree / handoff payloads, rejected unknown tools and extra keys, and recovered from malformed JSON.

Adversarial coverage worth a look if you are reviewing tests: malformed annotation fixtures (exact IDs and lines), facade restoration sensitivity on createPatternGraphAPI / PatternGraphAPI, curation verifiers that fail on missing / unapproved / reverse / duplicate edges, q mutation resistance, MCP extra-key and unknown-pattern paths. No fixed sleeps.

Reviewer guide by area

The GitHub range vs main is large. Read it in layers. Do not start at file 1 of 875.

1. Kernel, package split, projection pipeline (early commits on the branch). Event-sourced read model, codec/renderer split, docs-live/ generation, architecture context-map and per-group diagrams, overview disclosure. Background for ADR-006/005/009. Not the review focus unless you are checking that this cut did not slim PatternGraph. It did not.

2. Annotation re-enablement (WS-1, 6f2fc6c and follow-ons). Production @architect-uses restored after a refactor campaign had stripped them. Orphans came down in sessions, not in one sweep. Edge syntax is one comma-separated @architect-uses line. Useful context for the leave-dark policy later.

3. Verb CLI deletion, ADR-014 (2edfeea and the retarget commits through a255ee7). Start here for the agent CLI.

  • 2edfeea feat(cli)!: replace the verb CLI with the graph handle (ADR-014)
  • f1f773e skills/wiring: handle becomes the read path; architect-data-api retired
  • e961c56 docs-live/ regenerated from the reshaped graph
  • 3e30e62 / 66004de / 49724f4 / c17fa37 / a255ee7 stop-time review: dead verb strings, overview cliHints, pipeline slim, remaining overview instructions

Deleted commands should stay deleted. MCP names in that layer should stay.

4. Frozen Graph contract. packages/architect-core/src/graph/{schema,graph,views,analysis-views,spec-bridge,view-support,index}.ts and packages/architect-core/package.json ./graph. Check: no IO, no typescript runtime dep, deep freeze, deferred → plan, Jaccard 100 on empty diff, no thin status verbs.

5. Pure kernels and facade deletion. read-api/dependency-context.ts, rule aggregation, decision resolution, deleted pattern-graph-api.ts, rewritten public-contract.feature. Projection dependency-context.internal.ts must import the kernel, not createPatternGraphAPI.

6. CLI composition. packages/architect-cli/src/handle/graph.ts (IO only), cli-runtime.ts, cli-types.ts, graph-cli.ts, census-report.ts. CliContext has no api. Dangling JSON shape is pinned in tests/support/helpers/graph-handle-contract.ts.

7. MCP internals. pipeline-session.ts, tool-registry.ts, tool-metadata.ts. Count 21. architect_coverage / architect_dep_tree / architect_handoff payloads. mcp-pipeline-session-no-facade.feature.

8. Guard detectors. packages/architect-guard/src/validation/ts-annotation-integrity.ts and tests/ts-annotation-integrity.test.ts. Error severity, three IDs, valid near-misses.

9. Annotation batch. The seven files in the node/context table, plus the Todo 11 owners for the 21 pairs. Confirm leave-dark paths have no @architect-pattern. Confirm no authored @architect-usedBy.

10. Durable docs. ADR-006, ADR-014, MIGRATION.md, the one changeset, skills, docs/CLI.md. Then glance at generated docs-live/decisions/adr-014.md as a projection, not as a source.

Generated files

docs-live/ is the determinism-gate target. Regenerated as a whole-graph projection. Do not review it as hand-written prose. If it disagrees with an ADR, the ADR wins and the generator needs a bug.

Roots: ARCHITECTURE.md, PATTERNS.md, ROADMAP.md, CHANGELOG.md, CURRENT-WORK.md, DESIGN-REVIEW.md, TAXONOMY.md, TRACEABILITY.md, BUSINESS-RULES.md, REQUIREMENTS-EXECUTABLE.md, REQUIREMENTS-SPECS.md, VALIDATION-RULES.md, DECISIONS.md, API-REFERENCE.md, INDEX.md, plus routed children under architecture/, api-reference/, business-rules/, decisions/, design-review/.

This cut's generator delta vs the verb-CLI HEAD includes PatternGraphApi retirement, the three replacement test identities, the five curated nodes, the two domain contexts, ADR text, and package-seam / business-rule pages that now see those edges. docs-live/.generated-docs-manifest.json tracks the 49-file set. pnpm docs:check is the gate; git diff --exit-code cannot tell an uncommitted edit from a non-deterministic generator, which is why docs:check exists.

Intentionally excluded, not leftover

These are out of this PR on purpose. They are not "left for later" inside this delivery.

  • Local .omo/ working state. Plans, evidence, and orchestration files stay untracked. They are not part of the GitHub PR and should not be staged. .prettierignore now lists .omo/ next to .scratch/ and .pr-coordination/ so local evidence cannot fail format:check. That ignore is the product change. The directory itself is not.
  • Unrelated dirty deletion of .opencode/oh-my-openagent.jsonc. Pre-existing. Not restored, not staged, not this work.
  • @architect-executable-specs path resolution. Dangling and validate:all still check pattern-name refs, not the executable-specs file path. A design spec can point at a missing file and stay green. Recorded in FEEDBACK.md. Not in this scope.
  • Four roadmap specs with old monolith owner paths and no diff: status-aware-eslint-suppression, session-file-cleanup, traceability-generator, prd-generator-code-annotations-inclusion. Residual HEAD drift, not introduced here.
  • PatternGraph schema/view slimming. Separate documentation-projection redesign.
  • Import-to-@architect-uses derivation, 100% annotation, bulk bounded-context fill. Rejected. Significance, not coverage.
  • MCP inventory change or handle-for-Studio replacement. 21 tools stay.
  • Realization-edge policy, deletionReady, maturity/provenance redesign, projection-epic subtraction. Not this PR.

Try it

pnpm architect:q 'g.pattern("GraphHandle")'
pnpm architect:q 'return {counts: g.graph.counts, hasApi: "api" in g, frozen: Object.isFrozen(g.graph), go: g.fsm.isValidTransition("roadmap","active")}'
pnpm architect:graph census
pnpm architect:graph dangling --baseline packages/architect-guard/src/lint/dangling-baseline.json --strict

Operational guide: .agents/skills/architect-graph-handle/SKILL.md. Decision records: architect/decisions/adr-014-agent-read-surface.feature, architect/decisions/adr-006-single-read-model-architecture.feature. Consumer mapping: MIGRATION.md.

Adds renderMarkdownBundles metric covering patterns, requirements-executable,
and roadmap document types. Regenerates the baseline to reflect the current
codebase rather than the year-old ee58aac anchor. Closes review finding P1-#8
(02b-performance-raw.md H2, M1, M3).
…infer

Schemas become canonical; types derived via z.infer. The previous arrangement
constrained schemas to match hand-written interfaces (z.ZodType<Block>
annotation), blocking .describe() metadata from flowing into the types and
forcing dual maintenance. ListItem retains explicit z.ZodType annotation
because Zod 4.x cannot infer recursive lazy unions.

Closes review finding P0-4 (04a-framework-raw.md F2).
ProgressiveDisclosureLevelSchema, ProgressiveDisclosurePolicySchema,
ContentRichnessSchema, GroupingAxisSchema, RootShapeSchema, and
DisclosureSpecSchema gain field-level and enum-level descriptions so the
campaign's extractZodSchemaFields() extractor can surface non-empty reference
tables.

Closes review finding P0-3 (04a-framework-raw.md F4).
ESLint flat config at eslint.config.mjs:3 imports eslint-plugin-import and
references eslint-import-resolver-typescript via import/resolver, but neither
package was in root devDependencies. ESLint failed at config-load time, so
pnpm -r lint crashed even on packages whose src wouldn't trigger any
import/* rule.

Adds both plugins as devDependencies at root (pnpm hoists for workspace
packages). Pre-existing REMAINING-WORK.md item :135 specifically called this
out; pulled forward so per-wave lint can run as part of the substrate-prep
quality gate. Broader W2 lint wiring (custom no-suppression-comments rule,
per-package coverage) remains open.

Refs REMAINING-WORK.md :23, :131-135.
After the eslint-plugin-import install in ac1a16a surfaced real lint output,
two findings traced back to the W1.2 z.infer inversion: a hand-written
CollapsibleBlock declared via `type ...= {...}` (the lint config prefers
`interface`), and an unnecessary chained `as BlockType` cast inside the
isBlock guard. Both fixed in place; preserves z.infer-first inversion and
recursive-Block invariant intact.

The 4 pre-existing lint findings in taxonomy-digest, validation-rule-digest,
render-json, and render-ui are tracked separately in REMAINING-WORK.md
:135-bullet as not-introduced-by-this-campaign.
…lete 'dropped' shim

Splits documentation-types.ts along three seams:
- documentation-type-registry.ts — schema + 12 SUPPORTED entries + Map-backed lookup
- disclosure-matrix.ts — per-type matrices + disclosureMatrix/disclosureSpec helpers
- projection-filter-resolver.ts — runtime filter merging

Deletes the 'dropped' shim entirely (DroppedDocumentationType*, isDroppedDocumentationType,
4 dropped registry entries, and the dropped-branch politeness in
assertSupportedDocumentType). Per CLAUDE.md no-BC doctrine, the polite
"intentionally dropped" error message was a softener; UNKNOWN_DOCUMENT_TYPE
with the supported-types list is sufficient.

Moves the module-load forEach(schema.parse) loop into a test (restoring the
sideEffects: false contract). The schema/literal alignment check now runs at
test time rather than every import.

Updates 6 consumer files (bundle.internal, projections barrels, renderers).

Closes review findings P0-1, P0-2 (05-final-report.md), F2, F3 (01b),
F1, F3 (04a), and M4 (02b perf — Map-backed lookup).
…level modules

Lifts progressive-disclosure.ts and disclosure-spec.ts out of
projections/documentation-composition/ into:
- src/disclosure/levels.ts — disclosure tiers + policy
- src/disclosure/spec.ts — composition recipes
- src/routing/route-id.ts — logical route IDs + helpers

These are package-wide vocabulary (consumed by renderers, fragments, projections);
parking them inside one projection domain forced layering inversions in
renderers/types.ts and fragments/base.ts.

Consolidates fragments/base.ts BundleRouteId into LogicalRouteId — they were
structurally identical, maintained in parallel only because they lived in
different layers.

Adds ./context, ./disclosure, ./routing sub-entries to package.json exports
so consumers can import the slim surface without dragging in 400+ projection
symbols from the root barrel (finding F16).

Updates 13 consumers across renderers/, projections/, fragments/, and tests/.

Closes review findings P1-#10 (05-final-report.md), F5, F17, F18 (01b),
F5 (04a — LogicalRouteId branding intentionally deferred), F16 (01b — context
sub-entry).
Extends BundleRouting with optional disclosureSpec set at projection time
by projectDocumentationBundleInternal. The renderer's resolveBundleDisclosureSpec
now reads from bundle.routing.disclosureSpec instead of looking up the
documentation-type registry at render time.

This is the renderer-side half of decoupling: per ADR-005 + ADR-009, renderers
trust the bundle. render-markdown.ts no longer imports
getDocumentationTypeMetadata (markdown-paths.ts still does — separate wave
W3.2b will handle that, since it requires extending BundleRouting with
markdown-specific path data + changing MarkdownRouteProfile.mapPath signature).

Closes review finding P1-#7 (05-final-report.md) for the disclosure half;
addresses F4 (01b-architecture-raw.md).
Extends BundleRouting with markdownRootTarget, markdownChildDirectory, and
entityPathLayout. projectDocumentationBundleInternal sets all three from the
registry entry at projection time. MarkdownRouteProfile.mapPath now takes
routing as a parameter; markdown-paths.ts reads route data from routing
instead of looking up the documentation-type registry at render time.

Adds entityPathLayout to SupportedDocumentationTypeRegistryEntrySchema so
the 'requirements-executable' nested-index convention is declared on the
registry entry, not as a hardcoded string match in the renderer. The
'milestones' fallback in resolveRootMarkdownPath is dead code now that
routing.markdownRootTarget is always populated — deleted.

After this wave, NO file under src/renderers/ imports from
src/projections/documentation-composition/*. The renderer trusts the bundle.

Closes review finding P1-#7 (05-final-report.md) entirely; completes the
ADR-005 / ADR-009 cleanup. Eliminates Phase 1 H4 hardcoded doc-type strings.
…cation

Eliminates the redundant renderDocument call on the non-split path of
addRoutedDocument. shouldSplit's "render+count" was being thrown away and the
non-split branch re-rendered the same document. The new shape renders once,
counts lines via a no-allocation countLines() loop, and reuses the rendered
output for the non-split path. Saves one full render per non-splitting doc
(the common case).

The split path still pays for splitter measurement renders + final split-parent
render — those produce structurally different documents that must be rendered
fresh — but the redundant shouldSplit call is removed.

Also swaps splitOversizedDocument's interior split('\n').length to countLines.

Closes review finding P1-#9 (05-final-report.md), H1 + M5 (02b-performance-raw.md).
…lint boundaries, finalization

Lands tasks 1-11 of .sisyphus/plans/projection-substrate-session2.md plus the
post-final-wave finalization that the gate agents flagged as out of scope for
their pass. The package is now substrate-ready for the doc-generation campaign
drafted in .pr-coordination/.

Tasks 1-2 — schema consolidation
- PatternDetailSchema extends PatternSummarySchema (encodes the runtime
  subset relationship the projections already produced).
- Consolidate DeliverableSchema to one canonical definition; remove the
  parallel shape in pattern-relations/supporting.
- Consolidate slugForFilename / toKebabCase / createSlug to one helper.

Tasks 3-7 — JSDoc boilerplate sweep
- Replace the 39× "As a typed contract / data shape consumed by projection
  or render layers" placeholders across fragments / projections / renderers
  with per-file purpose prose.
- Lift renderer overview prose from docs/MIGRATION.md to each renderer
  entry point.
- Add a contributor warning above DOCUMENTATION_PROJECTION_FACTORIES
  pointing at DocDefinition.build(graph) (W-DOCS-1 deletion target).
- New scripts/jsdoc-boilerplate-audit.mjs prevents regression; wired into
  the package test script.

Tasks 8-9 — security invariants I1-I5
- JSDoc invariants on sanitizeMarkdownLinkTarget, render-ui URL passthrough,
  TRUSTED_MARKDOWN, isPlainObject prototype guard, parseAndProject options
  parsing.
- Dynamic markdown fence escalation + CodeBlockSchema.language regex
  hardening.
- 10 adversarial security tests covering markdown link/fence attacks,
  JSON non-plain-object rejection, prototype-polluted payloads,
  strict-option boundary checks, and the renderer namespace privacy
  contract.

Task 10 — projection trust boundary as lint
- Four rule clusters in root eslint.config.mjs scoped to
  src/renderers/**/*.ts. Each violation message carries a stable
  [arch-boundary:<id>] or [trust-boundary:<id>] tag for grepability:
  * renderer-no-doc-composition (6 paths)
  * renderer-no-route-construction (createIndexRouteId / createEntityRouteId
    banned; type-only LogicalRouteId remains allowed)
  * renderer-no-cross-layer-internal (../**/*.internal.js banned)
  * trusted-markdown-firewall (5 AST selectors blocking any import / export
    of the TRUSTED_MARKDOWN symbol).

Task 11 — final-wave verification — green
- build / typecheck / 1544 projection tests / perf gate / validate:all all
  pass. JSDoc-boilerplate audit reports zero flagged files. Boilerplate
  grep returns zero matches across packages/architect-projection/src/.

Finalization (post-final-wave, out of scope for the gate agents)
- Pre-existing lint debt at HEAD cleaned: removed three redundant
  no-unnecessary-type-assertion casts (taxonomy-digest.internal.ts,
  render-json.ts, render-ui.ts) and dropped the unused _context arg from
  the stateless internal buildValidationRuleDigest helper.
- New eslint override on src/**/*.ts sets argsIgnorePattern: '^_'
  (plus vars / caughtErrors variants) so the codebase's _-prefix
  convention works in the public projectValidationRuleDigest wrapper that
  must keep its parameter slot to satisfy the documentation-composition
  factory dispatch contract.
- Pre-existing dangling references fixed in architect/specs/: both
  @architect-see-also edges pointing at the non-existent
  ADR005CodecRendererSeparation were renamed to the actual ADR pattern key
  ADR005CodecBasedMarkdownRendering. validate:all now reports zero dangling
  references; the dangling-baseline.json zero-tolerance posture stays.

Documentation
- packages/architect-projection/README.md gains "Architecture invariants →
  Enforced at lint time" with the rule-id reference table.
- packages/architect-projection/docs/MIGRATION.md cross-references the
  ESLint enforcement from the trust-boundary section so v1→v2 consumers
  expect the rules.
- REMAINING-WORK.md: marks the W1.5.x dangling-baseline regression and
  W2 pre-existing lint findings DONE; records a new architect-core
  parserOptions lint gap to address in W2.

References:
- Plan: .sisyphus/plans/projection-substrate-session2.md
- Source review: .full-review/05-final-report.md (P0 and P1)
- Substrate target: .pr-coordination/PROPOSED-DESIGN.md
…(W2)

Resolves Wave 2 (Root tooling) of REMAINING-WORK.md. The repo now has a
working `pnpm -r lint` across all five publishable packages and the
no-BC suppression-comment doctrine is enforced by both ESLint and a
standalone ratcheting guard.

Per-package eslint configs
- New `eslint.config.mjs` in architect-core, architect-guard,
  architect-cli, architect-mcp. Each extends the root config and sets
  parserOptions.project to its own tsconfig.test.json, matching the
  architect-projection precedent. Type-aware rules now have the program
  info they need; the workspace-wide `pnpm -r lint` previously failed in
  4 of 5 packages with "rule which requires type information."

Pre-existing lint debt cleaned (4 errors surfaced by the new configs)
- architect-core/src/extractor/gherkin-extractor.ts:645, :669 — dropped
  redundant `as ExtractedPattern` casts after spread; TS already infers
  the right shape.
- architect-core/src/validation-schemas/codec-utils.ts:81 — dropped the
  unnecessary `as Record<string, unknown>` cast; TS narrows `data` via
  the preceding typeof / null / `in` checks.
- architect-cli/src/cli/commands/_shared/structured.ts:269 — dropped the
  unnecessary `as ArchCommandFlags` cast; the structural match holds
  through the optional-readonly shape.

No-suppression doctrine ported from architect-studio
- Root eslint.config.mjs registers a local `architect-local` plugin
  containing the `no-suppression-comments` rule. The rule scans for
  `eslint-disable`, `@ts-ignore`, `@ts-expect-error`, `@ts-nocheck` in
  comments and fires error with the searchable
  `[no-bc:no-suppression-comments]` tag. Active on
  `packages/*/src/**/*.ts` and `src/**/*.ts` only — tests stay free of
  the rule so type-narrowing tools remain available there.
- scripts/guard-no-suppressions.mjs ships the same pattern as a
  standalone guard against a path-aware hash baseline at
  scripts/guard-no-suppressions.baseline.json. Useful for partial CI
  lanes / file-only commits that bypass ESLint. Wired as
  `pnpm guard:no-suppressions`. Baseline starts empty — the codebase
  has zero suppression markers today.
- Studio's `no-tailwind-arbitrary-values` rule was deliberately not
  ported (no desktop-app surface here).

Decisions pinned in REMAINING-WORK.md
- Skip Turbo: `pnpm -r --filter` is sufficient for a 6-package repo.
- Skip Husky + lint-staged: CI gates already cover the same surface.
- `pnpm format` / `format:check` are verified working; a follow-up note
  records the 317 pre-existing format-drift files for a separate
  formatting sweep ahead of W4.

Verification
- `pnpm -r lint` — exit 0 across all 5 packages.
- `pnpm typecheck` — green.
- `pnpm guard:no-suppressions` — passes (0 markers, empty baseline).
- Probed ESLint rule fires on injected `eslint-disable` comment and
  standalone guard reports it as an addition; both back to green after
  cleanup.
- Tests: architect-core 1070, architect-projection 1544, architect-mcp
  170, architect-guard 37, architect-cli 17 — all pass.
…index extension

Capture the 2026-05-17 design-session outputs that close the open questions
in PROPOSED-DESIGN.md § 9. Two structural findings reshape the campaign:

1. DeepWiki-style wiki tree with a generated index is a distinct fourth
   reuse boundary on top of the existing ProjectionBundle.children +
   BundleRouting.entityPathLayout substrate. Add WikiIndexDefinition +
   projectWikiIndex as a new doc shape.

2. Every navigation surface the wiki index needs (File Map, Concept Index,
   Key Entities, Diagram Catalog, Reading Paths) is a projection over the
   existing UML/Gherkin substrate. Net taxonomy delta from the campaign is
   zero added carriers; possibly one removed under D9 follow-up.

W-DOCS-1 acceptance case becomes docs/ANNOTATION-GUIDE.md ported to a wiki
tree under docs-live/annotation-guide/ — proves the substrate end-to-end
before any doc-by-doc port.
…D4', D10–D12)

Replaces the earlier W-DOCS-1 acceptance target (ANNOTATION-GUIDE.md) with
a small self-contained PoC that generates two documents about the
wiki-doc-generation machinery itself — one skill + one wiki tree — from a
single source.

The PoC must exercise four data-source kinds: JSDoc from annotated blocks,
interface/code-snippet shapes, a small live mermaid diagram of the
generation pipeline, and a Gherkin business rule. Same content surfaces in
both targets at different INPUT disclosure depths; cross-references from
skill → wiki resolve via linkToCanonical.

Full information-duplication mapping (multi-agent pass described in
REMAINING-WORK.md) is deferred to execution waves W-DOCS-5+ (D11). The PoC
unblocks design without needing the mapping up front.

Methodology shifts to design-from-target (D12): the picked PoC artifacts
drive the plan-tier spec, not a bottom-up projection-walk spike.
…ation

Five Gherkin idea-tier specs in .pr-coordination/ideation-specs/ — one
parent epic (WikiDocGeneration) and four capability children:

  - DocSourceFidelity (no drift)
  - OneSourceMultipleAudiences (audience-shaped renderings, one source)
  - GoalOrientedNavigation (intent → page)
  - SourceCanonical (annotations + executable specs are the source)

Each spec is shaped per architect-plan-session skill: five tags, one user
story, one rule with one invariant, no scenarios, no deliverables, no
implementation choices. All files ≤17 lines (budget is 30).

Kept in .pr-coordination/ so they do not sit on any implementation path
during maintainer validation. On acceptance, files git mv to
architect/specs/ideas/ to enter the pattern graph.

IDEATION-SPECS.md is a thin index + validation marks checklist;
README.md adds it to the read order as gate 5.
Run the deferred repo-wide formatter pass before the W-DOCS-1 substrate work so later PRs do not mix mechanical Prettier churn with behavior changes.
Clarify the intentional split-document re-render, collapse logical route parsing into a narrower switch-based shape, make the perf comparator helpers read as named budget checks without losing aggregated failure reporting, and replace the remaining perf-step non-null assertions with explicit narrowing.
The lazy documentation-type registry still needs deferred initialization for sideEffects:false, but Array prototype methods already execute against the proxy correctly. Remove the extra rebinding wrapper so the facade stays lazy without carrying unnecessary trap machinery.
…ore + projection)

Fleet-annotated dark-but-load-bearing modules, raising curated PatternGraph
coverage: architect-core 36%->51% (34->48 nodes), architect-projection
64%->74% (88->102), total patterns 293->325. Added uses/implements edges +
role/bounded-context/status on real seams (ProjectionContext, ProjectionBundle,
ProjectionTrustBoundary, DomainEnumSchemas, ConfigDefaults, BrandedIdentifiers, ...).

Verified: 0 dangling (held at baseline), typecheck clean. Per-tag syntax matches
repo convention (space-form @architect-pattern/@architect-status; colon-form
@architect-role:/@architect-bounded-context:; csv @architect-uses).

4 .feature spec annotations remain dead (roadmap-target edge policy + package
feature-glob/colon-syntax gaps) -- addressed in follow-up. Findings +
baseline-corrected deltas: playground/ANNOTATION-FLEET-FINDINGS.md.
…n 2 dead specs

Round 2 annotated the next dark tier in core + projection (config, extract/
transform pipeline, taxonomy domains, validation schemas, projection support).
Graph 325->348; core coverage 51%->65% (61/94), projection 74%->80% (110/138);
0 dangling; typecheck clean.

Fixes (from round-1 findings):
- glob: scan packages/*/tests/features (self-hosting.ts) so package-local
  executable specs enter the graph -> BusinessRuleSet*/FragmentSchemaMirror*
  ExecutableTests now resolve with realization edges.
- add-lint: new 'gherkin-tag-space-form' anti-pattern flags space-form
  @architect-pattern/@architect-implements on .feature files.
- spec-syntax: colon-form repair on the 2 package-local specs.
- cleanup: removed 2 roadmap-target dead specs (live-state); realization-edge
  policy deferred to a human (documented in findings).

Two round-2 recipe bugs found + fixed at integration (silent-failure-to-zero):
missing bare @architect marker, and space-separated @architect-uses (comma
required). Logged to FEEDBACK.md.
…q/cli/smoke front doors

The handle now builds both cores fresh in-process per call (snapshot dump
deleted): buildAuthoredCore via buildCliContext(noCache) + buildMechanicalCore
tsc walk. PatternNode gains parent/children, implements/implementedBy/
enforcesDecisions; Invariant/AtRiskSpec gain the cohort honesty field and the
maturity⟺provenance coherence clamp. New front doors: q.ts (eval entry,
isatty stdin, REPO_ROOT anchor), cli.ts named demos, smoke.ts invariant
regression (asserts invariants, never frozen counts). playground:q/cli/smoke
scripts bake in --conditions=source (the staleness fix).

Claude-Session: https://claude.ai/code/session_017hfQmFkexwwqKmaAvN5WUt
…+ core utility/contract seams)

Additive @architect JSDoc headers only, zero logic change: CLIOutputAdapter,
CLIRuntimeGuards, CLIFlagSchemas, CLICommandRegistry, CLIContextTypes (the
fan-in _shared cluster the fleet findings queued), TagDirectiveRegexBuilders,
HierarchyLevelDomain, ArgvHygiene, ConfigValidationSchemas.

Claude-Session: https://claude.ai/code/session_017hfQmFkexwwqKmaAvN5WUt
The canonical on-ramp for the live graph handle (pnpm playground:q): surface
list, handle-vs-verb demand map, verified examples, freeze-vs-script principle.
Symlinked into .claude/ and .opencode/ (.codex inherits via the directory
symlink); pnpm check:skills green.

Claude-Session: https://claude.ai/code/session_017hfQmFkexwwqKmaAvN5WUt
…mand read surfaces

SessionStart hook drops the API-first contract and the live overview exec;
injects the source-first mental model + architect-base as mandatory first-load
with data-api / graph-handle / sessions as on-demand. AGENTS.md moves to the
4-skill model; kernel-bootstrap prompt mirrors it.

Claude-Session: https://claude.ai/code/session_017hfQmFkexwwqKmaAvN5WUt
The agent read surface is now the scriptable graph handle, not a verb wall.
The `architect` bin becomes the graph-handle CLI: `architect q '<js>'` evals
the caller's script against the live two-surface handle (g), named commands
are runnable documentation over it, and `dangling --baseline --strict` is the
ONE frozen machine contract (CI's graph-integrity gate — its second caller).

Graduated from playground/ into packages/architect-cli/src/handle/ under full
strict-TS + ESLint discipline (vm.Script compilation replaces new Function;
exactOptionalPropertyTypes throughout; Zod-validated flags). g.api exposes the
canonical PatternGraphAPI so every deterministic read incl. isValidTransition
stays one script away.

Deleted (No-BC): the 24-verb surface (commands/ families, query/arch
dispatchers, REPL, flag schemas), its self-referential dogfood features/steps,
the CLI-MCP parity test, the capability tour, and four dead scripts. The
runtime layer (buildCliContext), the docs generator, guard bins, and the MCP
tool surface are untouched. New executable coverage:
tests/features/cli/graph-handle.feature (q round-trips, invariant battery,
gate contract). ci:verify green end-to-end.

Claude-Session: https://claude.ai/code/session_017hfQmFkexwwqKmaAvN5WUt
…e architect-data-api

The architect-graph-handle skill is rewritten as the primary read surface
(recipes graduate into its references/); the architect-data-api skill is
deleted (its subject — the verb CLI — no longer exists). architect-base,
architect-sessions, and architect-refactor-session re-point every pre-flight
and gate at the handle (g.api reads, architect:graph dangling) or the
surviving architect_scope_validate MCP tool. SessionStart hook, AGENTS.md,
the OmO config/prompt, legacy docs/, and the package PRD boundary contracts
are re-recorded for the new shape; working-state specs re-point their planned
delivery surfaces off the retired verbs; playground/ slims to scratch home +
experiment findings with graduation banners.

Claude-Session: https://claude.ai/code/session_017hfQmFkexwwqKmaAvN5WUt
Verb-CLI patterns left the graph; the handle patterns + ADR-014 entered.

Claude-Session: https://claude.ai/code/session_017hfQmFkexwwqKmaAvN5WUt
Bidirectional per CONTEXT §9.1 — subtractive via the epic fold-down list,
additive by agent value (fan-in tail, buildCliContext, guard, boundedContext
backfill, edge-dark re-audit), plus status/spec hygiene (DRIFT push, F1 cohort
pilot, the maturity⟺provenance axis split) and the fleet-verified batch
protocol. Plan-only; execution is future sessions.

Claude-Session: https://claude.ai/code/session_017hfQmFkexwwqKmaAvN5WUt
… ADR-014 contradictions, orphans

Codex stop-time review follow-ups: delete the superseded
data-api-relationship-graph spec (its traversal/impact/path/dangling/orphans
capability shipped as the graph handle; planning frozen graph-walk commands
contradicts ADR-014) and retarget its two tracking pointers (ADR-001 Rule 6
narrative, taxonomy/source-ownership.ts). Consolidate PDR-001 in place onto
the surviving carriers (projections + architect_scope_validate /
architect_handoff MCP tools; DD-6 retired with the verb CLI). Re-point
monorepo-support / value-transfer / brief runner strings and verifiers off
nonexistent commands and the deleted data-api-help feature. Fix ADR-006's
stale pipeline-file cell, delete the orphaned cli/version.ts, add -h/-v
aliases to the architect bin, and correct the base skill's residual
verb-first phrasing.

Claude-Session: https://claude.ai/code/session_017hfQmFkexwwqKmaAvN5WUt
… records

Second review round: finish what the first pass started. The brief spec is
retargeted MCP-only end-to-end (its agent-side stitching premise is dissolved
by ADR-014; the surviving consumers are the machine sinks), model-enriched's
sibling reference and MVP boundary now name the MCP reads, value-transfer and
monorepo-support lose their last CLI-verb deliverable rows and flag-form
invariants, PDR-001's DD-2/3/4 consolidate flag language to option/input
language, the documentation-projection epic's reflexivity passages and the
read-model-reflexivity idea name the bin's command surface instead of the
retired verb schema, and the one remaining pointer to the deleted data-api
skill re-points at the graph-handle skill.

Claude-Session: https://claude.ai/code/session_017hfQmFkexwwqKmaAvN5WUt
The overview projection already emits the graph-handle READ SURFACE
banner; the executable test still expected the retired Data API copy.
Rename pattern-graph-cli-runtime/types to cli-runtime/cli-types and
drop ParsedArgs down to the three fields handle + dangling actually
pass. Delete the unused cache, empty-taxonomy-graph helper, and
--format json error envelope. Retarget PRD/ADR/test/docs copy onto
the graph-handle surface and reset FEEDBACK.md to the two still-open
non-verb items.
…faces

architect_overview still told agents to run `arch blocking`, `arch
workable`, and `documentation <type>`. Point those at
architect_arch_blocking / architect_documentation / the handle.
Also retarget MIGRATION.md's architect-bin row, the missing-baseline
diagnostic, and drop the dead generate-docs fallback helper.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant