diff --git a/AGENTS.md b/AGENTS.md index b8eeb92c..65ce6196 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,7 +11,7 @@ Treat this file as authoritative for everything else; don't restate its rules el The specific rules in this file implement a few governing principles. Read these first: they are the reason the branching, release, and versioning rules are shaped the way they are, and every rule below serves one of them. - **Distribution respects the user: pull by default, push only where the channel forces it.** Docker images, GitHub Releases, and NuGet/PyPI packages are **pull** - the user decides when to consume them. A few channels are **push**: HACS surfaces a new release to every installed user as a pending update they did not go looking for, and a consumer that vendors from `main` picks up its current state. Because a release can reach users who did not ask for it, releasing is a deliberate act that marks a real functional change - never mechanical churn. This is why a **human merge never auto-publishes** - a release is a deliberate `workflow_dispatch`, or a conditional auto-release when the App merges a code-affecting Dependabot/codegen PR to `main` (Docker also refreshes on a weekly schedule) - together with the no-op republish guarantee and maintainer-gated version bumps: a needless release spends the user's attention and, on a push channel, acts on their machine. -- **Both branches stay in sync, so a promotion never needs a back-merge.** Dependabot and codegen target `develop` and `main` in parallel, so neither branch drifts and a `develop -> main` promotion stays a clean forward merge by default. That is exactly what lets the model be **signed, linear, and free of back-merges** - forward sync removes any need to merge `main` back into `develop`, which the rules forbid. If sync is ever broken (a change lands on one branch only, or normalizes a file on one side), restore it forward-only; never back-merge. See "Branching Model". (This dual-target sync and the auto-publish rules below describe `release` repos; **operational** repos - registry `workflowModel: operational` - run no bots and commit directly to `develop`. They still cut a GitHub release, but **only** by manual `workflow_dispatch` (`releaseTrigger: dispatch-only`) - never automatically. See "Branching Model".) +- **Both branches stay in sync, so a promotion never needs a back-merge.** Dependabot and codegen target `develop` and `main` in parallel, so neither branch drifts and a `develop -> main` promotion stays a clean forward merge by default. That is exactly what lets the model be **signed, linear, and free of back-merges** - forward sync removes any need to merge `main` back into `develop`, which the rules forbid. If sync is ever broken (a change lands on one branch only, or normalizes a file on one side), restore it forward-only; never back-merge. See "Branching Model". (The auto-publish rules below describe `release` repos only; **operational** repos - registry `workflowModel: operational` - commit directly to `develop`, run no codegen or auto-publish bots, and cut a GitHub release **only** by manual `workflow_dispatch` (`releaseTrigger: dispatch-only`) - never automatically. Dependabot's dual-target sync and the App-signed merge-bot run on **every** tier, operational included. See "Branching Model".) - **Two version numbers, two jobs.** The 2-digit `major.minor` in `version.json` carries human meaning - the maintainer raises it only for a functional change (feature, behavior or API change, breaking change), at their discretion - while NBGV owns the patch position and always increments with git height, so every build is uniquely versioned with no edit. Human-facing docs name the 2-digit line; the toolchain guarantees monotonic builds. See "Release Model". - **Contracts state what, not how, and favor reuse.** [`WORKFLOW.md`](./WORKFLOW.md) fixes required outcomes, not a required implementation - two repos may satisfy a guarantee with different YAML. Within that freedom, apply good engineering practice: minimize duplication and maximize reuse, which is why the pipeline splits a carried, generic orchestration layer from a repo-owned build layer. diff --git a/registry/repos.json b/registry/repos.json index 210a708d..5de3680e 100644 --- a/registry/repos.json +++ b/registry/repos.json @@ -294,7 +294,7 @@ "requiredSecrets": [], "consumerModel": "pull", "releaseTrigger": "dispatch-only", - "driftNotes": ["Vantage InFusion / Design Center controller config edited on Windows (UTF-8 CRLF .dc XML, really special XML), so lineEndings crlf.", "Recreated lean and single-platform: Design Center is freely available, so no installer archives are kept; split out of HomeAutomation-Config. Being repopulated from the Windows editing host - operational onboarding (baseline, lint CI, dispatch-only publisher, rulesets, develop/main) pending once content lands."] + "driftNotes": ["Vantage InFusion / Design Center controller config edited on Windows (UTF-8 CRLF .dc XML, really special XML), so lineEndings crlf.", "Recreated lean and single-platform: Design Center is freely available, so no installer archives are kept; split out of HomeAutomation-Config.", "Operational onboarding completed 2026-07-16 (Vantage-Config #9): baseline docs, advisory lint CI, dispatch-only publisher, repo-config operational carry (rulesets/settings applied and verified in sync), Dependabot + App merge-bot with the secret pair in both stores, adapted self-audit (AUDIT.md + spec/secrets.json)."] }, { "name": "HolidayLights", diff --git a/repo-config/README.md b/repo-config/README.md index 413c0671..658fdd07 100644 --- a/repo-config/README.md +++ b/repo-config/README.md @@ -12,7 +12,7 @@ Every fleet repo carries this directory; the hub keeps the canonical copy. Rules - **Carry only your model's `develop` variant.** A `release` repo carries `develop.json`; an `operational` repo carries `operational/develop.json` instead. `main.json` and `settings.json` are shared by both models. `configure.sh` aborts when the payload its model needs is missing rather than applying a partial configuration. - **Hub-only references stay plain text.** The hub is a private repo: never URL-link it from a downstream repo - the link 404s for anyone without hub access. Files whose canonical fleet-wide form lives only at the hub are mentioned by name, not linked; links into files every repo carries (`AGENTS.md`) resolve everywhere and are fine. -- **Adapted self-audit carry.** A downstream repo carries **locally adapted** `AUDIT.md` and `spec/secrets.json`, scoped to self-auditing its own rulesets, settings, and secrets against the committed `repo-config/` baseline - the standard shape, so the carried tooling is self-contained. The hub's fleet-wide audit remains authoritative, and the local copies never link the hub. +- **Adapted self-audit carry.** A downstream repo carries **locally adapted** `AUDIT.md` and `spec/secrets.json`, scoped to self-auditing its own rulesets, settings, and secrets against the committed `repo-config/` baseline - the standard shape, so the carried tooling is self-contained. The hub's fleet-wide audit remains authoritative, and the local copies never link the hub. The reference adaptation is the [Vantage-Config carry][vantage-config] (`AUDIT.md` + `spec/secrets.json`, operational model): a settings diff, a normalized ruleset diff against the carried payloads, and a names-only secrets check, all targeting the current repo - adapt it, don't invent. A `release` repo adapts the same shape: its `develop` payload stays at `repo-config/develop.json`, and its `spec/secrets.json` keeps the baseline App pair plus the secret names for its own publish mechanisms (from the hub's canonical `spec/secrets.json`). The fleet audit letter-checks both carried files (`spec/files.json`). - **The regen snippet targets the current repo**, so it works unchanged in a carried copy. ## Rulesets @@ -65,3 +65,7 @@ The fleet-standard general settings live in [`settings.json`][settings-json] and [agents-branching-model]: ../AGENTS.md#branching-model [agents-git-and-commit-rules]: ../AGENTS.md#git-and-commit-rules [settings-json]: ./settings.json + + + +[vantage-config]: https://github.com/ptr727/Vantage-Config diff --git a/spec/files.json b/spec/files.json index a587e3b5..a40ca8a4 100644 --- a/spec/files.json +++ b/spec/files.json @@ -16,6 +16,8 @@ { "path": "version.json", "intentRef": "WORKFLOW.md#d3---versioning-and-classification", "appliesTo": "*" }, { "path": "repo-config/develop.json", "intentRef": "repo-config/README.md", "appliesTo": "*" }, { "path": "repo-config/main.json", "intentRef": "repo-config/README.md", "appliesTo": "*" }, + { "path": "AUDIT.md", "intentRef": "repo-config/README.md", "appliesTo": "*" }, + { "path": "spec/secrets.json", "intentRef": "repo-config/README.md", "appliesTo": "*" }, { "path": ".github/dependabot.yml", "appliesTo": "*" }, { "path": ".vscode/tasks.json", "sections": ["clean-compile task group"], "reference": "catalog/snippets/configs/vscode-tasks.json", "appliesTo": ["csharp"] }, { "path": ".vscode/tasks.json", "sections": ["clean-compile task group"], "reference": "catalog/snippets/configs/vscode-tasks-python.json", "appliesTo": ["python"] },