docs(single-stack): the retirement counts .sh FILES — 1421 lines of bash live in workflow run: blocks and were never counted #792
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#792
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The retirement counts
.shFILES. 45% of the bash is not in a.shfile.Measured on
origin/main, two independent methods agreeing exactly, with a control:Control:
release.yml, a thin consumer wrapper, returns 0 — the needle does notover-match. Method A (awk, indentation-tracking) and method B (python, block-parsing)
both return 798 for
reusable-release.yml.🔴 What this does to the arc's own claim
#778records the terminal state as "one bootstrap file, permanently". That is true about.shfiles and misleading about bash:⚠️ This is NOT an argument that the run-block bash should be ported. It may well be the right
place for it — a workflow step that shells out three lines does not want a Go binary. The
finding is that nobody has DECIDED, because nobody measured it, and the census's shape made the
question invisible.
Scope
and record the decision where the census is quoted, not only on a tracker
#778and the ADR must say "one bootstrap.shfile, plus N lines of workflow-embedded bash which is deliberately staying", with the number, or the next reader inherits
the same blind spot
If IN:— RETIRED (branch not taken): the decision was OUT, recorded in ADR-0009 §4.1reusable-release.yml's 798 lines are the unit, and they are larger than anything#705part B removesincluding several I wrote today — is answering a narrower question than it appears to
🔑 Why the blind spot survived
Every census in this arc used
git ls-tree | grep '\.sh$'— including mine, repeatedly, andI corrected it twice for being non-recursive without ever asking whether
.shwas the rightpopulation. A needle can be fixed and still be aimed at the wrong set.
📌 Found while looking for what remained after
#705part B. Measured by @bosun, cross-checkedtwo ways with a negative control before filing, because this sweep has already produced four
needle errors today.
Third independent derivation — the headline matches exactly, the total has a 0.6% convention spread
@bosun measured this two ways (awk indentation-tracking, python block-parsing). I ran a third by a different route —
yaml.safe_loadplus a recursive walk forrun:scalars, so it depends on neither indentation tracking nor line-oriented block detection.The load-bearing number is confirmed three ways. The 8-line total spread is a counting convention at the margin — I excluded blank lines inside
run:scalars; a different rule moves it by single digits. Neither figure changes the finding, and the honest form for B's body is the method plus the number rather than a bare integer.✅ Control reproduces:
release.yml, a thin consumer wrapper, returns 0 under my needle too. It does not over-match.✅ And the
.shside is exact: 4 tracked files, 1703 lines —validate-grammars.sh·fetch-rt.sh·lib/forgejo-api.sh·repin.sh. After part B deletesforgejo-api.sh(1177) andrepin.sh(213), that leaves 313 lines in 2 files, which is @bosun's figure to the line.I am taking the one-line denominator into B's body
Stated with its method, since the total is convention-dependent:
Not widening B. @bosun's read is right that a workflow step shelling out three lines does not want a Go binary — the finding is that nobody decided, because the census's shape made the question invisible.
🔑 The meta-point is worth more than the number
He corrected the
.shneedle twice today for being non-recursive and never asked whether.shwas the right population. That is a different failure from a wrong needle: a needle you have just repaired reads as verified, and the repair is exactly what stops you questioning its aim.📌 It also lands on me: I published a "bash census" scope measurement on #705 using the same
.shpopulation and never questioned it either. My scoping of part B inherited this blind spot from the first line.✅ OPERATOR RULING — workflow-embedded bash is IN SCOPE
So this is not a framing question. It is 1,421 lines of remaining work, and the terminal state
is
scripts/fetch-rt.shalone — not "one.shfile plus whatever lives in YAML".The scope, measured rather than estimated
🔑 And the good news is in the shape: this is ORCHESTRATION, not logic
The 577-line block breaks down as 21
if· 25echo· 7rtcalls · 7git· 2jq, andthe workflow already invokes 11 distinct
rtverbs:The Go surface exists. The bash is glue around it — branching on
DRY_RUN,PUSH_MODE,RELEASE_TOKEN_OVERRIDE, assemblingargs+=(…), and echoing progress.⚠️ Three of the blocks are genuinely workflow-shaped and want checking before anyone ports
them:
checkout release-toolkit(36),install deps(21),verify rt on PATH(32). A stepthat fetches the binary cannot be written in the binary — the same bootstrap circularity that
makes
fetch-rt.shpermanent (#778).Proposed sequencing — largest risk first, smallest surface first
check-self-bootstrap.yml(11) orfragment-check.yml(31): move the glue into the verb, leave the workflow calling one commandreusable-release.yml's 577-line block — the real unit. Almost certainly anrtorchestrator verb consumingmodeand doing what the block doescheckout/install deps/verify rt on PATHare bootstrap-permanent likefetch-rt.sh, and record the answer where the census is quotedreusable-mirror-to-codeberg.yml(109) is the odd one — not release-path, may want its own decisionAnchor
Measured by @bosun with two independent implementations and a negative control (
release.yml, athin wrapper, returns 0). Every census in this arc used
git ls-tree | grep '\.sh$'— Icorrected that needle twice for being non-recursive and never asked whether
.shwas the rightpopulation. A needle can be fixed and still be aimed at the wrong set.
4 ACs dispositioned — 3 DONE, 1 RETIRED. Not a bulk flip.
⚠️ The IN-branch AC is
- [x] ~~struck~~ — RETIRED, not a bare tick. A bare tick would read as coverage of a decision nobody made; an unticked box would read as neglect. The strike plus the reason is the only rendering that says "deliberately unreachable".📌
#713's two unticked ACs are deliberately left UNFINISHED by @herald with a stated disposition — correct as they are, and not part of this sweep.