docs(16.2): re-verify after gap closure 16.2-07 and UAT; phase complete

16.2-VERIFICATION.md passed 14/14: the five human items are resolved by the
16.2-07 gate log and the UAT re-run on v0.1.20 (16.2-UAT.md 5/5). covered_files
adds 16.2-07 PLAN/SUMMARY and openapi_conformance_test.go; digest recomputed
with verification.fingerprint. Re-verified by hand because msd-core 1.14.0
re-stales a report after gap closure and its verifier ignores passed UAT.
STATE points at 16.3 (phase.complete picked 11, an executed phase that is
only stale).
This commit is contained in:
2026-10-10 23:39:54 +02:00
parent ed8210132e
commit a04ba35271
4 changed files with 67 additions and 46 deletions

View File

@@ -999,7 +999,7 @@ Plans:
**Goal:** Plugins can register their own admin form field types (todo: cabana-richeditor-field-type), and the Journal plugin ships a first-class Blog Editor formwidget for post content — beyond the current markdown field or a plain rich editor — that edits imported HTML posts losslessly.
**Requirements**: TBD
**Depends on:** Phase 16.1
**Plans:** 6/7 plans executed
**Plans:** 7/7 plans complete
Plans:
**Wave 1**
@@ -1017,7 +1017,7 @@ Plans:
- [x] 16.2-06-PLAN.md — Unit tests: resave contract at every layer, strip-and-report and notices, policy cross-check corpus (both policies, identical copies), category strip, full Go and JS coverage, Postgres tests for a Docker host, phase gate scripts/check-phase16.2.sh, validation map
**Wave 5** *(gap closure, blocked on Wave 4 completion)*
- [ ] 16.2-07-PLAN.md — Gap closure G-16.2-1 and G-16.2-2: conformance cases for GET /field-types and the field upload route, Docker-free route inventory in the gate, TestJournalSVGEmbed fix; Journal post/category admin saves purge the host Nuxt route cache after commit through a token-protected vue-journal-layer route (browsers revalidate); full gate incl. postgres, release summercms v0.1.20 and vue-journal-layer v0.3.0, UAT redeploy, re-run of UAT Tests 3 and 2
- [x] 16.2-07-PLAN.md — Gap closure G-16.2-1 and G-16.2-2: conformance cases for GET /field-types and the field upload route, Docker-free route inventory in the gate, TestJournalSVGEmbed fix; Journal post/category admin saves purge the host Nuxt route cache after commit through a token-protected vue-journal-layer route (browsers revalidate); full gate incl. postgres, release summercms v0.1.20 and vue-journal-layer v0.3.0, UAT redeploy, re-run of UAT Tests 3 and 2
### Phase 16.3: Backend admin personal API tokens with scopes (INSERTED)

View File

@@ -1,19 +1,20 @@
---
msd_state_version: "1.0"
milestone: v1.0
current_phase: "16.2"
current_phase_name: Plugin-provided field types and the Blog Editor formwidget (INSERTED)
status: executing
stopped_at: Completed 16.2-07-PLAN.md
last_updated: "2026-10-10T19:05:40.959Z"
current_phase: "16.3"
current_phase_name: Backend admin personal API tokens with scopes
status: planning
stopped_at: "Phase 16.2 complete (re-verified after 16.2-07, UAT 5/5); Phase 16.3 ready to plan"
last_updated: "2026-10-10T21:39:28.413Z"
last_activity: 2026-10-10
last_activity_desc: Phase 16.2 execution started
state_head: aba063f723fbf629d1a2968dc1c8309926dc36fd
last_activity_desc: Phase 16.2 complete, next Phase 16.3
state_head: ed8210132ed77af6a5abdf65949357d4b5b14f8c
progress:
total_phases: 35
completed_phases: 13
total_plans: 158
completed_plans: 154
percent: 48
gsd_state_version: "1.0"
milestone_name: milestone
---
@@ -25,22 +26,22 @@ milestone_name: milestone
See: .planning/PROJECT.md (updated 2026-09-16)
**Core value:** An existing WinterCMS-shaped app can be ported plugin by plugin to a single Go binary without its frontend noticing: the PHP version's API contract is the acceptance test.
**Current focus:** Phase 16.2 — Plugin-provided field types and the Blog Editor formwidget (INSERTED)
**Current focus:** Phase 16.3 — Backend admin personal API tokens with scopes
## Current Position
Phase: 16.2 (Plugin-provided field types and the Blog Editor formwidget (INSERTED)) — EXECUTING
Plan: 2 of 7
Status: Ready to execute
Last activity: 2026-10-10 — Phase 16.2 execution started
Phase: 16.3 (Backend admin personal API tokens with scopes) — READY TO PLAN
Plan: Not started
Status: Ready to plan
Last activity: 2026-10-10 — Phase 16.2 complete, next Phase 16.3
Progress: [██████████] 100%
Progress: [█████░░░░░] 48%
## Performance Metrics
**Velocity:**
- Total plans completed: 65
- Total plans completed: 71
- Average duration: 21 min
- Total execution time: 104 min
@@ -59,6 +60,7 @@ Progress: [██████████] 100%
| 10 | 5 | - | - |
| 10.2 | 2 | - | - |
| 14.1 | 2 | - | - |
| 16.2 | 7 | - | - |
**Recent Trend:**
@@ -750,5 +752,5 @@ Items acknowledged and carried forward from previous milestone close:
## Session Continuity
Last session: 2026-10-10T19:05:40.225Z
Stopped at: Completed 16.2-07-PLAN.md
Stopped at: Phase 16.2 complete, ready to plan Phase 11
Resume file: None

View File

@@ -1,8 +1,8 @@
---
phase: 16.2-plugin-provided-field-types-and-the-blog-editor-formwidget
verified: 2026-10-10T17:05:00Z
status: human_needed
score: 13/14 must-haves verified
verified: 2026-10-10T20:10:00Z
status: passed
score: 14/14 must-haves verified
covered_files:
- .planning/phases/16.2-plugin-provided-field-types-and-the-blog-editor-formwidget/16.2-01-PLAN.md
- .planning/phases/16.2-plugin-provided-field-types-and-the-blog-editor-formwidget/16.2-01-SUMMARY.md
@@ -16,6 +16,8 @@ covered_files:
- .planning/phases/16.2-plugin-provided-field-types-and-the-blog-editor-formwidget/16.2-05-SUMMARY.md
- .planning/phases/16.2-plugin-provided-field-types-and-the-blog-editor-formwidget/16.2-06-PLAN.md
- .planning/phases/16.2-plugin-provided-field-types-and-the-blog-editor-formwidget/16.2-06-SUMMARY.md
- .planning/phases/16.2-plugin-provided-field-types-and-the-blog-editor-formwidget/16.2-07-PLAN.md
- .planning/phases/16.2-plugin-provided-field-types-and-the-blog-editor-formwidget/16.2-07-SUMMARY.md
- admin/src/app/fieldTypes.ts
- admin/src/components/form/fields/MLPluginField.vue
- admin/src/components/form/fields/PluginField.vue
@@ -26,42 +28,39 @@ covered_files:
- modules/cabana/field_type.go
- modules/cabana/field_type_upload.go
- modules/cabana/http.go
- modules/cabana/openapi_conformance_test.go
- modules/cabana/relation_field.go
- modules/cabana/tx_context.go
- modules/pact/capabilities.go
- scripts/check-phase16.2.sh
covered_digest: "v2:sha256:9eb467f60a452579c8faedf8900a27909d5234623d4f6760fef9f5691bbf6d75"
behavior_unverified: 1
covered_digest: "v2:sha256:1172372f0148895ed07ee76d9d0d9996ba7497c35d22ad3443e564c7a817e5d4"
behavior_unverified: 0
overrides_applied: 0
behavior_unverified_items:
- truth: "D-19 (amended): Journal category content uses blogeditor and is stripped and reported like post content; the 422 CheckHTML gate is retired"
test: "On a Docker host run `bash scripts/check-phase16.2.sh postgres` (TestCategoriesAdminContent, TestCategoriesAdminBlogEditor); on UAT change one word of a category's content in the Blog Editor and save"
expected: "Both Postgres tests pass; on UAT the save succeeds with no removal notice and the category page on the site shows the change"
why_human: "The code is present and wired (fields.yaml type blogeditor, prepareCategoryWrite no longer refuses, the shared Decode is unit-tested), but the end-to-end category save only runs in the Docker-only harness and the UAT category step was never performed (WINDOWS entry 18)"
human_verification:
re_verification: "2026-10-10, after gap closure plan 16.2-07 (G-16.2-1, G-16.2-2) and human UAT on the v0.1.20 UAT deploy; manual re-verification because msd-core 1.14.0 loops stale/human_needed after gap closure"
human_verification_resolved:
- test: "On a host with Docker, run `bash scripts/check-phase16.2.sh postgres` from summercms.go"
expected: "TestFieldTypeSavePostgres, TestListRelationSearchPostgres, TestPostsFormCompiles, TestPostsAdminCreateSmoke, TestPostsAdminResaveKeepsHTML, TestPostsAdminSaveSanitizesHTML, TestCategoriesAdminContent, TestCategoriesAdminBlogEditor and TestJournalSVGEmbed all pass (closes WINDOWS 11, 12, 14, 15, 16, 20, 21)"
why_human: "No Docker daemon on this host; the suites compile under go vet but have never run. They are the only end-to-end proof of the CR-01 and WR-04 Load changes, which landed after the UAT acceptance"
result: pass
evidence: "Full gate at ee62410 (gate2.log, 2026-10-10 18:44): phase16.2 postgres passed, 293 cabana and 78 sm-journal-plugin top-level tests; 'Phase 16.2 gate passed', exit 0. No non-planning change since. UAT Test 1"
- test: "D-19 on UAT: change one word of a category's content in the Blog Editor and save"
expected: "The save succeeds with no removal notice; the category page shows the change"
why_human: "WINDOWS entry 18; not among the four UAT steps the human ran"
- test: "After the next deploy (v0.1.19 with the review fixes), save post 1 and post 64 untouched again and re-run the read-only md5 SELECT"
expected: "md5(content), md5(content_html) and the post 64 en translation md5 equal the 16.2-05 snapshot; updated_at moved"
why_human: "The UAT D-03 evidence was taken on the v0.1.18 binary. The review fixes changed Load (CR-01: blank content served as content_html; WR-04: '<'-prefixed values compared with content_html). By reading the code the served value for posts 1 and 64 is unchanged, but the deployed proof predates the change"
- test: "Blog Editor preview pane in a real browser (quick 261010-iwu): toggle Preview in light and dark mode, narrow the window, put a <script> in a raw HTML block, add a YouTube embed and a relative /storage image"
expected: "50/50 split that wraps below about 720px; the script does nothing in the pane; the embed shows a thumbnail card; the relative image resolves"
why_human: "happy-dom cannot enforce iframe sandboxing, CSP or layout"
- test: "Judgment-tier prohibition (plan 02): 'The element renders no iframe and no live raw HTML in the admin'. Confirm the preview pane folded in from quick 261010-iwu is an accepted exception"
expected: "Human accepts that the sandboxed srcdoc iframe (empty sandbox, CSP meta, active content dropped, no src) does not violate the intent, or asks for a change"
why_human: "The preview pane renders the post HTML inside an iframe in the admin, which reads against the literal prohibition text; the LLM judgment is that its intent (no YouTube iframe, no script-capable raw HTML in the admin DOM) still holds"
result: pass
evidence: "16.2-07 Task 6 on v0.1.20: category 2 saved with no removal notice, edit visible on the first view of /cordyceps; category-purged and category-fresh pass. UAT Test 2"
- test: "After the next deploy, save post 1 and post 64 untouched again and re-run the read-only md5 SELECT"
result: pass
evidence: "16.2-07 Task 6 on v0.1.20 (includes CR-01/WR-04): posts-unchanged and translations-unchanged pass, updated_at moved past the 17:57:57Z restart. UAT Test 3"
- test: "Blog Editor preview pane in a real browser"
result: pass
evidence: "UAT Test 4"
- test: "Judgment-tier prohibition: sandboxed preview iframe accepted as an exception"
result: pass
evidence: "Human accepted. UAT Test 5"
---
# Phase 16.2: Plugin-provided field types and the Blog Editor formwidget Verification Report
**Phase Goal:** Plugins can register their own admin form field types (todo: cabana-richeditor-field-type), and the Journal plugin ships a first-class Blog Editor formwidget for post content (beyond the current markdown field or a plain rich editor) that edits imported HTML posts losslessly.
**Verified:** 2026-10-10T17:05:00Z
**Status:** human_needed
**Re-verification:** No, initial verification
**Status:** passed
**Re-verification:** Yes, 2026-10-10 after gap closure 16.2-07 and UAT (see Re-verification below)
ROADMAP lists no success criteria and REQUIREMENTS.md has none for this phase, so the must-haves are the six plans' frontmatter truths, keyed to CONTEXT decisions D-01 to D-19. They are merged into 14 truths below.
@@ -246,3 +245,23 @@ Status is `human_needed`, not `passed`, for three reasons:
_Verified: 2026-10-10T17:05:00Z_
_Verifier: Claude (msd-verifier)_
## Re-verification (2026-10-10, after 16.2-07)
Gap closure plan 16.2-07 closed G-16.2-1 (conformance cases for GET /field-types and the field upload route; a Docker-free route inventory check in the gate) and G-16.2-2 (Journal admin writes purge the host Nuxt route cache). It was released as summercms v0.1.20 and vue-journal-layer v0.3.0 and deployed to UAT.
All five human verification items above are resolved by evidence, recorded in `human_verification_resolved` and in 16.2-UAT.md (status complete, 5/5 pass):
| Item | Evidence |
|------|----------|
| Postgres suites (truth 10 Postgres half, truth 14) | gate2.log at ee62410: `phase16.2 postgres passed`, `Phase 16.2 gate passed` |
| D-19 category save and site visibility (truth 14) | 16.2-07 Task 6: category-purged, category-fresh, phrase found on the server-rendered page |
| Untouched re-save on the build with CR-01/WR-04 (truth 10) | 16.2-07 Task 6: posts-unchanged, translations-unchanged |
| Preview pane in a browser | UAT Test 4 pass |
| Preview iframe exception | UAT Test 5 pass, accepted by the human |
Checks at this re-verification: `go vet ./modules/cabana/ ./modules/pact/` clean; `go test ./modules/pact/` and `TestPhase10ConformanceInventory` pass; no change outside `.planning/` since aba063f. `covered_files` now includes 16.2-07-PLAN.md, 16.2-07-SUMMARY.md and modules/cabana/openapi_conformance_test.go, and `covered_digest` was recomputed with `msd_run query verification.fingerprint`.
Truth 14 (D-19) moves from NEEDS HUMAN to VERIFIED; the score is 14/14 and the status is `passed`.
This report was re-verified by hand, as Phase 9's was, because msd-core 1.14.0 makes a report stale after any gap-closure plan and its verifier ignores passed UAT results. Re-running execute-phase would have reset 16.2-UAT.md to pending.

View File

@@ -141,8 +141,8 @@
],
"next": {
"command": "/msd:progress --next",
"label": "Advance to the next step",
"reason": "Phase 16.2 of 35 · executing"
"label": "Advance to the next step (plan phase 11)",
"reason": "Phase 11 of 35 — needs a plan"
},
"updated_at": "2026-10-10T19:05:39.387Z"
"updated_at": "2026-10-10T21:38:57.992Z"
}