7.7 KiB
7.7 KiB
phase, slug, status, nyquist_compliant, wave_0_complete, created
| phase | slug | status | nyquist_compliant | wave_0_complete | created |
|---|---|---|---|---|---|
| 10.1 | runtime-admin-extension-point | draft | false | false | 2026-09-28 |
Phase 10.1 — Validation Strategy
Per-phase validation contract for feedback sampling during execution. Seeded from
10.1-RESEARCH.md§ Validation Architecture; task IDs are filled in once PLAN.md files exist.
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 (new) plus scripts/check-phase10.sh --all staying green |
| Estimated runtime | ~120 seconds with warm caches (Postgres containers dominate) |
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 ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|---|---|---|---|---|---|---|---|---|---|
| TBD | TBD | TBD | D-06, D-09 | T-10.1-11 | widget/partial types; per-type keys; tag prefix {vendor}-{plugin}-; unknown key fails boot |
unit | go test ./modules/cabana -run '^TestPhase101FormExtensionSchema$' -count=1 |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | 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 |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | D-11 | — | headerPartial compiles; missing template / parse error / missing view model fails boot |
unit | go test ./modules/cabana -run '^TestPhase101PartialSchema$' -count=1 |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | 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 caps | unit | go test ./modules/cabana -run '^TestPhase101PartialSanitizer$' -count=1 |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | D-12 | T-10.1-05 | toolbar names resolved against registered actions; unknown fails boot; permission-filtered | unit | go test ./modules/cabana -run '^TestPhase101Toolbar$' -count=1 |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | 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 |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | D-05 | T-10.1-04 | new POSTs refused without X-Requested-With | unit | go test ./modules/cabana -run '^TestPhase10CSRF$' -count=1 |
✅ | ⬜ pending |
| TBD | TBD | TBD | 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 |
✅ extend | ⬜ pending |
| TBD | TBD | TBD | D-14 | T-10.1-11, T-10.1-13 | loader idempotent; foreign URL refused; CSS disabled off-controller | vitest | npm --prefix admin test -- tests/app/pluginAssets.test.ts |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | D-05, D-07, D-08 | T-10.1-07 | widget attributes; event → POST; patch only fill keys; create mode | vitest | npm --prefix admin test -- tests/form/WidgetField.test.ts |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | D-17 | T-10.1-08 | PartialHost renders via h(); unknown tag/attr dropped; text stays text | vitest | npm --prefix admin test -- tests/list/PartialHost.test.ts tests/form/PartialField.test.ts |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | D-03, D-12 | — | list header slot; custom toolbar button → POST → toast → reload | vitest | npm --prefix admin test -- tests/list/ListToolbar.test.ts tests/views/ListView.test.ts |
✅ extend | ⬜ pending |
| TBD | TBD | TBD | D-09 | — | widget/partial registered, excluded from save body, render on create | vitest | npm --prefix admin test -- tests/form/registry.test.ts tests/form/formState.test.ts |
✅ extend | ⬜ pending |
| TBD | TBD | TBD | D-17 | T-10.1-08, T-10.1-10 | no raw-HTML sinks; plugin assets contain no fetch/XMLHttpRequest/document.cookie | gate | scripts/check-phase10.1.sh --self-test && scripts/check-phase10.1.sh --hygiene |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | D-04 | — | committed dist matches source | gate | scripts/check-admin-dist.sh |
✅ | ⬜ pending |
| TBD | TBD | TBD | D-01, D-02, D-03, D-12 | T-10.1-05, T-10.1-06, T-10.1-09 | Albums stats strip scoped per collection; widget stub fills; toolbar action toasts; limited admin 403; assets served | integration (Postgres) | cd ../fonoteka.go && go test ./plugins/golem15/fonoteka -run '^TestPhase101AlbumsExtension$' -count=1 |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | D-01 | — | framework repo has no Płytarium names | gate | scripts/check-phase10.sh --hygiene |
✅ | ⬜ pending |
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)modules/cabana/phase101_*_test.go— schema, sanitizer, assets, actions, toolbaradmin/tests/fixtures/extension.*.json— list/form schema with assets, widget, partial, toolbar actions; partial nodesadmin/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 |
D-13, D-16, D-07 | happy-dom does not enforce CSP or real module loading | summer serve for fonoteka, open /plytadmin Albums form in a browser, check 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
nyquist_compliant: trueset in frontmatter
Approval: pending