sync: dev -> main - #12
Closed
xor-machine wants to merge 24 commits into
Closed
Conversation
The e2e workflow proves the delivery mechanism every future package rides: an app composed from the skeleton (dev), the recipes checkout served as the Flex endpoint locally, minspec/fixture-hello required through it, and the independent test author's assertions run against the result. The planted-fault arm corrupts the served recipe, proves the plant landed and did not leak into the clean fixture, serves it from its own port so no cache can launder it, and requires the build to fail. CI additionally asserts Mate's container answer instead of listing tools. assert.sh was authored by the independent test author from the recipe contract alone, without sight of the implementation, and calibrated locally: 4/4 PASS on the wired app, 4/4 loud failures on an unwired app. Source: owner 2026-09-01 Source: original Co-Authored-By: GPT-5.6 Sol <noreply@openai.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XehTac5TJNmPAskwrPp7rJ
The first CI run caught two defects, which is the workflow doing its job. One: the planted fault did not fire — the local-endpoint rewrite set a top-level recipe_template while Flex reads it from _links, so both arms silently fetched the clean recipe from the GitHub API; both templates now point at the local server, and the broken arm also changes the recipe ref so no cache can launder the plant. Two: composer validate caught the lock file the bump plugin left stale while Actions was still disabled; reconciled. Hardening from the independent security audit (CHANGES verdict): workflow-level permissions contents:read on ci and e2e; persist-credentials false on every checkout; the committed APP_SECRET replaced with an obvious non-secret fixture sentinel. Finding: [P1] workflows ran with default token permissions Finding: [P2] .env.dev committed a real-looking APP_SECRET Verified: composer validate --strict at e2a7da1 (now valid); python yaml.safe_load on both workflows Source: original Co-Authored-By: GPT-5 Codex <noreply@openai.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Reviewed-by: GPT-5 Codex <noreply@openai.com> Claude-Session: https://claude.ai/code/session_01XehTac5TJNmPAskwrPp7rJ
e2e: the package road, asserted — both directions
The e2e workflow gains workflow_call with a ref input per component:
a calling repo slots its own PR into its slot and takes siblings at
dev, so skeleton, recipes, and fixtures PRs run the SAME road test
the workbench runs, not a copy that can drift. Checkouts are
SHA-pinned and credential-free per the audit standard; the workbench
checks out into wb/ so own-run and called-run share one path shape.
Source: owner 2026-09-01 ("make it a real test and stick to it")
Source: original
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XehTac5TJNmPAskwrPp7rJ
e2e: the org gate — one canonical road test, callable from every repo
The maintainer's definition of review for big PRs to dev: a Codex
security sweep and a Grok audit, both independent of the author,
both on the wire, findings applied through the lane with the finder
credited. Merge follows the verdicts; stable stays the
maintainer's.
Source: owner 2026-09-01 ("codex security sweep and a grok audit
for big PRs to dev - that's the review")
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XehTac5TJNmPAskwrPp7rJ
ops: the review — Codex sweeps, Grok audits, the conductor applies
The dev-lane machinery for MinSpec, reviewed by the lane's own two-harness review (Codex security sweep + Grok audit) with their findings applied or stated in AGENTS.md: dispatch (worker launcher), task (job registry), harness (isolation proofs), telemetry (usage readers), fixtures (synthetic replay data), the process docs, dispatch.sh/conf for this ops home (state under minspec/dispatch), the process skills, and the test-author and test-skeptic role agents. Public-safe by construction: - fixture envelopes carry only synthetic session and request ids, paths, reasoning text, and cost figures; store fixtures generate from a cwd parameter, so no machine path is baked in. - no committed .pyc; ops/devlane/.gitignore added. - ops/devlane/AGENTS.md states the trust boundary: TRUSTED work on the operator host only — no OS containment, so untrusted or public commits need an ephemeral container not yet built; dispatch.conf is owner-controlled shell; fixtures are synthetic, never raw captures. - the launcher self-resolves from the lane (no absolute pin); the real dispatch.conf is machine-local and gitignored behind an .example; apply-push carries a content guard that refuses home paths, job captures, and credential references in a landing commit. - go.sh: the one-line way to hand work to the lane. Verified: dispatch 247, task 151, harness 34, telemetry 63, fixtures 14 — all suites OK. Source: owner 2026-09-01 Co-Authored-By: GPT-5.6 Sol <noreply@openai.com> Co-Authored-By: Grok 4.6 <noreply@x.ai> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Reviewed-by: GPT-5.6 Sol <noreply@openai.com> Claude-Session: https://claude.ai/code/session_01XehTac5TJNmPAskwrPp7rJ Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
The PreToolUse guard hooks (boundary-match, unsafe-command, command_shape, conductor-enforce, test-guard, context custody) and the standalone workflow checks they depend on (commit_trailers and siblings), under ops/devlane. Machinery only, no captured data. Verified: 156/156 hook tests green, run from the worktree root. Source: owner 2026-09-01 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XehTac5TJNmPAskwrPp7rJ Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Local runners instead of GitHub-hosted minutes: a Gitea instance (bootstrap seeds a local mirror), an act_runner (labels ubuntu-latest:host), and the lane build image, under ops/devlane/infra. No secrets: runner-token.seed is an empty placeholder (the real token comes from the owner) and is gitignored along with gitea runtime state. Runner tests deferred. Activation is two owner-gated steps, in order: bring the runner up with a real token, THEN flip CI runs-on from ubuntu-latest to a self-hosted label. Flipping before a runner is live would stall every open PR. Source: owner 2026-09-01 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XehTac5TJNmPAskwrPp7rJ Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
…t use workflow/checks/term_wall.py scans tracked files, a commit message, a commit range, or stdin for names that must not appear here — not affirmed, not negated, not cited — never spelling them and masking every hit. The commit-msg hook runs it beside the trailer check (a clone without the wall warns and lets the commit through; CI holds the wall). apply-push's content guard refuses a landing patch that carries such a name in added content or a path, and the landing message is refused the same way before the bridge commits it. Verified: tree scan of this lane exits 0; planted message, stdin, path and content each exit 1 with a masked hit; a missing message file refuses with exit 2 on the wire; hooks suite 156/156 OK. Source: original Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
The codex and claude levers keep their job captures under their own jobs/ directories, which the ignore for the grok lever's root did not cover; a git add -A swept two write clones and their captures into a local commit before it was noticed and reset. Every lever job root is now ignored. Source: original Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Authored from the contract by a producer other than the implementer: each test runs term_wall.py as a subprocess in its own temporary git repository with a test-only pattern and asserts exit code and output shape — tree, message file, range, stdin, conf-file fallback, every refusal class, masking, binaries skipped. Red at this commit: 14 of 15 fail, identically over three runs. Source: original Co-Authored-By: GPT-5.6 Sol <noreply@openai.com> Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
term_wall.py reads its pattern from TERM_WALL, else ops/bin/term-wall.conf (machine-local, gitignored, an .example beside it), else refuses on the wire; every hit is masked. The commit-msg hook exports the pattern from the conf and refuses on a hit, warning through on a refusal like the trailer check. apply-push's content and message guards take the same pattern and refuse when none is available — the lever cannot look, so it does not land. CONTRACT-term-wall.md carries the contract verbatim. Source: original Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Same pin as the org action's contract: hit locations carry no colon, title and body are separate surfaces, refusal classes are named. The implementation moves to it; the tests stand. Source: original Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
A composite action cannot read vars (GitHub refuses the template: 'Unrecognized named-value: vars', PR#8 run 33568333825), so the calling step passes env TERM_WALL from vars.TERM_WALL and the action refuses when it did not. Same for the self-test's planted fault. Source: original Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
A mutable tag (`@v4`, `@v2`) lets whoever controls the upstream tag change what this workflow runs. Pin checkout, setup-php and cache to the commit each tag resolves to today; the tag stays as a comment. Source: original Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY Apply-Push-Job: 20260901T230110Z-apply-push-b4b8d4 Patch-SHA256: c1b69e625272039008a976d622d0f824ece2cfd936f36bd4e1ea63fa8288918c
The pinned wire: one summary line on a clean run, one `<surface>: <location>: <line>` per hit with the location never carrying a colon, four refusal classes (`pattern`, `git work tree`, `message`, `range`). Implementation moves; the tests stand. Source: original Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY Apply-Push-Job: 20260901T230301Z-apply-push-8bf543 Patch-SHA256: 18a95460cadb216e175fcbbfaad7424db85f9280ea13b2d19dd7a99da09dc5c9
Add the organisation's term wall to the `ci` job, right after checkout, pinned to the commit under review in minspec/.github#8. The step reads its pattern from the repository variable TERM_WALL and refuses when that is unset, so an unconfigured repository fails instead of passing. Source: original Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY Apply-Push-Job: 20260901T231003Z-apply-push-db7712 Patch-SHA256: 35bebcb925860d46a10042fcd31e8877c9a1208df74397d30dbda1672a7e2728
ops: the dev-lane, copied over — dispatch and everything else
minspec/.github#10 pins the content surface to every tracked blob, read from the object store, bytewise, symlinks never followed. Point the wall step at that merge. Source: original Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY Apply-Push-Job: 20260902T004028Z-apply-push-4faea8 Patch-SHA256: 57e5b08eab2bf07672c3ea101dcf7443de3419d46713583a712cf8cef7c1c6ba
repo: move the wall to the object-store scan
Process-group termination can leave dead descendants in zombie state until container PID 1 reaps them. Make the isolation assertions distinguish those non-runnable processes from surviving workers instead of relying on kill(pid, 0) alone. Source: original Co-Authored-By: OpenAI Codex <codex@openai.com>
…ssues Treat zombied descendants as terminated in dev-lane isolation tests
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.
Release sync: everything on
devsince the last sync, rebased onto the release branch. Today: the term wall in CI, the object-store content scan, theeditedtrigger, pinned actions and reusable workflows, and the review resolution.🤖 Generated with Claude Code
https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY