Skip to content

docs(openspec): no demo findings, and the signature's version states its coverage - #247

Merged
thecodedrift merged 4 commits into
mainfrom
openspec/signature-coverage-and-no-findings
Sep 2, 2026
Merged

docs(openspec): no demo findings, and the signature's version states its coverage#247
thecodedrift merged 4 commits into
mainfrom
openspec/signature-coverage-and-no-findings

Conversation

@thecodedrift

@thecodedrift thecodedrift commented Sep 2, 2026

Copy link
Copy Markdown
Member

Two docs-only changes, both fallout from the same round with the generator team. No source changes; every path is under openspec/.

1. There are no demo findings (runtime-demo-path)

The generator team withdrew the demonstration findings across three of their own rounds. Their argument settles it: the verification gate already refuses a rule whose fixture asymmetry does not hold, so a rule that reaches delivery has necessarily flagged the failing example and ignored the passing one. Findings served alongside would be a constant implied by delivery — a field whose content a reader could infer from having received a rule at all.

D6 becomes that withdrawal rather than disappearing, because the reasoning is worth keeping. Our wrapper was aimed at a real case — a flat list renders identically for a rule that catches the bad examples and one that fires on everything — and it was the right fix to the wrong problem: that case is answered upstream of the payload, not in it.

What survives is the concern, relocated. With nothing served beside the rule, running it is the demonstration. And taskless test currently reports a runtime rule as with "1 rule(s) tested" and exit 0 when its fixtures never ran (ran: false exists only in --json; the human renderer never reads it). Task 1.6 is now blocked on that rather than on a render.

Item Before After
D6 the findings wire shape the withdrawal, and where the concern went
spec requirement "shows what the rule found, per example" "serves the rule and nothing beside it"
task 0.4 tell the service the shape we want void, not done — no shape left to agree
tasks 1.7 / 4.4 / 4.5 assert the served asymmetry one task: consume it as an ordinary delivery

2. The signature's version states its coverage (new change)

The envelope is self-describing about how a signature was computed and silent about what it is over. Which file a rule's signature covers was agreed between the two teams and written down in neither specification.

That gap surfaced as a proposal to move signature from the rule onto each file, because "nothing in the payload says which file the signature covers". The observation was right; the remedy was not. Coverage is a property of the signature scheme rather than of a delivery, so it belongs on the version rather than distributed across the collection. The proposal was declined, and this is what we owe instead — it also answers what the proposal was reaching for, since a new algoVersion is already the mechanism for changing what a signature means.

Verified rather than asserted:

  • It generalises. ENGINE_LAYOUTS gives every engine exactly one ruleFile<id>.yml for sg and vale, check.ts for runtime — so this is stated at the engine level rather than special-casing runtime.
  • No source change is implied. ALGO_VERSION is 1 (rule-hash.ts:14), signRuleFile hashes one path (rule-hash.ts:116), run-set.ts:41 signs rule.checkFile once per rule.
  • It matches the service, not our preference. The generator team's own status records "a v1 signature covers the engine's ruleFile, multi-file signing would be v2" as settled.

Checks

openspec validate --changes --strict passes on all three changes. pnpm cli check reports only the 4 pre-existing no-hedging warnings (3 route.txt, 1 onboard.txt).

@thecodedrift

Copy link
Copy Markdown
Member Author

@claude /review

@claude

claude Bot commented Sep 2, 2026

Copy link
Copy Markdown

Claude finished @thecodedrift's task in 3m 0s —— View job


Review: docs(openspec): no demo findings, and the signature's version states its coverage

Review mode: incremental — read 0 prior review thread(s) before reviewing. .prior-review.json contained no prior review threads, review summaries, or top-level comments besides the @claude /review trigger itself, so this is the first substantive review of this PR.

  • Read .prior-review.json
  • Fetch PR diff (gh pr diff) and metadata
  • Review runtime-demo-path changes (design.md, spec.md, tasks.md)
  • Review signature-coverage-statement changes (proposal.md, spec.md, tasks.md, .openspec.yaml)
  • Cross-check claims in PR body against actual source (rule-hash.ts, layout.ts, run-set.ts)
  • Post findings

Verified claims

Everything the PR body asserts about the current codebase checks out:

  • ALGO_VERSION = 1packages/cli/src/rules/rule-hash.ts:14
  • signRuleFile reads and hashes exactly one path — rule-hash.ts:116
  • run-set.ts:41 signs rule.checkFile once per rule (signRuleFile(rule.checkFile))
  • ENGINE_LAYOUTS (packages/cli/src/rules/layout.ts) gives every engine exactly one ruleFile: ${ruleId}.yml for sg/vale, check.ts for runtime — so stating coverage at the algoVersion level does generalize rather than special-casing runtime
  • parseSignature does read the algoVersion up to the first ; before parsing key=value parameters, matching the "already reads the algoVersion before parsing parameters" claim
  • The taskless test gap referenced as the reason task 1.6 (runtime-demo-path) is now blocked is real: ran: boolean in packages/cli/src/rules/inspect.ts is set to false when fixtures never ran, and the PR's claim that this only surfaces in --json (not the human renderer) matches what's in that file

No source files are touched by this PR — everything is under openspec/, as stated.

Findings

[New] One finding, posted inline on openspec/changes/signature-coverage-statement/specs/cli-rule-reconciliation/spec.md (lines 3-31): the MODIFIED Requirements block for Canonical rule signature envelope drops two scenarios that exist under the same requirement in the main spec (Version is read before parameters, Signatures compare as whole strings), while restating the rest of the requirement text in full. The proposal frames this change as strictly additive ("one requirement, amended"), so this reads as an omission rather than an intended removal. It's likely benign given openspec-sync-specs's "preserve scenarios/content not mentioned in the delta" guardrail, but that's a soft, agent-judgment guarantee rather than something this delta states, and other MODIFIED blocks in this repo (e.g. generator-payload-alignment's cli-rules delta) follow the opposite convention of only adding new scenarios without restating existing ones — so a sync/archive that treats this delta as the complete replacement text would silently drop the two scenarios from the main spec. Recommend either including the two existing scenarios verbatim or noting explicitly that their omission is intentional.

Other notes (no action needed)

  • The runtime-demo-path spec/design/tasks changes are internally consistent: the removed Finding[]-wrapper scenarios in cli-runtime-demo/spec.md have no dangling references elsewhere in that change, task numbering (1.6/4.4) is renumbered consistently within the file, and no other change directory references the old task numbers or the withdrawn D6 shape.
  • signature-coverage-statement/proposal.md and tasks.md are consistent with each other and with the new delta spec's wording.

@thecodedrift

Copy link
Copy Markdown
Member Author

Re: @claude[bot] — "Claude finished @thecodedrift's task in 3m 0s — Review: docs(openspec): no demo findings, and the signature's version states its coverage…"
#247 (comment)

The inline finding was real and is fixed in abb551f. Worth recording the part the review left open: whether the omission was harmful "depends on how the sync/archive step is actually run".

Measured it. openspec archive rewrites the requirement to exactly what the delta contains — a replacement, not a patch — so both scenarios were silently deleted from the standing spec by a change whose proposal calls itself strictly additive. The preserve-on-sync guardrail the review cites did not save them, which also rules out the suggested alternative of noting the omission as intentional.

Both are carried verbatim now, and re-running the same experiment leaves all four scenarios in place. Task 2.3 records the measurement so the next MODIFIED delta here does not rediscover it.

Thanks for cross-checking the body's claims against rule-hash.ts, layout.ts and run-set.ts rather than taking them — the ENGINE_LAYOUTS confirmation is the one that matters, since it is what makes stating coverage at the algoVersion level generalise instead of special-casing the runtime tier.

— AI Coding Agent

@thecodedrift
thecodedrift force-pushed the openspec/signature-coverage-and-no-findings branch from 23772fd to fb4c8dd Compare September 2, 2026 18:04
The generator team withdrew the demonstration findings across three of their
own rounds, and the argument settles it: the verification gate already refuses a
rule whose fixture asymmetry does not hold, so a rule that reaches delivery has
necessarily flagged the failing example and ignored the passing one. Findings
served alongside it are a constant implied by delivery, not a result.

D6 becomes that withdrawal rather than disappearing. The wrapper we designed was
aimed at a real case, a flat list rendering identically for a rule that catches
the bad examples and one that fires on everything, and it was the right fix to
the wrong problem: that case is answered upstream of the payload.

What survives is where the concern actually lives. With nothing served beside
the rule, running it is the whole demonstration, and `taskless test` reports a
runtime rule as passing when its fixtures never ran. Task 1.6 is now blocked on
that rather than on a render.

The spec requirement becomes "the demo serves the rule and nothing beside it",
forbidding the CLI from requiring or reading a demo-only field. Task 0.4 is
marked void rather than done: there is no shape left to agree.
The envelope is self-describing about how a signature was computed and silent
about what it is over. Which file a rule's signature covers was agreed between
the two teams and written down in neither specification.

That gap surfaced as a proposal to move `signature` from the rule onto each
file, because "nothing in the payload says which file the signature covers".
The observation was right and the remedy was not: coverage is a property of the
signature scheme rather than of a delivery, so it belongs on the version, not
distributed across the collection. The proposal was declined and this is what we
owe instead.

Stating it answers what the proposal was reaching for. A new algoVersion is
already the mechanism for changing what a signature means, so an engine needing
to sign more than one file does so under a v2 signature rather than a new
payload shape.

Documentation-level. `ALGO_VERSION` stays 1, `signRuleFile` hashes one path, and
`ENGINE_LAYOUTS` gives every engine exactly one `ruleFile` — `<id>.yml` for sg
and vale, `check.ts` for runtime — so the statement generalises rather than
special-casing the runtime tier.
The MODIFIED delta restated the signature envelope requirement but carried only
one of its three scenarios, so `Version is read before parameters` and
`Signatures compare as whole strings` would have been deleted from the standing
spec by a change whose proposal calls itself strictly additive.

Measured rather than reasoned about: archiving the change and diffing the result
shows `openspec archive` rewrites the requirement to exactly what the delta
contains. It is a replacement, not a patch, and an omitted scenario is dropped
silently. Re-run with the scenarios restored, all four survive.

Recorded as task 2.3 so the next MODIFIED delta in this repository does not
learn it the same way.
A `## MODIFIED Requirements` block must restate the requirement in full,
including the scenarios it is not changing. `openspec archive` rewrites the
standing requirement to exactly what the delta contains, so anything omitted is
deleted from the spec with nothing reporting it.

Found on this branch's own change, which called itself strictly additive and
would have dropped two normative scenarios about parameter-parsing order and
whole-string signature comparison. `openspec validate --strict` passes either
way, which is why the section carries the archive-and-diff procedure that found
it rather than only the rule.

Also records that the preserve-on-sync guidance in `openspec-sync-specs` does
not reach `openspec archive`, so a delta that omits a scenario and a note saying
the omission is deliberate produce the same result.
@thecodedrift
thecodedrift force-pushed the openspec/signature-coverage-and-no-findings branch from fb4c8dd to 0b944c5 Compare September 2, 2026 18:05
@thecodedrift
thecodedrift merged commit 5c24f25 into main Sep 2, 2026
2 checks passed
@thecodedrift
thecodedrift deleted the openspec/signature-coverage-and-no-findings branch September 2, 2026 18:14
thecodedrift added a commit that referenced this pull request Sep 2, 2026
#247 merged the change and never took its tip step, so the statement it exists
to make lived in a change directory and not in the spec. Archiving is what
promotes a delta into `openspec/specs/`, which means until now
`cli-rule-reconciliation` did not carry the coverage rule we declined the
generator team's per-file signature proposal on the strength of writing down.

All four scenarios survive the promotion, including the two that were nearly
dropped in review: parameter-parsing order and whole-string comparison.

Nothing checks for this in either direction, which is how #246 came to be
outstanding too. A single-PR change has no later slice to carry the archive, so
it has to happen on the same PR or immediately after.
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