actorFile-level imports show where curation is missing
spec:consumers.impact-graph.curation-assistPacks: pack:design-iteration-v1, pack:self-hosting-v1
Design: 7 design entries · 4 pinned declarations · 1 decision
Findings: no errors, no warnings
specs/consumers/impact-graph.curation-assist.sdp.md
No open questions and no blocking questions; implementation binding present, verifier binding present, and expected-outcome oracle none.
Gen 1 of this tool, @libar-dev/architect, derived a mechanical import graph beside its curated one and used it to show authors where curation was missing: load-bearing modules no anchor covered, coverage by package, and designed modules no code realized yet. The idea held; the build did not. It hard-coded the repository's layout into the engine, read TypeScript only, and mixed both graphs in one query handle. A review of gen 1 found that the file-level layer gave most of its curation value and that only symbol queries need a symbol identity, which the impact graph's symbol-reach child holds open, so the file-level layer stands on its own.
Intent
- An author curating anchors across a codebase, or a design pass over a large redesign.
problem- Nothing tells an author which load-bearing files no anchor covers, where anchored
usesand the code's imports disagree, or which component designs no code realizes yet, so curation gaps surface only when someone reads the code. outcome- Report from file-level imports where anchors and component designs are missing or drifting, as advice that never authors intent.
Behavior
ruleline 25 ·specs/consumers/impact-graph.curation-assist.sdp.md:25- The layer reads file-level import edges from a per-language adapter and identifies each file by its repository-relative path, so it needs no symbol identity.
ruleline 26 ·specs/consumers/impact-graph.curation-assist.sdp.md:26- Every import relationship it derives is
inferred; the imports file's schema and the recipe's external-inferred-input label carry that claim for all of them at once, so no relationship carries its own. The relationships stay apart from the curated graph: nouses,memberOf,satisfiesor delivery fact derives from them, and a query of the curated graph never reads them unless the caller asks. ruleline 27 ·specs/consumers/impact-graph.curation-assist.sdp.md:27- It reports the files with the highest import fan-in that no anchor covers, the anchored
usesedges between two components whose files share no import, the imports between two anchored components that nousesstates, and the component designs nocomponent:anchor realizes yet. ruleline 28 ·specs/consumers/impact-graph.curation-assist.sdp.md:28- Every report is advice: it refuses nothing, fails no validation and authors no anchor, and an author who agrees edits an anchor or a Spec as usual.
ruleline 29 ·specs/consumers/impact-graph.curation-assist.sdp.md:29- The engine reads no repository layout convention: source roots and module resolution come from the adapter's configuration, and a file belongs to a component only when it holds that
component:anchor or a code anchormemberOfit, never through a path pattern in the engine. ruleline 30 ·specs/consumers/impact-graph.curation-assist.sdp.md:30- The TypeScript adapter reads imports through the compiler library extraction already depends on; another language arrives as another adapter.
ruleline 31 ·specs/consumers/impact-graph.curation-assist.sdp.md:31- The adapter runs outside extraction and outside
sdp q:sdp build, given the adapter's configuration, writes the import edges togenerated/imports.json, sorted and without a timestamp, and the curation recipe reads that file through--params, so no query derives imports and no validator sees an inferred edge. ruleline 32 ·specs/consumers/impact-graph.curation-assist.sdp.md:32- The imports configuration accepts optional root-relative
excludepaths matching a file or directory subtree, refuses unknown keys, and records exclusions in its output so curation distinguishes deliberate omissions from missing input. ruleline 33 ·specs/consumers/impact-graph.curation-assist.sdp.md:33- The recipe labels the file as external inferred input and reports a file present on one side only; it states nothing in the graph's name.
ruleline 34 ·specs/consumers/impact-graph.curation-assist.sdp.md:34- The adapter follows re-exports through barrel files, so a
usesthat reaches a component through an index file counts as backed by an import. ruleline 35 ·specs/consumers/impact-graph.curation-assist.sdp.md:35- Load-bearing is a ranked list, not a threshold: the recipe reports each uncovered file's import fan-in and fan-out, takes a
limit, and leaves the cut to the caller.
11 unkeyed rules.
Design
importsFlagline 39 ·specs/consumers/impact-graph.curation-assist.sdp.md:39sdp build --imports PATHnames the adapter configuration, a JSON object{ "adapter": "typescript", "tsconfig": "tsconfig.json", "roots": ["src"], "exclude": ["src/generated"] }with root-relative paths, whereexcludeis optional and each of its paths names a file or a directory subtree, and a key outside these four is refused; without the flag the build writes no imports file and leaves an existing one untouched.no citation recorded
importsFileline 40 ·specs/consumers/impact-graph.curation-assist.sdp.md:40{ "schema": "sdp-imports/1", "adapter": "typescript", "exclude": ["src/generated"], "files": [{ "file": "src/a.ts", "imports": ["src/b.ts"] }] }ingenerated/imports.json, files and imports sorted in code-unit order, paths root-relative with POSIX separators,excluderecording the configuration's exclusions in that form and sorted, every file the adapter reads under the configured roots and outside the exclusions listed even when it imports nothing, and imports outside the roots or under an exclusion left out. The schema and the recipe'sexternal inferred inputlabel give every listed relationship theinferredclaim.no citation recorded
barrelImportsline 41 ·specs/consumers/impact-graph.curation-assist.sdp.md:41- when a file imports a barrel that re-exports another file, its
importslists the barrel and every file the barrel's re-exports reach, so the list is already the backing ausescheck reads; a barrel under an exclusion is left out of the list while the files reached through it stay. importFormsline 42 ·specs/consumers/impact-graph.curation-assist.sdp.md:42- the TypeScript adapter reads the
.ts,.cts,.mtsand.tsxfiles under the configured roots and the module references the compiler resolves in them: import and export-from declarations, type-only and side-effect imports included,import x = require(...), andimport(...)calls and import types with a literal specifier; a computed specifier and a plainrequire(...)call are not read. curationRecipeline 43 ·specs/consumers/impact-graph.curation-assist.sdp.md:43- recipe 40, the curation report, takes
params.imports, the imports file's object, andparams.limit, 20 by default, and returns{ input, totals, uncovered, usesWithoutImport, importsWithoutUses, unrealizedComponents, oneSided }. curationRowsline 44 ·specs/consumers/impact-graph.curation-assist.sdp.md:44uncoveredrows are{ file, fanIn, fanOut }for files no anchor sits in, ranked by fan-in then path and cut atlimit;usesWithoutImportrows are{ from, to, fromComponent, toComponent };importsWithoutUsesrows are{ fromComponent, toComponent, imports, sample: { from, to } };unrealizedComponentsrows are{ spec, componentId }for component designs with no resolving anchoredsatisfiesedge from the plannedcomponent:unit to the design, so an existing id without that binding stays unrealized.no citation recorded
curationInputline 45 ·specs/consumers/impact-graph.curation-assist.sdp.md:45inputis{ label: "external inferred input", schema, adapter, exclude, files }, withexcludeechoing the imports file's exclusions, andoneSidedlists anchored source files the imports file does not list and imports-file entries outside every anchored component, so a stale or partial file shows.no citation recorded
Verification
Verifier bindings
- test:protocol.curation-imports · anchored · test anchor binding present ·
test/curation-imports.test.ts:17External run evidence from
test/curation-imports.test.tsTest anchors:
test:protocol.curation-imports. Specs verified by those bindings: spec:consumers.impact-graph, spec:consumers.impact-graph.curation-assist.Run 1: external run evidence from vitest 4.1.10
Build: CI 391 · Branch: cursor/media-plan-and-articles-09b1 · Commit: 076cd4f1f85640d8236e5cca1bffffa68ab79a33 · Start: 2026-10-31T15:32:20.471Z · Stop: 2026-10-31T15:34:02.073Z
Name Suite Result Duration compares Windows source paths in the form the compiler returns them TypeScript curation imports passed 1.95 ms resolves aliases, JS specifiers, types, side effects, import equals and cyclic barrels within configured roots TypeScript curation imports passed 611.38 ms sorts paths by code unit, includes empty files, and deduplicates overlapping roots TypeScript curation imports passed 623.27 ms follows re-exports through files outside the roots but never follows ordinary transitive imports TypeScript curation imports passed 250.5 ms reads literal dynamic imports and import types, and skips computed specifiers TypeScript curation imports passed 706.19 ms excludes exact files and subtrees with segment boundaries and normalized metadata TypeScript curation imports passed 490.89 ms resolves barrel reach through excluded intermediates without emitting them TypeScript curation imports passed 239.24 ms accepts empty exclusions and normalizes root-relative exclusion spellings TypeScript curation imports passed 773.99 ms refuses invalid exclusion configuration {"extra":true} TypeScript curation imports passed 2.41 ms refuses invalid exclusion configuration {"exclude":null} TypeScript curation imports passed 1.45 ms refuses invalid exclusion configuration {"exclude":"code"} TypeScript curation imports passed 1.36 ms refuses invalid exclusion configuration {"exclude":[1]} TypeScript curation imports passed 1.27 ms refuses invalid exclusion configuration {"exclude":[""]} TypeScript curation imports passed 1.24 ms refuses invalid exclusion configuration {"exclude":[" "]} TypeScript curation imports passed 1.41 ms refuses invalid exclusion configuration {"exclude":["."]} TypeScript curation imports passed 1.39 ms refuses invalid exclusion configuration {"exclude":["./"]} TypeScript curation imports passed 1.27 ms refuses invalid exclusion configuration {"exclude":["../other"]} TypeScript curation imports passed 3.83 ms refuses invalid exclusion configuration {"exclude":["code/../../other"]} TypeScript curation imports passed 1.26 ms refuses invalid exclusion configuration {"exclude":["/code"]} TypeScript curation imports passed 1.31 ms refuses invalid exclusion configuration {"exclude":["C:/code"]} TypeScript curation imports passed 1.25 ms refuses invalid exclusion configuration {"exclude":["C:code"]} TypeScript curation imports passed 2.18 ms refuses invalid exclusion configuration {"exclude":["code\\leaf.ts"]} TypeScript curation imports passed 3.76 ms refuses invalid configuration {} TypeScript curation imports passed 3.56 ms refuses invalid configuration {"adapter":"other","tsconfig":"tsconfig.json","roots":["code"]} TypeScript curation imports passed 2.13 ms refuses invalid configuration {"adapter":"typescript","tsconfig":"tsconfig.json","roots":[]} TypeScript curation imports passed 1.27 ms refuses invalid configuration {"adapter":"typescript","tsconfig":"tsconfig.json","roots":[1]} TypeScript curation imports passed 1.22 ms refuses invalid configuration {"adapter":"typescript","tsconfig":"../tsconfig.json","roots":["code"]} TypeScript curation imports passed 1.27 ms refuses invalid configuration {"adapter":"typescript","tsconfig":"tsconfig.json","roots":["../"]} TypeScript curation imports passed 1.16 ms refuses invalid configuration {"adapter":"typescript","tsconfig":"tsconfig.json","roots":["/src"]} TypeScript curation imports passed 3.27 ms refuses the source root missing by its configured path TypeScript curation imports passed 1.56 ms refuses the source root code/leaf.ts by its configured path TypeScript curation imports passed 1.88 ms builds the imports file atomically and leaves the curated graph byte-identical TypeScript curation imports passed 942.63 ms writes no imports file without the flag and preserves an existing file even on build failure TypeScript curation imports passed 25.59 ms removes requested stale imports after a configuration or extraction failure TypeScript curation imports passed 181.56 ms refuses invalid build flag argv "build" TypeScript curation imports passed 0.19 ms refuses invalid build flag argv "build" TypeScript curation imports passed 0.09 ms refuses invalid build flag argv "build" TypeScript curation imports passed 0.05 ms refuses invalid build flag argv "build" TypeScript curation imports passed 0.04 ms refuses invalid build flag argv "validate" TypeScript curation imports passed 0.04 ms refuses invalid build flag argv "view" TypeScript curation imports passed 0.03 ms refuses invalid build flag argv "census" TypeScript curation imports passed 0.03 ms refuses invalid build flag argv "mermaid" TypeScript curation imports passed 0.03 ms refuses invalid build flag argv "gherkin" TypeScript curation imports passed 0.12 ms completes over the repository src and lists a known build-command import TypeScript curation imports passed 2250.37 ms - test:protocol.curation-recipe · anchored · test anchor binding present ·
test/curation-recipes.test.ts:44External run evidence from
test/curation-recipes.test.tsTest anchors:
test:protocol.curation-recipe,test:protocol.slimming-recipe. Specs verified by those bindings: spec:consumers.impact-graph.curation-assist, spec:model.enrichment-lifecycle.Run 1: external run evidence from vitest 4.1.10
Build: CI 391 · Branch: cursor/media-plan-and-articles-09b1 · Commit: 076cd4f1f85640d8236e5cca1bffffa68ab79a33 · Start: 2026-10-31T15:32:20.471Z · Stop: 2026-10-31T15:34:02.073Z
Name Suite Result Duration requires both facts and uses recipe 24's opening span rule, with lines and bindings slimming candidates recipe passed 8.7 ms selects only Pack members and returns no rows for a clean Pack slimming candidates recipe passed 2.5 ms distinguishes an unknown Pack from a clean existing Pack slimming candidates recipe passed 1.99 ms includes enabled example verifier bindings without claiming they realize an entry slimming candidates recipe passed 1.59 ms returns diagnostics and no rows for invalid imports input undefined curation report recipe passed 5.5 ms returns diagnostics and no rows for invalid imports input null curation report recipe passed 0.96 ms returns diagnostics and no rows for invalid imports input [] curation report recipe passed 0.61 ms returns diagnostics and no rows for invalid imports input 'imports' curation report recipe passed 0.67 ms returns diagnostics and no rows for invalid imports input {} curation report recipe passed 0.8 ms returns diagnostics and no rows for invalid imports input { schema: 'sdp-imports/2', …(2) } curation report recipe passed 0.56 ms returns diagnostics and no rows for invalid imports input { schema: 'sdp-imports/1', files: [] } curation report recipe passed 0.55 ms returns diagnostics and no rows for invalid imports input { schema: 'sdp-imports/1', …(2) } curation report recipe passed 0.54 ms returns diagnostics and no rows for invalid imports input { schema: 'sdp-imports/1', …(3) } curation report recipe passed 0.6 ms returns diagnostics and no rows for invalid imports input { schema: 'sdp-imports/1', …(3) } curation report recipe passed 0.6 ms returns diagnostics and no rows for invalid imports input { schema: 'sdp-imports/1', …(2) } curation report recipe passed 0.59 ms returns diagnostics and no rows for invalid imports input { schema: 'sdp-imports/1', …(2) } curation report recipe passed 0.52 ms returns diagnostics and no rows for invalid imports input { schema: 'sdp-imports/1', …(2) } curation report recipe passed 0.48 ms returns diagnostics and no rows for invalid limit 0 curation report recipe passed 0.51 ms returns diagnostics and no rows for invalid limit -1 curation report recipe passed 0.43 ms returns diagnostics and no rows for invalid limit 1.5 curation report recipe passed 0.53 ms returns diagnostics and no rows for invalid limit "1" curation report recipe passed 0.41 ms returns diagnostics and no rows for invalid limit null curation report recipe passed 0.41 ms returns diagnostics and no rows for invalid limit true curation report recipe passed 0.47 ms recognizes every lawful component-id segment and keeps invalid convention values out curation report recipe passed 0.73 ms echoes import exclusions without changing the supplied graph or inferring omissions curation report recipe passed 2.31 ms joins directed component pairs, ranks uncovered files and reports incomplete input and unrealized designs curation report recipe passed 1.11 ms applies the limit only to uncovered rows and counts distinct file pairs curation report recipe passed 0.92 ms aggregates file pairs for a component pair and picks the first sample in path order curation report recipe passed 0.8 ms uses code-unit order for tied ranks and samples, and defaults to twenty uncovered rows curation report recipe passed 2.17 ms keeps several component bindings in one file and ignores inferred structural edges curation report recipe passed 1.28 ms builds a small fixture imports file and supplies its object to the recipe, backing uses through a barrel curation report recipe passed 520.53 ms reports missing or malformed parameter data {} curation report recipe passed 0.62 ms reports missing or malformed parameter data {"imports":{}} curation report recipe passed 0.36 ms reports missing or malformed parameter data {"imports":{"schema":"sdp-imports/1","adapter":"typescript","files":[{"file":"code/idle.ts","imports":[]},{"file":"code/a.ts","imports":["code/index.ts","code/leaf.ts"]},{"file":"code/index.ts","imports":["code/leaf.ts"]},{"file":"code/leaf.ts","imports":["code/a.ts"]},{"file":"code/loose.ts","imports":[]}]},"limit":-1} curation report recipe passed 0.32 ms reports missing or malformed parameter data {"imports":{"schema":"sdp-imports/1","adapter":"typescript","files":[{"file":"code/idle.ts","imports":[]},{"file":"code/a.ts","imports":["code/index.ts","code/leaf.ts"]},{"file":"code/index.ts","imports":["code/leaf.ts"]},{"file":"code/leaf.ts","imports":["code/a.ts"]},{"file":"code/loose.ts","imports":[]}]},"limit":1.5} curation report recipe passed 0.28 ms
Design view
Requirement drawing
- Declared verifying examples: no declared verifying example.
The diagram as text
- spec:consumers.impact-graph.curation-assist: File-level imports show where curation is missing · declared Spec
- spec:consumers.impact-graph: Mechanical code structure stays inferred and apart from curated intent · declared Spec
- impl:protocol.build-imports: opt-in imports publication in the build command · anchored code ·
src/cli/build-command.ts:243 - impl:protocol.curation-recipe: asserts the curation report over external inferred imports · anchored code ·
test/curation-recipes.test.ts:32 - impl:protocol.typescript-imports: TypeScript file imports and barrel reach for external curation input · anchored code ·
src/adapters/typescript-imports.ts:7 - test:protocol.curation-imports: test:protocol.curation-imports · anchored test binding · binding present ·
test/curation-imports.test.ts:17 - test:protocol.curation-recipe: test:protocol.curation-recipe · anchored test binding · binding present ·
test/curation-recipes.test.ts:44 - spec:consumers.impact-graph.curation-assist refines spec:consumers.impact-graph · declared
- impl:protocol.build-imports satisfies spec:consumers.impact-graph.curation-assist · anchored
- impl:protocol.curation-recipe satisfies spec:consumers.impact-graph.curation-assist · anchored
- impl:protocol.typescript-imports satisfies spec:consumers.impact-graph.curation-assist · anchored
- test:protocol.curation-imports verifies spec:consumers.impact-graph.curation-assist · anchored
- test:protocol.curation-recipe verifies spec:consumers.impact-graph.curation-assist · anchored
Mermaid source
Copyable source; the Studio draws static SVG.
Preferred and chosen syntax: requirementDiagram; exact refines, satisfies and verifies, with claim words in nodes and per-edge comments.
Decisions
- Architectural significance is annotated where it is realized
Architectural significance is annotated on the anchor of the unit that realizes it. A code anchor may carry
role, the architectural pattern the unit plays; acomponent:anchor may additionally carrylayer, one ofedge,application,domain,adapter, orinfrastructure, andcontext, its bounded context. Thecomponent:anchor is anchored architecture: it is the declared component, and there is no separate architecture file, because the anchor sits where the component is realized. It is not the original design's declared Component that could exist before code; an unrealized component lives in Specs and never as an invented CodeNode. A role is a free, corpus-owned vocabulary whose taxonomy the census renders with counts from the graph;service,decider,projection,read-model,codec,contract,barrel, andutilityare the lineage set, not a closed list.layeris a closed set, and a value outside it is an envelope error;layerorcontexton a non-component anchor is an envelope error. All three attributes are optional, and omission is lawful.
Runtime
component:protocol.adapters· external runtime and source adapters ·src/adapters/vitest.ts:23· layer adapter · context protocol Uses
component:protocol.runner· provider-neutral example execution ·src/runner/index.ts:99· layer application · context protocol
component:protocol.cli· entry points, shared build and publication ·src/cli/build-command.ts:32· layer edge · context protocol Uses
component:protocol.adapters· external runtime and source adapters ·src/adapters/vitest.ts:23· layer adapter · context protocol component:protocol.codegen· contracts and registrar output ·src/codegen/contracts.ts:633· layer application · context protocol component:protocol.extract· the carrier and source pipeline ·src/extract/index.ts:192· layer application · context protocol component:protocol.graph· the one graph and its semantic decisions ·src/graph/schema.ts:34· layer domain · context protocol component:protocol.import· canonical conversion with a fidelity boundary ·src/import/import.ts:45· layer application · context protocol component:protocol.model· the authored contracts and stable ids ·src/model/anchors.ts:100· layer domain · context protocol component:protocol.projections· read-only output, layout and owned publication ·src/projections/design-review.ts:29· layer edge · context protocol component:protocol.reader· the typed graph contract and body evaluator ·src/reader/reader.ts:671· layer application · context protocol component:protocol.validate· one finding currency and ordered checks ·src/validate/validators.ts:72· layer domain · context protocol
impl:protocol.build-imports· opt-in imports publication in the build command ·src/cli/build-command.ts:243Component:
component:protocol.cli· entry points, shared build and publication ·src/cli/build-command.ts:32· layer edge · context protocol Uses
None.
impl:protocol.curation-recipe· asserts the curation report over external inferred imports ·test/curation-recipes.test.ts:32Uses
None.
impl:protocol.typescript-imports· TypeScript file imports and barrel reach for external curation input ·src/adapters/typescript-imports.ts:7Component:
component:protocol.adapters· external runtime and source adapters ·src/adapters/vitest.ts:23· layer adapter · context protocol Uses
None.
Runtime observation: not tracked.
Evidence
Runtime observation: not tracked.
Build attestations: not tracked.
Deployments: not tracked.
Bills of materials: not tracked.
Impact
The diagram as text
- spec:consumers.impact-graph: Mechanical code structure stays inferred and apart from curated intent
- spec:consumers.impact-graph.curation-assist: File-level imports show where curation is missing
- spec:decisions.architectural-annotation: Architectural significance is annotated where it is realized
- spec:model.planned-architecture: Components are designed ahead of their code
- spec:consumers.impact-graph.curation-assist decidedBy spec:decisions.architectural-annotation · declared
- spec:consumers.impact-graph.curation-assist dependsOn spec:model.planned-architecture · declared — the report uses the component-design convention to identify unrealized planned components
- spec:consumers.impact-graph.curation-assist refines spec:consumers.impact-graph · declared
Mermaid source
Copyable source; the Studio draws static SVG.
Preferred syntax: flowchart. Chosen syntax: labelled flowchart, preserving exact relations, claims and folds.
Rests on
- refines · spec:consumers.impact-graph · stated ready, floor ready
- dependsOn · spec:model.planned-architecture · stated ready, floor ready
- decidedBy · spec:decisions.architectural-annotation · stated ready, floor ready
Rested on by
No Spec rests on this Spec.
Relations
| Relation and direction | Other end | Claim | Reason | Exercised keys |
|---|---|---|---|---|
| decidedBy · outgoing | Architectural significance is annotated where it is realizedspec:decisions.architectural-annotation · resolves | declared | None | None |
| dependsOn · outgoing | Components are designed ahead of their codespec:model.planned-architecture · resolves | declared | the report uses the component-design convention to identify unrealized planned components | None |
| refines · outgoing | Mechanical code structure stays inferred and apart from curated intentspec:consumers.impact-graph · resolves | declared | None | None |
Bindings
Implementation binding: present
impl:protocol.build-imports· opt-in imports publication in the build command ·src/cli/build-command.ts:243· role publisher · component component:protocol.cli· layer edge · context protocolimpl:protocol.curation-recipe· asserts the curation report over external inferred imports ·test/curation-recipes.test.ts:32impl:protocol.typescript-imports· TypeScript file imports and barrel reach for external curation input ·src/adapters/typescript-imports.ts:7· role adapter · component component:protocol.adapters· layer adapter · context protocol
Design reference: none
Verifier binding: present
- test:protocol.curation-imports · anchored ·
test/curation-imports.test.ts:17· test anchor - test:protocol.curation-recipe · anchored ·
test/curation-recipes.test.ts:44· test anchor
Expected-outcome oracle: none
Runtime observation: not tracked.
Run results: not recorded in the graph.
Findings
None.
Composing (0)
Composing needs the script.