Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions reports/divergences.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ Generated by `python3 spec/fidelity_honesty.py --report` - do not hand-edit. Cur
- **TODO.md** (manifest gap, carried by Blog, HomeAutomation-Config) - A repo's own running backlog, which STANDUP.md section 2 names as one of the four declared destinations for repo-specific content. It is advisory and required by no selector, so the manifest deliberately does not declare it and a repo's copy is its own content rather than a carry.
- **.husky/pre-commit** (manifest gap, carried by AudioCleaner, LanguageTags, MediaTools, NxWitness, PhotoCleaner, PlexCleaner, Utilities) - A path collision rather than a carry. Each repo's hook runs that repo's own language formatters, and the hub's runs the doc gates, so the seven downstream copies share the path and none of the content: LanguageTags and Utilities run language formatting and style with no Docker, PlexCleaner runs CSharpier and dotnet format, and the hub runs prose_lint.py and repo_gate.py. Verified by reading the downstream copies on 2026-08-10.
- **scripts/README.md** (manifest gap, carried by KiCadLibrary) - A path collision rather than a carry. KiCadLibrary's copy documents its own KiCad tooling (common.py, verify_library.py, build_library.py) beside the scripts it describes, and shares nothing with the hub's fleet-gate documentation. Verified by reading it on 2026-08-10. scripts/ is a generic path, so a repo with its own tooling directory matches this check without carrying anything of the hub's.
- **.github/workflows/publish-release.yml** (manifest gap, carried by Blog, ESPHome-Config, ESPHome-NonRoot, Financial-Modeling, HomeAssistant-Config, HomeAutomation-Config, KiCadLibrary, LanguageTags, MediaTools, NxWitness, PhotoCleaner, PlexCleaner, Utilities, VSCode-Server-DotNetCore, Vantage-Config, aiopurpleair, homeassistant-purpleair) - 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, so 17 downstream repos carry one and 4 carry none). 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.
- **.github/workflows/validate-task.yml** (manifest gap, carried by AudioCleaner, Blog, ESPHome-NonRoot, Financial-Modeling, HomeAutomation-Config, LanguageTags, MediaTools, NxWitness, PhotoCleaner, PlexCleaner, Utilities, VSCode-Server-DotNetCore, aiopurpleair) - As publish-release.yml, and settled in the same 2026-08-15 read (14 copies read, the hub's own included, so 13 downstream repos carry one and 8 carry none). 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.

## Untriaged - add a disposition to `spec/divergences.json`

Expand Down
13 changes: 7 additions & 6 deletions reports/plexcleaner/audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
- **Workflow model:** release
- **Verdict:** operational
- **Date:** 2026-08-15
- **Run stamps:** `audit run 2026-08-15T15:13:26Z | hub d54862a` (the hub `develop` head, byte-identical to `main` at `0e84805`), re-run at `audit run 2026-08-15T15:30:07Z | hub d54862a` after the two gap dispositions below were settled
- **Run stamps:** `audit run 2026-08-15T15:13:26Z | hub d54862a` (the hub `develop` head, byte-identical to `main` at `0e84805`), and `audit run 2026-08-15T17:35:45Z | hub 0713008` after the two gap dispositions below were settled by declaring both files

Supersedes the 2026-07-04 snapshot, which measured the repository before the `AGENTS.md` and `GOVERNANCE.md` split, before `repo-config/configure.sh` was retired, and before the README structure sweep, so it described drift that no longer exists. This report is measured rather than carried forward: every row below was re-read at `16f196e`, and each structural workflow divergence the old snapshot recorded was re-checked rather than assumed. Two of them are closed.

Expand All @@ -17,7 +17,7 @@ The repository was resynced against the hub `main` at `0e84805` and promoted on

## Dimensions

The deterministic subset is `spec/audit.py` at the run stamps above. The first reports **0 defect, letter, or error findings** and two `hub-only` drift items, both of them the fleet-wide ledger question rather than this repository's. The second, after that question was settled, reports **clean**. The judgment rows are hand-read at `16f196e`.
The deterministic subset is `spec/audit.py` at the run stamps above, and both runs report **0 defect, letter, or error findings**. The first also raised two `hub-only` drift items, the fleet-wide ledger question rather than this repository's. The second, with both files now declared at `intent`, replaces them with two staleness advisories, and reading each against the hub retires both, see Drift Finding 6. The judgment rows are hand-read at `16f196e`.

| Dimension | Letter | Intent | Verdict | Evidence (file:line) |
| --- | --- | --- | --- | --- |
Expand All @@ -26,7 +26,7 @@ The deterministic subset is `spec/audit.py` at the run stamps above. The first r
| docker | pass | pass | pass | Registry layer cache keyed `buildcache-<branch>`, never `type=gha`, reading both branches and writing only the built one on push (`build-docker-task.yml:92-95`). The trimmed overview publishes from `Docker/README.md` on `main` only (`:105-113`). The image push is gated on `inputs.push` alone, independent of the release-create skip |
| python | pass | pass | pass | Lint-only profile: `RegressionTests/pyproject.toml` carries `[tool.ruff]` and `[tool.mypy]` and no `[project]` table, so there is no lockfile to pin. The tools run through `uvx` at pinned versions, `uvx ruff@0.15.22 check .`, `format --check .`, and `uvx mypy@2.3.0 .` (`validate-task.yml:98-100`), which is `python.scripts.uvx` satisfied. `python.uvlock.pinned` and `python.coverage.codecov` are N/A for this subtree, as the registry records |
| branch-model | pass | pass | pass | `repo-config/configure.sh check ptr727/PlexCleaner release` from the hub checkout at `d54862a` reports every ruleset rule and every general setting matching the carried payloads, with nothing to apply |
| carried-scope | pass | pass | pass | `repo-config/configure.sh` is retired from the tree, and no other hub-hosted path is carried. The two `investigate` hits are the fleet-wide question settled in this change rather than a repository finding, see Proposed Registry / Spec Updates |
| carried-scope | pass | pass | pass | `repo-config/configure.sh` is retired from the tree, and no other hub-hosted path is carried. The two `investigate` hits were the fleet-wide question settled in this change, and both files are now declared carries rather than gaps, so this repository's copies are measured instead of unclassified, see Proposed Registry / Spec Updates |
| repo-setup | pass | pass | pass | Every name in `spec/secrets.json` is present in both stores with no forbidden name, per the mechanized run. `.github/dependabot.yml` declares `nuget` and `github-actions` against both `main` and `develop`, which covers every implied ecosystem (`docker` and `devcontainers` are not implied here). `host-tools.json` declares the .NET 10 SDK alone, with the media tools argued as runtime rather than host dependencies |
| linter-parity | pass | pass | pass | One config per linter drives editor, CLI, and CI: csharpier and `dotnet format style --verify-no-changes` (`validate-task.yml:64-71`), markdownlint-cli2 and cspell (`:73-85`), ruff and mypy (`:91-100`), actionlint and editorconfig-checker (`:102-106`). The `.husky/pre-commit` hook runs the C# half natively and the Markdown half through already-present Docker images |
| recurring-violations | drift | pass | drift | The tree passes the mechanized `eol` check and carries no charset violation in text written since the rules took effect, but a whole-tree run of the hub prose gate reports 772 findings and `repo_gate.py --check eol-coverage` reports one. Neither is swept in CI here, because this repository consumes no prose gate. See Drift Findings 1 and 2 |
Expand All @@ -52,18 +52,19 @@ None. No applicable check fails both letter and intent.

## Drift Findings

1. **CI runs no prose gate, and the tree carries the backlog that follows.** The repository vendors no prose gate and consumes none, so nothing checks a new line against the fleet prose rules at any point (`validate-task.yml` runs no such step, and `.husky/pre-commit` runs markdownlint and cspell only). A whole-tree run of the hub's `scripts/prose_lint.py` reports 772 findings, most of them `comment-wrap` (342), `comment-case` (135), `semicolon` (120), and `dash` (82), concentrated in the C# sources and in text written before the rules existed. The fleet remedy is the diff-scoped gate rather than a tree-wide sweep, so consuming the hub's `prose-gate` action in `validate-task.yml`, as PhotoCleaner does, bounds the backlog at today's size and leaves the rest to the fix-as-edited policy. Two findings are substantive rather than stylistic and can be fixed on sight: `RegressionTests/RegressionTest.sh:75,361` carry the British `behaviour`, and `PlexCleaner/VideoProps.cs:138` duplicates `not`.
2. **`.gitattributes:29` pins `*.Dockerfile` to LF and no tracked file matches it.** `repo_gate.py --check eol-coverage` fails on exactly this. The repository consolidated on a single `Docker/Dockerfile`, which the `:28` pin already covers, so the `*.Dockerfile` line is either dropped or marked forward-declared the way the `uv.lock` block above it is.
1. **CI runs no prose gate, and the tree carries the backlog that follows.** The repository vendors no prose gate and consumes none, so nothing checks a new line against the fleet prose rules at any point (`validate-task.yml` runs no such step, and `.husky/pre-commit` runs markdownlint and cspell only). A whole-tree run of the hub's `scripts/prose_lint.py` reports 772 findings, most of them `comment-wrap` (342), `comment-case` (135), `semicolon` (120), and `dash` (82), concentrated in the C# sources and in text written before the rules existed. The fleet remedy is the diff-scoped gate rather than a tree-wide sweep, so consuming the hub's `prose-gate` action in `validate-task.yml`, as PhotoCleaner does, bounds the backlog at today's size and leaves the rest to the fix-as-edited policy. Filed as ptr727/PlexCleaner#925. Two findings are substantive rather than stylistic and can be fixed on sight: `RegressionTests/RegressionTest.sh:75,361` carry the British `behaviour`, and `PlexCleaner/VideoProps.cs:138` duplicates `not`.
2. **`.gitattributes:29` pins `*.Dockerfile` to LF and no tracked file matches it.** `repo_gate.py --check eol-coverage` fails on exactly this. The repository consolidated on a single `Docker/Dockerfile`, which the `:28` pin already covers, so the `*.Dockerfile` line is either dropped or marked forward-declared the way the `uv.lock` block above it is. Filed as ptr727/PlexCleaner#926.
3. **No `changes` paths-filter (D1.1, D1.4, D1.5).** Deliberate, and documented in the workflow header. It over-builds on a docs-only or workflow-only push and cannot under-build.
4. **The dispatch guard skips rather than failing fast (D2.3).** `publish-release.yml:33`. A dispatch from a feature branch is a green run that published nothing, which reads as a successful release.
5. **Two `GOVERNANCE.md` mentions name a path this tree no longer holds.** `GOVERNANCE.md:29` names `repo-config/configure.sh`, which is the hub-hosted pointer that rule requires rather than a stale mention, and is the false positive filed as #721 and fixed in #731. `GOVERNANCE.md:282` names `.vscode/settings.json`, which this repository genuinely deleted, so that one is a real stale mention for the file's next edit.
6. **Both `intent` staleness advisories on the newly declared workflows are false trails, read and retired here.** The advisory is date-based by design, a hint rather than proof, and `intent` equivalence is a human call. `validate-task.yml` last changed 2026-08-05 against a hub canonical that moved on 2026-08-14, but that hub change added `ruff format --check` and this copy already runs it, at a pinned version rather than `@latest` per its own convention (`validate-task.yml:99`). `publish-release.yml` last changed 2026-07-24 against a hub canonical that moved on 2026-08-08, and that hub change was a Dependabot action-pin bump, which is per-repo drift by definition. Neither copy trails the hub in substance. The publisher case is not this repository's at all: the advisory has no action-pin normalization, so a Dependabot bump in the hub marks every carrier at once, 17 of them in this run, filed as #735.

## Proposed Registry / Spec Updates

- **Delete the branch-hygiene `driftNote`.** It reads "3 stale Dependabot nuget branches (PRs closed/superseded) and an unmerged feature/727-decouple-release-assets branch linger". The Dependabot branches are gone, and the live list now holds seven branches beyond `main` and `develop` rather than four, so the note describes neither the old state nor the new one. Branch hygiene is also not a baseline deviation any check scores, which is what a `driftNote` records, so it is deleted rather than re-snapshotted into prose that rots the same way. Applied in this change.
- **The other two `driftNotes` stand.** `ARCHITECTURE.md` and `codecov.yml` are both carried beyond the baseline, and the csharp-plus-python shape note is accurate down to its details (the `RegressionTests/` subtree, no `uv.lock`, a `pyproject.toml` holding only ruff and mypy config, and the two N/A check ids).
- **`status`, `types`, `publish`, `requiredSecrets`, `consumerModel`, `releaseTrigger`, and `configLayout` are unchanged and accurate.**
- **Settle both `investigate` gap dispositions as `accepted`.** Applied in this change, with the measurement written into the ledger reason. Neither `.github/workflows/publish-release.yml` nor `.github/workflows/validate-task.yml` can be declared. Reading every cataloged repository's copy on its ground-truth branch shows the publisher's job keys are per-repo (`publish` in 15 of the 18 copies read, against `create-release`, `publish-pypi`, and an eight-job orchestration elsewhere) and its triggers run from dispatch-only to dispatch plus schedule plus push, while `validate-task.yml` is uniformly `on: workflow_call` over a per-repo job list in six distinct shapes. The counts here include the hub's own copy, so 17 downstream repositories carry a publisher and 13 carry a validator, which is what the ledger's carrier lists name. No `interface` contract the schema can express fits either file, and no `appliesTo` selector separates the carriers from the non-carriers, since `source-only` repos sit on both sides of each. What governs them is already declared: `test-pull-request.yml` and `build-release-task.yml` carry the interface contracts, and WORKFLOW.md's D-guarantees are read by hand per AUDIT.md section 5.
- **Settle both `investigate` gap dispositions by declaring the files at `intent` fidelity.** Applied in this change, and it is a fleet decision rather than this repository's, taken by the maintainer on the measurement below. `spec/files.json` gains `.github/workflows/publish-release.yml` (`appliesTo` the three publishing `releaseTrigger` values) and `.github/workflows/validate-task.yml` (`appliesTo` `*`), and both ledger rows are deleted, since a declared file is no longer a gap. What the measurement settled is the fidelity rather than the question of carrying: reading every cataloged repository's copy on its ground-truth branch shows the publisher's job keys are per-repo (`publish` in 15 of the 18 copies read, against `create-release`, `publish-pypi`, and an eight-job orchestration elsewhere) and its triggers run from dispatch-only to dispatch plus schedule plus push, while `validate-task.yml` is uniformly `on: workflow_call` over a per-repo job list in six distinct shapes. No `interface` contract fits that spread, and `intent` is the tier that does: presence asserted, equivalence judged by hand against the `intentRef`, and a staleness advisory raised when the hub's copy moves past a repository's, which is what keeps a copy close to the canonical rather than merely present. The publisher's scope is exact, since every repository lacking one carries `releaseTrigger: none` and all 18 carriers carry a publishing trigger. The validator is declared fleet-wide by decision rather than by measurement, so the eight repositories that inline their validation into `test-pull-request.yml` now carry a presence finding, which is the convergence this asks for rather than noise.
- **Set the `csharp` plus `python` row's Last audited to 2026-08-15** in `reports/conformance-matrix.md`. Applied in this change.

## Escalations
Expand Down
Loading