From 8d221ccf50de195e4898f23cc5131053defb03a1 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Mon, 3 Aug 2026 16:23:06 -0700 Subject: [PATCH 1/2] Put the repo's own conventions where the section model sends them `AGENTS.md > Project Conventions` was a section the hub does not declare, which the audit flags as drift to reconcile. Reconciling it found that most of it was already reconciled elsewhere. Three of the four rules were near-verbatim duplicates of entries already in `TODO.md` Traps: never populating media over HTTP, `content/` being an imported archive, and a gate proving itself by failing. Duplicated rules are worse than absent ones, because the two copies drift and nothing says which is current, so those three are deleted here rather than moved. The fourth was unique and is the load-bearing one. The URL contract being ground truth and its lists being append-only appeared nowhere else, and in particular not in `OPERATIONS.md`, which operates that contract through the whole local-verification and deploy path without ever stating the invariant behind it. It moves there, ahead of the verification section that depends on it, and picks up the length-floor clause that `TODO.md` carried separately, since a floor is what makes append-only checkable rather than aspirational. `AGENTS.md` is left carrying only the three sections the hub declares, and its intro drops from four things to three, which is what the hub's own intro says. Note this does not resolve ProjectTemplate#552. That contradiction is about the byte-locked `Fleet Bootstrap` section naming the template repo, which is untouched here and still flagged. ## Verification - Every verbatim unit still byte-matches the canonical, so removing the local section disturbed none of the carried ones. - markdownlint, editorconfig-checker, and the prose gate are clean. Co-Authored-By: Claude Opus 5 (1M context) --- AGENTS.md | 11 +---------- OPERATIONS.md | 6 ++++++ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 67935ee..55805bd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,19 +2,10 @@ **Blog** is the source and deployment pipeline for a personal technical blog, a Hugo static site served by Caddy behind a reverse proxy. It holds the content, the media, the URL contract the site must honor, and the release tooling that builds and publishes it. -This file is the entry point every coding agent reads first, and it holds only four things: this project's own conventions, the bootstrap that says where the canonical rules live and which procedure to follow for the state this repository is actually in, the rules for managing context and delegation, which apply to every task, and a map of where every other rule lives. The rule text itself is in [`GOVERNANCE.md`](./GOVERNANCE.md), one section per topic. Code style lives in [`CODESTYLE.md`](./CODESTYLE.md), the CI/CD workflow contract in [`WORKFLOW.md`](./WORKFLOW.md), and the deploy, rollback, and server procedures in [`OPERATIONS.md`](./OPERATIONS.md). +This file is the entry point every coding agent reads first, and it holds only three things: the bootstrap that says where the canonical rules live and which procedure to follow for the state this repository is actually in, the rules for managing context and delegation, which apply to every task, and a map of where every other rule lives. The rule text itself is in [`GOVERNANCE.md`](./GOVERNANCE.md), one section per topic. Code style lives in [`CODESTYLE.md`](./CODESTYLE.md), the CI/CD workflow contract in [`WORKFLOW.md`](./WORKFLOW.md), and the deploy, rollback, and server procedures in [`OPERATIONS.md`](./OPERATIONS.md). Treat this file and `GOVERNANCE.md` as authoritative for cross-cutting rules, and do not restate their rules elsewhere. This project's own conventions and behavioral contracts live here, **not** in [`.github/copilot-instructions.md`](./.github/copilot-instructions.md), because that file targets GitHub Copilot / VS Code specifically, while this file and `GOVERNANCE.md` are the agent-agnostic ones every coding agent is directed to read, so any rule a reviewer must honor has to live in one of those two files to be provider-independent. -## Project Conventions - -This site has served the same domain across earlier platforms, so its whole risk is silent URL loss. These bind every change. - -- **The URL contract is ground truth.** [`checks/golden-urls.txt`](./checks/golden-urls.txt) and [`checks/redirect-urls.txt`](./checks/redirect-urls.txt) record URLs verified with a live request. The lists are append-only. Nothing legitimately removes a URL the site has served. -- **Never populate media over HTTP.** The source export is the only trustworthy media source, because a hosted platform serves optimized derivatives at the same filename and path. Verify by content hash, never by file count. -- **`content/` is an archive.** It carries sixteen years of text. Prose, spelling, and style sweeps do not reach it, and rewriting it corrupts provenance rather than improving style. -- **A gate proves itself by failing.** Every check here is demonstrated against a deliberate break before it is trusted, because a gate that has only ever passed is indistinguishable from one that checks nothing. - ## Fleet Bootstrap This repository is governed by a shared template, and the canonical rules, machine-readable spec, and procedures live in `github.com/ptr727/ProjectTemplate`. Fetch that repository before acting on anything about conformance, carried content, repository settings, or standing a repository up, because a carried copy here can be stale or absent and the hub is the only authority on what this repository is supposed to hold. This section is byte-locked across every repository in the fleet, so it reads identically wherever it is found, and it is the entry point whenever nothing else present says where the rules are. diff --git a/OPERATIONS.md b/OPERATIONS.md index d1a446b..ce954c0 100644 --- a/OPERATIONS.md +++ b/OPERATIONS.md @@ -29,6 +29,12 @@ Shipping the config inside the release is what makes a rollback honest. The rule `current` is a **relative** symlink. That frees the host path, so one bundle works at whatever root each environment mounts, with no rewriting. +## The URL Contract + +This site has served the same domain across earlier platforms, so its whole operational risk is silent URL loss. Everything below exists to make that risk visible. + +**The contract is ground truth.** [`checks/golden-urls.txt`](./checks/golden-urls.txt) and [`checks/redirect-urls.txt`](./checks/redirect-urls.txt) record URLs verified with a live request, not predicted from the content tree. The lists are **append-only**: nothing legitimately removes a URL the site has served, so a change that would drop one is a change to reject rather than a list to shorten. A list-driven check also carries a length floor, or a truncated list passes while checking almost nothing. + ## Local Verification Before a Pull Request **CI cannot prove a redirect.** The validation workflow builds the site and checks the render half of the contract, which is every URL that must return a page. The other 917 URLs are the web server's job, and nothing in a build exercises them. A change to the Caddy config or to a generated map is therefore invisible to CI: the workflow goes green while the redirect it broke stays broken until someone follows a sixteen-year-old link. From 88778c30d29bb53d3c1a8b25e12ee65f6de2d594 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Mon, 3 Aug 2026 16:28:16 -0700 Subject: [PATCH 2/2] Point at the doc that owns a convention, now that one moved The preamble said this project's own conventions live "here", which was true while `Project Conventions` was in this file and stopped being true in the same change that moved it out. An agent reading the sentence would look for repo invariants in `AGENTS.md` and find none. The sentence's actual point is provider independence, that a rule a reviewer must honor cannot live in the Copilot-specific file, and that point survives intact. It now names the topical docs that own the content instead of claiming this file does. Co-Authored-By: Claude Opus 5 (1M context) --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 55805bd..dc41645 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ This file is the entry point every coding agent reads first, and it holds only three things: the bootstrap that says where the canonical rules live and which procedure to follow for the state this repository is actually in, the rules for managing context and delegation, which apply to every task, and a map of where every other rule lives. The rule text itself is in [`GOVERNANCE.md`](./GOVERNANCE.md), one section per topic. Code style lives in [`CODESTYLE.md`](./CODESTYLE.md), the CI/CD workflow contract in [`WORKFLOW.md`](./WORKFLOW.md), and the deploy, rollback, and server procedures in [`OPERATIONS.md`](./OPERATIONS.md). -Treat this file and `GOVERNANCE.md` as authoritative for cross-cutting rules, and do not restate their rules elsewhere. This project's own conventions and behavioral contracts live here, **not** in [`.github/copilot-instructions.md`](./.github/copilot-instructions.md), because that file targets GitHub Copilot / VS Code specifically, while this file and `GOVERNANCE.md` are the agent-agnostic ones every coding agent is directed to read, so any rule a reviewer must honor has to live in one of those two files to be provider-independent. +Treat this file and `GOVERNANCE.md` as authoritative for cross-cutting rules, and do not restate their rules elsewhere. This project's own conventions and behavioral contracts live in the topical doc that owns them, [`OPERATIONS.md`](./OPERATIONS.md) for how the site is run and verified and [`CODESTYLE.md`](./CODESTYLE.md) for how it is written, and **never** in [`.github/copilot-instructions.md`](./.github/copilot-instructions.md), because that file targets GitHub Copilot / VS Code specifically while the rest are agent-agnostic, so any rule a reviewer must honor has to live outside it to be provider-independent. ## Fleet Bootstrap