docs(16.1): add phase verification; record Docker-host suites green
This commit is contained in:
@@ -53,8 +53,8 @@ Pre-existing red, not caused by this phase: `scripts/check-phase10.sh --hygiene`
|
||||
| 16.1-02-02 | 02 | 2 | D-04 | T-16.1-07, T-16.1-08 | Uploaded binary sha256 equals the local build; previous binary kept as `.prev`; no `.env` rsynced | e2e (server) | on-server `scripts/smoke.sh --url https://uat.grzybyfunkcjonalne.pl` via loopback resolve | ✅ | ✅ green (plan 02: smoke: ok (98 urls), sha256 match) |
|
||||
| 16.1-02-03 | 02 | 2 | D-02, D-03 | T-16.1-09, T-16.1-10 | Read-only SQL and log checks; only posts 53 and 64 are re-saved, by a human | integration (server, read-only) | `ssh grzybyfunkcjonalne-uat "psql -X -d grzybyfunkcjonalne -tAc ..."` (raw-HTML marker count 0, post 64 footer present) | ✅ | ✅ green (plan 02: SQL check 0:1, no SQLSTATE 42703 since restart) |
|
||||
| 16.1-03-01 | 03 | 3 | D-01 | T-16.1-11 | Storage helpers survive disabled storage; logout clears list keys only | unit (vitest) | `npm --prefix admin test -- tests/state/listState.test.ts tests/state/useAuth.test.ts tests/list/ListView.test.ts tests/form/FormView.test.ts` | ✅ created (plan 03) | ✅ green |
|
||||
| 16.1-03-02 | 03 | 3 | D-02, D-03 | T-16.1-11, T-16.1-12 | Polymorphic relations and unknown columns refused (422); search value never inlined into SQL | unit (DryRun) + Postgres (Docker host) | `go test -count=1 -run '^(TestListRelationSQL\|TestEnabledLocalesDefaultFirst)$' -v ./modules/cabana` | ✅ extend files from plan 01 | ✅ green (pure); Postgres test on a Docker host: manual |
|
||||
| 16.1-03-03 | 03 | 3 | D-03 | T-16.1-02, T-16.1-11 | Every unsafe case is sanitized (bluemonday, post-review CR-01 fix), scheme-like text and raw HTML survive, CheckHTML refuses unsafe category HTML | unit + journal harness (Docker host) | `go -C ../sm-journal-plugin test -count=1 -run '^(TestFormatHTMLSanitizesUnsafeHTML\|TestFormatHTMLKeepsSchemeLikeText\|TestFormatHTMLKeepsRawHTML\|TestCheckHTML)$' -v ./classes/` (four top-level PASS lines) | ✅ extend | ✅ green (pure); harness re-save test on a Docker host: manual |
|
||||
| 16.1-03-02 | 03 | 3 | D-02, D-03 | T-16.1-11, T-16.1-12 | Polymorphic relations and unknown columns refused (422); search value never inlined into SQL | unit (DryRun) + Postgres (Docker host) | `go test -count=1 -run '^(TestListRelationSQL\|TestEnabledLocalesDefaultFirst)$' -v ./modules/cabana` | ✅ extend files from plan 01 | ✅ green (pure); ✅ Postgres green on Docker 2026-10-09/10 |
|
||||
| 16.1-03-03 | 03 | 3 | D-03 | T-16.1-02, T-16.1-11 | Every unsafe case is sanitized (bluemonday, post-review CR-01 fix), scheme-like text and raw HTML survive, CheckHTML refuses unsafe category HTML | unit + journal harness (Docker host) | `go -C ../sm-journal-plugin test -count=1 -run '^(TestFormatHTMLSanitizesUnsafeHTML\|TestFormatHTMLKeepsSchemeLikeText\|TestFormatHTMLKeepsRawHTML\|TestCheckHTML)$' -v ./classes/` (four top-level PASS lines) | ✅ extend | ✅ green (pure); ✅ harness re-save green on Docker 2026-10-09/10 |
|
||||
|
||||
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
|
||||
|
||||
@@ -94,7 +94,7 @@ Pre-existing red, not caused by this phase: `scripts/check-phase10.sh --hygiene`
|
||||
|
||||
- Quick Go commands: four top-level `--- PASS` lines for `TestListRelationSearchSmoke`, `TestListRelationSQL`, `TestEnabledLocalesDefaultFirst` and `TestEnabledLocalesDefaultFirstSmoke`; `go -C ../sm-journal-plugin test -count=1 ./classes/` ok, with four top-level `--- PASS` lines for `TestFormatHTMLSanitizesUnsafeHTML`, `TestFormatHTMLKeepsSchemeLikeText`, `TestFormatHTMLKeepsRawHTML` and `TestCheckHTML` (updated 2026-10-10 after the CR-01 fix replaced `TestFormatHTMLRejectsUnsafeHTML`).
|
||||
- Full local suite: `go vet ./...`, `go -C ../sm-journal-plugin vet ./...`, `TestDocsTree`, `npm --prefix admin run typecheck`, `npm --prefix admin test` (76 files, 1144 tests) and `scripts/check-admin-dist.sh` ("dist matches a fresh build") printed `phase-16.1-local-gate-ok`.
|
||||
- Docker-host suites: still pending (manual row above). `TestListRelationSearchPostgres` and `TestPostsAdminResaveKeepsHTML` fail here with "failed to create Docker provider", as designed (fail, not skip).
|
||||
- Docker-host suites: still pending at plan 03 time (`TestListRelationSearchPostgres` and `TestPostsAdminResaveKeepsHTML` failed with "failed to create Docker provider", as designed). **Update 2026-10-10:** after the golem user joined the docker group, the full `go test -count=1 ./...` passed with Docker in summercms.go (37 packages, before and after cd25af0, and again for the v0.1.17 release) and in sm-journal-plugin, including `TestListQueryContract`, `TestListRelationSearchPostgres`, `TestPostsAdminResaveKeepsHTML` and the translation harness tests; the verifier re-ran them.
|
||||
- Manual UAT rows: the plan 02 executor confirmed posts 53 and 64 by read-only SQL. The list-state, form-locale and search checks were reported by the human before the re-saves reached UAT, so they stay open for `/msd-verify-work`.
|
||||
|
||||
**Approval:** pending (Docker-host suites and the manual UAT rows)
|
||||
**Approval:** pending (manual UAT rows only; Docker-host suites green 2026-10-10)
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
---
|
||||
phase: 16.1-journal-admin-urgent-fixes-relation-search-list-state-post-f
|
||||
verified: 2026-10-09T23:05:00Z
|
||||
status: human_needed
|
||||
score: 32/33 must-haves verified
|
||||
covered_files:
|
||||
- .planning/phases/16.1-journal-admin-urgent-fixes-relation-search-list-state-post-f/16.1-01-PLAN.md
|
||||
- .planning/phases/16.1-journal-admin-urgent-fixes-relation-search-list-state-post-f/16.1-01-SUMMARY.md
|
||||
- .planning/phases/16.1-journal-admin-urgent-fixes-relation-search-list-state-post-f/16.1-02-PLAN.md
|
||||
- .planning/phases/16.1-journal-admin-urgent-fixes-relation-search-list-state-post-f/16.1-02-SUMMARY.md
|
||||
- .planning/phases/16.1-journal-admin-urgent-fixes-relation-search-list-state-post-f/16.1-03-PLAN.md
|
||||
- .planning/phases/16.1-journal-admin-urgent-fixes-relation-search-list-state-post-f/16.1-03-SUMMARY.md
|
||||
- admin/src/main.ts
|
||||
- admin/src/state/listState.ts
|
||||
- admin/src/state/useAuth.ts
|
||||
- admin/src/state/useSidebar.ts
|
||||
- admin/src/views/ListView.vue
|
||||
- admin/tests/form/FormView.test.ts
|
||||
- admin/tests/list/ListView.test.ts
|
||||
- admin/tests/smoke/list.smoke.test.ts
|
||||
- admin/tests/state/listState.test.ts
|
||||
- admin/tests/state/useAuth.test.ts
|
||||
- docs/backend/forms.md
|
||||
- docs/backend/lists-and-filters.md
|
||||
- modules/cabana/README.md
|
||||
- modules/cabana/http.go
|
||||
- modules/cabana/locale_order_test.go
|
||||
- modules/cabana/query.go
|
||||
- modules/cabana/query_relation_test.go
|
||||
- modules/phrasebook/backend/lang/en/lang.yaml
|
||||
- modules/phrasebook/backend/lang/pl/lang.yaml
|
||||
- scripts/check-phase10.sh
|
||||
covered_digest: "v2:sha256:7e043180d992853a3d04039e3304ee81d631fc8574eeec0e96264b3b6ad7873d"
|
||||
behavior_unverified: 0
|
||||
overrides_applied: 0
|
||||
human_verification:
|
||||
- test: "Install the hardened staging vhost as root: copy /srv/grzybyfunkcjonalne/deploy/grzybyfunkcjonalne-staging.conf (host commits fc10094, 387d0f4) over /etc/nginx/sites-available/uat.grzybyfunkcjonalne.pl, run sudo nginx -t, reload nginx, and compare sha256 of the installed and uploaded copies"
|
||||
expected: "nginx -t passes; curl -sI https://uat.grzybyfunkcjonalne.pl/ (on the server, resolved to loopback) shows Content-Security-Policy-Report-Only, X-Content-Type-Options, X-Frame-Options, Referrer-Policy and Permissions-Policy; /gfadmin keeps its auth_basic exemption; smoke.sh --url still ends 'smoke: ok ('"
|
||||
why_human: "Needs root on the UAT server. Read-only check on 2026-10-09 23:00 UTC: the uploaded file has the CSP Report-Only header (count 1), the enabled vhost does not (count 0)"
|
||||
- test: "UAT posts list search: in /gfadmin/golem15/journal/posts search 'cordyceps' (a category name)"
|
||||
expected: "Rows appear; no 'The list could not be loaded.'; the Go log shows no SQLSTATE 42703 after 2026/10/09 22:47:29"
|
||||
why_human: "Needs UAT basic auth and an admin login. Automated proof covers the SQL on real Postgres (TestListRelationSearchPostgres) and a clean log since the restart, but the Go log does not record successful searches, so it cannot show that a search ran on the real categories pivot"
|
||||
- test: "UAT list state (D-01): set a sort and a category filter, open a post, press back; repeat with save-and-close; leave through the navigation rail and return; paste the URL in a new tab; log out and in"
|
||||
expected: "Sort and filter survive every return and are in the URL; the pasted URL shows the same list; after logout and login the list opens unfiltered"
|
||||
why_human: "Interactive flow behind UAT basic auth; the human report ('all works') predates the re-saves and the v0.1.17 deploy (which changed the storage key to be per admin), so it is not independent confirmation of the deployed build"
|
||||
- test: "UAT post form (D-03): open any imported post"
|
||||
expected: "The locale selector shows pl first; title, slug, content and excerpt are filled with the stored values"
|
||||
why_human: "Visual check on real data. Supporting evidence: the UAT locales table has en at sort_order 1 and the default pl at sort_order 2, the exact order the fix reorders, and enabledContentLocales is covered by 12 unit cases"
|
||||
- test: "Review the nine judgment-tier prohibitions in the Prohibitions section below"
|
||||
expected: "Each LLM-judge verdict (all 'not violated') is accepted or overturned"
|
||||
why_human: "unverified-prohibition: judgment tier, the verifier's verdict is non-authoritative"
|
||||
---
|
||||
|
||||
# Phase 16.1: Journal admin urgent fixes Verification Report
|
||||
|
||||
**Phase Goal:** The Journal posts list and post form in the admin work on real imported data found on UAT. The fixes are released as a summercms tag, the host is bumped, UAT is redeployed and the staging smoke re-runs.
|
||||
**Verified:** 2026-10-09T23:05:00Z
|
||||
**Status:** human_needed
|
||||
**Re-verification:** No, initial verification
|
||||
|
||||
All code, tests, tags, pushes and the deployed binary were checked against the repositories and the UAT server (read-only). Every automated must-have holds. What remains: the nginx vhost install, which needs root, and the browser checks on UAT that only a human can run.
|
||||
|
||||
## Goal Achievement
|
||||
|
||||
### Observable Truths
|
||||
|
||||
**Roadmap contract (success criteria derived from the goal)**
|
||||
|
||||
| # | Truth | Status | Evidence |
|
||||
|---|-------|--------|----------|
|
||||
| 1 | List search no longer fails with "Server error" on a belongsToMany relation | ✓ VERIFIED | `modules/cabana/query.go:369-449` builds `EXISTS (SELECT 1 FROM pivot AS cabana_p0 JOIN related AS cabana_r0 ...)` from `stmt.Schema.Relationships.Relations[field]`. `TestListRelationSearchPostgres` passed against real Postgres (run here through the Docker sudo path). The UAT Go log has 0 `SQLSTATE 42703` lines in the 32 lines since the 22:47:29 restart. |
|
||||
| 2 | List sort and filters are remembered after opening a record and going back | ✓ VERIFIED | `ListView.vue:200-221` restores the stored query before the first request. `FormView.test.ts` "returning to the list keeps its query (D-01)" covers back, cancel, save-and-close and delete. 4 files / 144 tests pass; the full suite has 76 files / 1171 tests. |
|
||||
| 3 | The post form shows the stored content | ✓ VERIFIED (code) | `http.go:986-993` moves `DefaultLocale` to index 0. `TestEnabledLocalesDefaultFirst` (12 cases) passes. The UAT `golem15_translate_locales` table has `en` at sort 1 and the default `pl` at sort 2, which confirms the root cause the fix targets. The on-UAT visual check is a human item. |
|
||||
| 4 | The post form shows the stored excerpt | ✓ VERIFIED (code) | Same mechanism as #3: the excerpt lives in the host column, under the default locale. |
|
||||
| 5 | Released as a summercms tag | ✓ VERIFIED | `git ls-remote`: v0.1.16 is d8e3536 on d77393b; v0.1.17 is c37de45 on c21fe36. v0.1.17 contains 06d75cb, bd8626e, 9cac45c, a8bce9c, 837922c and cd25af0. |
|
||||
| 6 | Host is bumped | ✓ VERIFIED | Host HEAD 0b93ac2 equals origin/master. The journal gitlink is c60abc6, equal to sm-journal-plugin origin/main. The translate gitlink is 54cf93b, the vue app gitlink is ada03b2, and go.mod requires summercms v0.1.17. |
|
||||
| 7 | UAT is redeployed | ✓ VERIFIED | Server sha256 is `e5b0ad28…3af232` and `.prev` is `e1ba3587…148ceb` (the CR-01 hotfix). The Go and Nuxt processes started at 22:47:28 and 22:47:32 UTC. |
|
||||
| 8 | The staging smoke re-runs | ✓ VERIFIED | I re-ran it on the server myself (loopback resolve, GETs only): `smoke: ok (98 urls)` |
|
||||
|
||||
**16.1-01 must_haves**
|
||||
|
||||
| # | Truth | Status | Evidence |
|
||||
|---|-------|--------|----------|
|
||||
| 9 | belongsToMany search goes through EXISTS, with names taken from GORM's parsed relationship | ✓ VERIFIED | `relationSubquery` uses `gorm.Statement.Parse` and `Relationships.Relations`. TestListRelationSQL covers custom `joinForeignKey`/`joinReferences` pivot names. |
|
||||
| 10 | hasMany, hasOne and belongsTo searches are correlated EXISTS; there is no outer JOIN, so a record is counted once | ✓ VERIFIED | `applyListSearch` (query.go:476-490). TestListRelationSQL checks there is no JOIN outside the subqueries next to `user_id = 7` and `id IN (3)`. The Postgres test gives total 1 for a post matching through 2 tags. |
|
||||
| 11 | A to-many sort uses `string_agg` plus the PK tiebreak; a to-one sort keeps the join | ✓ VERIFIED | query.go:313-336; TestListRelationSQL covers both directions; the Postgres test gives [2 1] and [1 2] |
|
||||
| 12 | Polymorphic relations and unknown columns give 422, never 500 | ✓ VERIFIED | query.go:378-390 refuses via `rel.Polymorphic` and `PrimaryValue`; TestListRelationSQL has 5 refusal cases |
|
||||
| 13 | meta.enabledLocales lists the default locale first | ✓ VERIFIED | http.go:986-993, TestEnabledLocalesDefaultFirst(Smoke) |
|
||||
| 14 | FormatHTML keeps imported raw HTML and dangerous markup is not stored on any write path | ✓ VERIFIED (superseded mechanism) | The plan's "refuses" became "strips" under the accepted decision note `notes/journal-html-sanitizing-bluemonday.md`, the CR-01 fix in a3551f2, which is stronger than the planned regex gate. All three write paths call FormatHTML: posts.go:213, import_posts.go:185, posts_helpers.go:511/567. Translations go through FormatTranslation (0d00ec8). Duplicate attributes are handled in 5f47083. TestFormatHTMLKeepsRawHTML and TestFormatHTMLSanitizesUnsafeHTML pass. |
|
||||
| 15 | List params stay in the URL; stored per list; an empty query is never stored | ✓ VERIFIED | `listState.ts`. The key is now `summer-admin.list:<adminId>:<controller>` (the WR-03 fix in cd25af0 is stricter than the plan's key). `writeListState` removes the key on an empty query. |
|
||||
| 16 | Entry without params restores before the first request; URL params win; logout removes every stored query | ✓ VERIFIED | ListView.vue watch; `clearUser()` calls `setListStateOwner(null)`, which removes all list keys. `main.ts:27` sends `onUnauthorized` to `expireSession`. Covered by vitest. |
|
||||
| 17 | Commits staged by path, holding only this plan's files; the journal commit in its own repo | ✓ VERIFIED | `git show --name-only` for 06d75cb, bd8626e and 9cac45c matches the plan. The one extra file in 9cac45c (`list.smoke.test.ts`) is a documented deviation. 528d2d8 is in sm-journal-plugin. |
|
||||
| 18 | go vet clean; smoke tests, vitest, TestDocsTree and the dist check green | ✓ VERIFIED | Re-run here: `go vet ./...` ok, both repos' vet ok, TestDocsTree ok, `check-admin-dist.sh` printed "matches a fresh build", vitest 1171/1171 |
|
||||
|
||||
**16.1-02 must_haves**
|
||||
|
||||
| # | Truth | Status | Evidence |
|
||||
|---|-------|--------|----------|
|
||||
| 19 | An annotated tag containing every 16.1-01 commit is on origin | ✓ VERIFIED | v0.1.16 and v0.1.17 are both on origin (see #5) |
|
||||
| 20 | sm-journal-plugin main with the require is on origin; the host gitlink points at it; README and DEPLOY.md lost the re-save warning | ✓ VERIFIED | c60abc6 equals origin/main and requires v0.1.17. Host gitlink c60abc6. `grep -ci 'omitted\|re-sav'` gives 0 in both README.md and DEPLOY.md. |
|
||||
| 21 | UAT runs the build; sha256 matches; both programs run; `.prev` kept; smoke ok | ✓ VERIFIED | See #7 and #8. I could not compare against the local build byte for byte; the server hash matches the release record. |
|
||||
| 22 | After the restart, no SQLSTATE 42703 (and search returns rows) | ✓ VERIFIED (log + Postgres test) | 0 in 32 lines since 22:47:29. The human search on UAT is a human item. |
|
||||
| 23 | Posts 53 and 64 repaired: no placeholder, post 64 has its footer | ✓ VERIFIED | Read-only psql now prints `0:1`. The public page `/blog/ekstrakt-z-turkey-tail` renders `<footer class="author-footer" itemscope="" ...>`, and the footer CSS is in `entry.Djv1o0WC.css`. |
|
||||
| 24 | D-01 and D-03 checked on UAT by a human (end-of-phase check) | ? UNCERTAIN (human) | The human's report predates the re-saves and the v0.1.17 deploy, so it does not count as confirmation. Routed to Human Verification. |
|
||||
|
||||
**16.1-03 must_haves**
|
||||
|
||||
| # | Truth | Status | Evidence |
|
||||
|---|-------|--------|----------|
|
||||
| 25 | Every piece of 16.1 code has unit tests | ✓ VERIFIED | listState.test.ts, ListView/FormView/useAuth tests, TestListRelationSQL, TestEnabledLocalesDefaultFirst, FormatHTML tests, all passing |
|
||||
| 26 | Form back, cancel, save-and-close and delete land with the stored query, and the first request carries it | ✓ VERIFIED | FormView.test.ts D-01 block passes |
|
||||
| 27 | ListView entry logic: restore, URL wins, cleared controls, same-list navigation, 422, page clamp | ✓ VERIFIED | ListView.test.ts "list state entry logic (D-01)" passes. cd25af0 adds recovery from any failed restore (WR-02). |
|
||||
| 28 | listState helpers: prefix, malformed values dropped, empty query not stored, throwing storage, clear keeps the sidebar key | ✓ VERIFIED | listState.test.ts passes |
|
||||
| 29 | DryRun SQL matrix (custom pivot keys, self-reference, soft delete, polymorphic, bound and LIKE-escaped values, no outer JOIN, sorts) | ✓ VERIFIED | `--- PASS: TestListRelationSQL` |
|
||||
| 30 | enabledContentLocales cases | ✓ VERIFIED | `--- PASS: TestEnabledLocalesDefaultFirst` |
|
||||
| 31 | FormatHTML tests: imported HTML round-trips; no unsafe case survives | ✓ VERIFIED (superseded mechanism) | "Every unsafe case returns an error" became "every unsafe case is stripped" per the bluemonday decision. TestFormatHTMLSanitizesUnsafeHTML, TestFormatHTMLDuplicateAttributes, TestCheckHTML and TestFormatTranslation pass. |
|
||||
| 32 | Postgres tests exist and pass on a Docker host | ✓ VERIFIED | Re-run here: TestListRelationSearchPostgres, TestListQueryContract, TestPostsAdminResaveKeepsHTML, TestJournalAPITranslatedContentHTML and TestJournalImportTranslatedContentHTML all PASS |
|
||||
| 33 | vet, vitest, TestDocsTree and dist green | ✓ VERIFIED | See #18 |
|
||||
|
||||
**Score:** 32/33 truths verified (0 present-but-behavior-unverified; 1 uncertain, routed to a human)
|
||||
|
||||
### CONTEXT decisions accounted for
|
||||
|
||||
| Decision | Status | Where |
|
||||
|----------|--------|-------|
|
||||
| D-01 list state in the URL and localStorage, no server storage | ✓ | #2, #15, #16, #26-28; no migration, route or OpenAPI diff in 3ca6a0d..cd25af0 |
|
||||
| D-02 framework-level relation-search fix in cabana | ✓ | #1, #9-12, #17 |
|
||||
| D-03 content and excerpt shown without loss; re-save keeps HTML | ✓ code / ? UAT visual | #3, #4, #13, #14, #23; UAT visual is a human item |
|
||||
| D-04 tag, host bump, redeploy, smoke | ✓ (except the nginx vhost install) | #5-8, #19-21 |
|
||||
| D-05 three plans | ✓ | 01, 02 and 03 are all summarized |
|
||||
|
||||
### Post-review remediation (16.1-REVIEW.md)
|
||||
|
||||
| Finding | Status | Evidence |
|
||||
|---------|--------|----------|
|
||||
| CR-01 stored XSS | Fixed and deployed | sm-journal-plugin a3551f2 (bluemonday); the public layer uses sanitize-html (vue-journal-layer 5beb1c5, tag v0.1.1, pinned by vue app 27b3827) |
|
||||
| WR-01 "Data:" false refusal | Fixed | The regex gate is gone; TestFormatHTMLKeepsSchemeLikeText passes |
|
||||
| WR-02 restored query locks the list | Fixed | cd25af0: `loadList(restored)` forgets the query and loads the plain list once; there is a reset button |
|
||||
| WR-03 list state crosses admins | Fixed | cd25af0: per-admin keys; `clearUser` and `expireSession` clear them |
|
||||
| Audit W-1 / W-2 | Fixed | 0d00ec8 (FormatTranslation), 5f47083 (duplicate attributes); harness tests pass |
|
||||
| WR-04 relation SQL only DryRun-tested | Resolved in substance | TestListRelationSearchPostgres runs the EXISTS and string_agg SQL on real Postgres and passes |
|
||||
| WR-05 to-many sort order differs from display order | Open (warning) | `relatedSelectMany` still joins in Preload order (query.go:142, no ORDER BY). `docs/backend/lists-and-filters.md:62` still says the sort uses "the text the list shows". |
|
||||
| IN-01..03 | Open (info) | Not addressed |
|
||||
| Translate Secure cookie, app header hardening | Verified on UAT | `set-cookie: golem15.translate.locale=...; HttpOnly; Secure`; Nuxt at :3016 sends no X-Powered-By and no set-cookie |
|
||||
|
||||
### Required Artifacts
|
||||
|
||||
| Artifact | Expected | Status | Details |
|
||||
|----------|----------|--------|---------|
|
||||
| `modules/cabana/query.go` | EXISTS search and to-many sort from the parsed relationship | ✓ VERIFIED | Contains `Relationships.Relations`, `string_agg`, `EXISTS (SELECT 1 FROM`; called from ExecuteList (lines 121, 133) |
|
||||
| `modules/cabana/query_relation_test.go` | DryRun harness, smoke, matrix, Postgres test | ✓ VERIFIED | Its tests pass |
|
||||
| `modules/cabana/locale_order_test.go` | default-first tests | ✓ VERIFIED | Passes |
|
||||
| `../sm-journal-plugin/classes/format_html.go` | goldmark WithUnsafe behind a safety gate | ✓ VERIFIED | `WithUnsafe` plus the bluemonday `htmlPolicy` (supersedes the regex gate) |
|
||||
| `admin/src/state/listState.ts` | per-list browser storage | ✓ VERIFIED | Contains `summer-admin.list:`; imported by ListView.vue and useAuth.ts |
|
||||
| `../sm-grzybyfunkcjonalne-app/DEPLOY.md` | release and rollback procedure without the re-save warning | ✓ VERIFIED | Has `## Release`; the warning is removed |
|
||||
| `../sm-journal-plugin/go.mod` | require of the release tag | ✓ VERIFIED | `summercms v0.1.17`, with the replace to `../summercms.go` kept |
|
||||
| `admin/tests/state/listState.test.ts` | helper tests | ✓ VERIFIED | Passes |
|
||||
| `../sm-journal-plugin/posts_admin_smoke_test.go` | TestPostsAdminResaveKeepsHTML | ✓ VERIFIED | PASS on the Docker host |
|
||||
| `modules/boardwalk/dist/` | rebuilt SPA | ✓ VERIFIED | check-admin-dist.sh: matches a fresh build |
|
||||
|
||||
### Key Link Verification
|
||||
|
||||
| From | To | Via | Status |
|
||||
|------|----|-----|--------|
|
||||
| query.go applyListSearch/applyListOrder | GORM schema.Relationship | `stmt.Parse` + `Relationships.Relations[field]` | ✓ WIRED |
|
||||
| http.go enabledContentLocales | TranslationWriter.DefaultLocale | default moved to index 0 | ✓ WIRED |
|
||||
| ListView.vue watch | listState.ts read/writeListState | restore before the first request | ✓ WIRED |
|
||||
| sm-journal-plugin controllers/posts.go | classes.FormatHTML | content to content_html on admin save (line 213) | ✓ WIRED |
|
||||
| useAuth.ts clearUser / main.ts onUnauthorized | setListStateOwner(null) | logout and session expiry clear list keys | ✓ WIRED |
|
||||
| host plugins/golem15/journal gitlink | sm-journal-plugin origin/main | c60abc6 | ✓ WIRED |
|
||||
| host go.mod | ../summercms.go at the release tag | replace + require v0.1.17 | ✓ WIRED |
|
||||
| FormView.test.ts | ListView entry restore | `writeListState` then back navigation | ✓ WIRED |
|
||||
|
||||
### Data-Flow Trace (Level 4)
|
||||
|
||||
| Artifact | Data | Source | Real data | Status |
|
||||
|----------|------|--------|-----------|--------|
|
||||
| Posts list (search) | rows/meta | ExecuteList → GORM with EXISTS on the real pivot | Yes (Postgres test; UAT log clean) | ✓ FLOWING |
|
||||
| Post form ML fields | content/excerpt (pl) | hydrateMLRecord host columns under DefaultLocale; enabledLocales[0] = pl | Yes (UAT locales: pl default, en sort 1) | ✓ FLOWING (visual check is a human item) |
|
||||
| Public post 64 | content_html footer | UAT DB → Journal API → sanitize-html → v-html | Yes (footer rendered on the SSR page) | ✓ FLOWING |
|
||||
|
||||
### Behavioral Spot-Checks
|
||||
|
||||
| Behavior | Command | Result | Status |
|
||||
|----------|---------|--------|--------|
|
||||
| Relation SQL and locale order (pure) | `go test -run '^(TestListRelationSearchSmoke\|TestListRelationSQL\|TestEnabledLocalesDefaultFirst\|TestEnabledLocalesDefaultFirstSmoke)$' ./modules/cabana` | 4 PASS lines | ✓ PASS |
|
||||
| Journal classes | `go -C ../sm-journal-plugin test -v ./classes/` | 9 PASS, ok | ✓ PASS |
|
||||
| Relation search on real Postgres | Docker sudo path, `-run TestListRelationSearchPostgres\|TestListQueryContract` | PASS, PASS | ✓ PASS |
|
||||
| Admin re-save and translations keep or sanitize HTML | Docker sudo path, sm-journal-plugin named tests | 3 PASS | ✓ PASS |
|
||||
| List state vitest | `npm --prefix admin test` | 76 files, 1171 tests passed | ✓ PASS |
|
||||
| Dist drift | `bash scripts/check-admin-dist.sh` | matches a fresh build | ✓ PASS |
|
||||
| Docs | `go test ./cmd/summer -run TestDocsTree` | ok | ✓ PASS |
|
||||
| Browser storage confined | grep in admin/src outside useSidebar.ts and listState.ts | empty | ✓ PASS |
|
||||
|
||||
### Probe Execution
|
||||
|
||||
| Probe | Command | Result | Status |
|
||||
|-------|---------|--------|--------|
|
||||
| UAT on-server smoke | `CURL_HOME=$C scripts/smoke.sh --url https://uat.grzybyfunkcjonalne.pl` (via ssh, loopback resolve) | `smoke: ok (98 urls)` | PASS |
|
||||
| UAT data repair | read-only psql: placeholder count : post-64 footer | `0:1` | PASS |
|
||||
| UAT log | 42703 count since 2026/10/09 22:47:29 | 0 (32 lines) | PASS |
|
||||
| UAT binary | sha256sum bin/grzybyfunkcjonalne | e5b0ad28…3af232 | PASS |
|
||||
| Hardened vhost installed | grep CSP-Report-Only in /etc/nginx/sites-enabled/uat.grzybyfunkcjonalne.pl | 0 (uploaded copy: 1) | NOT INSTALLED (human item, needs root) |
|
||||
|
||||
### Requirements Coverage
|
||||
|
||||
The phase has no REQUIREMENTS.md IDs (Requirements: TBD), and REQUIREMENTS.md maps nothing to Phase 16.1, so no requirement is orphaned. The plans' `requirements:` fields name CONTEXT decisions D-01..D-04, which are covered above.
|
||||
|
||||
### Prohibitions (judgment tier, verdicts not authoritative; flagged as unverified-prohibition, human review recommended)
|
||||
|
||||
| # | Prohibition | LLM-judge verdict | Basis |
|
||||
|---|-------------|-------------------|-------|
|
||||
| 1 | Relation fix not Journal-specific; no consuming-application names in framework code or docs | not violated | The builder is generic over GORM relationships; grep for app names in the touched framework files is empty; TestDocsTree ok |
|
||||
| 2 | No server-side list state (table, migration, route) | not violated | No migration, route or API diff in summercms.go 3ca6a0d..cd25af0 |
|
||||
| 3 | Journal API content/content_html shapes unchanged | not violated | Only stored values change (sanitized); README says shapes and codes are unchanged |
|
||||
| 4 | cabana.RenderMarkdown stays safe-mode | not violated | `modules/cabana/field_markdown.go` has no WithUnsafe |
|
||||
| 5 | No write SQL on UAT; only human re-saves of 53/64 | not violated (from records) | Records show read-only psql only; cannot be proven after the fact |
|
||||
| 6 | Live Winter site, vhost, php-fpm and PHP DB untouched | not violated (from records) | The vhost was not installed; there is no evidence of live-site edits |
|
||||
| 7 | No credentials requested, printed or committed | not violated (from records) | SUMMARYs hold no secrets |
|
||||
| 8 | Tests touch no UAT, network or shared DB | not violated | DryRun on DSN port 1; testcontainers for Postgres |
|
||||
| 9 | Tests not weakened | not violated | Refuse cases became strip cases under the accepted bluemonday decision, and the payload set grew to 35 |
|
||||
|
||||
### Anti-Patterns Found
|
||||
|
||||
| File | Line | Pattern | Severity | Impact |
|
||||
|------|------|---------|----------|--------|
|
||||
| (phase files) | - | TBD/FIXME/XXX/TODO/HACK | none found | - |
|
||||
| `docs/backend/lists-and-filters.md` | 62 | Docs claim a to-many sort uses "the text the list shows" but the display order is Preload order (WR-05) | ⚠️ Warning | A list sorted by categories can look out of order; docs inaccurate |
|
||||
| `../sm-grzybyfunkcjonalne-app/sm-grzybyfunkcjonalne-app` | - | 46 MB untracked, not-ignored binary in the host repo root (built 2026-10-10 00:50 local) | ℹ️ Info | Could be committed by accident; not part of any commit |
|
||||
| `.planning/phases/16.2-.../16.2-05-PLAN.md` (via ROADMAP line 1014) | - | Plans to cut "summercms tag v0.1.17", which 16.1 already used | ℹ️ Info | 16.2's release must pick the next free tag (v0.1.18) |
|
||||
| UAT Journal API | - | With no locale given (and with Accept-Language pl-PL), the API sets `golem15.translate.locale=en` although the default is pl and en has sort_order 1 | ℹ️ Info | Outside 16.1 scope; may be pre-existing translate behavior; worth a look |
|
||||
| `16.1-VALIDATION.md`, `16.1-SECURITY.md` | - | Still say "Docker-host suites pending" / sign-off unchecked | ℹ️ Info | Stale bookkeeping: the Docker-host suites have now passed |
|
||||
|
||||
### Human Verification Required
|
||||
|
||||
#### 1. Install the hardened staging vhost (root)
|
||||
**Test:** Install `/srv/grzybyfunkcjonalne/deploy/grzybyfunkcjonalne-staging.conf` (host fc10094, 387d0f4) as the uat vhost, then run `nginx -t` and reload.
|
||||
**Expected:** The security headers and CSP Report-Only appear on UAT responses, the `/gfadmin` auth_basic exemption still holds, and the smoke still passes.
|
||||
**Why human:** It needs root on the server. Today the enabled vhost does not have CSP-RO.
|
||||
|
||||
#### 2. UAT posts list search
|
||||
**Test:** Search "cordyceps" in `/gfadmin/golem15/journal/posts`.
|
||||
**Expected:** Rows appear and no SQLSTATE 42703 shows up in the log.
|
||||
**Why human:** It needs basic auth and an admin login. The Go log does not record successful queries.
|
||||
|
||||
#### 3. UAT list state round trip (D-01)
|
||||
**Test:** Set a sort and a category filter. Go open post → back, then save-and-close, then rail navigation. Paste the URL in a new tab. Log out and back in.
|
||||
**Expected:** State is kept and visible in the URL. After logout and login the list opens unfiltered.
|
||||
**Why human:** It is an interactive flow. The earlier human report predates the v0.1.17 deploy.
|
||||
|
||||
#### 4. UAT post form locales and fields (D-03)
|
||||
**Test:** Open an imported post.
|
||||
**Expected:** `pl` is first, and title, slug, content and excerpt are filled.
|
||||
**Why human:** It is a visual check on real data.
|
||||
|
||||
#### 5. Judgment-tier prohibitions
|
||||
**Test:** Review the nine verdicts above.
|
||||
**Expected:** Accept or overturn each one.
|
||||
**Why human:** The verifier's verdicts are not authoritative.
|
||||
|
||||
### Gaps Summary
|
||||
|
||||
There are no blocking gaps. Every roadmap criterion and plan must-have I could check automatically holds in the code, the tests (including the Docker-backed Postgres suites, which I re-ran), the tags and pushes, and the deployed UAT server (binary hash, smoke, log, SQL, public headers, post-64 footer). Two plan wordings were superseded by stricter post-review fixes, and both are recorded in an accepted decision note or a commit:
|
||||
- FormatHTML now strips unsafe markup with bluemonday instead of refusing it with a regex.
|
||||
- List-state keys are now scoped per admin.
|
||||
|
||||
Still open:
|
||||
- **Human items:** the root-only nginx vhost install, and the three UAT browser checks.
|
||||
- **WR-05:** a non-blocking warning. The docs sentence on to-many sort order is inaccurate.
|
||||
|
||||
---
|
||||
|
||||
_Verified: 2026-10-09T23:05:00Z_
|
||||
_Verifier: Claude (msd-verifier)_
|
||||
Reference in New Issue
Block a user