Skip to content

Adopter round 2: Pack order, question keys, the next rung, recipes 25 and 26, and the Studio captured ahead of its code - #28

Merged
darko-mijic merged 18 commits into
mainfrom
feature/adopter-round-2
Oct 10, 2026
Merged

darko-mijic merged 18 commits into
mainfrom
feature/adopter-round-2

Conversation

@darko-mijic

@darko-mijic darko-mijic commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

The second round from the first adopter, libar-dev/libar-platform. Its own pages and checks had to work around five things the Protocol did not give. This round gives them, and shows them on the Protocol's own design: a slice of the original design, captured as Specs ahead of their code.

What the owner ruled

  • Ratified spec:decisions.authored-entry-order ("Ratify now"). It states ready and supersedes the shipped-projections freeze for open-section rendering.
  • A Pack's member order ("Members list on Pack node"). The Pack node carries an ordered members list, and edges keep the global sort.
  • An open question's key ("Key in the marker"): [blocking #aggregateReach], addressed as spec:<id>#question.aggregateReach.
  • The key on the page ("Show the key"): a new decision record, spec:decisions.question-key-rendering, ratified.
  • A slice of the original design in this PR ("Studio review workbench"), captured as structured Specs whose patterns point at the code that realizes them, not as a prose retelling.

The rest are design rulings, recorded in plan 39's round-2 section.

What changed

Spec (states defined, derives ready unless noted) What it does
spec:decisions.authored-entry-order (ready) The Design Review renders each design and ui entry as a list item in authored order, its key as inline code. A structured value keeps a nested JSON fence.
spec:extraction.pack-member-order A Pack node carries its manifest's members in authored order. packContext and the Pack page follow it. Graph schema 0.7.0.
spec:model.open-question-keys An optional key in the marker in both carriers, unique per Spec. The entry address gains a question section. Prose mentions check it, and the importer writes it.
spec:decisions.question-key-rendering (ready) A keyed question's item opens with #<key> on its Spec page.
spec:validation.next-rung-floor evaluateReadinessFloor takes a target rung. SpecContext.nextRungFailures holds the unmet clauses of the rung above the floor. A typed-dependency failure names its targets, and recipe 9 reports them.
spec:consumers.agent-surface.address-and-cycle-recipes Recipe 25 resolves entry addresses in a batch. Recipe 26 reports dependsOn cycles, each with one cycle through it. Recipes 20, 22 and 23 learn the key. The catalog has 26 recipes.

The original design, captured ahead of its code

pack:spec-studio-v1 holds twelve Specs at scoped, in reading order. They capture chapter 07's sections 1 to 3, 11 and 12 of docs/lineage/v0-design/: why HTML, the four lenses, the Spec page and its panels, the custom elements, the phone layout and sharing.

  • Every claim has a home. It is a rule, a ui or design entry, an example space, or a keyed open question.
  • Where a ruled record departs from the original, the entry follows the record and a keyed question keeps the original's claim whole. There are 25 such questions, 3 of them blocking. The root Spec carries two more blocking questions that are not departures, #packageHome and #unservedReader, so the Pack holds 27 keyed questions, 5 of them blocking. Examples: the patch loop against spec:consumers.edit-model, HTML first against the Markdown Design Review, and seven rungs against four.
  • The reader shows the round at work. The Pack reads back in authored order. Four members are held at scoped by blocking questions, and eight reach defined. The reader names the dependencies that hold each one below ready.

The claim map as evidence. An Opus agent mapped each of the slice's 81 claims to the code anchor and file that realize it: 5 realized, 25 in part, 25 not built, 25 departed, 1 placed later. It found them by reading the code for shapes that resemble each claim. With every pattern of the design annotated in the code that realizes it, that map would be a projection of the graph, not a reading. Two ruled records, spec:decisions.architectural-significance-rides-primitives and spec:decisions.jsdoc-graph-extraction-refused, rule otherwise. The owner contests their account of the first generation's annotations, which the owner holds to be the approach's strongest value. The rulings stand for this round, and the map is the evidence for a later decision. That decision is now made: the annotations arc, stacked on this PR as #29, admits anchors in doc comments, references from code to a design, and role, layer and context on anchors, and the map becomes recipe 27 over the Studio Pack.

How it was built and checked

  • Spec text first: the Spec text was written and ruled first (ab024d0).
  • Six packages, each with its own suites and mutations, two of them in parallel lanes.
  • An integrator re-derived the self-hosting pins: 225 Specs, 2 Packs, 233 anchors, 460 nodes, 1,055 edges.
  • The whole npm run check passes.
  • One review at the arc level ran the branch against 5e29c03 on a frozen copy that carried one planted defect, and caught it. It found eight real defects, folded in by 644a70f. Its standing queries show no silent loss: recipe 2's drift alarm grows from 12 to 16 by exactly the four new implemented Specs, and recipe 8 keeps its 13 warnings.

For the owner

  • The annotation scout, docs/lineage/annotation-scout-2026-10-04.md: a read-only research report for the decision on annotations in code. It covers gen 1's tag inventory and formal registry, how its docs come from one graph, and what its history shows drifted. It quotes this repository's two refusals as written, and traces the type-safe annotation concept up to the original design's chapters 01 to 05. It closes with a candidate smallest annotation set. It is dated evidence, kept in the repository for a while at the owner's request.
  • ready statements: on the four implemented Specs and their examples, which the drift alarm lists.
  • Terms CONTEXT.md lacks: question key, next rung, target rung, dependency cycle; and, from the Studio slice, Spec Studio, lens, panel, shell, custom element, gathered intent, hand-off, build stamp, hosted preview, harness.
  • The 25 departures of the Studio Pack, each a keyed open question.
  • Two existing failures this round did not cause: check-carrier-rule.mjs and check-carrier-truth.mjs fail identically at 5e29c03. Neither is a package.json gate.

Review repairs (2026-10-10)

An external review of the open PRs raised three findings on this branch. Each was confirmed against the source and fixed before any merge. A second, independent read of the repairs (gpt-6-astra) then narrowed one of them and corrected a count in this description.

  • F1, an invalid open-question key dropped the whole array. The intent section's arrays were strict, so an openQuestions element with a non-static key (null, an identifier, a function, a template with substitutions) failed reification, the whole openQuestions property dropped with one non-static-section warning, a blocking sibling went with it, and readiness derived ready. reifyOpenQuestions now strips that key alone and reports it with the extract/unrecognized-property error at the key's line, so the question and its siblings survive and readiness derives scoped. spec:model.open-question-keys already promised this, so the Spec and the oracle are unchanged. Commit 294f9e7.
  • F3, a Pack's members list and its belongsTo edges could disagree. packContext read Pack.members while specContext and the impact queries followed the edges, and checkPackMembers reported only a repeated member, so a skewed graph answered differently per query with no finding. The validator now requires every listed member to carry exactly one belongsTo edge into the Pack and every such edge to name a listed member, names a listed member that is no Spec by its node kind only where no other check already reports it, and keeps authored order and the duplicate rule. spec:validation.pack-coherence gains the rule, and the oracle follows. Commit f4b4a33. The astra read found the edge-side pass still naming an unlisted edge whose source is absent or no Spec, a second finding beside referential integrity's or the edge contract's; the pass now defers such a source, as the Spec already said, and two tests pin each deferral. Commit 6b96885.
  • F8, recipe 26 recursed. Its connect was a recursive Tarjan, so a dependency chain of a few thousand Specs overflowed the stack. The body now walks an explicit frame stack with the same sets, order and cycleThrough output, and a probe in the recipe suite runs it as written over a 10,000-Spec chain and a 5,000-Spec ring. The carrying Spec, spec:consumers.agent-surface.address-and-cycle-recipes, names the output and not the walk, so it is unchanged. Commit 9d809e5.

Re-measured at 6b96885, after the three repairs and the astra fold, and unchanged: the self-hosting pins stand at 225 Specs, 2 Packs, 233 anchors, 460 nodes, 1,055 edges; recipe 2's drift alarm lists 16; recipe 8 keeps its 13 warnings; the catalog holds 26 recipes. npm run check passes.

🤖 Generated with Claude Code

darko-mijic and others added 13 commits October 4, 2026 04:10
The owner ratified spec:decisions.authored-entry-order on 2026-10-04 ("Ratify
now"): it states ready, supersedes the shipped-projections freeze for
open-section rendering, and keeps its decision text. The owner also ruled the
model of two changes ("Members list on Pack node"; "Key in the marker"), and
the rest are design rulings recorded in plan 39's new round:

- spec:extraction.pack-member-order: a Pack node carries its manifest's
  members in authored order; edges keep the global sort; schema 0.7.0.
- spec:model.open-question-keys: an optional key in the open question's
  marker, `[blocking #key]`, addressed as spec:<id>#question.<key>;
  spec:decisions.checked-mentions admits the question section.
- spec:validation.next-rung-floor: the floor evaluator answers for a target
  rung, the reader carries the next rung's unmet clauses, and a
  typed-dependency failure names its targets.
- spec:consumers.agent-surface.address-and-cycle-recipes: recipe 25 resolves
  entry addresses in a batch; recipe 26 reports dependsOn cycles.

The new Specs state defined and derive ready; no other rung moved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…order

Builds spec:decisions.authored-entry-order. The Design Review prints each
entry of a design or ui section as a list item, its key as inline code: a
string as escaped prose with further lines indented, a number, boolean or
null as inline code, and an array or object as a fenced JSON block nested
under its item. Byte tests cover each value case; swapping two entries or
dropping the key's code span fails them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed dependency's targets

Builds spec:validation.next-rung-floor. evaluateReadinessFloor takes an
optional target rung; the reader's SpecContext carries nextRungFailures, the
unmet clauses of the rung above the derived floor; a typed-dependency
failure lists the targets that break it, each with its type and stated rung.
Recipe 9 reports the next rung's unmet clauses and its first one. The
honesty/readiness-floor message does not change.

The parent sentences of readiness-floor, typed-dependency-floor and
authoring-recipes move with the change. The two examples state every
condition their test worlds set up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… graph

Builds spec:extraction.pack-member-order, by the owner's ruling of
2026-10-04 ("Members list on Pack node"). A Pack node carries its
manifest's members in authored order, repeats kept, and the belongsTo edges
keep the global edge sort. The reader's packContext and the Design Review's
Pack page follow the list, so a Pack written in reading order reads in that
order. An open question's optional key joins the graph's types and canonical
serialization. The graph schema moves to 0.7.0, one bump for both.

The parent sentences of derive-graph, design-review and reader move with the
change; the declared-version example states 0.7.0; the checkout goldens
regenerate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he import marker

Builds the carrier half of spec:model.open-question-keys. The Markdown marker
reads `[blocking #key]` and `[non-blocking #key]`; a key off the Design key
grammar or one an earlier question of the Spec carries refuses the carrier as
extract/invalid-markdown-structure, with "open question keys must be
lower-camel ASCII" or "open question keys must be unique". The TypeScript
carrier admits `key` on intent.openQuestions[] and drops a bad or repeated key
alone with an extract/unrecognized-property error, keeping the question and
the Spec. The import emitter writes a keyed question's marker as
`[<flag> #<key>]`. impl:protocol.open-question-keys binds the Spec at the
Markdown marker.

The body-grammar sentence on open-question markers moves with the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s open question keys

Builds the address half of spec:model.open-question-keys. ENTRY_ADDRESS_SECTIONS
is exported with design, ui and question, and a sub-part outside them is
refused with "entry address must be <section>.<key> with section design, ui,
or question". hasAddressedEntry resolves `spec:<id>#question.<key>` when an
open question of the Spec carries the key, where description is an ordinary
key; a renamed or removed key is the missing-entry error, whose message does
not change.

test:protocol.open-question-keys.* binds the three examples on Markdown worlds
in a temporary root. The keyed-question example now states every condition
its world sets up. The prose-mentions sentence and the stable-ids bound point
move with the change; the package smoke test pins the new root export.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds spec:decisions.question-key-rendering from R7 of the round's rulings,
stating ready on the owner's "Show the key" (2026-10-04): it refines the
Design Review, depends on spec:model.open-question-keys, supersedes the
shipped-projections freeze for this one rendering, and joins the self-hosting
Pack after the round's other Specs. A keyed question's item now opens with
`#<key>` as inline code before its escaped text; an unkeyed one renders as
before. The checkout-v1 goldens hold no keyed question and do not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…head of their code

The owner asked for a representative slice of the original design
(docs/lineage/v0-design/) captured as Specs ahead of their code, to show
this round's changes on the Protocol's own design: "That was more of FYI,
but it is actually a pefect case what to showcase in this PR". The slice is
chapter 07's sections 1 to 3, 11 and 12, the Studio review workbench.

pack:spec-studio-v1 lists twelve members in reading order, each stated
scoped and none anchored: the Studio's boundaries, why HTML, its data, the
shell, the four lenses, the Spec page and its panels, the intent panel, the
custom elements and why no framework, the phone layout, and sharing. Each
original claim has a home: a rule, a ui or design entry, an example space,
or, where a ruled record goes another way (the patch loop, HTML first, seven
rungs), an entry that follows the record and a keyed open question that
keeps the original's claim whole. Twenty-five questions, five blocking. A
member's code is reached through the realized Spec it relates to; the
claim-by-claim map to code anchors is in the pull request.

Read back: four members stop at scoped on their blocking questions; eight
reach defined, held below ready by the typed-dependency clause, with the
dependencies that hold each one named by the reader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on key

Builds spec:consumers.agent-surface.address-and-cycle-recipes. Recipe 25
resolves a list of entry addresses in one pass, a row per address with the
Spec, section and key, or the reason it does not resolve (malformed, spec,
entry). Recipe 26 reports every dependsOn strongly connected set and every
Spec that depends on itself, each with one cycle through it. Recipe 20
returns an open question's key; recipes 22 and 23 recognize the question
section of an entry address. The catalog grows to twenty-six, and every
count, the agent-surface, authoring and sessions skills, and the
register-recipes sentences move with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The self-hosting oracle follows the graph after the round's six packages and
the Studio Pack: 225 Specs, 2 Packs, 233 anchors, 460 nodes, 1,055 edges,
readiness {defined 58, idea 4, ready 150, scoped 13}, schema 0.7.0, the
twelve Studio members in the self-hosting Pack, and nine new
contract-dependent suites and registrars. Two anchor blocks move back
within their locality bound, with no executable change, and a Spec
rationale drops the date the temporal check refuses; plan 39 keeps it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review (gpt-6-astra at xhigh on a frozen copy with one planted defect,
caught) found these, each ruled by the main thread:

- The import emitter writes an omitted blocking flag as non-blocking, so a
  keyed TypeScript question without the flag imports.
- spec:extraction.pack-member-order keeps a repeated member only where the
  carrier admits one: the TypeScript carrier keeps it, the Markdown carrier
  refuses it.
- New tests: the authoring skill's taught marker extracts and resolves;
  recipe 25 refuses an inherited key; recipe 26 picks the specified cycle on
  a tie; the keyed-question example asserts whole question objects.
- The Studio Specs give the rail's harnesses, the Stories half of UI /
  Stories, the seven rung colours and the runtime binding patterns their
  homes, and the Pack's framing names the members with no realized
  neighbour yet.
- Plan 39 states what is now true of the round.

Work in progress at a seam: the whole gate runs next.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… matcher

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 109 files, which is 9 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 28e5025b-353a-4e74-a07b-e94a394e87df

📥 Commits

Reviewing files that changed from the base of the PR and between 5e29c03 and 6b96885.


⛔ Files ignored due to path filters (6)
  • test/extraction.pack-member-order.manifest-order-kept.test.generated.ts is excluded by !**/*.generated.*
  • test/model.open-question-keys.keyed-question-resolves.test.generated.ts is excluded by !**/*.generated.*
  • test/model.open-question-keys.renamed-key-breaks.test.generated.ts is excluded by !**/*.generated.*
  • test/model.open-question-keys.repeated-key-refused.test.generated.ts is excluded by !**/*.generated.*
  • test/validation.next-rung-floor.blocking-question.test.generated.ts is excluded by !**/*.generated.*
  • test/validation.next-rung-floor.typed-dependency-targets.test.generated.ts is excluded by !**/*.generated.*

📒 Files selected for processing (109)
  • .agents/skills/sdp-agent-surface/SKILL.md
  • .agents/skills/sdp-authoring/SKILL.md
  • .agents/skills/sdp-sessions/SKILL.md
  • AGENTS.md
  • CONTEXT.md
  • README.md
  • check-prose-schema.mjs
  • contract-dependent-suites.mjs
  • docs/agent-surface/recipes.md
  • docs/concept/06-consumers-and-projections.md
  • docs/lineage/annotation-scout-2026-10-04.md
  • plans/39-adopter-driven-hardening.md
  • specs/carrier/markdown-body-grammar.sdp.md
  • specs/consumers/agent-surface.address-and-cycle-recipes.sdp.md
  • specs/consumers/agent-surface.authoring-recipes.sdp.md
  • specs/consumers/agent-surface.register-recipes.sdp.md
  • specs/consumers/design-review.sdp.md
  • specs/consumers/reader.sdp.gherkin
  • specs/consumers/spec-studio.components.sdp.md
  • specs/consumers/spec-studio.data.sdp.md
  • specs/consumers/spec-studio.intent-panel.sdp.md
  • specs/consumers/spec-studio.lenses.sdp.md
  • specs/consumers/spec-studio.pack.sdp.md
  • specs/consumers/spec-studio.responsive.sdp.md
  • specs/consumers/spec-studio.sdp.md
  • specs/consumers/spec-studio.sharing.sdp.md
  • specs/consumers/spec-studio.shell.sdp.md
  • specs/consumers/spec-studio.spec-page.sdp.md
  • specs/consumers/spec-studio.verification-panels.sdp.md
  • specs/decisions/authored-entry-order.sdp.md
  • specs/decisions/checked-mentions.sdp.md
  • specs/decisions/question-key-rendering.sdp.md
  • specs/decisions/studio-html-surface.sdp.md
  • specs/decisions/studio-web-components.sdp.md
  • specs/extraction/derive-graph.sdp.md
  • specs/extraction/open-section-order.sdp.md
  • specs/extraction/pack-member-order.manifest-order-kept.sdp.md
  • specs/extraction/pack-member-order.sdp.md
  • specs/extraction/schema-versioning.declared-version.sdp.md
  • specs/model/open-question-keys.keyed-question-resolves.sdp.md
  • specs/model/open-question-keys.renamed-key-breaks.sdp.md
  • specs/model/open-question-keys.repeated-key-refused.sdp.md
  • specs/model/open-question-keys.sdp.md
  • specs/model/stable-ids.unsectioned-address-refused.sdp.md
  • specs/self-hosting.pack.sdp.md
  • specs/validation/next-rung-floor.blocking-question.sdp.md
  • specs/validation/next-rung-floor.sdp.md
  • specs/validation/next-rung-floor.typed-dependency-targets.sdp.md
  • specs/validation/pack-coherence.sdp.md
  • specs/validation/prose-mentions.sdp.md
  • specs/validation/readiness-floor.sdp.md
  • specs/validation/typed-dependency-floor.sdp.md
  • src/extract/derive.ts
  • src/extract/markdown-body-owner-behavior.ts
  • src/extract/reify.ts
  • src/extract/serialize.ts
  • src/graph/schema.ts
  • src/ids.ts
  • src/import/emit-markdown.ts
  • src/import/markdown-fidelity.ts
  • src/model/sections.ts
  • src/projections/design-review-markdown.ts
  • src/projections/design-review-section-content.ts
  • src/projections/design-review-sections.ts
  • src/reader/reader.ts
  • src/validate/readiness-floor.ts
  • src/validate/validators.ts
  • test/builders.typecheck.ts
  • test/checkout-v1.test.ts
  • test/design-review-question-keys.test.ts
  • test/design-review-review-08.test.ts
  • test/design-review.test.ts
  • test/extract.test.ts
  • test/fixtures/checkout-v1/expected-census/index.md
  • test/fixtures/checkout-v1/expected-design-review/index.md
  • test/fixtures/checkout-v1/expected-design-review/pack/checkout-v1.md
  • test/fixtures/checkout-v1/expected-graph.json
  • test/gherkin-view.test.ts
  • test/graph-schema.test.ts
  • test/ids.test.ts
  • test/import-emit-markdown.test.ts
  • test/import.test.ts
  • test/markdown-reifier.test.ts
  • test/mermaid-render.test.ts
  • test/package-smoke.test.ts
  • test/reader.test.ts
  • test/reader.typecheck.ts
  • test/readiness.test.ts
  • test/readiness.typecheck.ts
  • test/recipes.test.ts
  • test/self-hosting-graph.test.ts
  • test/self-hosting-next-rung-floor.test.ts
  • test/self-hosting-open-question-keys.test.ts
  • test/self-hosting-oracle/anchors.ts
  • test/self-hosting-oracle/carrier.ts
  • test/self-hosting-oracle/consumers.ts
  • test/self-hosting-oracle/decisions.ts
  • test/self-hosting-oracle/declared-relations.ts
  • test/self-hosting-oracle/extraction.ts
  • test/self-hosting-oracle/index.ts
  • test/self-hosting-oracle/model.ts
  • test/self-hosting-oracle/pack-members.ts
  • test/self-hosting-oracle/structural-edges.ts
  • test/self-hosting-oracle/validation.ts
  • test/self-hosting-pack-member-order.test.ts
  • test/self-hosting-typed-dependency.test.ts
  • test/self-hosting-validators.test.ts
  • test/skills.test.ts
  • test/validators.test.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread src/extract/reify.ts
Comment on lines +1529 to +1530
if (name === "intent") {
checkOpenQuestionKeys(inner, sanitized.value, file, subjectId, findings);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Invalid key drops questions

When a TypeScript carrier uses an open-question key such as key: null, section reification drops the entire openQuestions array before the key check runs. It emits a warning instead of a key-specific error and removes valid sibling questions. A blocking question can disappear, advancing readiness from scoped to ready. This must be fixed before merging.

Knowledge Base Used: Authoring and extraction

Artifacts

Evidence from the check

  • The authored test supplies valid-key and null-key carriers and asserts extraction and readiness behavior, making the expected comparison reproducible.

Evidence from the check

  • The authored configuration limits execution to the regression test, keeping validation on the affected path.

Command output from the check

  • The executed baseline retains both questions and reports `scoped` readiness, establishing the comparison condition.

Command output from the check

  • The executed null-key case warns instead of reporting a key-specific error, loses both questions, and reaches `ready`, confirming the defect.

View artifacts

T-Rex Ran code and verified through T-Rex

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 294f9e7 (merged into #29 at 0ae4400): reifyOpenQuestions strips a non-static key alone and reports it with the extract/unrecognized-property error at the key's line, so the question, its siblings and the derived readiness survive.

Comment thread src/reader/reader.ts
.filter((edge) => edge.type === "belongsTo")
.map((edge): PackMemberSummary => {
const member = index.primitivesById.get(edge.from);
const members = node.members.map((memberId): PackMemberSummary => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Pack queries disagree

If a supplied graph's Pack members list differs from its belongsTo edges, packContext shows the list while spec context and impact queries follow the edges. Graph validation does not report the mismatch. This non-blocking concern leaves readers with contradictory membership and impact results and no diagnostic explaining them.

Knowledge Base Used:

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Artifacts

Evidence from the check

  • This script supplies the disagreeing graph and invokes the exported reader and validator contracts; it is the command source used for both captures.

Command output from the check

  • Running the script against built origin/main shows the pack query following the edge and validation reporting no membership disagreement.

Command output from the check

  • Running the same script against built PR HEAD shows the pack query following the list while the other queries follow the edge, with no membership-disagreement finding.

View artifacts

T-Rex Ran code and verified through T-Rex

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in f4b4a33 (merged into #29 at 0ae4400): checkPackMembers now requires every listed member to carry exactly one belongsTo edge and every such edge to name a listed member, so packContext, specContext and the impact queries can no longer disagree without a finding; spec:validation.pack-coherence carries the rule.

…n and today

A read-only research report written for the owner's decision on
annotations in code: gen 1's tag inventory and formal registry, how its
docs are generated from one graph, what its history shows drifted and why,
the operative sentences of this repository's two refusals, the progression
of the type-safe annotation concept to the original design's chapters 01 to
05, and a candidate smallest annotation set mapped onto those chapters. It
is dated evidence beside the original design, not current truth.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
darko-mijic and others added 4 commits October 10, 2026 11:18
The intent section reified `openQuestions` through the strict array rule, so a
question whose `key` was not static (`null`, `undefined`, an identifier, a
function, a template with a substitution) dropped the whole array with one
non-static-section warning. The key check never ran, every question was lost,
and readiness derived past a blocking question.

`reifyOpenQuestions` now reifies that one array so a non-static `key` reifies
to a marker the key check refuses at the key's line, with the same
`extract/unrecognized-property` error a static key off the grammar gets. Only
the key drops; the question and its siblings stay. Every other property keeps
the strict array rule. The Markdown carrier parses keys from the marker and is
unaffected. The carrying Spec, `spec:model.open-question-keys`, already
promised this; its text and oracle row do not change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`packContext` reads `Pack.members`; a Spec's `packs` and blast radius follow
the `belongsTo` edges. The pack-coherence check reported only a member listed
twice, so a supplied graph with one member in the list and another on an edge
answered membership differently per query with no finding.

`checkPackMembers` now holds the two readings to one manifest: every listed
member has one belongsTo edge into the Pack (none is an error, and a listed
member that is no Spec and no edge carries is named by kind), and every edge
comes from a listed member (an unlisted source is an error). Findings keep
authored order; the duplicate rule stays and counts the list or the edges,
whichever repeats. An edge whose source is absent or no Spec stays referential
integrity's or the edge contract's finding. `spec:validation.pack-coherence`
gains the rule, with its oracle row and the anchor label re-synced. The
self-hosting validate stays at 0 errors and 13 warnings, the example at 0 and 0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The dependency-cycles recipe found its strongly connected sets with a
recursive `connect`, so a `dependsOn` chain of 5,000 Specs overflowed the
call stack. The walk now keeps its own frame stack (an explicit-stack Tarjan)
and emits the same sets, in the same order, with the same `cycleThrough`
paths and totals; the existing oracle checks hold unchanged. The recipe suite
gains a probe that runs the body as written against a synthetic graph built
in memory: an acyclic chain of 10,000 Specs reports no cycle, and one ring of
5,000 reports one set with a closed path of 5,001 ids. The carrying Spec,
`spec:consumers.agent-surface.address-and-cycle-recipes`, names the output
and not the walk, so it does not change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… is not a second finding

`checkPackMembers` named every belongsTo edge whose source the members
list omits, so an edge from an absent node or from a CodeNode drew a
pack-coherence error beside the referential-integrity or edge-contract
finding that already names it. `spec:validation.pack-coherence` rules
that such an edge stays the other check's finding, never a second one
here; the edge-side pass now defers an absent or non-Spec source, and
two tests pin each deferral. The Spec and the oracle are unchanged: the
code moves to the Spec. Found by an independent read of the repairs
(gpt-6-astra).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@darko-mijic
darko-mijic merged commit 415b095 into main Oct 10, 2026
3 checks passed
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