Skip to content

Promote the Fleet Resync Reports, the copilot-instructions Fixes, and the Upstream Repo-Layout Segment - #734

Merged
ptr727 merged 6 commits into
mainfrom
develop
Aug 15, 2026
Merged

Promote the Fleet Resync Reports, the copilot-instructions Fixes, and the Upstream Repo-Layout Segment#734
ptr727 merged 6 commits into
mainfrom
develop

Conversation

@ptr727

@ptr727 ptr727 commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Closes #719
Closes #720
Closes #721
Closes #722

Promotes six merged develop PRs to main:

🤖 Generated with Claude Code

ptr727 added 6 commits August 15, 2026 08:23
… entry (#724)

The measured half of the HomeAutomation-Config resync, per `RESYNC.md`
"Ship It": done means measured, not applied.

## What

- **`reports/homeautomation-config/audit.md`**, the repository's first
committed report. Graded at `main` (`e10a2cf`, run stamp `audit run
2026-08-15T14:58:02Z | hub d54862a`) and at the convergence in flight on
`develop` (`c8252c7`, `audit run 2026-08-15T14:58:25Z | hub d54862a |
branch override develop`), kept apart because the promotion
(ptr727/HomeAutomation-Config#52) was open when the report was written.
`develop` is clean on every mechanized check after
ptr727/HomeAutomation-Config#51, and the two type checks for
`source-only` plus the cross-cutting dimensions are judged by hand with
`file:line` evidence.
- **Registry**: the third `driftNote` (a README that self-flagged
committed secrets) is deleted. The secrets left the checkout in
ptr727/HomeAutomation-Config#46 and #49 and the README no longer
mentions them, so the note described finished work. `spec/validate.py`
passes.
- **Conformance matrix**: the `operational` config row gains
HomeAutomation-Config as its reference repository, since it is now the
first operational repository with a committed report.

## Escalations

All three the run surfaced were already on file from sibling resyncs the
same day, so the report cites them rather than opening duplicates: #720
(the canonical `copilot-instructions.md` naming the hub by slug), #669
(the two `investigate` workflow dispositions), #721 (`dead-path` on
hub-hosted paths in carried text). Corroborating comments were left on
#720 and #721.

## Checks

The CI prose gate set over the changed files and the whole tree is
clean, markdownlint and editorconfig-checker are clean, `repo_gate.py`
is clean, and `spec/validate.py` classifies 22 repositories cleanly. The
report is CRLF like the rest of `reports/`.
## What this does

Addresses #725. The layout block in the `repo-worktree` skill carried a
clause from #699 reasoning that no owner segment is needed "since every
repo here is under one owner". A machine that also keeps third-party
clones falsifies that, and what it produces is a collision rather than
an untidy name.

The collision is caused by the fork naming rule, which #699 mentioned
only in passing and nothing wrote down: a fork is named
`<upstream-owner>-<upstream-repo>` at fork time, so
`ptr727/home-assistant-core` already occupies `home-assistant-core`. A
clone of `home-assistant/core` joined the same way lands on it, and
reduced to a bare `core` it names no project and collides with the next
`core` cloned from any other owner.

### The layout

```text
~/repos/<Repo>                          base clone, on its default/working branch
~/repos/worktrees/<Repo>-<task-slug>    one worktree per in-flight task, own branch
~/repos/upstream/<owner>-<repo>         clone of a repo under another owner, not a fork
```

`upstream/` is flat rather than nested by owner, so one `ls` reads every
reference checkout, the same reasoning that already keeps `worktrees/`
flat. Naming a clone by the same `<owner>-<repo>` join a fork uses means
forking it later moves the directory up one level under the name it
already has, and a worktree off it needs no new rule:
`~/repos/worktrees/<owner>-<repo>-<task-slug>`.

### The two naming rules the flat namespace depends on

Both were practice, neither was written down, and the collision is only
explicable with them stated:

- **A fork carries the upstream owner in its name at fork time**,
`esphome-esphome` for `esphome/esphome`. 15 of the 17 existing forks
already do this.
- **A repository adopted as the owner's own work is detached from its
parent and keeps a plain name**, `aiopurpleair` rather than
`bachya-aiopurpleair`, since it tracks nothing upstream. The fleet
already has both of those repos side by side, which is what makes this
the existing rule rather than a new one.

The section also notes that contributing from an `upstream/` clone is
never a push out of it, routing to the `upstream-contribution-workflow`
skill, which fixes the layout back to the flat namespace once a fork
exists.

## Testing

- `python3 scripts/build_dist.py` regenerated the plugin tree, and
`--check` reports it current.
- `python3 scripts/prose_lint.py` clean over the whole tree (195 files).
- `python3 scripts/repo_gate.py` clean (eol, eol-coverage, sha-pin).
- The `cspell` gate covers README and HISTORY only, so this file is out
of its scope and no dictionary entry is needed.

## Follow-up, not in this PR

Two existing repos are off the convention this PR writes down, and
renaming a repository is outward-facing, so the list is the maintainer's
to run:

- `ptr727-jellyfin` -> `jellyfin-jellyfin` (parent `jellyfin/jellyfin`).
The live upstream makes this a real future collision.
- `esphome-esphome-docs` -> `esphome-esphome.io` (parent
`esphome/esphome.io`). A hand-name for a dotted upstream, where the
sibling `home-assistant-home-assistant.io` keeps its dot.
- `Postfix-Relay` (parent `juanluisbaptiste/docker-postfix`)
deliberately keeps its name. It is an adopted product rather than a
tracked fork, so under the rule above it is a candidate to detach on
GitHub, not to rename.
Refreshes `reports/photocleaner/audit.md` after the resync driven from
hub `0e84805`, per RESYNC.md section 6 ("done means measured").

- `main` (`c457ff3`) still measures as the pre-resync state (43
findings, run stamp `audit run 2026-08-15T14:28:27Z | hub 0e84805`),
reported as such rather than reading `develop` as ground truth.
- `develop` (`e8b7a81`, after ptr727/PhotoCleaner#49 and
ptr727/PhotoCleaner#50) reports only the two `investigate`-dispositioned
hub-only files (`audit run 2026-08-15T14:58:12Z | hub d54862a | branch
override develop`).
- The `develop -> main` promotion ptr727/PhotoCleaner#51 is open and
blocked on the prose gate's `dead-path` rule flagging verbatim mentions
of the retired `repo-config/configure.sh`, filed as #721. The second hub
finding from the pass, the dead `every-finding-ends-in-an-action` anchor
in `.github/copilot-instructions.md`, is #722.
- The registry `driftNotes` stand: both still describe reality (publish
shape, private-for-now).

Report lints clean (markdownlint, prose_lint), and `spec/validate.py`
passes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…tions.md (#730)

Closes #720
Closes #722

Both defects are in `.github/copilot-instructions.md`, which every fleet
repo carries whole, so each one reaches every carrier rather than
staying in the hub. #722 is the same dead anchor as #720's second item,
filed separately from a different downstream pass.

**The hub slug (#720 item 1).** The "A Shape Nothing Recognizes Blocks
the Loop and Earns an Issue" step named the hub as
`ptr727/ProjectTemplate`. The file declares no verbatim section, so the
audit's `carried:` check flags that name in any downstream copy, and a
byte-faithful carry trips it: `audit.py --branch hub-resync-2026-08-15
PlexCleaner` reported exactly that on ptr727/PlexCleaner#922. The rule's
own exception, in `comment-and-doc-style`'s
`references/carried-doc-references.md`, is scoped to a verbatim region,
so the canonical is what needs fixing rather than the check needing an
exception. The step now routes the reader through the `AGENTS.md` "Fleet
Bootstrap" section, which is byte-locked and whose whole function is to
name the hub, matching the wording PlexCleaner already reworded its copy
to.

**The dead anchor (#720 item 2, #722).** The Disproved Claims section
linked `../GOVERNANCE.md#every-finding-ends-in-an-action`. That heading
left `GOVERNANCE.md` when the review-loop contract was packaged as the
`pr-review-conduct` Skill (#677), where the rule now reads "Every
finding ends in one of five outcomes", so the link resolves nowhere in
the hub or in any carrier. It now points at "PR Review Etiquette", the
section that routes to that Skill, and names the Skill.

A sweep of every relative Markdown anchor in the tree (101 files) found
this as the only dead one, so the fix is complete rather than the first
of a batch.

Prose gate and markdownlint clean on the file.
Closes #721

A repository that retires its copy of a hub-hosted file, per the
`retire` disposition in `spec/divergences.json`, keeps naming the hub's
copy in its carried docs. That is what `GOVERNANCE.md` "Hub-Hosted
Tooling" requires of carried text naming a tool ("a pointer that
resolves nowhere teaches the reader that a pointer in carried text is
decorative"), so rewording is the wrong remedy. But the tree no longer
holds the file and git once tracked it, which is exactly the signature
`dead-path` keys on, so every such mention is reported.

The rule's own exemption reads the scanning tree's `spec/files.json`,
which no repository carries, so downstream the exemption set is empty
and the class cannot be recognized at all. It surfaces at the `develop
-> main` promotion, whose diff base brings the whole retirement into
scope, leaving a maintainer's ruleset bypass as the only local remedy
for a linter false positive. Observed on ptr727/PhotoCleaner#51, and
PlexCleaner carries the same `GOVERNANCE.md:29` mention.

This is option 1 from the issue. Option 2 (reword the verbatim units to
name no path) is the one `RESYNC.md` section 4 warns against, since a
layout sentence that names no path is the blind spot the whole
`dead-path` rule exists to narrow.

- `HUB_HOSTED` is a literal in `prose_lint.py`, because the prose-gate
action fetches that one file with no hub tree beside it to read the
ledger from.
- A test asserts the literal equals the ledger's `retire` dispositions,
so a new retirement cannot land on one side only.
- A second test builds a repository that tracked and deleted
`repo-config/configure.sh` and asserts the mention is clean.
- The two exemption sets are now compared as posix paths, which is the
form the manifest and the ledger hold.

`docs/fleet-map.md` G4 records the second exemption and why it cannot be
derived downstream.

Verified: 246 tests in `test_prose_lint.py` pass, every other
`scripts/tests` module passes, `build_dist.py --check` is current, ruff
format and check are clean, and the whole-tree prose gate,
`repo_gate.py`, and `spec/validate.py` all pass.
…-15 Resync (#732)

Closes #719

The hub-side half of `RESYNC.md` for the PlexCleaner pass promoted this
morning (ptr727/PlexCleaner#922, #923, #924, `main` at `16f196e`). All
three checkboxes on the issue.

**Report (`reports/plexcleaner/audit.md`).** The committed one was dated
2026-07-04 and described drift that no longer exists. Re-measured at
`16f196e` rather than carried forward, so every workflow divergence the
old snapshot recorded was re-read:

- Two are **closed**: `validate-release` is now a dedicated entry job
checking both directions, and the release task deletes its
`release-asset-*` transfer artifacts at the point of consumption.
- Two still **stand as letter misses** whose intent holds: no `changes`
paths-filter (it over-builds and cannot under-build), and a dispatch
guard that skips silently rather than failing fast.
- Two are **new**: the repo consumes no prose gate, so nothing checks a
new line against the fleet prose rules (a whole-tree run reports 772
findings, the fleet remedy being the diff-scoped gate rather than a
sweep), and `.gitattributes:29` pins `*.Dockerfile` to LF with no
tracked file matching, which fails `repo_gate.py --check eol-coverage`.
- `develop` is 0 ahead and 89 behind `main` with **identical trees**, so
the count is the promotion-merge artifact rather than the divergence the
2026-07 snapshot reported.

Verdict: operational. `spec/audit.py PlexCleaner` reports clean after
the ledger settlement below.

**Registry.** The branch-hygiene `driftNote` is deleted. The three
Dependabot branches it names are gone and the live list holds seven
branches beyond `main` and `develop` rather than four, so it describes
neither state, and branch hygiene is not a baseline deviation any check
scores. Re-snapshotting it would only rot again. The
`ARCHITECTURE.md`/`codecov.yml` note and the csharp+python shape note
were both re-verified and stand, down to the
`RegressionTests/pyproject.toml` holding only ruff and mypy config.
`status`, `types`, `publish`, `requiredSecrets`, `consumerModel`,
`releaseTrigger`, and `configLayout` are unchanged.

**Ledger.** `.github/workflows/publish-release.yml` and
`.github/workflows/validate-task.yml` move from `investigate` to
`accepted`, settled by reading every cataloged repo's copy on its
ground-truth branch rather than by judgment:

- The publisher: 18 carry one, 4 do not. Job keys are per-repo
(`publish` in 15 of 18, against `create-release`, `publish-pypi`, and an
eight-job orchestration), and triggers run from dispatch-only through
dispatch plus schedule plus a paths-filtered push.
- The validator: 14 carry one, 8 do not, in six distinct job-list
shapes, sharing only the `workflow_call` trigger.
- No `interface` contract the schema can express fits either, and no
`appliesTo` selector separates the carriers from the non-carriers, since
`source-only` repos sit on both sides of each. What each file must honor
is already declared through `test-pull-request.yml` and
`build-release-task.yml`, plus WORKFLOW.md's D-guarantees read by hand.

This clears the last standing finding in every repo that carries these
two files, so it is worth a second look at review.
`reports/divergences.md` is regenerated from the ledger and picks up
live fleet state since its last run.

**Also.** `reports/conformance-matrix.md` gets the `csharp` + `python`
row's first audit date, this being the first run to judge the `python`
checks.

Verified: `spec/validate.py`, `spec/audit.py --selftest`,
`scripts/repo_gate.py`, the whole-tree and diff-scoped prose gates, and
markdownlint all pass.
Copilot AI lite review requested due to automatic review settings August 15, 2026 17:42

Copilot AI left a comment

Copy link
Copy Markdown

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 promotes a set of already-merged develop changes to main, focusing on (1) settling fleet divergence ledger dispositions, (2) fixing a real downstream-blocking false positive in prose_lint.py’s dead-path rule, (3) updating canonical Copilot runbook wording, (4) documenting/updating the repo layout convention for upstream clones, and (5) refreshing/resyncing audit reports and registry notes to reflect current ground truth.

Changes:

  • Update the divergence ledger to accept previously-investigate workflow “gaps” as intentional path-collisions, and regenerate fleet reports accordingly.
  • Fix prose_lint.py dead-path to exempt hub-hosted (retired) paths in downstream repos, with new regression tests and updated fleet-map documentation.
  • Refresh audit reports and supporting registry/conformance-matrix entries; update Copilot instructions and the repo-worktree skill to include the new upstream/ layout segment.

Reviewed changes

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

Show a summary per file
File Description
spec/divergences.json Settles workflow gap dispositions and refines retire-ledger wording used by generated divergence reporting.
scripts/prose_lint.py Exempts hub-hosted retired paths from dead-path findings and normalizes path keys to posix form for git pathspecs.
scripts/tests/test_prose_lint.py Adds regression coverage for hub-hosted exemptions and asserts the literal set matches the ledger.
docs/fleet-map.md Documents the new hub-hosted exemption rationale and test coverage for the dead-path rule.
.github/copilot-instructions.md Fixes hub routing wording and re-points a previously dead GOVERNANCE anchor reference.
reports/plexcleaner/audit.md Replaces an outdated audit snapshot with a current measured report reflecting post-resync state.
reports/photocleaner/audit.md Refreshes the audit report to distinguish main vs develop state and record the promotion blockage context.
reports/homeautomation-config/audit.md Adds the first committed audit report for HomeAutomation-Config after resync/promotion.
reports/divergences.md Regenerated divergence report reflecting updated ledger dispositions and repo carry state.
reports/conformance-matrix.md Updates audited dates/shape references for csharp+python and operational config reference repo.
registry/repos.json Removes stale drift notes for PlexCleaner and HomeAutomation-Config now that the described conditions are resolved.
.agents/skills/repo-worktree/SKILL.md Documents ~/repos/upstream/<owner>-<repo> and clarifies naming/relationship rules for upstream clones vs forks.
.claude-plugin/fleet-skills/skills/repo-worktree/SKILL.md Mirrors the same repo layout convention update in the packaged skill copy.
.claude-plugin/fleet-skills/.source-digest Updates the digest to reflect the regenerated skill source state.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@ptr727
ptr727 merged commit b09078e into main Aug 15, 2026
7 checks passed
ptr727 added a commit that referenced this pull request Aug 15, 2026
…xes (#741)

Promotes `develop` to `main`. Two commits since #734, both governance
rather than tooling, and the trial merge is conflict-free.

Closes #737
Closes #738

## #736, the publisher and validator declared at intent fidelity

`spec/files.json` gains `.github/workflows/publish-release.yml` and
`.github/workflows/validate-task.yml`, and the two matching
`investigate` rows leave `spec/divergences.json`, a declared file being
no longer a gap.

This reverses the call #732 shipped. That change settled both as
`accepted`, which silences the finding and stops the audit measuring
either file again, and the maintainer caught that as the opposite of
what the fleet wants for them. `interface` genuinely does not fit, since
job keys and triggers are per-repo across every carrier, but `intent`
does: presence asserted, equivalence judged by hand, and a staleness
advisory when the hub's copy moves past a carrier's.

Scope is measured rather than assumed. The publisher applies to the
three publishing `releaseTrigger` values, which selects exactly the 18
carriers, since every repository lacking one carries `releaseTrigger:
none`. The validator applies to `*` by decision, making the reusable
validation task the fleet standard.

What promoting this turns on, fleet-wide, measured in one run at `audit
run 2026-08-15T17:35:45Z | hub 0713008`: 0 absences for the publisher, 8
for the validator (homeassistant-purpleair, KiCadLibrary, EspDinIoT,
ESPHome-Config, HomeAssistant-Config, DevKitCIoT, Vantage-Config,
HolidayLights), and 30 staleness advisories. 17 of those 30 are a known
false class, since the advisory has no action-pin normalization and the
hub's publisher last changed in a Dependabot bump, filed as #735.

`reports/plexcleaner/audit.md` is updated in the same commit, since it
is the report the earlier settlement was written into.

## #740, two carried-wording fixes

Both raised by Copilot against a carried copy on
ptr727/ESPHome-Config#94, and both are the same failure: a faithful copy
makes every carrier re-litigate one finding.

- **#737**: the `GOVENANCE.md` quotation now reads as quoted ("the
reviewer's own spelling and a path no diff carries") in the three
Markdown occurrences. The misspelling stays literal, because it is the
evidence for the sentence it sits in.
- **#738**: the `AGENTS.md` sentence named no sections and read as "none
of this file is editable". It now names the three byte-locked sections
and states that the preamble above them is the repository's own.

## Verification

Run against `develop` at `7c67328`: whole-tree prose gate,
`repo_gate.py` (eol, eol-coverage, sha-pin), `spec/validate.py`,
`spec/audit.py --selftest`, `build_dist.py --check`, markdownlint, and
editorconfig-checker all pass. `git merge-tree` of `main` and `develop`
is conflict-free, so there is no EOL-only conflict to resolve on this
promotion.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants