Skip to content

feat(template): run the verification loop of an extension from its first pull request #405

Closed

Description

@pascalandy

Outside the plan: Pascal assigns this card. Its pull request says that it is outside the plan.

Problem

An agent that builds a new extension from the template stops after one pass.

  • The template AGENTS.md says "Done when just check and just acceptance pass". Nothing asks for a second pass.
  • The template skill runs the readiness review only when the user asks for it.
  • The intake of the template skill reads the source of a script and asks its author. It gives no method to get the acceptance criteria of a third-party program from its documentation, exit codes, and limits.
  • The core skill nicely ("Build an extension") sends the agent to the AGENTS.md of the new repository. That AGENTS.md sends the agent to the template skill only to take in a script or to review the extension.
  • The core skill tells the agent to use the release tag that ncly --version prints. A development build prints a pseudo-version, such as v0.23.2-0.20261029012724-29243324a937. That value is not a tag, so the agent can select the wrong template.

Evidence: on 2026-10-30, four agents built extensions from v0.24.0 in a sandbox. just check passed for all four, with no notice. An independent readiness review found blocking findings in all four. For example, an input of the wrong type gave a success, and an output that appeared during the run was replaced.

Goal

The template sets up the verification loop of the extension from the first pull request.
The first implementation is incomplete by design.
The author gets the acceptance criteria from the program that the extension wraps.
Each pull request starts a verification of all layers. Its result starts the next pull request.
A user who asks for an extension does not name the template or its skill. The core skill sends the agent there.

Scope

1. Core skill nicely, section "Build an extension"

  • Tell the agent to build each command with the nicely-extension skill of the new repository, from the first command.
  • When ncly --version prints a pseudo-version, use its commit as VERSION. Copier must accept that value for --vcs-ref, and Go must accept it for the SDK.

2. Template skill .agents/skills/nicely-extension/SKILL.md

  • Intake of a program. For a third-party program, read its documentation, manual page, exit codes, limits, and known failure modes. Do not run a command that writes or bills to learn its behavior.
  • Acceptance lines. Start from the generic cases of the contract (part 5). Add one line for each case of the program. Each line of Failures and Acceptance in spec.md has a state: open, proven, or limit.
  • Round 1. The first pull request implements the main path and writes every line. Each line that has no test stays open.
  • Each next round. Select open lines. For each line, write a scenario that fails first, then change the handler, then set the line to proven. Then run just check, just acceptance, an independent review, and the readiness review. Open the next pull request from the findings. When the previous pull request is not merged, base the next one on its branch.
  • Readiness review. Run it at the end of each round, not only when the user asks.
  • Exit. Stop when no line is open, the readiness verdict is Ready or Ready with stated limits, and the hosted checks pass. After 5 rounds, stop and report each open line.
  • Release. The release receipt and the human points of qa.md come after the merge, as the Release part of AGENTS.md says.

3. Template AGENTS.md.jinja

  • "Change a command" sends the agent to the skill for each command, not only for a script.
  • "Done when" states the exit of the loop.
  • The rule index adds the rules of the loop, marked "Prose only".

4. Template spec.md.jinja

  • Each line of Failures and Acceptance shows its state. Keep the spec IDs that the test kit reads.

5. Contract

Add one list of generic cases for a command that reads or writes user files. Put it in the part that the placement rule names, and link it from the template skill:

  • Empty input, truncated input, unreadable input, input of the wrong type, very large input
  • Existing output without --force, output that is a link to the input, output that appears during the run
  • SIGINT and SIGTERM during the work, timeout
  • File names with spaces, a leading dash, or shell characters
  • Dry run with no effect, missing program

Take each new example from the template's own inspect command or from text files. Do not add an example that names an existing extension.

Out of scope

  • A new check of the test kit for line states. Add it only when a trial shows the failure, because each check fails first on a named past mistake.
  • The formal-verification example that names an external extension.
  • A release.

Done when

  • just check passes, including the template test.
  • An agent that starts from ncly skill view nicely reaches the template skill, through Copier and the new AGENTS.md.
  • The VERSION rule gives a value that Copier and Go accept for a development build. Prove it with a pseudo-version.
  • The pull request stays open and unmerged, for evaluation by a trial.

Second pass, after trial 1

Trial 1 (2026-10-30): a fresh agent built an extension from the head of this pull request. The routing worked: ncly skill view nicely, then nicely-extensions, Copier at the development commit, then AGENTS.md and the template skill. The loop did not run:

  • The agent made one pull request and one independent review, then stopped.
  • It wrote None. under ## Open lines, although several cases had no proof.
  • It wrote its losses as a free paragraph of limits. The user did not accept them.
  • It ran no readiness review. It used the merge gate of its delivery skill (full-stop) as its exit, in place of "Done when".
  • It read the source of the external extension that the template skill names as the example for formal verification.

just check and just acceptance passed. An independent replay then found wrong output for several cases of the wrapped program. The program intake and the readiness review are there to catch these cases.

Add these changes to this pull request:

  1. Finish gate. Add a recipe to the template, separate from just check, such as just finish. "Done when" runs it. It fails when:

    • a line is open under ## Open lines
    • a line under Limits. has no spec ID, no state limit, or no record that the user accepted it
    • no readiness verdict is recorded for the current commit, or the verdict is Needs work

    just check stays green for an incomplete first round. Prove the gate with a test that fails first on the state of trial 1: None. under Open lines, a limit paragraph that nobody accepted, and no readiness record.

  2. Ready. Ready means no block and no warn. Ready with stated limits means no block, and the user accepted each warn as a limit line.

  3. Delivery after the loop. State in the template skill and in AGENTS.md: a delivery skill or a merge gate, such as a "full stop" or "full send" request, runs after "Done when" holds. It never replaces "Done when". When the previous pull request is not merged, the next round stacks on its branch.

  4. No external example. Remove the line that names an external extension as the example for formal verification. Keep the rule for a command that replaces a user file or replays paid work.

Out of scope: the SDK answers that omit the input file. A separate issue tracks them.

Done when, second pass

  • just check passes, and the finish gate has a test that fails first on the state of trial 1.
  • The pull request is merged through just signoff, as AGENTS.md says.

Activity

  1. added
    1-ready-for-agentValidated work, sufficiently specified for an autonomous agent
    2-type:featureNew or improved functionality; specification lives in the issue
    3-pty:p2Normal planned work; default when no priority is established
    on Oct 30, 2026
  2. pascalandy commented on Nov 2, 2026

    @pascalandy
    OwnerAuthor

    Note

    🤖 Claude Opus 5.5 responding on behalf of Pascal Andy

    #406 shipped this issue, and it stayed open only for the day-1 trials. The six trial rounds ended on 2026-11-01, their fixes are in #418, #421, and #424, and the remaining gaps are in #425. Closing it so no agent picks it up again from 1-ready-for-agent.

  3. removed
    1-ready-for-agentValidated work, sufficiently specified for an autonomous agent
    on Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    2-type:featureNew or improved functionality; specification lives in the issue3-pty:p2Normal planned work; default when no priority is established

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions