docs(19.8-04): unit tests and gate executed, post-release fix awaiting go-ahead

This commit is contained in:
Jakub Zych
2026-10-21 19:58:37 +02:00
parent 72b8383c10
commit a7431c34f0
2 changed files with 283 additions and 0 deletions

View File

@@ -0,0 +1,271 @@
---
phase: 19.8-console-commands-overhaul
plan: 04
subsystem: console
tags: [tests, gate, diary, bonfire, slogtest, goldens, surf, conga, lagoon, cabana, flare, dev]
requires:
- phase: 19.8-01
provides: diary (channels, components, daily files, console handler)
- phase: 19.8-02
provides: bonfire global flags, list, help, errors, widgets, prompts
- phase: 19.8-03
provides: swept framework commands, request log, summaries, v0.4.0, swept plugins, applications
provides:
- "scripts/check-phase19.8.sh: fail-closed gate (self-test, go, hello, docs, plugins, apps, landing, docker) with --self-test"
- "Unit and golden tests for diary, sunscreen, bonfire, docsite and every swept framework command"
- "fix(bonfire): PeekGlobals reads clustered shorthands (post-release fix, in v0.4.0)"
affects: [19.8 verification, the next framework tag]
actuals:
tokens: 53163 # chars/4 over the added lines of this plan's diff (goldens excluded)
tasks: 4 # Tasks 1-4 done; Task 5 is the checkpoint, Task 6 waits on its reply
commits: 11 # MEASURED: git rev-list --count plan_head_before..plan_head_after
plan_head_before: b906a31c368ad6a59ea8f6ac82121714ffad20da
plan_head_after: 72b8383c1022a993b66c6cd8b4f739bdee062246
tech-stack:
added: []
patterns:
- "Goldens under modules/bonfire/testdata with an -update flag; color detection cleared per test (plainEnv)"
- "testing/slogtest for the console handler through a key=value line parser, and for the full pipeline through JSON"
- "Interactive-terminal tests on a pseudo-terminal opened with syscall only (/dev/ptmx), no new dependency"
- "Gate additive check finds each plugin's sweep commit by subject and diffs it against its parent"
key-files:
created:
- scripts/check-phase19.8.sh
- modules/diary/diary_test.go
- modules/diary/config_test.go
- modules/diary/daily_test.go
- modules/diary/console_test.go
- modules/diary/slogtest_test.go
- modules/bonfire/globals_test.go
- modules/bonfire/root_test.go
- modules/bonfire/golden_test.go
- modules/bonfire/errors_test.go
- modules/bonfire/docs_test.go
- modules/bonfire/widgets_test.go
- modules/bonfire/live_test.go
- modules/bonfire/version_test.go
- modules/bonfire/testdata/*.golden (9 files)
- internal/docsite/check_commands_test.go
- modules/surf/summary_test.go
- modules/conga/stats_test.go
- modules/conga/logger_test.go
- modules/conga/confirm_linux_test.go
- modules/lagoon/pending_test.go
- modules/lagoon/commands_flags_test.go
- modules/lagoon/logger_test.go
- modules/lagoon/pty_linux_test.go
- modules/cabana/token_json_test.go
modified:
- modules/bonfire/globals.go
- modules/bonfire/version.go
- modules/sunscreen/sunscreen_test.go
- modules/surf/accesslog_test.go
- modules/flare/commands_test.go
- internal/dev/watch_test.go
- cmd/summer/runtime_test.go
key-decisions:
- "PeekGlobals reads a single-dash cluster letter by letter like pflag (-qn, -vq, -nvv) and stops at the first non-global letter; released as a post-release fix pending the Task 5 reply"
- "BuildVersion reads build info through an unexported package variable (refactor, no behaviour change) so tests pin the tagged, replaced and go.work cases"
- "Interactive confirmation is tested on a real pseudo-terminal (syscall ioctls on /dev/ptmx) instead of adding a pty dependency or a bonfire test seam"
- "The landing stage runs nuxt generate before the TAP suite and checks the roadmap snapshot against origin/master; TestTerminalCommands (deployed one-liner) is opt-in"
requirements-completed: [SC-5, D-03, D-08, D-09, D-10, D-12, D-13, D-14, D-15, D-16, D-17, D-18, D-19, D-21, D-23, D-25, D-27, D-28, D-29]
coverage:
- id: D1
description: "Fail-closed gate: detectors proven on planted output, additive and NOT SWEPT rules on planted git repositories, docker NOT RUN rule"
requirement: SC-5
verification:
- kind: other
ref: "bash scripts/check-phase19.8.sh --self-test"
status: pass
human_judgment: false
- id: D2
description: "diary config rules, floors, verbosity, quiet, daily rotation/retention/permissions/degradation, path confinement, redaction on every driver, control characters, lifecycle, concurrency, slogtest"
requirement: D-08
verification:
- kind: unit
ref: "modules/diary#TestConfigRules ... TestSlogtestPipeline (27 names in the gate)"
status: pass
human_judgment: false
- id: D3
description: "bonfire goldens (list, list --all, JSON, styled, help, passthrough help, three error blocks), flags, exit codes, duplicates, version header"
requirement: D-13
verification:
- kind: unit
ref: "modules/bonfire#TestListGolden, TestHelpGolden, TestErrorGolden, TestPeekGlobals, TestGlobalFlagsAgree, TestExitCodes"
status: pass
human_judgment: true
rationale: "The goldens were created with -update and read against the D-13, D-14 and D-18 previews; layout taste is a person's call"
- id: D4
description: "Widget matrix, live models, prompts, ConfirmProceed, Secret under -n, PrintAbove"
requirement: D-03
verification:
- kind: unit
ref: "modules/bonfire#TestWidgetMatrix, TestLiveModels, TestPromptsNoInteraction, TestSecretWithNoInteraction, TestConfirmProceed, TestPrintAbove"
status: pass
- kind: manual_procedural
ref: "throwaway program under script(1) on a pty: spinner, progress and process view print their final frames"
status: pass
human_judgment: false
- id: D5
description: "Swept framework commands: serve summary/records/report, request log, WorkerStats, PendingMigrations, --pretend, production question, --json, -q data, Reported, summer dev, delegates"
requirement: D-29
verification:
- kind: unit
ref: "go stage names for surf, conga, lagoon, flare, internal/dev, cmd/summer"
status: pass
- kind: integration
ref: "docker stage: TestServeLifecycle, TestPendingMigrations, TestMigratePretend, TestRollbackPretend, TestDeferredPurgePretend, TestMigrateStatusJSON, TestTokenCreateJSON, TestTokenListJSON, TestTokenCreateQuietKeepsToken"
status: pass
human_judgment: false
- id: D6
description: "Plugins (15 repositories), applications (5) and landing run from the gate"
requirement: D-17
verification:
- kind: other
ref: "bash scripts/check-phase19.8.sh --all (PHASE198_REQUIRE_DOCKER=1): every stage PASS"
status: pass
human_judgment: false
duration: 69min
completed: 2026-10-21
status: checkpoint
---
# Phase 19.8 Plan 04: unit tests and the phase gate Summary
**A fail-closed `scripts/check-phase19.8.sh` (eight stages, green with `--all` and Docker required) plus unit, golden, slogtest and pseudo-terminal tests for diary, bonfire and every swept framework command; the tests found one bug in released code, `PeekGlobals` ignoring clustered shorthands such as `-qn`, fixed in its own commit and waiting on the Task 5 go-ahead.**
## Performance
- **Started:** 2026-10-21T16:47:08Z
- **Checkpoint reached:** 2026-10-21T17:56Z (about 69 min)
- **Tasks:** 4 of 6 done; Task 5 (checkpoint:decision) presented; Task 6 waits on its reply
- **Files:** 40 changed, 6,036 insertions, 7 deletions
## Accomplishments
- Gate with stages `self-test`, `go`, `hello`, `docs`, `plugins`, `apps`, `landing`, `docker`; detectors for `go test -json` and node `--test` TAP output, the additive check and the NOT SWEPT rule, each proven on planted input.
- diary: 24 new tests incl. `testing/slogtest` conformance for the console handler and the pipeline, 100 concurrent writers under `-race`, rotation with an injected clock, retention, 0640 files under a strict umask.
- bonfire: 9 goldens and 26 new tests (global flags, exit codes, widgets, live models, prompts, version header).
- Framework commands: summaries and reports, request log (never the path), WorkerStats, the production question on a real pseudo-terminal, `--pretend`, `--json`, `-q` data, Reported failures, `summer dev` with a real child process.
- `--all` runs the 15 swept plugins (short suites, coverage test, `GOWORK=off` build, additive check), the 5 applications (build, `summer build` leaves `main.go` unchanged, `list`, `help migrate`), the landing site and the Docker suites.
## Task Commits
1. **Task 1 (tracer): gate with the smoke tests by name**: `9b2fa6c` test(19.8)
2. **Task 2: diary, sunscreen, River and GORM**: `24f4643` test(diary), `db83a14` test(conga,lagoon)
3. **Task 3: bonfire and docsite**: `efb043e` fix(bonfire) (post-release fix), `9641a1b` refactor(bonfire), `7b58ad5` test(bonfire) goldens, `eeeee59` test(bonfire) flags/exit codes/widgets, `fd52868` test(docsite)
4. **Task 4: framework commands and the remaining stages**: `6720cae` test(surf,conga,lagoon), `2baec56` test(cabana,flare,dev,summer), `72b8383` test(19.8) gate stages
5. **Task 5**: checkpoint presented (see below)
6. **Task 6**: waits on the Task 5 reply
`commits: 11` is measured from the ledger (`b906a31..72b8383`); all eleven are this plan's. The tracer feedback gate re-ran Task 1's automated verify after its commit (green), so expansion continued.
## Post-release fixes
| # | Commit | Module | Symptom | Pinning test | In v0.4.0 | Needs require (plugins) | Regenerate (apps) |
|---|--------|--------|---------|--------------|-----------|-------------------------|-------------------|
| 1 | `efb043e` | bonfire | `PeekGlobals` read only `-v` clusters, so `-qn`, `-vq`, `-nvv` were missed before cobra parsed them: the generated main's pre-boot diary setup ignored them (boot logs not quieted), `Execute`'s error block rendered without the `-v` chain, and passthrough commands (summer's delegates) saw no globals. cobra itself parsed them, so the commands ran with the right options. | `TestPeekGlobals`, `TestGlobalFlagsAgree` (rows `combined -qn`, `combined -vq`, `combined -nvv`) | yes | no (no API change) | no (generated `main.go` unchanged; applications pick it up with a framework require bump) |
Not a fix, nothing to publish: `9641a1b` refactor(bonfire) reads build info through an unexported variable for `TestVersionHeader`; no behaviour change, it rides with the next tag.
Proposed patch tag: **v0.4.1** (framework only).
## Task 5 reply
Pending. Before the reply `git tag --points-at HEAD` printed nothing (no tag on HEAD).
## --all stage summary
`PHASE198_REQUIRE_DOCKER=1 TESTCONTAINERS_HOST_OVERRIDE=127.0.0.1 bash scripts/check-phase19.8.sh --all` at `72b8383`:
```
PASS self-test
PASS go
PASS hello
PASS docs
PASS plugins
PASS apps
NOT RUN TestTerminalCommands (the deployed one-liner end to end: needs network, Docker and ports 54320 and 8080; set SUMMERCMS_TERMINAL_CHECK=1)
PASS landing
PASS docker
Phase 19.8 gate passed
```
`go vet ./...`, `go test -count=1 -short ./...` and `--self-test` were green in the same run. No line of the log starts with `FAIL` or reports an unimplemented stage.
## Docker
- **Run.** The docker stage ran (daemon up, `PHASE198_REQUIRE_DOCKER=1`): `TestServeLifecycle`, `TestPendingMigrations`, `TestMigratePretend`, `TestRollbackPretend`, `TestDeferredPurgePretend`, `TestMigrateStatusJSON`, `TestTokenCreateJSON`, `TestTokenListJSON`, `TestTokenCreateQuietKeepsToken`: PASS.
- The complete Docker suites of `modules/lagoon/...`, `modules/cabana`, `modules/surf` and `modules/conga` (`go test -count=1 ./...` without `-short`) also pass with the new tests.
- Plugins: only their short suites run in the gate; the known Docker failures of sitemap, faq, menu and the user plugin's `updates` package (deferred-items.md, plan 03) are not part of this gate.
## Goldens against the previews
Read after `-update`; sections, order and alignment match D-13, D-14 and D-18. Intentional differences: the list also shows `help`; help prints the value placeholder as the upper-cased flag name (`--expires=EXPIRES`, the preview shows `DAYS`) and adds the `Global options` and `Help` sections the preview left out; the argument column aligns with the option labels.
## Decisions Made
See `key-decisions`. The two worth a look: the post-release fix above, and testing the production question on a real pseudo-terminal (`/dev/ptmx` with `syscall` ioctls, linux build tag), which needs no new dependency and no bonfire test seam.
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] PeekGlobals ignored clustered shorthands**
- **Found during:** Task 3 (`TestGlobalFlagsAgree`)
- **Fix:** read single-dash clusters letter by letter; stop at the first non-global letter
- **Files:** modules/bonfire/globals.go
- **Commit:** `efb043e` (in the Post-release fixes table)
**2. [Rule 3 - Blocking] No injectable build-info reader**
- **Found during:** Task 3 (`TestVersionHeader`)
- **Fix:** `var readBuildInfo = debug.ReadBuildInfo`, used by `BuildVersion`
- **Commit:** `9641a1b` (refactor, no behaviour change)
**3. [Rule 3 - Blocking] gate build of library-only plugins**
- `go build -o dir/ ./...` refuses repositories without a main package; the plugins stage uses `GOWORK=off go build ./...`.
### Recorded differences
4. **Extra test files** not in the plan's list: `modules/conga/confirm_linux_test.go` (queue:clear's question, `TestQueueClearConfirm`), `modules/lagoon/pty_linux_test.go` (`TestConfirmProductionInteractiveNo`, `TestForceSkipsConfirm`), additional tests `TestDefaultConfig`, `TestConsoleLevelFromOptions`, `TestRouteListJSON` (in summary_test.go), `TestMigrateStatusJSON` (in pending_test.go, Docker).
5. **Component names with dots.** `TestConfigRules` pins the nested form as refused and the literal YAML key as accepted (compass keeps it literal); the docs' "cannot contain dots" wording is a deferred item.
6. **Version header.** Equal `devel` versions collapse to `SummerCMS acme devel`; pinned, deferred.
7. **TestErrorScrubbed** covers the credential shapes `sunscreen.Scrub` knows (Bearer, `sk-`, `x-api-key:`) in the message, explanation, Try line and `-v` chain; a `password=` in a message is not scrubbed (sunscreen contract; deferred).
8. **Widget matrix on a terminal.** Live views on a buffer draw no frames (no window size), so the terminal row checks the live path (three cursor-hide sequences, no fallback lines); `TestLiveModels` renders the frames with a fixed size and a pty run showed every final frame.
9. **TestServeGracefulNil and TestShutdownReportAborted** drive `requestCounter` and `shutdownReport` through a real `http.Server` with serve's drain logic; serve's own wiring of them is covered by `TestServeLifecycle` (Docker).
10. **Landing.** The stage runs `nuxt generate` before the TAP suite (plan 03 deviation 12); `TestTerminalCommands` is opt-in (NOT RUN line); `sync-roadmap.sh --check` uses `ROADMAP_REF=origin/master` because local master carries other sessions' unpushed planning commits.
11. **Verify chain flake.** One run of Task 3's verify chain stopped red after its race step without a visible failure; every piece passed separately and the full chain passed on the rerun.
**Total deviations:** 3 auto-fixed (1 bug, 2 blocking), 8 recorded differences.
## Issues Encountered
- Pre-existing gofmt drift in plan 03 files (`cmd/summer/main.go`, `runtime.go`, `runtime_test.go`, `modules/flare/commands.go`); logged in deferred-items.md.
## Known Stubs
None.
## Threat Flags
None. No new endpoint or input path; the goldens hold fixed fake values (secret scan over `modules/bonfire/testdata` finds no JWT, `sk-` key or private key header).
## g15office
No g15office tool is available in this executor session: the Phase 19.8 milestone task was not commented. Suggested comment once the Task 5 reply is in: "Plan 19.8-04 executed: phase gate green (--all with Docker), one post-release fix (PeekGlobals clustered shorthands); waiting on verification."
## Next
Task 5 reply ("release vX.Y.Z", "push-only" or "hold"), then Task 6 under it, then `/msd-verify-work 19.8`.
## Self-Check: PASSED
Every created file listed above exists (9 goldens), and the eleven commits `9b2fa6c`, `24f4643`, `db83a14`, `efb043e`, `9641a1b`, `7b58ad5`, `eeeee59`, `fd52868`, `6720cae`, `2baec56`, `72b8383` resolve.

View File

@@ -18,3 +18,15 @@ Each failure below also fails at the plugin's commit before the sweep, with fram
- **sm-user-plugin `updates` migration tests** (`TestExtendUsersMigration`, `TestCreateUserThrottleMigration`, `TestCreateJwtBlacklistMigration`, `user_session_test.go`): "survived rollback", a varying subset per run; also at v0.1.5 with framework v0.3.1.
- **Plugin boot logs on `list`.** Application binaries print INFO boot records (for example `paymentgateway: operators registered`) before `list` and `help` output. Already captured by another session as a todo (summercms.go `c1f5ded`, "Quiet plugin boot logs on console commands like --help").
- **sm-demo-app roadmap snapshot vs local master.** `scripts/sync-roadmap.sh --check` fails against local framework master while other sessions' 19.6 and 19.6.1 planning commits are unpushed; it passes with `ROADMAP_REF=origin/master`. Re-sync after those commits are pushed.
## Found during 19.8-04 (unit tests)
Recorded, not fixed here: none of them is a defect in released behaviour.
- **gofmt drift from plan 03.** `gofmt -l` lists `cmd/summer/main.go`, `cmd/summer/runtime.go`, `cmd/summer/runtime_test.go` (map key alignment) and `modules/flare/commands.go`; each already differs at the plan 03 release. The tests added here are formatted.
- **Dotted component names in YAML.** The diary README and `docs/services/logging.md` say component names cannot contain dots. compass keeps a dotted YAML key literal (`components: {golem15.blog: debug}` parses as component `golem15.blog` and works for `diary.For("golem15.blog")`); only the nested form, which `SUMMER_LOG__` variables produce, is refused. `TestConfigRules` pins both. Either reject the literal form or reword the docs ("use names without dots so environment overrides can reach them").
- **`Version.Header` collapses equal versions.** An application built as `devel` against a `devel` framework prints `SummerCMS acme devel` without `(framework devel)`, the same rule that gives `SummerCMS summer v0.4.0`. Go stamps VCS pseudo-versions on applications, so it shows only with `-buildvcs=false`. Pinned by `TestVersionHeader`.
- **Error blocks scrub credential shapes only.** `RenderError` passes text through `sunscreen.Scrub` (Bearer tokens, `sk-` keys, `x-api-key:`); a `password=...` written into an error message is printed as is. The plan's `TestErrorScrubbed` wording ("a password attribute in the message") is covered for the shapes Scrub knows; extending Scrub is a sunscreen change for every log line and needs its own decision.
- **Live views on a non-terminal writer draw no frames.** `runLive` takes the window size from the terminal; with a buffer the renderer draws nothing but the PrintAbove lines. The widget matrix therefore proves the live path ran (cursor hidden, no fallback lines) and `TestLiveModels` renders the frames with a fixed size; a pty run of spinner, progress and process view printed every final frame (`✓ fast spinner`, `4/4`, `✓ a`, `✗ b bad row`, `Importing 2/2 … 100%`).
- **Landing end-to-end check.** `TestTerminalCommands` (sm-summercmsio-app) runs the deployed one-liner and needs network, Docker and ports 54320 and 8080; the gate runs it only with `SUMMERCMS_TERMINAL_CHECK=1` and prints NOT RUN otherwise.
- **Stray binary in sm-grzybyfunkcjonalne-app.** An untracked `sm-grzybyfunkcjonalne-app` executable sits in that application's root (present before this plan; a `go build` without `-o`). Not this plan's; left alone.