Skip to content

docs: complete the curated fork patch registry - #45

Merged
Freudator86 merged 6 commits into
mainfrom
fm/fm-admiralty-patch-inventar
Aug 1, 2026
Merged

docs: complete the curated fork patch registry#45
Freudator86 merged 6 commits into
mainfrom
fm/fm-admiralty-patch-inventar

Conversation

@Freudator86

Copy link
Copy Markdown
Collaborator

Intent

Complete the curated fork patch registry in docs/fork-patches.md so this vessel can move to the admiralty fleet repository. The commodore ordered a patch inventory BEFORE integration, on the explicit reasoning that a tool can enumerate the patches but cannot say why they exist, and that this part is not reconstructable later. The value of this work is therefore the WHY, not the list.

Starting point: the registry existed but carried only four rows while the fork had merged through PR #40, and the file itself named backfilling as an open decision. That decision is now taken: backfill.

What was done: all 84 fork-only, non-merge commits were enumerated exactly the way bin/fm-fork-sync-check.sh does it (git rev-list --oneline --no-merges upstream..fork, equivalence via git cherry), so the registry and the check mean the same set. Fork base de0b95b against canonical upstream a805766; git cherry finds zero patch-equivalent commits, which is stated in the header so that every 'absorbed' verdict is visibly a separate semantic judgment rather than a mechanical result.

Deliberate decisions a reviewer reading only the diff would not know:

  1. Each row carries four fields folded into the EXISTING table shape (What it does / Why it exists / Verdict / Scope). Adding columns rather than placing a second table beside the first was explicitly required. Do not propose splitting this into two tables or a per-commit section list.

  2. The primary source for the Why column is the associated pull request's '## Intent' section, NOT the diff. Where no PR survives or its text yields nothing, the row deliberately says 'Warum nicht mehr feststellbar' (German, quoted from the order, intentionally not translated). This is required behavior: an honest unknown is useful, while a plausible-sounding motive reconstructed from the diff is exactly the damage this task exists to prevent. Rows admitting an unknown are correct, not incomplete.

  3. The four pre-existing rows were re-verified rather than carried over, and all four were downgraded to 'Warum nicht mehr feststellbar'. This is correct and evidenced: the repository history was repointed, so a commit titled '(feat: configure Codex Graphify approval profile #1)' no longer corresponds to PR feat: configure Codex Graphify approval profile #1 in the current repository (PR feat: configure Codex Graphify approval profile #1 there is 'configure Codex Graphify approval profile', a different patch). Their previous rationales were written against an older upstream tip and were not trustworthy.

  4. The Scope column (ship-specific vs general) is the only field that steers a later action - it decides the integration target - so it is assigned per commit. No group verdicts were issued: the order explicitly warned that bulk handling is what made this divergence unreadable and that a bulk convergence would be the same mistake in reverse.

Hard constraints observed: nothing was converged, integrated, or absorbed from upstream; no git merge or cherry-pick; config/firstmate-update-base and config/fork-sync-upstream were left unset; and no shared surface other than docs/fork-patches.md was touched. This home is under a standing block against advancing its instruction surface from upstream - writing this registry is its own documentation, not an adoption.

Style: firstmate shared tracked material, so the repo's one-sentence-per-line rule applies.

What Changed

  • Backfilled docs/fork-patches.md from four rows to all 88 fork-only, non-merge commits between canonical upstream a805766 and the pinned fork snapshot dc6c1bc, enumerated the same way bin/fm-fork-sync-check.sh does (git rev-list --no-merges upstream..fork, equivalence via git cherry).
  • Extended the existing table in place with What it does, Why it exists, Verdict and Scope columns; the Why column is sourced from each pull request's ## Intent section and states Warum nicht mehr feststellbar where no usable PR intent survives, rather than reconstructing a motive from the diff. The four pre-existing rows were re-verified and all downgraded to that unknown, because the repository was repointed and their old PR references no longer resolve.
  • Added header prose defining the verdict and scope tests: git cherry finds zero patch-equivalent commits, so absorbed is a content-level judgment that must name the upstream file, rule or provenance carrying the effect, and it is distinguished from the fork-sync check's own filename-level absorbed prefilter in state/fork-sync.pending. The pin is documented as a deliberate snapshot, so a divergence from the live check's count is expected and is repaired by adding rows and re-stamping.

Risk Assessment

✅ Low: A one-clause documentation edit that replaces file-level evidence with the already-verified content-level evidence on a single row, leaving verdict, scope and every other row unchanged, and closing the last gap in the registry's own auditability rule.

Testing

I reproduced the registry's own enumeration exactly as bin/fm-fork-sync-check.sh performs it, in a throwaway bare repo fetched from both the fork and canonical upstream, and confirmed the 88 rows are a precise one-to-one chronological match for the 88 fork-only non-merge commits with git cherry reporting zero patch-equivalent commits. I then tested the substance rather than just the shape: every absorbed row's files exist upstream, every denied row's named absence really is absent (including 1c53ff8, whose denial rests on content inside a file upstream does have), and the four re-verified rows' downgrade to Warum nicht mehr feststellbar is backed by the current repository's PRs #1-#4 being demonstrably different patches from the ones their commit subjects name. Structural and hard-constraint checks confirm a single table with Scope folded into the existing column shape, no second table, per-commit scope assignment, a docs-only diff with no merge commits, both currency-base config files unset, and the one-sentence-per-line rule held. The repo's changed-file map selects no suite for a docs-only change, so I additionally ran tests/fm-fork-sync-check.test.sh (the suite owning the mirrored mechanism), which passes. Because the end-user surface here is a rendered Markdown registry, I rendered it to standalone HTML and captured three screenshots showing the header's methodology statement, the absorbed-verdict rows with their upstream evidence, and the ship-specific row - all checks passed and the worktree is clean.

  • Evidence: Rendered registry: header methodology and the four re-verified rows (local file: /tmp/no-mistakes-evidence/01KYXKF36QHAYMATBBTF5ZVNGT/01-registry-header-and-first-rows.png)
  • Evidence: Rendered registry: absorbed verdicts and the mixed-substance denials (117dec5, 063e03e, 7e6ec22) (local file: /tmp/no-mistakes-evidence/01KYXKF36QHAYMATBBTF5ZVNGT/02-absorbed-verdict-rows.png)
  • Evidence: Rendered registry: ship-specific absorbed row dba4fdb beside its non-absorbed guards 779c347 / 33f2e8e (local file: /tmp/no-mistakes-evidence/01KYXKF36QHAYMATBBTF5ZVNGT/03-ship-specific-and-tail-rows.png)
Evidence: Registry-vs-check parity transcript

Pins resolve live: origin HEAD (fork) = dc6c1bc66ace1b62965c820e922ff16d3140f011 canonical upstream HEAD= a805766622afb291681a15a80c5135517f1cb5ed $ git rev-list --oneline --no-merges upstream..fork | wc -l 88 (registry header claims 88) Row set vs commit set (7-char SHAs, sorted): registry rows = 88 (unique 88) rows not in commit set = 0 commits without a row = 0 row order = chronological (exact reverse of rev-list) $ git cherry upstream fork 88 lines, 0 marked "-" (patch-equivalent) -> header claim "no absorbed verdict can rest on it" holds Table shape (single table, existing shape kept, Scope folded in): base dc6c1bc header : | Commit | Summary | Verdict | Rationale | Last reviewed upstream | head baed08b header : | Commit | What it does | Why it exists | Verdict | Scope | Last reviewed upstream | header rows in file : 1 delimiter rows: 1 (one table only) Column value domains: 6 verdict absorbed 21 verdict keep 61 verdict upstream-candidate 83 scope general 5 scope ship-specific rows admitting "Warum nicht mehr feststellbar": 21 of 88 The four pre-existing rows, re-verified against the repointed repository: PR #1 [merged] feat: configure Codex Graphify approval profile PR #2 [merged] fix(fleet-sync): skip non-repo directories nested in enclosing repo PR #3 [closed, not merged] feat: add bootstrap and watcher drift checks PR #4 [merged] feat(bin): add fork-sync, firstmate-update, and AXI-suite checks -> none of these is the patch its commit subject "(#N)" names Hard constraints: files changed dc6c1bc..baed08b : docs/fork-patches.md merge commits on branch : 0 config/ directory present : no - firstmate-update-base and fork-sync-upstream remain unset non-ASCII characters in file : 0 prose lines with >1 sentence : 0 (one-sentence-per-line rule holds)

Registry-vs-check parity, docs/fork-patches.md @ baed08b
=========================================================

Pins resolve live:
  origin HEAD (fork)     = dc6c1bc66ace1b62965c820e922ff16d3140f011
  canonical upstream HEAD= a805766622afb291681a15a80c5135517f1cb5ed

Enumeration reproduced exactly as bin/fm-fork-sync-check.sh:100 does it:
  $ git rev-list --oneline --no-merges upstream..fork | wc -l
  88   (registry header claims 88)

Row set vs commit set (7-char SHAs, sorted):
  registry rows          = 88 (unique 88)
  rows not in commit set = 0
  commits without a row  = 0
  row order              = chronological (exact reverse of rev-list)

Patch equivalence, as bin/fm-fork-sync-check.sh:102 does it:
  $ git cherry upstream fork
  88 lines, 0 marked "-" (patch-equivalent)  -> header claim "no absorbed verdict can rest on it" holds

Table shape (single table, existing shape kept, Scope folded in):
  base dc6c1bc header : | Commit | Summary | Verdict | Rationale | Last reviewed upstream |
  head baed08b header : | Commit | What it does | Why it exists | Verdict | Scope | Last reviewed upstream |
  header rows in file : 1   delimiter rows: 1   (one table only)
  every data row has 6 populated columns, no empty What/Why cell

Column value domains:
      6   verdict absorbed
     21   verdict keep
     61   verdict upstream-candidate
     83   scope   general
      5   scope   ship-specific
  rows admitting "Warum nicht mehr feststellbar": 21 of 88

The four pre-existing rows, re-verified against the repointed repository:
  PR #1  [merged] feat: configure Codex Graphify approval profile
  PR #2  [merged] fix(fleet-sync): skip non-repo directories nested in enclosing repo
  PR #3  [closed, not merged] feat: add bootstrap and watcher drift checks
  PR #4  [merged] feat(bin): add fork-sync, firstmate-update, and AXI-suite checks
  -> none of these is the patch its commit subject "(#N)" names; all four rows now read "Warum nicht mehr feststellbar"

Hard constraints:
  files changed dc6c1bc..baed08b : docs/fork-patches.md 
  merge commits on branch        : 0
  config/ directory present      : no - firstmate-update-base and fork-sync-upstream remain unset
  non-ASCII characters in file   : 0
  prose lines with >1 sentence   : 0 (one-sentence-per-line rule holds)
Evidence: Content-level absorption test against upstream a805766

Absorption content test: for each 'absorbed' row, list changed files that upstream a805766 does NOT have. 117dec5 files=3 absent-upstream: none 7e6ec22 files=1 absent-upstream: none 052df46 files=1 absent-upstream: none 9e6e895 files=3 absent-upstream: none 578d9c5 files=1 absent-upstream: none dba4fdb files=2 absent-upstream: none Denial test: for each row denied 'absorbed' on new-file grounds, count changed files upstream lacks. 93b21ac files=3 absent-upstream=1 e.g. tests/fm-private-material-ignore.test.sh fc25d2f files=4 absent-upstream=1 e.g. tests/fm-private-material-ignore.test.sh 063e03e files=143 absent-upstream=11 (exactly 7 of them ADDED by the commit, as the row states) 2d6ff5e files=1 absent-upstream=1 e.g. tests/fm-private-material-ignore.test.sh 8709b19 files=3 absent-upstream=1 e.g. tests/fm-test-lib.test.sh 779c347 files=1 absent-upstream=1 e.g. tests/fm-instruction-owners.test.sh 33f2e8e files=1 absent-upstream=1 e.g. tests/fm-instruction-owners.test.sh 1c53ff8 files=1 absent-upstream=0 (denied on content, not filename: upstream's docs/configuration.md has 0 hits for the paragraph's tokens)

Absorption content test: for each 'absorbed' row, list changed files that upstream a805766 does NOT have.

117dec5  files=3    absent-upstream: none
7e6ec22  files=1    absent-upstream: none
052df46  files=1    absent-upstream: none
9e6e895  files=3    absent-upstream: none
578d9c5  files=1    absent-upstream: none
dba4fdb  files=2    absent-upstream: none

Denial test: for each row denied 'absorbed' on new-file grounds, count changed files upstream lacks.
93b21ac  files=3    absent-upstream=1   e.g. tests/fm-private-material-ignore.test.sh
fc25d2f  files=4    absent-upstream=1   e.g. tests/fm-private-material-ignore.test.sh
063e03e  files=143  absent-upstream=11  e.g. bin/fm-continuity-command-policy.mjs
2d6ff5e  files=1    absent-upstream=1   e.g. tests/fm-private-material-ignore.test.sh
8709b19  files=3    absent-upstream=1   e.g. tests/fm-test-lib.test.sh
779c347  files=1    absent-upstream=1   e.g. tests/fm-instruction-owners.test.sh
33f2e8e  files=1    absent-upstream=1   e.g. tests/fm-instruction-owners.test.sh
1c53ff8  files=1    absent-upstream=0   e.g. (none)
Evidence: Standalone rendered registry (offline, no network assets)
<!doctype html><meta charset=utf-8><title>docs/fork-patches.md</title><style>
body { font: 15px/1.55 -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
       color: #1f2328; background: #fff; margin: 0; padding: 32px 40px; max-width: 1500px; }
h1 { font-size: 30px; border-bottom: 1px solid #d1d9e0; padding-bottom: .3em; margin-top: 0; }
p { margin: 0 0 16px; }
code { background: #eff1f3; padding: .2em .4em; border-radius: 6px;
       font: 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
a { color: #0969da; }
table { border-collapse: collapse; width: 100%; margin: 16px 0; font-size: 13px; }
th, td { border: 1px solid #d1d9e0; padding: 6px 13px; text-align: left; vertical-align: top; }
th { background: #f6f8fa; font-weight: 600; }
tr:nth-child(2n) td { background: #f6f8fa; }
</style><h1>Curated fork patch registry</h1>
<p>This ledger is the fork-maintenance tax that the fleet repository is meant to end; see <a href="admiralty-fleet-repo.md"><code>docs/admiralty-fleet-repo.md</code></a> for what replaces it and how far that work has got.<br>
Until a vessel is actually cut over, this registry stays authoritative.<br>
The 2026-08-01 review records all 88 fork-only, non-merge commits reported by <code>git rev-list --oneline --no-merges &quot;$upstream..$fork&quot;</code> for fork <code>dc6c1bc</code> against canonical upstream <code>a805766</code>.<br>
That fork commit is a pinned snapshot of the fork&#x27;s default branch, not a live reference.<br>
<code>bin/fm-fork-sync-check.sh</code> resolves its own fork side from the live origin <code>HEAD</code> instead, so its commit set grows the moment anything lands on the fork&#x27;s default branch while this pin stays where it is.<br>
A divergence between the check&#x27;s count and this registry&#x27;s row count is therefore expected and is not a defect in either.<br>
The remedy is to add one row per unrecorded commit and re-stamp the pin in the sentence above; <code>git rev-list --oneline --no-merges &lt;pinned-fork&gt;..origin/main</code> names exactly what a stale pin is missing.<br>
The registry is deliberately not self-updating, because a generated row could only restate the diff, which is the reconstructed motive this document exists to prevent.</p>
<p>Each fork-only, non-merge commit has one row recording what it does, the problem that required it, its current verdict, and whether another vessel would want it.<br>
The Why column uses the associated pull request&#x27;s <code>## Intent</code> section as its primary source.<br>
Where the surviving repository has no matching pull request or no usable intent, the row says <code>Warum nicht mehr feststellbar</code> instead of reconstructing a motive from the diff.</p>
<p>Verdict answers whether this vessel still needs the patch when it moves.<br>
Use <code>absorbed</code> when upstream fully replaces the patch and it can be dropped, <code>keep</code> when the patch must travel with the vessel, and <code>upstream-candidate</code> when it must travel and should additionally be proposed upstream.<br>
The matching <code>git cherry &quot;$upstream&quot; &quot;$fork&quot;</code> check found no patch-equivalent commit mechanically, so no <code>absorbed</code> verdict can rest on it.<br>
The test used instead is whether upstream already carries the whole of what the commit contributes, judged at content level rather than by filename.<br>
A shared path proves nothing on its own, because a commit can edit a file upstream also has while every line it changes is fork-authored, and a commit that mixes an already-upstream effect with fork-only material is not absorbed however clearly the upstream side is evidenced.<br>
Every <code>absorbed</code> row therefore names the upstream file, rule or provenance that already carries its effect, and every row denied that verdict names what upstream does not have.<br>
That rule is why a patch and its own guard can end up on opposite sides: <code>dba4fdb</code> restores a skill upstream still ships, while <code>779c347</code> and <code>33f2e8e</code> pin that skill inside <code>tests/fm-instruction-owners.test.sh</code>, of which upstream has no copy.<br>
It is why <code>93b21ac</code>, <code>fc25d2f</code> and <code>063e03e</code> are not absorbed despite carrying real upstream substance - each creates a file upstream does not have, and dropping the commit would drop that file with it.<br>
And it is why <code>1c53ff8</code> is not absorbed either, reaching the same collision through a shared path rather than a new one: it edits <code>docs/configuration.md</code>, which upstream has, but the paragraph it edits is fork-authored throughout.</p>
<p>Scope answers a separate question and is assigned independently of Verdict: would another vessel hit this problem and want this behavior, or does the patch exist only because of this home&#x27;s own configuration and history?<br>
A <code>keep</code> patch can still be general - the fork-sync checks are the clearest case, since every downstream vessel wants them while upstream, being the upstream, has no use for them.<br>
An <code>absorbed</code> patch can still be ship-specific, as <code>dba4fdb</code> is: the skill it restores belongs to upstream, but the loss it repairs was this fork&#x27;s alone.<br>
The honest result is lopsided, with only five ship-specific rows, because these patches overwhelmingly harden mechanisms every vessel shares; what is genuinely local to this home is its Codex approval profile (<code>2bdd0f1</code>), the two repairs to its own history reconciliation (<code>abcc1e1</code>, <code>e59d3a0</code>), its admiralty move record (<code>356cd52</code>), and the restoration of a skill only this fork had lost (<code>dba4fdb</code>).</p>
<p>Re-review a row when the upstream tip moves.</p>
<table><thead><tr><th>Commit</th><th>What it does</th><th>Why it exists</th><th>Verdict</th><th>Scope</th><th>Last reviewed upstream</th></tr></thead><tbody><tr><td><code>e623032</code></td><td>Adds the AXI-suite updater and primary safety guards.</td><td>Warum nicht mehr feststellbar; the current repository&#x27;s PR #1 describes a different post-repoint patch.</td><td>keep</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>4939c5b</code></td><td>Wakes supervision on Bridge inbox traffic.</td><td>Warum nicht mehr feststellbar; the current repository&#x27;s PR #2 describes a different post-repoint patch.</td><td>keep</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>df159d2</code></td><td>Adds the upstream Firstmate update check.</td><td>Warum nicht mehr feststellbar; the current repository&#x27;s PR #3 is closed and unmerged, and its body carries the later history-reconciliation intent rather than this patch&#x27;s original review.</td><td>keep</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>8f3190b</code></td><td>Reads Bridge inbox state from fetched <code>origin/main</code>.</td><td>Warum nicht mehr feststellbar; the current repository&#x27;s PR #4 is the later history-recovery merge rather than this patch&#x27;s original review.</td><td>keep</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>c8496fb</code></td><td>Adds curated-fork sync detection.</td><td>Warum nicht mehr feststellbar; no associated pull request survives in the current repository.</td><td>keep</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>a3794c7</code></td><td>Removes an unused local fetch and de-personalizes the fork-sync cron documentation.</td><td>Warum nicht mehr feststellbar; no associated pull request survives in the current repository.</td><td>keep</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>40b1f11</code></td><td>Installs AFK signal traps before lock acquisition.</td><td>Warum nicht mehr feststellbar; no associated pull request survives in the current repository.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>6aedfec</code></td><td>Documents fork-sync in architecture and configuration references.</td><td>Warum nicht mehr feststellbar; no associated pull request survives in the current repository.</td><td>keep</

... [21465 bytes truncated] ...

>general</td><td><code>a805766</code></td></tr><tr><td><code>357ef6b</code></td><td>Reconciles executor deployment duties with the project-write boundary.</td><td>An executor role could otherwise read as permission to write another vessel&#x27;s project despite Firstmate&#x27;s always-loaded prohibition.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>643051b</code></td><td>Points the executor overlay at hard rule 1 instead of restating it.</td><td>A second copy of the project-write contract would drift and make the new role appear to own a safety rule it only applies.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>e94925e</code></td><td>Updates role tests so executor documentation is no longer treated as missing.</td><td>Tests and documentation could preserve the old reserved-but-unwritten state after the overlay became real.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>879bf50</code></td><td>Adds a shared board layout and the <code>/decisionboard</code> capability.</td><td>Existing boards recompiled remote Tailwind assets on every open, lacked a standard fast layout, and presented duplicated model-panel decision records without structural collapse.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>f6b585a</code></td><td>Refuses line-wrapped remote board references and surfaces empty board states.</td><td>The no-network guard could miss wrapped URLs, while a structurally valid but empty board could fail silently.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>8544518</code></td><td>Scans CSS <code>@import</code> as a statement.</td><td>Treating <code>@import</code> as a trailing word left the board&#x27;s no-network proof vulnerable to CSS syntax the browser would still execute.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>fda5664</code></td><td>Restricts CSS network scanning to browser-executed contexts.</td><td>Scanning inert text as CSS created false alarms without improving the guarantee about actual browser requests.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>1cd246d</code></td><td>Covers every style-attribute form that can fetch a resource.</td><td>Alternate attribute quoting and layout forms could bypass a guard that recognized only one serialization.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>c822045</code></td><td>Documents table, monospace, distribution, and <code>data-src</code> board coverage.</td><td>The reusable layout and its no-network boundary needed an explicit owner so later boards would not guess which forms were supported.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>9000261</code></td><td>Points board guard documentation at <code>fm-board.sh --help</code>.</td><td>Repeating guard mechanics in the board document would create a second owner and drift from the executable contract.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>b6d84f4</code></td><td>Adds evidence-based review-quality grading.</td><td>The decision to keep no-mistakes relied on the tool&#x27;s own finding ledger, so false-positive rate and whether fixes actually improved code had no independent measurement.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>dba4fdb</code></td><td>Restores the <code>ask-user-authority</code> skill from upstream.</td><td>A squash import lost the procedure even though <code>AGENTS.md</code> still required the behavior, leaving ask-user findings without their decision owner; <code>.agents/skills/ask-user-authority/SKILL.md</code> exists upstream and the commit message records that it was restored from there.</td><td>absorbed</td><td>ship-specific</td><td><code>a805766</code></td></tr><tr><td><code>779c347</code></td><td>Pins the authority skill and its trigger in instruction-owner tests.</td><td>The same skill or trigger could otherwise disappear again while every repository test stayed green; upstream has no <code>tests/fm-instruction-owners.test.sh</code>, so the pin cannot have been absorbed even though the skill it pins exists upstream.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>7fe9640</code></td><td>Fixes grading chain boundaries, diff parsing, and metric provenance.</td><td>Incorrect fix-chain boundaries and unproven source attribution would make the new independent review metrics misleading.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>33f2e8e</code></td><td>Pins authority-skill body structure and collapses redundant trigger assertions.</td><td>The authority procedure&#x27;s load-bearing body and trigger could drift silently under the same unguarded-skill failure that caused its loss; upstream has no <code>tests/fm-instruction-owners.test.sh</code>, so these assertions cannot have been absorbed.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>a9931ca</code></td><td>Deduplicates identical fix chains and normalizes detection paths.</td><td>One correction could be counted more than once or attributed to a different path spelling, corrupting the review-quality evidence.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>0277ee0</code></td><td>Rejects bare basenames and sentence-final path tokens in grading evidence.</td><td>Loose path matching could treat persuasive prose as proof that a finding actually targeted the measured file.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>832fc66</code></td><td>Documents grading environment variables and links the first-reading record.</td><td>Without the tunable bounds and provenance record, another reviewer could not reproduce or interpret the grading result honestly.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>e58e931</code></td><td>Requires every skill to declare a load trigger and a conditional frontmatter description.</td><td><code>ask-user-authority</code> lost its trigger line, every test stayed green, and the skill silently stopped being loaded for months, so the check enumerates the <code>.agents/skills/</code> directory rather than naming skills in a list, because a hand-maintained list carries the identical silent-staleness failure mode as the gap it guards.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>61b03a9</code></td><td>Anchors the skill frontmatter probes, stamps the audit&#x27;s counts with their base tree, and links the audit record from the guidelines skill.</td><td>Warum nicht mehr feststellbar; the commit has no distinct intent beyond the surrounding validation run.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>7762040</code></td><td>Anchors the frontmatter name probe and corrects the audit&#x27;s recorded cost and base stamps.</td><td>Warum nicht mehr feststellbar; the commit has no distinct intent beyond the surrounding validation run.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr><tr><td><code>78ffa4f</code></td><td>Records the frontmatter description as a second skill arrival route and states what the new check does and does not enforce.</td><td>The description is the only arrival path left in a deployment where no instruction-surface trigger line is possible at all, and the check&#x27;s condition clause is knowingly a weak floor that proves a condition is stated rather than that it is the right one, so the convention&#x27;s own section had to say that triggers are written precisely rather than written to the check.</td><td>upstream-candidate</td><td>general</td><td><code>a805766</code></td></tr></tbody></table>
Evidence: Mechanical commit enumeration used for the parity check
78ffa4f no-mistakes(document): document enforced skill trigger and description floor
7762040 no-mistakes(review): anchor name probe, correct audit cost and base stamps
61b03a9 no-mistakes(review): anchor skill frontmatter probes, base-stamp audit, link record
e58e931 test(skills): require every skill to declare a load trigger
832fc66 no-mistakes(document): register fm-grade env vars, link first-reading record
0277ee0 no-mistakes(review): reject bare-basename matches and sentence-final path tokens
a9931ca no-mistakes(review): dedupe identical fix chains and normalise detection paths
33f2e8e no-mistakes(review): pin ask-user-authority body structure, collapse per-skill trigger assertions
7fe9640 no-mistakes(review): fix grade engine chain boundary, diff parsing, and metric provenance
779c347 no-mistakes(review): pin ask-user-authority in instruction-owners guard test
dba4fdb docs: restore ask-user-authority skill from upstream
b6d84f4 grade(review): measure review quality on evidence the reviewed tool does not control
9000261 no-mistakes(document): point guard-coverage section at fm-board.sh --help
c822045 no-mistakes(document): document board layout's table, mono, dist, and data-src coverage
1cd246d no-mistakes(review): fix(board): read every style-attribute form a browser fetches
fda5664 no-mistakes(review): fix(board): scan CSS only where a browser runs it
8544518 no-mistakes(review): fix(board): scan @import as a statement, not a trailing word
f6b585a no-mistakes(review): fix(board): refuse line-wrapped remote refs and surface silent board states
879bf50 board(layout): make the standard board layout shared material, and add /decisionboard
e94925e no-mistakes(document): no stale docs for the executor role overlay
643051b no-mistakes(review): reference hard rule 1 instead of restating it
357ef6b no-mistakes(review): reconcile executor deploys with project-write rule
cfd67ab feat(roles): write the executor role overlay
1c53ff8 no-mistakes(document): drop stale suite enumeration from gitignore rationale
8709b19 no-mistakes(review): assert seed-marker ignore behavior and cover isolate refusals
9411e07 no-mistakes(review): scope the map die and make the gitignore guard enforcing
ab11e91 no-mistakes(review): isolate gitignore probes and map every .gitignore dependent
feb5141 fix(tests): assert the ignore behavior instead of a literal gitignore line
2d6ff5e no-mistakes(review): make ignore breadth guard fail loudly on git errors
fc25d2f no-mistakes(review): trim gitignore comment, map it to ignore tests, guard breadth
93b21ac fix(repo): ignore captain-private config wholesale instead of by name
bbf0023 feat(bin): serve review boards on each vessel's own tailnet address (#38)
7dd7be5 fix(bin): render fleet snapshots past the argv size ceiling (#37)
8502757 fix(axi): isolate AXI suite installs per vessel npm prefix (#36)
050cdce feat(bin): add detect-only staleness lint for backlog dependency edges (#35)
ce8309f fix(bin): require a live away pusher before an away turn can end (#34)
6bc798a feat(bin): add a repeatable model-panel capability (#33)
967a7f6 fix(bin): produce conforming PDFs and gate delivery on a real reader (#32)
a669313 fix(bin): accept resolved archived captain decisions in the completion gate (#31)
a0fe90d fix: ignore checkout-local harness runtime artifacts so fresh clones stay self-updatable (#30)
356cd52 docs: record the admiralty fleet repository and its pin contract (#29)
ce43899 docs(skills): re-verify codex harness-adapters facts against codex-cli 0.145.0 (#28)
e52cc76 feat(bin): select a fleet role by per-home config over one shared code root (#27)
e743665 feat(bin): resolve the upstream currency comparison bases from per-home config files (#26)
1142961 fix(watch): collapse duplicate supervision wakes for one crew event (#25)
5229506 fix(bin): isolate the per-task Claude turn-end hook from settings.local.json (#24)
5baa843 fix(bin): make fork-sync upstream drift detection content-aware (#23)
6f62c6b test(tests): harden stale-lock concurrency test and fix tmproot variable shadowing (#22)
a1ab5b5 no-mistakes(document): docs(architecture): fix stale away-marker classification note
36edd37 no-mistakes: apply CI fixes
b4c7699 no-mistakes: apply CI fixes
92e08d0 no-mistakes: apply CI fixes
3211115 no-mistakes(lint): Waiting for background fm-lint.sh run to finish before final verification
1eb46a3 no-mistakes(document): Sync bootstrap doc order and watch-arm close-classification text with code
578d9c5 fix: canonically classify operational inputs across harnesses (#909)
9e6e895 fix: exclude operational injections from ahoy boundaries (#899)
052df46 fix(herdr): group projected children beneath owning parents (#821)
7e6ec22 feat(watch): follow GitLab merge requests to merge (#797)
7ce70cd feat(watch): add Bridge frequency monitor for near-instant inbox notice (#21)
063e03e feat: harden Pi operational-input trust boundary and expand crew supervision tooling (#20)
c6feb47 feat(watch): watch multiple Bridge vessel inboxes (#19)
b9cb8bf feat(watch): daemonize watcher supervision via systemd --user template unit (#18)
b918595 feat(bin): add guarded direct-relay path for Bridge envelope traffic (#17)
117dec5 fix(pi): restore successor/retry continuity in Pi watcher (#16)
db06c4b fix(test): guard Pi lock test TS import (#15)
4d1fd1c docs(secrets): add fleet-wide transcript-safe secrets doctrine (#14)
c5063d8 fix(tests): stop bridge-inbox test hang from ambient FM_BRIDGE_ROOT leak (#13)
33bc721 feat(watch): reduce supervision wake clutter with quiet re-arm (#12)
2c6ab08 fix(watcher): reap arm-owned watcher orphans on wrapper death (#9)
761c18e fix(wake): bound blocking lock acquisition wait time (#10)
33176e1 feat(secondmate): add resting state for idle secondmates (#8)
a8ce717 feat(session-start): arm direct Telegram receiver (#7)
e3ad719 fix(wake): harden test cleanup and wake-queue locking against tmp leaks and filesystem failures (#6)
b0b04d0 feat(bootstrap): detect primary checkout drift from its own origin (#5)
e59d3a0 no-mistakes(review): Fix inverted Bridge vessel config precedence in AGENTS.md
abcc1e1 no-mistakes(review): Restore dropped AXI-suite/Bridge/scripts.md/test-guard merge content
b384c1b fix(fleet-sync): skip non-repo directories nested in enclosing repo (#2)
2bdd0f1 feat: configure Codex Graphify approval profile (#1)
8a5fd11 fix(watch): deduplicate Bridge inbox wakes with a surfaced-signature marker (#7)
9053fc4 fix(watch): scope Bridge inbox vessel per home (#6)
6aedfec no-mistakes(document): Docs synced: added fork-sync-check mentions to architecture.md and configuration.md systemd/env sections
40b1f11 no-mistakes(test): fix(afk): install signal traps before lock acquire to avoid race
a3794c7 no-mistakes(review): fix: drop unused local-checkout fetch, de-personalize docs cron path
c8496fb feat: add curated fork sync detection
8f3190b fix(watch): read Bridge inbox state from fetched origin/main instead of stale local tree (#4)
df159d2 feat(bootstrap): add upstream firstmate update check (#3)
4939c5b feat(watch): wake on Bridge inbox traffic (#2)
e623032 feat: add AXI-suite self-update and primary safety seatbelts (#1)
Evidence: Raw git cherry output (88 lines, none patch-equivalent)
+ e623032de0ab9288c9e8df9383a3bf37864b415c
+ 4939c5b91d8508044ffc9e35a65d7008199679ac
+ df159d237b8eba44b60eaa72802ab75132427fec
+ 8f3190bbd0db790ba881f346da6cb7bd462ec9f6
+ c8496fb8aef93e564610ac21b06e08ca265323c4
+ a3794c7a0c4bd1cccf6d31cf7cab1e3b778ad183
+ 40b1f11f7663423faa72dc17d5e09b6f19945f2a
+ 6aedfecd27ad4dec8737f73960e3ad13734ee3d6
+ 9053fc4b4fa7e30bf6828eeb0899219914d7544d
+ 8a5fd11c056e187b5322c7d93b4a815aa097c98a
+ 2bdd0f14e04d62c0af61cb91930f050f2ac230b5
+ b384c1b47123067f93179527a2ad8d6772f73bec
+ abcc1e190f0ebc4c26bbcda9a0bfa674b7f159f4
+ e59d3a08c051e44d6b701701dadd5249766c902d
+ b0b04d05f4cc0acf4a021d7e78b11b8714701545
+ e3ad719f4992db66a00aa3de402633de7430e8eb
+ a8ce71756344e6278413103b87c91c919c0f5d2a
+ 33176e1558789c43898e3335fc75c7d26724b8e0
+ 761c18e66cbbdceccbb5d0b466be9cc7817a6008
+ 2c6ab08248594ecfb249413ecca600a4c14c170f
+ 33bc7214a49dc3847af81e852be4c8fd57ec44bb
+ c5063d807c51e78064bcc493e279ffb985497ea4
+ 4d1fd1c1e3e2dfd02358aadd24ee500ca406243c
+ db06c4b26fa402c1665cf78774f4bfd9663f2619
+ 117dec580d7e5ba5ad5e95483a73ff0db5f5406f
+ b918595a2a88fb12987427f2e5e4b038e3e183f0
+ b9cb8bfc565577ec217ad4e12f3e97540a890855
+ c6feb472bf926188dad0105270bfa6bc5ea976e3
+ 063e03e51ea3faba656890c925a59f2b2627d3f7
+ 7ce70cd684184cdb31bc3218a766329655d47227
+ 7e6ec2267cf019824d401389687b2996b1824cf7
+ 052df46a761faf822865d27f5438334ba15125d0
+ 9e6e895c1104b732aceb0114c39e08a41b6d7fda
+ 578d9c5aa5f56cba6248a261dca2254ddcf48378
+ 1eb46a30dd7e338fb13ece47ba7c5c7b07f76fa9
+ 3211115022937df9164aed0590031b55ccab78dc
+ 92e08d0c1e4a2a137b5d781c0fb3994b1d68ed54
+ b4c769908b72676c62b39d3aedcc5f5552427d29
+ 36edd376cc2eb00b667d78fa238c79727d56f51c
+ a1ab5b537bc9d218b747ba2b6f9ee681fa9de339
+ 6f62c6bbefd3596b22ca3371e00275b69ed11d4d
+ 5baa8432c30c6cad06c618441786ee0a07421dc1
+ 522950664bfcd6e01dc0e4c823ef72a7acf98168
+ 11429613a7ead595ceb4a7e313f8fdf876d91154
+ e743665135e61645816530b4eec0162447d387e3
+ e52cc7642f495af2f0cae9cb8e28706faa2a3a6d
+ ce43899b245d0af13b7c49d2e4b5a0639bb57228
+ 356cd5250a83e21ad91b96c8bdd57964e1e2103f
+ a0fe90d942a757e1802b4d3a1cdb0e69ad41c118
+ a6693130802ec6a4986ead5cf95dbff4e27a72cf
+ 967a7f63db2f7a94b28d5e1f71c49a87c5c44f97
+ 6bc798abd7911540a9c9a040d17c74e6e43d6c6f
+ ce8309fcaa6a151a71701c19b6183eb4b5055458
+ 050cdceb8f1e210344749d9c552c1581514c12eb
+ 8502757e64f8d7fda53e00092a26069e88844085
+ 7dd7be5e0785e359bf321a5aef7ba3229605704b
+ bbf00232b2a660d9b45fcf513a4a88ac265bfd5f
+ 93b21ace18eb85cb4df668054e347cccd877203c
+ fc25d2f43802ca87142dfbfc2699ffe67759b20f
+ 2d6ff5e9796f91a8e457dd44b3ea03a6c46b91d2
+ feb514186c06d27118900c96d16527b6a00e869d
+ ab11e910eaaf50aab49619f03c6c34d0ee553218
+ 9411e075f33ff362fb0f7da0ed57d8bf846b3934
+ 8709b19a8264192f90129220913dbfc10736744a
+ 1c53ff83e85f38c53ad1d734ec35f6b18a44b684
+ cfd67ab04cbde46b9b9d2f8e010b24accaa6789a
+ 357ef6ba8f6bdaab916519e494d6880005ddf7a4
+ 643051b4fc6ce6eff6bfa8c6a9aaddff264b74ab
+ e94925ed091c41b8c47dff67ff17d77228a1e1b7
+ 879bf5052a6af1626f04527c095bd5958ee6d7b0
+ f6b585a9782941db2f7e3f2def2859ccc55f6c76
+ 8544518181db3d526749703dee66dfb30fd98eec
+ fda5664a1366f4bef8f4ee3ca17270f4281bf525
+ 1cd246dc4d43cd9225141a4407f74ecd353612c8
+ c822045b2d3da4098113a81922917d1f77185cd1
+ 90002612e9b4b6f8c733a9cf2cde0a63184fca8a
+ b6d84f474864b7d3eaca96f8ee22a92c347f7d8b
+ dba4fdbd6feba6e317d9508b716b1236f4d52c5f
+ 779c3473deafa3f1cfc6c4ca272c6d2fa72c23a3
+ 7fe9640a7f9231ded3c50b71b45fd7895d7a4051
+ 33f2e8eb4eed0536fcb4510404e4ac8b52ddd392
+ a9931caa734f2b3f0a95d76ec3323bb5819492e1
+ 0277ee0cddf23fef5ed32ec898184125f7d8cde8
+ 832fc667761bdae811a4937510a3aefec8e0716d
+ e58e931074381acb3febdf35f4185e4353ee7d25
+ 61b03a9cdea75cb01aadba6821640c976082874e
+ 776204097495a2e893bed468d0907d63e1f1b657
+ 78ffa4fec6cc4c05d100d822aa5484a28fd54211

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 5 issues found → auto-fixed (4) ✅
  • ⚠️ docs/fork-patches.md:5 - The registry's completeness claim is already stale at its own merge base. Line 5 pins the review to fork de0b95b and line 8 states the absolute contract "Each fork-only, non-merge commit has one row", but this branch is based on dc6c1bc, which contains four additional fork-only, non-merge commits with no rows: e58e931, 61b03a9, 7762040, 78ffa4f (all from PR test(skills): enforce a load trigger and description condition for every skill #44, merged after de0b95b). bin/fm-fork-sync-check.sh:77,100 resolves the fork side from the live origin HEAD, not from a pin, so the registry and the check describe different sets the moment this lands — contradicting the intent's stated goal that "the registry and the check mean the same set". Either add the four rows and re-stamp the snapshot to dc6c1bc, or soften line 8 to say the contract holds as of the named snapshot commit.
  • ⚠️ docs/fork-patches.md:73 - 93b21ac ("Ignores all captain-private config/ material by pattern") is given the verdict absorbed. Line 11 defines absorbed as "upstream fully replaces the patch", which is the verdict that authorizes dropping the patch at the fleet move. The rule is still fork-only and live at .gitignore:16 (config/*), it was authored in this fork in PR fix(repo): ignore captain-private config wholesale instead of by name #39, and line 6 records that git cherry found no patch-equivalent commit — so nothing in the document evidences the absorption. The row's own Why states the failure mode: name-by-name ignores "could let a plain git add -A stage a Telegram bot token". If this verdict is acted on and the judgment is wrong, the captain-private ignore disappears in the admiralty tree. Either record the provenance evidence that upstream carries an equivalent rule, or downgrade to keep.
  • ⚠️ docs/fork-patches.md:75 - PR fix(repo): ignore captain-private config wholesale instead of by name #39's eight-commit chain receives mutually exclusive verdicts on one feature. 93b21ac (the ignore rule), fc25d2f, 2d6ff5e, 8709b19 and 1c53ff8 are absorbed, while feb5141, ab11e91 and 9411e07 — interleaved in the same chain and iterating on the same ignore rule and its breadth guard test — are upstream-candidate. 2d6ff5e ("guard fail on Git errors") and 9411e07 ("map guard enforcing and correctly scoped") harden the same guard yet get opposite destinations. Upstream cannot both already contain this work and need it proposed to it; one side of the split is wrong. By contrast PR fix(skills): restore ask-user-authority skill lost in squash-import #42 (dba4fdb/779c347/33f2e8e, all absorbed) and PR feat(bin): add fm-grade review-quality scale independent of the reviewed tool #43 (all upstream-candidate) are internally consistent.
  • ⚠️ docs/fork-patches.md:14 - The Scope column carries no information the Verdict column does not already imply. Across all 84 rows the cross-tab is exactly: 21 keep/ship-specific, 49 upstream-candidate/general, 14 absorbed/general — a perfect one-to-one mapping, which also follows definitionally from line 11 (keep is defined as "vessel-specific behavior remains necessary", upstream-candidate as "a general patch should be proposed upstream"). Because the two fields can never disagree, Scope cannot express the case the intent says it is there to steer: a patch the vessel must keep now whose mechanism is nonetheless general (e.g. 5baa843 fork-sync drift detection, keep/ship-specific, versus the closely related b0b04d0 primary-checkout drift detection, upstream-candidate/general). Either re-derive Scope independently of Verdict for the rows where it differs, or state that Scope is intentionally implied by Verdict so a later reader does not treat it as a second judgment.
  • ℹ️ docs/fork-patches.md:18 - The row for df159d2 says "the current repository's PR feat: add bootstrap and watcher drift checks #3 is the later history-recovery merge rather than this patch's original review". PR feat: add bootstrap and watcher drift checks #3 in this repository is closed and was never merged; the merged history reconciliation is PR feat(bin): add fork-sync, firstmate-update, and AXI-suite checks #4 (Merge pull request #4 from Freudator86/fm/fm-recover-fork-drift), which the 8f3190b row on line 19 already names correctly. PR feat: add bootstrap and watcher drift checks #3's title is in fact "feat: add bootstrap and watcher drift checks", close to this commit's subject, though its ## Intent body is the history-reconciliation text — which is the substantive point the row is making. In a document whose entire value is provenance accuracy, calling an unmerged PR "the merge" is worth correcting.

🔧 Fix: correct fork registry verdicts, scope, and snapshot pin
2 issues (1 warning, 1 info) still open:

  • ⚠️ docs/fork-patches.md:88 - The file-existence absorption test introduced at line 19 is applied inconsistently one row apart. 2d6ff5e was flipped off absorbed in this round with the evidence "upstream has no tests/fm-private-material-ignore.test.sh" — but 93b21ac (line 88) creates that same file (121 lines, alongside .gitignore and docs/configuration.md) and fc25d2f (line 89) adds 41 more lines to it plus a bin/fm-test-run.sh mapping, and both keep the verdict absorbed, whose definition at line 17 is "upstream fully replaces the patch and it can be dropped". Acting on all three verdicts is incoherent: dropping 93b21ac removes the file that 2d6ff5e's retained 16-line change edits. This is not the round-1 objection about missing evidence — the .gitignore provenance the user supplied is recorded correctly and the ignore rule itself really is absorbed. It is the flip of 2d6ff5e that turned the pair into a contradiction. The same diff already shows the intended handling for exactly this shape at line 76 (063e03e), where the Why cell says the absorption evidence "is genuinely mixed" and names both the upstream files carrying the substance and the paths upstream lacks. Applying that treatment to 93b21ac and fc25d2f — or noting on those rows that the guard test travels separately — would close it without disturbing the verified .gitignore finding.
  • ℹ️ docs/fork-patches.md:25 - Line 25 states "The honest result is lopsided, with only five ship-specific rows" and then enumerates what is genuinely local as "its Codex approval profile, the repairs to its own history reconciliation, and its admiralty move record" — three categories covering four rows (2bdd0f1, abcc1e1, e59d3a0, 356cd52). The fifth ship-specific row is dba4fdb, which line 24 does explain as a separate case, but a reader auditing the column against the header's own list finds a count that does not reconcile. Adding the skill-restoration case to the enumeration on line 25 would make the justified-uniformity claim self-checking.

🔧 Fix: flip mixed-substance gitignore rows off absorbed
1 warning still open:

  • ⚠️ docs/fork-patches.md:97 - 1c53ff8 keeps the verdict absorbed on file-level reasoning that line 19's tightened rule was written to reject. Its Why cell argues "the commit changes docs/configuration.md and nothing else, and upstream carries that file, so the whole of what it contributes is already upstream" — but what the commit contributes is a one-line rewrite inside a paragraph that is entirely fork-authored. git log -L on that block shows the section was introduced by 93b21ac and refined by fc25d2f, ab11e91 and 9411e07, and its text names tests/fm-private-material-ignore.test.sh and the .gitignore arm of bin/fm-test-run.sh — fork-only material by this document's own evidence. All four of those parent commits are now upstream-candidate, so at the fleet move the paragraph travels while 1c53ff8 is dropped, and the stale suite enumeration it removed (naming tests/fm-model-panel.test.sh and tests/fm-role-config.test.sh, a list the runner owns) reappears in the moved tree. This is the same collision just fixed one row up, reached through a shared file rather than a new one: the file exists upstream, the content does not. The other six remaining absorbed rows survive the same sweep — 117dec5, 7e6ec22, 052df46, 9e6e895, 578d9c5 and dba4fdb touch only paths the verified upstream data covers, and none touches a known fork-only file.

🔧 Fix: apply content-level absorption test to registry
1 info still open:

  • ℹ️ docs/fork-patches.md:59 - 117dec5 is the one remaining absorbed row whose recorded absorption evidence is the file-level form line 20 now rejects. Its Why cell ends "all three files it changes exist upstream", while line 20 states "A shared path proves nothing on its own, because a commit can edit a file upstream also has while every line it changes is fork-authored" and line 21 requires every absorbed row to name "the upstream file, rule or provenance that already carries its effect". The verdict is not in doubt — the fix instructions verified it at content level (upstream's .pi/extensions/fm-primary-pi-watch.ts carries the same successor, retry and single-flight logic, 38 matching occurrences against the fork's 39) — but that evidence did not make it into the row, so this is the only absorbed verdict a later reader cannot re-audit against the document's own stated test. The other five are covered: 7e6ec22 names upstream's bin/fm-pr-lib.sh handling, and 052df46, 9e6e895, 578d9c5 and dba4fdb each lead with provenance, which line 21 explicitly admits. Replacing the trailing file-existence clause with the content-level finding would close it.

🔧 Fix: record content-level absorption evidence for 117dec5
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • git rev-list --oneline --no-merges upstream..fork in a throwaway bare repo fetched from both remotes - 88 commits, matching the registry's 88 unique rows with zero rows unmatched in either direction and identical ordering
  • git cherry upstream fork - 88 lines, 0 marked -, confirming the header's claim that no absorbed verdict can rest on mechanical equivalence
  • git rev-parse refs/heads/fork refs/heads/upstream - confirmed the document's pins dc6c1bc and a805766 are the live HEADs of both repositories
  • Content-level absorption test: for each of the 6 absorbed rows, checked every file the commit touches exists in upstream: - all present; for each row denied absorbed on new-file grounds, confirmed the named files are absent upstream and that 063e03e adds exactly seven such files
  • Verified 1c53ff8's content-level denial by grepping upstream's docs/configuration.md for the paragraph's tokens (fm-private-material-ignore, config/*, fm-test-run.sh) - zero hits despite the shared path
  • gh-axi pr view 1|2|3|4|6|7 - confirmed the repoint evidence: PR #1 is the Codex Graphify profile, #3 is closed and unmerged carrying reconciliation intent, #4 is the recovery merge; also confirmed the PRs whose ## Intent text matches rows 2bdd0f1, b384c1b, a8ce717, e3ad719
  • Table structure checks on docs/fork-patches.md - one header row and one delimiter row (single table), uniform 6 populated columns per row, verdict domain {absorbed:6, keep:21, upstream-candidate:61}, scope domain {general:83, ship-specific:5}, 21 rows admitting Warum nicht mehr feststellbar
  • Hard-constraint checks - git diff --name-only dc6c1bc..baed08b (only docs/fork-patches.md), git log --merges dc6c1bc..baed08b (none), absence of config/ so firstmate-update-base and fork-sync-upstream stay unset, zero non-ASCII characters, one-sentence-per-line prose scan
  • bash tests/fm-fork-sync-check.test.sh - passes (the suite owning the enumeration mechanism the registry mirrors)
  • bash bin/fm-test-run.sh --changed --list - confirmed the changed-file map selects no suite for this docs-only change, which is why the checks above were built by hand
  • Rendered docs/fork-patches.md to standalone HTML and screenshotted it in Chrome at 1600x1100 to capture the reviewer-visible registry surface
⚠️ **Document** - 1 info
  • ℹ️ docs/fork-patches.md:5 - The header's central claim — that dc6c1bc has exactly 88 fork-only non-merge commits against canonical upstream a805766 — could not be independently verified in this worktree, because a805766 is not present in the local object store and no upstream fetch was performed. What I could verify holds: all 88 listed SHAs are unique, exist, are non-merge, and are ancestors of the pinned dc6c1bc, and the prose tallies (88 rows, five ship-specific rows and exactly the five commits named in the Scope paragraph, six absorbed rows consistent with the worked examples) match the table. Re-confirming the 88-count and the a805766 stamp requires a fetch of real upstream.
⚠️ **Lint** - 1 warning
  • ⚠️ linter found issues (exit code 127)
✅ **Push** - passed

✅ No issues found.

@Freudator86
Freudator86 merged commit 22b6464 into main Aug 1, 2026
10 checks passed
@Freudator86
Freudator86 deleted the fm/fm-admiralty-patch-inventar branch August 3, 2026 18:50
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.

1 participant