Repository navigation
S2.6.7 — The live rung, never required - #338
Merged
dev-pmallapp merged 3 commits intoSep 15, 2026
Merged
dev-pmallapp merged 3 commits into
dev-pmallapp merged 3 commits into
Conversation
Build target 8 of docs/design/stories/293.md. Case 15 and the mechanism cases 19 and 13 will use. The live run itself is a separate commit. The seam rung runs transcriptions against a fake forge; its population is the transcription, never the model reading the markdown. The live rung is the other population, so this script does not execute a skill -- it is the recording seam an operator's model-driven run is driven through, which is why it is subcommand-shaped: init, mark, exec, report. exec runs each argv through createRecordingPort(createRealPort()) and logs the argv, exit code, run index and stdout/stderr BYTE LENGTHS -- never their contents, because a real forge response can carry content this repository has no classification for. report reuses classifyArgv, countReads and isMutatingGhArgv rather than restating them, and emits every distinct argv that exited non-zero: that list is the first-contact record for #330. tokenCost is null unless --token-cost is supplied, and the summary says so in words. It is structurally impossible for the artifact to assert a cost nobody measured. Case 15 ships with the denominator made readable: DATA_CLASSES is a frozen array in classify/levels.ts and RANK is DERIVED from it, so a fifth class cannot be added to one and not the other. admitToLiveModel THROWS on a block and returns only on admit -- there is no boolean for a caller to ignore. The egress gate runs first in init, before anything touches the filesystem, and demonstrates its converse on the same path: if a USER/-derived payload is NOT refused, init fails. A gate that cannot be shown refusing is an unexercised branch. THE FINDING, now issue #336. classify() imports only ./levels and ./recognisers -- it never imports ./path, so classifyPath's USER/ rule is consulted by nothing. Measured: {source_path:"USER/..."} is PRIVATE, but so is {zzz_unrelated:"x"} with no USER/ anywhere, and {work_state:"USER/..."} is INTERNAL, which clears a cloud destination. The old test named "classify resolves USER/-derived content to PRIVATE" therefore passed for a reason other than its name -- it could not distinguish the reason for its own answer. Case 15 still passes honestly: its wording is "PRIVATE by fail-safe default", which is exactly the unrecognised-key rule that fires. The test is renamed to say so, a control proves the discrimination, and a tripwire asserts classify.ts does not import ./path so wiring it in forces this record to be revisited deliberately. NEVER-293.10 holds -- the gap is in classification, not the guard. The live rung's flag surface is a closed enumerated set asserted by test, and --force-private-goals-payload is proven to occur exactly once and to select the PRIVATE payload, so the one undocumented flag can only ever cause a refusal. The egress gate is NOT what stops a run against the real goals source -- a real goals document under work_state would clear it too. What stops it is that the payload is built from renderGoalsFixture with no redirection path. Two protections guarding two different things; the comment now says so.
…uired Cases 13 and 14 of docs/test-plans/293-plan.md, anchoring NEVER-293.10. .github/workflows/live.yml is a SEPARATE file with workflow_dispatch as its only trigger, and the separation is the mechanism, not tidiness. A job in ci.yml runs on every pull_request; a live job must not. ci.yml deliberately carries no paths: and no branches: filter, because NEVER-9.8 says a filtered workflow leaves required checks pending forever -- so there is no way to add a non-PR-triggering job to that file. A workflow_dispatch-only workflow is the only shape that cannot fire on a PR, which is also why it can never be accidentally promoted: a context that never reports would block every PR forever if required. Fork PRs receiving no secrets is the third independent reason a required live job is structurally illegal. The job proves the seam -- live-rung --help and its test file -- and never opens a session against a real repository. A real conformance run is model-driven by a human operator; this script is only the recording seam. test/ci-workflow.test.ts now asserts, for NEVER-293.10: `live` appears in none of the four hardcoded required lists; the four still agree; the required count is READ and compared before and after rather than hardcoded, so #334 taking it to seven does not require editing this test to keep it true; every required job carries no `if:`; live.yml's trigger set equals exactly {workflow_dispatch}; and live.yml's jobs are disjoint from ci.yml's and from every required list. The partition is extended across BOTH workflow files rather than carved out: every job in every workflow must be required, or named not-required with a reason. Four mutations injected, four killed, including a pull_request trigger added to live.yml and an unclassified second job.
Cases 13, 14, 15 and 19. Measured on 603b02d, which frontmatter `commit:` pins as the parent; the conformance run itself was performed on 2026-09-12 at 1527dfb, which is what the attestation states. The artifact is deliberately self-contained. Its subject -- the fixture repository -- was created to be destroyed and has been deleted, so every figure and every argv is reproduced in full. An artifact whose evidence lives only in a deleted repository is an assertion, not a record. THE RESULT WORTH KEEPING. A model read skills/goal-create/SKILL.md and performed it twice against a real forge: run 1 three reads and one mutation, run 2 three reads and ZERO mutations. Those are the same six numbers SCENARIO_ROSTER's goal-create/absent-milestone scores. The audit compared prose to code; this compares code to reality. Neither subsumes the other, and CLAIM-41.8 stays model-judged -- n=1 over a non-deterministic trajectory is an existence proof, not a property. #330 IS PAID IN PART, AND THE PRECEDENT INVERTED. Thirteen argvs built by the real exported builders were executed against a real forge and thirteen were accepted, against S2.1's precedent of 7 of 9 rejected. Every mutation was then verified by READING THE FORGE, never by trusting the exit code -- #320's M9/M9b pair. pr's 12 exports and sub-issues' 14 remain unexecuted: smaller, not settled. Both of the fake's unmodelled shapes -- the milestone PATCH and --milestone on gh issue edit -- succeeded live. The two dead branches are dead because of the fake, exactly as the audit claimed. Token cost is recorded as 305.2k / $36.14 and labelled a SESSION TOTAL, an upper bound that also covers building the live rung, the audit and the CI work. M2.md:240-241 asks for one verb's cost and SHOULD NOT be ticked on this number. Raised as #337 with the cheap fix named. Closing a context-budget criterion on a bound orders of magnitude above the thing bounded is the stronger-sounding- class failure verification.md:43-46 names. The attestation names dev-pmallapp, the commit, the host and the category, per references/verification.md:37 -- human-attested fails when nobody is named.
dev-pmallapp
marked this pull request as ready for review
September 15, 2026 13:21
5 tasks
dev-pmallapp
merged commit Sep 15, 2026
60c187b
into
story/293-s2-6-skill-execution-harness
8 checks passed
8 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #324. Refs #293.
Build target 8. Cases 13, 14, 15, 19.
A model read a
SKILL.mdand performed it against a real forgeRun 2 issued no mutating command at all, exactly as
skills/goal-create/SKILL.md:91-93promises.Those are the same six numbers
SCENARIO_ROSTER'sgoal-create/absent-milestonescores. The transcription audit compared prose to code; this compares code to reality. Neither subsumes the other — andCLAIM-41.8staysmodel-judged, because n=1 over a non-deterministic trajectory is an existence proof, not a property. Gate ruling G2 still forbids otherwise.#330 is paid in part, and the precedent inverted
13 argvs executed against a real forge. 13 accepted. 0 rejected. The S2.1 precedent was 7 of 9 rejected on first contact.
Every mutation was verified by reading the forge afterwards, never by trusting the exit code — #320's M9/M9b pair measured that a double which refuses and one which accepts return the same verdict and differ only in state.
Both of the fake's unmodelled shapes succeeded live — the milestone
PATCHand--milestoneongh issue edit. The two dead branches the audit recorded are dead because of the fake, exactly as it claimed.pr(12 exports) andsub-issues(14) remain unexecuted. Smaller, not settled.Why the live rung can never become required
.github/workflows/live.ymlis a separate file,workflow_dispatch-only, and the separation is the mechanism: a job inci.ymlruns on every PR;ci.ymlmay carry nopaths:/branches:filter (NEVER-9.8); so a non-PR-triggering job cannot live there. A workflow that cannot fire on a PR also cannot be accidentally promoted — a never-reporting required context would block every PR forever.test/ci-workflow.test.tsreads the required count rather than hardcoding6, so #334 taking it to seven will not require editing the test. The partition now spans both workflow files.Case 15 — and the finding underneath it
#336:
classify.tsimports only./levelsand./recognisers— never./path— soclassifyPath'sUSER/rule is consulted by nothing.{ work_state: "USER/…" }classifies INTERNAL and clears a cloud destination.The old test "classify resolves USER/-derived content to PRIVATE" passed for a reason other than its name: its payload was PRIVATE by the unrecognised-key default, and would have passed identically for
{ zzz: "x" }. It could not distinguish the reason for its own answer.Case 15 still passes honestly — its wording is "PRIVATE by fail-safe default", which is exactly what fires. Renamed to say so, with a control proving the discrimination and a tripwire asserting
classify.tsdoes not import./path.NEVER-293.10holds: the gap is in classification, not the guard.Token cost — recorded, and deliberately not used to close M2
305.2k tokens / $36.14, labelled a session total: an upper bound that also covers building the live rung, the audit and the CI work.
docs/milestones/M2.md:240-241asks for one verb's cost. It should not be ticked on this number — raised as #337 with the cheap fix named (one dedicated session running a single verb). Closing a context-budget criterion on a bound orders of magnitude above the thing bounded is the "stronger-sounding class than the check supports" failurereferences/verification.md:43-46names.Attested
references/verification.md:37:human-attested"fails when nobody is named". Attested bydev-pmallapp, at commit1527dfb, host opencode, routing categoryplan.The fixture repo
dev-pmallapp/iai-live-rung-fixturewas created to be destroyed and has been deleted — verified absent. The evidence artifact is self-contained for that reason.Chain, on
603b02d1156 tests / 1142 pass / 0 fail / 14 skip / 4218
expect()· lint 0 across 126 files · typecheck clean · claim-lint 125 files, 0 errors, 1 warning ·skill-harness0,--inject1 · both verifiers PASS at six.Evidence:
docs/evidence/324-20260915T131526Z.md.