Document the publishing workflow and the migration record - #49
Conversation
The README gains two sections for a human reader: a short pointer to the migration post, and a high-level walk of how a change reaches the site, with mermaid diagrams for the pipeline, the branch model, and the loop that runs while the site serves. WORKFLOW.md remains the tooling contract and is not duplicated. OPERATIONS.md gains The Migration Record, naming the post as the artifact to cite before touching checks/ or deploy/maps/, and Rebuilding from the Exports, which records what the provenance capture holds and which parts of it can be fetched again. The capture path was recoverable only from memory, so CAPTURE_ROOT joins the other machine-specific values in secrets/, with checks/README.md pointing at it beside the tool that consumes it. The migration post gains a step 0 making the same point for a reader running their own migration. Log Review is corrected: the edge access log exists, so the section describing retention as unconfigured was false. It now states what each tier can answer without naming a retention window or a size limit, both of which belong to the host and can change without this file knowing. Absolute counts that describe volatile state are replaced by what they represent. The counts that survive describe the legacy contract, which content additions do not move, and checks/README.md and deploy/README.md now say so rather than leaving a reader to infer it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the repository’s human-facing documentation to better explain the WordPress→Hugo migration context, the publish pipeline from branch to production, and the provenance needed to rebuild the redirect maps and other migration-derived artifacts without relying on tribal knowledge.
Changes:
- Add new README sections documenting the WordPress migration context and a high-level “change to production” workflow (with Mermaid diagrams).
- Expand OPERATIONS.md with a “Migration Record” and “Rebuilding from the Exports” section to centralize provenance and rebuild guidance.
- Update ancillary docs/config examples to emphasize stable concepts over volatile counts and to record
CAPTURE_ROOTas rebuild provenance.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| TODO.md | Replaces volatile migration counts with durable statements; expands production cutover checklist details. |
| README.md | Adds “Migration from WordPress” and “How a Change Reaches the Site” sections, including Mermaid diagrams and new references. |
| OPERATIONS.md | Adds a migration artifact reference section and documents rebuild provenance, plus refines log/retention documentation. |
| deploy/README.md | Clarifies contract invariants vs. content growth and removes dependence on fixed URL counts in prose. |
| deploy/env.example | Documents CAPTURE_ROOT as a machine-specific provenance input for regenerating redirect maps. |
| content/posts/2026/08/01/moving-this-blog-from-wordpress-to-hugo.md | Adds an explicit “step 0” about where to store capture inputs and why. |
| checks/README.md | Clarifies what counts represent (contract vs. site) and points readers to CAPTURE_ROOT provenance documentation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
The strict-build wording used a clipped absolute construction in both the diagram label and the prose beneath it, and the orphan table's cause and effect ran together in one comma-spliced cell. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (2)
OPERATIONS.md:228
- Traefik access-log JSON uses
RequestURIfor the full request (path + query);RequestPathis path-only. As written, this line claimsRequestPathincludes the query string, which would be false for/?p=<id>traffic unless you’re actually readingRequestURI(or otherwise logging the query).
**On the VPS the reviewable record is Traefik's access log**, at `/var/log/traefik/access.log`, one JSON object per line, one line per request, across every hostname the host serves. `RequestPath` carries the query string, so the legacy `/?p=<id>` traffic is visible as itself. Request headers are dropped except `Referer` and `User-Agent`, which is what keeps the Pangolin resource access token out of a file that is retained and copied, and query strings are logged in full, so treat an extract as sensitive.
TODO.md:32
comms/vps-agent.mdis referenced as if it were in the repository, butcomms/is gitignored and the file isn’t present in-tree. As a result, this pointer is a dead link for anyone reading TODO.md on GitHub unless you explicitly note that it must be pulled from/srv/agent-comms/(per OPERATIONS.md).
- **Deploy production once, to a name that is not the live one.** The host side is done and the interim name is live: `blog.insanegenius.net` answers `200` unauthenticated, on a Let's Encrypt certificate issued 2026-08-07, serving `0000-placeholder`. The VPS agent calls this M7a, and M7b is the `.com` cutover. Three items belong to this repo before the first production deploy, all detailed in `comms/vps-agent.md` §19 and §20:
TODO.md cited the channel file by its working-copy path, which is gitignored, so the reference read as an in-tree file that a reader on GitHub cannot open. Name the section that carries the pull instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ptr727
commented
Aug 8, 2026
Working the two suppressed comments from the review on Accepted: |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (3)
TODO.md:11
- Grammar: “Every migrated post and page carried” is missing a verb, so it reads ungrammatically in the status summary.
| Content and media | done. Every migrated post and page carried, and the media hash-verified against the export tar |
checks/README.md:44
- The note “including one the list does not hold” is grammatically awkward/unclear in a table cell; consider rephrasing to make it clear the matcher accepts dates not present in the contract list.
| Date archives | 83 | Redirect to `/all/`, since **Hugo has no built-in year or month archive**. The matcher covers any date, including one the list does not hold |
deploy/README.md:271
- The phrase “the matcher covers a date the list does not” is unclear in this table row; it reads like a single specific date rather than the general case (any date).
| `@date_archive` | 83 | `/YYYY/`, `/YYYY/MM/`, and their pagination -> `/all/`, and the matcher covers a date the list does not |
The status row elided its verb, and the two date-archive rows described the matcher's coverage in a phrase that reads as one specific date rather than the general case. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ptr727
commented
Aug 8, 2026
The review on
The last two are the same sentence in two files, and the objection is right about both: the singular read as one specific date rather than the general case, which inverts the point. That point is load-bearing here, because it is the reason a new post needs no entry in |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (2)
OPERATIONS.md:199
- This sentence is inaccurate: the URL contract isn’t “checked against the crawl”; the parity gate verifies the committed URL lists against the build output (and redirects via a live server). The point here seems to be that anything not captured into the contract can’t be detected by the gates, so rephrase to avoid implying the checks re-crawl the site.
**Real traffic is the only source that finds what every check here is blind to.** The URL contract proves the URLs someone thought to list and the redirects derived from the export. It cannot know about a URL nobody recorded, because the crawl that produced the lists is the same crawl the lists are checked against. A visitor following a sixteen-year-old link is the one reader who tests that.
deploy/env.example:66
- The comments here say CAPTURE_ROOT should live only in secrets/.env (not in every env file), but this file is the template that gets copied to create per-environment env files. As written, it encourages copying CAPTURE_ROOT everywhere while simultaneously saying not to; clarify the guidance so the template and the comment don’t contradict each other.
# Environment-independent, so it belongs in secrets/.env alone rather than in every file.
# Nothing sources this value, so it is recorded to keep a rebuild from depending on memory.
The Log Review section said the lists are checked against the crawl that produced them. The gates read the built site and the running server, so the circularity is that the lists are their own standard, not that a crawl is re-run. State it that way. The CAPTURE_ROOT comment told a reader to keep the value in one file while sitting in the template that is copied to make the others, so it now says to drop it from the per-environment copies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ptr727
commented
Aug 8, 2026
The review on
This was pre-existing prose that I edited in this PR, which is what brought it into scope.
|
What
Two new README sections for a human reader, and the repo-side records that make a rebuild possible without asking anyone where the inputs live.
Migration from WordPress, a short pointer to the post, andHow a Change Reaches the Site, a high-level walk from a branch to production with mermaid diagrams for the pipeline, the branch model, and the loop that runs while the site serves.WORKFLOW.mdstays the tooling contract and is not duplicated.The Migration Record, naming the post as the artifact to cite before touchingchecks/ordeploy/maps/, andRebuilding from the Exports, recording what the provenance capture holds and which parts of it can be fetched again.CAPTURE_ROOTjoins the other machine-specific values indeploy/env.example, because the capture's location was recoverable only from an agent's memory.checks/README.mdpoints at it besidebuild-redirects.py, which consumes it.Corrections
Log Reviewdescribed log retention as unconfigured, which the edge access log has made false. It now states what each tier can answer, without naming a retention window or a size limit. Both belong to the host and can change without this file knowing.Absolute numbers
Counts that describe volatile state, or another system's configuration, are replaced by what they represent. The counts that survive describe the legacy contract, which content additions do not move, since the parity gate reports a new post as
additional URLs built (not a failure)rather than growing a list.checks/README.mdanddeploy/README.mdnow say that outright rather than leaving a reader to infer it from a number that looks wrong after the next post.Verification
hugo --gc --minify --panicOnWarningbuilds clean.checks/check-url-parity.py publicpasses: 328/328 render, 778/778 legacy media, 1049/1049 assets, orphans at the recorded constant.content/:PASS - 1245 URLs honored, rules confirmed live from the deployed release id.🤖 Generated with Claude Code