From 76435e6624c6c0fcf6c680f8641be4dd59a06d49 Mon Sep 17 00:00:00 2001 From: Pierre Mardon Date: Sat, 3 Oct 2026 22:20:51 +0200 Subject: [PATCH] A hand back at conformity that fits a branch with no pull request At conformity, `/surface-execute` told the developer to mark the pull request ready whether or not one existed. In the six runs of the first campaign of the evaluations none was ever opened, the container having no `gh`, and every last message spoke of one all the same: the step that was the developer's, opening it, was never said (#66). Refs #66 --- docs/guide.md | 2 +- skills/surface-execute/SKILL.md | 6 +++--- tests/prompts/chain_contract.py | 6 ++++++ tests/prompts/test_execute_and_status_skills.py | 13 +++++++++++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/docs/guide.md b/docs/guide.md index 88663e1..4544e5f 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -58,7 +58,7 @@ The loop hands back in three cases, tells you in the terminal, and in the first |---|---|---| | A contract break: the blueprint would have to change to stay true | a plan change proposal, in `plan-changes/`, presented at the level of the blueprint | Decline it with a reason in one line: the loop goes on, the agents bring the code back to the blueprint and do not raise the same break again. Accept it, then run `/surface-plan`, which draws the new revision for you to approve with `/surface-execute`. | | The ceiling of autonomous passes, three by default | a summary of what does not converge | Answer that it resumes: the loop goes on in the session with a fresh count. Or amend the plan with `/surface-plan `. | -| The conformant state | one line that says so, and an updated PR description | Mark the PR ready when you want: step 5. | +| The conformant state | one line that says so, and an updated PR description | Mark the PR ready when you want: step 5. When the chain could open no PR, without `gh` or a remote, that line tells you to open it, and how to print its description. | ### 5. Mark the PR ready, then merge diff --git a/skills/surface-execute/SKILL.md b/skills/surface-execute/SKILL.md index 80da99f..5157ea3 100644 --- a/skills/surface-execute/SKILL.md +++ b/skills/surface-execute/SKILL.md @@ -126,7 +126,7 @@ The fixer runs the full gates once at its end. Green, it records `fix-done` and ## Conformity -The last review found nothing and nothing changed since: the reviewer wrote `conformity.md`. `surface-status record conformant --conformity conformity.md`, then commit the journal, with `conformity.md` when its content is not committed yet. Stop, as "When the loop stops" says, and hand back in one line: the plan is conformant, and the developer marks the pull request ready when they want, which triggers their CI. Conformant means the reviewer proved every acceptance criterion, since one it cannot prove is a finding: `conformity.md` keeps that proof, and nothing asks the developer to read it. Say the one exception in one sentence: a conformant plan leaves nothing to check, except the code of the critical zones the project declares, whose changed files the pull request description lists, when there are any, for the developer to read themselves. +The last review found nothing and nothing changed since: the reviewer wrote `conformity.md`. `surface-status record conformant --conformity conformity.md`, then commit the journal, with `conformity.md` when its content is not committed yet. Stop, as "When the loop stops" says, its push and its refresh first, then hand back in one line: the plan is conformant, and the developer marks the pull request ready when they want, which triggers their CI. When the refresh reached no pull request, for want of one, of `gh` or of a remote, that line names the step that fits instead: the developer opens the pull request, if none is open yet, with the description `surface-status pr-body` prints, the script given by its full path since they run it themselves. Nobody marks ready, or refreshes, a pull request that does not exist. Conformant means the reviewer proved every acceptance criterion, since one it cannot prove is a finding: `conformity.md` keeps that proof, and nothing asks the developer to read it. Say the one exception in one sentence: a conformant plan leaves nothing to check, except the code of the critical zones the project declares, whose changed files the pull request description lists, when there are any, for the developer to read themselves. Refused with the code `critical-files`: the list of those files, which the reviewer left in `conformity.md` for the script, is malformed or names a file the branch did not change. The developer is not asked to repair an agent's list, and only a reviewer edits a reviewer's report: launch a fresh `surface-reviewer`. Its mandate: the plan folder, the base commit (`base` of `surface-status commits --json`), and the mode, a refused list of critical files, with the refusal's reason. It corrects that list and nothing else, and records nothing: when it returns, record `conformant` again, as above. Refused again: a fresh reviewer again, with the new reason, up to `passes.ceiling` of `show --json` reviewers in all, since the one setting that bounds what the loop does on its own bounds this too. Keep that count yourself: a refused `conformant` leaves no line in the journal, and these attempts do not raise `passes.execution`. Still refused after them: stop and report the reason to the developer. @@ -151,5 +151,5 @@ At every stop, once a plan was found: 1. Say in the terminal why the loop stopped and whose turn it is, with the paths worth reading. 2. Push the branch to its upstream, which `/surface-plan` set at the first draft. Without an upstream, push nothing and say so. -3. Refresh the pull request's description: the output of `surface-status pr-body` (it takes no argument, since it describes every plan of the branch), given to `gh pr edit --body-file -` on its standard input. Without a pull request or without `gh`, say so. Nothing else is written on the pull request. -4. Never mark the pull request ready, since that triggers the CI: on `conformant`, the developer does, when they want. +3. Refresh the pull request's description: the output of `surface-status pr-body` (it takes no argument, since it describes every plan of the branch), given to `gh pr edit --body-file -` on its standard input. Without a pull request or without `gh`, say so in one line. Nothing else is written on the pull request. +4. Never mark the pull request ready, since that triggers the CI: on `conformant`, the developer does, when they want, or opens it first when the refresh reached none. diff --git a/tests/prompts/chain_contract.py b/tests/prompts/chain_contract.py index 66422fa..6e4b069 100644 --- a/tests/prompts/chain_contract.py +++ b/tests/prompts/chain_contract.py @@ -21,6 +21,12 @@ CONFORMANT_HAND_BACK = ( "the plan is conformant, and the developer marks the pull request ready when they want" ) +# A branch may have no pull request: no `gh`, no remote, or a push the developer declined. The +# line then names the step that fits, since nobody marks ready a pull request that does not exist. +CONFORMANT_WITHOUT_PULL_REQUEST = ( + "the developer opens the pull request, if none is open yet, with the description" + " `surface-status pr-body` prints" +) # The one exception, which the hand-back says in one sentence: where a mistake would cost most, # in the zones the host's agent instructions declare critical, the developer reads the code # themselves, from the list of changed files the pull request description gives. diff --git a/tests/prompts/test_execute_and_status_skills.py b/tests/prompts/test_execute_and_status_skills.py index 3e2af64..21a8433 100644 --- a/tests/prompts/test_execute_and_status_skills.py +++ b/tests/prompts/test_execute_and_status_skills.py @@ -16,6 +16,7 @@ from chain_contract import ( CONFORMANT_EXCEPTION, CONFORMANT_HAND_BACK, + CONFORMANT_WITHOUT_PULL_REQUEST, CORRECTIONS_CEILING, DOCUMENTS_LANGUAGE, EXECUTE, @@ -486,6 +487,18 @@ def test_conformant_hands_back_in_one_line_and_leaves_the_ready_mark_to_the_deve body = _execute() conformity = section(body, "Conformity") assert f"hand back in one line: {CONFORMANT_HAND_BACK}" in conformity + without, fitting, absurd = _positions( + conformity, + [ + "When the refresh reached no pull request, for want of one, of `gh` or of a remote", + f"that line names the step that fits instead: {CONFORMANT_WITHOUT_PULL_REQUEST}", + "Nobody marks ready, or refreshes, a pull request that does not exist", + ], + ) + assert conformity.index(CONFORMANT_HAND_BACK) < without < fitting < absurd + # The refresh tells whether a pull request can be reached: it comes before the line. + assert "its push and its refresh first, then hand back in one line" in conformity + assert "or opens it first when the refresh reached none" in section(body, "When the loop stops") assert "one it cannot prove is a finding" in conformity assert "nothing asks the developer to read it" in conformity stopping = section(body, "When the loop stops")