You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .agents/skills/bootstrap-diagnostics/SKILL.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -65,7 +65,8 @@ When any diagnostic needs captain attention, report the plain consequence and re
65
65
A `config/fork-sync-upstream is unusable` detail is not a network failure: the check refused a configured comparison base, so handle it as `CURRENCY_BASE` below.
66
66
-`GROSSREINSCHIFF: weekly fleet cleanup sweep is due (...)` - this home has not completed its Thursday cleanup sweep for the current week; load the `grossreinschiff` skill and run it.
67
67
Nothing is broken: the line is a cadence reminder, and it repeats each session start until `bin/fm-grossreinschiff-due.sh --record` marks a sweep that actually produced a report.
68
-
The reported window-open days say how late the sweep is, and a large number is itself worth reporting to the captain because it means this home has been dark or the reminder has been passed over.
68
+
The reported window-open days say only how far into the current week's window this session start falls; the count is bounded to 0 through 6 and never measures how long the home has been dark.
69
+
Judge staleness from the `last swept:` date in the same line: a date more than one week before the current Thursday means whole weeks were missed, and that is what is worth reporting to the captain.
69
70
In a session that did not get the fleet lock this line is advisory only: the sweep changes records, so the session holding the lock owns it - note it and leave it.
70
71
-`TANGLE: <remediation>` - the primary checkout is stranded on a feature branch instead of its default branch; `AGENTS.md` section 8 explains why this guard exists and what it protects.
71
72
The work is safe on that branch ref; restore the primary to its default branch with the printed `git -C <root> checkout <default>`, then re-validate that branch in a proper worktree.
Copy file name to clipboardExpand all lines: .agents/skills/grossreinschiff/SKILL.md
+15-5Lines changed: 15 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,7 +22,8 @@ None is hypothetical, and `docs/grossreinschiff.md` carries the incident behind
22
22
23
23
**Cadence: weekly, on Thursday.**
24
24
`bin/fm-grossreinschiff-due.sh` owns it and nothing else - its header states the rule, the state file, and why there is no separate scheduler.
25
-
The sweep runs at the first session start on or after Thursday; a vessel that was dark on Thursday sweeps late rather than skipping the week, and the due line says how late.
25
+
The sweep runs at the first session start on or after Thursday; a vessel that was dark on Thursday sweeps late rather than skipping the week.
26
+
The due line reports how far into the current window the sweep is, a count bounded to 0 through 6; its `last swept:` date is the field that shows how many weeks were missed.
26
27
27
28
## The five safety properties
28
29
@@ -53,27 +54,36 @@ These bind every item below. They are properties, not preferences: each one is a
53
54
## The landedness ladder
54
55
55
56
Item 1 turns entirely on this, and getting it wrong is the one mistake in this skill that destroys work.
56
-
Apply the tests in order and stop at the first that settles the branch.
57
+
Apply the tests in the table's order - **A**, **P**, **E**, **C**, **X** - and stop at the first that settles the branch.
58
+
The order is measured, not a matter of taste: the trap notes below say what moving a rung costs.
57
59
The technique is not this skill's invention: the worktree-scoped form is owned by `bin/fm-teardown.sh`, whose header is the authority on what "landed" means for a task's own work, and the per-branch form below was worked out and validated in `data/bridge-branch-sprawl-classify/report.md` §1.
58
60
That report is captain-private to the vessel that ran it, so a reader on another home cannot open it - `docs/grossreinschiff.md` carries the measurements and the reproduction, and is tracked.
59
61
60
62
| Code | Test | Settles |
61
63
|:-:|---|---|
62
64
|**A**|`git merge-base --is-ancestor <branch> <default>`| landed. Only ever a *positive* result - a negative one means nothing here. |
63
65
|**P**| Patch-id equality: `git diff $(git merge-base <default> <branch>) <branch> \| git patch-id --stable` against `git diff <merge_sha>^ <merge_sha> \| git patch-id --stable`, where `<merge_sha>` is the forge's recorded merge commit for that branch's PR *and* is itself an ancestor of the default branch. | landed. This is the test that handles the squash flow, and it does most of the work. |
66
+
|**E**| The branch tip's tree equals its merge-base tree. Only meaningful *after***A** and **P**: for a branch that is already an ancestor of the default branch the merge base **is** the branch, so this holds trivially and would relabel every ordinarily landed branch. | landed vacuously - the branch has commits but changes nothing against its fork point, so there is nothing to land. |
64
67
|**C**|`git merge-tree --write-tree <default> <branch>` exits 0 **and** its first line equals `git rev-parse <default>^{tree}`. | landed - the branch adds nothing the default branch does not already have. |
65
-
|**X**| Every path the branch adds is absent from the default branch's tree **and**`git log <default> -- <path>` is empty, so it never existed there at any point. | not landed. |
66
-
|**E**| The branch tip's tree equals its merge-base tree. | landed vacuously - there is nothing to land. |
68
+
|**X**|**Precondition: the branch adds at least one path.** A branch that adds none - a modify-only or delete-only branch, the ordinary shape of a small fix - falls through to `undetermined`, never to `not landed`. With that precondition met: every path the branch adds is absent from the default branch's tree **and**`git log <default> -- <path>` is empty, so it never existed there at any point. | not landed. |
67
69
| - | none of the above |**undetermined**. Never a deletion candidate. |
68
70
69
-
Two traps, both hit in practice:
71
+
Four traps.
72
+
The first two were hit in practice; the last two were caught by applying this skill's own checklist to this skill before it shipped, and `docs/grossreinschiff.md` records that.
70
73
71
74
-**C is inconclusive far more often than it looks.**
72
75
`git merge-tree` exits non-zero on a conflict, and an old branch whose files the default branch has since edited conflicts routinely.
73
76
A caller that reads only the tree hash and drops the exit status reads a conflict as "adds content" - which reads as "not landed" - and that is a delete-real-work bug.
74
77
Measured on this repo, 2026-08-03: over 52 merged-PR branches the ladder settled 18 by **A**, 33 by **P**, 1 by **C**, and 0 undetermined. In the same session, **C** applied alone with its exit status dropped reported "adds content" for all six ancestry-unmerged branches it was tried on - and for the three of those six that are branches of merged pull requests, the full ladder settles every one as landed.
75
78
-**P needs the merge commit verified as an ancestor of the default branch**, not merely recorded by the forge.
76
79
A recorded merge commit that is not on the default branch proves nothing about the default branch.
80
+
-**A vacuous universal is a false certainty.**
81
+
**X** is quantified over the paths the branch adds, so a branch that adds none satisfies both of its conjuncts on zero evidence and would be handed the definitive verdict `not landed`.
82
+
That state is reachable exactly where this ladder is routine: **A** fails because the fleet squashes, **P** fails when no forge merge commit is recorded or it is not an ancestor of the default branch, and **C** goes inconclusive on the conflict above.
83
+
Safety property 3 bars promoting an unsettled branch to a definitive verdict, so the precondition in the **X** row is the rule and has no exception.
84
+
-**E's place in the order is load-bearing in both directions.**
85
+
It must come after **A**, because a branch that is already an ancestor has itself as its merge base and would be relabelled `landed (vacuous)` on a triviality.
86
+
It must come before **C**, because a content-free branch cannot make `merge-tree` conflict, so **C** would absorb it as plain `landed` and **E** would never fire at all.
77
87
78
88
Patch-id is safe for rename-only branches - it hashes the `diff --git a/… b/…` header paths, so a pure rename still produces a distinct hash rather than an empty one.
79
89
Before trusting a P result across a large set, check for patch-id collisions across the whole set, as §1 of the sprawl report does; a hash shared by two different pieces of work invalidates every P verdict in the batch.
Copy file name to clipboardExpand all lines: docs/grossreinschiff.md
+30-2Lines changed: 30 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -116,10 +116,18 @@ A check registration and its trust binding for `graph-freshness`, with no `state
116
116
117
117
Measured on `Freudator86/firstmate` at `origin/main` = `d126ea61`, 2026-08-03, over the 52 branches of merged pull requests that still exist on `origin`.
118
118
119
-
The ladder, applied in order A → P → C, stopping at the first test that settles a branch:
119
+
**The applied order is A → P → E → C → X**, stopping at the first test that settles a branch.
120
+
121
+
The published measurement below ran A → P → C, before E and X were placed in the order.
122
+
Inserting E between P and C does not change it: none of the 34 non-ancestor branches was content-free, so E fires on none of them and these counts stand as measured.
For a branch that is already an ancestor of the default branch, `merge-base(default, branch)`**is** the branch, so E's tree-equality condition holds trivially for every ordinarily landed branch: placed first, it would have relabelled all 18 ancestry-settled branches above as `landed (vacuous)`.
128
+
Placed after A it sees only the 34 non-ancestor branches, and fires on none of them.
129
+
It must still come before C, because a content-free branch cannot make `merge-tree` conflict, so C would settle it as plain `landed` and E would never fire at all.
130
+
123
131
**Ancestry alone would have called 34 of 52 landed branches unmerged.** On `coditan-bridge` the same reading was worse: 152 of 154 read as unmerged, because PR #1 is the only pull request in that repository's history merged with a real merge commit - the only merge commit in 7,724 commits on `main`. Everything else was squashed, so branch tips are unreachable from `main` by construction. "152 not merged" is a restatement of "we squash", nothing more.
124
132
125
133
### The content test is inconclusive far more often than it looks
@@ -163,7 +171,9 @@ Three options were considered.
163
171
The rule, owned by the script's header: **due when the last recorded sweep predates the most recent Thursday 00:00 local.**
164
172
165
173
- An absent record means never swept, which is due. A home that has never swept is the one most likely to have accumulated something, and it joins the Thursday rhythm after its first sweep.
166
-
- A home that ran no session on Thursday sweeps at its next session start rather than skipping the week, and the line says how many days into the window it is.
174
+
- A home that ran no session on Thursday sweeps at its next session start rather than skipping the week, and the line says how many days into the *current* window it is.
175
+
That count is `days_back`, bounded to 0 through 6, so it is a window position and never a measure of lateness: a home three weeks dark that wakes on a Thursday reads 0.
176
+
The line's `last swept:` date is the field that carries the staleness, and it is what the reader judges by.
167
177
- A corrupt or unparseable record reads as never swept, so it makes the sweep due rather than silently skipping it.
168
178
- The week boundary is today's local midnight minus whole days, so a daylight-saving change inside the preceding week moves it by an hour twice a year. An hour of drift cannot make a weekly sweep fire twice or skip a week.
169
179
@@ -173,6 +183,24 @@ Through the pin, like every other instruction-surface change: it lands on the de
173
183
174
184
One All-Ships notice announces the day and what the sweep covers. That is an announcement, not the mechanism - a vessel that never reads the notice still gets the due line from its own session start, and a vessel that reads the notice but never pins never sweeps.
175
185
186
+
## The sweep's own checklist, applied to the sweep
187
+
188
+
Before this skill shipped, its own nine-item checklist was run against its own prose.
189
+
It got three hits, all the same defect class the sweep exists to clean, and all three were fixed before delivery.
190
+
191
+
-**The due line's window-open count is bounded to 0 through 6 by construction**, so it can never report a home dark for weeks: a home three weeks behind that wakes on a Thursday reads 0, while one merely four days late reads 4.
192
+
The handling guidance told the reader to escalate on a large number, which is an instrument that never fires - checklist item 3.
193
+
The `last swept:` date already carried the signal, and the guidance now points there.
194
+
-**Ladder rung X returned a definitive `not landed` for a branch that adds no paths**, because a universal over an empty set is vacuously true.
195
+
A verdict on zero evidence is a false certainty, and it is exactly what safety property 2 warns about when it bans judging by ancestry - and property 3, which bars promoting an unsettled branch to a definitive verdict.
196
+
X now carries the precondition in its own row.
197
+
-**Ladder rung E could never be reached** in the A → P → C → X → E order it was first written in, because C absorbs every content-free branch first.
198
+
An unreachable rung is dead text - item 3 again.
199
+
E now sits between P and C, and the order caveat is recorded above because moving it either way is measurably wrong.
200
+
201
+
This is recorded plainly because it is evidence the checklist works, not an embarrassment to soften.
202
+
The night of 2026-08-02/03 produced the checklist from other people's surfaces; the first thing it was pointed at was its own, and it found three.
203
+
176
204
## Known limits
177
205
178
206
Stated here because the skill requires every sweep to state its own, and the mechanism should hold itself to the same rule.
0 commit comments