Commit Graph

64 Commits

Author SHA1 Message Date
3da2fd65b0 test(16.2): phase gate
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.
2026-10-10 16:12:19 +02:00
9cac45c389 fix(admin): keep list state in the URL and browser storage
- 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
2026-10-09 21:04:00 +02:00
c5e03f4a3a test(16-05): Phase 16 gate
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".
2026-10-09 20:15:14 +02:00
Jakub Zych
9b3803c098 feat(sunrise): update an application in place with summercms.io/update
- 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
2026-10-08 20:15:50 +02:00
Jakub Zych
c4c91f0f6b chore(14.3-04): keep the gate marker line unique in check-phase14.3.sh 2026-10-08 12:30:11 +02:00
Jakub Zych
89f1ab2c44 chore(14.3-04): fail-closed phase 14.3 gate with --unit, --security and --all
- --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
2026-10-08 12:25:24 +02:00
Jakub Zych
612d0c6dcb chore(14.3-02): add the D-20 container acceptance stages to the phase 14.3 gate
- --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
2026-10-08 11:55:27 +02:00
Jakub Zych
6695ab422a chore(14.3-01): add the phase 14.3 generator gate
- 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
2026-10-08 11:44:44 +02:00
Jakub Zych
27711b7c21 chore(scripts): allow the sanitized markdown preview binding in raw-HTML gates
- 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
2026-10-06 20:58:45 +02:00
Jakub Zych
7307b36baa test(15-04): add fail-closed Phase 15 gate and ASVS L1 review
scripts/check-phase15.sh --all refuses skip/no-tests/race/dirty PHP pin; the review closes T-15-01..15 and T-15-SC with executed TestNames.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-06 19:22:19 +02:00
Jakub Zych
ef03016314 test(14.2.1-06): land remaining named tests and phase gate
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>
2026-10-06 16:28:29 +02:00
Jakub Zych
ba6e4369f6 test(14.2.1-04): add fail-closed check-phase14.2.1.sh
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>
2026-10-06 14:21:56 +02:00
Jakub Zych
3190b1ce59 test(12.1-05): complete the Phase 12.1 gate with the removal, coverage, app and evidence stages
- --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
2026-10-05 16:01:10 +02:00
Jakub Zych
c076b4c059 test(12.1-05): threat test for the Phase 12.1 framework contracts and the first gate stages
- 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
2026-10-05 14:30:31 +02:00
Jakub Zych
a1fccd39ad test(14-06): check-phase14.sh --evidence refuses an incomplete phase record
- 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
2026-10-04 02:11:39 +02:00
Jakub Zych
4c042f7cd5 test(14-06): check-phase14.sh runs the named tests, the coverage floors and the removal harness
- --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
2026-10-04 02:11:15 +02:00
Jakub Zych
88f7683b99 test(14-06): check-phase14.sh gates the phase over both repositories, the corpus and the named flows
- --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
2026-10-04 00:53:53 +02:00
Jakub Zych
ad79b3cca9 test(13-06): run TestOverlapConstraintFallsThrough in the gate's named stage
- The evidence stage refused T-13-23's review row because the named stage
  did not run the test its removal check RC-01 relies on
2026-10-03 11:32:35 +02:00
Jakub Zych
12b961b1c0 test(13-06): add the fail-closed Phase 13 gate
- 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
2026-10-03 11:27:44 +02:00
Jakub Zych
d5494faa81 test(12.2-05): SPA unit tests for the phase and the check-phase12.2 gate
- 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
2026-10-02 20:51:36 +02:00
Jakub Zych
6f4386c2f9 chore(12-05): add the fail-closed Phase 12 gate
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
2026-10-02 16:39:03 +02:00
Jakub Zych
6649763590 chore(12-04): require every album broadcast golden to pass
All four goldens run through the album handlers now: no pending skip is expected
and the named check requires created and updated to pass.
2026-10-02 14:30:13 +02:00
Jakub Zych
7ac6c05ab3 chore(12-04): expect only the updated broadcast golden to skip
The album store handler asserts the created golden now; updated stays pending
until the update handler lands.
2026-10-02 14:01:32 +02:00
Jakub Zych
bbdc7a6b7e fix(09): WR-18 judge the gate's zero-test check per package 2026-10-01 21:35:18 +02:00
Jakub Zych
be51bfe1e1 fix(11.2): WR-04 keep the site gate's summary grep non-fatal
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+.
2026-10-01 17:06:16 +02:00
Jakub Zych
29adc23595 test(11.2): complete the phase gate
- --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
2026-10-01 16:39:09 +02:00
Jakub Zych
f5f9387ac9 test(11.2): cover site_url and site_label and gate the framework, app and site stages
- 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
2026-10-01 16:35:09 +02:00
Jakub Zych
18fe100113 test(11.2): add the phase gate with the plugin stage
- 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
2026-10-01 16:31:20 +02:00
Jakub Zych
037dc53030 feat(lagoon): per-query collation for OrderBy, drop the database locale check
- 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
2026-10-01 09:51:03 +02:00
Jakub Zych
550fa06f91 test(11.1-07): acceptance scanner sees blockquoted and aliased fences; gate plants the holes
- scanDocFences strips blockquote markers and indentation and cross-checks captions
- the phase gate plants callout src=, golang fences, env-prefix and flag-first commands, and wrong-case identifiers
2026-10-01 08:51:58 +02:00
Jakub Zych
85ce154640 fix(11.1-06): remove the docs gate's scratch directories on a refusal
- 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
2026-10-01 00:21:34 +02:00
Jakub Zych
c1c9a9f853 test(11.1-06): acceptance subtests per success criterion and the final docs gate
- 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
2026-10-01 00:10:12 +02:00
Jakub Zych
1d38e73f03 test(11.1-06): plant one fixture per docs checker rule and run them in the gate
- 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
2026-09-30 23:52:19 +02:00
Jakub Zych
93c735b8a2 fix(11-08): make transaction gates fail closed 2026-09-30 22:24:12 +02:00
Jakub Zych
dd11bdb0c7 feat(11.1-02): add the documentation theme, chroma highlighting and docs:serve
- 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
2026-09-30 21:57:55 +02:00
Jakub Zych
5d4c1e3046 feat(11.1-02): check links, commands, forbidden names and fence policy
- 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
2026-09-30 21:40:46 +02:00
Jakub Zych
f4605292b5 feat(11.1-02): check module identifiers in docs and READMEs
- 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
2026-09-30 21:35:56 +02:00
Jakub Zych
d4fc957f8f fix(11-08): add the T-11-31 removal check to the phase gate
- RC-14 removes the foreign-transaction refusal in lagoon.AfterCommit and
  requires TestTransactionAfterCommit to fail
2026-09-30 21:00:20 +02:00
Jakub Zych
61da4d1a4c fix(11): let the Phase 10 gate accept the Phase 12 pending goldens
- 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
2026-09-30 15:22:00 +02:00
Jakub Zych
73cfed74ed fix(11-07): let the Phase 10.1 gate accept the Phase 12 pending goldens
- 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
2026-09-30 14:55:16 +02:00
Jakub Zych
7743487b76 test(11-07): add the fail-closed Phase 11 gate and removal harness
- 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)
2026-09-30 14:42:38 +02:00
Jakub Zych
02df0a8a15 feat(10.1-04): add the fail-closed Phase 10.1 gate
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
2026-09-29 03:13:08 +02:00
Jakub Zych
9aeb0e156b fix(10.1-04): drop the stale parity allow-list from the Phase 10 gate
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.
2026-09-29 03:13:08 +02:00
Jakub Zych
38f087deb3 fix(10.2): exclude planning artifacts from import gate
- Align Git-backed source enumeration with the fallback scan
- Prove tracked historical imports are ignored in self-test
2026-09-28 13:35:11 +02:00
Jakub Zych
4c7d4cc4b9 test(10.2-02): add nested-layout hygiene gate
- Refuse root package directories, old imports, missing READMEs, and stale status text\n- Validate Go vet and tests across framework and Fonoteka
2026-09-28 13:18:08 +02:00
Jakub Zych
5e50b166ef refactor(10.2-01): nest framework packages under modules
- Move remaining beach packages and embedded admin assets\n- Rewrite framework, example, build, and gate paths
2026-09-28 02:21:02 +02:00
Jakub Zych
fbef773a24 test(10-05): hygiene confines browser storage and self-tests each rule
- --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
2026-09-27 18:15:05 +02:00
Jakub Zych
07edc6ca29 test(10-05): fail-closed Phase 10 gate script
- 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
2026-09-27 18:10:59 +02:00
Jakub Zych
dafdb18234 feat(10-01): harden the admin cookie session and prefix boot guards
- 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
2026-09-27 15:34:19 +02:00
Jakub Zych
5f9353841b feat(10-01): serve the embedded admin SPA at backend.uri with cookie login
- backend.uri prefix (default /backend) mounts the admin API at {prefix}/api/v1
  and the embedded SPA shell at {prefix} with an api/ JSON 404 fallback
- cookie transport: an X-Requested-With login sets the HttpOnly summer_admin
  cookie and returns no token; the backend guard reads the cookie after Bearer
- CSRF wrapper refuses cookie-only POST/PUT/DELETE without X-Requested-With
- boardwalk package embeds boardwalk/dist, rewrites index.html once per prefix
  and sets cache and security headers
- framework admin OpenAPI pipeline (swag, swagger2openapi, openapi-typescript)
  with prefix-relative paths and typed envelopes for the tracer routes
- admin/ Vite SPA: login, plugin rail, section panel and read-only list
  through the openapi-fetch client typed by the generated schema
2026-09-27 15:21:48 +02:00