From 60a463c912aa8863d9b0947535ff8734cc8125a2 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Thu, 15 Oct 2026 23:42:54 -0700 Subject: [PATCH 1/5] Reconcile VSCode-Server-DotNetCore in the Hub After Its Resync Delete the stale driftNotes entry, tick the three adoption items on live main evidence, regenerate the workflow-reuse report, and refresh the audit report. Co-Authored-By: Claude Sonnet 5.5 --- docs/reusable-workflows.md | 6 +- registry/repos.json | 3 +- reports/vscode-server-dotnetcore/audit.md | 101 ++++------------ reports/workflow-reuse.md | 139 +++++++++------------- 4 files changed, 84 insertions(+), 165 deletions(-) diff --git a/docs/reusable-workflows.md b/docs/reusable-workflows.md index f23ac9141..80d3ac8e3 100644 --- a/docs/reusable-workflows.md +++ b/docs/reusable-workflows.md @@ -196,7 +196,7 @@ Hub: `get-version-task.yml` and `publish-plan-task.yml` hosted, and the downstre - [ ] NxWitness (`get-version-task.yml` and `publish-plan-task.yml`) - [ ] PhotoCleaner (`get-version-task.yml`) - [ ] PlexCleaner (`get-version-task.yml`, and gains the `plan` job D4.1 requires by adopting `publish-plan-task.yml` rather than by a copy) - - [ ] VSCode-Server-DotNetCore (`get-version-task.yml`) + - [x] VSCode-Server-DotNetCore (`get-version-task.yml`): carries no copy, with versioning through the hub's `build-release-task.yml`, which calls `get-version-task.yml`, adopted on `develop` in ptr727/VSCode-Server-DotNetCore#129 and carried on `main`, its ground-truth branch, at `e571822`, where the `main` audit run 2026-10-16T06:40:34Z reports no `interface` finding. - [x] KiCadLibrary (`get-version-task.yml`): its copy deleted, with versioning through the hub's `build-release-task.yml`, which calls `get-version-task.yml`, in ptr727/KiCadLibrary#60, promoted to `main` in ptr727/KiCadLibrary#65, where the `main` audit run 2026-10-04T01:15:54Z reports no `interface` finding. - [ ] aiopurpleair (`get-version-task.yml`) - [x] homeassistant-purpleair (`get-version-task.yml`): adopted on `develop` in ptr727/homeassistant-purpleair#372 at `2725f91`, which deleted its copy and pointed its local `build-release-task.yml` at the hub's. It is promoted to `main` in ptr727/homeassistant-purpleair#373 at `32a33d1`. Since the Stage 4 adoption below, the call runs through the hub's `build-release-task.yml`, and `main` carries no `get-version-task.yml`. @@ -213,7 +213,7 @@ Hub: `build-release-task.yml` provides the `dotnet-publish`, `build-nuget`, and - [x] Promoted to `main` in #774 (`0b07a59d`) and released as `2.0.352`, the first tag carrying `build-release-task.yml` and `build-docker-task.yml`. The first release attempt, on `82fecef`, ended in `startup_failure` in [run-startup-failure][run-startup-failure] because `build-nuget` and `github-release` declared job-level permissions. #772 fixed it before #774 promoted. - [x] PhotoCleaner (pilot, vanilla Docker plus .NET publish): ptr727/PhotoCleaner#55 on `develop` (`c80cb29`), promoted in ptr727/PhotoCleaner#56 (`fa91db0`). The migration deleted five carried task files. It mapped every value to a task input (`dotnet_publish_project`, `docker_image`) and needed no repo hook. The [pilot publish run][pilot-publish-run] released `1.1.11` with the .NET publish asset and Docker image. That run exposed an archive naming regression between the hub default and the repo leaf. The fix derives the name from the project file, with `dotnet_publish_asset_name` as an override. The next PhotoCleaner release proves the fix. - [ ] PlexCleaner (second, the same shape) -- [ ] VSCode-Server-DotNetCore (vanilla Docker only) +- [x] VSCode-Server-DotNetCore (vanilla Docker only): `publish-release.yml` on `main`, its ground-truth branch, calls `build-release-task.yml` by pin with `enable_docker: true` and the other legs off, and `main` at `e571822` carries only the `merge-bot-pull-request.yml`, `publish-release.yml`, and `test-pull-request.yml` stubs, where the `main` audit run 2026-10-16T06:40:34Z reports no `interface` finding. - [ ] ESPHome-NonRoot (`docker-prepare` hook for the upstream pin) - [ ] NxWitness (matrix hook and `build-base`) - [x] KiCadLibrary (`build-release-asset` hook for its library zip, the hook's first caller): adopted in ptr727/KiCadLibrary#60, promoted to `main` in ptr727/KiCadLibrary#65, where the `main` audit run 2026-10-04T01:15:54Z reports no `interface` finding, and first published as 2.1.48. @@ -234,7 +234,7 @@ Hub: `publish-docker-readme-task.yml` with a `docker-readme-transform` hook, `ch - [x] Hub pull request on `develop` in #761. - [x] Promoted to `main` in #774 (`0b07a59d`) and released as `2.0.352`, the first tag carrying `publish-docker-readme-task.yml`, `check-upstream-version-task.yml`, `deploy-site-task.yml`, and `run-codegen-pull-request-task.yml`. - [ ] Adoption, one checkbox per carrier added when the hub pull request merges. - - [ ] VSCode-Server-DotNetCore (`publish-docker-readme-task.yml`) + - [x] VSCode-Server-DotNetCore (`publish-docker-readme-task.yml`): `publish-release.yml` on `main`, its ground-truth branch, calls `publish-docker-readme-task.yml` by pin and keeps no local copy, at `e571822`, where the `main` audit run 2026-10-16T06:40:34Z reports no `interface` finding. - [ ] NxWitness (`publish-docker-readme-task.yml`, moving the readme job out of `publish-release.yml`, and `run-codegen-pull-request-task.yml` with its scheduler) - [ ] ESPHome-NonRoot (`check-upstream-version-task.yml`, both trackers, the second with `auto-merge: false`) - [ ] Blog (`deploy-site-task.yml`, keeping `deploy-site.yml` as its own caller) diff --git a/registry/repos.json b/registry/repos.json index 9f03d70a0..aba290ab6 100644 --- a/registry/repos.json +++ b/registry/repos.json @@ -137,8 +137,7 @@ "publish": [{ "target": "docker", "mechanism": "static-secret" }], "requiredSecrets": ["DOCKER_HUB_USERNAME", "DOCKER_HUB_ACCESS_TOKEN"], "consumerModel": "pull", - "releaseTrigger": "two-phase", - "driftNotes": ["Separate publish-docker-readme-task for the Hub overview."] + "releaseTrigger": "two-phase" }, { "name": "NxWitness", diff --git a/reports/vscode-server-dotnetcore/audit.md b/reports/vscode-server-dotnetcore/audit.md index 68349ac74..6753a719f 100644 --- a/reports/vscode-server-dotnetcore/audit.md +++ b/reports/vscode-server-dotnetcore/audit.md @@ -1,97 +1,46 @@ # Audit: VSCode-Server-DotNetCore -- **Audited branch:** main (`80067f91167f2b56f223946397b69e41b70be834`) +- **Audited branch:** main (`e5718224c45eb598356d50a47be9df9566d79e7b`) - **Types:** docker (from registry) - **Verdict:** operational -- **Date:** 2026-07-04 +- **Date:** 2026-10-16 + +Basis: `python3 spec/audit.py VSCode-Server-DotNetCore` run 2026-10-16T06:40:34Z at hub `ddaeefb4`, reporting 0 defect, letter, or error findings, plus a read of the `main` tree. This report replaces the 2026-07-04 report, which described the repository before its resync to hub 2.0.685 (ptr727/VSCode-Server-DotNetCore#127 through #131) and its later pin bumps. ## Develop Drift -`develop` vs `main`: ahead 1, behind 19 (`gh api repos/ptr727/VSCode-Server-DotNetCore/compare/main...develop` -> `status: diverged, ahead_by: 1, behind_by: 19`). **Diverged - a drift finding.** `develop` carries 1 commit `main` lacks and is 19 behind. Under the forward-only model (no `main -> develop` back-merge) the `main`-only CI/CD rework and Dependabot bumps merged straight to `main` have not reached `develop`. The publisher has no push trigger (schedule is `main`-only, `publish-release.yml:12-16`) and `develop` publishes only via manual dispatch, so the divergence has no release impact; still worth reconciling. +`develop` vs `main`: ahead 2, behind 78 (`gh api repos/ptr727/VSCode-Server-DotNetCore/compare/main...develop` -> `status: diverged`). Classified by content, the two trees are identical (a recursive diff of the `main` and `develop` tarballs reports no difference). The two `develop` commits are the Dependabot bumps ptr727/VSCode-Server-DotNetCore#157 and #159, whose same-titled twins ptr727/VSCode-Server-DotNetCore#158 and #160 reached `main`. Benign, inherent to merge-commit promotions. Not a drift finding. ## Dimensions | Dimension | Letter | Intent | Verdict | Evidence (file:line) | | --- | --- | --- | --- | --- | -| csharp | - | - | N/A | no `*.csproj`/`*.slnx`/`*.cs` in tree (`git ls-files`); the image installs the .NET SDK but ships no in-repo source. `.editorconfig:55-222` retains the shared `[*.cs]`+ReSharper block as inert governance | -| nuget | - | - | N/A | no `dotnet nuget push` workflow | -| pypi | - | - | N/A | no Python project / `gh-action-pypi-publish` | -| python | - | - | N/A | no `pyproject.toml`/`setup.py` | -| console | - | - | N/A | no executable build task | -| docker | pass | pass | pass | multi-arch `linux/amd64,linux/arm64` (`build-docker-task.yml:54`); registry layer cache `buildcache-` (never `type=gha`) `:81-84` (`cache-from` reads both branches, `cache-to` writes only-branch + only-on-push); trimmed `Docker/README.md` published via `peter-evans/dockerhub-description`, main-only (`publish-docker-readme-task.yml:27-34`); image always re-pushes on `inputs.push` (`dockerhub && !smoke`) independent of the release-create skip (`build-release-task.yml:64,118`); plain docker repo tags off `:SemVer2` (`build-docker-task.yml:77`), correct - not a wrapper. Static `DOCKER_HUB_*` secret (expected for docker, not OIDC) | -| branch-model | drift | pass | drift | both branches protected (live rulesets `enforcement: active`); normalized diff of committed `repo-config/ruleset-{develop,main}.json` vs live matches on rules/conditions **except** the committed files omit `bypass_actors` (live carries `RepositoryRole 5 always`) and `required_reviewers: []` inside the `pull_request` params. Required-check `context` `Check pull request workflow status job` (`ruleset-main.json:32`) matches the repo's aggregator `name:` (`test-pull-request.yml:48`) - fleet canonical, not drift. Off-baseline filenames - see Drift | -| repo-setup | pass | pass | pass | actions **and** dependabot stores both hold `DOCKER_HUB_USERNAME`, `DOCKER_HUB_ACCESS_TOKEN` (docker-hub) and `CODEGEN_APP_CLIENT_ID`, `CODEGEN_APP_PRIVATE_KEY` (merge-bot App, `merge-bot-pull-request.yml:42-43`); no forbidden `NUGET_API_KEY`/`CODEGEN_APP_ID`; no stale `DOCKER_HUB_PASSWORD` (cleaner than the ESPHome/PlexCleaner stale-secret cases) | -| linter-parity | pass | pass | pass | one `.markdownlint-cli2.jsonc` + `cspell.json` drive editor + CLI + CI (`validate-task.yml:29-45`); CI runs markdownlint `:29-32`, cspell `:35-41`, actionlint `:44-45`; no C#/Python configs needed (docker-only) | -| recurring-violations | drift | pass | drift | comments concise; docs ASCII-clean (em-dash/smart-quote grep -> none); `cspell.json:3` `"language": "en-US"`. **Letter miss (eol):** `.editorconfig` lacks the global `[*] end_of_line = crlf` default (`:17-22`) **and** `build-docker-task.yml` is committed with **mixed** endings (4 LF lines against its own `[*.{yml,yaml}] crlf` rule) plus a trailing space after a Dockerfile line-continuation. See Drift #1/#2/#3 | -| readme-structure | drift | pass | drift | heavily reshaped from `spec/readme-structure.md`: `## License` is the **first** section (`README.md:6`, canonical last), no `## Build and Distribution` parent, no `## Table of Contents`, no `Releases`/`Use Cases`/`Questions or Issues` sections, headings are flat `## Build Status`/`## Container Images`/`## Release History`/`## Usage` (`:10,16,31,38`), all links are **inline** (not reference-style). Distribution/status/tags/usage content present but non-canonical. `Docker/README.md` is the intentionally-trimmed Hub overview, not measured against the project-README spec | -| workflow (WORKFLOW.md 5A/5B) | drift | pass | drift | all applicable D-guarantees hold by **outcome**; divergences are structural (see 5A/5B): single-branch-per-run publisher, no `changes` paths-filter, NBGV without `IGNORE_GITHUB_REF`, dispatch guard skips instead of failing fast, one-directional embedded release gate, bespoke release task attaching repo files directly without `expect_release_assets` | - -## WORKFLOW.md 5A Static Audit (applicable D-guarantees) - -- **D1.1 / D1.4 (paths-filter):** DRIFT - no `changes`/`dorny/paths-filter` job; `validate` and `smoke-build` run on **every** push (`test-pull-request.yml:25-42`, deliberate per header `:1-10`). Over-builds; with a single always-built target the "changed target slips unbuilt" failure cannot occur. -- **D1.2 (validation always runs):** PASS - `validate` (the lint gate, this docker-only repo's replacement for `unit-test`) runs unconditionally `if: !github.event.deleted` (`test-pull-request.yml:25-28`); the aggregator `needs:` it `:50`. -- **D1.3 (smoke uploads/pushes nothing):** PASS - the smoke caller passes `github: false`, `dockerhub: false`, `smoke: true` (`test-pull-request.yml:38-42`); the Docker push is gated `inputs.dockerhub && !inputs.smoke` (`build-release-task.yml:64`), github-release `inputs.github && !inputs.smoke` `:69`. No `upload-artifact` exists (Docker pushes to the registry; the release attaches repo files directly). -- **D1.5 (one aggregator):** PASS - `check-workflow-status`, `needs: [validate, smoke-build]`, `always() && !github.event.deleted`, fails on any non-`success` (`test-pull-request.yml:47-63`). Name is the ruleset-bound context `:48`. -- **D2.1 / D2.2 (validate-at-entry):** DRIFT (letter) / PASS (intent) - the release gate is the `Verify public release version step` **inside** github-release (`build-release-task.yml:83-93`), not an upfront entry job; it checks **one direction only** (main-not-prerelease), is `inputs.branch == 'main'`-guarded, and only fires inside the `!smoke` github-release. Safe because `version.json:4-6` makes `main` the sole public ref and the publisher builds one branch per run. -- **D2.3 (dispatch guard):** DRIFT - the publish job `if: github.ref_name == 'main' || github.ref_name == 'develop'` (`publish-release.yml:33`) **silently skips** a dispatch from any other ref rather than failing fast with `::error::`. -- **D2.4 (paired/XOR inputs):** N/A - the docker-readme task takes only `branch` and pushes a single `repository:` (`publish-docker-readme-task.yml:5-10,33`); no `repositories` XOR `manifest` combination to validate. -- **D3.1 (version from checked-out branch):** DRIFT (letter) / PASS (intent) - NBGV runs once in `get-version` on `inputs.ref` (`get-version-task.yml:47-57`); **no** `IGNORE_GITHUB_REF=true`. Correct because the publisher builds one branch per run with `github.ref` aligned; a future both-branch matrix would misclassify. -- **D3.2 (default = public, others = prerelease):** PASS - `version.json:4-6` `publicReleaseRefSpec ^refs/heads/main$`; gate literal `inputs.branch == 'main'` `build-release-task.yml:84`; `prerelease: inputs.branch != 'main'` `:124`; image moving tag `main => latest`, else `develop` `build-docker-task.yml:76`. -- **D3.3 (floor + git height):** PASS - `version.json:3` `version "1.1"`; NBGV appends the git height. Retained though the repo has no compiled code (owns the release tag/`GitCommitId`). -- **D3.4 (registry version per classification):** PASS - every published image carries the `:SemVer2` tag (`build-docker-task.yml:77`) plus the moving `latest`/`develop` `:76`. -- **D3.5 (wrapper external version):** N/A - **plain docker repo**, not an upstream wrapper: no `upstream-version.json`, no tracker; the leaf correctly tags off `SemVer2`. The base image `lscr.io/linuxserver/code-server:latest` (`Dockerfile:26`) is `:latest`, refreshed by the weekly rebuild, not a committed pin. -- **D4.1 (two-phase / both branches):** DRIFT - two-phase holds (merges never publish; the publisher runs only on `schedule` + `workflow_dispatch`, no push trigger, `publish-release.yml:12-16`), but it builds **only** the trigger branch `:39-40`, not both via a matrix. The weekly schedule rebuilds `main` only; `develop` only via manual dispatch. Outcomes correct; structural divergence. -- **D4.2 (tag the built commit):** PASS - `target_commitish: needs.get-version.outputs.GitCommitId` `build-release-task.yml:123`; github-release checks out the same commit `:79`. -- **D4.3 (release contents):** DRIFT (letter) / PASS (intent) - tag + `generate_release_notes` + `LICENSE` + `README.md` with `fail_on_unmatched_files: true` (`build-release-task.yml:121-128`); `prerelease = branch != main` `:124`. No `expect_release_assets` input - the bespoke release task attaches the two repo files directly (both exist, so the gate passes) rather than the template's `expect_release_assets: false` + `release-asset-*` mechanism. Equivalent tag+files outcome; forks the mechanism (differs from ESPHome, which omitted `fail_on_unmatched_files`). -- **D4.4 (no-op republish):** PASS - release-create gated `exists == false || workflow_dispatch` `build-release-task.yml:118`; the existence check `:95-112` skips a duplicate on a weekly re-run; Docker still re-pushes within the same run. -- **D5 (cleanup):** N/A - no `upload-artifact` / cross-job transfer artifact anywhere (Docker pushes to the registry; the release attaches `LICENSE`/`README.md`, not produced assets). -- **D6.1 / D6.2 / D6.3 (seam):** PASS (mostly N/A) - no `release-asset-*` artifacts, so no `pattern:`/`artifact-ids:` handoff to police; branch-derived config/tags key off `inputs.branch` (`build-docker-task.yml:76-77`, `build-release-task.yml:84,124`), never `github.ref_name`. -- **D7.1 / D7.2 (concurrency / permissions):** PASS - publisher group `${{ github.workflow }}` ref-independent + `cancel-in-progress: false` (`publish-release.yml:20-22`); the publish caller grants `contents: write` at the one entry point `:36-37`, docker-readme `contents: read`; the merge-bot jobs declare least-privilege `permissions:`; Docker uses the static secret (no OIDC). -- **D7.3 / D7.4 (booleans / optional-dep chaining):** PASS - `build-docker` uses `!cancelled() && get-version == 'success' && (validate == 'success' || 'skipped')` `build-release-task.yml:54`; booleans are `workflow_call`-only here. -- **D8.1 (merge-bot):** PASS - auto-merge on `opened`/`reopened` (`merge-bot-pull-request.yml:28-31`), method by base ref (`develop => --squash`, `main => --merge`) `:48-56`; disable on maintainer `synchronize` `:66-70`; concurrency keyed on the PR number `:17-19`; App token so the merge fires downstream workflows `:38-43`. -- **D8.2 (Dependabot):** PASS - `github-actions` on both `main` and `develop`, daily, grouped (`dependabot.yml:6-27`). -- **D8.3 (upstream tracker):** N/A - not a wrapper. -- **D9.1 (SHA-pinning):** PASS - all actions SHA-pinned with version comments; `dotnet/nbgv@master` is the sanctioned lagging-tag exception (`get-version-task.yml:53-57`). -- **D9.4 (docker cache):** PASS - registry `buildcache-`, `cache-to` writes only the built branch and only on push, `cache-from` reads both (`build-docker-task.yml:81-84`). -- **D9.5 (line endings):** DRIFT - see Drift #1 (`build-docker-task.yml` committed with mixed endings against `.editorconfig`). -- **NuGet / PyPI / console 5A addenda:** N/A. - -## WORKFLOW.md 5B Trace (applicable scenarios) - -- **S1** (PR touches the Docker target): `validate` (lint) + `smoke-build` (amd64-only, no push) run; no push/upload; github-release skipped (smoke); aggregator success; version prerelease. PASS. -- **S2 / S3** (docs-only / workflow-only PR): `smoke-build` **runs** (no paths-filter) instead of skipping; aggregator success - safe but over-builds. DRIFT. -- **S4** (PR base = main): smoke prerelease; the main-only verify step is inside the `!smoke` github-release so it does not fire; promotion not blocked. PASS. -- **S5 / S6** (push, opt-in un/set): N/A - the publisher has **no** push trigger (`publish-release.yml:12-16`), so no push ever publishes (stronger than the opt-in-variable model). -- **S7** (scheduled/dispatched publish): builds **only** the trigger branch. Schedule -> `main` -> stable + `latest` + `:SemVer2`, Docker Hub overview refreshed; dispatch from `develop` -> prerelease + `develop` tag, readme skipped. DRIFT (single-branch); outcomes correct. -- **S8** (dispatch from a non-publishable ref): publish job **skipped** (`publish-release.yml:33`; template fails fast). DRIFT. -- **S9** (re-run, version unchanged): release-create skipped (tag exists, non-dispatch); Docker still re-pushes; no duplicate release. PASS. -- **S10** (branch/version disagree): the main-only verify step fails loud if `main` carries a prerelease suffix (`build-release-task.yml:90-93`). PASS. -- **S11** (wrapper bump): N/A - not a wrapper. +| csharp | - | - | N/A | no `*.csproj`, `*.slnx`, or `*.cs` in the tree; the image installs the .NET SDKs and ships no in-repo source | +| nuget | - | - | N/A | `enable_nuget: false` (`publish-release.yml`, publish job `with:`) | +| pypi | - | - | N/A | no Python project; `enable_pypi: false` | +| python | - | - | N/A | no `pyproject.toml` or `setup.py` | +| dotnet-publish | - | - | N/A | `enable_dotnet_publish: false` in both callers | +| hugo | - | - | N/A | no site | +| docker | pass | pass | operational | the image is built by the hub's `build-release-task.yml` with `enable_docker: true` and `docker_image: ptr727/vscode-server-dotnetcore` (`publish-release.yml:41-62`); the Hub overview is published by the hub's `publish-docker-readme-task.yml` (`publish-release.yml:66`), main-only per the job comment, and no local copy of either task remains (`.github/workflows/` holds three files). Static `DOCKER_HUB_*` secrets, expected for docker | +| branch-model | pass | pass | operational | rulesets `develop` and `main` both `enforcement: active` (`gh api repos/ptr727/VSCode-Server-DotNetCore/rulesets`); the required context `Check pull request workflow status job` matches the aggregator `name:` (`test-pull-request.yml`); the stale `repo-config/ruleset-*.json` copies are gone | +| carried-scope | pass | pass | operational | the `spec/audit.py` run reports no `scope` finding | +| repo-setup | pass | pass | operational | the actions and dependabot secret stores both hold `DOCKER_HUB_USERNAME`, `DOCKER_HUB_ACCESS_TOKEN`, `CODEGEN_APP_CLIENT_ID`, and `CODEGEN_APP_PRIVATE_KEY`; no forbidden `NUGET_API_KEY` or `CODEGEN_APP_ID` | +| runtime-secrets | pass | pass | operational | every secret the callers map (`publish-release.yml:47-48,69-70`, `test-pull-request.yml` smoke job) exists in the actions store | +| verbatim-tree | drift | pass | drift | the carried instruction files and skills tree match a past hub revision, not the current canonical (`spec/audit.py`: `verbatim` and `tree` findings for `GOVERNANCE.md`, `.markdownlint-cli2.jsonc`, and 17 `.github/skills/` files), because the hub advanced after the 2.0.972 resync. Re-vendor from hub `main` | +| linter-parity | pass | pass | operational | one `.markdownlint-cli2.jsonc` and `cspell.json` drive editor and CI, and the hub's `validate-task.yml` runs in both `test-pull-request.yml` and `publish-release.yml:33` | +| recurring-violations | pass | pass | operational | `.editorconfig:21` sets the global `end_of_line = lf` default; no committed rulesets or mixed-ending workflow remain; `Docker/Dockerfile` is the path the hub Docker core expects | +| readme-structure | pass | pass | operational | `README.md` carries `## Build and Distribution` (`:7`), `## Table of Contents` (`:35`), `## Installation`, `## Usage`, `## Questions or Issues`, `## 3rd Party Tools`, and `## License` last (`:90`) | +| workflow (WORKFLOW.md 5A/5B) | pass | pass | operational | the three workflows are thin callers pinned to hub 2.0.1004 (`098016c8`): `test-pull-request.yml` calls `validate-task.yml` and `build-release-task.yml` with `smoke: true`, `github: false`, `dockerhub: false`, and an always-run aggregator; `publish-release.yml` calls `publish-plan-task.yml`, `validate-task.yml`, `build-release-task.yml`, and `publish-docker-readme-task.yml`, with the ref-keyed concurrency group (`:10-11`) and a weekly schedule (`:8`); `merge-bot-pull-request.yml` calls the hub merge-bot task. The five retired task workflows and the bespoke release task are gone | ## Defects (most severe first) -None. No applicable check fails both letter and intent. +None. The `spec/audit.py` run reports 0 defect, letter, or error findings. ## Drift Findings -1. **`build-docker-task.yml` is committed with mixed line endings, violating the repo's own `.editorconfig` CRLF rule.** 82 of 86 lines are CRLF but 4 are LF-only - lines `52`, `57`, `64`, `70`, which are exactly the `uses: @ # vX` lines Dependabot rewrites - while `.editorconfig:35-37` mandates `[*.{yml,yaml}] end_of_line = crlf` and every other workflow YAML is pure CRLF (`git ls-files --eol` -> `i/mixed` for this file, `i/crlf` for the rest). Nothing caught the split because `.gitattributes:6` uses `* -text` (no renormalization) and `.editorconfig` carries no global `[*] end_of_line` default, so an automated tool rewriting individual lines with LF leaves the file mixed. A **concrete** `recurring.eol` violation, and a sharper form than ESPHome's whole-file-LF case: here the automated `uses:` edits landed LF inside an otherwise-CRLF file. No runtime impact (Actions parses either), but a genuine hygiene miss and diff-churn risk. -2. **`.editorconfig` lacks the canonical global line-ending default.** The `[*]` block (`.editorconfig:17-22`) sets charset/indent/trim but **no** `end_of_line`; CRLF is re-declared per file-type (`:26,31,36,41,53`) with LF pins for `*.sh` and Dockerfiles (`:45,49`) - the older per-extension form the strengthened `recurring.eol` flags. Template canonical is `[*] end_of_line = crlf` + LF pins. **(Recurs with Utilities / PlexCleaner / LanguageTags / ESPHome-NonRoot - five repos now, and here the missing default enabled finding #1.)** -3. **Dockerfile line-continuation carries a trailing space.** `Dockerfile:76` ends with a backslash line-continuation followed by a trailing space (`cat -A` shows `dotnet-install.sh \ $`), which also violates `.editorconfig:22` `trim_trailing_whitespace = true` (no Dockerfile override relaxes it). BuildKit tolerates it (the image publishes), but it is a latent line-continuation hazard and a trailing-whitespace lint miss with no CI guard. -4. **Publisher builds one branch per run, not a both-branch matrix.** `publish-release.yml:12-16,39-40` publishes only the trigger branch; the weekly schedule rebuilds `main` only, `develop` only on manual dispatch. WORKFLOW.md D4.1's model schedules both via a matrix. Outcomes correct; `develop` gets no scheduled refresh. **(Recurs with PlexCleaner / ESPHome-NonRoot.)** -5. **No `changes` paths-filter; every push smoke-builds.** `test-pull-request.yml:25-42` runs `validate` + `smoke-build` on every push including docs-only and workflow-only. **(Recurs across the fleet.)** -6. **Committed rulesets omit fields the live rulesets carry.** `repo-config/ruleset-{develop,main}.json` omit top-level `bypass_actors` (live carries `RepositoryRole 5 always`) and `required_reviewers: []` inside the `pull_request` params. Enforcement intact; context matches. **(Recurs with LanguageTags / ESPHome-NonRoot.)** -7. **repo-config filenames off-baseline.** Committed as `repo-config/ruleset-{develop,main}.json`; `spec/files.json:15-16` expects `repo-config/develop.json` / `main.json`. **(Recurs with Utilities / PlexCleaner / LanguageTags / ESPHome-NonRoot.)** -8. **NBGV without `IGNORE_GITHUB_REF`; release gate one-directional and embedded.** `get-version-task.yml:47-57` runs NBGV with no `IGNORE_GITHUB_REF=true`; `build-release-task.yml:83-93` verifies only that `main` is not prerelease, inside github-release. Correct only because one branch is built per run. **(Recurs with PlexCleaner / LanguageTags / ESPHome-NonRoot.)** -9. **Dispatch guard skips instead of failing fast.** `publish-release.yml:33` silently no-ops a dispatch from a non-`main`/`develop` ref; WORKFLOW.md D2.3 wants a fail-fast `::error::`. **(Recurs across the fleet.)** -10. **Docker-only release attaches repo files without the `expect_release_assets` mechanism.** The bespoke `build-release-task.yml:117-128` lists `LICENSE`/`README.md` directly with `fail_on_unmatched_files: true` rather than the template's `expect_release_assets: false` + `release-asset-*` pattern download. Equivalent tag+files outcome; forks the mechanism (differs from ESPHome-NonRoot, which reached tag-only by omitting `fail_on_unmatched_files`). -11. **README reshaped from the canonical structure.** `## License` is the first section (`README.md:6`); no `## Build and Distribution` parent, no `## Table of Contents`, no `Releases`/`Use Cases`/`Questions or Issues`; headings are flat `##` siblings; all links inline, not reference-style. Content complete; shape non-canonical - more minimal than the other docker repos. -12. **`HISTORY.md` overstates the publish model.** `HISTORY.md:8` says the weekly run "publishes both `main` ... and `develop`", but the schedule is `main`-only (`publish-release.yml:12-16`) and `develop` publishes only via manual dispatch. Minor doc/behavior mismatch. -13. **`develop` diverged from `main`** (ahead 1, behind 19). See Develop Drift. +- Carried content trails the hub: `GOVERNANCE.md` (four sections), `CODESTYLE.md`, `WORKFLOW.md`, `.github/copilot-instructions.md`, `.editorconfig`, `.editorconfig-checker.json`, `.gitattributes`, `.markdownlint-cli2.jsonc`, `cspell.json`, `version.json`, and 17 files under `.github/skills/` match a past hub revision or predate a later hub change. The resync landed at hub 2.0.972 and the hub has moved since. The next resync closes it, and it is that repository's work. +- The earlier report's structural findings (single-branch publisher, no paths-filter, mixed line endings, off-baseline `repo-config/` names, reshaped README, bespoke release task) are resolved by the resync and no longer apply. ## Proposed Registry / Spec Updates -- Registry `VSCode-Server-DotNetCore` types `["docker"]`, publish `docker` via `static-secret`, status `cataloged` are accurate; **no** upstream-wrapper type applies (own `Dockerfile`, no `upstream-version.json`). Keep `version.json` + NBGV. Consider advancing `status` once the structural workflow drifts and EOL hygiene are addressed. -- **Spec signal (strongest EOL case yet).** The missing global `[*] end_of_line = crlf` default now recurs across five repos, and here it produced a **mixed-ending** file (four automated `uses:` lines committed LF inside an otherwise-CRLF workflow) because `.gitattributes: * -text` does not renormalize. Strengthens the case for a machine check that asserts (a) a global `[*] end_of_line` default exists and (b) tracked files' committed endings match `.editorconfig` - a **per-line** check would catch this mixed case a whole-file check would miss. -- **Spec gap - merge-bot App secrets.** As with PlexCleaner / ESPHome-NonRoot, `spec/secrets.json` models `CODEGEN_APP_CLIENT_ID`/`CODEGEN_APP_PRIVATE_KEY` only under `codegen-app`, but here they are required by the **merge-bot** on a repo with no codegen. Model a `merge-bot`/`app-signing` mechanism requiring the App secrets. -- **Spec gap - docker-only tag+files release.** This repo reaches a no-`release-asset` release by hand-listing `LICENSE`/`README.md` with `fail_on_unmatched_files: true`, a third distinct shape (vs the template's `expect_release_assets: false` and ESPHome's omit-`fail_on_unmatched`). If docker-only repos keep hand-rolling the release task, the spec should bless one canonical no-asset form. -- **Recurring cross-fleet drifts** (off-baseline `repo-config/ruleset-*.json` filenames, committed rulesets omitting `bypass_actors`/`required_reviewers`, no `changes` paths-filter, skip-not-fail dispatch guard, single-branch publisher, NBGV without `IGNORE_GITHUB_REF`) appear here too. +- The `driftNotes` entry "Separate publish-docker-readme-task for the Hub overview." is stale, since the repository calls the hub's task and keeps no local copy. Deleted in the same change as this report. diff --git a/reports/workflow-reuse.md b/reports/workflow-reuse.md index 6759cd422..7235bf5d2 100644 --- a/reports/workflow-reuse.md +++ b/reports/workflow-reuse.md @@ -1,12 +1,12 @@ # Fleet workflow reuse report -Generated by `python3 spec/workflow_reuse.py --report` at hub `5ce0374` - do not hand-edit. Each row reads a repo's ground-truth branch at generation time and compares it against the hub canonical of the same name after line-ending, action-pin, and job-needs normalization, per [`spec/fidelity-model.md`][fidelity-model] "Normalization". Git dates this file. The target model and the migration phases are in [`docs/reusable-workflows.md`][reusable-workflows]. +Generated by `python3 spec/workflow_reuse.py --report` at hub `ddaeefb4` - do not hand-edit. Each row reads a repo's ground-truth branch at generation time and compares it against the hub canonical of the same name after line-ending, action-pin, and job-needs normalization, per [`spec/fidelity-model.md`][fidelity-model] "Normalization". Git dates this file. The target model and the migration phases are in [`docs/reusable-workflows.md`][reusable-workflows]. ## Fleet Total -- **101 workflow files, 9,592 lines** across 20 downstream repos, 92 of them named for a hub canonical. No workflow at all in EspDinIoT. -- **3,513 lines (37%) are byte-identical to a hub canonical** after normalization, which is the confirmed duplication. The rest is mostly a per-repo edit of the same canonical rather than independent code. -- **Files reaching a hub reusable workflow or composite action through a pinned `uses:`: 19.** That is the state every carried copy converges to, so this number rises and the two above fall as the migration lands. +- **69 workflow files, 5,382 lines** across 20 downstream repos, 64 of them named for a hub canonical. No workflow at all in EspDinIoT. +- **2,133 lines (40%) are byte-identical to a hub canonical** after normalization, which is the confirmed duplication. The rest is mostly a per-repo edit of the same canonical rather than independent code. +- **Files reaching a hub reusable workflow or composite action through a pinned `uses:`: 51.** That is the state every carried copy converges to, so this number rises and the two above fall as the migration lands. ## Per Workflow @@ -14,137 +14,108 @@ Downstream copies of each hub canonical. A variant is a cluster of copies each a | File | Copies | Lines | Identical to hub | Variants | Callers | | --- | --- | --- | --- | --- | --- | -| `build-release-task.yml` | 9 | 1,709 | 827 | 6 | 0 | -| `test-pull-request.yml` | 20 | 1,615 | 501 | 14 | 6 | -| `merge-bot-pull-request.yml` | 17 | 1,401 | 276 | 7 | 6 | -| `publish-release.yml` | 17 | 1,335 | 506 | 15 | 6 | -| `validate-task.yml` | 9 | 891 | 323 | 7 | 0 | -| `build-docker-task.yml` | 4 | 512 | 266 | 4 | 0 | -| `get-version-task.yml` | 7 | 439 | 342 | 4 | 0 | -| `publish-plan-task.yml` | 3 | 252 | 198 | 1 | 0 | -| `run-codegen-pull-request-task.yml` | 2 | 161 | 127 | 1 | 0 | -| `check-upstream-version-task.yml` | 1 | 133 | 93 | 1 | 0 | -| `run-periodic-codegen-pull-request.yml` | 2 | 48 | 29 | 2 | 0 | -| `publish-docker-readme-task.yml` | 1 | 34 | 25 | 1 | 0 | +| `test-pull-request.yml` | 20 | 1,720 | 594 | 15 | 16 | +| `publish-release.yml` | 17 | 1,566 | 687 | 14 | 16 | +| `merge-bot-pull-request.yml` | 17 | 565 | 348 | 3 | 16 | +| `validate-task.yml` | 3 | 352 | 102 | 3 | 0 | +| `build-release-task.yml` | 1 | 140 | 89 | 1 | 0 | +| `check-upstream-version-task.yml` | 1 | 132 | 94 | 1 | 0 | +| `build-docker-task.yml` | 1 | 124 | 61 | 1 | 0 | +| `publish-plan-task.yml` | 1 | 84 | 66 | 1 | 0 | +| `get-version-task.yml` | 1 | 56 | 49 | 1 | 0 | +| `run-periodic-codegen-pull-request.yml` | 2 | 52 | 43 | 2 | 2 | ### Variant Members Each variant names the repos whose copies cluster together, so a hub task's inputs and hooks can be designed against the shapes that exist rather than against the canonical alone. -- `build-release-task.yml` - - 2: ESPHome-NonRoot, VSCode-Server-DotNetCore - - 1: KiCadLibrary - - 3: LanguageTags, MediaTools, Utilities - - 1: PlexCleaner - - 1: aiopurpleair - - 1: homeassistant-purpleair - `test-pull-request.yml` - 1: AudioCleaner - 1: Blog - 2: DevKitCIoT, HolidayLights - 1: ESPHome-Config - 1: ESPHome-NonRoot - - 2: Financial-Modeling, HomeAssistant-Config + - 3: Financial-Modeling, HomeAssistant-Config, Vantage-Config - 1: HomeAutomation-Config - 1: KiCadLibrary - - 4: LanguageTags, MediaTools, Utilities, aiopurpleair + - 3: LanguageTags, MediaTools, Utilities - 1: NxWitness - 1: PhotoCleaner - - 2: PlexCleaner, VSCode-Server-DotNetCore - - 1: Vantage-Config - - 1: homeassistant-purpleair -- `merge-bot-pull-request.yml` - - 6: Blog, ESPHome-Config, Financial-Modeling, HomeAssistant-Config, HomeAutomation-Config, PhotoCleaner - - 3: ESPHome-NonRoot, NxWitness, homeassistant-purpleair - - 1: KiCadLibrary - - 1: LanguageTags - - 2: MediaTools, aiopurpleair - - 3: PlexCleaner, Utilities, Vantage-Config + - 1: PlexCleaner - 1: VSCode-Server-DotNetCore + - 1: aiopurpleair + - 1: homeassistant-purpleair - `publish-release.yml` - 1: Blog - 1: ESPHome-Config - 1: ESPHome-NonRoot - 1: Financial-Modeling - - 2: HomeAssistant-Config, HomeAutomation-Config + - 2: HomeAssistant-Config, Vantage-Config + - 1: HomeAutomation-Config - 1: KiCadLibrary - - 2: LanguageTags, MediaTools + - 3: LanguageTags, MediaTools, Utilities - 1: NxWitness - 1: PhotoCleaner - 1: PlexCleaner - - 1: Utilities - 1: VSCode-Server-DotNetCore - - 1: Vantage-Config - 1: aiopurpleair - 1: homeassistant-purpleair +- `merge-bot-pull-request.yml` + - 15: Blog, ESPHome-Config, Financial-Modeling, HomeAssistant-Config, HomeAutomation-Config, KiCadLibrary, LanguageTags, MediaTools, NxWitness, PlexCleaner, Utilities, VSCode-Server-DotNetCore, Vantage-Config, aiopurpleair, homeassistant-purpleair + - 1: ESPHome-NonRoot + - 1: PhotoCleaner - `validate-task.yml` - - 3: AudioCleaner, MediaTools, Utilities + - 1: AudioCleaner - 1: ESPHome-NonRoot - - 1: LanguageTags - - 1: NxWitness - 1: PlexCleaner - - 1: VSCode-Server-DotNetCore - - 1: aiopurpleair +- `build-release-task.yml` + - 1: ESPHome-NonRoot +- `check-upstream-version-task.yml` + - 1: ESPHome-NonRoot - `build-docker-task.yml` - 1: ESPHome-NonRoot - - 1: NxWitness - - 1: PlexCleaner - - 1: VSCode-Server-DotNetCore -- `get-version-task.yml` - - 4: ESPHome-NonRoot, NxWitness, PlexCleaner, VSCode-Server-DotNetCore - - 1: KiCadLibrary - - 1: aiopurpleair - - 1: homeassistant-purpleair - `publish-plan-task.yml` - - 3: ESPHome-NonRoot, NxWitness, Utilities -- `run-codegen-pull-request-task.yml` - - 2: LanguageTags, NxWitness -- `check-upstream-version-task.yml` + - 1: ESPHome-NonRoot +- `get-version-task.yml` - 1: ESPHome-NonRoot - `run-periodic-codegen-pull-request.yml` - 1: LanguageTags - 1: NxWitness -- `publish-docker-readme-task.yml` - - 1: VSCode-Server-DotNetCore ## Per Repo | Repo | Files | Lines | Identical to hub | Callers | Repo-local files | | --- | --- | --- | --- | --- | --- | | AudioCleaner | 2 | 134 | 57 | 0 | - | -| Blog | 4 | 220 | 97 | 4 | `deploy-site.yml` | -| DevKitCIoT | 1 | 58 | 25 | 0 | - | -| ESPHome-Config | 3 | 327 | 113 | 3 | - | -| ESPHome-NonRoot | 11 | 1,154 | 457 | 0 | `check-upstream-dependency.yml`, `check-upstream-version.yml` | -| Financial-Modeling | 3 | 137 | 77 | 3 | - | -| HolidayLights | 1 | 53 | 25 | 0 | - | -| HomeAssistant-Config | 3 | 124 | 98 | 3 | - | -| HomeAutomation-Config | 4 | 164 | 99 | 3 | `test-homelab-runner.yml` | -| KiCadLibrary | 6 | 772 | 201 | 0 | `build-datebadge-task.yml` | -| LanguageTags | 7 | 724 | 280 | 0 | - | -| MediaTools | 5 | 530 | 188 | 0 | - | -| NxWitness | 10 | 1,102 | 375 | 0 | `build-base-images-task.yml` | -| PhotoCleaner | 3 | 203 | 85 | 3 | - | -| PlexCleaner | 8 | 805 | 362 | 0 | `build-executable-task.yml` | -| Utilities | 6 | 621 | 266 | 0 | - | -| VSCode-Server-DotNetCore | 8 | 563 | 294 | 0 | - | -| Vantage-Config | 3 | 229 | 59 | 0 | - | -| aiopurpleair | 6 | 611 | 220 | 0 | - | -| homeassistant-purpleair | 7 | 1,061 | 135 | 0 | `check-ha-version.yml`, `test-release-task.yml` | +| Blog | 4 | 227 | 99 | 4 | `deploy-site.yml` | +| DevKitCIoT | 1 | 58 | 33 | 0 | - | +| ESPHome-Config | 3 | 277 | 122 | 3 | - | +| ESPHome-NonRoot | 11 | 1,153 | 461 | 0 | `check-upstream-dependency.yml`, `check-upstream-version.yml` | +| Financial-Modeling | 3 | 143 | 107 | 3 | - | +| HolidayLights | 1 | 53 | 33 | 0 | - | +| HomeAssistant-Config | 3 | 123 | 94 | 3 | - | +| HomeAutomation-Config | 4 | 196 | 100 | 3 | `test-homelab-runner.yml` | +| KiCadLibrary | 3 | 205 | 89 | 3 | - | +| LanguageTags | 4 | 302 | 106 | 4 | - | +| MediaTools | 3 | 268 | 87 | 3 | - | +| NxWitness | 4 | 330 | 104 | 4 | - | +| PhotoCleaner | 3 | 230 | 90 | 3 | - | +| PlexCleaner | 4 | 335 | 120 | 3 | - | +| Utilities | 3 | 263 | 85 | 3 | - | +| VSCode-Server-DotNetCore | 3 | 169 | 86 | 3 | - | +| Vantage-Config | 3 | 122 | 92 | 3 | - | +| aiopurpleair | 3 | 250 | 87 | 3 | - | +| homeassistant-purpleair | 4 | 544 | 81 | 3 | `check-ha-version.yml` | ## Repo-Local Workflows A workflow no hub canonical names. Each is either genuinely repo-specific, and stays, or a candidate for a hub task with a hook, and the design doc lists which. -- **Blog** `deploy-site.yml` (70 lines) +- **Blog** `deploy-site.yml` (73 lines) - **ESPHome-NonRoot** `check-upstream-dependency.yml` (111 lines) - **ESPHome-NonRoot** `check-upstream-version.yml` (41 lines) -- **HomeAutomation-Config** `test-homelab-runner.yml` (43 lines) -- **KiCadLibrary** `build-datebadge-task.yml` (37 lines) -- **NxWitness** `build-base-images-task.yml` (89 lines) -- **PlexCleaner** `build-executable-task.yml` (107 lines) -- **homeassistant-purpleair** `check-ha-version.yml` (316 lines) -- **homeassistant-purpleair** `test-release-task.yml` (248 lines) +- **HomeAutomation-Config** `test-homelab-runner.yml` (51 lines) +- **homeassistant-purpleair** `check-ha-version.yml` (315 lines) From 962d3a4b76d69a7cfa989eb143f513d27f9bdd77 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Thu, 15 Oct 2026 23:46:34 -0700 Subject: [PATCH 2/5] Correct the VSCode-Server-DotNetCore Audit Citations and the Merge-Bot Item Co-Authored-By: Claude Sonnet 5.5 --- docs/reusable-workflows.md | 2 +- reports/vscode-server-dotnetcore/audit.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/reusable-workflows.md b/docs/reusable-workflows.md index 80d3ac8e3..075fa101b 100644 --- a/docs/reusable-workflows.md +++ b/docs/reusable-workflows.md @@ -136,7 +136,7 @@ Adoptable since `2.0.338`. Each repo replaces the whole of its `.github/workflow - [x] LanguageTags (`delete-branch: true`): adopted on `develop` in ptr727/LanguageTags#336 at `e44eb09`, merged 2026-09-02 and carried on `main`, its ground-truth branch, where `merge-bot-pull-request.yml` calls `merge-bot-task.yml` by pin. - [x] aiopurpleair (`delete-branch: true`): adopted on `develop` in ptr727/aiopurpleair#103 at `3b69dc3`, merged 2026-09-09 and carried on `main`, its ground-truth branch, where `merge-bot-pull-request.yml` calls `merge-bot-task.yml` by pin. - [x] MediaTools (`delete-branch: true`): adopted on `develop` in ptr727/MediaTools#32 at `7ed693e`, merged 2026-09-26 and carried on `main`, its ground-truth branch, where `merge-bot-pull-request.yml` calls `merge-bot-task.yml` by pin. -- [x] VSCode-Server-DotNetCore (`delete-branch: true`): adopted on `develop` in ptr727/VSCode-Server-DotNetCore#129 at `ca46db7`, merged 2026-09-26 and carried on `main`, its ground-truth branch, where `merge-bot-pull-request.yml` calls `merge-bot-task.yml` by pin. +- [x] VSCode-Server-DotNetCore: adopted on `develop` in ptr727/VSCode-Server-DotNetCore#129 at `ca46db7`, merged 2026-09-26 and carried on `main`, its ground-truth branch, where `merge-bot-pull-request.yml` calls `merge-bot-task.yml` by pin. - [x] Blog: adopted on `develop` in ptr727/Blog#97 at `71bcb64`, merged 2026-08-23 and carried on `main`, its ground-truth branch, where `merge-bot-pull-request.yml` calls `merge-bot-task.yml` by pin. - [x] ESPHome-Config: adopted on `develop` in ptr727/ESPHome-Config#100 at `a21dfd7`, merged 2026-08-19 and carried on `main`, its ground-truth branch, where `merge-bot-pull-request.yml` calls `merge-bot-task.yml` by pin. - [x] HomeAssistant-Config: adopted on `develop` in ptr727/HomeAssistant-Config#33 at `f980637`, merged 2026-08-20 and carried on `main`, its ground-truth branch, where `merge-bot-pull-request.yml` calls `merge-bot-task.yml` by pin. diff --git a/reports/vscode-server-dotnetcore/audit.md b/reports/vscode-server-dotnetcore/audit.md index 6753a719f..ef7a9f72a 100644 --- a/reports/vscode-server-dotnetcore/audit.md +++ b/reports/vscode-server-dotnetcore/audit.md @@ -5,7 +5,7 @@ - **Verdict:** operational - **Date:** 2026-10-16 -Basis: `python3 spec/audit.py VSCode-Server-DotNetCore` run 2026-10-16T06:40:34Z at hub `ddaeefb4`, reporting 0 defect, letter, or error findings, plus a read of the `main` tree. This report replaces the 2026-07-04 report, which described the repository before its resync to hub 2.0.685 (ptr727/VSCode-Server-DotNetCore#127 through #131) and its later pin bumps. +Basis: `python3 spec/audit.py VSCode-Server-DotNetCore` run 2026-10-16T06:40:34Z at hub `ddaeefb4`, reporting 0 defect, letter, or error findings, plus a read of the `main` tree. This report replaces the 2026-07-04 report, which described the repository before its resync to hub 2.0.685 (ptr727/VSCode-Server-DotNetCore#127 through #131) and the second resync to hub 2.0.972 (ptr727/VSCode-Server-DotNetCore#153). ## Develop Drift @@ -21,12 +21,12 @@ Basis: `python3 spec/audit.py VSCode-Server-DotNetCore` run 2026-10-16T06:40:34Z | python | - | - | N/A | no `pyproject.toml` or `setup.py` | | dotnet-publish | - | - | N/A | `enable_dotnet_publish: false` in both callers | | hugo | - | - | N/A | no site | -| docker | pass | pass | operational | the image is built by the hub's `build-release-task.yml` with `enable_docker: true` and `docker_image: ptr727/vscode-server-dotnetcore` (`publish-release.yml:41-62`); the Hub overview is published by the hub's `publish-docker-readme-task.yml` (`publish-release.yml:66`), main-only per the job comment, and no local copy of either task remains (`.github/workflows/` holds three files). Static `DOCKER_HUB_*` secrets, expected for docker | +| docker | pass | pass | operational | the image is built by the hub's `build-release-task.yml` with `enable_docker: true` and `docker_image: ptr727/vscode-server-dotnetcore` (`publish-release.yml:41-59`); the Hub overview is published by the hub's `publish-docker-readme-task.yml` (`publish-release.yml:66`), main-only per the job comment, and no local copy of either task remains (`.github/workflows/` holds three files). Static `DOCKER_HUB_*` secrets, expected for docker | | branch-model | pass | pass | operational | rulesets `develop` and `main` both `enforcement: active` (`gh api repos/ptr727/VSCode-Server-DotNetCore/rulesets`); the required context `Check pull request workflow status job` matches the aggregator `name:` (`test-pull-request.yml`); the stale `repo-config/ruleset-*.json` copies are gone | | carried-scope | pass | pass | operational | the `spec/audit.py` run reports no `scope` finding | | repo-setup | pass | pass | operational | the actions and dependabot secret stores both hold `DOCKER_HUB_USERNAME`, `DOCKER_HUB_ACCESS_TOKEN`, `CODEGEN_APP_CLIENT_ID`, and `CODEGEN_APP_PRIVATE_KEY`; no forbidden `NUGET_API_KEY` or `CODEGEN_APP_ID` | -| runtime-secrets | pass | pass | operational | every secret the callers map (`publish-release.yml:47-48,69-70`, `test-pull-request.yml` smoke job) exists in the actions store | -| verbatim-tree | drift | pass | drift | the carried instruction files and skills tree match a past hub revision, not the current canonical (`spec/audit.py`: `verbatim` and `tree` findings for `GOVERNANCE.md`, `.markdownlint-cli2.jsonc`, and 17 `.github/skills/` files), because the hub advanced after the 2.0.972 resync. Re-vendor from hub `main` | +| runtime-secrets | pass | pass | operational | every secret the callers map (`publish-release.yml:46-47,70-71`, `test-pull-request.yml` smoke job) exists in the actions store | +| verbatim-tree | drift | pass | drift | the carried instruction files and skills tree match a past hub revision, not the current canonical (`spec/audit.py`: `verbatim` and `tree` findings for `GOVERNANCE.md`, `.markdownlint-cli2.jsonc`, and 16 `.github/skills/` files), because the hub advanced after the 2.0.972 resync. Re-vendor from hub `main` | | linter-parity | pass | pass | operational | one `.markdownlint-cli2.jsonc` and `cspell.json` drive editor and CI, and the hub's `validate-task.yml` runs in both `test-pull-request.yml` and `publish-release.yml:33` | | recurring-violations | pass | pass | operational | `.editorconfig:21` sets the global `end_of_line = lf` default; no committed rulesets or mixed-ending workflow remain; `Docker/Dockerfile` is the path the hub Docker core expects | | readme-structure | pass | pass | operational | `README.md` carries `## Build and Distribution` (`:7`), `## Table of Contents` (`:35`), `## Installation`, `## Usage`, `## Questions or Issues`, `## 3rd Party Tools`, and `## License` last (`:90`) | @@ -38,7 +38,7 @@ None. The `spec/audit.py` run reports 0 defect, letter, or error findings. ## Drift Findings -- Carried content trails the hub: `GOVERNANCE.md` (four sections), `CODESTYLE.md`, `WORKFLOW.md`, `.github/copilot-instructions.md`, `.editorconfig`, `.editorconfig-checker.json`, `.gitattributes`, `.markdownlint-cli2.jsonc`, `cspell.json`, `version.json`, and 17 files under `.github/skills/` match a past hub revision or predate a later hub change. The resync landed at hub 2.0.972 and the hub has moved since. The next resync closes it, and it is that repository's work. +- Carried content trails the hub: `GOVERNANCE.md` (four sections), `CODESTYLE.md`, `WORKFLOW.md`, `.github/copilot-instructions.md`, `.editorconfig`, `.editorconfig-checker.json`, `.gitattributes`, `.markdownlint-cli2.jsonc`, `cspell.json`, `version.json`, and 16 files under `.github/skills/` match a past hub revision or predate a later hub change. The resync landed at hub 2.0.972 and the hub has moved since. The next resync closes it, and it is that repository's work. - The earlier report's structural findings (single-branch publisher, no paths-filter, mixed line endings, off-baseline `repo-config/` names, reshaped README, bespoke release task) are resolved by the resync and no longer apply. ## Proposed Registry / Spec Updates From 628254f3eda695fc9f4751c685bf9d3e00b382a4 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Thu, 15 Oct 2026 23:50:02 -0700 Subject: [PATCH 3/5] Count the Retired VSCode-Server-DotNetCore Task Workflows Once Co-Authored-By: Claude Sonnet 5.5 --- reports/vscode-server-dotnetcore/audit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reports/vscode-server-dotnetcore/audit.md b/reports/vscode-server-dotnetcore/audit.md index ef7a9f72a..28439cc2c 100644 --- a/reports/vscode-server-dotnetcore/audit.md +++ b/reports/vscode-server-dotnetcore/audit.md @@ -30,7 +30,7 @@ Basis: `python3 spec/audit.py VSCode-Server-DotNetCore` run 2026-10-16T06:40:34Z | linter-parity | pass | pass | operational | one `.markdownlint-cli2.jsonc` and `cspell.json` drive editor and CI, and the hub's `validate-task.yml` runs in both `test-pull-request.yml` and `publish-release.yml:33` | | recurring-violations | pass | pass | operational | `.editorconfig:21` sets the global `end_of_line = lf` default; no committed rulesets or mixed-ending workflow remain; `Docker/Dockerfile` is the path the hub Docker core expects | | readme-structure | pass | pass | operational | `README.md` carries `## Build and Distribution` (`:7`), `## Table of Contents` (`:35`), `## Installation`, `## Usage`, `## Questions or Issues`, `## 3rd Party Tools`, and `## License` last (`:90`) | -| workflow (WORKFLOW.md 5A/5B) | pass | pass | operational | the three workflows are thin callers pinned to hub 2.0.1004 (`098016c8`): `test-pull-request.yml` calls `validate-task.yml` and `build-release-task.yml` with `smoke: true`, `github: false`, `dockerhub: false`, and an always-run aggregator; `publish-release.yml` calls `publish-plan-task.yml`, `validate-task.yml`, `build-release-task.yml`, and `publish-docker-readme-task.yml`, with the ref-keyed concurrency group (`:10-11`) and a weekly schedule (`:8`); `merge-bot-pull-request.yml` calls the hub merge-bot task. The five retired task workflows and the bespoke release task are gone | +| workflow (WORKFLOW.md 5A/5B) | pass | pass | operational | the three workflows are thin callers pinned to hub 2.0.1004 (`098016c8`): `test-pull-request.yml` calls `validate-task.yml` and `build-release-task.yml` with `smoke: true`, `github: false`, `dockerhub: false`, and an always-run aggregator; `publish-release.yml` calls `publish-plan-task.yml`, `validate-task.yml`, `build-release-task.yml`, and `publish-docker-readme-task.yml`, with the ref-keyed concurrency group (`:10-11`) and a weekly schedule (`:8`); `merge-bot-pull-request.yml` calls the hub merge-bot task. The five retired task workflows, the bespoke release task among them, are gone | ## Defects (most severe first) From 3a2c1c509373c3dfd2b522258bac3b9eb065a082 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Thu, 15 Oct 2026 23:53:37 -0700 Subject: [PATCH 4/5] Reconcile the Stage 3 Carrier Wording and Cite the Audit Drift Evidence Co-Authored-By: Claude Sonnet 5.5 --- docs/reusable-workflows.md | 2 +- reports/vscode-server-dotnetcore/audit.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reusable-workflows.md b/docs/reusable-workflows.md index 075fa101b..32329193c 100644 --- a/docs/reusable-workflows.md +++ b/docs/reusable-workflows.md @@ -191,7 +191,7 @@ Hub: `get-version-task.yml` and `publish-plan-task.yml` hosted, and the downstre - [x] Hub pull request on `develop`, #759. - [x] Promoted to `main` in #774 (`0b07a59d`) and released as `2.0.352`, the first tag carrying `get-version-task.yml` and `publish-plan-task.yml`. - [ ] Catalog snippet for a caller stub, after the release: a caller of either task is a job inside a repo's own `publish-release.yml` or a future `build-release-task.yml` rather than a standalone top-level workflow, so today's honest answer is no snippet, only the `with:`/`uses:` lines in [Adopting the Pure Functions](#adopting-the-pure-functions). Revisit if an adopting repo's shape argues otherwise. -- [ ] Adoption, one checkbox per carrier added when the hub pull request merges: today `get-version-task.yml` has 8 carriers and `publish-plan-task.yml` 3, with ESPHome-NonRoot and NxWitness carrying both. +- [ ] Adoption, one checkbox per carrier added when the hub pull request merges: the carriers still holding a copy are the unticked items below, ESPHome-NonRoot and NxWitness carrying both tasks. - [ ] ESPHome-NonRoot (`get-version-task.yml` and `publish-plan-task.yml`) - [ ] NxWitness (`get-version-task.yml` and `publish-plan-task.yml`) - [ ] PhotoCleaner (`get-version-task.yml`) diff --git a/reports/vscode-server-dotnetcore/audit.md b/reports/vscode-server-dotnetcore/audit.md index 28439cc2c..81b9a48c2 100644 --- a/reports/vscode-server-dotnetcore/audit.md +++ b/reports/vscode-server-dotnetcore/audit.md @@ -38,7 +38,7 @@ None. The `spec/audit.py` run reports 0 defect, letter, or error findings. ## Drift Findings -- Carried content trails the hub: `GOVERNANCE.md` (four sections), `CODESTYLE.md`, `WORKFLOW.md`, `.github/copilot-instructions.md`, `.editorconfig`, `.editorconfig-checker.json`, `.gitattributes`, `.markdownlint-cli2.jsonc`, `cspell.json`, `version.json`, and 16 files under `.github/skills/` match a past hub revision or predate a later hub change. The resync landed at hub 2.0.972 and the hub has moved since. The next resync closes it, and it is that repository's work. +- Carried content trails the hub (evidence: the `spec/audit.py` run named under Basis, whose `verbatim`, `tree`, and `intent` lines name each file and the later hub commit; the carried `GOVERNANCE.md` sections sit at `GOVERNANCE.md:27` Repository Boundaries and Write Safety, `:174` Verification Discipline, `:248` Workflow YAML Conventions, and `:279` Editor and Tasks): `GOVERNANCE.md` (four sections), `CODESTYLE.md`, `WORKFLOW.md`, `.github/copilot-instructions.md`, `.editorconfig`, `.editorconfig-checker.json`, `.gitattributes`, `.markdownlint-cli2.jsonc`, `cspell.json`, `version.json`, and 16 files under `.github/skills/` match a past hub revision or predate a later hub change. The resync landed at hub 2.0.972 and the hub has moved since. The next resync closes it, and it is that repository's work. - The earlier report's structural findings (single-branch publisher, no paths-filter, mixed line endings, off-baseline `repo-config/` names, reshaped README, bespoke release task) are resolved by the resync and no longer apply. ## Proposed Registry / Spec Updates From e0d49d95f9dd104fb5cbfeb4e67093378f810336 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Thu, 15 Oct 2026 23:55:16 -0700 Subject: [PATCH 5/5] Drop the Stage 3 Carrier Count and Fix the Audit Evidence Wording Co-Authored-By: Claude Sonnet 5.5 --- docs/reusable-workflows.md | 2 +- reports/vscode-server-dotnetcore/audit.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reusable-workflows.md b/docs/reusable-workflows.md index 32329193c..b2b37669d 100644 --- a/docs/reusable-workflows.md +++ b/docs/reusable-workflows.md @@ -191,7 +191,7 @@ Hub: `get-version-task.yml` and `publish-plan-task.yml` hosted, and the downstre - [x] Hub pull request on `develop`, #759. - [x] Promoted to `main` in #774 (`0b07a59d`) and released as `2.0.352`, the first tag carrying `get-version-task.yml` and `publish-plan-task.yml`. - [ ] Catalog snippet for a caller stub, after the release: a caller of either task is a job inside a repo's own `publish-release.yml` or a future `build-release-task.yml` rather than a standalone top-level workflow, so today's honest answer is no snippet, only the `with:`/`uses:` lines in [Adopting the Pure Functions](#adopting-the-pure-functions). Revisit if an adopting repo's shape argues otherwise. -- [ ] Adoption, one checkbox per carrier added when the hub pull request merges: the carriers still holding a copy are the unticked items below, ESPHome-NonRoot and NxWitness carrying both tasks. +- [ ] Adoption, one checkbox per carrier added when the hub pull request merges. - [ ] ESPHome-NonRoot (`get-version-task.yml` and `publish-plan-task.yml`) - [ ] NxWitness (`get-version-task.yml` and `publish-plan-task.yml`) - [ ] PhotoCleaner (`get-version-task.yml`) diff --git a/reports/vscode-server-dotnetcore/audit.md b/reports/vscode-server-dotnetcore/audit.md index 81b9a48c2..05a023279 100644 --- a/reports/vscode-server-dotnetcore/audit.md +++ b/reports/vscode-server-dotnetcore/audit.md @@ -38,7 +38,7 @@ None. The `spec/audit.py` run reports 0 defect, letter, or error findings. ## Drift Findings -- Carried content trails the hub (evidence: the `spec/audit.py` run named under Basis, whose `verbatim`, `tree`, and `intent` lines name each file and the later hub commit; the carried `GOVERNANCE.md` sections sit at `GOVERNANCE.md:27` Repository Boundaries and Write Safety, `:174` Verification Discipline, `:248` Workflow YAML Conventions, and `:279` Editor and Tasks): `GOVERNANCE.md` (four sections), `CODESTYLE.md`, `WORKFLOW.md`, `.github/copilot-instructions.md`, `.editorconfig`, `.editorconfig-checker.json`, `.gitattributes`, `.markdownlint-cli2.jsonc`, `cspell.json`, `version.json`, and 16 files under `.github/skills/` match a past hub revision or predate a later hub change. The resync landed at hub 2.0.972 and the hub has moved since. The next resync closes it, and it is that repository's work. +- Carried content trails the hub (evidence: the `spec/audit.py` run named under Basis, whose `verbatim`, `tree`, and `intent` lines name each file, the `intent` lines also naming the later hub commit; the carried `GOVERNANCE.md` sections sit at `GOVERNANCE.md:27` Repository Boundaries and Write Safety, `:174` Verification Discipline, `:248` Workflow YAML Conventions, and `:279` Editor and Tasks): `GOVERNANCE.md` (four sections), `CODESTYLE.md`, `WORKFLOW.md`, `.github/copilot-instructions.md`, `.editorconfig`, `.editorconfig-checker.json`, `.gitattributes`, `.markdownlint-cli2.jsonc`, `cspell.json`, `version.json`, and 16 files under `.github/skills/` match a past hub revision or predate a later hub change. The resync landed at hub 2.0.972 and the hub has moved since. The next resync closes it, and it is that repository's work. - The earlier report's structural findings (single-branch publisher, no paths-filter, mixed line endings, off-baseline `repo-config/` names, reshaped README, bespoke release task) are resolved by the resync and no longer apply. ## Proposed Registry / Spec Updates