docs(14.2.1-04): complete translate tests, gate, and security review
Record the last-plan SUMMARY, closed high-threat review, validation sign-off, and 4/4 roadmap progress. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -830,7 +830,7 @@ Plans:
|
|||||||
Plans:
|
Plans:
|
||||||
- [ ] TBD (run $gsd-plan-phase 14.2 to break down)
|
- [ ] TBD (run $gsd-plan-phase 14.2 to break down)
|
||||||
|
|
||||||
### Phase 14.2.1: Translate plugin (INSERTED)
|
### Phase 14.2.1: Translate plugin (INSERTED) — complete 2026-10-06
|
||||||
|
|
||||||
**Goal:** Golem15.Translate is ported to Go as `sm-translate-plugin` so Journal (Phase 15) can keep translatable fields. Lean core only: Locale model and Locales admin, Translatable API, cabana `mltext`/`mlmarkdown`, and PHP Translator locale resolution (URL prefix / session / cookie / default).
|
**Goal:** Golem15.Translate is ported to Go as `sm-translate-plugin` so Journal (Phase 15) can keep translatable fields. Lean core only: Locale model and Locales admin, Translatable API, cabana `mltext`/`mlmarkdown`, and PHP Translator locale resolution (URL prefix / session / cookie / default).
|
||||||
**Requirements**: TBD
|
**Requirements**: TBD
|
||||||
@@ -843,7 +843,7 @@ Plans:
|
|||||||
3. Cabana `markdown`/`mltext`/`mlmarkdown` compose; nested locale writes are not dropped; docs, OpenAPI, TS types and `boardwalk` `dist/` update in the same change.
|
3. Cabana `markdown`/`mltext`/`mlmarkdown` compose; nested locale writes are not dropped; docs, OpenAPI, TS types and `boardwalk` `dist/` update in the same change.
|
||||||
4. Proof host `sm-grzybyfunkcjonalne-app` boots with user+translate; unit tests are the last plan.
|
4. Proof host `sm-grzybyfunkcjonalne-app` boots with user+translate; unit tests are the last plan.
|
||||||
|
|
||||||
**Plans:** 3/4 plans executed
|
**Plans:** 4/4 plans executed
|
||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
|
|
||||||
@@ -857,7 +857,7 @@ Plans:
|
|||||||
- [x] 14.2.1-03-PLAN.md — Cabana markdown/ML fields, nested save, docs/OpenAPI/dist, proof host boot
|
- [x] 14.2.1-03-PLAN.md — Cabana markdown/ML fields, nested save, docs/OpenAPI/dist, proof host boot
|
||||||
|
|
||||||
**Wave 4** *(blocked on Wave 3 completion)*
|
**Wave 4** *(blocked on Wave 3 completion)*
|
||||||
- [ ] 14.2.1-04-PLAN.md — Unit/integration tests last, phase gate, security review
|
- [x] 14.2.1-04-PLAN.md — Unit/integration tests last, phase gate, security review
|
||||||
|
|
||||||
### Phase 15: Journal plugin
|
### Phase 15: Journal plugin
|
||||||
|
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ gsd_state_version: "1.0"
|
|||||||
milestone: v1.0
|
milestone: v1.0
|
||||||
current_phase: 14.2.1
|
current_phase: 14.2.1
|
||||||
current_phase_name: Translate plugin
|
current_phase_name: Translate plugin
|
||||||
status: executing
|
status: verifying
|
||||||
stopped_at: Completed 14.2.1-03-PLAN.md
|
stopped_at: Completed 14.2.1-04-PLAN.md
|
||||||
last_updated: "2026-10-06T11:29:17Z"
|
last_updated: "2026-10-06T12:21:36Z"
|
||||||
last_activity: 2026-10-06
|
last_activity: 2026-10-06
|
||||||
last_activity_desc: 14.2.1-03 cabana ML fields and proof host boot
|
last_activity_desc: 14.2.1-04 tests, phase gate, and security review
|
||||||
state_head: e3b3475
|
state_head: ba6e436
|
||||||
progress:
|
progress:
|
||||||
total_phases: 26
|
total_phases: 26
|
||||||
completed_phases: 12
|
completed_phases: 12
|
||||||
total_plans: 129
|
total_plans: 129
|
||||||
completed_plans: 128
|
completed_plans: 129
|
||||||
milestone_name: milestone
|
milestone_name: milestone
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -28,12 +28,12 @@ See: .planning/PROJECT.md (updated 2026-09-16)
|
|||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 14.2.1 (Translate plugin) — EXECUTING
|
Phase: 14.2.1 (Translate plugin) — VERIFYING
|
||||||
Plan: 3 of 4 complete; next 14.2.1-04
|
Plan: 4 of 4 complete
|
||||||
Status: Ready for unit/integration tests
|
Status: Ready for phase verification / UAT
|
||||||
Last activity: 2026-10-06 — Cabana markdown/ML fields, docs/dist, and proof host boot
|
Last activity: 2026-10-06 — End-to-end tests, matrices, fail-closed gate, security review
|
||||||
|
|
||||||
Progress: [████████░░] 75%
|
Progress: [██████████] 100%
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
@@ -183,6 +183,7 @@ Progress: [████████░░] 75%
|
|||||||
| Phase 14.2.1 P01 | 16 min | 3 tasks | 23 files |
|
| Phase 14.2.1 P01 | 16 min | 3 tasks | 23 files |
|
||||||
| Phase 14.2.1 P02 | 15 min | 3 tasks | 21 files |
|
| Phase 14.2.1 P02 | 15 min | 3 tasks | 21 files |
|
||||||
| Phase 14.2.1 P03 | 5 min | 3 tasks | 40 files |
|
| Phase 14.2.1 P03 | 5 min | 3 tasks | 40 files |
|
||||||
|
| Phase 14.2.1 P04 | 51 min | 3 tasks | 22 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -582,6 +583,7 @@ Recent decisions affecting current work:
|
|||||||
- [Phase 14.2.1]: MorphName is an import-stable string, never reflect.Type.String(); Translated applies D-11 fallback and TranslatedExact does not.
|
- [Phase 14.2.1]: MorphName is an import-stable string, never reflect.Type.String(); Translated applies D-11 fallback and TranslatedExact does not.
|
||||||
- [Phase 14.2.1]: Locales is HasAdminControllers plus HasNavigation (not HasSettings); Fillable excludes is_default/sort_order; makeDefault uses GORM Updates maps.
|
- [Phase 14.2.1]: Locales is HasAdminControllers plus HasNavigation (not HasSettings); Fillable excludes is_default/sort_order; makeDefault uses GORM Updates maps.
|
||||||
- [Phase 14.2.1]: Task 2 locked grzyby-submodules: proof host is sm-grzybyfunkcjonalne-app with plugins/golem15/user and plugins/golem15/translate; host go.work replace points at ../summercms.go.
|
- [Phase 14.2.1]: Task 2 locked grzyby-submodules: proof host is sm-grzybyfunkcjonalne-app with plugins/golem15/user and plugins/golem15/translate; host go.work replace points at ../summercms.go.
|
||||||
|
- [Phase 14.2.1]: 14.2.1-04 security review was executor-self-performed (no gsd-security-auditor in this Cursor session); every cited TestName was re-run. Full cabana `-race` needs `-timeout 30m`. WhereIndex falls back to the host column when no index row matches (PHP transWhere).
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -634,6 +636,6 @@ Items acknowledged and carried forward from previous milestone close:
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-10-06T11:29:17Z
|
Last session: 2026-10-06T12:21:36Z
|
||||||
Stopped at: Completed 14.2.1-03-PLAN.md
|
Stopped at: Completed 14.2.1-04-PLAN.md
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
228
.planning/phases/14.2.1-translate-plugin/14.2.1-04-SUMMARY.md
Normal file
228
.planning/phases/14.2.1-translate-plugin/14.2.1-04-SUMMARY.md
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
---
|
||||||
|
phase: 14.2.1-translate-plugin
|
||||||
|
plan: 04
|
||||||
|
subsystem: i18n
|
||||||
|
tags: [translate, tests, phase-gate, security-review, testcontainers, race]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 14.2.1-03
|
||||||
|
provides: "cabana ML fields, TranslationWriter adapter, proof-host user+translate boot"
|
||||||
|
provides:
|
||||||
|
- "TestTranslateEndToEnd on real Postgres through party/surf/cabana"
|
||||||
|
- "Migration up/down/re-up, Translator, Translatable, Locales, ML, markdown, SPA matrices"
|
||||||
|
- "scripts/check-phase14.2.1.sh fail-closed gate ending with Phase 14.2.1 gate passed"
|
||||||
|
- "14.2.1-SECURITY-REVIEW.md ASVS L1 with T-14.2.1-01..18 and T-14.2.1-SC closed"
|
||||||
|
affects: [15-journal-plugin]
|
||||||
|
|
||||||
|
actuals:
|
||||||
|
tokens: 38000
|
||||||
|
tasks: 3
|
||||||
|
commits: 7
|
||||||
|
plan_head_before: c7e2e4b4ed1a1048af3dcdaa2c74d37ef70de482
|
||||||
|
plan_head_after: ba6e436
|
||||||
|
plugin_repo_head_after: 64f8901
|
||||||
|
host_repo_head_after: 20108b8
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Phase gate uses go -C for sibling plugin and proof host; Docker/Postgres failure is a failure except explicit -short"
|
||||||
|
- "Security review without a dedicated auditor still re-runs every cited TestName and records that fallback"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- ../sm-translate-plugin/integration_test.go
|
||||||
|
- ../sm-translate-plugin/admin_harness_test.go
|
||||||
|
- ../sm-translate-plugin/updates/migrations_test.go
|
||||||
|
- ../sm-translate-plugin/classes/translator_resolve_test.go
|
||||||
|
- ../sm-translate-plugin/classes/translatable_test.go
|
||||||
|
- ../sm-translate-plugin/locales_admin_test.go
|
||||||
|
- modules/cabana/ml_test.go
|
||||||
|
- modules/cabana/markdown_test.go
|
||||||
|
- admin/tests/form/MarkdownField.test.ts
|
||||||
|
- scripts/check-phase14.2.1.sh
|
||||||
|
- .planning/phases/14.2.1-translate-plugin/14.2.1-SECURITY-REVIEW.md
|
||||||
|
modified:
|
||||||
|
- ../sm-grzybyfunkcjonalne-app/boot_test.go
|
||||||
|
- modules/surf/locale_resolver_test.go
|
||||||
|
- modules/cabana/openapi_conformance_test.go
|
||||||
|
- .planning/phases/14.2.1-translate-plugin/14.2.1-VALIDATION.md
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "WhereIndex follows PHP transWhere: when no golem15_translate_indexes row matches, it falls back to the host column"
|
||||||
|
- "Full cabana go test -race needs -timeout 30m; the default 10m timed out on the existing suite, not on the new tests"
|
||||||
|
- "14.2.1-04 security review was executor-self-performed (no gsd-security-auditor in this Cursor session); every cited TestName was re-run"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Fail-closed phase gate: named PASS lines, refuse skip/no-tests/race, sibling go -C, PHP SHA pin, forbidden-surface scan"
|
||||||
|
- "Integration fixture plugin is process-local via party.Register in tests only and must not appear in plugins.gen.go"
|
||||||
|
|
||||||
|
requirements-completed: [D-01, D-02, D-03, D-04, D-05, D-06, D-07, D-08, D-09, D-10, D-11, D-12, D-13, D-14, D-15, D-16, D-17]
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
- id: D1
|
||||||
|
description: "Real-Postgres e2e activates user+translate+fixture, 403s Locales without manage_locales, saves nested ML en/pl, and proves URL locale precedence"
|
||||||
|
requirement: D-17
|
||||||
|
verification:
|
||||||
|
- kind: e2e
|
||||||
|
ref: "sm-translate-plugin#TestTranslateEndToEnd"
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: "sm-grzybyfunkcjonalne-app#TestBootUserTranslate"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D2
|
||||||
|
description: "Migration up/down/re-up, Translator D-07 order, Translatable storage/fallback, and Locales authorization/mass-assignment matrices"
|
||||||
|
requirement: D-07
|
||||||
|
verification:
|
||||||
|
- kind: integration
|
||||||
|
ref: "sm-translate-plugin/updates#TestTranslateMigrationsRollbackAndRemigrate"
|
||||||
|
status: pass
|
||||||
|
- kind: unit
|
||||||
|
ref: "sm-translate-plugin/classes#TestTranslatorResolve"
|
||||||
|
status: pass
|
||||||
|
- kind: unit
|
||||||
|
ref: "sm-translate-plugin/classes#TestTranslatorConcurrentIsolation"
|
||||||
|
status: pass
|
||||||
|
- kind: unit
|
||||||
|
ref: "sm-translate-plugin/classes#TestTranslatableGetSet"
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: "sm-translate-plugin#TestLocalesAdminForbidden"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D3
|
||||||
|
description: "Cabana ML/markdown, surf isolation, SPA fields, OpenAPI FormView types, and fail-closed phase gate"
|
||||||
|
requirement: D-06
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "modules/cabana#TestMLNestedSave"
|
||||||
|
status: pass
|
||||||
|
- kind: unit
|
||||||
|
ref: "modules/cabana#TestMarkdownRejectsUnsafeHTML"
|
||||||
|
status: pass
|
||||||
|
- kind: unit
|
||||||
|
ref: "modules/surf#TestLocaleResolver"
|
||||||
|
status: pass
|
||||||
|
- kind: automated_ui
|
||||||
|
ref: "admin/tests/form/MLFields.test.ts"
|
||||||
|
status: pass
|
||||||
|
- kind: other
|
||||||
|
ref: "bash scripts/check-phase14.2.1.sh --all"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D4
|
||||||
|
description: "ASVS L1 security review closes T-14.2.1-01 through T-14.2.1-18 and T-14.2.1-SC"
|
||||||
|
verification:
|
||||||
|
- kind: other
|
||||||
|
ref: ".planning/phases/14.2.1-translate-plugin/14.2.1-SECURITY-REVIEW.md"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D5
|
||||||
|
description: "Proof-host Locales SPA check as an administrator holding manage_locales"
|
||||||
|
requirement: D-17
|
||||||
|
verification: []
|
||||||
|
human_judgment: true
|
||||||
|
rationale: "Needs a running host, admin login, and visual confirmation of English then Polski; recorded as end-of-phase UAT"
|
||||||
|
|
||||||
|
duration: 51min
|
||||||
|
completed: 2026-10-06
|
||||||
|
status: complete
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 14.2.1 Plan 04: Translate unit/integration tests and phase gate Summary
|
||||||
|
|
||||||
|
**Real-Postgres e2e, decision/security test matrices, fail-closed `check-phase14.2.1.sh`, and an ASVS L1 review that closes T-14.2.1-01..18 plus T-14.2.1-SC**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 51 min
|
||||||
|
- **Started:** 2026-10-06T11:31:12Z
|
||||||
|
- **Completed:** 2026-10-06T12:21:36Z
|
||||||
|
- **Tasks:** 3
|
||||||
|
- **Files modified:** 22
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- `TestTranslateEndToEnd` boots user+translate plus a process-local fixture on dedicated Postgres, proves 403 without `golem15.translate.manage_locales`, nested mltext/mlmarkdown save (English on the host, one Polish attribute/index row), WithLocale reads, D-11 fallback, and `/pl/...` winning over cookie + Accept-Language.
|
||||||
|
- Horizontal matrices cover gormigrate up/down/re-up, Translator D-07 order and `-race` isolation, Translatable storage/fallback/morph isolation, Locales mass-assignment and default-lifecycle guards, cabana ML lift/rollback, unsafe markdown rejection, and SPA markdown composition without `v-html=`.
|
||||||
|
- `scripts/check-phase14.2.1.sh --all` passed every stage and printed `Phase 14.2.1 gate passed`. PHP pin SHA `725d547ec839f02b5fdc0f0a6faaed601a414d50` is unchanged. High threats are mitigated with re-executed named tests in `14.2.1-SECURITY-REVIEW.md`.
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: End-to-end integration harness**
|
||||||
|
- `e612b7f` (test) sm-translate-plugin — TestTranslateEndToEnd harness
|
||||||
|
- `20108b8` (test) sm-grzybyfunkcjonalne-app — expanded TestBootUserTranslate
|
||||||
|
2. **Task 2: Decision and security matrices**
|
||||||
|
- `1cfb5ee` (test) sm-translate-plugin — migrate/Translator/Translatable/Locales
|
||||||
|
- `1bc6200` (test) summercms.go — ML, markdown, resolver, SPA
|
||||||
|
3. **Task 3: Phase gate, security review, validation sign-off**
|
||||||
|
- `64f8901` (test) sm-translate-plugin — gofmt harness
|
||||||
|
- `ba6e436` (test) summercms.go — `scripts/check-phase14.2.1.sh`
|
||||||
|
|
||||||
|
**Plan metadata:** (this commit)
|
||||||
|
|
||||||
|
Nothing was pushed. The proof host remains local-only.
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `../sm-translate-plugin/integration_test.go` — production-path e2e
|
||||||
|
- `../sm-translate-plugin/admin_harness_test.go` — fail-closed TestMain + fixture plugin
|
||||||
|
- `../sm-translate-plugin/updates/migrations_test.go` — schema, seed, rollback
|
||||||
|
- `../sm-translate-plugin/classes/translator_resolve_test.go` — D-07 + race isolation
|
||||||
|
- `../sm-translate-plugin/classes/translatable_test.go` — storage, fallback, morph
|
||||||
|
- `../sm-translate-plugin/locales_admin_test.go` — 403, mass-assignment, default guards
|
||||||
|
- `modules/cabana/ml_test.go`, `markdown_test.go` — ML lift/XSS
|
||||||
|
- `modules/surf/locale_resolver_test.go` — present/absent/isolation
|
||||||
|
- `admin/tests/form/MarkdownField.test.ts` — SPA sinks
|
||||||
|
- `scripts/check-phase14.2.1.sh` — fail-closed gate
|
||||||
|
- `14.2.1-SECURITY-REVIEW.md`, `14.2.1-VALIDATION.md` — review and sign-off
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- WhereIndex matches PHP transWhere and falls back to the host column when no index row matches.
|
||||||
|
- Cabana's existing suite needs `-timeout 30m` under `-race`.
|
||||||
|
- Security review used the Phase 08 fallback (executor-performed) because this session has no `gsd-security-auditor`.
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Correctness] Polish-index lookup vs host-column fallback**
|
||||||
|
- **Found during:** Task 1 (e2e)
|
||||||
|
- **Issue:** Asserting that English slug `hello` must not match a Polish `WhereIndex` failed because `WhereIndex` falls back to the host column when no index row matches.
|
||||||
|
- **Fix:** Assert the Polish index row is `slug=witaj` and that an unknown slug is `ErrRecordNotFound`.
|
||||||
|
- **Files modified:** `../sm-translate-plugin/integration_test.go`
|
||||||
|
- **Verification:** `TestTranslateEndToEnd` PASS
|
||||||
|
- **Committed in:** `e612b7f`
|
||||||
|
|
||||||
|
**2. [Correctness] SPA verify paths**
|
||||||
|
- **Found during:** Task 2
|
||||||
|
- **Issue:** `npm --prefix admin test -- --run admin/tests/form/...` finds no files because Vitest include is `tests/**/*.test.ts` under `admin/`.
|
||||||
|
- **Fix:** Gate and verify use `tests/form/registry.test.ts`, `MLFields.test.ts`, `MarkdownField.test.ts`.
|
||||||
|
- **Verification:** 53 Vitest tests PASS
|
||||||
|
- **Committed in:** `ba6e436` (gate)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 2 auto-fixed (correctness)
|
||||||
|
**Impact on plan:** Required for PHP-parity lookup and a green SPA stage. No scope creep.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
- `go test ./modules/cabana -race` hit the default 10m timeout on the pre-existing suite. New tests pass under `-race` in seconds. The gate uses `-timeout 30m` and the full cabana+surf race passed.
|
||||||
|
- Plugin `go.mod` gained a sibling `replace` for `sm-user-plugin` and a direct `gocloud.dev v0.46.0` require (already-decided pin) so the e2e harness can activate the real user plugin. Not a new package install (T-14.2.1-SC).
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
Phase 14.2.1 code and gate are green. Ready for `$gsd-verify-work` / milestone audit. Human UAT remains: boot the proof host, open Locales as `manage_locales`, confirm English then Polski. Journal (Phase 15) can implement `Translatable()` on its models.
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 14.2.1-translate-plugin*
|
||||||
|
*Completed: 2026-10-06*
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
---
|
||||||
|
phase: 14.2.1
|
||||||
|
slug: translate-plugin
|
||||||
|
status: verified
|
||||||
|
threats_total: 19
|
||||||
|
threats_closed: 19
|
||||||
|
threats_open: 0
|
||||||
|
accepted_risks: 0
|
||||||
|
asvs_level: 1
|
||||||
|
created: 2026-10-06
|
||||||
|
verified: 2026-10-06
|
||||||
|
reviewer: gsd-executor (14.2.1-04 Task 3, self-performed -- see Reviewer Note)
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 14.2.1 — Security Review
|
||||||
|
|
||||||
|
> Lean Translate plugin (`sm-translate-plugin`), cabana `markdown`/`mltext`/`mlmarkdown`,
|
||||||
|
> surf `LocaleResolver`, and the proof-host boot of user+translate. Every
|
||||||
|
> T-14.2.1 threat locked in plans 01–04 is mapped below to executed, named Go
|
||||||
|
> or Vitest evidence. Unmapped IDs would be a review gap, not an accepted
|
||||||
|
> risk; none exist.
|
||||||
|
|
||||||
|
**Date:** 2026-10-06
|
||||||
|
**Scope:** Plans 14.2.1-01 through 14.2.1-04; `sm-translate-plugin`;
|
||||||
|
`summercms.go` modules `cabana` and `surf` plus admin SPA ML/markdown
|
||||||
|
controls; proof host `sm-grzybyfunkcjonalne-app`.
|
||||||
|
**Repos grepped:** `sm-translate-plugin`, `summercms.go` (excluding
|
||||||
|
`.planning/` except this review), `sm-grzybyfunkcjonalne-app`.
|
||||||
|
|
||||||
|
## Reviewer Note
|
||||||
|
|
||||||
|
14.2.1-04-PLAN.md Task 3 calls for an independent `gsd-security-auditor`
|
||||||
|
agent pass. This Cursor session has no dedicated security-auditor subagent
|
||||||
|
(same fallback as Phase 08): the 14.2.1-04 executor performed the review
|
||||||
|
directly. Every high threat below is closed with source citations and named
|
||||||
|
tests **re-executed during this review** (2026-10-06), not merely inherited
|
||||||
|
from earlier plans. The executor checkpoint return states this plainly.
|
||||||
|
|
||||||
|
No external API integration: this phase ports a compiled plugin and local
|
||||||
|
framework/host contracts only.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verdict Summary
|
||||||
|
|
||||||
|
The register contains **19 total threats: 19 closed, 0 open, 0 accepted
|
||||||
|
risks**. High findings block phase completion; all high rows are mitigate
|
||||||
|
with executed named tests. PHP pin SHA `725d547ec839f02b5fdc0f0a6faaed601a414d50`
|
||||||
|
is unchanged.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Trust Boundaries
|
||||||
|
|
||||||
|
| Boundary | Description | Data Crossing |
|
||||||
|
|----------|-------------|----------------|
|
||||||
|
| untrusted request → Translator | URL prefix, cookies, Accept-Language, principal preferred_locale | locale codes only; must match enabled Locale rows |
|
||||||
|
| unauthenticated vs `manage_locales` | Locales admin CRUD | JWT + permission grant |
|
||||||
|
| admin SPA → cabana save | nested mltext/mlmarkdown JSON | locale→string maps lifted before Fill |
|
||||||
|
| markdown source → HTML | stored body / SPA preview | goldmark without WithUnsafe; SPA interpolates text |
|
||||||
|
| test fixture → production binary | process-local `acme.fixture` | must not appear in generated plugin imports |
|
||||||
|
| gate → production claims | skipped containers / stale dist | named PASS + final marker |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Threat Register
|
||||||
|
|
||||||
|
| Threat ID | Category | Component | Severity | Disposition | Proof |
|
||||||
|
|-----------|----------|-----------|----------|-------------|-------|
|
||||||
|
| T-14.2.1-01 | Tampering | Translator locale inputs | high | mitigate | `classes/translator_resolve_test.go:TestTranslatorResolve` (URL/session/header invalid codes ignored; only enabled `en`/`pl`) |
|
||||||
|
| T-14.2.1-02 | Information Disclosure | request locale state | high | mitigate | `classes/translator.go` has no process singleton; `TestTranslatorConcurrentIsolation`; `modules/surf/locale_resolver_test.go:TestLocaleResolver` |
|
||||||
|
| T-14.2.1-03 | Tampering | manual-selection cookie | medium | mitigate | `classes/translator_test.go:TestManualFlagIsNotALocale`; `TestTranslatorResolve/manual_flag_blocks_accept-language` |
|
||||||
|
| T-14.2.1-04 | Tampering | schema source | high | mitigate | `updates/migrations_test.go:TestTranslateTables`; `TestTranslateMigrationsRollbackAndRemigrate`; no AutoMigrate in production plugin |
|
||||||
|
| T-14.2.1-05 | Elevation of Privilege | Locales admin | high | mitigate | `locales_admin_test.go:TestLocalesAdminForbidden`; `integration_test.go:TestTranslateEndToEnd` 403 without `golem15.translate.manage_locales` |
|
||||||
|
| T-14.2.1-06 | Tampering | Locale writes | high | mitigate | `models/locale.go` Fillable excludes `is_default`/`sort_order`; `TestLocalesAdminMassAssignment`; `TestLocalesAdminDefaultGuards` |
|
||||||
|
| T-14.2.1-07 | Tampering | SetTranslated | high | mitigate | `classes/translatable.go` declared-field + enabled-locale checks; `TestInvalidLocaleRejected`; `TestTranslatableGetSet` |
|
||||||
|
| T-14.2.1-08 | Information Disclosure | Morph/index queries | medium | mitigate | `TestTranslatableIndexAndMorphIsolation`; MorphName is an import-stable string |
|
||||||
|
| T-14.2.1-09 | Tampering | ML nested request | high | mitigate | `modules/cabana/field_ml.go` `liftMLValues`; `TestMLNestedSave`; `TestMLFieldTypes` |
|
||||||
|
| T-14.2.1-10 | Elevation of Privilege | TranslationWriter | high | mitigate | no standalone translate-write route; `TestML/writer_is_not_invoked_before_query_checks`; writer runs after host PK inside the save transaction |
|
||||||
|
| T-14.2.1-11 | Tampering | mass assignment | high | mitigate | nested non-ML maps still dropped; default scalar only reaches Fill; `TestMLNestedSave` |
|
||||||
|
| T-14.2.1-12 | Tampering | markdown preview | high | mitigate | `modules/cabana/field_markdown.go:RenderMarkdown`; `TestMarkdownRejectsUnsafeHTML`; `admin/tests/form/MarkdownField.test.ts` |
|
||||||
|
| T-14.2.1-13 | Tampering | host submodule provenance | medium | mitigate | `TestBootUserTranslate` gitlink `160000`; `scripts/check-phase14.2.1.sh --layout` |
|
||||||
|
| T-14.2.1-14 | Repudiation | phase gate | high | mitigate | `scripts/check-phase14.2.1.sh` detector refuses skip/no-tests/race; `--self-test` proves fail-closed |
|
||||||
|
| T-14.2.1-15 | Information Disclosure | concurrent Translator | high | mitigate | `TestTranslatorConcurrentIsolation` under `go test -race`; `TestLocaleResolver/conflicting_requests_stay_isolated` |
|
||||||
|
| T-14.2.1-16 | Tampering | migration rollback | medium | mitigate | `TestTranslateMigrationsRollbackAndRemigrate` dedicated Postgres |
|
||||||
|
| T-14.2.1-17 | Tampering | generated admin artifacts | medium | mitigate | `TestMLOpenAPIConformance`; `scripts/check-admin-openapi.sh --check`; `scripts/check-admin-dist.sh` |
|
||||||
|
| T-14.2.1-18 | Elevation of Privilege | test fixture | high | mitigate | `TestTranslateEndToEndFixtureAbsentFromProduction`; host `plugins.gen.go` has no `acme.fixture` |
|
||||||
|
| T-14.2.1-SC | Tampering | package installs | high | mitigate | no `go get` / npm install this plan; plugin `replace` of `sm-user-plugin` is a sibling checkout; framework `go.mod`/`admin/package-lock.json` unchanged |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Findings by Threat
|
||||||
|
|
||||||
|
### T-14.2.1-01 — locale injection
|
||||||
|
|
||||||
|
- **Source:** `sm-translate-plugin/classes/translator.go` `isValid` / `enabledCodes` (enabled Locale rows only).
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestTranslatorResolve` subtests `invalid_url_session_and_header_ignored`, `url_prefix_wins_and_strips`, `accept-language_reduced_to_enabled_codes` — PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-02 — process-wide locale leak
|
||||||
|
|
||||||
|
- **Source:** `Translator.Locale` reads `towel.Locale(ctx)` only; no package-level current locale.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestTranslatorConcurrentIsolation` PASS; `TestLocaleResolver` isolation subtest PASS; plugin `go test ./... -race` PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-03 — manual cookie as locale
|
||||||
|
|
||||||
|
- **Source:** `hasManualFlag` treats any non-empty value as a flag; `rememberedLocale` reads a different cookie name.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestManualFlagIsNotALocale` (package classes); `TestTranslatorResolve/manual_flag_blocks_accept-language` PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-04 — schema / AutoMigrate
|
||||||
|
|
||||||
|
- **Source:** gormigrate files `updates/202610060001`–`005`; plugin production Go has no `AutoMigrate`.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestTranslateTables`, `TestSeedEnPl`, `TestTranslateMigrationsRollbackAndRemigrate` PASS. Gate `--forbidden` refuses production `AutoMigrate`.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-05 — manage_locales privilege
|
||||||
|
|
||||||
|
- **Source:** `controllers/locales.go` `RequiredPermissions` = `golem15.translate.manage_locales`.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestLocalesAdminForbidden` PASS; `TestTranslateEndToEnd` 403 on list/schema without the grant PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-06 — Locale mass assignment and default lifecycle
|
||||||
|
|
||||||
|
- **Source:** `models/locale.go` `Fillable` is `code,name,is_enabled`; `FormBeforeDelete` / `FormBeforeUpdate` / `makeDefault`.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestLocalesAdminMassAssignment`, `TestLocalesAdminDefaultGuards` covered by the plugin suite (smoke + full admin tests) PASS in `go test ./...`.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-07 — undeclared field / invalid locale writes
|
||||||
|
|
||||||
|
- **Source:** `classes/translatable.go` `validateCall`.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestInvalidLocaleRejected`, `TestTranslatableGetSet` PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-08 — morph/index isolation
|
||||||
|
|
||||||
|
- **Source:** `WhereIndex` predicates on `model_type`, `locale`, `item`, `value`.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestTranslatableIndexAndMorphIsolation` in the plugin `./...` suite PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-09 — nested ML JSON
|
||||||
|
|
||||||
|
- **Source:** `modules/cabana/field_ml.go` `liftMLValues` (enabled locale codes, string values, default required).
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestMLFieldTypes`, `TestMLNestedSave` PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-10 — TranslationWriter privilege
|
||||||
|
|
||||||
|
- **Source:** `cabana.TranslationWriter` comment and `crud.go` `save`: apply after Create/Update, after permission/query/lock checks.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestML/writer_is_not_invoked_before_query_checks`, `TestML/writer_failure_rolls_back_host_write` PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-11 — ML mass assignment
|
||||||
|
|
||||||
|
- **Source:** lift before `ProjectWritableFields`; extra nested keys stay blocked.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestMLNestedSave` PASS (unlifted nested maps empty; extra locale `de` rejected).
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-12 — stored XSS / markdown
|
||||||
|
|
||||||
|
- **Source:** `RenderMarkdown` goldmark without `html.WithUnsafe`; rejects script/iframe/event/javascript/vbscript/data. SPA preview interpolates text, no `v-html=`.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestMarkdownRejectsUnsafeHTML` (script/iframe/event/javascript/vbscript/data) PASS; Vitest `tests/form/MarkdownField.test.ts` 3/3 PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-13 — submodule provenance
|
||||||
|
|
||||||
|
- **Source:** host gitlinks `plugins/golem15/{user,translate}`.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestBootUserTranslate` PASS; `--layout` PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-14 — gate repudiation
|
||||||
|
|
||||||
|
- **Source:** `scripts/check-phase14.2.1.sh` JSON detector.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `--self-test` PASS (fail/skip/zero/no-tests/race/missing-named).
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-15 — concurrent Translator
|
||||||
|
|
||||||
|
- **Source:** context-only locale; Rewrite clones the request.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestTranslatorConcurrentIsolation` PASS; plugin `-race` PASS; `TestLocaleResolver/conflicting_requests_stay_isolated` PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-16 — migration rollback
|
||||||
|
|
||||||
|
- **Source:** gormigrate RollbackLast ×5 then remigrate on a dedicated database.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestTranslateMigrationsRollbackAndRemigrate` PASS.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-17 — generated artifacts
|
||||||
|
|
||||||
|
- **Source:** committed `admin/openapi/admin.json`, `schema.d.ts`, `modules/boardwalk/dist`.
|
||||||
|
- **Test evidence:** `TestMLOpenAPIConformance` PASS (re-run 2026-10-06); gate `--admin` regenerates and diffs.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-18 — test fixture in production
|
||||||
|
|
||||||
|
- **Source:** `party.Register` of `acme.fixture` is `sync.Once` inside tests only.
|
||||||
|
- **Test evidence (re-run 2026-10-06):** `TestTranslateEndToEndFixtureAbsentFromProduction` matched by `TestTranslateEndToEnd*` in the plugin `./...` run PASS; host `plugins.gen.go` lists only `golem15.user` and `golem15.translate`.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
### T-14.2.1-SC — package installs
|
||||||
|
|
||||||
|
- **Source:** no new module versions beyond existing stack pins; plugin `replace` of `sm-user-plugin` points at the host submodule checkout; `gocloud.dev v0.46.0` is the already-decided blob pin. Framework `go.mod` / `admin/package-lock.json` were not changed in this phase.
|
||||||
|
- **Test evidence:** `git log -- go.mod go.sum` on the framework shows no 14.2.1 commits; plugin go.mod Task 1 added a local replace, not a downloaded package.
|
||||||
|
- **Disposition:** closed / mitigate.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deferred surfaces confirmed absent
|
||||||
|
|
||||||
|
Gate `--forbidden` (re-run 2026-10-06, PASS) refuses production `manage_messages`, `plugin.Open`/`yaegi`, plugin `AutoMigrate`, `acme.fixture` outside tests, Winter/RainLab table names in production Go, consuming-application names in framework docs, and `v-html=` in `admin/src`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ASVS L1 mapping (selected)
|
||||||
|
|
||||||
|
| ASVS | Control | Evidence |
|
||||||
|
|------|---------|----------|
|
||||||
|
| V4.1 | Access control on admin | `TestLocalesAdminForbidden` |
|
||||||
|
| V5.1.3 | Mass assignment | Locale Fillable + ML lift |
|
||||||
|
| V5.2 | Sanitization / XSS | `RenderMarkdown` + SPA text interpolation |
|
||||||
|
| V11.1 | Stored locale injection | enabled-row validation |
|
||||||
|
| V14.2 | Dependency integrity | T-14.2.1-SC |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Approval:** closed — all high threats mitigated with re-executed named tests.
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
---
|
---
|
||||||
phase: "14.2.1"
|
phase: "14.2.1"
|
||||||
slug: "translate-plugin"
|
slug: "translate-plugin"
|
||||||
# status lifecycle: draft (seeded by plan-phase) → validated (set by validate-phase §6)
|
status: validated
|
||||||
# audit-milestone §5.5 distinguishes NOT-VALIDATED (draft) from PARTIAL (validated + nyquist_compliant: false) (#2117)
|
nyquist_compliant: true
|
||||||
status: draft
|
wave_0_complete: true
|
||||||
nyquist_compliant: false
|
|
||||||
wave_0_complete: false
|
|
||||||
created: "2026-10-06"
|
created: "2026-10-06"
|
||||||
|
validated: "2026-10-06"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Phase 14.2.1 — Validation Strategy
|
# Phase 14.2.1 — Validation Strategy
|
||||||
|
|
||||||
> Per-phase validation contract for feedback sampling during execution.
|
> Per-phase validation contract. Signed off after plan 14.2.1-04 tests and
|
||||||
|
> `scripts/check-phase14.2.1.sh` stages were executed.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -19,19 +19,19 @@ created: "2026-10-06"
|
|||||||
|
|
||||||
| Property | Value |
|
| Property | Value |
|
||||||
|----------|-------|
|
|----------|-------|
|
||||||
| **Framework** | Go `testing` + testcontainers-go v0.44.0 (Postgres) |
|
| **Framework** | Go `testing` + testcontainers-go v0.44.0 (Postgres) + Vitest for admin SPA |
|
||||||
| **Config file** | none — `go test ./...` |
|
| **Config file** | none — `go test ./...`; gate `scripts/check-phase14.2.1.sh` |
|
||||||
| **Quick run command** | `go test ./... -short -count=1` (plugin + `./modules/cabana` + `./modules/surf`) |
|
| **Quick run command** | `go -C ../sm-translate-plugin test ./... -short -count=1` plus `go test ./modules/cabana ./modules/surf -short -count=1` |
|
||||||
| **Full suite command** | `go test ./... -count=1` in `sm-translate-plugin`, `summercms.go`, and host `go test ./...` |
|
| **Full suite command** | `bash scripts/check-phase14.2.1.sh --all` |
|
||||||
| **Estimated runtime** | ~60 seconds (short); ~180 seconds (full, Postgres) |
|
| **Estimated runtime** | ~60 seconds (short); ~15–25 minutes (full + race, Postgres) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Sampling Rate
|
## Sampling Rate
|
||||||
|
|
||||||
- **After every task commit:** Run `go test ./... -short -count=1` in the repo that changed
|
- **After every task commit:** named verify command in that plan's task
|
||||||
- **After every plan wave:** Run `go test ./... -count=1` and `go vet ./...` in that repo
|
- **After every plan wave:** `go vet` + `go test ./... -count=1` in the repo that changed
|
||||||
- **Before `$gsd-verify-work`:** Full suite must be green in plugin, `summercms.go`, and host
|
- **Before `$gsd-verify-work`:** `bash scripts/check-phase14.2.1.sh --all`
|
||||||
- **Max feedback latency:** 60 seconds (short)
|
- **Max feedback latency:** 60 seconds (short)
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -40,16 +40,19 @@ created: "2026-10-06"
|
|||||||
|
|
||||||
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|
||||||
|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------|
|
|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------|
|
||||||
| 14.2.1-W0 | 04 | 0 | D-05 | T-14.2.1-01 | Locales admin requires `golem15.translate.manage_locales` | integration | `go test ./... -run TestLocalesAdminForbidden -count=1` | ❌ W0 | ⬜ pending |
|
| 14.2.1-W0 | 04 | 0 | D-05 | T-14.2.1-05 | Locales admin requires `golem15.translate.manage_locales` | integration | `go -C ../sm-translate-plugin test . -run TestLocalesAdminForbidden -count=1` | ✅ `locales_admin_test.go` | ✅ green |
|
||||||
| 14.2.1-W0 | 04 | 0 | D-06 | — | `type: mltext` and `type: mlmarkdown` compile; unknown type fails boot | unit | `go test ./modules/cabana -run TestMLFieldTypes -count=1` | ❌ W0 | ⬜ pending |
|
| 14.2.1-W0 | 04 | 0 | D-06 | T-14.2.1-09 | `type: mltext` and `type: mlmarkdown` compile; unknown type fails boot | unit | `go test ./modules/cabana -run TestMLFieldTypes -count=1` | ✅ `modules/cabana/ml_test.go` | ✅ green |
|
||||||
| 14.2.1-W0 | 04 | 0 | D-07 | T-14.2.1-02 | URL prefix wins; invalid code ignored; session/cookie flag; not header-only | unit | `go test ./classes -run TestTranslatorResolve -count=1` | ❌ W0 | ⬜ pending |
|
| 14.2.1-W0 | 04 | 0 | D-07 | T-14.2.1-01 | URL prefix wins; invalid code ignored; session/cookie flag; not header-only | unit | `go -C ../sm-translate-plugin test ./classes -run TestTranslatorResolve -count=1` | ✅ `classes/translator_resolve_test.go` | ✅ green |
|
||||||
| 14.2.1-W0 | 04 | 0 | D-08 | — | Seed inserts `en` (default, enabled) and `pl` (enabled, not default); not `de` | integration | `go test ./updates -run TestSeedEnPl -count=1` | ❌ W0 | ⬜ pending |
|
| 14.2.1-W0 | 04 | 0 | D-08 | — | Seed inserts `en` (default, enabled) and `pl` (enabled, not default); not `de` | integration | `go -C ../sm-translate-plugin test ./updates -run TestSeedEnPl -count=1` | ✅ `updates/migrations_test.go` | ✅ green |
|
||||||
| 14.2.1-W0 | 04 | 0 | D-09/D-12 | — | `Translatable()` + get/set + `WithLocale` | unit | `go test ./classes -run TestTranslatableGetSet -count=1` | ❌ W0 | ⬜ pending |
|
| 14.2.1-W0 | 04 | 0 | D-09/D-12 | T-14.2.1-07 | `Translatable()` + get/set + `WithLocale` | unit | `go -C ../sm-translate-plugin test ./classes -run TestTranslatableGetSet -count=1` | ✅ `classes/translatable_test.go` | ✅ green |
|
||||||
| 14.2.1-W0 | 04 | 0 | D-10 | — | Tables `golem15_translate_locales\|attributes\|indexes\|messages` exist after migrate | integration | `go test ./updates -run TestTranslateTables -count=1` | ❌ W0 | ⬜ pending |
|
| 14.2.1-W0 | 04 | 0 | D-10 | T-14.2.1-04 | Tables `golem15_translate_locales\|attributes\|indexes\|messages` exist after migrate | integration | `go -C ../sm-translate-plugin test ./updates -run TestTranslateTables -count=1` | ✅ `updates/migrations_test.go` | ✅ green |
|
||||||
| 14.2.1-W0 | 04 | 0 | D-11 | — | Missing `pl` falls back to default locale column | unit | `go test ./classes -run TestFallbackDefaultLocale -count=1` | ❌ W0 | ⬜ pending |
|
| 14.2.1-W0 | 04 | 0 | D-11 | — | Missing `pl` falls back to default locale column | unit | `go -C ../sm-translate-plugin test ./classes -run TestFallbackDefaultLocale -count=1` | ✅ `classes/translatable_test.go` | ✅ green |
|
||||||
| 14.2.1-W0 | 04 | 0 | D-17 | — | Host/plugin Activate with user+translate | smoke | `go test ./... -run TestBootUserTranslate -count=1` | ❌ W0 | ⬜ pending |
|
| 14.2.1-W0 | 04 | 0 | D-17 | T-14.2.1-13 | Host/plugin Activate with user+translate | smoke | `go -C ../sm-grzybyfunkcjonalne-app test ./... -run TestBootUserTranslate -count=1` | ✅ `boot_test.go` | ✅ green |
|
||||||
| 14.2.1-W0 | 04 | 0 | T-SEC-01 | T-14.2.1-03 | Unlisted locale never stored | unit | `go test ./classes -run TestInvalidLocaleRejected -count=1` | ❌ W0 | ⬜ pending |
|
| 14.2.1-W0 | 04 | 0 | T-SEC-01 | T-14.2.1-07 | Unlisted locale never stored | unit | `go -C ../sm-translate-plugin test ./classes -run TestInvalidLocaleRejected -count=1` | ✅ `classes/translatable_test.go` | ✅ green |
|
||||||
| 14.2.1-W0 | 04 | 0 | T-SEC-02 | T-14.2.1-04 | Nested ML body not dropped | unit | `go test ./modules/cabana -run TestMLNestedSave -count=1` | ❌ W0 | ⬜ pending |
|
| 14.2.1-W0 | 04 | 0 | T-SEC-02 | T-14.2.1-09 | Nested ML body not dropped | unit | `go test ./modules/cabana -run TestMLNestedSave -count=1` | ✅ `modules/cabana/ml_test.go` | ✅ green |
|
||||||
|
| 14.2.1-04-1 | 04 | 4 | D-17 | T-14.2.1-18 | Production-path e2e on real Postgres | e2e | `go -C ../sm-translate-plugin test . -run '^(TestTranslateEndToEnd)$' -count=1` | ✅ `integration_test.go` | ✅ green |
|
||||||
|
| 14.2.1-04-2 | 04 | 4 | D-07 | T-14.2.1-15 | Concurrent request locale isolation | unit | `go -C ../sm-translate-plugin test ./classes -race -run TestTranslatorConcurrentIsolation -count=1` | ✅ `classes/translator_resolve_test.go` | ✅ green |
|
||||||
|
| 14.2.1-04-3 | 04 | 4 | D-12 | T-14.2.1-12 | Unsafe markdown rejected | unit | `go test ./modules/cabana -run TestMarkdownRejectsUnsafeHTML -count=1` | ✅ `modules/cabana/markdown_test.go` | ✅ green |
|
||||||
|
|
||||||
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
|
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
|
||||||
|
|
||||||
@@ -57,30 +60,30 @@ created: "2026-10-06"
|
|||||||
|
|
||||||
## Wave 0 Requirements
|
## Wave 0 Requirements
|
||||||
|
|
||||||
- [ ] `sm-translate-plugin` module and test files listed above
|
- [x] `sm-translate-plugin` module and test files listed above
|
||||||
- [ ] `modules/cabana` ML compile/save tests
|
- [x] `modules/cabana` ML compile/save tests
|
||||||
- [ ] `modules/surf` Resolver-present vs absent locale tests
|
- [x] `modules/surf` Resolver-present vs absent locale tests (`TestLocaleResolver`)
|
||||||
- [ ] Plugin Postgres harness (copy user plugin TestMain / testcontainers)
|
- [x] Plugin Postgres harness (fail-closed TestMain / testcontainers)
|
||||||
- [ ] No new test framework install
|
- [x] No new test framework install
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Manual-Only Verifications
|
## Manual-Only Verifications
|
||||||
|
|
||||||
| Behavior | Requirement | Why Manual | Test Instructions |
|
| Behavior | Requirement | Why Manual | Test Instructions | Status |
|
||||||
|----------|-------------|------------|-------------------|
|
|----------|-------------|------------|-------------------|--------|
|
||||||
| Create Gitea remote `git@git.golem15.com:golem15/sm-translate-plugin.git` | D-15 | Requires user credentials on git.golem15.com | User creates public repo; executor verifies clone URL exists |
|
| Gitea remote `git@git.golem15.com:golem15/sm-translate-plugin.git` | D-15 | Requires user credentials | Created in plan 01; clone URL exists | ✅ done (01) |
|
||||||
| Locales admin works in the proof-host SPA | D-17 | Needs running host + admin login | Boot `sm-grzybyfunkcjonalne-app`; open Locales; create/edit locale as permitted user |
|
| Locales admin in the proof-host SPA | D-17 | Needs running host + admin login | Boot the proof host; sign in as an administrator holding `golem15.translate.manage_locales`; open Locales; confirm English then Polski; edit name/enabled; a user without the permission cannot open the controller | ⬜ end-of-phase UAT |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Validation Sign-Off
|
## Validation Sign-Off
|
||||||
|
|
||||||
- [ ] All tasks have `<automated>` verify or Wave 0 dependencies
|
- [x] All tasks have `<automated>` verify or Wave 0 dependencies
|
||||||
- [ ] Sampling continuity: no 3 consecutive tasks without automated verify
|
- [x] Sampling continuity: no 3 consecutive tasks without automated verify
|
||||||
- [ ] Wave 0 covers all MISSING references
|
- [x] Wave 0 covers all MISSING references
|
||||||
- [ ] No watch-mode flags
|
- [x] No watch-mode flags
|
||||||
- [ ] Feedback latency < 60s
|
- [x] Feedback latency < 60s (short)
|
||||||
- [ ] `nyquist_compliant: true` set in frontmatter
|
- [x] `nyquist_compliant: true` set in frontmatter
|
||||||
|
|
||||||
**Approval:** pending
|
**Approval:** validated 2026-10-06 (executor 14.2.1-04). Human UAT for Locales SPA remains end-of-phase.
|
||||||
|
|||||||
Reference in New Issue
Block a user