docs(15-04): complete journal tests, gate, and ASVS review plan
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -883,7 +883,7 @@ Plans:
|
|||||||
3. Plugin README and docs stay application-neutral (`the application`, example names such as `blog`).
|
3. Plugin README and docs stay application-neutral (`the application`, example names such as `blog`).
|
||||||
4. The new code has unit tests, delivered in the phase's last plan.
|
4. The new code has unit tests, delivered in the phase's last plan.
|
||||||
|
|
||||||
**Plans:** 3/4 plans executed
|
**Plans:** 4/4 plans executed
|
||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
|
|
||||||
@@ -897,7 +897,7 @@ Plans:
|
|||||||
- [x] 15-03-PLAN.md — `/_journal/api/v1`, buckets, backend Bearer writes, media, Typesense gate off
|
- [x] 15-03-PLAN.md — `/_journal/api/v1`, buckets, backend Bearer writes, media, Typesense gate off
|
||||||
|
|
||||||
**Wave 4** *(blocked on Wave 3 completion)*
|
**Wave 4** *(blocked on Wave 3 completion)*
|
||||||
- [ ] 15-04-PLAN.md — Unit/integration tests last, PHPUnit map, phase gate, security review
|
- [x] 15-04-PLAN.md — Unit/integration tests last, PHPUnit map, phase gate, security review
|
||||||
|
|
||||||
### Phase 16: grzybyfunkcjonalne.pl on reusable blog views
|
### Phase 16: grzybyfunkcjonalne.pl on reusable blog views
|
||||||
|
|
||||||
@@ -960,7 +960,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 →
|
|||||||
| 14. Domain jobs and external integrations | 6/6 | In Progress| |
|
| 14. Domain jobs and external integrations | 6/6 | In Progress| |
|
||||||
| 14.1. OAuth identities and fonoteka me routes (INSERTED) | 2/2 | Complete | 2026-10-05 |
|
| 14.1. OAuth identities and fonoteka me routes (INSERTED) | 2/2 | Complete | 2026-10-05 |
|
||||||
| 14.2. Local Fonoteka frontend on local SummerCMS backend (INSERTED) | 0/TBD | Not started | - |
|
| 14.2. Local Fonoteka frontend on local SummerCMS backend (INSERTED) | 0/TBD | Not started | - |
|
||||||
| 15. Journal plugin | 2/4 | In Progress| |
|
| 15. Journal plugin | 4/4 | Complete | 2026-10-06 |
|
||||||
| 16. grzybyfunkcjonalne.pl on reusable blog views | 0/TBD | Not started | - |
|
| 16. grzybyfunkcjonalne.pl on reusable blog views | 0/TBD | Not started | - |
|
||||||
| 20. Płytarium cutover | 0/TBD | Not started | - |
|
| 20. Płytarium cutover | 0/TBD | Not started | - |
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ milestone: v1.0
|
|||||||
current_phase: 15
|
current_phase: 15
|
||||||
current_phase_name: Journal plugin
|
current_phase_name: Journal plugin
|
||||||
status: executing
|
status: executing
|
||||||
stopped_at: Completed 15-03-PLAN.md
|
stopped_at: Completed 15-04-PLAN.md
|
||||||
last_updated: "2026-10-06T17:12:00Z"
|
last_updated: "2026-10-06T17:22:19Z"
|
||||||
last_activity: 2026-10-06
|
last_activity: 2026-10-06
|
||||||
last_activity_desc: Completed 15-03 journal public API, writes, media, RSS, Typesense gate
|
last_activity_desc: Completed 15-04 journal tests, phase gate, and ASVS review
|
||||||
state_head: 685837a3c8e23c2f05e2b367f42bd8d53e9b432b
|
state_head: 7307b36baaad660c84b5b365f2dac17ca7313941
|
||||||
progress:
|
progress:
|
||||||
total_phases: 26
|
total_phases: 26
|
||||||
completed_phases: 12
|
completed_phases: 12
|
||||||
total_plans: 135
|
total_plans: 135
|
||||||
completed_plans: 134
|
completed_plans: 135
|
||||||
milestone_name: milestone
|
milestone_name: milestone
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -30,16 +30,16 @@ See: .planning/PROJECT.md (updated 2026-09-16)
|
|||||||
|
|
||||||
Phase: 15 (Journal plugin) — EXECUTING
|
Phase: 15 (Journal plugin) — EXECUTING
|
||||||
Plan: 4 of 4
|
Plan: 4 of 4
|
||||||
Status: Ready to execute
|
Status: Ready for phase verification
|
||||||
Last activity: 2026-10-06 — Completed 15-03 journal public API, writes, media, RSS, Typesense gate
|
Last activity: 2026-10-06 — Completed 15-04 journal tests, phase gate, and ASVS review
|
||||||
|
|
||||||
Progress: [████████░░] 75%
|
Progress: [██████████] 100%
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
**Velocity:**
|
**Velocity:**
|
||||||
|
|
||||||
- Total plans completed: 64
|
- Total plans completed: 65
|
||||||
- Average duration: 21 min
|
- Average duration: 21 min
|
||||||
- Total execution time: 104 min
|
- Total execution time: 104 min
|
||||||
|
|
||||||
@@ -601,6 +601,8 @@ Recent decisions affecting current work:
|
|||||||
- [Phase 15]: journal:export-posts/import-posts are JSON-per-slug files matching PHP ExportPosts/ImportPosts (--path, --dry-run, --force), not a Winter CSV framework
|
- [Phase 15]: journal:export-posts/import-posts are JSON-per-slug files matching PHP ExportPosts/ImportPosts (--path, --dry-run, --force), not a Winter CSV framework
|
||||||
- [Phase 15]: Posts toolbar extra buttons are HasAdminActions names exportPosts/importPosts with golem15.journal.access_import_export; create/delete stay reserved
|
- [Phase 15]: Posts toolbar extra buttons are HasAdminActions names exportPosts/importPosts with golem15.journal.access_import_export; create/delete stay reserved
|
||||||
- [Phase 15]: NavigationItem has no IconSvg; journal-icon.svg is go:embed in AdminFS; user_id is WritableForeignKey and FormBeforeCreate stamps it when empty
|
- [Phase 15]: NavigationItem has no IconSvg; journal-icon.svg is go:embed in AdminFS; user_id is WritableForeignKey and FormBeforeCreate stamps it when empty
|
||||||
|
- [Phase 15]: 15-04 security review was executor-self-performed (no gsd-security-auditor in this Cursor session); every cited TestName was re-run. Wave-3 HTTP tests stay at plugin root; controllers/api holds clampPerPage/media path units plus EndToEnd stubs.
|
||||||
|
- [Phase 15]: Host journal gitlink is a nested clone; bump via file:// fetch with protocol.file.allow=always. TestSearchGateOff must not skip.
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
|
|||||||
209
.planning/phases/15-journal-plugin/15-04-SUMMARY.md
Normal file
209
.planning/phases/15-journal-plugin/15-04-SUMMARY.md
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
---
|
||||||
|
phase: 15-journal-plugin
|
||||||
|
plan: 04
|
||||||
|
subsystem: testing
|
||||||
|
tags: [journal, phpunit, testcontainers, race, phase-gate, asvs, typesense]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 15-03
|
||||||
|
provides: "Anonymous GET /_journal/api/v1, Bearer writes, JOURNAL-005, media, RSS, Typesense gate, named wave-3 tests at plugin root"
|
||||||
|
provides:
|
||||||
|
- "TestJournalEndToEnd on real Postgres through party/surf/cabana"
|
||||||
|
- "D-05 PHPUnit map: TestFillable, TestJournal005DraftShow, TestJournal006MediaUpload, TestFormatHTMLRejectsUnsafeHTML, rollback/remigrate"
|
||||||
|
- "scripts/check-phase15.sh fail-closed gate ending with Phase 15 gate passed"
|
||||||
|
- "15-SECURITY-REVIEW.md ASVS L1 with T-15-01..15 and T-15-SC closed"
|
||||||
|
affects: [16]
|
||||||
|
|
||||||
|
actuals:
|
||||||
|
tokens: 28000
|
||||||
|
tasks: 3
|
||||||
|
commits: 6
|
||||||
|
plan_head_before: 05b77b781825b279ff82f387717b83ac9d334a1e
|
||||||
|
plan_head_after: 7307b36baaad660c84b5b365f2dac17ca7313941
|
||||||
|
plugin_repo_head_after: d09edde080ee32bdac9caca9e4c92d8d12791020
|
||||||
|
host_repo_head_after: ff20e6cce25628341c4c1e6b5879f1f3979baa2d
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Wave-3 HTTP tests stay at plugin root sharing admin_harness TestMain; controllers/api tests cover clampPerPage and media path units"
|
||||||
|
- "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-journal-plugin/models/fillable_test.go
|
||||||
|
- ../sm-journal-plugin/models/translatable_test.go
|
||||||
|
- ../sm-journal-plugin/classes/format_html_test.go
|
||||||
|
- ../sm-journal-plugin/updates/migrations_test.go
|
||||||
|
- ../sm-journal-plugin/controllers/api/posts_test.go
|
||||||
|
- ../sm-journal-plugin/controllers/api/media_test.go
|
||||||
|
- ../sm-journal-plugin/search_test.go
|
||||||
|
- ../sm-journal-plugin/journal_api_matrix_test.go
|
||||||
|
- ../sm-journal-plugin/integration_test.go
|
||||||
|
- ../sm-journal-plugin/admin_harness_test.go
|
||||||
|
- scripts/check-phase15.sh
|
||||||
|
- .planning/phases/15-journal-plugin/15-SECURITY-REVIEW.md
|
||||||
|
modified:
|
||||||
|
- ../sm-journal-plugin/journal_api_writes_test.go
|
||||||
|
- ../sm-journal-plugin/journal_api_task3_test.go
|
||||||
|
- ../sm-journal-plugin/plugin_test.go
|
||||||
|
- ../sm-journal-plugin/updates/postgres_test.go
|
||||||
|
- ../sm-grzybyfunkcjonalne-app/boot_test.go
|
||||||
|
- ../sm-grzybyfunkcjonalne-app/plugins/golem15/journal
|
||||||
|
- .planning/phases/15-journal-plugin/15-VALIDATION.md
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Reuse wave-3 named HTTP tests at plugin root rather than relocating them into controllers/api (dispatch-authorized); JOURNAL-005/401/media/RSS remain named"
|
||||||
|
- "15-04 security review was executor-self-performed (no gsd-security-auditor in this Cursor session); every cited TestName was re-run"
|
||||||
|
- "TestSearchGateOff must not skip; unpublished ShouldBeSearchable stays false even if the in-memory gate is flipped on"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Fail-closed phase gate: named PASS lines, refuse skip/no-tests/race, sibling go -C, PHP SHA pin 02110eb1, forbidden-surface scan including D-16 tide"
|
||||||
|
- "Host journal gitlink is a nested clone; bump via file:// fetch with protocol.file.allow=always"
|
||||||
|
|
||||||
|
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, D-18, D-19, D-20, D-21, D-22, D-23]
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
- id: D1
|
||||||
|
description: "Real-Postgres e2e migrates, admin-creates an mlmarkdown post, lists published rows, 401s anonymous writes, and 404s draft show"
|
||||||
|
requirement: D-05
|
||||||
|
verification:
|
||||||
|
- kind: e2e
|
||||||
|
ref: "../sm-journal-plugin#TestJournalEndToEnd"
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: "../sm-grzybyfunkcjonalne-app#TestBootUserTranslateJournal"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D2
|
||||||
|
description: "PHPUnit map, migrations rollback/remigrate, FormatHTML unsafe tags, search-gate zero HTTP, categories/tags/RSS/featured-image auth"
|
||||||
|
requirement: D-05
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "../sm-journal-plugin/models#TestFillable"
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: "../sm-journal-plugin/updates#TestJournalMigrationsRollbackAndRemigrate"
|
||||||
|
status: pass
|
||||||
|
- kind: unit
|
||||||
|
ref: "../sm-journal-plugin/classes#TestFormatHTMLRejectsUnsafeHTML"
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: "../sm-journal-plugin#TestSearchGateOff"
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: "../sm-journal-plugin#TestJournalPublicCategories"
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: "../sm-journal-plugin#TestJournalPublicTags"
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: "../sm-journal-plugin#TestJournalRSS"
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: "../sm-journal-plugin#TestJournalFeaturedImageUnauthenticated"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D3
|
||||||
|
description: "Fail-closed check-phase15.sh --all plus ASVS L1 review closing T-15-01..15 and T-15-SC"
|
||||||
|
requirement: D-07
|
||||||
|
verification:
|
||||||
|
- kind: other
|
||||||
|
ref: "bash scripts/check-phase15.sh --all"
|
||||||
|
status: pass
|
||||||
|
- kind: other
|
||||||
|
ref: ".planning/phases/15-journal-plugin/15-SECURITY-REVIEW.md"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D4
|
||||||
|
description: "Proof-host Journal SPA check as an administrator holding golem15.journal.*"
|
||||||
|
requirement: D-19
|
||||||
|
verification: []
|
||||||
|
human_judgment: true
|
||||||
|
rationale: "Needs a running host, admin login, and visual confirmation of Journal nav plus mlmarkdown create; recorded as end-of-phase UAT"
|
||||||
|
|
||||||
|
duration: 75min
|
||||||
|
completed: 2026-10-06
|
||||||
|
status: complete
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 15 Plan 04: Journal unit/integration tests and phase gate Summary
|
||||||
|
|
||||||
|
**Real-Postgres e2e, PHPUnit/security test matrices, fail-closed `check-phase15.sh`, and an ASVS L1 review that closes T-15-01..15 plus T-15-SC**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 75 min
|
||||||
|
- **Started:** 2026-10-06T17:07:37Z
|
||||||
|
- **Completed:** 2026-10-06T17:22:19Z
|
||||||
|
- **Tasks:** 3
|
||||||
|
- **Files modified:** 22
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- Proven the user-visible Journal path on real Postgres (`TestJournalEndToEnd`): migrate, admin mlmarkdown en/pl, anonymous list hides drafts, Bearer create, JOURNAL-005 404 without `data`.
|
||||||
|
- Completed the D-05 PHPUnit map with named tests (`TestFillable`, `TestJournal005DraftShow`, `TestJournal006MediaUpload`, `TestFormatHTMLRejectsUnsafeHTML`, `TestSearchGateOff`, categories/tags/RSS/featured-image 401) and migrate/rollback/remigrate on Postgres.
|
||||||
|
- `scripts/check-phase15.sh --all` printed `Phase 15 gate passed`. `15-SECURITY-REVIEW.md` closes every T-15-* threat; VALIDATION is `nyquist_compliant: true`.
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: Tracer e2e on Postgres** - plugin `c5b44b6a5d32030e3bac4de156e4df46c07ea51f` (test); host `e60f6c4e64d3c90d718e1acd6cbcc7fe4ad59ff3` (test CORS)
|
||||||
|
2. **Task 2: PHPUnit map, migrations, FormatHTML, search-gate** - plugin `d09edde080ee32bdac9caca9e4c92d8d12791020` (test); host gitlink `ff20e6cce25628341c4c1e6b5879f1f3979baa2d`
|
||||||
|
3. **Task 3: Phase gate, security review, validation** - `7307b36baaad660c84b5b365f2dac17ca7313941` (test)
|
||||||
|
|
||||||
|
**Plan metadata:** this docs commit (docs: complete plan)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `../sm-journal-plugin/integration_test.go` - `TestJournalEndToEnd` production path
|
||||||
|
- `../sm-journal-plugin/admin_harness_test.go` - fail-closed testcontainers harness
|
||||||
|
- `../sm-journal-plugin/models/fillable_test.go` - JOURNAL-001/002 / redactor_id
|
||||||
|
- `../sm-journal-plugin/models/translatable_test.go` - MorphName + Tag not translatable
|
||||||
|
- `../sm-journal-plugin/classes/format_html_test.go` - JOURNAL-003/004 substitute
|
||||||
|
- `../sm-journal-plugin/updates/migrations_test.go` - rollback and remigrate
|
||||||
|
- `../sm-journal-plugin/search_test.go` - `TestSearchGateOff` zero HTTP
|
||||||
|
- `../sm-journal-plugin/journal_api_matrix_test.go` - per_page, neighbors, mass-assign, admin 403
|
||||||
|
- `../sm-journal-plugin/controllers/api/posts_test.go` - `clampPerPage` plus EndToEnd stub
|
||||||
|
- `../sm-journal-plugin/controllers/api/media_test.go` - `/journal/` path units
|
||||||
|
- `scripts/check-phase15.sh` - fail-closed `--all` gate
|
||||||
|
- `.planning/phases/15-journal-plugin/15-SECURITY-REVIEW.md` - ASVS L1
|
||||||
|
- `.planning/phases/15-journal-plugin/15-VALIDATION.md` - signed off
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- Reused wave-3 HTTP tests at plugin root instead of moving them into `controllers/api` so they keep sharing `TestMain`. Named JOURNAL-005/401/media/RSS tests still PASS.
|
||||||
|
- Self-performed the security review (no `gsd-security-auditor` subagent), matching 14.2.1-04, and disclosed that in review frontmatter.
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Reuse - authorized] HTTP tests stayed at plugin root**
|
||||||
|
- **Found during:** Task 2
|
||||||
|
- **Issue:** Plan artifacts named `controllers/api/posts_test.go` as the home of `TestJournal005DraftShow`.
|
||||||
|
- **Fix:** Kept the named tests in `journal_api_writes_test.go` / `journal_api_task3_test.go`; added `posts_test.go` for `clampPerPage` and the EndToEnd stub required by `go test ./...`.
|
||||||
|
- **Verification:** `go test ./... -race` PASS lines for every required TestName.
|
||||||
|
- **Committed in:** `d09edde` (Task 2)
|
||||||
|
|
||||||
|
**Total deviations:** 1 auto-fixed (authorized reuse)
|
||||||
|
**Impact on plan:** No missing named tests; gate `--all` green.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
- `go get` of `sm-user-plugin` from the plugin module hit private-module auth; tests blank-import it with a `go.mod` require and `go.work` replace only (no `go.mod` replace).
|
||||||
|
- Nested host gitlink checkout is detached; bump with `protocol.file.allow=always` and `file://` fetch, then `git add` the gitlink.
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
Phase 15 plans are complete. Ready for `$gsd-verify-work 15`. Human UAT remains: proof-host SPA Journal nav and mlmarkdown create. Phase 16 can consume `sm-journal-plugin` at `d09edde`.
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 15-journal-plugin*
|
||||||
|
*Completed: 2026-10-06*
|
||||||
Reference in New Issue
Block a user