Skip to content

✨ feat: template: one case matrix before the first review, and signoff runs the first failing run again - #424

Open
pascalandy wants to merge 22 commits into
feat/420-intake-proofsfrom
feat/423-case-matrix
Open

pascalandy wants to merge 22 commits into
feat/420-intake-proofsfrom
feat/423-case-matrix

Conversation

@pascalandy

@pascalandy pascalandy commented Nov 1, 2026 •

Copy link
Copy Markdown
Owner

Outside the plan: Pascal assigned #423, which holds #422 in full as its point 1, and the % bug as its point 6. This pull request stacks on feat/420-intake-proofs of #421, which is open and not merged, at 2f813aa. #421 stacks on #418. It closes #422 and #423.

In round 5 of the day-1 trials, the loop held, and the replay scored 35, 36, and 36 of 36. But no build reached "Done when" in 5 rounds. The judge's cause: authors and reviewers find one variant of a family of cases at a time, and each narrow fix lets the next review find a sibling. Some gaps only the SDK can close: a grade can hide in free form, a first failing run is checked only for its form, and a new finding with no state passes beside None.. And ncly panics at startup in a folder whose path holds %.

What changes

Each new rule has a row in AGENTS/rule-index.md, with its check or "Prose only".

Decisions made without Pascal

  • One allowed recipe. The allowed list holds one form, just scenario <name>. Signoff runs go test itself and does not use the justfile of the Scenario commit, so a changed recipe forges nothing.
  • Same assertion means same line. The run must fail on a line of the scenario that the record holds. The reviewer still judges whether that line proves the missing behavior.
  • The matrix check reads the references only. Finish cannot know which generic cases apply. It checks that each family names a test, that each family names a passing input, and that each line of Failures and Acceptance has a family. It cannot prove that the matrix is complete or correct, or that the extension is ready. The reviewer checks that the matrix is complete. finish-gate.md, the skill, the readiness review, and the rule index say so.
  • No claim about the trials. This pull request does not claim that the trials succeeded. No build of the day-1 trials reached an earned "Done when".
  • The parser limit is narrow on purpose. A grade in other words, such as "a block for me", passes finish. Rounds 1 and 2 of the review found false positives on ordinary table cells and on "block level". So the cell rule needs a finding ID in its row, and the level form needs a hyphen. "block-level" still fails.
  • The assertion line is exempt from the severity forms. It copies a line of the scenario. Only the first one is exempt, and finish reads that one.
  • Earlier builds are judged with the new no-state rule. A ledger of the unmerged template: limit a build to 5 rounds, keep a ledger of findings, and close the gaps of round 3 #417 to ✨ feat: template: finish proves the first failing run and one state of open work, and release runs finish again #421 stack whose passing build ended with a stateless advise now fails. No release holds the ledger, so I accepted this.
  • verify-nicely without the keychain. The agent skipped ncly doctor with no domain, the feature auth, and the template step Doctor. They probe the keychain, which this task must not touch. The refusal step used a text file with a NUL byte instead of the bytes of the doc.
  • Stack. I ran just signoff on this head only. just signoff-layers would also sign the heads of ✨ feat: template: a build stops at 5 rounds, and a ledger keeps every finding #418 and ✨ feat: template: finish proves the first failing run and one state of open work, and release runs finish again #421, which this task does not touch.

Checklist

  • 1. Spec: finish-gate.md, extension-repository.md, generic-cases.md, and test-kit.md cover each check and each rule
  • 2. Scenario: each new case failed first, see "Proved by"
  • 3. Code: those cases pass in just template and just check
  • 4. Text: n/a. The messages of just finish and just signoff stay in code, as every message of sdk/extensionrepo does
  • 5. Checks: just check passes
  • 6. Verify: an agent that did not write the change ran verify-nicely on template and on ncly --version in a folder whose path holds %. Every step that ran passed, see "Proved by"
  • 7. Docs: n/a for the backlog, because the card is outside the plan. README.md shows no change for a user. The skills of the template teach each new rule
  • 8. Sign off: just signoff passes on this head

Proved by

  • Fails first, then passes. A probe called the parsers of sdk/extensionrepo at the base 2f813aa and at this head:

    == 2f813aa8 (base)
    grade "| R1-F1 | really a warn |"                              -> 0 problem(s)
    grade "Grade: block. The name is a block for me."              -> 0 problem(s)
    grade "This issue is warn-level and should block the release." -> 0 problem(s)
    grade "Large files block the terminal, and inspect may warn."  -> 0 problem(s)
    no-state finding of round 2 beside None.                       -> []
    first run "echo invented"                                      -> []
    first run "just scenario inspect"                              -> []
    == this head
    grade "| R1-F1 | really a warn |"                              -> 1 problem(s)
    grade "Grade: block. The name is a block for me."              -> 1 problem(s)
    grade "This issue is warn-level and should block the release." -> 1 problem(s)
    grade "Large files block the terminal, and inspect may warn."  -> 0 problem(s)
    no-state finding of round 2 beside None.                       -> ["...the finding R2-F1 of this round has no state, so it is open..."]
    first run "echo invented"                                      -> ["...names the command \"echo invented\", which is not just scenario <name>..."]
    first run "just scenario inspect"                              -> []
    
  • %. The new lines of testdata/script/version.txtar failed before the fix with panic: ... invalid URL escape "%/s" at line 27, and pass after it.

  • The replay. scripts/template-signoff-test.sh runs the rendered just signoff on real commits. It refuses echo invented, a Scenario commit that does not compile, a scenario that passes at its commit, and a record of another line. It signs a correct repository and prints signoff: the first scenario fails again at <sha>.

  • The other cases. The template tests prove the paired grades and the prose control, the case matrix (each refusal and the passing state), the stateless finding beside None. and then with its open line, and just scenario on a scenario and on a path.

  • Checks. just template passed at 4fb1d87. just check passed at f3fe78c. At 20be50c, one timed scenario of agent, agent_run_cancel, timed out while another job loaded the host. It then passed 3 of 3 runs alone with just scenario agent/agent_run_cancel --count 3. just signoff ran just check again on this head, see below.

  • verify-nicely. An agent that wrote none of the change ran it on 75c627e. ncly --version names the build. Every step of the feature template that ran passed. The rendered spec.md holds ## Case matrix at line 58, and just --list shows scenario name. just finish names each Fill: line, also the one of the matrix, and the missing verdict. In work 100%, ncly --version and ncly describe --json exit 0 with no panic.

  • Review. Three rounds by an agent that wrote none of the code, one reviewer each, then a review of the last fix. Round 1: 1 block, 4 warn, 6 advise. Round 2: 1 warn, 2 advise. Round 3: Ready, 1 advise. Review of the last fix: Ready, with 1 test that it suggested, now added. Two advise items were declined: an assertion that pastes many lines still needs a real failure on a line it names, and the rule for earlier builds above.

  • Sign off. just signoff ran just check on 75c627e in a detached scratch worktree, then printed Signed off on 75c627ebb49498b4ab1728017dcf45f1843cdb54. The status signoff of this head is green.

by Opus-5.5 via Claude Code

pascalandy and others added 21 commits November 1, 2026 00:16
…own file

validate and noRemote move from scenario.go to answer_schema.go, with no
change of behavior, so a fix of the schema name can grow them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
compileSchema and noRemote move from schema.go to schema_compile.go, with
no change of behavior, so a fix of the schema name can grow them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The schema compiler resolved the relative name schema.json against the
working folder as a file URL. A % in that path made ncly panic at startup
with "invalid URL escape", even for --version. The schemas now have a URN
that no folder changes, and so do the answers that the test kit checks.

Refs #423

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

The severity patterns, severityCause, and severityCell move from
readiness.go to readiness_severity.go. Their proofs move from
template-finish-test.sh to template-finish-forms-test.sh. Nothing changes
in behavior, so the next fix can grow them.

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

A review could grade in notes and pass just finish, with forms such as
"Grade: block", "warn-level", or the cell "really a warn". Finish now
fails on the word grade before a severity, on a severity before the word
level, and on a cell whose last word is a severity. Ordinary prose with
the words block and warn still passes. finish-gate.md states the exact
forms that the parser finds, and the reviewer moves each other grade to
the bullet Severity.

Refs #422, #423

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A review could add a finding with no state beside None. under ## Open
lines, and just finish passed when the verdict allowed it. Such a finding
of the last round is now open: finish fails on it, and fails with its ID
when ## Open lines omits it.

Refs #423

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

The cleanup of Run that prints the reservations and the missing coverage
moves to kit.reportCoverage in coverage_report.go, with no change of
behavior, so a run of one scenario can change it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A record of ## First failing run passed when its form was right, also with
the command `echo invented` or with a failure that was a compile error.
The record now names the recipe just scenario <name>, of a scenario of
the Scenario commit, and its assertion holds a line of that scenario.
After just finish, just signoff checks out the Scenario commit in a new
scratch worktree and runs that scenario alone with go test. The run must
fail on the line that the record names. Signoff builds the arguments from
the name of the scenario, and never runs the text of the record.

just scenario <name> runs one scenario. The test kit then skips its
coverage checks, which need every scenario.

Refs #422, #423

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ves to its own file

The section "Commands that replace a file" of the nicely-extension skill
moves to replace-a-file.md beside it, and the skill links it. Nothing
changes in the rules, so the next rules of the rounds fit in SKILL.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each build found one variant of a family of cases at a time, and each
narrow fix let the next review find a sibling. spec.md now holds a table
under ## Case matrix: one row for each family of cases, from the generic
cases and from the intake, with the spec IDs of the tests that pass and
of the tests that refuse. just finish fails when a family names no test,
when a family names no input that passes, or when a line of Failures or
Acceptance is in no family. The skill asks for a pair of tests for each
refusal and each branch that classifies an input, the first reviewer
checks and runs the matrix before any repair, and a repair tests its
whole family.

Refs #423

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

The section "Error mapping" of the nicely-extension skill moves to
error-mapping.md beside it, and the skill links it. Nothing changes in
the rules, so the next rules of the rounds fit in SKILL.md.

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

An intake could name a part of a source with no read of it in the
transcript. Each settled fact now links the part of the source that the
agent read, at a fixed revision, and a fact without a read is marked
inference. Each unknown fact is an open line with an ID before the spec.
The reviewer of round 1 refuses a fact that only cites a source.

Refs #423

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

No build had a test file for this case before its first review. Before
the first review, acceptance.sh now makes a file whose block that a reader
needs uses a value that is not the default and holds private text. An
independent reader proves that the private text is gone and that the
content still shows correctly, and a handler that keeps the raw block
fails the check.

Each experiment uses a new scratch folder, and no recursive delete runs
inside sh -c or a loop, which a harness can stop for an approval that
nobody gives. The tests and just acceptance need no root, no mount, and
no system service.

Refs #423

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

Finish failed on each table cell whose last word was a severity, so a
cell such as "the header block" failed. A cell now grades in that form
only in a row that names a finding ID, such as | R1-F1 | really a warn |.
Elsewhere a cell grades only when it holds the severity alone. The level
form needs a hyphen, such as warn-level, so "block level" in prose
passes.

Refs #422, #423

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

A test now records one line of the first scenario while the replay fails
on another, and signoff refuses it. The template test runs just scenario
on a scenario that passes and on a name that is a path. The test kit
skips coverage only when -run selects the scenario that
NCLY_TEST_SCENARIO names, and test-kit.md documents that variable.

Refs #422

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

The message of a finding of this round with no state now says that the
author can decline an advise, and so does the skill. The rule index says
that the matrix check needs a spec ID in Accepted, and the reviewer checks
that it passes. A test helper of ncly gives its schema a URN too, so the
tests of Nicely pass in a folder whose path holds %. A comment of
ledger_run.go splits a sentence of 33 words.

Refs #423

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

readiness-review.md now says that a finding is fixed only when its repair
adds a pair of tests for its whole family, as ## Case matrix lists it.
spec.md states that rule in its prose, not only on a Fill: line that the
author deletes.

Refs #423

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e in the assertion

A Refused cell of `None` in code, the form that the docs show, failed the
matrix check. The check now strips the marks. The line Assertion of ##
First failing run copies a line of the scenario, which can name a
severity. Finish no longer reads it as a grade.

Refs #422, #423

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

Each line Assertion under each ## First failing run was exempt from the
severity forms, while finish read only the last one as the record. Only
the first one is now exempt, and finish reads that one. A second line
Assertion that grades fails finish.

Refs #422

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

A record whose first line Assertion grades and holds no line of the
scenario fails finish, even when a second line Assertion is valid. So the
record parser keeps reading the first value, as the severity forms do.

Refs #422

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

The step Loop text of the feature template now checks that the rendered
spec.md holds ## Case matrix beside ## Open lines.

Refs #423

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

coderabbitai Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 2874cd6a-42df-430a-b757-3f7383567fc2

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

Use the checkbox below for a quick retry:

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

The check of ## Case matrix proves that each family names a test and
that each line of Failures and Acceptance has a family. It cannot
prove that the matrix is complete or correct. Say so in
finish-gate.md, the skill, the readiness review, and the rule index
(judge 6 of the day-1 trials).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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