Astro + Starlight docs site + Warp docubot port + /update-docs decommission — PLAN
Astro + Starlight docs site + Warp docubot port + /update-docs decommission — PLAN
Section titled “Astro + Starlight docs site + Warp docubot port + /update-docs decommission — PLAN”Status: DRAFT (
{9.4}, kh-prod-readiness-S61). Authored by a FRESH task-planner instance per Q-PLANNER-2 (NOT the{9.2}PRODUCT or{9.3}TECH Planner). Decomposes the ratified PRODUCT.md (52 invariants) + TECH.md (1342 lines, §0–§7 + Testing-and-validation 52-row 1-to-1 mapping + §Parallelization 17-slice sketch) into seventeen implementation Subtasks (9.5through9.21) plus this PLAN Subtask (9.4). Sibling-only Subtask dependency constraint honoured throughout (no cross-Task dependency surfaced; escalation tripwire was not hit).
Companion specs
Section titled “Companion specs”- PRODUCT spec (ratified
{9.2}S59):./PRODUCT.md— 52 numbered Behaviour invariants across four scope-thirds plus supporting deliverables.- Third 1 (Docs site): Inv-1..24 (24 invariants — IA, rendering, sync hierarchy, AI-invisibility, UK English).
- Third 2 (Docubot port): Inv-25..35 (11 invariants — trigger, authoring, auth, Phase-2 composability).
- Third 3 (5-skill port): Inv-36..43 (8 invariants — scope, per-skill triggers, workflow shape).
- Third 4 (Decommission): Inv-44..50 (7 invariants — successor mapping, two-session sequence, hard deadline).
- Supporting deliverables (OQ-1 DEFAULT): Inv-51..52 (2 invariants —
AGENTS.md +
keep-docs-in-sync).
- TECH spec (ratified
{9.3}S60):./TECH.md— §0 name resolution + 4 critical locks (Inv-30 docubot direct-write; KH-persona prompt template; canonical 5-skill workflow shape; Vercel-default-subdomain framing); §1 Context; §2 Docs site infrastructure (11 subsections); §3 Docubot port (7 subsections); §4 Five-skill port (canonical shape + 5 per-skill); §5/update-docsdecommission; §6 Cross-third integration (AGENTS.md +keep-docs-in-sync); §7 Cross-project packaging; Testing-and-validation table (52-row 1-to-1 invariant → test mapping); End-to-end Mermaid sequence diagram; Risks (15 rows); Parallelization (17-slice sketch); Follow-ups (13 explicit non-goals); 3 new OQs (T1/T2/T3 — all ratified at S60 close). - Research (background,
{9.1}):docs/research/docs-site-rebuild-research.md— 716 lines, 6 Warp docs skills inventoried + docubot mechanism + KH docs/ IA audit + delta vs stale S47 specs.
Ratifications absorbed at {9.3} close (S60)
Section titled “Ratifications absorbed at {9.3} close (S60)”The three new TECH OQs were Liam-ratified at S60 close:
| OQ | Ratification | PLAN consequence |
|---|---|---|
| OQ-T1 (docubot divergence handling) | DEFAULT — front-matter flag (kh_docubot_owned: true) + sync-script honour | 9.6 sync script honours the flag; 9.11 docubot prompt enforces the flag |
| OQ-T2 (per-skill cron-trigger enablement) | DEFAULT — enable all 4 active crons at foundation | 9.15 (sync-source-docs weekly), 9.17 (check-for-broken-links daily), 9.18 (docs-seo-audit — cron present but commented per OQ-T3) ship with crons enabled |
| OQ-T3 (docs-seo-audit deferred-enable) | DEFAULT — workflow file committed with schedule: commented out, uncomment post-deploy | 9.18 docs-seo-audit ships workflow file with schedule: block commented; Follow-up commit (NOT a Subtask) uncomments post first-deploy |
The three PRODUCT OQs (OQ-6 ci.yml direct-commit-vs-side-PR, OQ-7
cross-worktree preview, OQ-8 AGENTS.md vs CLAUDE.md separation) were
ratified at S59 close per {9.2} PRODUCT close-out notes — folded into TECH
§5.2 (direct-commit with side-PR fallback), §2.5 (--source-root flag), §6.1
(complementary AGENTS.md cross-references CLAUDE.md).
Decomposition principles applied
Section titled “Decomposition principles applied”- Vertical slicing. Each Subtask delivers a vertical capability slice leaving the system in a working state. Horizontal slicing (build all infra first then all features) is explicitly avoided. The scaffold-first Subtask (9.5) is the one foundation slice; everything thereafter is a capability that adds independently-verifiable value.
- Sibling-only Subtask dependencies (§3.3 / A6 forcing function). Every
implementation Subtask depends only on other Subtasks of ID-9. No
cross-Task dependency surfaced during decomposition. ID-19.x (worktree
isolation hooks) is referenced in TECH only as a brief-authoring
discipline pointer (CLAUDE.md ID-19.4) and requires no co-edit. ID-15
(legacy ID migration) is independent — docubot reads
task-list.json/ roadmap / backlog via standard tooling. - ≤2-3h per Subtask. Aligned with the workflow rule “max 2h per Executor dispatch” (CLAUDE.md). Most Subtasks sit at ~1.5-2h; the four marked ~2-3h (9.5 scaffold + 9.6 sync + 9.11 composite action + 9.16 missing-docs) carry buffer for unforeseen scope mid-flight.
- Dependency-graph foundations first. Scaffold (9.5) precedes sync (9.6) and theming (9.7); AGENTS.md (9.9) precedes anything that loads it in prompt context (9.10, 9.11, 9.13); composite action (9.11) precedes workflow (9.12) and skill-driver inheritance (9.13).
- Parallelization-friendly per TECH §Parallelization. After 9.5 lands: 9.6 + 9.7 can run in parallel worktrees. After 9.9 + 9.10 land: 9.11 + 9.19 (independent ci.yml edit) parallelize. After 9.13 lands: 9.14-9.18 (five skill bodies) parallelize fully. After 9.12 + 9.14 land: Session A (9.20) can begin while 9.15-9.18 still settle. Worktree parallelization guidance is per-Subtask under §Notes for Orchestrator dispatch.
- Coverage transitivity, not invariant-per-Subtask 1:1. TECH’s Testing-and-validation table already maps each PRODUCT invariant to a concrete test colocated with the TECH §. Each Subtask below cites the invariant range and TECH § it implements; full 52/52 coverage verified under §Coverage verification.
- Sub-agent worktree heritage discipline (per CLAUDE.md ID-19.4). Every
Subtask’s
detailsfield opens with a verbatim worktree-first-action gate (pwd && git branch --show-current && git fetch origin production-readiness && git reset --hard origin/production-readiness && git branch --show-current && git status). Nocdprefix anywhere in dispatch text. Absolute paths reserved for the worker’s own worktree only; sibling-worktree absolute paths NEVER mentioned in dispatch text (primer effect risk). - Test philosophy alignment (
docs/reference/test-philosophy.md). Every Subtask’stestStrategyline names the concrete file paths underdocs-site/__tests__/,__tests__/skills/,__tests__/workflows/, or__tests__/scripts/that the Executor authors. Where a behaviour is only verifiable by manual session-close inspection (e.g. docubot run quality on 3 sample PRs), thetestStrategysays so explicitly with the Inv-X acceptance criterion cited.
Subtask dependency graph
Section titled “Subtask dependency graph” 9.4 PLAN.md (this Subtask, in_progress at dispatch) │ ├── 9.5 Docs-site scaffold (§2.1 + §2.3 + §2.4) │ └── (foundation; no deps) │ ├── 9.6 Sync script + manifest + divergence-flag honour (§2.5 + §2.6 + §3.4) │ └── depends on 9.5 (needs content-collection schema + spaces config) │ ├── 9.7 Warm Meridian theming + token-drift guard (§2.7 + §2.8) │ └── depends on 9.5 (needs customCss path + astro.config.mjs surface) │ ├── 9.8 AI-invisibility + UK English CI guards + 404 + empty states (§2.9 + §2.10 + §2.11) │ └── depends on 9.6 (operates on synced output) │ ├── 9.9 AGENTS.md at repo root (§6.1) │ └── (foundation; no deps; standalone repo-root file) │ ├── 9.10 keep-docs-in-sync skill (§6.2) │ └── depends on 9.9 (cross-references AGENTS.md) │ ├── 9.11 Docubot composite action + KH-persona prompt template (§3.1 + §3.3 + §3.6) │ └── depends on 9.9 + 9.10 (prompt rule names both) │ ├── 9.12 Docubot workflow + Claude Agent SDK driver (§3.2 + §3.5 + §3.7) │ └── depends on 9.11 (workflow invokes composite action) │ ├── 9.13 5-skill canonical workflow scaffold + shared driver (§4.1 + §4.2) │ └── depends on 9.9 + 9.10 + 9.11 (driver loads AGENTS.md + │ keep-docs-in-sync; inherits composite action shape) │ ├── 9.14 review-docs-pr skill body + workflow (§4.3) │ └── depends on 9.13 (uses shared driver) │ ├── 9.15 sync-source-docs skill body + workflow (§4.4) │ └── depends on 9.13 (uses shared driver) │ ├── 9.16 missing-docs skill body + Python audit script + workflow (§4.5) │ └── depends on 9.13 (uses shared driver) │ ├── 9.17 check-for-broken-links skill body + Python link-walker + workflow (§4.6) │ └── depends on 9.13 (uses shared driver) │ ├── 9.18 docs-seo-audit skill body + Python audit + workflow (§4.7) │ └── depends on 9.13 (uses shared driver) │ ├── 9.19 ci.yml regenerate-stats job (§5.2) │ └── (independent ci.yml edit; no deps) │ ├── 9.20 Session A decommission verification gate (§5.3 gate 1) │ └── depends on 9.12 (docubot live) + 9.14 (review-docs-pr live for │ Inv-35 second-pass requirement); Liam manual review of 3 sample │ docubot PRs │ └── 9.21 Session B atomic decommission: ci.yml verified + remove update-docs + CLAUDE.md atomic edit (§5.4 + §5.5) └── depends on 9.19 (regenerate-stats job verified live) + 9.20 (Session A gate closed)Total: 4 spec Subtasks (9.1 RESEARCH done, 9.2 PRODUCT done, 9.3 TECH
in_progress→done at S61, 9.4 this PLAN) + 17 implementation Subtasks (9.5
through 9.21) = 21 total Subtasks under ID-9. Within the 25-Subtask soft
ceiling per §3.4 / A7.
Phase / checkpoint plan
Section titled “Phase / checkpoint plan”Phase 1 — Docs-site foundation (must land before any docubot work)
Section titled “Phase 1 — Docs-site foundation (must land before any docubot work)”- 9.5 Docs-site scaffold (Astro + Starlight + Vercel + content collection)
- 9.6 Sync script + manifest + divergence-flag honour (parallel-eligible after 9.5)
- 9.7 Warm Meridian theming + token-drift guard (parallel-eligible after 9.5)
- 9.8 AI-invisibility + UK English CI guards + 404 + empty states (parallel-eligible after 9.6)
Checkpoint after Phase 1 (9.5+9.6+9.7+9.8):
cd docs-site && bun install && bun run buildsucceeds from a fresh clone (acceptance criterion third 1 row 1).- All 5 canonical front-door directories publish to their assigned spaces in the visible 5-space sidebar.
- Vercel sibling project
knowledge-hub-docsdeploys to a default subdomain Liam can browse. - Warm Meridian palette visibly applied; no default Starlight cobalt-blue.
- CI gates the docs build (malformed front matter / broken internal link / removed referenced page → build fails).
- AI-invisibility grep guard fails build on forbidden phrases.
Phase 2 — Style guide + skill foundation (parallel-eligible with Phase 1 sync work)
Section titled “Phase 2 — Style guide + skill foundation (parallel-eligible with Phase 1 sync work)”- 9.9 AGENTS.md at repo root (independent of docs-site; can run in parallel with 9.5-9.8)
- 9.10 keep-docs-in-sync skill (depends on 9.9)
Checkpoint after Phase 2 (9.9+9.10):
AGENTS.mdexists at repo root with the 5 required sections per Inv-51..claude/skills/keep-docs-in-sync/SKILL.mdexists with the 7 required sections per Inv-52.- Both files validated by
__tests__/agents-md/agents-md-shape.test.ts+__tests__/skills/keep-docs-in-sync-shape.test.ts(NEW).
Phase 3 — Docubot (depends on Phase 1 docs-site + Phase 2 style guide)
Section titled “Phase 3 — Docubot (depends on Phase 1 docs-site + Phase 2 style guide)”- 9.11 Docubot composite action + KH-persona prompt template
- 9.12 Docubot workflow + Claude Agent SDK driver
Checkpoint after Phase 3 (9.11+9.12):
.github/actions/docubot/action.yml+.github/workflows/docubot.yml.github/actions/docubot/prompt.txtall present.
workflow_dispatchinvocation succeeds end-to-end on at least one sample run (Inv-25 acceptance).pull_request.types: [closed]filter onmerged == truetriggers docubot on at least one real source-PR merge.- Run artefacts (
prompt.output.txt+ SDK log) upload on every run viaactions/upload-artifact@v4withif: always().
Phase 4 — 5-skill port (depends on Phase 3 docubot composite action)
Section titled “Phase 4 — 5-skill port (depends on Phase 3 docubot composite action)”- 9.13 5-skill canonical workflow scaffold + shared driver
- 9.14-9.18 Five per-skill bodies + workflows (parallelizable after 9.13)
Checkpoint after Phase 4 (9.13+9.14+9.15+9.16+9.17+9.18):
- All 5 skills present at
.claude/skills/<name>/SKILL.md(review-docs-pr, sync-source-docs, missing-docs, check-for-broken-links, docs-seo-audit). - Each has its
.github/workflows/<name>.ymlworkflow file matchingdocubot.yml’s canonical shape per Inv-43. update-changelogis explicitly NOT present (OQ-3 OVERRIDE confirmed via__tests__/skills/skill-inventory.test.ts).- Each skill loads
AGENTS.md(verified by grep ofscripts/skills/run-skill.ts).
Phase 5 — Decommission (depends on Phase 3 docubot + Phase 4 review-docs-pr)
Section titled “Phase 5 — Decommission (depends on Phase 3 docubot + Phase 4 review-docs-pr)”- 9.19 ci.yml regenerate-stats job (independent; can land any time after 9.5 stabilises)
- 9.20 Session A decommission verification gate
- 9.21 Session B atomic decommission + CLAUDE.md edit
Final checkpoint after Phase 5 (9.19+9.20+9.21):
ci.ymlregenerate-statsjob runs successfully on at least one merge-to-main commit (Inv-48 acceptance).- Session A gate closed: docubot demonstrably handled (a)+(b)+(d) workloads
on at least 3 sample source-PR merges (per OQ-PLAN-1, synthetic via
workflow_dispatchon 3 historical PRs is acceptable). .claude/skills/update-docs/directory removed.- CLAUDE.md atomically updated to remove
/update-docsreferences + add docubot +keep-docs-in-syncreferences (same commit as the directory removal — Inv-49). - Hard deadline honoured per Inv-50 (no
/update-docslingering beyond Session B).
Sibling-only dependency verification
Section titled “Sibling-only dependency verification”Every dependency emitted by the Subtasks below points to another Subtask of ID-9. No cross-Task dependency surfaced.
| Subtask | Depends on | All deps are siblings of ID-9? |
|---|---|---|
| 9.5 | (none) | yes — no deps |
| 9.6 | 9.5 | yes |
| 9.7 | 9.5 | yes |
| 9.8 | 9.6 | yes |
| 9.9 | (none) | yes — no deps |
| 9.10 | 9.9 | yes |
| 9.11 | 9.9, 9.10 | yes |
| 9.12 | 9.11 | yes |
| 9.13 | 9.9, 9.10, 9.11 | yes |
| 9.14 | 9.13 | yes |
| 9.15 | 9.13 | yes |
| 9.16 | 9.13 | yes |
| 9.17 | 9.13 | yes |
| 9.18 | 9.13 | yes |
| 9.19 | (none) | yes — no deps |
| 9.20 | 9.12, 9.14 | yes |
| 9.21 | 9.19, 9.20 | yes |
No cross-Task dependency surfaced. The forcing-function escalation tripwire (Q-PLANNER-2 / A6) was not hit. ID-19.x (worktree-isolation hooks) is referenced as brief-authoring discipline only — non-coupling. ID-15.x (legacy ID migration) reads/writes occur via standard tooling; no ID-9-Subtask depends on an ID-15-Subtask outcome.
25-Subtask soft ceiling status
Section titled “25-Subtask soft ceiling status”Total Subtasks under ID-9 after this PLAN lands: 21 (9.1 through 9.21).
Within the 25 soft ceiling (per workflow-orchestration §3.4 / A7). The
4-spec-chain + 17-implementation split keeps the boundary correct — no Task
split surfaced as necessary.
If 9.16 (missing-docs) blows up during implementation (Python audit script has four sub-audits and could realistically split per-sub-audit), the Orchestrator may add 9.22+9.23+9.24+9.25 sub-slicing missing-docs into 4 sub-audits. That would land at exactly 25 — still within the ceiling. A fifth split would breach. If breached, the Orchestrator escalates and splits into ID-9a / ID-9b (per workflow §3.4 escalation pattern).
New OQs surfaced during decomposition
Section titled “New OQs surfaced during decomposition”This PLAN surfaces THREE new OQs (one per workflow rule ≤3 ceiling), all with defaults the Executor may proceed against unless Liam overrides.
New OQ-PLAN-1 — Session A docubot acceptance gate: synthetic vs organic source-PR merges
Section titled “New OQ-PLAN-1 — Session A docubot acceptance gate: synthetic vs organic source-PR merges”Question: Per PRODUCT Inv-47 + acceptance criteria third 4: “Docubot
opens at least 3 sample docs-PRs on real source-PR merges.” Is “real” a
hard requirement (3 organic post-Phase-3 source-PR merges in steady state),
or is workflow_dispatch invocation against 3 historical PR numbers
acceptable (synthetic)? The trigger path (pull_request.types: [closed] +
merged == true filter) is identical to workflow_dispatch for the
docubot’s actual run — only the launch event differs.
Default proposed: Synthetic is acceptable. Rationale: (a) the trigger
path is functionally identical from docubot’s perspective (same composite
action, same prompt template, same SDK invocation, same single-comment
guardrail); (b) waiting for 3 organic merges post-Phase-3 could delay the
Session B gate by days/weeks depending on PR cadence, breaching the Inv-50
two-session bound; (c) the synthetic path exercises the same gh pr view
gh pr diffcontext gather + envsubst + SDK + git-commit + gh-pr-create- gh-pr-comment chain.
Why this is an OQ: “Real source-PR merges” in Inv-47 could reasonably read either way. Liam may prefer to wait for organic merges if the goal is to exercise the natural trigger event under real load. The default unblocks Session A; the override pushes Session A close-out into a later session.
New OQ-PLAN-2 — 5-skill rollout ordering relative to Session A gate
Section titled “New OQ-PLAN-2 — 5-skill rollout ordering relative to Session A gate”Question: Per Phase 4 (5-skill port) + Phase 5 (decommission Session A), which of the five skills MUST be live before Session A’s gate closes?
- Inv-35 (Phase 2 composability) requires
review-docs-prto run against the docubot-opened docs-PR as a second-pass auto-review. Soreview-docs-pr(9.14) is hard-required for Session A. - The other 4 skills (
sync-source-docs,missing-docs,check-for-broken-links,docs-seo-audit) are scheduled-cron skills. They operate independently of docubot per Inv-35 (“Other scheduled skills operate independently of docubot but share the samekeep-docs-in-sync+AGENTS.mdcontext”).
Three options:
- Option A (recommended): Session A (9.20) depends on 9.12 + 9.14 ONLY. Skills 9.15-9.18 can land before, parallel with, or after Session A. Session B (9.21) does not require any of 9.15-9.18 to have shipped.
- Option B: Session A depends on ALL of 9.14-9.18. 5-skill port + docubot both verified before Session A close. Slower but more comprehensive.
- Option C: Skills 9.15-9.18 ship in a separate Task (ID-9 successor) entirely.
Default proposed: Option A. Rationale: tighter Session A scope; faster
Session B close; the 4 cron skills are low-risk (they write to PRs, not
main; failure mode is low-signal PR opening which review-docs-pr catches);
PRODUCT acceptance criteria third 3 only requires each skill to “run at
least once” + emit findings, NOT for Session A close.
Why this is an OQ: Reasonable to insist on the full skill suite live before declaring docubot “verified” — Inv-35 Phase-2 composability is the whole point of the skill set. Liam may prefer Option B for cohesion.
New OQ-PLAN-3 — AGENTS.md vs keep-docs-in-sync content overlap
Section titled “New OQ-PLAN-3 — AGENTS.md vs keep-docs-in-sync content overlap”Question: Per Inv-51 + Inv-52, AGENTS.md has 5 sections (voice + tone,
terminology, frontmatter contract, content-type style guides,
AI-invisibility) and keep-docs-in-sync has 7 sections (IA, palette,
AI-invisibility policy reference, UK English requirements,
documentation-inventory index, commit + PR conventions, single-comment
guardrail). There is overlap on UK English + AI-invisibility.
Three options for handling the overlap:
- Option A (recommended): AGENTS.md is canonical for UK English +
AI-invisibility (the voice + tone surfaces).
keep-docs-in-syncreferences AGENTS.md for those subjects (one sentence “see AGENTS.md §X”) rather than re-stating them.keep-docs-in-syncowns the KH-specific content not in AGENTS.md (IA, palette, doc-inventory, single-comment guardrail, commit conventions). - Option B: Both files re-state UK English + AI-invisibility in full (duplication). Risk: drift over time as one file updates.
- Option C: Move UK English + AI-invisibility to a shared third file both reference. Increases file count.
Default proposed: Option A. Same pattern as PRODUCT OQ-8 ratification
(AGENTS.md complementary to CLAUDE.md, cross-references rather than
duplicates). Cheapest to maintain, preserves AGENTS.md as the Warp-canonical
docs-style oracle, keep-docs-in-sync stays KH-conventions-specific.
Why this is an OQ: Without explicit handling, two Executors authoring 9.9 + 9.10 in parallel could redundantly write the same UK English + AI-invisibility content. The default sets the ownership contract; override is duplicate-and-tolerate or shared-third-file.
Test philosophy alignment
Section titled “Test philosophy alignment”All Subtask testStrategy lines reference docs/reference/test-philosophy.md
discipline transitively: tests verify real behaviour, not mock-internal
state. Per TECH’s Testing-and-validation table, every test colocates with
the TECH § proposing the change. The implementation Subtasks below adopt
the TECH test layout directly — no separate “test scaffolding” Subtask
needed. The shared createMockSupabaseClient() helper applies only where a
test touches Supabase; the docs-site / docubot / skill tests are
filesystem + YAML + grep based and do NOT need it.
Date-sensitive tests (Inv-14 last-updated timestamps) pin time via
vi.spyOn(Date, 'now') per CLAUDE.md test-philosophy gotcha. Workflow-shape
tests parse YAML via js-yaml + assert shape — they do NOT execute the
workflow runtime (that’s CI’s job).
Coverage verification — all 52 PRODUCT invariants mapped transitively
Section titled “Coverage verification — all 52 PRODUCT invariants mapped transitively”Each invariant range maps to one or more implementation Subtasks. Coverage is transitive: the Subtask author implements the spec slice + the test file named in TECH’s Testing-and-validation table.
| Invariant range | Implemented in Subtask(s) | TECH § anchor |
|---|---|---|
Inv-1 (authoring stays in docs/) | 9.6 (sync reads from ../docs) | §2.1 + §2.5 |
| Inv-2 (Vercel default subdomain) | 9.5 (astro.config.mjs site:) | §2.2 + §2.3 |
| Inv-3 (include-by-default + deny-list) | 9.6 (sync-manifest.json shape) | §2.5 |
| Inv-4 (5-space IA sidebar order) | 9.5 (astro.config.mjs sidebar array) | §2.3 |
| Inv-5 (space landing index pages) | 9.5 + 9.6 (sync produces index pages) | §2.3 + §2.5 |
| Inv-6 (cross-space absolute paths) | 9.6 (sync script detect+rewrite) | §2.6 |
| Inv-7 (single-version) | 9.5 (no versions config) | §2.3 |
| Inv-8 (Pagefind 5-space search) | 9.5 (Starlight default) | §2.3 |
| Inv-9 (keyboard / SR / mobile / WCAG / callouts) | 9.5 (Starlight Aside component) | §2.3 + §2.8 |
| Inv-10 (Warm Meridian palette + dark mode) | 9.7 (warm-meridian.css mirror) | §2.7 |
| Inv-11 (code blocks + tables + callouts) | 9.7 + 9.5 (Starlight Code component) | §2.7 + §2.8 |
| Inv-12 (internal links resolve; broken → build fail) | 9.6 + 9.8 (sync link validator) | §2.5 + §2.9 |
| Inv-13 (edit-on-GitHub link) | 9.5 (editLink.baseUrl) | §2.3 |
| Inv-14 (last-updated DD/MM/YYYY) | 9.5 (lastUpdated: true + format) | §2.3 |
Inv-15 (pure-.md rendering) | 9.5 (default Starlight behaviour) | §2.5 |
| Inv-16 (Zod-validated front matter) | 9.5 (content.config.ts) | §2.4 |
| Inv-17 (empty / loading / error / 404) | 9.5 + 9.8 (Starlight default 404 + axe scan) | §2.9 |
| Inv-18 (docubot PRIMARY) | 9.11 + 9.12 + 9.6 (combined: docubot writes + sync honours flag) | §3 + §3.4 |
| Inv-19 (build-time sync SUPPLEMENTARY) | 9.6 (sync script) | §2.5 |
| Inv-20 (schema-driven scheduled syncs) | 9.15 (sync-source-docs) | §4.4 |
| Inv-21 (search/nav stable across worktrees) | 9.5 (deploy from main) | §2.2 |
| Inv-22 (content removal explicit + tracked) | 9.6 (sync diff + removal report) | §2.5 |
| Inv-23 (AI-invisibility CI guard) | 9.8 (check-ai-invisibility.ts) | §2.10 |
| Inv-24 (UK English) | 9.8 + 9.9 (AGENTS.md enforces; lint deferred) | §2.11 + §6.1 |
| Inv-25 (workflow_dispatch + pull_request:closed + merged==true) | 9.12 (docubot.yml triggers + if filter) | §3.2 |
| Inv-26 (one docs-PR per source-PR merge) | 9.11 (prompt rule) | §3.3 |
| Inv-27 (one comment per run) | 9.11 (prompt rule) | §3.3 |
| Inv-28 (time-to-docs-PR 15min / 30min timeout) | 9.12 (timeout-minutes: 30 in workflow) | §3.2 + §3.7 |
| Inv-29 (KH commit conventions) | 9.11 (prompt rule) | §3.3 |
| Inv-30 (docubot writes to docs-site directly) | 9.11 + 9.6 (prompt rule + sync honour) | §3.3 + §3.4 |
| Inv-31 (loads AGENTS.md + keep-docs-in-sync + inventory) | 9.11 (prompt rule + driver reads files) | §3.3 + §6.3 |
| Inv-32 (Claude Agent SDK integration) | 9.12 (run-agent.ts imports) | §3.5 |
| Inv-33 (secrets contract + ubuntu-latest) | 9.12 (workflow env block) | §3.6 |
| Inv-34 (run artefacts upload on every run) | 9.11 (action.yml upload-artifact if: always()) | §3.1 |
| Inv-35 (Phase-2 composability with review-docs-pr) | 9.14 (review-docs-pr workflow trigger filter) | §4.3 |
| Inv-36 (5 skills port; update-changelog NOT) | 9.13 + 9.14..9.18 (5 skills land; no 6th) | §4.2 |
| Inv-37 (each skill loads AGENTS.md) | 9.13 (run-skill.ts loads it) | §6.3 |
| Inv-38 (review-docs-pr emits review.json) | 9.14 | §4.3 |
| Inv-39 (sync-source-docs three KH source pairs) | 9.15 | §4.4 |
| Inv-40 (missing-docs two-phase + four sub-audits) | 9.16 | §4.5 |
| Inv-41 (check-for-broken-links five error types) | 9.17 | §4.6 |
| Inv-42 (docs-seo-audit 11+ issues + ASK-before-fixing) | 9.18 | §4.7 |
| Inv-43 (canonical workflow shape) | 9.13 + 9.14..9.18 (all share shape) | §4.1 |
| Inv-44 ((a)+(b)+(d) to docubot) | 9.20 (Session A gate verifies via 3 samples) | §5.1 + §5.3 |
Inv-45 (ci.yml regenerate-stats job) | 9.19 | §5.2 |
| Inv-46 (/handoff preserved standalone) | 9.21 (CLAUDE.md atomic edit verifies) | §5.1 |
| Inv-47 (Session A acceptance) | 9.20 | §5.3 |
| Inv-48 (Session B acceptance) | 9.21 | §5.3 |
| Inv-49 (CLAUDE.md atomic update) | 9.21 (same commit as removal) | §5.4 |
| Inv-50 (hard deadline) | 9.21 (Orchestrator enforces) | §5.5 |
| Inv-51 (AGENTS.md 5 sections) | 9.9 | §6.1 |
| Inv-52 (keep-docs-in-sync 7 sections) | 9.10 | §6.2 |
52/52 invariants covered transitively. Acceptance per third-by-third criteria in PRODUCT.md §Acceptance criteria.
Subtask records (TM-shape, ready for task-list.json append)
Section titled “Subtask records (TM-shape, ready for task-list.json append)”The seventeen records below are the implementation Subtasks 9.5-9.21.
Each is a complete TM-shape record ready for the Orchestrator to splice
into docs/reference/task-list.json under ID-9’s subtasks array.
Each details field is load-bearing per workflow-orchestration:
the Executor receiving the brief should NOT need to re-read PRODUCT.md
or TECH.md to start work. The details cites TECH § anchors so an
Executor that wants spec-slice detail can navigate, but the Subtask is
self-sufficient for dispatch.
9.5 — Docs-site scaffold (Astro + Starlight + Vercel + content collection schema)
Section titled “9.5 — Docs-site scaffold (Astro + Starlight + Vercel + content collection schema)”- Implements: TECH §2.1 (sibling
docs-site/directory layout) + §2.2 (Vercel sibling project shape) + §2.3 (astro.config.mjs with Starlight 5-space sidebar, editLink, lastUpdated, Pagefind defaults) + §2.4 (Zod content-collection schema withkh_source/kh_last_verified/kh_docubot_ownedextensions). - PRODUCT invariants covered: Inv-2 (Vercel default subdomain), Inv-4 (5-space IA sidebar order), Inv-7 (single-version), Inv-8 (Pagefind), Inv-9 (keyboard/SR/mobile/WCAG), Inv-13 (edit-on-GitHub), Inv-14 (last-updated), Inv-15 (pure-md), Inv-16 (Zod frontmatter), Inv-17 (404 + empty states), Inv-21 (stable across worktrees).
- Dependencies: none.
- Effort estimate: ~2-3h.
- Acceptance gate:
cd docs-site && bun install && bun run buildsucceeds from a fresh clone; sidebar shows 5 spaces in the order product-functionality → ontology → reference → runbooks → decisions; site field uses<vercel-default-subdomain>placeholder (nodocs.kh.phew.org.ukframing surviving); content.config.ts validates fixture front-matter via Zod; build fails on unknown / malformed frontmatter field per Inv-16; light + dark theme switcher renders. - Test files (NEW):
docs-site/__tests__/astro-config-sidebar.test.ts,docs-site/__tests__/frontmatter-schema.test.ts,docs-site/__tests__/pure-md-render.test.ts,docs-site/__tests__/astro-config-versioning.test.ts,docs-site/__tests__/last-updated.test.ts,docs-site/e2e/edit-link.spec.ts.
9.6 — Sync script + manifest + divergence-flag honour (build-time SUPPLEMENTARY path)
Section titled “9.6 — Sync script + manifest + divergence-flag honour (build-time SUPPLEMENTARY path)”- Implements: TECH §2.5 (sync-content.ts include-by-default + deny-list +
kh_docubot_ownedhonour +--source-rootflag for cross-worktree preview) + §2.6 (cross-space link rewriting absolute-paths-only) + §3.4 (sync script honourskh_docubot_owned: truefront matter — divergence Option A per OQ-T1 ratified default). - PRODUCT invariants covered: Inv-1 (authoring in
docs/), Inv-3 (include-by-default + deny-list), Inv-5 (each space landing index), Inv-6 (cross-space absolute paths), Inv-12 (broken-link build fail), Inv-19 (build-time SUPPLEMENTARY), Inv-22 (content removal explicit + tracked), Inv-30 (Option A divergence handling — sync skipskh_docubot_owned: truepaths). - Dependencies: 9.5.
- Effort estimate: ~2-3h (sync script is the biggest single-file change in this scope-third; LOC budget ~250 per TECH risk row).
- Acceptance gate:
bun run syncagainst../docsproduces a populateddocs-site/src/content/docs/tree with all 5 spaces; deny-list entries do not appear in output; deliberatekh_docubot_owned: truefixture is skipped on sync; deliberate cross-space relative link in fixture is rewritten to absolute path-style URL OR build fails per Inv-12;--source-root ../../knowledge-hub/docsworks against sibling worktree (manual smoke test); removal-tracking: removed source surfaces in sync diff output. - Test files (NEW):
docs-site/__tests__/sync-content.test.ts,docs-site/__tests__/sync-manifest.test.ts,docs-site/__tests__/cross-space-links.test.ts,docs-site/__tests__/removal-tracking.test.ts,docs-site/__tests__/sync-hierarchy.test.ts(verifieskh_docubot_ownedhonour),docs-site/__tests__/build-time-sync.test.ts.
9.7 — Warm Meridian theming + token-drift guard + code/tables/callouts
Section titled “9.7 — Warm Meridian theming + token-drift guard + code/tables/callouts”- Implements: TECH §2.7 (mirror oklch primitives + KH semantic tokens
into
warm-meridian.css; Instrument Sans load; sidebar +--sl-content-width) + §2.8 (Code component + line numbers + copy + language label viaexpressive-code; Aside icon-and-label; table styling). Token-drift guard atdocs-site/scripts/check-token-parity.tsasserts mirrored block matchesapp/globals.csssnapshot. - PRODUCT invariants covered: Inv-10 (Warm Meridian palette + dark mode), Inv-11 (code blocks + tables + callouts at KH quality).
- Dependencies: 9.5.
- Effort estimate: ~1.5-2h.
- Acceptance gate: Light + dark mode renders with Warm Meridian palette
(visual smoke on deployed preview); no default Starlight cobalt-blue
accent surviving; token-drift guard CI script passes against current
app/globals.css; deliberate drift fixture (mutated warm-meridian.css) makes the guard exit non-zero; code blocks show language label + copy button + line numbers; Aside components render with icon + text label per Inv-9; Instrument Sans loaded. - Test files (NEW):
docs-site/__tests__/warm-meridian-tokens.test.ts,docs-site/__tests__/code-block-rendering.test.ts,docs-site/__tests__/callout-icon-label.test.ts.
9.8 — AI-invisibility + UK English CI guards + 404 + empty states
Section titled “9.8 — AI-invisibility + UK English CI guards + 404 + empty states”- Implements: TECH §2.9 (404 page branding + empty sidebar group +
no-match search) + §2.10 (
docs-site/scripts/check-ai-invisibility.tsregex guard with deny-list forai-visibility-policy.mditself) + §2.11 (UK English enforcement via AGENTS.md style guide;retext-britishlint deferred to Follow-up). - PRODUCT invariants covered: Inv-12 (broken-link build fail; tested via deliberate-broken-link fixture), Inv-17 (404 branded + empty states), Inv-23 (AI-invisibility CI guard), Inv-24 (UK English).
- Dependencies: 9.6.
- Effort estimate: ~1-1.5h.
- Acceptance gate: Fixture with “AI-powered” string in body fails build
via
check-ai-invisibility.tsexit non-zero; deny-list path (docs-site/src/content/docs/reference/ai-visibility-policy.md) passes; deliberate broken internal link in fixture fails Starlight build; 404 page renders branded with search + home link (E2E smoke); empty sidebar group does not render an empty header (Starlight default verified). - Test files (NEW):
docs-site/__tests__/ai-invisibility-guard.test.ts,docs-site/__tests__/uk-english.test.ts(placeholder; lint deferred),docs-site/__tests__/link-validator.test.ts,docs-site/e2e/404-page.spec.ts.
9.9 — AGENTS.md at repo root (5-section style guide)
Section titled “9.9 — AGENTS.md at repo root (5-section style guide)”- Implements: TECH §6.1 (AGENTS.md at repo root, sibling to CLAUDE.md, cross-references CLAUDE.md for project-wide rules per OQ-8 Option A ratified default).
- PRODUCT invariants covered: Inv-51 (AGENTS.md 5 content sections).
- Dependencies: none (foundation; can run in parallel with 9.5-9.8).
- Effort estimate: ~1.5-2h.
- Acceptance gate:
AGENTS.mdexists at repo root; contains 5 numbered sections per Inv-51:- Voice + tone rules (UK English, professional-direct, no marketing copy, no emoji).
- Terminology table (Knowledge Hub vs “the platform” vs “the app”; “Change Reports” vs “Digest”; canonical taxonomy terms; “docubot” vs Claude vs the SDK).
- Frontmatter contract (matching Zod schema in TECH §2.4).
- Content-type style guides (concept / procedural / reference / troubleshooting).
- AI-invisibility rules (per Inv-23 +
docs/reference/ai-visibility-policy.md). Section opener cross-references CLAUDE.md: “For project-wide conventions, see CLAUDE.md. This file adds docs-corpus-specific conventions on top.”
- Test files (NEW):
__tests__/agents-md/agents-md-shape.test.ts(asserts all 5 sections present with the canonical section titles).
9.10 — keep-docs-in-sync skill at .claude/skills/keep-docs-in-sync/SKILL.md
Section titled “9.10 — keep-docs-in-sync skill at .claude/skills/keep-docs-in-sync/SKILL.md”- Implements: TECH §6.2 (keep-docs-in-sync skill with 7 content sections per Inv-52; cross-references AGENTS.md for UK English + AI-invisibility subjects per OQ-PLAN-3 Option A default).
- PRODUCT invariants covered: Inv-52 (keep-docs-in-sync 7 content sections).
- Dependencies: 9.9.
- Effort estimate: ~1.5h.
- Acceptance gate:
.claude/skills/keep-docs-in-sync/SKILL.mdexists; contains 7 sections per Inv-52:- KH
docs/IA conventions (5-space layout + cross-space absolute-path rule). - Warm Meridian palette + typography references (link to
docs/design/warm-meridian-implementation-spec.md). - AI-invisibility policy reference (link to AGENTS.md §5 +
docs/reference/ai-visibility-policy.md). - UK English requirements (cross-reference AGENTS.md §1).
docs/reference/documentation-inventory.mdindex (so docubot does not recreate existing docs).- Commit + PR conventions (matching
commit-commands:commit-push-pr). - Single-comment guardrail (matching Warp’s pattern + Inv-27).
Skill frontmatter includes proper
name:+description:per skill schema; body remains under ~250 LOC.
- KH
- Test files (NEW):
__tests__/skills/keep-docs-in-sync-shape.test.ts(asserts SKILL.md contains all 7 sections; frontmatter shape valid).
9.11 — Docubot composite action + KH-persona prompt template + secrets contract
Section titled “9.11 — Docubot composite action + KH-persona prompt template + secrets contract”- Implements: TECH §3.1 (
.github/actions/docubot/action.ymlcomposite action with checkout / setup-bun / install / gather-pr-context / render-prompt / run-agent / upload-artifact steps) + §3.3 (KH-persona prompt template at.github/actions/docubot/prompt.txt— verbatim shape per TECH §3.3 embedded text body) + §3.6 (secrets contract: ANTHROPIC_API_KEY + GITHUB_TOKEN; runs-on ubuntu-latest). - PRODUCT invariants covered: Inv-26 (one docs-PR per merge — prompt
rule), Inv-27 (one comment per run — prompt rule), Inv-29 (KH commit
conventions — prompt rule), Inv-30 (docubot writes to docs-site directly
kh_docubot_owned: truefrontmatter — prompt rule per OQ-T1 ratified default), Inv-31 (loads AGENTS.md + keep-docs-in-sync + documentation-inventory — prompt rule), Inv-33 (secrets contract + ubuntu-latest), Inv-34 (upload-artifact if: always()).
- Dependencies: 9.9, 9.10.
- Effort estimate: ~2h (prompt template body is ~89 lines of text; the action.yml itself is ~50 lines).
- Acceptance gate:
.github/actions/docubot/action.ymlexists with the six composite steps per TECH §3.1;.github/actions/docubot/prompt.txtcontains the KH-persona body verbatim per TECH §3.3 (no Warp persona surviving; nowarpdotdev/gitbookreferences; Vercel default subdomain framing);upload-artifact@v4step hasif: always()per Inv-34; shape-test on action.yml passes. - Test files (NEW):
__tests__/workflows/docubot-action-shape.test.ts(parse YAML; assert composite steps +if: always()on upload),__tests__/actions/docubot-prompt-shape.test.ts(grep prompt.txt for the six required rule sections: persona / scope / divergence flag / style / commit-conventions / output-instructions).
9.12 — Docubot workflow + Claude Agent SDK driver
Section titled “9.12 — Docubot workflow + Claude Agent SDK driver”- Implements: TECH §3.2 (
.github/workflows/docubot.ymlwith workflow_dispatch + pull_request.types:[closed] + merged==true filter + timeout-minutes:30 + composite-action invocation) + §3.5 (scripts/docubot/run-agent.tsdriver: imports@anthropic-ai/claude-agent-sdk, reads AGENTS.md + keep-docs-in-sync into prompt context, invokes Agent with cwd=GITHUB_WORKSPACE) + §3.7 (time-to-docs-PR observability via timeout-minutes:30; soft target 15min). - PRODUCT invariants covered: Inv-25 (trigger surface), Inv-28 (timeout-minutes:30; 15min soft target), Inv-32 (Claude Agent SDK integration), Inv-33 (runs-on ubuntu-latest verified in workflow).
- Dependencies: 9.11.
- Effort estimate: ~2h (SDK driver is ~80-120 LOC; workflow YAML is ~50 lines).
- Acceptance gate:
.github/workflows/docubot.ymlexists with both triggers (workflow_dispatch+pull_request.types: [closed]) + the job-levelif:containingmerged == true;runs-on: ubuntu-latest;timeout-minutes: 30; permissions block grantscontents: write+pull-requests: write+issues: write;scripts/docubot/run-agent.tsexists; imports from@anthropic-ai/claude-agent-sdkdirectly (no barrel re-export); reads AGENTS.md + keep-docs-in-sync viafs.readFile; invokes Agent with cwd=$GITHUB_WORKSPACE; SDK version pinned inpackage.jsondevDependencies. - Test files (NEW):
__tests__/workflows/docubot-workflow-shape.test.ts(parse YAML; assert triggers + merged-filter + timeout + permissions),__tests__/scripts/docubot-prompt-loading.test.ts(grep run-agent.ts for AGENTS.md + keep-docs-in-sync references),__tests__/dependencies/claude-agent-sdk.test.ts(assert SDK package in devDependencies; assert direct import in run-agent.ts).
9.13 — 5-skill canonical workflow scaffold + shared driver
Section titled “9.13 — 5-skill canonical workflow scaffold + shared driver”- Implements: TECH §4.1 (canonical workflow shape at
.github/workflows/<skill-name>.ymlper Inv-43 lock; ONE template shared by all 5 skills) + §4.2 (skill set scope: 5 skills port;update-changelogNOT ported per OQ-3 OVERRIDE) + shared driver scriptscripts/skills/run-skill.ts(~100 LOC; —skill + —skill-md flags; loads AGENTS.md + keep-docs-in-sync + per-skill SKILL.md + per-skill references/*.md; invokes Claude Agent SDK identical to run-agent.ts shape). - PRODUCT invariants covered: Inv-36 (5 skills port; update-changelog NOT), Inv-37 (each skill loads AGENTS.md — verified via run-skill.ts reads), Inv-43 (canonical workflow shape).
- Dependencies: 9.9, 9.10, 9.11.
- Effort estimate: ~1.5-2h (driver is parameterised version of run-agent.ts; workflow template lifts from docubot.yml).
- Acceptance gate:
scripts/skills/run-skill.tsexists; reads AGENTS.md + keep-docs-in-sync + per-skill SKILL.md by--skill-mdarg; invokes Claude Agent SDK; placeholder.github/workflows/files for all 5 skills exist with the canonical workflow shape per §4.1 (workflow_dispatch- optional schedule + the shared driver invocation); none of the 5 skill
SKILL.md bodies exist yet (those land in 9.14-9.18);
update-changelogworkflow / skill NOT present.
- optional schedule + the shared driver invocation); none of the 5 skill
SKILL.md bodies exist yet (those land in 9.14-9.18);
- Test files (NEW):
__tests__/scripts/run-skill-loading.test.ts(grep run-skill.ts for AGENTS.md + keep-docs-in-sync references),__tests__/workflows/skill-workflow-shape.test.ts(parse all 5 workflow YAMLs; assert canonical shape match per §4.1),__tests__/skills/skill-inventory.test.ts(assert 5 skill directories exist post-9.14-9.18; assert noupdate-changelog/directory).
9.14 — review-docs-pr skill body + workflow
Section titled “9.14 — review-docs-pr skill body + workflow”- Implements: TECH §4.3 (
review-docs-prSKILL.md body adapted from Warp’s review-docs-pr; trigger overridepull_request_reviewfor docubot-opened docs PRs; emitsreview.jsonwith summary + comments[] schema; severity prefixes[CRITICAL]/[IMPORTANT]/[SUGGESTION]/[NIT]without emoji per KH no-emoji rule; comments posted viagh pr comment). - PRODUCT invariants covered: Inv-35 (Phase-2 composability — review-docs-pr runs against docubot-opened PRs), Inv-38 (review-docs-pr contract).
- Dependencies: 9.13.
- Effort estimate: ~1.5-2h (skill body ~150 LOC; workflow inherits from §4.1 template; trigger override adds ~10 lines to workflow YAML).
- Acceptance gate:
.claude/skills/review-docs-pr/SKILL.mdexists with Warp-template body adapted to KH (UK English, no emoji);.github/workflows/review-docs-pr.ymlexists with canonical shape +pull_request_reviewtrigger override; job’sif:filters head-branch matchingdocubot/*OR base-branch main with title startingDocs:; output contract forreview.jsondefined in SKILL.md; severity labels use prefix not emoji. - Test files (NEW):
__tests__/skills/review-docs-pr.test.ts(fixture: sample PR diff → assert review.json emitted with summary + comments[]; assert no emoji in comment bodies; assert severity prefix format).
9.15 — sync-source-docs skill body + workflow
Section titled “9.15 — sync-source-docs skill body + workflow”- Implements: TECH §4.4 (
sync-source-docs— KH-renamed from Warp’ssync-error-docs; three KH source pairs: schema/schema-quick-reference.md, MCP registrations/mcp-inventory.md, route definitions/api-routes.md— third is NEW page authored on first run; weekly Monday 06:00 UTC cron per OQ-T2 ratified default; opens docs-PR per detected drift; marks output filekh_docubot_owned: true). - PRODUCT invariants covered: Inv-20 (schema-driven SUPPLEMENTARY for code-generated content), Inv-39 (sync-source-docs three KH source pairs).
- Dependencies: 9.13.
- Effort estimate: ~2h (skill body + 3-pair drift detection logic;
third pair
api-routes.mdis NEW page, needs first-creation flow). - Acceptance gate:
.claude/skills/sync-source-docs/SKILL.mdexists with three KH source pairs documented;.github/workflows/sync-source-docs.ymlexists with canonical shape +schedule: cron '0 6 * * 1'enabled per OQ-T2; fixture run against each source pair detects drift + emits docs-PR draft; first-creation flow forapi-routes.mddocumented. - Test files (NEW):
__tests__/skills/sync-source-docs.test.ts(fixture per source pair: drift detected → docs-PR opens withkh_docubot_owned: truefrontmatter on rewritten file).
9.16 — missing-docs skill body + Python audit script + workflow
Section titled “9.16 — missing-docs skill body + Python audit script + workflow”- Implements: TECH §4.5 (
missing-docstwo-phase audit + draft; Phase 1audit_docs.pywith four sub-audits: env vars, CLI commands, MCP/route surfaces, terminology staleness; Phase 2 readskh_surface_map.mdfor draft;workflow_dispatchonly at foundation, Phase 2 may add monthly cron later). - PRODUCT invariants covered: Inv-40 (missing-docs two-phase + four sub-audits).
- Dependencies: 9.13.
- Effort estimate: ~2-3h (Python audit script with 4 sub-audits is the largest LOC contributor among the 5 skills; pre-identified split point if mid-flight scope blows up: 9.22-9.25 sub-slice the 4 sub-audits).
- Acceptance gate:
.claude/skills/missing-docs/SKILL.mdexists with two-phase contract;.claude/skills/missing-docs/scripts/audit_docs.pyexists with 4 sub-audit entrypoints (env-vars / cli-commands / mcp-routes / terminology);.claude/skills/missing-docs/references/stale_terms.mdkh_surface_map.mdexist;.github/workflows/missing-docs.ymlexists with canonical shape +workflow_dispatchonly (no schedule cron at foundation per OQ-T2; Phase 2 schedule is FU).
- Test files (NEW):
__tests__/skills/missing-docs-audit.test.ts(per sub-audit fixture: deliberate-gap detected → reported in audit output).
9.17 — check-for-broken-links skill body + Python link-walker + workflow
Section titled “9.17 — check-for-broken-links skill body + Python link-walker + workflow”- Implements: TECH §4.6 (
check-for-broken-linksPython link-walker; five error types: file-not-found / case-mismatch / missing-mdx-ext / cross-space-relative / external-4xx-or-timeout; daily 05:00 UTC cron per OQ-T2; invoked from inside review-docs-pr per Warp pattern;--gh-pr-commentflag replaces Warp’s--slack-notify). - PRODUCT invariants covered: Inv-41 (check-for-broken-links 5 error
types +
--gh-pr-commentmode). - Dependencies: 9.13.
- Effort estimate: ~2h.
- Acceptance gate:
.claude/skills/check-for-broken-links/SKILL.mdexists;.claude/skills/check-for-broken-links/scripts/check_links.pyexists with 5 error-type detection;.github/workflows/check-for-broken-links.ymlexists with canonical shape +schedule: cron '0 5 * * *'enabled per OQ-T2;--gh-pr-commentflag posts findings viagh pr comment. - Test files (NEW):
__tests__/skills/check-for-broken-links.test.ts(per error-type fixture: deliberate-broken-link detected;--gh-pr-commentmode mocksgh pr commentinvocation).
9.18 — docs-seo-audit skill body + Python audit + workflow (cron commented per OQ-T3)
Section titled “9.18 — docs-seo-audit skill body + Python audit + workflow (cron commented per OQ-T3)”- Implements: TECH §4.7 (
docs-seo-auditPython SEO audit; 11+ issue types across 3 severity tiers; ASK-before-fixing guardrail preserved verbatim from Warp; monthly 1st 07:00 UTC cron — but per OQ-T3 ratified default, workflow file committed withschedule:block COMMENTED OUT at foundation; a Follow-up commit uncomments post first-deploy when sitemap exists). - PRODUCT invariants covered: Inv-42 (docs-seo-audit 11+ issues + 3 tiers + ASK-before-fixing).
- Dependencies: 9.13.
- Effort estimate: ~2h.
- Acceptance gate:
.claude/skills/docs-seo-audit/SKILL.mdexists with ASK-before-fixing rule preserved verbatim;.claude/skills/docs-seo-audit/scripts/audit_seo.pyexists;.claude/skills/docs-seo-audit/references/seo_issues.mdenumerates 11+ issue types across 3 severity tiers;.github/workflows/docs-seo-audit.ymlexists with canonical shape +workflow_dispatchtrigger +schedule:block PRESENT BUT COMMENTED OUT per OQ-T3 (comment explicitly cites OQ-T3 + Follow-up commit expectation). - Test files (NEW):
__tests__/skills/docs-seo-audit.test.ts(fixture sitemap → per-issue detection; SKILL.md grep assert “ASK before fixing” rule present),__tests__/workflows/docs-seo-audit-cron.test.ts(assert schedule: block exists in YAML AND is commented per OQ-T3).
9.19 — ci.yml regenerate-stats job (independent decommission glue)
Section titled “9.19 — ci.yml regenerate-stats job (independent decommission glue)”- Implements: TECH §5.2 (new
regenerate-statsjob appended to.github/workflows/ci.yml; triggers onpush: mainonly; runsbun run stats+bun run generate:mcp-inventory; direct-commit per OQ-6 Option A with side-PR fallback if branch protection blocks thegithub-actions[bot]push;[skip ci]commit suffix prevents infinite CI loop). - PRODUCT invariants covered: Inv-45 ((c) function moves to ci.yml).
- Dependencies: none (independent ci.yml edit; can land any time after 9.5 stabilises).
- Effort estimate: ~1h.
- Acceptance gate:
regenerate-statsjob exists in.github/workflows/ci.ymlwith the seven steps per TECH §5.2 (checkout + setup-bun + install + run stats + check-for-changes + commit-or-side-PR);if: github.event_name == 'push' && github.ref == 'refs/heads/main'; commit message contains[skip ci]; first run on push:main produces a commit OR side-PR with regenerateddocs/generated/files. - Test files (NEW):
__tests__/workflows/ci-regenerate-stats.test.ts(parse ci.yml; assertregenerate-statsjob + push:main filter + bun run stats + bun run generate:mcp-inventory + direct-commit-with-side-PR-fallback shape + [skip ci] suffix).
9.20 — Session A decommission verification gate
Section titled “9.20 — Session A decommission verification gate”- Implements: TECH §5.3 Session A (gate 1) acceptance verification:
docubot opens at least 3 sample docs-PRs on source-PR merges (synthetic
via
workflow_dispatchagainst 3 historical PR numbers per OQ-PLAN-1 default); all 3 narrative-doc updates ((a)+(b)+(d) workloads) execute correctly (Liam manual review); docubot’s single-comment + commit-conventions hold across all 3 samples. - PRODUCT invariants covered: Inv-44 ((a)+(b)+(d) move to docubot — verified by 3 sample runs), Inv-47 (Session A acceptance).
- Dependencies: 9.12 (docubot live + functional), 9.14 (review-docs-pr live for Inv-35 Phase-2 composability requirement).
- Effort estimate: ~1.5h (verification, not implementation; manual Liam review of 3 sample docubot PRs + Checker grep of single-comment guardrail across 3 runs).
- Acceptance gate: 3 sample docubot PRs opened via
workflow_dispatchagainst 3 historical source-PR numbers (per OQ-PLAN-1 synthetic default); each PR has exactly ONE source-PR comment (single-comment guardrail verified); each PR title matchesDocs: <summary> (from #<N>); each commit message matchesdocs(<area>): <summary>; each branch matchesdocubot/<slug>; manual Liam review verifies (a)+(b)+(d) workload faithfulness on the 3 samples; review-docs-pr workflow ran against each of the 3 docubot-opened PRs and emittedreview.json. - Test files (NEW):
__tests__/decommission/session-a-acceptance.test.ts(assert 3 docubot PRs exist in repo with the expected branch/title/commit shapes; for each, assert exactly-one comment on source PR; assert review-docs-pr workflow ran). Liam manual review captured in Subtask<info added on ...>journal block.
9.21 — Session B atomic decommission: ci.yml verified + remove update-docs + CLAUDE.md atomic edit
Section titled “9.21 — Session B atomic decommission: ci.yml verified + remove update-docs + CLAUDE.md atomic edit”- Implements: TECH §5.3 Session B (gate 2) + §5.4 (CLAUDE.md atomic
update — same commit as
.claude/skills/update-docs/removal) + §5.5 (hard deadline forcing function per Inv-50). - PRODUCT invariants covered: Inv-46 (/handoff preserved standalone), Inv-48 (Session B acceptance: ci.yml regenerate-stats runs + update-docs removed + callers updated), Inv-49 (CLAUDE.md atomic update — same commit), Inv-50 (hard deadline).
- Dependencies: 9.19 (regenerate-stats job verified live), 9.20 (Session A gate closed).
- Effort estimate: ~1.5h.
- Acceptance gate:
.claude/skills/update-docs/directory removed in same commit as CLAUDE.md edit; commit diff shows BOTH the directory deletion AND the CLAUDE.md edits in ONE atomic git operation (verifies Inv-49); CLAUDE.md’s/update-docsreferences replaced with docubot +keep-docs-in-syncreferences in Implementation Workflow section + any reference-doc tables that cited it;/handoffpreserved as standalone skill (not removed); regenerate-stats job has run successfully on at least one merge-to-main commit (verified by ci.yml run history + a resultingdocs/generated/commit on main); grep.claude/for stale/update-docsreferences returns zero hits (except in deletion-comment lines). - Test files (NEW):
__tests__/decommission/update-docs-removed.test.ts(assert.claude/skills/update-docs/does NOT exist; grep.claude/for/update-docsreturns zero stale hits; grep CLAUDE.md forupdate-docsreturns zero references; grep CLAUDE.md fordocubot+keep-docs-in-syncreturns the expected references),__tests__/skills/handoff-preserved.test.ts(assert.claude/skills/handoff/SKILL.mdexists post-removal).
Risks specific to this PLAN’s decomposition
Section titled “Risks specific to this PLAN’s decomposition”| Risk | Impact | Mitigation |
|---|---|---|
| 9.5 scaffold underestimates Astro+Starlight+Vercel integration friction (Vercel default subdomain TBC could block first deploy) | Medium | Subdomain string deferred to first-deploy; <vercel-default-subdomain> placeholder used in astro.config.mjs. Liam confirms subdomain at 9.20 verification gate (or earlier, opportunistic). 9.5 ships without the live URL — verified at staging preview. |
| 9.6 sync script grows beyond 250 LOC budget | Medium | TECH §Risks names the 250 LOC budget; if mid-flight scope creep surfaces, Executor escalates and Orchestrator may split into 9.6a (manifest + walk) + 9.6b (link rewriting + diff). |
| 9.11 prompt template body too long to embed in 9.11 Subtask details verbatim | Low | The full prompt body is in TECH §3.3 — Executor reads TECH for the verbatim content. 9.11’s details cite TECH §3.3 explicitly and require the Executor to copy the body into prompt.txt without rewording. |
9.13 + 9.14-9.18 5-skill parallel-wave merge conflicts (each skill touches .github/workflows/ + scripts/skills/run-skill.ts) | Medium | All 5 skill workflows are NEW files (distinct paths) — no merge conflict on workflow YAMLs. scripts/skills/run-skill.ts is ONE file authored at 9.13; 9.14-9.18 do not modify it (they consume it via --skill flag). Cherry-pick sequence: 9.13 first, then 9.14-9.18 in any order. |
| 9.16 missing-docs Python audit script exceeds 2-3h estimate | High | Pre-identified split point. If mid-flight, Orchestrator adds 9.22+9.23+9.24+9.25 sub-slicing the 4 sub-audits (env-vars / CLI / MCP-routes / terminology). Stays within 25 ceiling at 25 exactly. |
9.20 Session A gate fails because synthetic workflow_dispatch doesn’t match real PR-merge load (per OQ-PLAN-1 default) | Low | If synthetic is insufficient, Liam overrides OQ-PLAN-1 default → Session A waits for organic PR merges. This delays Session B but doesn’t break the workflow. |
| 9.21 CLAUDE.md atomic edit accidentally drops MemPalace section reference | Low | Pre-edit grep of CLAUDE.md for /update-docs mentions + careful per-occurrence replace. Test update-docs-removed.test.ts checks for stale hits post-removal. |
| Hook propagation discipline failure on parallel sub-agent dispatch (CLAUDE.md ID-19.4) | High | Pre-dispatch check `git show origin/main:.claude/settings.json |
| Brief-authoring discipline failure (sibling-worktree absolute paths in dispatch text) | Medium | This PLAN.md follows the discipline (relative paths only, no sibling-worktree absolute paths). Orchestrator must preserve discipline when composing dispatch briefs from these Subtask details fields. |
| docubot direct-write divergence handling regression (OQ-T1 front-matter flag interaction with sync script) | Medium | 9.6 sync script unit test (sync-hierarchy.test.ts) asserts kh_docubot_owned: true paths are skipped on sync. 9.11 docubot prompt enforces flag-set on every docubot write. Both invariants tested independently before 9.20 verification. |
Notes for Orchestrator dispatch
Section titled “Notes for Orchestrator dispatch”- Worktree-parallelizable pairs (per TECH §Parallelization + PLAN
refinement):
- Phase 1 sub-parallel: 9.6 + 9.7 (sync + theming) after 9.5 lands.
They touch disjoint files (
docs-site/scripts/sync-content.ts+docs-site/sync-manifest.jsonvsdocs-site/src/styles/warm-meridian.cssdocs-site/scripts/check-token-parity.ts).
- Phase 1 ↔ Phase 2 parallel: 9.9 (AGENTS.md) is independent of all of 9.5-9.8 — can dispatch alongside any Phase 1 worker. 9.10 chains on 9.9.
- Phase 3 ↔ 9.19 parallel: 9.19 (
ci.ymlregenerate-stats) is an independent.github/workflows/ci.ymledit; can dispatch in parallel with 9.11+9.12 (docubot). - Phase 4 wide-parallel: 9.14-9.18 all parallelize after 9.13. Each
touches a distinct
.claude/skills/<skill-name>/subdirectory plus a distinct.github/workflows/<skill-name>.ymlfile. Cherry-pick wave = 9.13 first, then 9.14-9.18 in any order, then 9.19 (if not already landed).
- Phase 1 sub-parallel: 9.6 + 9.7 (sync + theming) after 9.5 lands.
They touch disjoint files (
- Sub-agent worktree heritage gotcha (per CLAUDE.md ID-19.4): Before
EACH
isolation: "worktree"dispatch, the Orchestrator MUST rungit show origin/main:.claude/settings.json | grep -c "Tier 2.2 hook (ID-19.3)"and verify the count is ≥1. The Tier 2.2 hook is on production-readiness at the time of this PLAN authoring; if main has not yet received the hook propagation, the Orchestrator MUST merge/cherry-pick to main BEFORE dispatching any Phase-1+ Subtask. - Brief-authoring discipline: When composing dispatch briefs from the
Subtask
detailsfields below, the Orchestrator MUST use relative paths only. The only absolute path acceptable is the worker’s own worktree path. NEVER mention sibling-worktree absolute paths likeknowledge-hub-production-readiness/orknowledge-hub/in dispatch text — primer effect causes the sub-agent’s Write tool to autocomplete the wrong path. The Tier 2.2 hook is the backstop; brief-authoring discipline is the cheapest defense layer. - OQ-T1 / OQ-T2 / OQ-T3 ratifications applied throughout: Where any
Subtask
detailsfield reaches into these decision spaces, the ratified default is cited inline. Executor proceeds against the default unless Liam overrides. Nodetailsfield re-derives a ratified decision. - No
mcp__task-master-ai__*invocations. KH adopts the TM JSON shape (§7 of the canonical SDLC doc) but NOT the TM tool. The Orchestrator splices Subtask records intodocs/reference/task-list.jsonvia surgical Edit (perworkflow-orchestrationPromote mode pattern — never round-trip JSON.parse/stringify). - Cherry-pick (not merge) parallel branches per CLAUDE.md “Worktree
isolation rules” — agents branched from main at launch time; earlier
merges make later agents stale. Sequential cherry-pick onto
production-readinesstrack branch +bun run testafter each. - Knip baseline check after Phase 4 lands: the 5 new
.claude/skills/<name>/SKILL.mdfiles +scripts/skills/run-skill.ts.github/workflows/<name>.ymlfiles will register against Knip. Add.claude/skills/**+.github/workflows/**to Knip’s ignore list at end-of-task if not already present (per TECH §Risks row 12).
Stop-criterion for this PLAN
Section titled “Stop-criterion for this PLAN”This PLAN ships when:
- All seventeen Subtask records below are populated with sibling-only deps
- load-bearing
detailsfields + concretetestStrategylines + test file names per TECH Testing-and-validation table.
- load-bearing
- 52/52 PRODUCT invariants transitively covered (verified under §Coverage verification).
- 25-Subtask soft ceiling respected (21 total Subtasks; reserved buffer for 9.22-9.25 if 9.16 missing-docs sub-slices).
- 3 new PLAN-level OQs (OQ-PLAN-1/2/3) surfaced with defaults — within the workflow ≤3 ceiling.
- Sibling-only dependency constraint honoured (forcing-function escalation tripwire NOT hit).
- Worktree-first-action gate + brief-authoring discipline applied to every
Subtask
detailsfield.
{9.4} close-out moves status: pending → in_progress (by this Planner)
→ done (by Checker post-ratification + Orchestrator promotion).
End of PLAN spec {9.4} for Task ID-9.