Skip to content

Commit 0683a08

Browse files
spec: living-docs regen automation (CI fail-if-stale + make regen-all)
Almost every code-touching PR needs a manual "regenerate sidecar templates" follow-up commit. Spec proposes CI-fail-if-stale + a single `make regen-all` target. Trade-offs vs pre-commit / bot / auto-regen captured in the decisions doc. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 43c25eb commit 0683a08

1 file changed

Lines changed: 127 additions & 0 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Decisions — Living-docs regen automation
2+
3+
**Status:** draft — awaiting decision on Approach.
4+
**Owner:** Patrick
5+
6+
## Problem
7+
8+
Almost every code-touching PR in attune-gui needs a follow-up
9+
"regenerate sidecar templates" commit added by hand. The
10+
sidecar generates living-docs templates (`.help/templates/`)
11+
and a Vite editor bundle (`editor-frontend/dist/`) that are
12+
**both committed** to the repo. When source changes, the
13+
generated artifacts drift, and a contributor (or assistant)
14+
has to remember to regenerate and commit them in a second
15+
step.
16+
17+
Recent examples — every one of these triggered a manual
18+
follow-up regen commit:
19+
20+
- `30cc722` fix(specs) → `ac6b552` regenerate
21+
- `d282f21` test(mcp) → `7e01b1a` regenerate
22+
- `1657c2f` feat(mcp) → `db4c562` regenerate
23+
- `05489c1` feat(mcp/tools) → regenerate
24+
25+
Across ~10 PRs over recent weeks, that's ~10 extra commits of
26+
mechanical work. The risk is not "we forget once" — the risk
27+
is *we forget often enough that stale generated files become
28+
the norm* and the living-docs system silently drifts from the
29+
source of truth.
30+
31+
## Current state (verified 2026-05-23)
32+
33+
- No git hooks installed (`.pre-commit-config.yaml`,
34+
`.husky/`, `lefthook.yml` all absent).
35+
- A post-commit *webhook* exists (`scripts/install-living-docs-hook.sh`)
36+
but it only **notifies the sidecar to scan** — it does
37+
not regenerate.
38+
- CI (`.github/workflows/tests.yml`) runs ruff + pytest +
39+
vitest typecheck. **It does not check for stale generated
40+
artifacts.**
41+
- Generated artifacts are deterministic:
42+
- Editor bundle uses Vite content-hashed filenames, no
43+
timestamps in output.
44+
- Living-docs templates have `generated_at` (timestamp)
45+
and `source_hash` (content hash) frontmatter — `generated_at`
46+
is the only intrinsic source of churn, and it's not
47+
semantic.
48+
49+
## Decision
50+
51+
**Approach: CI-fail-if-stale + a single `make regen-all` target.**
52+
53+
CI runs `make regen-all` then `git diff --exit-code`. If any
54+
generated file changed, CI fails with a clear message pointing
55+
the contributor at `make regen-all` to fix locally. No
56+
auto-commit, no bot, no pre-commit hook blocking local work.
57+
58+
The contributor's loop becomes:
59+
60+
```bash
61+
# After making source changes that touch templates or editor:
62+
make regen-all
63+
git add -u
64+
git commit -m "regenerate sidecar templates"
65+
```
66+
67+
If they forget, CI tells them in the same PR run.
68+
69+
### Why this and not the alternatives
70+
71+
| Option | Pro | Con |
72+
|---|---|---|
73+
| **Pre-commit hook** (chosen against) | Catches drift at commit time. | Blocks local commits; slow (editor build is ~7s + author maintain on top); requires Node + uv on every contributor's machine; regen is partly async — hard to wait for completion in a hook; many contributors disable hooks. |
74+
| **Post-merge bot commit** (chosen against) | Zero friction; always-correct main. | Needs bot write access to main; conflicts with stacked-PR rebases; adds noise (one bot commit per PR); audit trail becomes "Claude regenerated these" rather than "Patrick approved these"; opaque. |
75+
| **CI fail-if-stale** (chosen) | Visible; deterministic; no bot access; one command for contributors; aligns incentives — the PR author owns the regen. | Adds friction of one extra command + commit per affected PR. (Net win: it's the friction we already pay manually, but now it's enforced, so we stop forgetting.) |
76+
| **Auto-regen commit in CI** (chosen against) | No contributor friction. | Same bot-access concerns as post-merge; harder to attribute changes; stacked-PR conflict surface. |
77+
78+
## Scope
79+
80+
**In scope:**
81+
82+
1. New `make regen-all` target that runs:
83+
- `make build-editor` (already exists at `Makefile:6-18`)
84+
- `attune-author maintain` for the sidecar living-docs corpus
85+
- Any other regen step we discover during implementation
86+
2. New CI job `regen-up-to-date` in `.github/workflows/tests.yml`:
87+
- Installs node + uv
88+
- Runs `make regen-all`
89+
- Runs `git diff --exit-code -- .help/ editor-frontend/dist/` (paths refined during impl)
90+
- On failure: prints a clear message with the fix command
91+
3. README update under `## Development` documenting the contract.
92+
93+
**Out of scope:**
94+
95+
- Pre-commit hooks (deliberately).
96+
- Any bot or automation that writes to main.
97+
- Migrating the post-commit-webhook scan trigger (separate concern).
98+
- Reducing the regen time itself (separate perf spec if it becomes painful).
99+
100+
## Acceptance criteria
101+
102+
- `make regen-all` is a single command that produces a clean
103+
working tree on a fresh checkout with no source changes.
104+
- CI fails a PR that modifies source-of-truth files without
105+
regenerating, and the failure message names the fix command.
106+
- README documents `make regen-all` in the existing
107+
`## Development` section.
108+
- No new commits land on `main` from any bot account.
109+
110+
## Open questions
111+
112+
1. What's the exact `attune-author maintain` invocation for
113+
this repo's federated config? (Phase 1 task.)
114+
2. Should we gate the CI check behind a label (e.g. only run
115+
`regen-up-to-date` when paths matching `sidecar/**` or
116+
`editor-frontend/src/**` change) to keep PR feedback fast
117+
for docs-only or test-only changes? Default: yes, conditional.
118+
3. CI runtime budget — `make build-editor` is ~7s; `attune-author maintain`
119+
time unknown. If the combined regen-check exceeds 60s, revisit
120+
whether to split it.
121+
122+
## Phase outline (when this spec is approved)
123+
124+
- **Phase 1** — Inventory the exact regen commands and write `make regen-all`.
125+
- **Phase 2** — Add the CI job, gated on relevant paths; verify it fails
126+
intentionally on a stale-artifact PR before flipping it to required.
127+
- **Phase 3** — README update; make the contract official.

0 commit comments

Comments
 (0)