Invariant
Executable procedure in the standardize-repo skill ships as an executable
asset. Where a mode's steps are load-bearing shell — ordering, fail-closed
guards, frozen object IDs — the operator runs a shipped script rather than
lifting fenced blocks out of prose into files of their own.
mode-update.md is the exception, and it is the largest body of shell in the
skill.
Current violation (observed 2026-08-11)
ai/skills/repo/standardize-repo/references/mode-update.md:
|
|
| total lines |
3,494 |
fenced sh/bash lines |
1,882 (54% of the file) |
| fenced blocks |
31 |
| longest single block |
1,196 lines |
| invocations of a shipped asset |
5 (diff-template.sh ×2, verify-applied.sh ×1, shepherd's check-codex-cloud-review.sh ×2) |
The skill does ship assets — diff-template.sh (80 KB),
verify-applied.sh (107 KB), detect-project-type.sh,
template-owned-files.txt. What is missing is the guarded update procedure
itself: §1 preparation and the read-only offline clone, the non-adoption
rehearsal, §2 apply / reconcile / promote, and the rollback. Those exist only
as prose the operator must transcribe into files before anything can run.
A 1,196-line fenced block is a program. It defines shell functions
(run_guarded_copier, guarded_checkout_id, nonadoption_*), maintains state
across steps in $GUARDED_STATE, and freezes Git object IDs that later steps
re-compare — none of which survives being pasted one block at a time.
This is specific to update mode, not a house style:
| mode |
fenced shell lines |
mode-update.md |
1,882 |
mode-new-repo.md |
168 |
mode-adopt-existing.md |
87 |
mode-audit.md |
13 |
Why it costs correctness, not just effort
The document is aware of this. It warns that its blocks "are written to survive
bash -eu", that they "get lifted piecemeal", that LC_ALL=C must be pinned
"per command, never a one-time export at the top of a section" — all of which
are mitigations for transcription, and all of which assume the operator
performs it faithfully.
Transcription is where defects enter. In one session updating three consumer
repos to v4.27.0 (#413 and siblings), the operator hand-transcribed §1/§2 into
scripts and introduced two parsing bugs of their own while doing adjacent §6
work — one of which reported 41 labels as about to be overwritten when the true
answer was zero. Neither bug was in the skill; both were in the copy. A shipped
runner removes that entire class, and test-skills.sh-style fixtures could
then exercise it.
Verify
S=ai/skills/repo/standardize-repo
awk '/^```(sh|bash)$/{b++;inb=1;n=0;next}
/^```$/{if(inb){t+=n; if(n>max)max=n}; inb=0}
inb{n++}
END{printf "blocks=%d shell_lines=%d longest_block=%d\n", b, t, max}' \
"$S/references/mode-update.md"
ls "$S/assets/"
grep -oE 'assets/[a-z-]+\.sh' "$S/references/mode-update.md" | sort -u
Output means: a large shell_lines / longest_block alongside an
assets/ listing that contains no update-mode runner means the recipe is still
prose and the violation stands. It is resolved when the guarded procedure is
invoked from assets/ and the fenced blocks shrink to the calls plus the
decisions an operator must make (the reviewed-answer choices, the conflict
adjudication) — which are genuinely prose and should stay that way.
Acceptance criteria
Related
Invariant
Executable procedure in the
standardize-reposkill ships as an executableasset. Where a mode's steps are load-bearing shell — ordering, fail-closed
guards, frozen object IDs — the operator runs a shipped script rather than
lifting fenced blocks out of prose into files of their own.
mode-update.mdis the exception, and it is the largest body of shell in theskill.
Current violation (observed 2026-08-11)
ai/skills/repo/standardize-repo/references/mode-update.md:sh/bashlinesdiff-template.sh×2,verify-applied.sh×1, shepherd'scheck-codex-cloud-review.sh×2)The skill does ship assets —
diff-template.sh(80 KB),verify-applied.sh(107 KB),detect-project-type.sh,template-owned-files.txt. What is missing is the guarded update procedureitself: §1 preparation and the read-only offline clone, the non-adoption
rehearsal, §2 apply / reconcile / promote, and the rollback. Those exist only
as prose the operator must transcribe into files before anything can run.
A 1,196-line fenced block is a program. It defines shell functions
(
run_guarded_copier,guarded_checkout_id,nonadoption_*), maintains stateacross steps in
$GUARDED_STATE, and freezes Git object IDs that later stepsre-compare — none of which survives being pasted one block at a time.
This is specific to update mode, not a house style:
mode-update.mdmode-new-repo.mdmode-adopt-existing.mdmode-audit.mdWhy it costs correctness, not just effort
The document is aware of this. It warns that its blocks "are written to survive
bash -eu", that they "get lifted piecemeal", thatLC_ALL=Cmust be pinned"per command, never a one-time export at the top of a section" — all of which
are mitigations for transcription, and all of which assume the operator
performs it faithfully.
Transcription is where defects enter. In one session updating three consumer
repos to v4.27.0 (#413 and siblings), the operator hand-transcribed §1/§2 into
scripts and introduced two parsing bugs of their own while doing adjacent §6
work — one of which reported 41 labels as about to be overwritten when the true
answer was zero. Neither bug was in the skill; both were in the copy. A shipped
runner removes that entire class, and
test-skills.sh-style fixtures couldthen exercise it.
Verify
Output means: a large
shell_lines/longest_blockalongside anassets/listing that contains no update-mode runner means the recipe is stillprose and the violation stands. It is resolved when the guarded procedure is
invoked from
assets/and the fenced blocks shrink to the calls plus thedecisions an operator must make (the reviewed-answer choices, the conflict
adjudication) — which are genuinely prose and should stay that way.
Acceptance criteria
assets/, covering at minimum §1 preparation + offline clone, thenon-adoption rehearsal, and §2 apply / reconcile / promote.
mode-update.mdinvokes them instead of inlining them; what remainsfenced is the operator's decisions, not the mechanism.
guard is most destructive.
skills tests, so the recipe has regression coverage it cannot have today.
still refuses to proceed while any
__REVIEW_REQUIRED__sentinel stands,rather than defaulting them.
Related
both make the same argument from different ends: update mode's correctness
currently rests on an operator executing a long prose procedure exactly.
diff-template.shinternals; adjacent only in that they concernthe assets that are shipped.