Skip to content

release: dev -> master - #13

Merged
xormania merged 27 commits into
masterfrom
release/dev-into-master
Sep 2, 2026
Merged

release: dev -> master#13
xormania merged 27 commits into
masterfrom
release/dev-into-master

Conversation

@xor-machine

Copy link
Copy Markdown
Contributor

Release: dev merged into master, conflicts resolved to dev. Earlier rebase releases left master with copies of dev commits, so a plain merge conflicts on files changed since; the resulting tree is identical to dev. Needs a merge commit: linear history off on master.

🤖 Generated with Claude Code

https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY

xormania and others added 27 commits September 1, 2026 12:03
Three changes, mirroring the constitution's new lane: the Authority
Model gains the lane bullet; the Incubation Contribution Boundary is
scoped to unsolicited patches with a pointer to the lane; Source
Authority names the lane a controlled source path. Reason: two
statements of one rule must not diverge — the org governance now
cites the lane where the constitution defines it.

Source: owner 2026-09-01
Source: original
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XehTac5TJNmPAskwrPp7rJ
Tracked .serena/project.yml and .mcp.json, uniform across the
MinSpec org, so every checkout and worktree of this repository is a
Serena-served agent workspace with identical scope. The PHP backend
is Phpactor (PHAR-managed, no Node). Mate is deliberately absent:
it is application-scoped by nature and lives in minspec/workbench,
the org's application host.

Source: owner 2026-09-01
Source: original
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XehTac5TJNmPAskwrPp7rJ
governance: mirror the maintainer-directed agent lane
repo: register Serena for agent sessions
CI on pull requests and on pushes to dev and the stable branch:
composer validate for PHP manifests, the create-project end-to-end
oracle where this repo is the skeleton, JSON/YAML validity
elsewhere. Public repo: GitHub-hosted runners are free; the check
name "ci" is the required context the dev ruleset will pin.

Source: owner 2026-09-01
Source: original
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XehTac5TJNmPAskwrPp7rJ
repo: real CI — the ci workflow on dev
Findings applied from the independent audit (CHANGES verdict):
workflow-level permissions contents:read; persist-credentials false
on checkout; every action pinned to a reviewed commit SHA with its
tag in a comment; Serena pinned in .mcp.json to the audited git
commit instead of floating uvx resolution.

Finding: [P1] workflows ran with default token permissions
Finding: [P1] .mcp.json launched unversioned uvx serena
Finding: [P2] mutable action tags across all repositories
Verified: python yaml.safe_load + json.load on the changed files

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
repo: workflow and MCP hardening from the security audit
…n CI

A composite action every repo's ci job runs: it scans tracked content,
file paths, the change's commit messages (base...head via the API, or
the pushed commit), the pull request title and body, and the branch
name for names that must not appear here — not affirmed, not negated,
not cited. The wall never spells what it refuses and masks every hit
it prints; a surface it could not read is a hit, never a pass. This
repo's own ci runs it and then proves it fires on a planted fault and
stays quiet on a clean neighbour.

Verified locally: 10/10 cases (clean tree and PR; planted content,
path, title, branch name, commit message via API and via push; API
unreachable) exit as specified, and the action's files pass their own
wall.

Source: original
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Two producers read the contract differently: the location of a hit
(with or without a colon), the pull request title and body as one
surface or two, and the names of the refusal classes. The contract now
pins all three in a table; 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
Authored from the contract by a producer other than the implementer:
each test runs term-wall.sh as a subprocess in its own temporary git
repository with a test-only pattern, simulating pull_request and push
events, and asserts exit code and output shape. Red at
this commit: 13 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
Apply-Push-Job: 20260901T225145Z-apply-push-ca3088
Patch-SHA256: 5c280fccf2f955ddce536df7b4d99ca4c652c5a7edd059354eab12a985bb92e1
…token

term-wall.sh reads its pattern only from TERM_WALL (the action takes it
from vars.TERM_WALL) and refuses on the wire when it is unset; commit
messages come from git (base..head, or the head commit on a branch
creation), fetched offline, never from an API, so the action holds no
token; every hit is masked; the self-test plants vars.TERM_WALL_PLANT
and proves the refusal. CONTRACT.md carries the contract verbatim.

Source: original
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Apply-Push-Job: 20260901T225148Z-apply-push-dc1f97
Patch-SHA256: 3f59b7252e7ae3b3e0c7894ec551f7e1811d1811f7ed285ef585232bb740fddb
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
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. The pattern now arrives from
the calling step (`env: TERM_WALL: ${{ vars.TERM_WALL }}`) because the
runner refuses `vars` inside a composite action; the action refuses
when the step passed nothing. ci.yml passes it.

Source: original
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Apply-Push-Job: 20260901T230235Z-apply-push-4be45d
Patch-SHA256: c8606262ab7780275c529792f1882bd9c94478fff501ad995d318c286ef7eeb7
repo: the term wall — names this organisation does not use, refused in CI
`pull_request` without `types` fires on opened, synchronize and
reopened only, so a title or body edited after the checks passed
reached the merge unscanned. Name the types and add `edited`; the
wall then runs against the current text.

Source: original
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Apply-Push-Job: 20260901T234631Z-apply-push-a1af92
Patch-SHA256: f9816cdf7b1a595a0a2c9e69366d5ae859daf5624cb7a5edb495fd8bf6a18491
A working-tree scan skipped what `grep -I` calls binary and followed
symlinks to their targets, so a tracked blob carrying the name could
land while the wall reported clean. The content surface is now every
tracked blob, read from the object store, bytewise; a symlink is
scanned as the blob it is, never followed; a blob that is not UTF-8
reports `[binary blob]` in place of the line.

Source: original
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Apply-Push-Job: 20260901T234752Z-apply-push-4f650a
Patch-SHA256: 82bfe322636865f3130a554e957100917ee1f99402bea2137f9635d8cc838575
Five subprocess tests, each in its own temporary repository: a blob
that is not UTF-8 carrying the planted fault, a symlink whose target
text carries it, a clean symlink to a clean file, a clean commit with
a dirtied working tree, and a committed fault deleted from the
working tree. Written against the pinned contract, before the
implementation; red until it moves.

Source: original
Co-Authored-By: Codex <noreply@openai.com>
Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Apply-Push-Job: 20260901T235011Z-apply-push-77cd09
Patch-SHA256: 7b9e0252dd5761078e3b1a1f88134326ef7d53ec10efdb4b55d5b9538c9d5e06
Enumerate the scanned commit's tree with `git ls-tree -r -z`, read
each blob with `git cat-file`, scan bytewise; a symlink is scanned as
the blob it is and never followed; a blob that is not UTF-8 reports
`[binary blob]` in place of the line; a blob that cannot be read is a
`git work tree` refusal. Implementation moves to the pinned contract;
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: 20260901T235752Z-apply-push-437ac9
Patch-SHA256: 47bcffbb08b404c5732c0e9ef2ed74a2344887559f096ab5c6dfe6f74048ccd2
The pinned content surface makes every tracked blob scannable, so
the pre-existing test asserting that a binary blob passed as clean
contradicts the contract. The binary-blob test written against the
amendment covers the case.

Source: original
Co-Authored-By: Codex <noreply@openai.com>
Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Apply-Push-Job: 20260901T235927Z-apply-push-91f0e5
Patch-SHA256: 5f57e606b263e185759beacf0f8ec59baa69a00b7b4c23c80e85b3c8e6aa3a9f
The content surface is the scanned commit's tree, so a planted file
that is only staged is not on it. The self-test now commits the plant
before expecting the wall to fire.

Source: original
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Apply-Push-Job: 20260902T000046Z-apply-push-aa7d57
Patch-SHA256: fa75a5987b8760303465c1ab5e6ec4a2aa9e52100f37a9e9a34a7537baa00fd6
repo: pin the content surface to the object store
repo: scan a pull request again when its text is edited
Workflows name master where they named main, and CODEOWNERS makes
the release branch the owner's to approve.

Source: original
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
Apply-Push-Job: 20260902T222636Z-apply-push-1b731f
Patch-SHA256: e9f8c08a0cade732915569a960cbd632ab7f6f3bf2164f5b583b1e8897fb7e78
repo: master is the release branch
Earlier rebase releases left master with copies of dev's commits, so
the merge conflicts on files changed since. Resolved to dev, the trunk.

Source: original
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jj94rkp3tfHAxUkTCthgY
@xor-machine
xor-machine marked this pull request as ready for review September 2, 2026 22:44
@xormania
xormania merged commit f507515 into master Sep 2, 2026
1 check passed
@xormania
xormania deleted the release/dev-into-master branch September 2, 2026 22:48
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