Skip to content

Report a section that never arrived as absent, not as hand-modified - #541

Merged
ptr727 merged 2 commits into
developfrom
ledger-missing-section
Aug 3, 2026
Merged

Report a section that never arrived as absent, not as hand-modified#541
ptr727 merged 2 commits into
developfrom
ledger-missing-section

Conversation

@ptr727

@ptr727 ptr727 commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Follow-up to the suppressed finding on #535, which is now merged. That finding was correct and pointed at a defect with a measurable cost.

The defect

spec/fidelity_honesty.py put a verbatim section whose heading is missing downstream into the same differs bucket as a genuine local edit (region is None -> spread["differs"]), and the report rendered both as "hand-modified".

The two states want opposite responses. A hand-edit is drift to reconcile against a local decision someone made. An absence is a section that never arrived, which is carried. Calling the second one the first sends a reader looking for decisions that were never taken.

What it actually produced

Seventeen repos were reported as having hand-modified AGENTS.md > Context and Delegation Discipline and Where the Rules Live. None of them edited anything: they still hold the pre-split monolithic AGENTS.md, so the sections are simply not there.

That claim was quoted as evidence in this repo's own backlog work before a reviewer caught it. The conclusion drawn from it happened to be right, because absence was separately confirmed by direct reads against the live repos, but the word it was drawn from was wrong, which is the more dangerous shape.

There is a second-order effect the finding also named: an absent section contributes nothing to the history set, so it can never be classified stale. That means every newly added verbatim section reports as hand-modified across the whole fleet on the day it lands. The new GOVERNANCE.md > Representative Data in Agent-Authored Text row was showing exactly that.

The change

A new absent bucket, with three consequences handled beyond the label itself:

  • It no longer disqualifies an intent unit from promotion. A missing section is not evidence of a local decision, so it should not block a unit from being promoted to verbatim.
  • It still counts as a live divergence for burn-down, because the section is genuinely owed to that repo.
  • The untriaged section reports the two kinds separately, since one is fixed by reconciling and the other by carrying.

Result

-- **AGENTS.md > Where the Rules Live** - hand-modified in AudioCleaner, DevKitCIoT, ...
+- **AGENTS.md > Where the Rules Live** - **not carried** by AudioCleaner, DevKitCIoT, ..., so the section never arrived rather than being edited

Three rows change, covering nineteen repo-section pairs.

Verification

  • spec/validate.py: OK, 21 cataloged
  • prose_lint --diff: clean
  • editorconfig: clean, CRLF preserved on the regenerated report
  • Report regenerated from a live fleet pass so it matches its source

A verbatim section whose heading is missing downstream landed in the same
differs bucket as a genuine local edit, and the report rendered both as
"hand-modified". The two want opposite responses: an edit is reconciled
against a local decision, an absence is carried.

The cost was concrete. The report accused seventeen repos of hand-editing
AGENTS.md sections they had never been given, because they still hold the
pre-split monolithic file. A reader acting on that would go looking for local
decisions that do not exist. The claim was quoted as evidence in this repo's
own backlog work before a reviewer caught the mislabel.

An absent section also contributes nothing to the history set, so it can never
read as stale, which is why every newly added verbatim section reported as
hand-modified fleet-wide on the day it landed. The new GOVERNANCE.md
Representative Data row was showing exactly that.

Three consequences handled beyond the label. An absent section no longer
disqualifies an intent unit from promotion, since it is not evidence of a local
decision. It still counts as a live divergence for burn-down, because the
section is genuinely owed. And the untriaged section reports the two kinds
separately, since they are fixed differently.

Report regenerated: the three affected rows now read "not carried by" instead
of "hand-modified in".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 18:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the fidelity/divergence audit so a missing downstream section is reported as not carried/absent (the section never arrived) instead of being lumped into hand-modified drift, and regenerates the divergence ledger accordingly.

Changes:

  • Add an absent bucket to spec/fidelity_honesty.py to classify “section heading not found” separately from true byte diffs.
  • Update report rendering to list untriaged hand-modified vs not carried divergences as separate rows, and adjust the per-unit spread summary output.
  • Regenerate reports/divergences.md so affected rows read “not carried” rather than “hand-modified”.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
spec/fidelity_honesty.py Introduces an absent bucket, updates bucketing/report output, and includes absent in divergence accounting.
reports/divergences.md Regenerated report reflecting the new “not carried” classification for missing sections.

Comment thread spec/fidelity_honesty.py Outdated
The description claimed an absent section no longer blocks promotion to
verbatim, and the code added a guard that kept blocking it. The description
was the correct intent and the code was wrong.

Absence is not evidence that a repo decided anything locally, and only such
evidence argues against promoting a unit. An unavailable file has never
disqualified a candidate for exactly that reason, so treating an absent
section as disqualifying was the same conflation this bucket was split out
to end, reintroduced two lines below the split.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 19:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit a549572 into develop Aug 3, 2026
7 checks passed
@ptr727
ptr727 deleted the ledger-missing-section branch August 3, 2026 21:00
ptr727 added a commit that referenced this pull request Aug 3, 2026
…ndor groundwork (#542)

Six commits, all from one session. Merged as a **merge commit**, never
squashed, per the branching model.

| Commit | PR | What it does |
| --- | --- | --- |
| `1ab9b32` | #537 | Deletes three stale PhotoCleaner `driftNotes` that
described finished work |
| `bf746aa` | #535 | Buckets `TODO.md` by the surface each entry
changes, records five issues verified complete, refreshes the divergence
ledger |
| `69276d1` | #536 | Adds the byte-locked `AGENTS.md` "Fleet Bootstrap"
section, the host-wide `fleet-bootstrap` block, and the `AUDIT.md`
routing that sends an un-stood-up repo to `STANDUP.md` first |
| `530dc0d` | #539 | Records two `gh-write-guard` limits found by
running it: a write inside a script is unseen, and a push followed by a
newline over-blocks |
| `5f4c17f` | #540 | Makes `configure.sh check` verify what the payloads
declare, closing a false clean where a `jq` failure left every setting
reported as passing while nothing was compared |
| `a549572` | #541 | Reports a verbatim section that never arrived as
**absent** rather than as hand-modified |

## Why this promotion matters more than most

Two of these change what the fleet is measured against, so until they
reach `main` every downstream audit compares against ground truth that
predates them.

**#536 is the one with reach.** A downstream agent had no way to
discover this repository. `AGENTS.md` is carried at `intent`, and the
hub's only self-reference described *the hub*, which is false about a
downstream repo, so an agent adapting the file correctly deleted it.
Four repos now hold no hub reference at all and one holds no `AGENTS.md`
either. The replacement is `verbatim` so adaptation cannot remove it,
declared in `spec/files.json` and classified in `spec/section-model.md`
so the audit reports its absence as drift rather than losing it
silently.

**#540 closes a false clean.** `check_settings` streamed its payload
from a process substitution, and a `jq` failure there leaves the loop
body unexecuted without tripping `set -e`. Every static setting reported
as checked and passing while nothing was compared. Verified by negative
test rather than by a clean pass: a malformed `settings.json` now fails
with exit 1, an extra live rule fails the rule-set assertion, and a
changed `copilot_code_review` parameter fails the parameters assertion.

**#541 corrects a report that was actively misleading.** It accused
seventeen repos of hand-editing `AGENTS.md` sections they had never been
given. They still hold the pre-split monolithic file, so the sections
are simply absent. A hand-edit is reconciled against a local decision,
an absence is carried, and the report was naming the wrong one.

## Fleet state behind this

Seventeen downstream re-vendor pull requests merged alongside this work,
each gate-checked at merge time and each verified after. Four repos had
`configure.sh` withdrawn from their re-vendor when review found they
carry `ruleset-*.json` payload names the canonical does not resolve,
which would have left `apply` and `check` aborting on files that do not
exist. That payload migration is still owed and is tracked in `TODO.md`.

## Expected immediately after this merges

The divergence ledger currently reports the hub itself as not carrying
"Fleet Bootstrap" and as owing a `configure.sh` re-vendor. That is the
ledger reading each repo's `main`, honestly, before this promotion.
Regenerating after the merge is what makes the report meaningful again,
and the `configure.sh` re-vendor list will collapse as repos take the
corrected script.

## Verification

`spec/validate.py` OK (21 cataloged), diff-scoped `prose_lint` clean,
`markdownlint-cli2` clean, editorconfig clean, `gh-write-guard
--selftest` PASS, 157 `prose_lint` unit tests pass.
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.

2 participants