- setup: introduction, installation rewritten from install to serve,
configuration with the keys an application sets
- console: introduction, setup and maintenance, scaffolding, writing
commands, utilities; every command name is checker-verified
- bonfire ExampleCatalog shows arguments, bare and repeatable flags
- index links the section introductions; TestDocsRequiredPages lists
the seven new pages
- docs/setup/coming-from-wintercms.md maps WinterCMS concepts to checked
pkg.Ident spans and lists what SummerCMS does not provide
- party BlogPlugin and ExamplePlugin, shown through src= fences
- TestDocsRequiredPages asserts required pages build as .html and .md
- index links the new page
- WinterCMS-style shell: header with search and theme toggle, grouped
sidebar, on-page TOC, pager, page actions, callouts, heading
permalinks, footer and a 404 page
- fenced code highlighted at build time by chroma/v2 into tok-* classes,
with a copy button; no inline script, style or handler
- vendored DM Sans/DM Mono fonts and Lucide icons with their licences
- client-side search over search-index.json built with textContent only
- summer docs:serve builds into a temp dir, serves on loopback by default,
returns 404.html with status 404 and rebuilds on change
- CLAUDE.md: API, config-key and CLI changes update the affected docs
pages; the docs checkers are named; config-key checking is deferred
- todo: wristband's default resource URL and comments name a consuming
application
- relative links and anchors resolve against the renderer's heading IDs
- summer and ./bin/<app> command names come from the real command
constructors through docsite.Options.Commands; a nil set is a problem
- consuming-application names fail in page sources and built outputs
- go fences in docs/ pages need src=, callouts are NOTE, TIP or WARNING,
docs/ headings are plain ASCII
- gate gains --claude and self-test plants for each new rule
- go/parser index of every modules/ package and sub-package, with methods,
fields, interface methods and promoted members
- code spans in docs pages, module READMEs and the root README fail
Check and docs:build when the named identifier does not exist
- scripts/check-phase11.1.sh with preconditions, deps, docs, forbidden,
go and a self-test that plants one violation per rule
- src= fences name a file, a Go declaration or Example body, or a docs:start region
- confinement: relative clean paths inside the root, no dotfiles or .env,
no nested go.mod modules, Examples need // Output:, test regions must run
- a drifted or missing snippet is a problem, so docs:build writes nothing
- docs:sync rewrites drifted fence bodies in place
- fences render in figure.code with a source caption; .md fences keep only the language
- bonfire ExampleCall is the first verified example, shown in setup/installation
- discover modules/<m> with non-test Go files; a missing README is a readme: problem
- one GitHub-compatible slug parser.IDs for heading anchors, passed per page
- rewrite links to .md pages and module READMEs to site .html and .md URLs
- search-index.json gains one entry per H2 with 300-char plain text
- add the api section to docs/site.yaml; docsite.Pages exposes reading order
- tests: TestSlugIDs, TestReadmeIngestion, TestEveryModuleInSidebar, TestDocsAIOutputsInSync
- lagoon.Transaction doc and README state that a nested call over a root
handle returns an error instead of opening an independent transaction
- beachcomber README no longer promises an immediate sync inside a plain
GORM transaction; it is warned and skipped since 11-08
Six plans (tracer generator, site UX and checkers, content A, content B,
acme/blog walkthrough, unit tests). SC4/DOCS-04 narrowed to docs/ pages per
D-18; README Go fence conversion logged as a todo.
- 11-06 records TestBroadcastGoldens/created and /updated and reports them
as skipped until Phase 12; the Phase 10 detector refused any skip, so
check-phase10.sh --all failed on the fonoteka.go suite
- mirrors 73cfed7 (check-phase10.1.sh): the detector accepts exactly those
skips when their output carries 'pending: Phase 12'; the self-test proves
a pending skip passes and one without the text fails
- 11-06 records TestBroadcastGoldens/created and /updated and reports them
as skipped until Phase 12; the 10.1 detector refused any skip, so
check-phase10.1.sh --all failed on the fonoteka.go suite
- the detector now accepts exactly those skips when their output carries
'pending: Phase 12' (the same rule check-phase11.sh enforces); the
self-test proves a pending skip passes and one without the text fails
- 11-SECURITY-REVIEW.md: T-11-01..T-11-30 and T-11-SC with each plan's
severity and disposition, mitigation, test and result; RC-01..RC-13
removal checks for every high mitigated threat; the three defects fixed
in 11-07
- 11-VALIDATION.md: task ids, plans and waves per row, commands run,
status validated, nyquist_compliant and wave_0_complete true
- scripts/check-phase11.sh: --self-test, --hygiene, --go, --postgres,
--named, --evidence, --all (prints 'phase11 all passed') and --removal
- the go test -json detector refuses failures, skips, zero tests and
'no tests to run'; only the two Phase 12 broadcast goldens may skip, and
only with their pending text
- hygiene refuses application names in the Phase 11 framework files, the
Centrifugo/Typesense/Web Push client libraries, a direct cron
requirement, River other than v0.47.0 and a module without README or
root row; each rule returns on its first violation and the self-test
proves each refuses its own plant and accepts look-alikes
- --removal: anchor-exact mutations for the high threats, each required to
fail its named test on an assertion and restored byte for byte (cmp)
- TestSyncEngineRegistration: the typesense import registers the driver
and a missing or blank api_key reports Configured false, the gate that
keeps beachcomber from sending anything
- TestCentrifugoRecorder: info/unsubscribe answers, 405 with Allow, 413
above the body cap (not recorded), authorization as a comparison that is
never stored, empty key never authorized, loopback ListenAndServe and
shutdown, waitListening and sleepCtx failures
- TestFlowIDNames: default masked id variables
- TestEngineWire: API key and Accept on every request, create on 404 with
the schema or auto fields, 409 as success, JSONL import with
success:false and unreadable lines as errors (message capped, no
document), 404-tolerant delete/flush with id escaping, SearchIDs
parameters and id parsing, typed errors without bodies, transport
errors without the URL, timeout
- TestEngineConfig: search.typesense.* parsing and the registered engine
(coverage 95.6%)
- beachcomber and lighthouse released their savepoint whenever the inner
function reported no error; a Gate that counts a failed read as off,
or a channel function or delete snapshot that swallows one, left the
caller's Postgres transaction aborted (25P02) and failed the write
- a failed RELEASE now rolls back to the savepoint, as the READMEs promise
- beachcomber gets its testcontainers harness and sync tests
(TestSyncGates, TestSyncAfterCommit, TestSyncDeleteAndSoftDelete,
TestSyncFailuresNonFatal, TestServiceSetup); lighthouse gets
TestBroadcastSwallowedReadFailure
- lighthouse:after_create/update/delete also declare
Before(gorm:commit_or_rollback_transaction); an After-only anchor put
them past GORM's own commit, so a plain gdb.Create enqueued its
broadcast job after the commit on the pool (deferred from 11-05)
- lighthouse gets the testcontainers Postgres harness and TestBroadcastTx
(commit publishes once, rollback nothing, single-statement write
enqueues on its own transaction, failed write enqueues nothing)
- lagoon.Transaction, the lagoon:after_commit flush and the immediate
AfterCommit path pass a handle with an empty statement on the write's
connection (Session NewDB+Context, Clauses(), Session NewDB)
- a WithContext query through the handle no longer continues from the
written model's statement (deferred from 11-05)
- TestTransactionAfterCommit/callback_handle_has_a_clean_statement covers
the implicit, plain-transaction and lagoon.Transaction paths
- centrifugo.Client.Info probes the info API method; an error body fails
- websockets:health ports CentrifugoHealthCheck: exits 1 without an API
key or when the probe fails, prints the Setting/Value table otherwise
- websockets:generate-vapid-keys prints a new P-256 pair, shows configured
keys only truncated, and --update persists them to overrides.yaml
- websockets:test-push reads subscriptions from an app-published
SubscriptionSource, refuses to send while push is disabled and sends
one encrypted push per subscription
- no command prints a configured private key or the Centrifugo API key
- flare and lighthouse READMEs document the CLI commands
Persist rewrote overrides.yaml with only this process's runtime values,
so saving one key (for example websockets:generate-vapid-keys --update)
dropped every key persisted earlier. It now starts from the saved file
and lets runtime values win.
- RFC 8291 aes128gcm encryption from crypto/ecdh, crypto/hkdf and AES-GCM,
matching the RFC 8291 Appendix A vector byte for byte
- RFC 8292 vapid t=<ES256 JWT>, k=<key> header (aud origin, exp +12h, sub)
- Pusher, Subscription, SendOptions, SubscriptionSource, Service and From
reading push.* (enabled, keys, subject, ttl, allowed_hosts)
- sends only to https endpoints on push.allowed_hosts, checked before
dialing, and never follows redirects; 404/410 map to ErrSubscriptionGone
- module README and root modules row