docs(16.2-07): complete gap closure plan; UAT Tests 2 and 3 pass on v0.1.20

Purge token set on UAT, restart at 2026-10-10T17:57:57Z, smoke, token-match
and purge-ok pass. posts-unchanged, translations-unchanged, category-purged
and category-fresh pass after the human re-saves. Debug sessions for
G-16.2-1 and G-16.2-2 resolved.
This commit is contained in:
2026-10-10 21:05:47 +02:00
parent aba063f723
commit e1703c7489
5 changed files with 159 additions and 22 deletions

View File

@@ -2,18 +2,18 @@
msd_state_version: "1.0"
milestone: v1.0
current_phase: "16.2"
current_phase_name: Plugin-provided field types and the Blog Editor formwidget
status: verifying
stopped_at: Phase 16.3 context gathered
last_updated: "2026-10-10T14:21:46.539Z"
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"
last_activity: 2026-10-10
last_activity_desc: Phase 16.2 execution started
state_head: 9652834ca02230d338888344c5bb0d0c0550abed
state_head: aba063f723fbf629d1a2968dc1c8309926dc36fd
progress:
total_phases: 35
completed_phases: 13
total_plans: 157
completed_plans: 153
total_plans: 158
completed_plans: 154
gsd_state_version: "1.0"
milestone_name: milestone
---
@@ -25,14 +25,14 @@ 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
**Current focus:** Phase 16.2 — Plugin-provided field types and the Blog Editor formwidget (INSERTED)
## Current Position
Phase: 16.2 (Plugin-provided field types and the Blog Editor formwidget) — EXECUTING
Plan: 6 of 6
Status: Phase complete — ready for verification
Last activity: 2026-10-10 - Completed quick task 261010-iwu: Blog Editor live preview pane
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
Progress: [██████████] 100%
@@ -749,6 +749,6 @@ Items acknowledged and carried forward from previous milestone close:
## Session Continuity
Last session: 2026-10-10T13:33:02.885Z
Stopped at: Phase 16.3 context gathered
Resume file: .planning/phases/16.3-backend-admin-personal-api-tokens-with-scopes/16.3-CONTEXT.md
Last session: 2026-10-10T19:05:40.225Z
Stopped at: Completed 16.2-07-PLAN.md
Resume file: None

View File

@@ -1,8 +1,8 @@
---
status: diagnosed
status: resolved
trigger: "UAT gap G-16.2-2: Updated content in https://uat.grzybyfunkcjonalne.pl/gfadmin/golem15/journal/categories/2 (\"Te grzyby, szczególnie\" changed into \"Te grzyby, a szczególnie\") and i see the change in backend even after refresh but not on frontend"
created: 2026-10-10T17:20:00+02:00
updated: 2026-10-10T17:32:00+02:00
updated: 2026-10-10T20:05:00+02:00
goal: find_root_cause_only
---
@@ -116,3 +116,7 @@ root_cause: "Not a 16.2 save defect. The save, the DB row and the Journal API al
fix: (not applied — goal find_root_cause_only)
verification: "Observed self-healing without any write: 127.0.0.1:3016/cordyceps returned the old text at 15:24:01 UTC (last-modified 14:59:08) and the new 'Te grzyby, a szczególnie' at 15:25:00 (last-modified 15:24:01)"
files_changed: []
## Resolution
Fixed by plan 16.2-07 (released as summercms v0.1.20 and vue-journal-layer v0.3.0) and confirmed on UAT on 2026-10-10. See 16.2-07-SUMMARY.md.

View File

@@ -1,8 +1,8 @@
---
status: diagnosed
status: resolved
trigger: "UAT gap G-16.2-1: bash scripts/check-phase16.2.sh postgres fails in ./modules/cabana: TestPhase10OpenAPIConformance: openapi_conformance_test.go:418: admin route GET /field-types has no conformance case"
created: 2026-10-10T17:10:00+02:00
updated: 2026-10-10T17:28:00+02:00
updated: 2026-10-10T20:05:00+02:00
goal: find_root_cause_only
---
@@ -150,3 +150,7 @@ suggested_fix_direction: |
- Add two conformCases. GET /field-types: status 200, ref "cabana.FieldTypesResponse", decode into[cabana.FieldTypesResponse](); register a plugin field type on the conform fixture (conformPlugin implements pact.HasFormFieldTypes; element under its widget tag prefix; a script already in conformFS) so the list is non-empty and the ?v= asset URL can be checked with assertPluginAsset. POST .../fields/{field}/upload: status 201, ref "cabana.Envelope-cabana_FieldUploadResponse", decode into[cabana.Envelope[cabana.FieldUploadResponse]](); a gadget fields.yaml field of that alias whose type has Upload, multipart part named "file", sent with requireAjax headers. Mind that a plugin-typed field on the gadget form also runs Decode/Load in the existing create/update/show cases — make them benign or give conformGadget a column for it.
- Fix TestJournalSVGEmbed to assert the intended `type: mlblogeditor` (optionally htmlColumn: content_html) for post content.
- Recurrence guard: split the static inventory check out of the Docker setup (e.g. move `env := newConformEnv(t)` after the coverage loop, or a package-level conformCaseKeys + a Docker-free TestPhase10ConformanceInventory) and add it to FRAMEWORK_RUN in check-phase16.2.sh (and later gates); add openapi_conformance_test.go to the "new admin route" checklist next to phase09Routes and admin_openapi.go.
## Resolution
Fixed by plan 16.2-07 (released as summercms v0.1.20 and vue-journal-layer v0.3.0) and confirmed on UAT on 2026-10-10. See 16.2-07-SUMMARY.md.

View File

@@ -0,0 +1,129 @@
---
phase: 16.2-plugin-provided-field-types-and-the-blog-editor-formwidget
plan: 07
subsystem: gap-closure
tags: [gap-closure, conformance, site-cache, purge, nitro-swr, release, uat, d-03, d-19]
gap_closure: true
gap_ids: [G-16.2-1, G-16.2-2]
requires:
- phase: 16.2-06
provides: scripts/check-phase16.2.sh and the Postgres suites whose stage G-16.2-1 found red
- phase: 16.2-05
provides: the UAT deploy procedure and its corrections
provides:
- "Conformance cases for GET /field-types and the field upload route, and a Docker-free route inventory check in the gate's go stage (G-16.2-1)"
- "Journal admin post and category writes purge the host Nuxt route cache after commit through a token-protected loopback route (G-16.2-2)"
- "summercms v0.1.20 and vue-journal-layer v0.3.0, released to UAT with the plugin and host bumps"
- "UAT Tests 2 and 3 re-run on the deployed build: all four on-server checks pass"
affects: [16.2 verify-work, sm-journal-plugin, vue-journal-layer, sm-grzybyfunkcjonalne-app]
actuals:
tasks: 6
executor_sessions: [summercms-go-da (Tasks 1-5 except step 8), summercms-go-16 (Task 5 step 8 onward, Task 6)]
plan_head_before: d0b7fe4
plan_head_after: aba063f
plugin_commits_repo: ../sm-journal-plugin
plugin_head_after: 5eea57f
layer_commits_repo: ../vue-journal-layer
layer_head_after: 25e9bfe
site_app_head_after: 3a920c7
host_head_after: f1d53af
key-files:
created:
- ../sm-journal-plugin/classes/site_cache.go
- ../sm-journal-plugin/classes/site_cache_test.go
- ../sm-journal-plugin/controllers/site_cache.go
- ../vue-journal-layer/app/utils/siteCache.ts
- ../vue-journal-layer/server/api/__journal__/cache/purge.post.ts
- ../vue-journal-layer/testing/purge-check.mjs
modified:
- modules/cabana/openapi_conformance_test.go
- scripts/check-phase16.2.sh
- ../sm-journal-plugin/plugin_test.go
- ../sm-journal-plugin/README.md
- ../vue-journal-layer/README.md
---
# Phase 16.2 Plan 07: Gap closure for G-16.2-1 and G-16.2-2
**The phase gate is green again with the field type routes under conformance, and a Journal admin save now clears the host Nuxt route cache, so an edited category shows on the next view of the site. Released as summercms v0.1.20 and vue-journal-layer v0.3.0 and confirmed on UAT.**
## Task 4 answer
"release" (verbatim).
## Release
| Item | Value |
|------|-------|
| summercms tag | v0.1.20, tag object ad7981f, pushed |
| vue-journal-layer tag | v0.3.0, tag object c09e0d0 on 25e9bfe, pushed |
| summercms.go master | aba063f |
| sm-journal-plugin main | 5eea57f (requires summercms v0.1.20) |
| vue-journal-layer main | 25e9bfe |
| vue-grzybyfunkcjonalne-app main | 3a920c7 (pins vue-journal-layer#v0.3.0) |
| sm-grzybyfunkcjonalne-app master | f1d53af |
| UAT binary sha256 | 8a64d015… (matches the local build) |
| First start | migrate, smoke (98 URLs) and deploy-ok at 2026-10-10T17:34:31Z |
### Purge token (Task 5 step 8) and restart
- The token was generated and written on the server by a script the user approved: `token-written`. It was never printed or sent back over the connection. Both env files stay mode 0600.
- RESTART_UTC: 2026-10-10T17:57:57Z. Both programs RUNNING.
- LOG_ANCHOR: `client_id=alexandria_2026_10_10T17_57_58_009306`. This replaces the first anchor (`client_id=alexandria_2026_10_10T17_34_31_364928`).
- smoke: `smoke: ok (98 urls)`
- token-match: `token-match`
- purge-ok: `200 83 403 401` (an authorized loopback purge removed 83 entries; a POST through nginx gets 403, a loopback POST without a token gets 401)
### Snapshot before Task 6 (equal to the 16.2-05 expected rows)
- posts md5: `1:a026264105f900175b9770e637e5ec5c:a026264105f900175b9770e637e5ec5c`, `64:0e4be845390b1656871513957d471a7c:e785e14e80f6400534e16b4769749d3c`
- translations: `64:en:862fc5b362cc9856e6736a2078dca3ba`
- updated_at: post 1 `2026-10-10 15:05:09.645641+00`, post 64 `2026-10-10 15:05:18.083705+00`
- category 2: `cordyceps:4053158bd1a58eb7f9547c18cb5a1724:2026-10-10 15:00:27.940875+00`
## Task 6: UAT re-run
Human replies: step 1 approved, step 2 approved (no removal notice on the untouched saves of posts 1 and 64), step 3 confirmed (category 2 saved with no removal notice), step 4 confirmed (the edit showed on the first view of /cordyceps, by reload and by the menu link).
Phrase after the edit: "Te grzyby, a szczególnie Cordyceps sinensis i Cordyceps militaris, od wieków zajmują bardzo ważne miejsce" (was "… zajmują ważne miejsce"). The user chose to keep the edit; the word was not changed back.
| Check | Result |
|-------|--------|
| posts-unchanged | pass: content and content_html of posts 1 and 64 are byte-identical, and both saves moved updated_at past RESTART_UTC |
| translations-unchanged | pass |
| category-purged | pass: successful `kind=category slug=cordyceps` purges after the anchor, every purge succeeded, no panic or SQLSTATE lines, category 2 saved after RESTART_UTC |
| category-fresh | pass: /cordyceps Last-Modified 2026-10-10 19:00:35 GMT, after the category's updated_at |
| Phrase on the server-rendered /cordyceps | found 1 time |
Purge lines after the anchor: post `10-faktow-na-temat-cordycepsu` purged=5, post `ekstrakt-z-turkey-tail` purged=0, category `shiitake` purged=0 (twice), category `cordyceps` purged=7, 3, 3. All status=200. The shiitake purges are from other admin activity during the session and do not affect any check.
**Ready for /msd-verify-work:** UAT Test 2 (D-19) and Test 3 (D-03) can be marked pass. Test 1 (the postgres gate stage) is covered by the Task 3 gate log (gate2.log, full gate including postgres).
## Commits
summercms.go: 11be08d (conformance cases), ee62410 (gate stages), aba063f (docs: route checklist, validation rows).
sm-journal-plugin: f3b223f (tracer: purge after a category update), 2a3afb5 (purge on every post and category write), 09e5643 (TestJournalSVGEmbed expects mlblogeditor), 4405fee (full purge coverage), 5eea57f (require v0.1.20).
vue-journal-layer: a03e076 (token-protected purge route), 0a01bfe (browser revalidation, docs), 4f55511 (tests), 03a90e9 (forward the visitor address), 25e9bfe (release v0.3.0).
vue-grzybyfunkcjonalne-app: 5095f95 (docs), 3a920c7 (layer v0.3.0). sm-grzybyfunkcjonalne-app: 152e1ef (deploy docs: purge token), f1d53af (bump plugin and site app).
## Deviations from Plan
1. **[Rule 1 - Bug] Visitor address lost on route-cached renders.** Layer fix 03a90e9 forwards it through `event.context.journalForwardedFor`.
2. **Scratch host build.** It uses a `file:` override instead of `link:`, and TMPDIR moved off /tmp.
3. **TDD RED and GREEN in one commit.** RED for TestPhase10ConformanceInventory was run locally (RED_EVIDENCE_OK), then committed together with GREEN in 11be08d, because go test must stay green at every commit.
4. **Extra helper file.** `controllers/site_cache.go` in sm-journal-plugin, not listed in files_modified.
5. **Layer README additions.** The 16.2-VALIDATION.md rows for Tasks 4 to 6 were left pending by the first executor.
6. **pnpm store.** `pnpm_config_store_dir=/media/nvme/dev/golem15/summercms.io/summercms/.pnpm-store`, because /tmp/.pnpm-store belongs to another user.
7. **Task 5 step 8 blocked by the Secret read guard.** The hook blocks agent commands that name a .env file. The step ran as a server-side script whose command line does not name the file, with the user's explicit approval of each command; the token was never printed.
8. **Executor handover.** summercms-go-da ran Tasks 1 to 5 up to step 8, then stood down when the user lost access to that console. summercms-go-16 ran step 8 onward and Task 6, so RESTART_UTC and LOG_ANCHOR come from the second restart.
## Next
- /msd-verify-work 16.2: mark Tests 2 and 3 pass, then re-run phase verification (VERIFICATION.md is still `human_needed`).
- Fill the 16.2-VALIDATION.md rows for Tasks 4 to 6.

View File

@@ -141,8 +141,8 @@
],
"next": {
"command": "/msd:progress --next",
"label": "Advance to the next step (verify)",
"reason": "Phase 16.2 of 35 · ready to verify"
"label": "Advance to the next step",
"reason": "Phase 16.2 of 35 · executing"
},
"updated_at": "2026-10-10T14:21:45.523Z"
"updated_at": "2026-10-10T19:05:39.387Z"
}