20 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 14.2.1-translate-plugin | 04 | execute | 4 |
|
|
true |
|
|
Purpose: make every locked decision and high-risk locale/admin write behavior observably fail when broken. Output: full test matrix, migration rollback proof, phase gate, security review, and validated validation map.
<execution_context>
@/.codex/gsd-core/workflows/execute-plan.md
@/.codex/gsd-core/templates/summary.md
</execution_context>
Spec-less probe fallback
The phase has no mapped REQUIREMENTS.md IDs. This is a visible, intentional skip of spec-less probes. Tests and gate rows map directly to D-01 through D-17, the frozen PHP pin, and the RESEARCH validation/threat tables.
Artifacts this phase produces
TestTranslateEndToEndspanning migration, activation, resolver, permissioned admin, nested ML write, en/pl storage, fallback, and indexed query.- Real-Postgres migration/seed/rollback suite.
- Translator, surf, Translatable, Locales admin, cabana ML/markdown, SPA, generated-contract, and proof-host tests.
scripts/check-phase14.2.1.shwith short/full/docs/admin/host/security stages.14.2.1-SECURITY-REVIEW.mdand a completed14.2.1-VALIDATION.md.
Multi-source coverage audit
| SOURCE | ID | Feature/Requirement | Plan | Status | Notes |
|---|---|---|---|---|---|
| GOAL | — | Lean Translate core lets Journal keep translatable fields and boots in proof host | 01-04 | COVERED | Schema, API, admin, ML fields, host, tests |
| REQ | — | No mapped requirement IDs | — | COVERED | Visible spec-less fallback; D-IDs are used |
| CONTEXT | D-01..D-04 | Frozen/read-only PHP SHA | 01,04 | COVERED | Pin asserted; PHP tree unchanged |
| CONTEXT | D-05 | Locale/admin/behavior lean scope; deferred surfaces absent | 02,04 | COVERED | Negative scope checks in gate |
| CONTEXT | D-06 | markdown/mltext/mlmarkdown compose | 03,04 | COVERED | Go + SPA + generated artifacts |
| CONTEXT | D-07 | full request locale resolution | 01,04 | COVERED | Ordered and concurrent tests |
| CONTEXT | D-08 | en/pl only | 01,04 | COVERED | Seed/absence tests |
| CONTEXT | D-09..D-12 | explicit Translatable APIs/storage/fallback | 02-04 | COVERED | Fixture and full matrix |
| CONTEXT | D-13..D-17 | proof host, remotes, submodules, boot/proof | 01,03,04 | COVERED | Host smoke and layout checks |
| RESEARCH | — | Exact four final tables/columns/indexes and migrations up/down | 01,04 | COVERED | Real Postgres |
| RESEARCH | — | Permission, default-locale guards, phrasebook separation | 02,04 | COVERED | Admin suite |
| RESEARCH | — | Nested ML map before projection, safe markdown | 03,04 | COVERED | Security tests |
| RESEARCH | — | README/docs/OpenAPI/TS/dist same change | 03,04 | COVERED | Consistency gate |
| RESEARCH | — | No external SaaS API integration | 01-04 | COVERED | No COVERAGE matrix or fabricated API tests |
Excluded by explicit scope: Messages catalogue/admin, CMS locale components, locale picker/hreflang/banner, AI/theme commands, message import/export, extra locale seeds, PHP edits, and Phase 15 Journal implementation.
Task 1: Prove migration → activation → resolver → Locales admin → ML save → WithLocale read end to end ../sm-translate-plugin/updates/postgres_test.go, ../sm-translate-plugin/integration_test.go, ../sm-translate-plugin/admin_harness_test.go, ../sm-grzybyfunkcjonalne-app/boot_test.go ../fonoteka.go/plugins/golem15/user/updates/postgres_test.go, ../fonoteka.go/plugins/golem15/user/admin_harness_test.go, ../sm-translate-plugin/plugin.go, ../sm-translate-plugin/classes/translator.go, ../sm-translate-plugin/classes/translatable.go, ../sm-translate-plugin/controllers/locales.go, modules/cabana/ml_smoke_test.go, ../sm-grzybyfunkcjonalne-app/boot_test.go, .planning/phases/14.2.1-translate-plugin/14.2.1-VALIDATION.md Build the final integration harness on testcontainers Postgres, copying the proven user-plugin fail-closed TestMain/dedicated database pattern. Docker unavailability is a failure for full runs; only an explicit `-short` invocation may skip integration.TestTranslateEndToEnd must migrate user and translate plugin sets in dependency order, activate the real user and translate plugins plus a test-only neutral fixture controller/model, assemble surf/cabana, and create backend principals with and without golem15.translate.manage_locales. Assert unauthorized Locales access is 403 and authorized schema/list sees en then pl. Send one real fixture create/update body with mltext title and mlmarkdown body maps for en/pl. Assert host columns contain English, only the Polish non-default attribute row exists, safe markdown source round-trips, WithLocale(...,"pl") reads Polish, a missing Polish field falls back to English, and indexed Polish slug lookup finds only the fixture.
Exercise a request with /pl/... and conflicting preferred/session/header candidates to prove URL precedence reaches towel.Locale(ctx) == "pl". Keep all fixture plugin/model registration process-local to the test.
Expand host TestBootUserTranslate to prove both actual gitlink plugins activate, migrations are discoverable, and the Locales controller/permission are registered. It need not duplicate the fixture model.
go -C ../sm-translate-plugin test ./... -count=1 -v -run '^(TestTranslateEndToEnd)$' && go -C ../sm-grzybyfunkcjonalne-app test ./... -count=1 -v -run '^(TestBootUserTranslate)$'
<fails_when>Non-zero exit; either run prints "--- FAIL", "--- SKIP", "no tests to run", container startup failure treated as skip, or lacks its named "--- PASS" line.</fails_when>
<acceptance_criteria>
- Integration uses real Postgres and actual gormigrate/party/surf/cabana production paths.
- Unauthorized Locales is 403; authorized list includes only seeded en/pl in order.
- One nested admin save persists English on the host and Polish in attributes/indexes.
- WithLocale Polish read, default fallback, and indexed lookup all pass.
- URL prefix wins over all conflicting candidates and locale is context-only.
- Fixture registration cannot appear in the production plugin list or host binary.
</acceptance_criteria>
The entire Phase 14.2.1 user-visible path is proven through production wiring on real Postgres before horizontal test expansion.
Migration tests: assert every final table, column type/default, PHP-indexed column, empty Messages row count, no rainlab/provisional tables, idempotent seed, en/pl exact flags/order/names, no de, and rollback removes all four tables in reverse-safe order. Re-migrate after rollback.
Translator tests: table-drive URL prefix precedence and stripping; preferred locale; remembered locale; absent/present manual flag behavior; weighted Accept-Language reduced only to enabled codes; default fallback; invalid URL/session/header ignored; API resolver preferred → header → default without persistence; plugin-absent surf retains old behavior. Run parallel requests with conflicting locales under -race and assert no cross-request leak.
Translatable tests: default/non-default storage, D-11 fallback, explicit empty translation, invalid locale and undeclared field no-write, sibling JSON field preservation, indexed upsert/update and morph/model isolation, WithLocale context isolation, transaction rollback. Admin tests: exact permission 403/allowed, is_default/sort_order mass-assignment rejection, delete/unset/disabled-default guards, no manage_messages surface, phrasebook keys in en/pl.
Cabana tests: three types compile and unknown mlunknown fails; non-ML nested values remain blocked; ML values lift before projection; malformed/extra locale keys fail; writer failure rolls back host write; writer is not invoked before permission/query checks. Markdown tests include script, iframe, event attributes, javascript/vbscript/data schemes. SPA tests cover selector synchronization, per-locale editing, copy, complete nested payload, and markdown composition without raw-HTML sinks. Extend OpenAPI conformance for all types.
go -C ../sm-translate-plugin test ./... -count=1 -race && go test ./modules/surf ./modules/cabana -count=1 -race && npm --prefix admin test -- --run admin/tests/form/registry.test.ts admin/tests/form/MLFields.test.ts admin/tests/form/MarkdownField.test.ts
<fails_when>Non-zero exit; Go race detector reports a race; any package/test reports FAIL; integration tests unexpectedly SKIP in the plugin run; or Vitest reports no tests or failures.</fails_when>
<acceptance_criteria>
- Every D-01..D-17 behavior assigned to code has at least one named assertion or gate check.
- Migrate, rollback, and re-migrate are proven against real Postgres.
- Parallel locale tests pass under -race with no shared current-locale state.
- High threats T-14.2.1-01/02/04/05/06/07/09/10/11/12 have concrete fail-when-broken tests.
- No tests require Messages admin, CMS components, AI/theme commands, import/export, or extra locale seeds.
</acceptance_criteria>
All production branches introduced by Plans 01-03 have focused unit or integration evidence, including race, rollback, authorization, mass-assignment, and XSS cases.
Run the requested security-review lane over the local Phase 14.2.1 changes. Produce 14.2.1-SECURITY-REVIEW.md at ASVS L1, preserving unique threat IDs T-14.2.1-01 through T-14.2.1-18. For every high threat, cite the exact source control and executed named test; status must be mitigated or the phase gate remains red. Review locale injection, manage_locales privilege, nested ML JSON, stored XSS, mass assignment, process-wide leakage, and submodule provenance. Do not fabricate an external-API matrix: state No external API integration: this phase ports a compiled plugin and local framework/host contracts only.
Update VALIDATION frontmatter to validated/nyquist compliant/wave 0 complete only after all mapped commands pass. Replace pending rows with exact test names and threat references, record the proof-host/manual Locales SPA check as end-of-phase UAT, and run the phase gate once in full.
bash scripts/check-phase14.2.1.sh --all
<fails_when>Non-zero exit; any stage is absent/skipped; output contains FAIL, a Go race, no-tests-to-run, unexpected SKIP, stale generated artifacts, forbidden deferred surface, unmitigated high threat, or lacks the final Phase 14.2.1 gate passed line.</fails_when>
<acceptance_criteria>
- Gate uses go -C ../sm-translate-plugin and go -C ../sm-grzybyfunkcjonalne-app; it does not invent a nested application directory.
- Plugin, cabana, surf, admin, docs, generated artifacts, and proof host all have explicit fail-closed stages.
- Security review contains every T-14.2.1-NN exactly once and blocks on all high findings.
- Validation rows name existing tests/commands and frontmatter is marked validated/nyquist compliant only after green execution.
- Gate confirms no Messages admin/manage_messages, CMS locale components, AI/theme commands, import/export, de seed, runtime plugin loading, AutoMigrate, or PHP modifications.
</acceptance_criteria>
The full three-repository phase gate is green, all high threats are mitigated with executed evidence, and validation is signed off.
<threat_model>
Trust Boundaries
| Boundary | Description |
|---|---|
| Test/gate → production claims | A no-op, skipped container, or stale generated artifact must not pass |
| Concurrent requests → context locale | Conflicting request locales must stay isolated |
| Security review → phase completion | High findings block completion |
STRIDE Threat Register
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|---|---|---|---|---|---|
| T-14.2.1-14 | Repudiation | phase gate | high | mitigate | Require named PASS/final marker; reject no-tests and unexpected skips |
| T-14.2.1-15 | Information Disclosure | concurrent Translator | high | mitigate | Race-enabled conflicting-locale test asserts context isolation |
| T-14.2.1-16 | Tampering | migration rollback | medium | mitigate | Up/down/re-up on dedicated Postgres with exact schema assertions |
| T-14.2.1-17 | Tampering | generated admin artifacts | medium | mitigate | Regenerate and require clean OpenAPI/TS/dist diff after build |
| T-14.2.1-18 | Elevation of Privilege | test fixture | high | mitigate | Fixture plugin is process-local/test-only and absent from generated production imports |
| T-14.2.1-SC | Tampering | package installs | high | mitigate | No dependency installation; existing exact pins and lockfile only |
ASVS L1: phase completion is blocked on every high finding. </threat_model>
`bash scripts/check-phase14.2.1.sh --all` is the authoritative final command and must end with `Phase 14.2.1 gate passed`. With the executor-started proof host and admin SPA, sign in as an administrator holding `golem15.translate.manage_locales`; open Locales, confirm English and Polski appear in order, edit the permitted name/enabled fields, and verify a user without the permission cannot open the controller.<success_criteria>
- Full unit, integration, race, migration rollback, SPA, docs, generated-artifact, and host gates pass.
- Every locked D-01..D-17 decision is covered.
- Every high STRIDE threat is mitigated with source and named-test evidence.
- No deferred surface or new external dependency entered the phase. </success_criteria>