- go stage: TestPhase10ConformanceInventory (Docker-free), and the Journal
TestSiteCachePurgeConfig and TestSiteCachePurgeRequest by name
- postgres stage: TestPhase10OpenAPIConformance and the Journal
TestCategoriesAdminPurgesSiteCache and TestPostsAdminPurgesSiteCache
- layer stage: the four site cache purge tests by name
- new cache stage: playground build, purge-check, then the acme SSR smoke
on the same route-cached build
Fail-closed stages go, admin, editor, layer, docs and postgres with go,
vitest-JSON and TAP detectors, the editor corpus copy comparison and a
self-test that proves each fails on planted output. --all runs postgres
only when a Docker daemon answers and otherwise prints a loud NOT RUN
notice; PHASE162_REQUIRE_POSTGRES=1 makes that a failure.
- listState.ts stores each list's query (search, sort, dir, page, per_page,
filter[name]) under summer-admin.list:<controller>; an empty query is
never stored, malformed stored values are dropped like a hand-edited URL
- ListView restores the stored query into the URL before its first list
request when entered without list params; a URL with list params wins
- a 422 forgets the stored query; an out-of-range page clamps to last_page
- logout clears every stored list query
- check-phase10.sh allows browser storage in useSidebar.ts and listState.ts
- list smoke tests start from a clean list state
- rebuilt modules/boardwalk/dist
scripts/check-phase16.sh runs the layer unit tests, the layer playground
SSR smoke, the site app install/build/tests/smokes, the host boot tests,
the grzyby command tests with -race and check-deploy. Each stage fails on
not ok, fail/skip/todo/cancelled counts, missing named tests, go test
failures, skips, no tests to run, data races or a smoke without ok; it
ends with "Phase 16 gate passed".
- new.sh gains --update, run inside one application directory (go.mod and
summer.yaml required); it changes only that application
- the framework checkout is read from the app's go.mod replace (single-line
or block form); module-version replaces, missing targets and foreign or
dirty checkouts are refused through the shared check_framework_dir
- a detached checkout moves fast-forward only to the newest release (or
SUMMERCMS_REF) through the shared move_detached; a branch checkout is
pulled with git pull --no-rebase --ff-only, refusing a missing upstream
or a diverged branch with the checkout unchanged
- other sm-*-app directories on the same checkout are named on one
"not rebuilt" line and never built or written
- summer is reinstalled, a missing SUMMER_ADMIN__JWT__SECRET is appended to
this app's .env (openssl, else head and base64; mode kept, never printed),
then summer build runs and the script ends with the migrate and restart
reminder and the shared path_hint
- sunrise.UpdateScript() serves the same script with its last line changed
to main "$@" --update, so truncated downloads still run nothing
- check-phase14.3.sh --forbidden now allows only the literal
SUMMER_ADMIN__JWT__SECRET in new.sh and still fails on any other
SUMMER_ name or on a read or export of one; TestUpdateScript and
TestUpdateScriptRoute are required tests
- --unit: vet, full suite with named --- PASS lines for every required test,
goldens unchanged, examples/hello, docs check, site plugin/app, landing page
- --forbidden: no SUMMER_ name in new.sh, no new go.mod require since v0.1.12,
no plugin/yaegi dependency, relative golden paths, goldens not ignored
- --bootstrap and --terminal run the gated end-to-end checks
- --security parses the threat register; --all runs every stage in its own process
- --acceptance: in a bare node:24-bookworm container install jq, the Docker
CLI and compose plugin (Docker apt repo) and Go 1.27.0 (sha256 from go.dev),
pipe the committed new.sh into bash with SUMMERCMS_REPO=/fw and
SUMMERCMS_REF=HEAD, then run the D-20 chain and require the starter route
- refuses when modules/sunrise/new.sh differs from HEAD; unique compose
project with host-side cleanup of containers, volumes and networks
- --acceptance-production: same chain against https://summercms.io/new
- scripts/check-phase14.3.sh --generator runs summer new next to a
symlinked checkout with no git identity, checks the layout and first
commit, then docker compose up, summer build, migrate and serve, and
requires the starter route to answer
Claude-Session: https://claude.ai/code/session_01M8Qu9LgCKYy7iYEho52tW8
- check-phase10, 12.1, 12.2 and 14.2.1 drop only the exact
MarkdownField.vue line binding sanitizedHtml (server-rendered by
cabana.RenderMarkdown); every other raw-HTML sink is still refused
WR-02 proofs and T-14.2.1-19..23 must fail the phase closed if hydration or child locale validation is removed.
Co-authored-by: Cursor <cursoragent@cursor.com>
Require named PASS lines, real Postgres, sibling go -C, and a closed high-threat review before the phase gate can pass.
Co-authored-by: Cursor <cursoragent@cursor.com>
- --go, --spa, --openapi, --dist, --docs and --hygiene on the pattern of the Phase 12.2 gate
- --app runs vet and the tests of every module of the application workspace, with the application's name masked in output
- --coverage refuses a package of pact, cabana or the user plugin below 80 percent
- --removal: 27 anchor-exact mutations, one per high or critical protection and one per fix; a dirty file is refused and every file is restored and compared with cmp
- --evidence ties every threat of the five plans to a review row, a test and a removal row
- --self-test plants an input for every detector
- TestPhase121Threats: one subtest per mitigated threat T-12.1-01 to T-12.1-15
- roster fixture: sentinel names and knobs for failing hooks and providers
- scripts/check-phase12.1.sh: fail-closed go test detector, --self-test and --security
- every T-14 threat has one review row copying its plan's severity and
disposition; a mitigated one names a test --named runs and a removal row
- the validation map is validated, Nyquist-compliant and Wave 0 complete,
with no open row and only tests --named runs
- each COVERAGE.md INTEGRATE row names a run test, each OPT-OUT a reason
- REQUIREMENTS.md keeps no SDK wording for INTG-02 and no sitemap output
for API-08; the ROADMAP Phase 14 repos and criteria name the album
Discogs and recognize routes and both shared plugin repos
- --all runs it after the coverage stage
- --named runs every test the validation map and the security review name,
by package, the fonoteka, discogs, golem and feedback suites with -race
- --coverage enforces the 80% floor on the framework packages, classes/
discogs, console and every package of both shared plugins, and on each of
the 132 Phase 14 functions of the fonoteka root, classes and
controllers/api (two exemptions with their reasons)
- --removal applies 43 anchor-exact mutations, one or more per mitigated
threat, requires the named test to fail on an assertion and restores
each file byte for byte; the self-test plants each refusal
- --self-test proves each detector fails on planted failing, skipped,
zero-test, racy and non-JSON runs, a fourth pending route, a vendor SDK
in the module graph and planted corpus secrets
- --go runs vet and tests in summercms.go and, with -race, in fonoteka.go
including sm-golem-plugin and sm-feedback-plugin
- --parity requires 175 recorded, 172 ported and passing, 3 pending, every
TestFonotekaNuxtFlows subtest, the sidecar replay, check_corpus secrets
and the docs checks
- scripts/check-phase13.sh with --self-test, --go, --parity, --named,
--removal, --coverage, --evidence and --all, modelled on check-phase12
- Parity reads the replay's own coverage line: 157 ported and passing,
0 failing, 14 recorded and not ported; every TestFonotekaNuxtFlows
subtest, the three wishlist goldens, docs checks and the corpus scan
- Coverage floors of 80% for surf, conga, lagoon, tide and the four
application packages, the user plugin's classes and every function of
controllers/registration.go, and the controllers package's pre-phase value
- 31 anchor-exact removal checks with cmp restore, dirty-file refusal and
a signal-safe restore; FORCE_COLOR unset by the gate itself
- sessionKey, dateFormat, FileuploadField (protected thumbnails and
keyboard reorder backstops), RelationChildModal, RelationPivotModal,
RelationManager row actions and create-screen deferral, date and time
list cells; typed deferred relation-schema and file-list fixtures
- scripts/check-phase12.2.sh: go, security (named tests, refuses missing
or skipped), spa, openapi, dist, docs, hygiene and app stages, a
detector self-test, one PASS or FAIL line per stage under --all
scripts/check-phase12.sh, modelled on check-phase11.sh:
- --go: vet and test both repositories, golang.org/x/image pinned at v0.46.0
- --parity: 99 ported routes in the manifest, TestParityCorpus with its
coverage subtest, all four broadcast goldens, both Nuxt flows,
check_corpus --require-recorded --check-secrets and a secret scan of the
fuzz seed corpus
- --named: every test 12-VALIDATION.md names, by exact name, the fonoteka
plugin's under -race
- --removal: 25 anchor-exact mutations behind 12-SECURITY-REVIEW.md, each
required to fail its named test on an assertion; a dirty file is
refused and every file is restored and compared with cmp
- --coverage: an 80% floor per Phase 12 package in both repositories
- --evidence: one review row per T-12 threat, a removal row per high
mitigated threat, a green validation file naming only tests the gate runs
- --self-test: every detector, plant and harness branch fails closed
Under set -e a missing TAP summary aborted run_site without a refuse
message; the explicit refuse checks now report it. The site's test
script pins the TAP reporter so the summary lines exist on Node 23+.
- --built: build.sh (release when the framework checkout has v0.1.0, else
dev), then TestLandingLinks, TestTerminalCommandsInPage and
TestDocsHeaderSiteLink with SUMMERCMS_REQUIRE_BUILD=1, required to PASS
- --smoke and --deploy require smoke: ok and check-deploy: ok
- --terminal runs TestTerminalCommands with this checkout as the clone URL;
--verbatim leaves the page's URL for the cutover run
- --full runs the framework's whole suite; --all runs every stage in order
- TestCheckSiteURL (21 accepted and rejected values), TestSiteLabel and
TestSiteURLPrecedence (option over site.yaml, label-without-URL and
invalid option errors); new TestParseSite rows for blank and two-line labels
- TestSiteLink: escaped label, section page and 404 page, exact unset header
bytes
- TestDocsSiteFlagsInHelp and the --site-label-without-URL error
- check-phase11.2.sh --framework, --app and --site
- scripts/check-phase11.2.sh --plugin: go vet, the named plugin tests through
a go test -json detector (fail, skip, missing test, zero tests and no tests
to run all refuse) and a 90% statement coverage floor
- unknown modes print usage and exit 2
- lagoon.OrderBy takes variadic lagoon.OrderOption values; lagoon.Collate(name)
emits a validated, double-quoted COLLATE clause (e.g. "pl-x-icu")
- remove the exported CheckLocale and the ICU pl-PL check from Open and Use
- framework test containers and per-test databases are plain PostgreSQL
- lagoon README, root README and docs pages drop the locale requirement;
queries-and-pagination gains a "Sorting with a collation" section
backed by ExampleCollate
- a refusal exits from inside a stage, where the RETURN trap never ran,
leaving the self-test's 48 MB scratch copy in /tmp; an EXIT trap now
removes every stage's scratch paths
- the self-test copies examples/ with tar, excluding examples/*/bin,
instead of git ls-files, so a PHASE11_1_ROOT copy without .git works
- TestPhase11_1Acceptance asserts SC1 to SC5 on the real tree: sections
and module pages, theme markers and no Node exec, AI outputs in sync,
every go fence a src= copy run by go test, concept map and walkthrough
- check-phase11.1.sh --named runs every named test of the phase by exact
name (modules' TestDocs* and output Examples derived from source) and
refuses failures, skips, missing or renamed tests and no tests to run
- --all runs preconditions, deps, self-test, docs, forbidden, claude,
named and the full go vet and go test
- testdata/clean passes every check; 63 violation cases each overlay one
fault and a want.txt naming the single problem it must produce
- TestPlantedViolations also plants the forbidden name (split literals)
and symlink escapes at run time; TestBuildOutputGuard covers --out
- check-phase11.1.sh --self-test runs the corpus through a go test -json
detector that refuses FAIL, SKIP, zero tests and no tests to run
- the self-test scratch copy now carries examples/ and README.md, so its
baseline sees the example command literals the real tree sees
- 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
- 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
- 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
- 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)
scripts/check-phase10.1.sh: --self-test, --go, --security, --postgres,
--spa, --openapi, --dist, --hygiene, --evidence and --all.
- phase101_detect refuses failed, skipped, zero-test, non-JSON and
build-failed runs and required tests that did not pass
- hygiene_101 refuses HTML-string parsers in admin/src, network, cookie
or storage access in application plugin asset JS, and script, style or
inline handler markup in application partial templates; each rule is
proven by its own self-test plant
- --evidence requires a review row and, for every high threat, a named
test and a removal check row
TestMigrateSeedsCanonicalGenres and TestSchemaMatchesPHPSnapshot pass
since fonoteka.go 21c0f12, and the detector refuses an allow-listed
failure that passes, so check-phase10.sh --go failed. The gate now
allow-lists nothing.
- --hygiene refuses localStorage, sessionStorage, indexedDB or document.cookie
outside admin/src/state/useSidebar.ts (T-10-22)
- --self-test plants each violation with a scratch test import, so the
refusal must come from that rule and not from the untested-module check
- scripts/check-phase10.sh with --self-test, --go, --security, --postgres,
--spa, --openapi, --dist, --hygiene, --evidence and --all
- phase10_detect refuses failed, skipped, zero-test, non-JSON and build-failed
go test runs and named tests that did not pass
- the two known fonoteka parity failures are the only allow-listed ones and
refuse the gate once they pass again
- hygiene enforces the framework/app boundary, SC-4 alias-only API types,
typed-client-only HTTP, no raw HTML, same-origin dist, named lucide imports,
no retired admin prefix routes and a test import for every SPA module
- refresh and logout read the Bearer header first, then the summer_admin
cookie; a cookie refresh rotates the cookie without a token in the body and
logout always expires the cookie
- backend.cookie_secure (default true) may drop Secure outside production only
- activation rejects controller vendor segments api, assets, login, settings
- BuildRouter rejects non-cabana routes at or under the admin prefix
- SPA single-flights refresh on 401, replays once, and refreshes proactively
at 80 percent of expires_in; dist rebuilt
- scripts/check-admin-dist.sh rebuilds the SPA and fails on dist drift
- tests: TestPhase10CookieAuth, TestPhase10CSRF, TestPhase10Prefix,
TestPhase10AdminPrefixCollision, boardwalk serving and header tests