From 16be02c6f14e98f114810a29051d0f81304a5aeb Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Thu, 1 Oct 2026 08:59:26 +0200 Subject: [PATCH] docs(11.1-07): complete the fail-closed checkers plan --- .planning/ROADMAP.md | 6 +- .planning/STATE.md | 31 +-- .../11.1-07-SUMMARY.md | 209 ++++++++++++++++++ 3 files changed, 230 insertions(+), 16 deletions(-) create mode 100644 .planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-07-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 24fad4c..b24cf44 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -544,7 +544,7 @@ Plans: 4. Every Go example in a `docs/` page is compiled and run by `go test ./...` (Go code in ingested module READMEs is identifier-checked, not compiled — D-18). An identifier checker and an internal link/anchor checker also run there and fail on stale names or broken links. 5. A "Coming from WinterCMS" concept map and an `acme/blog` porting walkthrough exist, and the walkthrough's code is verified under criterion 4. -**Plans:** 6/7 plans executed +**Plans:** 7/7 plans executed Plans: **Wave 1** @@ -566,7 +566,7 @@ Plans: - [x] 11.1-06-PLAN.md — Unit tests last: planted-violation fixtures, internal/docsite coverage, SC1-SC5 acceptance, final gate, validated VALIDATION.md **Wave 7** *(gap closure, blocked on Wave 6 completion)* -- [ ] 11.1-07-PLAN.md — Checkers fail closed: AST fence discovery (nested and README src= refused, captions only on verified fences, Go-lexer aliases need src=), go test roots and go/build membership for src= targets, `go doc -c`, env/flag/go run/bin command forms; planted fixtures and unit tests for every hole +- [x] 11.1-07-PLAN.md — Checkers fail closed: AST fence discovery (nested and README src= refused, captions only on verified fences, Go-lexer aliases need src=), go test roots and go/build membership for src= targets, `go doc -c`, env/flag/go run/bin command forms; planted fixtures and unit tests for every hole ### Phase 11.2: Ready to share: summercms.io website and newsletter plugin (INSERTED) @@ -677,7 +677,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → | 9. Backend admin authentication and schema pipeline | 12/12 | In Progress| | | 10. Admin Vue SPA | 5/5 | Complete | 2026-09-27 | | 11. Jobs, realtime and search infrastructure | 8/8 | In Progress| | -| 11.1. SummerCMS documentation for humans and AI agents | 6/7 | In Progress| | +| 11.1. SummerCMS documentation for humans and AI agents | 7/7 | In Progress| | | 11.2. Ready to share: summercms.io website and newsletter plugin | 0/TBD | Not started | - | | 12. Płytarium API — Collections and Albums | 0/TBD | Not started | - | | 13. Płytarium API — wishlist, notifications, CSV, credentials, public routes | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 1a243d0..fbbc4f3 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,18 +2,18 @@ gsd_state_version: "1.0" milestone: v1.0 current_phase: "11.1" -current_phase_name: summercms-documentation-for-humans-and-ai-agents -status: executing -stopped_at: Completed 11.1-06-PLAN.md -last_updated: "2026-09-30T23:52:47.764Z" -last_activity: 2026-09-30 +current_phase_name: SummerCMS documentation for humans and AI agents (INSERTED) +status: verifying +stopped_at: Completed 11.1-07-PLAN.md +last_updated: "2026-10-01T06:58:29.387Z" +last_activity: 2026-10-01 last_activity_desc: Phase 11.1 execution started -state_head: 209e44cfd7d44e1f2081f10f0321b38e77e50d46 +state_head: ce5dcec7e4e0733b07676b36abb26188d7150501 progress: total_phases: 19 completed_phases: 9 total_plans: 93 - completed_plans: 92 + completed_plans: 93 milestone_name: milestone --- @@ -28,10 +28,10 @@ See: .planning/PROJECT.md (updated 2026-09-16) ## Current Position -Phase: 11.1 (summercms-documentation-for-humans-and-ai-agents) — READY TO EXECUTE -Plan: 6 of 6 -Status: Ready to execute -Last activity: 2026-09-30 — Phase 11.1 execution started +Phase: 11.1 (SummerCMS documentation for humans and AI agents (INSERTED)) — EXECUTING +Plan: 7 of 7 +Status: Phase complete — ready for verification +Last activity: 2026-10-01 — Phase 11.1 execution started Progress: [██████░░░░] 60% @@ -147,6 +147,7 @@ Progress: [██████░░░░] 60% | Phase 11.1 P04 | 47min | 3 tasks | 68 files | | Phase 11.1 P05 | 18min | 3 tasks | 37 files | | Phase 11.1 P06 | 29min | 3 tasks | 168 files | +| Phase 11.1 P07 | 33 min | 5 tasks | 64 files | ## Accumulated Context @@ -409,6 +410,10 @@ Recent decisions affecting current work: - [Phase 11.1]: 11.1-06: violation cases are overlays on testdata/clean with a want.txt naming the one problem each plant must produce - [Phase 11.1]: 11.1-06: check-phase11.1.sh --named requires every named test to PASS; module TestDocs* and output Examples are derived from source - [Phase 11.1]: 11.1-06: CRLF and BOM docs pages stay refused, with a message naming the encoding +- [Phase 11.1]: A src= fence that is not a top-level block of a docs page is refused and docs:sync does not rewrite it. +- [Phase 11.1]: Module README src= fences are refused and never captioned; Go fences without src= in a README stay legal. +- [Phase 11.1]: The identifier fallback runs go doc -c, so a span must match the declaration's case. +- [Phase 11.1]: Shell command words follow cobra stripFlags and include env prefixes, go run ./cmd/summer and bin/{app}. ### Pending Todos @@ -439,6 +444,6 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-09-30T22:17:57.872Z -Stopped at: Completed 11.1-06-PLAN.md +Last session: 2026-10-01T06:53:41.688Z +Stopped at: Completed 11.1-07-PLAN.md Resume file: None diff --git a/.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-07-SUMMARY.md b/.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-07-SUMMARY.md new file mode 100644 index 0000000..a0e4604 --- /dev/null +++ b/.planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-07-SUMMARY.md @@ -0,0 +1,209 @@ +--- +phase: 11.1-summercms-documentation-for-humans-and-ai-agents +plan: 07 +subsystem: docs +tags: [docsite, goldmark, go-doc, chroma, snippets] + +requires: + - phase: 11.1-06 + provides: planted-violation corpus, docs:build --check, and the phase 11.1 gate +provides: + - AST fence discovery shared by the snippet, policy, and command checkers + - Refusal of nested src= fences and of src= fences in module READMEs + - Proof that a .go src= target is in the default build and reached from a Test or an Example with output + - Case-sensitive go doc fallback and cobra-style command words +affects: [11.1 verification, README src= follow-up] + +actuals: + tokens: 22900 + tasks: 5 + commits: 6 +plan_head_before: d9f187ae39d174d813309a7e9adc8ddc3cc7fe10 +plan_head_after: ce5dcec7e4e0733b07676b36abb26188d7150501 + +tech-stack: + added: [] + patterns: + - "Checkers walk the goldmark AST from newMarkdown, the same parse the renderer uses" + - "build.ImportDir on build.Default decides which .go files go test ./... compiles" + - "commandWord mirrors cobra stripFlags for a root whose only bool flag is --help/-h" + +key-files: + created: + - internal/docsite/fences.go + - internal/docsite/fences_test.go + modified: + - internal/docsite/snippet.go + - internal/docsite/check_policy.go + - internal/docsite/check_commands.go + - internal/docsite/check_identifiers.go + - internal/docsite/render.go + - cmd/summer/phase11_1_acceptance_test.go + - scripts/check-phase11.1.sh + +key-decisions: + - "A src= fence that is not a top-level block of a docs page is refused, and docs:sync does not rewrite it." + - "Module README src= fences are refused and never captioned; a Go fence without src= in a README stays legal." + - "The identifier fallback runs go doc -c, so a span must match the declaration's case." + - "Shell command words follow cobra stripFlags and include env prefixes, go run ./cmd/summer, and bin/{app}." + +patterns-established: + - "Pattern: fence discovery is collectFences over the renderer's AST, not a line scan." + - "Pattern: captions are emitted only for top-level src= fences of docs/ pages." + +requirements-completed: [DOCS-04, DOCS-05] + +coverage: + - id: D1 + description: Nested src= fences (callout, blockquote, list item) are refused and are not rewritten by docs:sync. + requirement: DOCS-04 + verification: + - kind: unit + ref: internal/docsite TestPlantedViolations/snippet-callout-drift TestCollectFences TestSyncParsedFences + status: pass + human_judgment: false + - id: D2 + description: Go-lexer fences without src= are refused at any depth, and module README src= fences are refused and not captioned. + requirement: DOCS-04 + verification: + - kind: unit + ref: internal/docsite TestGoLang TestNestedFenceChecks TestFenceCaptionsOnlyVerified + status: pass + human_judgment: false + - id: D3 + description: A .go src= target must be in the default build and reached from a Test or an Example with output; go doc -c and commandWord cover the name-form holes. + requirement: DOCS-05 + verification: + - kind: unit + ref: internal/docsite TestSnippetRootsAndBuild TestIdentifierGoDocCaseSensitive TestCommandWord + status: pass + human_judgment: false + - id: D4 + description: The acceptance scanner sees blockquoted and aliased fences, and the phase gate plants each hole. + requirement: DOCS-04 + verification: + - kind: integration + ref: go test ./cmd/summer -run '^(TestPhase11_1Acceptance|TestAcceptanceFenceScanner)$' and scripts/check-phase11.1.sh --all + status: pass + human_judgment: false + +duration: 33 min +completed: 2026-10-01 +status: complete +--- + +# Phase 11.1 Plan 07: Fail-closed docs checkers Summary + +**Docs checkers walk the goldmark AST, refuse nested and module-README `src=` fences, and accept a Go `src=` target only when `go test ./...` compiles and runs it.** + +## Performance + +- **Duration:** 33 min +- **Started:** 2026-10-01T06:19:48Z +- **Completed:** 2026-10-01T06:53:36Z +- **Tasks:** 5 +- **Files modified:** 64 + +## Accomplishments + +- `collectFences` finds every fenced code block the renderer parses, including fences inside callouts, blockquotes, and list items. A `src=` fence that is not a top-level block of a docs page fails Check, docs:build, and docs:sync, and sync writes nothing. +- Captions are limited to top-level `src=` fences of docs/ pages. A module README `src=` fence is refused with `readmeSrcMessage` and is not extracted. A Go fence without `src=` in a README stays legal. +- A `.go` `src=` target must sit in the default build (`build.ImportDir` on `build.Default`, plus `testdata` and `_`-prefixed directories) and inside a `Test` function or an Example with `// Output:`, or a function one of them calls. `go doc -c` makes the identifier fallback case-sensitive. `commandWord` parses env prefixes, cobra-style flags, `go run ./cmd/summer`, and `bin/{app}`. +- Eighteen planted fixtures and branch tests pin those holes. `internal/docsite` coverage is 94.1%. `scripts/check-phase11.1.sh --all` printed `phase11.1 all passed`. + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: AST fence discovery, nested src= refused, captions only on verified fences** - `5b7e37f` (fix) +2. **Task 2: Go-lexer policy, README src= refusal, shell fences from the AST** - `73c72af` (fix) +3. **Task 3: Proof of execution, go doc -c, command words** - `efc3161` (fix) +4. **Task 4: Planted fixtures and unit tests** - `9ba5530` (test) +5. **Task 5: Acceptance scanner and gate plants** - `550fa06` (test) +6. **Task 5 planning: VALIDATION rows and README todo** - `ce5dcec` (docs) + +**Plan metadata:** committed after this file. + +## Files Created/Modified + +- `internal/docsite/fences.go` - AST fence collection shared by check and sync. +- `internal/docsite/snippet.go` - nested and README refusals, build membership, test-graph roots. +- `internal/docsite/check_policy.go` - Go-lexer fences at every depth; unknown callouts from remaining blockquotes. +- `internal/docsite/check_commands.go` - shell fences from the AST; `commandWord`. +- `internal/docsite/check_identifiers.go` - `go doc -c`. +- `internal/docsite/render.go` - captions only on verified top-level docs fences; `openFence` rejects indent above 3 spaces. +- `internal/docsite/highlight.go` - `goLang` via the chroma Go lexer. +- `cmd/summer/phase11_1_acceptance_test.go` - independent `scanDocFences` and caption cross-check. +- `scripts/check-phase11.1.sh` - self-test plants and the new test names. +- `docs/console/utilities.md`, `README.md` - the top-level, alias, callout, and README rules. +- `internal/docsite/testdata/violations/` - 18 new plants (81 directories total). + +## Decisions Made + +- Nested `src=` fences are refused instead of extracted, because docs:sync cannot rewrite a line that still carries its container marker. +- Module README code blocks stay rendered as written. A `src=` there would claim a check that does not run, so it is refused, and the caption transformer skips README pages. +- Reachability roots are the cmd/go `Test` name rule plus `go/doc` Examples that have output. An Example without `// Output:` is not a root. +- `commandWord` treats `--help` and `-h` as bool flags and consumes the next token for every other `--name` or two-character `-x`, matching cobra's `stripFlags`. + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Drift fixture was a nested src= fence** +- **Found during:** Task 1 (AST fence discovery) +- **Issue:** `TestSyncRewritesDrift` planted a `src=` fence inside a list item. The new nested rule correctly refused it, so the test no longer reported drift. +- **Fix:** Removed the list marker. The drifted fence is a two-space-indented top-level fence. The expected problem line moved from 13 to 11. Indent-preserving sync assertions still hold. +- **Files modified:** `internal/docsite/docsite_test.go` +- **Commit:** `5b7e37f` + +**Total deviations:** 1 auto-fixed (Rule 1). **Impact:** the drift test still pins body mismatch; nested fences are covered by the new plants instead of that fixture. + +Tasks 2 and 3 needed no source fix on the real tree. `go run ./cmd/summer docs:build --check` printed `docs:build: no problems found` after each. No existing unit-test tree relied on an Example without output as a root. + +### Tracking + +`state.advance-plan` at close-out read `Plan: 1 of 7` (phase begin had reset the counter) and stepped it to `2 of 7`. The position was set back to `Plan: 7 of 7` before the last-plan advance, which waits until this summary exists. + +DOCS-04 and DOCS-05 are listed in `requirements-completed` from the plan frontmatter. They were not ticked in REQUIREMENTS.md; re-verification does that. + +## Mutation checks + +Recorded from scratch edits that were restored and not committed: + +- Removing the nested branch of `checkFences` turned `TestPlantedViolations/snippet-callout-drift` red (the test panicked in `fenceBody` because a nested fence has no top-level line span). +- Dropping `-c` from `goDoc` turned `TestPlantedViolations/identifier-wrong-case` red (zero problems; the wrong-case span passed). +- Treating every Example as a root turned `TestPlantedViolations/snippet-example-no-output-helper` red (zero problems; the helper became reachable). +- Renaming `TestCommandWord` in a scratch copy made `scripts/check-phase11.1.sh --named` exit 1 with `refuse: named tests did not pass ... TestCommandWord`. The rename was restored. + +## Follow-up + +The identifier index still reads build-ignored files. That hole is outside this plan and was not changed. + +## Authentication Gates + +None. + +## Known Stubs + +None. + +## Threat Flags + +None. The checkers stay inside the plan's threat register (T-11.1-20 through T-11.1-25). No new endpoint, credential path, or dependency. `git diff d9f187ae39d174d813309a7e9adc8ddc3cc7fe10 HEAD -- go.mod go.sum` is empty. + +## Self-Check: PASSED + +- FOUND: internal/docsite/fences.go +- FOUND: internal/docsite/fences_test.go +- FOUND: cmd/summer/phase11_1_acceptance_test.go +- FOUND: scripts/check-phase11.1.sh +- FOUND: .planning/phases/11.1-summercms-documentation-for-humans-and-ai-agents/11.1-VALIDATION.md +- FOUND: 5b7e37f +- FOUND: 73c72af +- FOUND: efc3161 +- FOUND: 9ba5530 +- FOUND: 550fa06 +- FOUND: ce5dcec +- `go test ./internal/docsite ./cmd/summer -count=1` passed after Tasks 3 and 4. +- `go test ./internal/docsite` coverage 94.1% (above 85%). +- `scripts/check-phase11.1.sh --all` printed `phase11.1 all passed`.