Skip to content
Merged
1 change: 0 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ end_of_line = lf
# [SuppressMessage] attribute or the owning project's .editorconfig; relax a rule
# repo-wide here only when it applies to every project (never a brownfield batch).
dotnet_diagnostic.IDE0055.severity = none
dotnet_analyzer_diagnostic.severity = suggestion
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
Expand Down
2 changes: 1 addition & 1 deletion AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ A repo is **operational** only if every applicable check passes. A single applic

Write `reports/<repo>/audit.md` from [`reports/_template.md`][template]: a dimension x {letter, intent, verdict, evidence} table with `file:line` citations (WORKFLOW.md 5A style), a drift section, and a list of proposed registry/spec updates (e.g. a resolved `classificationPending`). Rank findings most severe first.

**Findings are a point-in-time snapshot - stamp them and re-verify before acting.** [`spec/audit.py`][audit-runner] prints a run stamp (`audit run <UTC> | hub <sha>`) and, per repo, the exact commit it read (`@ <branch>@<sha>`). Anything derived from a run - a report, and especially an **onboarding or conformance issue** - quotes that stamp, so a reader can tell whether it still applies. An agent picking up such an issue **re-runs the audit first and acts on the live result, not the pasted findings**: a repo moves between filing and pickup, so a stale block leads an agent to "fix" what is already fixed (re-requesting secrets that exist, attempting a no-op forward-sync). State the findings as evidence for *why* the issue was filed, never as the current state.
**Findings are a point-in-time snapshot - stamp them and re-verify before acting.** [`spec/audit.py`][audit-runner] prints a run stamp (`audit run <UTC> | hub <sha>`) and, per repo, the exact commit it read (`@ <branch>@<sha>`). Anything derived from a run - a report, and especially an **onboarding or conformance issue** - quotes that stamp, so a reader can tell whether it still applies. A convergence issue is generated from the audit, never composed by hand: `spec/audit.py --issue <repo>` emits a ready-to-file title and body from that repo's live findings (grouped into must-fix, converge, and could-not-verify), so the issue content cannot drift from what the audit actually found and regenerates as the repo changes. An agent picking up such an issue **re-runs the audit first and acts on the live result, not the pasted findings**: a repo moves between filing and pickup, so a stale block leads an agent to "fix" what is already fixed (re-requesting secrets that exist, attempting a no-op forward-sync). State the findings as evidence for *why* the issue was filed, never as the current state.

**Reconcile `driftNotes` in the same pass.** A registry `driftNote` records a *current* deviation from the baseline. Once the deviation is resolved the note is deleted, not left describing finished work - hand-maintained prose drifts silently otherwise. `spec/audit.py` flags this: when a repo audits clean but a note still asserts outstanding work ("pending", "not yet", "missing", "behind", ...), it raises a drift finding naming the note.

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ Running backlog (kept here, in a committed file, so the guidance survives across
- Classify the standardization-backlog repos in [registry/repos.json][repos] (marked `classificationPending`) on first audit.
- Canonicalize Python linter-config placement on `pyproject.toml` (one cataloged repo uses standalone `.ruff.toml` + `pyrightconfig.json`); track as a drift finding, fix downstream.
- Consider renaming this repo to reflect the audit-catalog identity (updates badge and link URLs across the fleet).
- Adopt the OCI annotation keys (`org.opencontainers.image.*`) for Docker image metadata across the Docker repos, replacing the ad-hoc and `org.label-schema.*` labels (from #363).
- Finish onboarding hardening (from #310): make the `AUDIT.md` audit a required onboarding step and run the per-type cold-start self-tests tracked in `reports/conformance-matrix.md` (`STANDUP.md` is already in place).

## License

Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"nuget",
"nugetlibrary",
"onCreateCommand",
"opencontainers",
"Optix",
"othercommand",
"paramref",
Expand Down
2 changes: 1 addition & 1 deletion registry/repos.json
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
"requiredSecrets": ["CODECOV_TOKEN"],
"consumerModel": "pull",
"releaseTrigger": "none",
"driftNotes": ["Work-in-progress: pre-CI (no .github/workflows, no version.json, no repo-config).", "Pre-conformance: main exists but the work-in-progress content lives on develop - promote to main to converge.", "Dockerfile present but no docker build/push workflow, so no publish wired."]
"driftNotes": ["Partially onboarded: the PR gate and linters are live (test-pull-request.yml + validate-task.yml with the canonical aggregator name), but rulesets, repo-config/, version.json, WORKFLOW.md, AUDIT.md, spec/secrets.json, dependabot.yml, and the release pipeline are still missing (reports/photocleaner/audit.md).", "develop is diverged from main (ahead 1, behind 3) - forward-sync the main-only commits to develop.", "Dockerfile present but no docker build/push workflow, so no publish wired."]
},
{
"name": "MediaTools",
Expand Down
6 changes: 4 additions & 2 deletions reports/divergences.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ Generated by `python3 spec/fidelity_honesty.py --report` - do not hand-edit. Cur

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

_None - every live divergence has a recorded disposition._
- **AGENTS.md > Repository Boundaries and Write Safety** - hand-modified in AudioCleaner, DevKitCIoT, ESPHome-Config, ESPHome-NonRoot, Financial-Modeling, HolidayLights, HomeAssistant-Config, HomeAutomation-Config, KiCadLibrary, LanguageTags, MediaTools, NxWitness, PhotoCleaner, PlexCleaner, Utilities, VSCode-Server-DotNetCore, Vantage-Config, aiopurpleair, homeassistant-purpleair (verbatim canonical)
- **AGENTS.md > Git and Commit Rules** - hand-modified in AudioCleaner, DevKitCIoT, ESPHome-Config, ESPHome-NonRoot, Financial-Modeling, HolidayLights, HomeAssistant-Config, HomeAutomation-Config, KiCadLibrary, LanguageTags, MediaTools, NxWitness, PhotoCleaner, PlexCleaner, Utilities, VSCode-Server-DotNetCore, Vantage-Config, aiopurpleair, homeassistant-purpleair (verbatim canonical)
- **AGENTS.md > Verification Discipline** - hand-modified in AudioCleaner, DevKitCIoT, ESPHome-Config, ESPHome-NonRoot, Financial-Modeling, HolidayLights, HomeAssistant-Config, HomeAutomation-Config, KiCadLibrary, LanguageTags, MediaTools, NxWitness, PhotoCleaner, PlexCleaner, Utilities, VSCode-Server-DotNetCore, Vantage-Config, aiopurpleair, homeassistant-purpleair (verbatim canonical)

## Mechanical re-vendor (verbatim stale copies)

A past hub revision, not the current canonical - the audit already flags these as DRIFT. Copy the current file down. No judgment needed.

- **.markdownlint-cli2.jsonc** (15): DevKitCIoT, ESPHome-Config, ESPHome-NonRoot, HolidayLights, HomeAssistant-Config, HomeAutomation-Config, KiCadLibrary, LanguageTags, MediaTools, NxWitness, PlexCleaner, Utilities, VSCode-Server-DotNetCore, Vantage-Config, homeassistant-purpleair
- **repo-config/configure.sh** (8): ESPHome-Config, Financial-Modeling, HomeAssistant-Config, HomeAutomation-Config, PlexCleaner, ProjectTemplate, Utilities, Vantage-Config
- **repo-config/configure.sh** (7): ESPHome-Config, Financial-Modeling, HomeAssistant-Config, HomeAutomation-Config, PlexCleaner, Utilities, Vantage-Config

## Promote candidates (intent uniform -> verbatim)

Expand Down
44 changes: 44 additions & 0 deletions reports/photocleaner/audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Audit: PhotoCleaner

- **Audited branch:** main (`3b33b98956190b91b8ed1d3e49e8242545ea523c`)
- **Types:** csharp, console, docker (from registry)
- **Verdict:** not operational
- **Date:** 2026-07-23
- **Run stamp:** `audit run 2026-07-23T13:51:20Z | hub 614a291`

## Develop Drift

`develop` vs `main`: ahead 1, behind 3 (`gh api repos/ptr727/PhotoCleaner/compare/main...develop`). **Diverged, and the behind direction is the anomaly** - under the forward-only model `develop` never trails `main`, so the three `main`-only commits need a forward sync to `develop` - re-apply or cherry-pick them onto `develop`, never a `main -> develop` back-merge.

## Dimensions

| Dimension | Letter | Intent | Verdict | Evidence (file:line) |
| --- | --- | --- | --- | --- |
| csharp | fail | fail | drift | `.editorconfig:60` carries the repo-wide `dotnet_analyzer_diagnostic.severity = suggestion` CODESTYLE.md forbids (the hub canonical dropped it in ProjectTemplate#400). `PhotoCleaner/PhotoCleaner.csproj:3-4` sets `AnalysisLevel=latest-all` + `EnableNETAnalyzers=true` but **no `TreatWarningsAsErrors` anywhere**, so analyzers are demoted to suggestions and warnings never fail the build. The ProjectTemplate#353 probe measured what this hides: 362 `xUnit1051` + 2 `xUnit1030`, plus pre-existing `NU1903` (SQLitePCLRaw 2.1.10 high-severity advisory) and 4 `CS8625` that warn without failing anything |
| console | fail | pass | drift | a real System.CommandLine console app (`PhotoCleaner/PhotoCleaner.csproj:9 OutputType=Exe`, `PhotoCleaner/PhotoCleaner.csproj:34 System.CommandLine 2.0.5`, net10.0) but no `build-executable-task.yml` and no release pipeline, so the smoke-subset and `release-asset-<branch>-<target>` checks have nothing to bind to |
| docker | fail | fail | drift | `Docker/Dockerfile` present but no docker build/push workflow and no `Docker/README.md` - the Dockerfile is dead weight until a pipeline exists |
| branch-model | fail | fail | defect | **no rulesets at all** - `develop` and `main` both unprotected (audit DEFECT x2). No `repo-config/` payloads to import. Branches diverged (see Develop Drift) |
| repo-setup | pass | fail | drift | secrets fully provisioned in both stores (`CODECOV_TOKEN`, `CODEGEN_APP_CLIENT_ID`, `CODEGEN_APP_PRIVATE_KEY` in actions + dependabot) but nothing consumes the App creds - `.github/dependabot.yml` is absent (no dual-target sync keystone) and there is no merge-bot workflow |
| linter-parity | pass | pass | pass | `validate-task.yml:66-88` runs csharpier check, `dotnet format style --verify-no-changes`, markdownlint (SHA-pinned action), cspell (SHA-pinned), actionlint (SHA-pinned), and editorconfig-checker via docker `:latest`. The unit-test job collects coverage and uploads to codecov v7 (`validate-task.yml:36-40`). Matches the fleet lint architecture |
| recurring-violations | pass | pass | pass | `.gitattributes:3` fleet-standard `* -text` with LF pins for `*.sh` and `.husky/pre-commit`. README em-dash grep clean |
| readme-structure | fail | pass | drift | app-focused and thorough (`## Overview:5`, `## Usage:46`, flow sections, `## Docker:415`, `## Development Tooling:474`, `## License:653`) but not the fleet section set - no Build and Distribution block (nothing to badge pre-release), no Table of Contents, no Questions or Issues, Development-Environment-Setup slot filled by `Development Tooling` |
| workflow (WORKFLOW.md 5A/5B) | fail | pass | drift | no publisher, so the 5A publish guarantees are N/A. The PR gate itself is sound - `validate` runs unconditionally and the aggregator carries the canonical ruleset-bound name `Check pull request workflow status job` (`test-pull-request.yml:34-40`, interface contract passes, no paths-filter/smoke by design per the header `test-pull-request.yml:5`) - but with no ruleset the required check binds to nothing, so the gate is advisory until branch-model lands |

nuget, pypi, python: N/A (no packaging, no Python).

## Defects (most severe first)

1. **Both branch rulesets missing** - `develop` and `main` are unprotected: no signed-commit requirement, no PR gate, no required status check, force-push and deletion possible. Import `repo-config/develop.json` + `main.json` via `configure.sh apply` once `repo-config/` is carried.

## Drift Findings

- `AGENTS.md` is an old skeleton: 6 of the carried intent sections missing (Branching Model, Release Model, Pull Request Title and Commit Message Conventions, Documentation Style Conventions, PR Review Etiquette, Workflow YAML Conventions) and all 3 verbatim universal sections absent (Repository Boundaries and Write Safety, Git and Commit Rules, Verification Discipline) - re-vendor from the hub.
- `.markdownlint-cli2.jsonc` hand-modified (matches no hub revision) - re-vendor the canonical.
- Absent baseline files (audit LETTERs): `WORKFLOW.md`, `version.json`, `repo-config/` (all six), `AUDIT.md`, `spec/secrets.json`, `.github/dependabot.yml`, `Docker/README.md`.
- `.editorconfig:60` analyzer relaxation + no `TreatWarningsAsErrors` (see csharp dimension) - the ProjectTemplate#353 downstream item, sequenced as its own PR (362 sites).
- Committed `CLAUDE.md` and `PhotoCleaner.code-workspace` at the repo root - repo-local extras. `AGENTS.md` is the fleet's agent-agnostic doc, so a committed `CLAUDE.md` duplicates that role and can drift from it.

## Proposed Registry / Spec Updates

- Refresh the stale `driftNotes`: the repo is no longer pre-CI (PR gate + linters live). The current gaps are rulesets, `repo-config/`, `version.json`, governance docs, `dependabot.yml`, and the release pipeline. Applied in the same change as this report.
- `releaseTrigger: none` remains accurate until a publisher exists.
Loading