Skip to content

ops: the dev-lane, copied over — dispatch and everything else - #7

Merged
xor-machine merged 12 commits into
devfrom
ops/dev-lane
Sep 1, 2026
Merged

ops: the dev-lane, copied over — dispatch and everything else#7
xor-machine merged 12 commits into
devfrom
ops/dev-lane

Conversation

@xor-machine

@xor-machine xor-machine commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

The MinSpec dev-lane: dispatch, task, harness, telemetry, fixtures, hooks, workflow checks and infra under ops/devlane, with the operator scripts under ops/bin. Copied from the maintainer's private lane and scrubbed of every trace of its origin; this branch was rewritten once, with the owner's permission, to drop the unscrubbed history.

Gates this lane brings

  • Term wall, ops/devlane/workflow/checks/term_wall.py, contract in CONTRACT-term-wall.md. Pattern is configuration only (ops/bin/term-wall.conf locally, the TERM_WALL repository variable in CI); the tree never spells what it bans. Tests were written by Codex against the contract before the implementation existed (red 14/15), the implementation by Claude (green 15/15); where the two read the contract differently the contract was pinned in favour of the tests, and both amendments were ratified by an independent Codex adjudication (the second on live runner evidence).
  • Commit-message hook and the apply-push lever refuse anything the wall would refuse.
  • CI now runs the organisation's wall action (minspec/.github#8) and pins every action to a commit.

Review resolution (Codex sweep of this branch)

  • P1, launch.py owner name. Refuted: the value is the maintainer's own handle, which is not a banned term.
  • P2, mutable action tags in ci.yml. Fixed in e178ae4: checkout, setup-php and cache pinned to release commits.
  • P2, unpinned npm/apt in the Dockerfile. Deferred with a note for the owner: the lane image is developer tooling, not a shipped artefact; pin when the image gets a release process.
  • P2, identity residue in isolation.py, bootstrap.sh, hooks/tests/corpus.py. Ruled not a leak: the maintainer's own identity, present by design as the lane's owner.
  • P3, synthetic envelope path. Noted; fixture-only.

Outstanding for the owner

🤖 Generated with Claude Code

https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY

@xor-machine
xor-machine marked this pull request as draft September 1, 2026 18:27
xormania and others added 4 commits September 1, 2026 18:21
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
xormania and others added 8 commits September 1, 2026 18:45
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
@xor-machine
xor-machine marked this pull request as ready for review September 1, 2026 23:10
@xor-machine
xor-machine merged commit e636834 into dev Sep 1, 2026
2 checks passed
xor-machine added a commit that referenced this pull request Sep 2, 2026
ops: the dev-lane, copied over — dispatch and everything else
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.

2 participants