Severity: P1 critical
Problem
Hard gates trust writable files under .codearbiter/.markers/ as proof that a privileged review path already passed.
Source evidence:
plugins/ca/hooks/pre-bash.py:449-467 trusts .codearbiter/.markers/security-gate-passed when it is fresh and contains the digest of each sensitive added line.
plugins/ca/hooks/security-pass.py:75-90 writes that marker unconditionally for the current diff. The script itself does not verify that crypto-compliance or secret-handling actually ran.
plugins/ca/hooks/pre-bash.py:508-524 trusts .codearbiter/.markers/migration-gate-passed for migration commits.
plugins/ca/hooks/migration-pass.py:82-95 writes migration digests unconditionally for current migration files.
plugins/ca/skills/decision-lifecycle/SKILL.md:31-38 authorizes ADR writes by touching .codearbiter/.markers/adr-authoring-active.
plugins/ca/hooks/pre-write.py:36-42 and pre-edit.py:64-70 allow ADR writes whenever that marker exists and is fresh.
The Write/Edit guards do not protect .codearbiter/.markers/*, and pre-bash.py does not block direct execution of security-pass.py, migration-pass.py, or touch .codearbiter/.markers/adr-authoring-active.
Reproduction
In a throwaway enabled repo, stage a crypto change containing hashlib.md5(...).
Control case:
without marker exit 2
without marker stderr BLOCKED [H-09b]: This commit introduces crypto/TLS changes, but no security-gate pass is recorded ...
Then hand-write .codearbiter/.markers/security-gate-passed with the line_digest() of that added line, without running any security review.
Observed:
forged marker exit 0
forged marker stderr
The same class applies to migration-gate-passed by writing content_digest() values, and to ADR authoring by creating adr-authoring-active.
Impact
The marker files are the mechanism that turns a BLOCK into an allow. Because they are ordinary writable repo files and their producer scripts can be invoked directly, an agent can approve its own security, secret, migration, or ADR gate without the corresponding reviewer/skill ever running.
This collapses the hard-gate model to prose compliance.
Smallest credible fix
Do not treat a repo-writable marker as sufficient authority by itself.
Possible directions:
- Block direct Write/Edit/Bash mutation of load-bearing marker files.
- Block direct
security-pass.py and migration-pass.py execution outside a sanctioned gate context.
- Bind marker creation to a command-scoped nonce or signed receipt emitted by the reviewing gate, not just to diff content.
- Add regression tests that direct marker writes and direct marker-script invocations cannot unblock H-09b/H-10b/H-14/H-11.
Duplicate check
Checked existing issues with:
gh issue list --repo arbiterForge/codeArbiter --state all --search "security-gate-passed OR migration-gate-passed OR adr-authoring-active OR marker forge OR forge marker OR marker bypass"
No matching marker-forgery issue was returned.
Severity: P1 critical
Problem
Hard gates trust writable files under
.codearbiter/.markers/as proof that a privileged review path already passed.Source evidence:
plugins/ca/hooks/pre-bash.py:449-467trusts.codearbiter/.markers/security-gate-passedwhen it is fresh and contains the digest of each sensitive added line.plugins/ca/hooks/security-pass.py:75-90writes that marker unconditionally for the current diff. The script itself does not verify that crypto-compliance or secret-handling actually ran.plugins/ca/hooks/pre-bash.py:508-524trusts.codearbiter/.markers/migration-gate-passedfor migration commits.plugins/ca/hooks/migration-pass.py:82-95writes migration digests unconditionally for current migration files.plugins/ca/skills/decision-lifecycle/SKILL.md:31-38authorizes ADR writes by touching.codearbiter/.markers/adr-authoring-active.plugins/ca/hooks/pre-write.py:36-42andpre-edit.py:64-70allow ADR writes whenever that marker exists and is fresh.The Write/Edit guards do not protect
.codearbiter/.markers/*, andpre-bash.pydoes not block direct execution ofsecurity-pass.py,migration-pass.py, ortouch .codearbiter/.markers/adr-authoring-active.Reproduction
In a throwaway enabled repo, stage a crypto change containing
hashlib.md5(...).Control case:
Then hand-write
.codearbiter/.markers/security-gate-passedwith theline_digest()of that added line, without running any security review.Observed:
The same class applies to
migration-gate-passedby writingcontent_digest()values, and to ADR authoring by creatingadr-authoring-active.Impact
The marker files are the mechanism that turns a BLOCK into an allow. Because they are ordinary writable repo files and their producer scripts can be invoked directly, an agent can approve its own security, secret, migration, or ADR gate without the corresponding reviewer/skill ever running.
This collapses the hard-gate model to prose compliance.
Smallest credible fix
Do not treat a repo-writable marker as sufficient authority by itself.
Possible directions:
security-pass.pyandmigration-pass.pyexecution outside a sanctioned gate context.Duplicate check
Checked existing issues with:
No matching marker-forgery issue was returned.