diff --git a/.planning/STATE.md b/.planning/STATE.md index da3f1bac..e5662146 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -5,10 +5,10 @@ current_phase: "19.4" current_phase_name: OIDC provider on wristband status: planning stopped_at: Roadmap reordered 2026-10-18; ready to plan Phase 19.4 -last_updated: "2026-10-18T21:15:16.568Z" -last_activity: 2026-10-18 -last_activity_desc: "Roadmap reordered: demo at 20, cutover 20→30, chat polish 19.2→31" -state_head: 6aaaf59f4381607e0c93d62d264aa7554a608e91 +last_updated: "2026-10-18T22:16:41.885Z" +last_activity: 2026-10-19 +last_activity_desc: "Completed quick task 261019-05g: Phase 17 verify-work unblock and console docs example" +state_head: 86c5a8049667dcdcf6229ba51961405c0ea776c8 progress: total_phases: 42 completed_phases: 34 @@ -32,7 +32,7 @@ See: .planning/PROJECT.md (updated 2026-10-12) Phase: 19.4 — OIDC provider on wristband Plan: Not started Status: Ready to plan -Last activity: 2026-10-18 — Roadmap reordered: demo at 20, cutover 20→30, chat polish 19.2→31 +Last activity: 2026-10-19 - Completed quick task 261019-05g: Phase 17 verify-work unblock and console docs example Progress: [████████░░] 83% @@ -947,6 +947,7 @@ Recent decisions affecting current work: | 261018-k9s | add the D-17 module in summercms.go: modules/breakwater Render(markdown)/Purify(html) with the forum bluemonday policy | 2026-10-18 | 98bc6de | [261018-k9s-add-the-d-17-module-in-summercms-go](./quick/261018-k9s-add-the-d-17-module-in-summercms-go/) | | 40 | Goldens secret scan in check-phase19.1.sh (closes T-19.1-12) | 2026-10-18 | 8643195 | — | | 261018-qbs | Fix 19.1 review WR-04 (chatbots dispatch checks IsAvailable) and WR-05 (chatvideo user.Deleting heir + LiveKit cleanup); extending.md optional-dependency go.mod note | 2026-10-18 | 97daec5 | [261018-qbs-fix-19-1-review-findings-wr-04-chatbots-](./quick/261018-qbs-fix-19-1-review-findings-wr-04-chatbots-/) | +| 261019-05g | Phase 17 verify-work unblock (COVERAGE.md reason, goal as user story, sm-sitemap-plugin requires v0.2.0) and console docs example of the application binary's --help | 2026-10-19 | 86c5a80 | [261019-05g-phase-17-verify-work-unblock-coverage-md](./quick/261019-05g-phase-17-verify-work-unblock-coverage-md/) | ## Deferred Items diff --git a/.planning/quick/261019-05g-phase-17-verify-work-unblock-coverage-md/261019-05g-PLAN.md b/.planning/quick/261019-05g-phase-17-verify-work-unblock-coverage-md/261019-05g-PLAN.md new file mode 100644 index 00000000..06653302 --- /dev/null +++ b/.planning/quick/261019-05g-phase-17-verify-work-unblock-coverage-md/261019-05g-PLAN.md @@ -0,0 +1,187 @@ +--- +phase: quick-261019-05g +plan: 01 +quick_id: 261019-05g +slug: phase-17-verify-work-unblock-coverage-md +type: execute +mode: quick +wave: 1 +depends_on: [] +files_modified: + - /media/nvme/dev/golem15/summercms.io/summercms/summercms.go/.planning/phases/17-blog-companions/COVERAGE.md + - /media/nvme/dev/golem15/summercms.io/summercms/summercms.go/.planning/ROADMAP.md + - /media/nvme/dev/golem15/summercms.io/summercms/sm-sitemap-plugin/go.mod + - /media/nvme/dev/golem15/summercms.io/summercms/sm-sitemap-plugin/go.sum + - /media/nvme/dev/golem15/summercms.io/summercms/summercms.go/docs/console/introduction.md +autonomous: true +requirements: [17-VERIFY-GATE-COVERAGE, 17-VERIFY-GATE-USER-STORY, 17-GAP-SITEMAP-REQUIRE, DOCS-CONSOLE-BINARY-HELP] +source: + - orchestrator brief (items 1-4, wording of COVERAGE.md line and Phase 17 goal approved by the user) + - .planning/phases/17-blog-companions/COVERAGE.md (current single opt-out line, reason 278 chars, gate limit 200) + - .planning/ROADMAP.md line 1068 (Phase 17 **Goal:**, **Mode:** mvp on line 1069) + - .planning/phases/17-blog-companions/17-VERIFICATION.md (untracked, read-only here; last open gap is the sitemap require) + - docs/console/introduction.md line 16 (insertion point) + +estimate: + tokens: 45000 + raw_tokens: 45000 + tasks: 3 + confidence: low + +must_haves: + truths: + - "`node ~/.claude/msd-core/bin/msd-tools.cjs check api-coverage.verify-pre .planning/phases/17-blog-companions --raw` reports \"block\": false; COVERAGE.md is exactly the one user-approved opt-out line (reason 169 chars, under the 200-char limit)." + - "`roadmap.get-phase 17 --pick goal` returns the user-approved story and `user-story.validate` on it returns true; no other ROADMAP.md line changes." + - "sm-sitemap-plugin requires git.golem15.com/golem15/summercms v0.2.0 (the release its siblings sm-menu/faq/journal-plugin require), keeps `replace git.golem15.com/golem15/summercms => ../summercms.go`, and is green on go vet and go test -short." + - "sm-sitemap-plugin also compiles and vets against the published v0.2.0 with the replace removed (checked in a throwaway copy; the repo itself is not left modified)." + - "The sm-sitemap-plugin commit `chore: require summercms v0.2.0` is on origin/main (fast-forward push, no force); no consuming app's gitlink is bumped." + - "docs/console/introduction.md shows, right after the 'The application binary is what you deploy...' paragraph, running `./bin/acme` bare and with `--help`, followed by REAL output captured from a fresh build of examples/hello with only the binary name rewritten to acme; `go test ./cmd/summer -run TestDocsTree` and `go run ./cmd/summer docs:build --check` pass." + - "summercms.go gets exactly two new commits (planning docs; docs(console)), staged by explicit path, not pushed; untracked .msd/ and 17-VERIFICATION.md stay untouched and untracked." + artifacts: + - "summercms.go/.planning/phases/17-blog-companions/COVERAGE.md — one line: the approved `No external API integration: ...` opt-out" + - "summercms.go/.planning/ROADMAP.md — Phase 17 **Goal:** line replaced by the approved user story" + - "sm-sitemap-plugin/go.mod, go.sum — summercms require v0.1.23 -> v0.2.0, tidied" + - "summercms.go/docs/console/introduction.md — new lead-in sentence, an sh fence (`./bin/acme`, `./bin/acme --help`) and a text fence with captured output" + key_links: + - "verify-work 17 gates: api-coverage.verify-pre reads COVERAGE.md (REASON_MAX_LEN = 200 in ~/.claude/msd-core/bin/lib/api-coverage.cjs); the mvp-mode gate reads the ROADMAP `**Goal:**` line through roadmap.get-phase and validates /^As a .+, I want to .+, so that .+\\.$/." + - "sm-sitemap-plugin calls signpost.ValidItemPattern (controllers/definitions.go:143, console/import_winter.go:337); it is absent at summercms v0.1.23 and present at v0.2.0 (modules/signpost/signpost.go:187). Without the bump the plugin only builds through the replace." + - "Docs checker (internal/docsite/check_commands.go): sh/shell/bash/console fences and code spans are scanned for `summer` and `./bin/` command words; `./bin/acme` bare and `./bin/acme --help` yield no command word, and `text` fences are not scanned, so captured output belongs in a `text` fence." + - "examples/hello/main.go hardcodes the root name (`bonfire.NewRoot(\"hello\", ...)`) and loads `config/` relative to the working directory, so the binary must be run from examples/hello and its printed name rewritten to acme for the page." +--- + + +Unblock `/msd-verify-work 17` and close the last open item of the orphaned 17-VERIFICATION.md gap, then fold in one small console docs addition. + +1. Shorten the Phase 17 COVERAGE.md opt-out reason under the 200-char gate limit and restate the Phase 17 ROADMAP goal as a user story (Phase 17 is `**Mode:** mvp`), using the exact user-approved wording. +2. Make sm-sitemap-plugin require summercms v0.2.0 (it uses signpost.ValidItemPattern, first tagged in v0.1.24) so it builds without the development replace, commit and push it (push approved by the user). +3. Show real console output of an application binary run bare and with `--help` in docs/console/introduction.md. + +Purpose: verify-work for Phase 17 currently stops at the api-coverage gate and would stop again at the user-story gate; the sitemap plugin's go.mod lies about its framework dependency. +Output: two summercms.go commits (planning docs, docs(console)), one pushed sm-sitemap-plugin commit. + + + +@~/.claude/msd-core/workflows/execute-plan.md +@~/.claude/msd-core/templates/summary.md + + + +@.planning/STATE.md +@./CLAUDE.md +@docs/console/introduction.md + +Live state observed at planning time (2026-10-19), re-check where a task says so: +- COVERAGE.md is tracked, one line, reason 278 chars; the gate currently returns "block": true. +- ROADMAP.md line 1068 is the Phase 17 goal (not a user story); ROADMAP.md had no uncommitted changes. +- sm-sitemap-plugin: branch main, clean, `## main...origin/main`, HEAD 1bb89ce; go.mod requires summercms v0.1.23 with `replace git.golem15.com/golem15/summercms => ../summercms.go`; tracked go.work also replaces summercms and sm-translate-plugin. No README/yaml/script mentions a summercms version. Siblings committed the same bump as `chore: require summercms v0.2.0` (sm-menu-plugin f7eddd5, sm-faq-plugin 2efe351). +- Tag v0.2.0 exists on origin (d5f754a) and resolves with the default GOPROXY; a throwaway copy of sm-sitemap-plugin with the replace dropped, go.work removed and the require at v0.2.0 passed `GOWORK=off GOFLAGS=-mod=mod go build ./...` and `go vet ./...`. +- examples/hello/bin/ is gitignored; examples/hello is in the root go.work. A stale build of it printed, both bare and with --help (byte-identical, exit 0, nothing on stderr): `Usage:` / `hello [command]`, 19 `Available Commands` rows (admin:create ... serve, including the example plugin's greeter:hello and cobra's help), `Flags:` `-h, --help help for hello`, and `Use "hello [command] --help" for more information about a command.` The task must capture from a fresh build, not reuse this. + +Repo rules that apply (CLAUDE.md): no co-author trailers in any commit (user instruction overrides any attribution reminder); one logical change per commit, planning docs and code/docs separate; stage by explicit path, never `git add -A`; leave untracked `.msd/` and `.planning/phases/17-blog-companions/17-VERIFICATION.md` alone; do not push summercms.go; framework docs never name a consuming application; every identifier and command on a docs page must exist. + + + + + + Task 1: Unblock verify-work 17 end to end — COVERAGE.md reason and Phase 17 goal as user story + /media/nvme/dev/golem15/summercms.io/summercms/summercms.go/.planning/phases/17-blog-companions/COVERAGE.md, /media/nvme/dev/golem15/summercms.io/summercms/summercms.go/.planning/ROADMAP.md + `git -C /media/nvme/dev/golem15/summercms.io/summercms/summercms.go diff --quiet -- .planning/ROADMAP.md .planning/phases/17-blog-companions/COVERAGE.md` exits 0 (no other session has uncommitted edits in these two files); if it does not, stop and report instead of committing someone else's hunk. + Work in /media/nvme/dev/golem15/summercms.io/summercms/summercms.go. + +COVERAGE.md: replace the whole file content with exactly this single line followed by one newline, nothing else (wording approved by the user; the reason after the colon is 169 chars): +No external API integration: ports the internal sitemap, menu and FAQ plugins and serves first-party read APIs (/_menu, /_faq, /sitemap.xml) to our own Nuxt layers; no third-party service is called. + +ROADMAP.md: in the section `### Phase 17: Blog companions`, use a scoped Edit (never a whole-file Write) to replace only the `**Goal:**` line (line 1068, currently starting "**Goal:** The sitemap, menu and FAQ plugins run on SummerCMS as shared") with exactly: +**Goal:** As a blog site editor, I want to manage menus, FAQs and the sitemap in the SummerCMS admin through the shared sitemap, menu and FAQ plugins, so that they are no longer hardcoded in the Nuxt app. +Leave `**Mode:** mvp`, Depends on, Repos, Port sources, Requirements and Success Criteria untouched. + +Run both gates (see verify). Then stage exactly these two paths and commit them together as one planning-docs commit, message: `docs(17): shorten the COVERAGE.md opt-out reason and state the goal as a user story`. No co-author trailer. Do not stage .msd/, 17-VERIFICATION.md, STATE.md or anything else. + + cd /media/nvme/dev/golem15/summercms.io/summercms/summercms.go && node ~/.claude/msd-core/bin/msd-tools.cjs check api-coverage.verify-pre .planning/phases/17-blog-companions --raw | grep -q '"block": *false' && G=$(node ~/.claude/msd-core/bin/msd-tools.cjs query roadmap.get-phase 17 --pick goal) && test "$(node ~/.claude/msd-core/bin/msd-tools.cjs query user-story.validate --story "$G" --pick valid)" = true && C=$(git log -1 --format=%H -F --grep='docs(17): shorten the COVERAGE.md opt-out reason') && test -n "$C" && N=$(git diff --numstat "$C^..$C" -- .planning/ROADMAP.md) && test "$(printf '%s\n' "$N" | cut -f1,2)" = "$(printf '1\t1')" && F=$(git show --name-only --format= "$C") && test "$(printf '%s\n' "$F" | sort | tr '\n' ' ')" = ".planning/ROADMAP.md .planning/phases/17-blog-companions/COVERAGE.md " && echo OK + + The api-coverage.verify-pre gate returns "block": false for Phase 17; the Phase 17 goal validates as a user story; the docs(17) commit (found by subject, not by HEAD offset, since other sessions commit here) touches only COVERAGE.md and ROADMAP.md (ROADMAP: 1 line added, 1 removed); no co-author trailer; .msd/ and 17-VERIFICATION.md still untracked. + + + + Task 2: sm-sitemap-plugin requires summercms v0.2.0, verified without the replace, committed and pushed + /media/nvme/dev/golem15/summercms.io/summercms/sm-sitemap-plugin/go.mod, /media/nvme/dev/golem15/summercms.io/summercms/sm-sitemap-plugin/go.sum + In /media/nvme/dev/golem15/summercms.io/summercms/sm-sitemap-plugin, after `git fetch origin`: `git status --porcelain` is empty, the branch is main and `git rev-parse HEAD` equals `git rev-parse origin/main` (observed at planning: HEAD 1bb89ce, in sync); if not, stop and report. + Work in /media/nvme/dev/golem15/summercms.io/summercms/sm-sitemap-plugin (module git.golem15.com/golem15/sm-sitemap-plugin). The plugin calls signpost.ValidItemPattern, which v0.1.23 lacks; v0.2.0 (the version sm-menu/faq/journal-plugin require) has it. + +1. Bump the require only: `go mod edit -require=git.golem15.com/golem15/summercms@v0.2.0`. Keep the go.mod line `replace git.golem15.com/golem15/summercms => ../summercms.go` and leave the tracked go.work unchanged. +2. Tidy deterministically against the module's own go.mod: `GOWORK=off go mod tidy`. +3. `go vet ./...` and `go test -short ./...` (normal workspace mode) must be green. +4. Prove it builds WITHOUT the replace, in a throwaway copy so the repo is never modified: create a temp dir with `mktemp -d`, `rsync -a --exclude .git ./ "$T/"`, then in "$T": remove go.work and go.work.sum if present, `go mod edit -dropreplace=git.golem15.com/golem15/summercms`, and run `GOWORK=off GOFLAGS=-mod=mod go build ./...` and `GOWORK=off GOFLAGS=-mod=mod go vet ./...` (the copy sits outside the meta repo, so ../summercms.go cannot be picked up by accident). Remove "$T" afterwards. If this fails because the plugin needs an API added after v0.2.0, stop and report the missing identifier and the first tag that has it instead of choosing another version (v0.2.0 is the user-approved target). +5. Confirm `git diff --name-only` lists only go.mod and/or go.sum and that the replace line is still present. +6. Stage go.mod and go.sum by path and commit with message `chore: require summercms v0.2.0` (mirrors the sibling commits). No co-author trailer. +7. Push: `git push origin main` (fast-forward only; never --force; push approved by the user). Do NOT bump the sm-sitemap-plugin gitlink in any consuming application. + + cd /media/nvme/dev/golem15/summercms.io/summercms/sm-sitemap-plugin && grep -qE '^[[:space:]]+git\.golem15\.com/golem15/summercms v0\.2\.0$' go.mod && grep -q '^replace git.golem15.com/golem15/summercms => ../summercms.go$' go.mod && go vet ./... && go test -short ./... && test -z "$(git status --porcelain)" && git fetch origin && test "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" && S=$(git log -1 --format=%s) && test "$S" = "chore: require summercms v0.2.0" && B=$(git log -1 --format=%B) && ! printf '%s\n' "$B" | grep -qi '^co-authored-by' && F=$(git show --name-only --format= HEAD) && test -z "$(printf '%s\n' "$F" | grep -vxE 'go\.(mod|sum)')" && echo OK + + go.mod requires summercms v0.2.0 with the replace kept; go vet and go test -short green; the no-replace build and vet against v0.2.0 passed in a removed temp copy; one commit `chore: require summercms v0.2.0` touching only go.mod/go.sum, no co-author trailer, pushed so HEAD equals origin/main; working tree clean; no app gitlink changed. + + + + Task 3: Console docs show a bare and --help run of the application binary with real output + /media/nvme/dev/golem15/summercms.io/summercms/summercms.go/docs/console/introduction.md + `git -C /media/nvme/dev/golem15/summercms.io/summercms/summercms.go diff --quiet -- docs/console/introduction.md` exits 0 (no in-flight edit from another session). + Work in /media/nvme/dev/golem15/summercms.io/summercms/summercms.go. + +Capture real output (do not invent or hand-edit command rows): +- Build the workspace example into a temp dir without regenerating tracked files: `T=$(mktemp -d)`, then from examples/hello run `go build -o "$T/hello" .` (use go build, not `summer build`, so the committed examples/hello/main.go and plugins.gen.go are not rewritten). +- From examples/hello (the binary loads `config/` relative to the working directory) run it bare and with `--help`, stdout and stderr to separate files in "$T", and record both exit codes. `diff` the two stdout captures. +- Remove "$T" when done; `git status --short examples/` must stay empty. + +Edit docs/console/introduction.md: insert after the paragraph on line 16 ("The application binary is what you deploy, ... rather than of `summer`.") and before `## Getting help`, separated by blank lines: +- One lead-in sentence. If the two captures are identical (as observed at planning time), say that run with no arguments the binary prints its usage and every command it has, the framework's and those its plugins add, and that `--help` prints the same. If they differ, describe each and show both outputs. +- An `sh` fence with two lines: `./bin/acme` and `./bin/acme --help` (the docs checker finds no command word in either, so nothing new needs registering). +- A `text` fence (not sh/console: those are scanned as commands) with the captured stdout, where the only change is the binary name: the root name printed in the Usage line, the `help for ...` flag line and the closing `Use "... [command] --help"` line becomes `acme`, matching the `./bin/acme` name used throughout the page. Keep column alignment, row order and descriptions verbatim, including the example plugin's own command row, which shows that plugin commands join the list. +- Trimming: the stale build had 19 command rows (about 26 lines); keep the full list if the fresh capture has at most 22 rows. Otherwise keep the first and last few rows, replace the middle with a single ` ...` line, and add a short sentence after the fence saying the list is shortened. +- Do not touch the rest of the page, the module READMEs or any other docs page; name no consuming application. + +Run the docs checks (see verify), then stage docs/console/introduction.md by path and commit as `docs(console): show the application binary run bare and with --help`. No co-author trailer. Do not push summercms.go. + + cd /media/nvme/dev/golem15/summercms.io/summercms/summercms.go && go test ./cmd/summer -run TestDocsTree && go run ./cmd/summer docs:build --check && grep -q 'acme \[command\]' docs/console/introduction.md && grep -q 'help for acme' docs/console/introduction.md && C=$(git log -1 --format=%H -F --grep='docs(console): show the application binary run bare and with --help') && test -n "$C" && N=$(git diff --numstat "$C^..$C" -- docs/console/introduction.md) && test "$(printf '%s\n' "$N" | cut -f2)" = 0 && F=$(git show --name-only --format= "$C") && test "$F" = docs/console/introduction.md && E=$(git status --short examples/) && test -z "$E" && go vet ./... && echo OK + + The page shows, between the deploy paragraph and `## Getting help`, a lead-in sentence, an sh fence with `./bin/acme` and `./bin/acme --help`, and a text fence holding output captured from a fresh examples/hello build with the binary name rewritten to acme (trimmed only per the rule, with a note if so); TestDocsTree and `docs:build --check` pass; the commit adds lines only to docs/console/introduction.md; examples/ is clean; go vet is green; nothing pushed. + + + + + +## Trust Boundaries + +| Boundary | Description | +|----------|-------------| +| sm-sitemap-plugin go.mod -> module proxy / git.golem15.com | the require now resolves summercms v0.2.0 from the network when the replace is absent | +| local sm-sitemap-plugin -> origin main | a commit is published to the shared plugin repo that apps consume as a submodule | +| local binary output -> public docs site | captured console output is published on the docs page | + +## STRIDE Threat Register + +Numbering continues after the highest Phase 17 ID in use (T-17-41). + +| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan | +|-----------|----------|-----------|----------|-------------|-----------------| +| T-17-42 | Tampering | sm-sitemap-plugin go.mod/go.sum (summercms v0.1.23 -> v0.2.0) | medium | mitigate | Target is our own tag v0.2.0 (d5f754a on origin), already required by the sibling plugins; go.sum hashes come from `go mod tidy` with the default GOPROXY and checksum DB; Task 2 verify refuses a commit touching anything but go.mod/go.sum; the -mod=mod no-replace build runs only in a removed temp copy. | +| T-17-43 | Tampering | push of sm-sitemap-plugin main | low | mitigate | Precondition requires a clean tree in sync with origin/main before the bump; push is fast-forward only (no --force); verify checks HEAD == origin/main and the single expected subject; consuming apps' gitlinks are deliberately not moved. | +| T-17-44 | Information disclosure | captured binary output in docs/console/introduction.md | low | accept | `--help` prints only usage, command names and descriptions (observed); stderr is captured separately and not pasted; the only rewrite is the binary name to acme, and `docs:build --check` refuses consuming-application names. | +| T-17-SC | Tampering | npm/pip/cargo installs | high | mitigate | No package-manager install and no new dependency: Task 2 changes the version of an existing first-party requirement only; Task 3 builds an in-repo example with the existing module graph. | + + + +- `node ~/.claude/msd-core/bin/msd-tools.cjs check api-coverage.verify-pre .planning/phases/17-blog-companions --raw` -> "block": false. +- `roadmap.get-phase 17 --pick goal` piped into `user-story.validate --pick valid` -> true. +- sm-sitemap-plugin: go vet and go test -short green; HEAD == origin/main; subject `chore: require summercms v0.2.0`. +- summercms.go: `go vet ./...`, `go test ./cmd/summer -run TestDocsTree`, `go run ./cmd/summer docs:build --check` green. +- summercms.go history contains the docs(17) and docs(console) commits (located by subject; other sessions may have committed in between); `git status --short` still lists only the untracked `.msd/` and `.planning/phases/17-blog-companions/17-VERIFICATION.md` (plus any other session's own edits, untouched); summercms.go not pushed. +- No commit in either repo carries a Co-Authored-By trailer. + + + +`/msd-verify-work 17` is no longer blocked by the api-coverage or user-story gates; the sitemap plugin's declared framework dependency (v0.2.0) is the one it actually needs and is published on origin/main; the console introduction shows what a bare application binary and `--help` really print. + + + +Create `.planning/quick/261019-05g-phase-17-verify-work-unblock-coverage-md/261019-05g-SUMMARY.md` when done, listing: the two summercms.go commit hashes, the sm-sitemap-plugin commit hash and the pushed origin/main ref, the go.sum delta (lines added/removed), the result of the no-replace check, whether the bare and --help captures were identical and whether the command list was trimmed, and the new threat rows T-17-42 .. T-17-44 for later registration in Phase 17's security record. Note that consuming apps still pin the previous sm-sitemap-plugin gitlink (bump left for a separate task). + diff --git a/.planning/quick/261019-05g-phase-17-verify-work-unblock-coverage-md/261019-05g-SUMMARY.md b/.planning/quick/261019-05g-phase-17-verify-work-unblock-coverage-md/261019-05g-SUMMARY.md new file mode 100644 index 00000000..a5137e15 --- /dev/null +++ b/.planning/quick/261019-05g-phase-17-verify-work-unblock-coverage-md/261019-05g-SUMMARY.md @@ -0,0 +1,87 @@ +--- +phase: quick-261019-05g +plan: 01 +quick_id: 261019-05g +subsystem: planning, sm-sitemap-plugin, docs/console +tags: [phase-17, verify-work, api-coverage, user-story, go-mod, docs] +status: complete +requires: [] +provides: + - Phase 17 COVERAGE.md under the 200-char opt-out gate + - Phase 17 goal as a user story (mvp gate) + - sm-sitemap-plugin requires summercms v0.2.0 (pushed) + - console docs show real bare / --help output of an application binary +affects: [phase-17 verify-work, apps consuming sm-sitemap-plugin (gitlink not bumped)] +tech-stack: + added: [] + patterns: [] +key-files: + created: [] + modified: + - .planning/phases/17-blog-companions/COVERAGE.md + - .planning/ROADMAP.md + - docs/console/introduction.md + - ../sm-sitemap-plugin/go.mod + - ../sm-sitemap-plugin/go.sum +decisions: + - "sm-sitemap-plugin go.mod tidied with the development replace in effect (GOWORK=off); the resulting indirect set (aws-sdk-go-v2, go-redis, otter, wire, atomic) matches the sibling sm-menu/sm-faq plugins, and summercms.go go.mod is unchanged since v0.2.0" +metrics: + duration: ~3min + completed: 2026-10-19 +actuals: + tokens: 1600 + tasks: 3 + commits: 2 +commits: 2 +plan_head_before: eb7e39d335d32983b0ca461725cd01f561189643 +plan_head_after: 86c5a8049667dcdcf6229ba51961405c0ea776c8 +--- + +# Phase quick-261019-05g Plan 01: Unblock verify-work 17, sitemap plugin require, console help output Summary + +Phase 17's api-coverage and user-story gates now pass, sm-sitemap-plugin declares (and is pushed with) the summercms v0.2.0 it actually needs, and the console introduction shows the real usage output of an application binary. + +## Commits + +| Repo | Task | Commit | Subject | +|------|------|--------|---------| +| summercms.go | 1 | 59f5781 | docs(17): shorten the COVERAGE.md opt-out reason and state the goal as a user story | +| sm-sitemap-plugin | 2 | 46898c2 | chore: require summercms v0.2.0 | +| summercms.go | 3 | 86c5a80 | docs(console): show the application binary run bare and with --help | + +`commits: 2` counts summercms.go only (measured `git rev-list --count eb7e39d..HEAD`); the sm-sitemap-plugin commit is in its own repo. No commit carries a co-author trailer. summercms.go not pushed. + +## Task results + +**Task 1 (tracer).** COVERAGE.md is the single approved line (reason 169 chars). `check api-coverage.verify-pre` returns `"block": false` (`none_declared: true`, overriding 2 detected signals). `roadmap.get-phase 17 --pick goal` returns the approved story and `user-story.validate` returns `true`. Commit touches only COVERAGE.md and ROADMAP.md (ROADMAP 1+/1-). Tracer gate re-ran the verify end to end and passed. + +**Task 2.** go.mod require v0.1.23 -> v0.2.0, replace `=> ../summercms.go` kept, go.work untouched. go.mod +25/-1 (require bump plus 23 new indirect lines pulled in by v0.2.0's dependency graph), go.sum +24/-0. `go vet ./...` and `go test -short ./...` green. No-replace check in a removed temp copy (go.work dropped, replace dropped, `GOWORK=off GOFLAGS=-mod=mod`): `go build ./...` and `go vet ./...` passed, resolving `git.golem15.com/golem15/summercms v0.2.0`. Pushed fast-forward: `1bb89ce..46898c2 main -> main`; HEAD == origin/main == 46898c2c754da280481d3a992ebc05ae3dc7c89e. + +**Task 3.** Fresh `go build` of examples/hello into a temp dir, run from examples/hello: bare and `--help` both exit 0, stderr empty, stdout byte-identical. 18 command rows (under the 22-row limit), so the list is shown in full, not trimmed. The page's `text` block was diffed against the capture with only `hello` -> `acme` rewritten in the Usage, `help for` and closing `Use "..."` lines: match. Commit adds 37 lines, removes 0. `TestDocsTree`, `docs:build --check` and `go vet ./...` pass; `git status --short examples/` empty. + +## Deviations from Plan + +**1. [Rule 1 - Verify script] Locale-dependent sort in Task 1 verify** +- **Found during:** Task 1 tracer gate +- **Issue:** The automated verify compares `sort` output to a C-locale ordering; under the shell's locale, `sort` placed `.planning/phases/...` before `.planning/ROADMAP.md`, so the check failed although the commit was correct. +- **Fix:** Re-ran the same verify with `LC_ALL=C`; it printed OK. No file change. + +Otherwise the plan executed as written. + +## Threat Flags (for Phase 17's security record) + +| Threat ID | Category | Component | Severity | Disposition | Mitigation | +|-----------|----------|-----------|----------|-------------|------------| +| T-17-42 | Tampering | sm-sitemap-plugin go.mod/go.sum (summercms v0.1.23 -> v0.2.0) | medium | mitigate | Own tag v0.2.0, same as siblings; go.sum from `go mod tidy` with default GOPROXY and checksum DB; commit touches only go.mod/go.sum; no-replace build only in a removed temp copy. | +| T-17-43 | Tampering | push of sm-sitemap-plugin main | low | mitigate | Clean tree in sync with origin/main before the bump; fast-forward push, no force; HEAD == origin/main verified; consuming apps' gitlinks not moved. | +| T-17-44 | Information disclosure | captured binary output in docs/console/introduction.md | low | accept | Only usage, command names and descriptions; stderr empty and not pasted; only the binary name rewritten to acme. | + +## Follow-ups + +- Consuming apps still pin the previous sm-sitemap-plugin gitlink (1bb89ce); bumping it to 46898c2 is left for a separate task. +- Untracked `.msd/` and `.planning/phases/17-blog-companions/17-VERIFICATION.md` were left untouched. + +## Self-Check: PASSED + +- FOUND: .planning/phases/17-blog-companions/COVERAGE.md, .planning/ROADMAP.md, docs/console/introduction.md, ../sm-sitemap-plugin/go.mod, ../sm-sitemap-plugin/go.sum +- FOUND commits: 59f5781, 86c5a80 (summercms.go), 46898c2 (sm-sitemap-plugin, also on origin/main)