- 10.1-SECURITY-REVIEW.md: T-10.1-01 to T-10.1-22 and T-10.1-SC with mitigation, test or gate stage, observed result and 23 removal checks - 10.1-VALIDATION.md: every plan task mapped to its command, all green under check-phase10.1.sh --all; nyquist_compliant and wave 0 complete - Phase 10 deferred item for the parity failures marked resolved
12 KiB
12 KiB
phase, slug, status, nyquist_compliant, wave_0_complete, created, validated
| phase | slug | status | nyquist_compliant | wave_0_complete | created | validated |
|---|---|---|---|---|---|---|
| 10.1 | runtime-admin-extension-point | validated | true | true | 2026-09-28 | 2026-09-29 |
Phase 10.1 — Validation Strategy
Per-phase validation contract for feedback sampling during execution. Seeded from
10.1-RESEARCH.md§ Validation Architecture; task IDs and statuses are filled in from the executed plans 10.1-01 to 10.1-04 and the final run ofscripts/check-phase10.1.sh --all. Requirement: ADMIN-07.
Test Infrastructure
| Property | Value |
|---|---|
| Framework | Go testing (+ testcontainers Postgres); Vitest 3.2.7 + happy-dom 20.11.6 + @vue/test-utils 2.4.11 |
| Config file | admin/vitest.config.ts; go.mod / go.work |
| Quick run command | go test ./modules/cabana -run 'TestPhase101' -count=1 and npm --prefix admin test -- tests/form tests/list tests/app |
| Full suite command | go vet ./... && go test ./... in both repos, npm --prefix admin run typecheck && npm --prefix admin test |
| Phase gate | scripts/check-phase10.1.sh --all plus scripts/check-phase10.sh --all staying green |
| Estimated runtime | ~120 seconds with warm caches for the test commands; the full gate (npm ci, both repositories, every Postgres suite) takes several minutes |
Sampling Rate
- After every task commit: the quick run command for the touched side (cabana
-run TestPhase101or the touched vitest files), plusgo vet ./... - After every plan wave: full suite in both repos,
scripts/check-admin-openapi.sh --check, andscripts/check-admin-dist.shafter SPA changes - Before
/gsd-verify-work:scripts/check-phase10.1.sh --allandscripts/check-phase10.sh --allgreen - Max feedback latency: 120 seconds
Per-Task Verification Map
Task IDs are {plan}-T{n}. A row lists the task that built the behaviour and the 10.1-04 task that brought its full tests. Every row's command passed in the final gate run.
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|---|---|---|---|---|---|---|---|---|---|
| 10.1-01-T1, 10.1-04-T1 | 10.1-01, 10.1-04 | 1, 4 | ADMIN-07 (D-06, D-09) | T-10.1-11 | widget/partial types; per-type keys; tag prefix {vendor}-{plugin}-; reserved names; unknown key and settings-form use fail boot |
unit | go test ./modules/cabana -run '^TestPhase101FormExtensionSchema$' -count=1 |
✅ | ✅ green |
| 10.1-01-T1, 10.1-04-T1 | 10.1-01, 10.1-04 | 1, 4 | ADMIN-07 (D-07) | T-10.1-05, T-10.1-06, T-10.1-07 | fill ⊆ writable fields; server drops extra keys; action permission + scoped record load | unit + Postgres | go test ./modules/cabana -run '^TestPhase101Actions$' -count=1 |
✅ | ✅ green |
| 10.1-01-T3, 10.1-04-T1 | 10.1-01, 10.1-04 | 1, 4 | ADMIN-07 (D-11) | — | headerPartial compiles; missing template / parse error / missing view model / Winter path fails boot |
unit | go test ./modules/cabana -run '^TestPhase101PartialSchema$' -count=1 |
✅ | ✅ green |
| 10.1-01-T3, 10.1-04-T1 | 10.1-01, 10.1-04 | 1, 4 | ADMIN-07 (D-10, D-17) | T-10.1-08, T-10.1-09, T-10.1-12 | allowlisted node tree; script/on*/style/javascript: dropped; record data escaped; size, node and depth caps; model view model refused | unit | go test ./modules/cabana -run '^TestPhase101PartialSanitizer$' -count=1 |
✅ | ✅ green |
| 10.1-01-T2, 10.1-04-T1 | 10.1-01, 10.1-04 | 1, 4 | ADMIN-07 (D-12) | T-10.1-05 | toolbar names resolved against registered actions; unknown fails boot; permission-filtered and localized per request | unit | go test ./modules/cabana -run '^TestPhase101Toolbar$' -count=1 |
✅ | ✅ green |
| 10.1-01-T2, 10.1-04-T1 | 10.1-01, 10.1-04 | 1, 4 | ADMIN-07 (D-13, D-16) | T-10.1-01, T-10.1-02, T-10.1-03 | exact asset allowlist; MIME + nosniff + CORP; ETag/304; traversal/undeclared → SPA fall-through | unit | go test ./modules/cabana -run '^TestPhase101Assets$' -count=1 |
✅ | ✅ green |
| 10.1-01-T2, 10.1-04-T1 | 10.1-01, 10.1-04 | 1, 4 | ADMIN-07 (D-16) | T-10.1-02 | exported ContentType and SetSecurityHeaders |
unit | go test ./modules/boardwalk -run '^TestPhase101BoardwalkExports$' -count=1 |
✅ | ✅ green |
| 10.1-01-T1, 10.1-01-T2 | 10.1-01 | 1 | ADMIN-07 (D-05) | T-10.1-04 | new POSTs refused without X-Requested-With | unit | go test ./modules/cabana -run '^TestPhase10CSRF$' -count=1 |
✅ | ✅ green |
| 10.1-01-T1, 10.1-01-T2, 10.1-01-T3 | 10.1-01 | 1 | ADMIN-07 (D-05, D-12) | T-10.1-04 | route inventory, permission matrix and OpenAPI conformance cover the new routes | unit + Postgres | go test ./modules/cabana -run '^(TestPhase09PermissionMatrix|TestPhase09ContractInventory|TestPhase10OpenAPIConformance)$' -count=1 && scripts/check-admin-openapi.sh --check |
✅ | ✅ green |
| 10.1-02-T1, 10.1-02-T3, 10.1-04-T2 | 10.1-02, 10.1-04 | 2, 4 | ADMIN-07 (D-14) | T-10.1-13, T-10.1-16 | loader idempotent; foreign and dot-segment URLs refused (encoded too); CSS disabled off-controller | vitest | npm --prefix admin test -- tests/app/pluginAssets.test.ts |
✅ | ✅ green |
| 10.1-02-T1, 10.1-04-T2 | 10.1-02, 10.1-04 | 2, 4 | ADMIN-07 (D-05, D-07, D-08) | T-10.1-17, T-10.1-18 | widget attributes only; event → POST once while busy; patch only fill keys; 5000 ms timeout; create mode | vitest | npm --prefix admin test -- tests/form/WidgetField.test.ts |
✅ | ✅ green |
| 10.1-02-T2, 10.1-04-T2 | 10.1-02, 10.1-04 | 2, 4 | ADMIN-07 (D-09, D-17) | T-10.1-14 | PartialHost renders via h(); unknown tag/attr dropped; text stays text; skeleton, empty, failure and busy-refetch states | vitest | npm --prefix admin test -- tests/list/PartialHost.test.ts tests/form/PartialField.test.ts |
✅ | ✅ green |
| 10.1-02-T3, 10.1-04-T2 | 10.1-02, 10.1-04 | 2, 4 | ADMIN-07 (D-03, D-12) | — | list header slot; custom toolbar button → POST {} → toast → reload; header refetch only after bulk delete and actions | vitest | npm --prefix admin test -- tests/list/ListToolbar.test.ts tests/list/ListView.test.ts |
✅ | ✅ green |
| 10.1-02-T1, 10.1-02-T2, 10.1-04-T2 | 10.1-02, 10.1-04 | 2, 4 | ADMIN-07 (D-09) | — | widget/partial registered, excluded from save body, span labels, render on create, form context provided | vitest | npm --prefix admin test -- tests/form/registry.test.ts tests/form/formState.test.ts tests/form/FormField.test.ts tests/form/FormView.test.ts |
✅ | ✅ green |
| 10.1-02-T1, 10.1-02-T2, 10.1-02-T3 | 10.1-02 | 2 | ADMIN-07 (D-04, D-05, D-17) | T-10.1-14, T-10.1-18 | end-to-end SPA smoke of widget, partials, toolbar actions and scoped stylesheets; framework strings resolve | vitest + unit | npm --prefix admin test -- tests/smoke && go test ./modules/phrasebook -run '^TestPhase10SPAKeysResolve$' -count=1 |
✅ | ✅ green |
| 10.1-04-T3 | 10.1-04 | 4 | ADMIN-07 (D-17) | T-10.1-08, T-10.1-10, T-10.1-14, T-10.1-19, T-10.1-20 | no raw-HTML sinks or HTML-string parsers; plugin assets contain no network, cookie or storage access; partial templates carry no script or handlers; detectors fail closed | gate | scripts/check-phase10.1.sh --self-test && scripts/check-phase10.1.sh --hygiene |
✅ | ✅ green |
| 10.1-02-T1, 10.1-02-T2, 10.1-02-T3, 10.1-04-T2 | 10.1-02, 10.1-04 | 2, 4 | ADMIN-07 (D-04) | T-10.1-SC | committed dist matches source | gate | scripts/check-admin-dist.sh |
✅ | ✅ green |
| 10.1-03-T1 | 10.1-03 | 3 | ADMIN-07 (D-01, D-03) | T-10.1-15 | Albums stats strip scoped per collection; copy in pl and en | integration (Postgres) | cd ../fonoteka.go && go test ./plugins/golem15/fonoteka -run '^(TestPhase101AlbumsSmoke|TestPhase10LangCatalog|TestAlbumsAdminList|TestAlbumsAdminRegistration|TestPhase10ControllerCopy)$' -count=1 |
✅ | ✅ green |
| 10.1-03-T2 | 10.1-03 | 3 | ADMIN-07 (D-02, D-06, D-07) | T-10.1-21, T-10.1-22 | Discogs widget stub fills year and format; a save persists them (json.Number fill) | integration (Postgres) + unit | cd ../fonoteka.go && go test ./plugins/golem15/fonoteka -run '^(TestPhase101AlbumsSmoke|TestAlbumsAdminForm|TestAlbumsAdminCRUD|TestPhase10Controllers|TestPhase10AlbumRelations|TestPhase10AssembledAcceptance)$' -count=1 && go test ./modules/lagoon -run '^TestFillJSONNumber$' -count=1 |
✅ | ✅ green |
| 10.1-03-T3 | 10.1-03 | 3 | ADMIN-07 (D-12) | T-10.1-21 | Sync with Discogs toolbar stub toasts; limited admin 403 | integration (Postgres) | cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/... -count=1 |
✅ | ✅ green |
| 10.1-03-T1, 10.1-03-T2, 10.1-03-T3, 10.1-04-T1 | 10.1-03, 10.1-04 | 3, 4 | ADMIN-07 (D-01, D-02, D-03, D-12) | T-10.1-05, T-10.1-06, T-10.1-09, T-10.1-15, T-10.1-21 | Albums stats strip over two collections; widget stub fills and saves; toolbar action toasts; Genres-only admin 403; assets served; labels resolve in pl and en; every route template in admin.json | integration (Postgres) | cd ../fonoteka.go && go test ./plugins/golem15/fonoteka -run '^(TestPhase101AlbumsExtension|TestPhase101AlbumsSmoke)$' -count=1 |
✅ | ✅ green |
| 10.1-03-T3, 10.1-04-T1 | 10.1-03, 10.1-04 | 3, 4 | ADMIN-07 (D-01) | T-10.1-20 | framework repo has no application names | gate | scripts/check-phase10.sh --hygiene |
✅ | ✅ green |
| 10.1-04-T3 | 10.1-04 | 4 | ADMIN-07 | T-10.1-19, T-10.1-SC | the whole phase: go, security, postgres, spa, openapi, dist, hygiene and evidence stages; Phase 10 gate still green | gate | scripts/check-phase10.1.sh --all && scripts/check-phase10.sh --all |
✅ | ✅ green |
Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky
Wave 0 Requirements
modules/cabana/testdata/extension/— acme fixture plugin tree (config YAML,_stats.htm,_summary.htm, fields/columns,assets/js/lookup.js,assets/css/gadgets.css, en/pl lang)modules/cabana/phase101_*_test.go— schema, sanitizer, assets, actions, toolbaradmin/tests/fixtures/extension.*.json— list/form schema with assets, widget, partial, toolbar actions; partial nodes (from 10.1-02, reused)admin/tests/app/pluginAssets.test.ts,tests/form/WidgetField.test.ts,tests/form/PartialField.test.ts,tests/list/PartialHost.test.ts../fonoteka.go/plugins/golem15/fonoteka/admin_phase101_albums_test.goscripts/check-phase10.1.shwith--self-test,--go,--security,--postgres,--spa,--openapi,--dist,--hygiene,--evidence,--all
No framework install needed.
Manual-Only Verifications
| Behavior | Requirement | Why Manual | Test Instructions |
|---|---|---|---|
Browser loads plugin module script under CSP script-src 'self'; widget renders; fill then save persists; strip and buttons wrap at 768px with pl labels; plugin CSS off on other controllers; Vite /assets dev proxy |
ADMIN-07 (D-13, D-16, D-07) | happy-dom does not enforce CSP, load module scripts or lay out | The human-check blocks of 10.1-02 Task 3 and 10.1-03 Task 3, collected at /gsd-verify-work: summer serve for fonoteka, open /plytadmin Albums in a browser, check the console for CSP errors, click the Discogs widget, save, reload |
Validation Sign-Off
- All tasks have
<automated>verify or Wave 0 dependencies - Sampling continuity: no 3 consecutive tasks without automated verify
- Wave 0 covers all MISSING references
- No watch-mode flags
- Feedback latency < 120s for the per-task commands
nyquist_compliant: trueset in frontmatter
Approval: validated 2026-09-29 by scripts/check-phase10.1.sh --all