Skip to content

Reconcile the PlexCleaner Registry Entry and Report After the 2026-08-15 Resync - #732

Merged
ptr727 merged 4 commits into
developfrom
audit/719-plexcleaner-reconcile
Aug 15, 2026
Merged

Reconcile the PlexCleaner Registry Entry and Report After the 2026-08-15 Resync#732
ptr727 merged 4 commits into
developfrom
audit/719-plexcleaner-reconcile

Conversation

@ptr727

@ptr727 ptr727 commented Aug 15, 2026

Copy link
Copy Markdown
Owner

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.

…-15 resync

Closes the hub-side half of RESYNC.md for the PlexCleaner pass promoted
this morning (ptr727/PlexCleaner#922, #923, #924, main at 16f196e).

Report: the committed one was dated 2026-07-04 and predated the AGENTS.md
and GOVERNANCE.md split, the retirement of repo-config/configure.sh, and
the README structure sweep. Re-measured at 16f196e rather than carried
forward. Two of the workflow divergences it recorded are closed (the
validate-release entry gate now runs in both directions, and the release
task deletes its transfer artifacts at consumption), two still stand as
letter misses, and two new drift items surfaced: no prose gate runs in
that repo's CI, and a .gitattributes LF pin matches no tracked file.

Registry: the branch-hygiene driftNote described a state this pass did not
re-verify and that no longer holds (the Dependabot branches are gone and
the live list is longer), so it is deleted per AUDIT.md section 8 rather
than re-snapshotted. The other two notes were re-checked and stand.

Ledger: the publish-release.yml and validate-task.yml gap dispositions
move from investigate to accepted, settled by reading every cataloged
repo's copy on its ground-truth branch. Neither can be declared, since
the job lists are per-repo and no appliesTo selector separates the
carriers from the repos that carry none. What each must honor is already
declared through test-pull-request.yml and build-release-task.yml.
reports/divergences.md regenerated from the ledger.
Copilot AI lite review requested due to automatic review settings August 15, 2026 15:32

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

Updates the hub-side RESYNC artifacts for the PlexCleaner promotion on 2026-08-15 by refreshing the PlexCleaner audit snapshot, reconciling the registry entry, and settling previously “investigate” ledger items so the generated fleet divergence report reflects current dispositions.

Changes:

  • Mark .github/workflows/publish-release.yml and .github/workflows/validate-task.yml gap dispositions as accepted in spec/divergences.json.
  • Replace the stale PlexCleaner audit report with a re-measured 2026-08-15 snapshot and updated ledger settlement narrative.
  • Regenerate/refresh derived reporting (reports/divergences.md, reports/conformance-matrix.md) and remove an obsolete PlexCleaner registry drift note.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
spec/divergences.json Settles two workflow gap dispositions from investigate to accepted with updated rationale.
reports/plexcleaner/audit.md Replaces the old audit snapshot with a fresh 2026-08-15 report and updated drift/ledger notes.
reports/divergences.md Regenerated divergence report reflecting the updated dispositions and current fleet state.
reports/conformance-matrix.md Records the first audit date for the csharp + python (PlexCleaner) shape.
registry/repos.json Removes a stale PlexCleaner branch-hygiene drift note from the registry entry.
Suppressed comments (1)

reports/plexcleaner/audit.md:70

  • This escalation bullet also claims #721 was "fixed in this change", but there’s no corresponding fix in this PR. Consider removing the "fixed" claim or citing the PR/commit where it was actually fixed.
- **#721, fixed in this change.** `prose_lint.py --check dead-path` cannot recognize a hub-hosted path in a repository that retired the file, so `GOVERNANCE.md:29` here reports as a dead path. This repository is a second carrier of the finding PhotoCleaner hit at its promotion gate.

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

Comment thread spec/divergences.json Outdated
Comment thread reports/plexcleaner/audit.md Outdated
Comment thread reports/plexcleaner/audit.md Outdated
Comment thread reports/plexcleaner/audit.md Outdated
The report was rewritten whole, which flattened it to LF and failed
editorconfig-checker. Normalized back to CRLF, the endings the tree pins.

Content: the #721 fix is credited to #731 rather than to this change, the
carrier counts say they include the hub's own copy so they read one above
the downstream carrier lists in reports/divergences.md, and the workflow
model moves off the Types line onto its own.
Copilot AI review requested due to automatic review settings August 15, 2026 15:42
@ptr727

ptr727 commented Aug 15, 2026

Copy link
Copy Markdown
Owner Author

Answering the suppressed finding from round 1, which opens no thread (reports/plexcleaner/audit.md:70):

This escalation bullet also claims #721 was "fixed in this change", but there's no corresponding fix in this PR. Consider removing the "fixed" claim or citing the PR/commit where it was actually fixed.

Accepted, and it was right on both occurrences. Fixed in 72a3fa1: the escalation bullet now reads "fixed in #731 rather than here", and the Drift Finding that made the same claim cites #731 as well. The rule change lives in #731, which this PR only depends on for the GOVERNANCE.md:29 mention to stop reporting.

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

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

Suppressed comments (2)

reports/divergences.md:17

  • This generated bullet enumerates the carrier repos in the heading (“carried by …”), but the reason text still says “The carriers are not enumerated here…”, which contradicts what the reader sees and is confusing. Suggest rewording the underlying ledger reason (in spec/divergences.json) so it stays true both in the ledger (no per-repo list) and in the generated report (list is derived from live state).
- **repo-config/configure.sh** (manifest gap, carried by ESPHome-NonRoot, Financial-Modeling, HomeAssistant-Config, LanguageTags, NxWitness, PhotoCleaner, Utilities, VSCode-Server-DotNetCore, Vantage-Config, aiopurpleair, homeassistant-purpleair) - The script is hub-hosted rather than carried, per GOVERNANCE.md "Hub-Hosted Tooling", so it is no longer a manifest entry and a downstream copy is retired rather than re-vendored. Every copy the fleet holds is the hub's content with nothing per-repo in it, and the copies predate the payload-driven check mode, which is the drift this removes rather than converges. Delete the copy as each repo is next visited and run the hub's script against the repo instead. The carriers are not enumerated here, because the fleet-wide gap pass names them from live state and a hand-kept list understated them: it read six while fifteen repos carry one. The ruleset payloads and settings.json stay carried, since those are what the repo is audited against and what its own AUDIT.md diffs the live configuration against.

spec/divergences.json:16

  • These ledger reasons refer to “the carrier list above”, but spec/divergences.json itself doesn’t include a carrier list for these gaps, so “above” is ambiguous in the ledger context. Consider referencing the generated report explicitly (or noting it’s the downstream carrier list) to keep the ledger self-explanatory.
        { "path": ".github/workflows/publish-release.yml", "disposition": "accepted", "reason": "A path collision rather than a carry, settled 2026-08-15 by reading every cataloged repo's copy on its ground-truth branch (18 copies read, the hub's own included, and 4 repos carry none, so the carrier list above names 17). Each repo's publisher is its own. The job keys are per-repo (publish in 15 of the 18, against create-release on homeassistant-purpleair, publish-pypi on aiopurpleair, and an eight-job orchestration on NxWitness), and the triggers run from dispatch-only through dispatch plus schedule plus a paths-filtered push. No interface contract the schema can express fits that spread, and no appliesTo selector separates the carriers from the four that carry none, since both source-only and csharp+console repos sit on either side. What the file must honor is declared elsewhere and needs no second entry: build-release-task.yml carries the interface contract for the release path, and WORKFLOW.md's D2.3, D4.1, and D7.1 are read by hand per AUDIT.md section 5.", "tracking": null },
        { "path": ".github/workflows/validate-task.yml", "disposition": "accepted", "reason": "As publish-release.yml, and settled in the same 2026-08-15 read (14 copies read, the hub's own included, and 8 repos carry none, so the carrier list above names 13). Every carrier is on: workflow_call over a per-repo job list, in six distinct shapes across the 14 (lint alone on 3, unit-test plus lint on 5, validate alone on 2, lint plus test plus docs on 2, compile-test plus lint on 1, and unit-test plus lint plus codegen-drift on 1), so the only thing every copy shares is the trigger, which no contract field states. The 8 that carry none inline their validation instead, and no selector separates them, since source-only repos again sit on either side. The fixed part is the required check the aggregator reports, which test-pull-request.yml declares at interface fidelity and the ruleset binds by name.", "tracking": null }

Two suppressed review findings, both about a reference that only resolves
in the rendered report. The new reasons said "the carrier list above",
which names nothing in the ledger itself, and the configure.sh reason
said the carriers are not enumerated here while the generated bullet
enumerates them in its heading. Each now names where the list lives.
Copilot AI review requested due to automatic review settings August 15, 2026 15:50
@ptr727

ptr727 commented Aug 15, 2026

Copy link
Copy Markdown
Owner Author

Answering the two suppressed findings from round 2, which open no threads. Both accepted, fixed in 49789c5.

spec/divergences.json:16 These ledger reasons refer to "the carrier list above", but spec/divergences.json itself doesn't include a carrier list for these gaps, so "above" is ambiguous in the ledger context.

Correct, and it was my wording. Both reasons now say "the carrier list in the generated reports/divergences.md names 17" (and 13), so the reference resolves from inside the ledger rather than only from the rendered page.

reports/divergences.md:17 This generated bullet enumerates the carrier repos in the heading ("carried by ..."), but the reason text still says "The carriers are not enumerated here...", which contradicts what the reader sees.

Also correct, and pre-existing rather than from this change, but it is one clause and the fix is the same shape as the one above, so it is done here rather than deferred. The repo-config/configure.sh reason now reads "not enumerated in this ledger entry, because the fleet-wide gap pass names them from live state in the generated report", which is true in both places. reports/divergences.md is regenerated from it.

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

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

Suppressed comments (2)

spec/divergences.json:16

  • Same self-referential phrasing issue as the publish-release entry: this reason mentions “the generated reports/divergences.md”, but the same string is emitted into that generated report. Rewording to “the downstream carrier list” keeps the meaning without pointing at the report itself.
        { "path": ".github/workflows/validate-task.yml", "disposition": "accepted", "reason": "As publish-release.yml, and settled in the same 2026-08-15 read (14 copies read, the hub's own included, and 8 repos carry none, so the carrier list in the generated reports/divergences.md names 13). Every carrier is on: workflow_call over a per-repo job list, in six distinct shapes across the 14 (lint alone on 3, unit-test plus lint on 5, validate alone on 2, lint plus test plus docs on 2, compile-test plus lint on 1, and unit-test plus lint plus codegen-drift on 1), so the only thing every copy shares is the trigger, which no contract field states. The 8 that carry none inline their validation instead, and no selector separates them, since source-only repos again sit on either side. The fixed part is the required check the aggregator reports, which test-pull-request.yml declares at interface fidelity and the ruleset binds by name.", "tracking": null }

spec/divergences.json:15

  • The reason text references reports/divergences.md as “the generated reports/divergences.md”, but this string is also embedded verbatim into reports/divergences.md during generation. That makes the report self-referential and less clear. Consider wording that works in both contexts (e.g., “the downstream carrier list”).

This issue also appears on line 16 of the same file.

        { "path": ".github/workflows/publish-release.yml", "disposition": "accepted", "reason": "A path collision rather than a carry, settled 2026-08-15 by reading every cataloged repo's copy on its ground-truth branch (18 copies read, the hub's own included, and 4 repos carry none, so the carrier list in the generated reports/divergences.md names 17). Each repo's publisher is its own. The job keys are per-repo (publish in 15 of the 18, against create-release on homeassistant-purpleair, publish-pypi on aiopurpleair, and an eight-job orchestration on NxWitness), and the triggers run from dispatch-only through dispatch plus schedule plus a paths-filtered push. No interface contract the schema can express fits that spread, and no appliesTo selector separates the carriers from the four that carry none, since both source-only and csharp+console repos sit on either side. What the file must honor is declared elsewhere and needs no second entry: build-release-task.yml carries the interface contract for the release path, and WORKFLOW.md's D2.3, D4.1, and D7.1 are read by hand per AUDIT.md section 5.", "tracking": null },

The reason text is embedded into the generated report, so a phrase naming
that report reads as self-referential once rendered. Both reasons now
give the downstream count outright, which is true in either context.
Copilot AI review requested due to automatic review settings August 15, 2026 15:58
@ptr727

ptr727 commented Aug 15, 2026

Copy link
Copy Markdown
Owner Author

Answering the round-3 suppressed findings (both the same point, on spec/divergences.json:15 and :16). Accepted, fixed in 0713008.

The reason text references reports/divergences.md as "the generated reports/divergences.md", but this string is also embedded verbatim into reports/divergences.md during generation. That makes the report self-referential and less clear.

Right, and it is the second time this clause has been reworded, so it is now written to need no referent at all: "18 copies read, the hub's own included, so 17 downstream repos carry one and 4 carry none" (and 14/13/8 for the validator). That states the downstream count outright, which is true in the ledger and in the generated report alike, and it also removes the ambiguity the round-2 finding raised. The audit report's matching sentence is reworded the same way.

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

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

@ptr727
ptr727 merged commit 4ab230c into develop Aug 15, 2026
7 checks passed
@ptr727
ptr727 deleted the audit/719-plexcleaner-reconcile branch August 15, 2026 16:20
ptr727 added a commit that referenced this pull request Aug 15, 2026
… the Upstream Repo-Layout Segment (#734)

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

Promotes six merged `develop` PRs to `main`:

- #732 -- Reconcile the PlexCleaner registry entry and audit report
after the 2026-08-15 resync (closes #719).
- #731 -- Exempt hub-hosted paths from the prose gate's `dead-path` rule
(closes #721).
- #730 -- Fix the hub slug and the dead anchor in the canonical
`copilot-instructions.md` (closes #720, #722).
- #723 -- Refresh the PhotoCleaner audit report after the 0e84805
resync.
- #733 -- Add an `upstream/` segment to the repo layout convention
(addresses #725, not closed -- the fork-naming variant differs from the
issue's proposal).
- #724 -- Add the HomeAutomation-Config audit report and reconcile its
registry entry.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
ptr727 added a commit that referenced this pull request Aug 15, 2026
Follow-up to #732, which settled `.github/workflows/publish-release.yml`
and `.github/workflows/validate-task.yml` as `accepted` gaps. That call
was wrong and this reverses it.

## What was wrong

`accepted` means "a path collision, the repo's own file", and its effect
is to silence the finding and stop the audit measuring either file ever
again. The fleet's intent for these two is the opposite: carry the hub's
copy as closely as each repository's targets allow, so a diff against
the canonical stays small and readable.

The reasoning behind #732 tested both files against `interface`
fidelity, found correctly that no named contract fits (job keys and
triggers are genuinely per-repo), and then concluded that nothing could
be declared. That skipped `intent`, which is exactly the tier for this:
presence asserted, equivalence judged by hand against the `intentRef`,
content never hashed, and a staleness advisory raised when the hub's
canonical moves past a carrier's copy.

The `appliesTo` claim was also wrong for the publisher. Re-measured:
every repository lacking one carries `releaseTrigger: none`
(AudioCleaner, HolidayLights, EspDinIoT, DevKitCIoT), and all 18
carriers carry a publishing trigger. That is an exact selector, and it
states something true, namely that a repository which publishes a
release has a publisher.

## What this does

```json
{ "path": ".github/workflows/validate-task.yml", "fidelity": "intent",
  "intentRef": "WORKFLOW.md#d1---pr-fast-feedback-smoke", "appliesTo": "*" },
{ "path": ".github/workflows/publish-release.yml", "fidelity": "intent",
  "intentRef": "WORKFLOW.md#d4---release--publish",
  "appliesTo": ["two-phase", "dispatch-only", "publish-on-merge"] }
```

Both ledger rows are deleted, since a declared file is no longer a gap
and `fidelity_honesty.py` drops such a row from the generated report by
construction.

The validator is declared fleet-wide **by decision rather than by
measurement**: no selector separates its carriers from the repositories
that inline validation into `test-pull-request.yml`, and the
maintainer's call is that the reusable task is the fleet standard. The
skill text already reads that way, naming `publish-release.yml` in the
orchestration layer that is "the standardization baseline".

## Measured impact, whole fleet

One full audit run at `audit run 2026-08-15T17:35:45Z | hub 0713008`:

| | absent (letter) | staleness advisory (drift) |
| --- | --- | --- |
| `publish-release.yml` | 0 | 17 |
| `validate-task.yml` | 8 | 13 |

- The publisher's 0 absences confirm the selector is exact.
- The validator's 8 absences are the convergence this asks for:
homeassistant-purpleair, KiCadLibrary, EspDinIoT, ESPHome-Config,
HomeAssistant-Config, DevKitCIoT, Vantage-Config, HolidayLights.
- **17 of the 30 advisories are a false class**, and they are not this
change's fault so much as this change's discovery: the intent advisory
compares dates with no action-pin normalization, and the hub's publisher
last changed in a Dependabot pin bump (`1892d6f`), so every carrier
trips at once on drift the fidelity model already calls governed and
per-repo. Filed as #735 with three options.
- The other 13 are against `0d18078`, which added `ruff format --check`.
Real content, though a repository that adopted the same step
independently still reports as trailing, which is why the tier is an
advisory and not a verdict.

## PlexCleaner report

`reports/plexcleaner/audit.md` is updated in place, since it is the
report this settlement was written into. Its two new advisories are read
and retired in Drift Finding 6: the validator copy already runs `ruff
format --check` at a pinned version, and the publisher advisory is the
pin-bump class above. Verdict is unchanged at operational.

Verified: `spec/validate.py`, `spec/audit.py --selftest` (which asserts
no declared path leaks into the hub-only set), `scripts/repo_gate.py`,
the whole-tree prose gate, markdownlint, and editorconfig-checker all
pass.
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

Development

Successfully merging this pull request may close these issues.

2 participants