From c385dc79ebd3c4491b396db61dc9f4c25a0965fd Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Sun, 11 Oct 2026 13:08:54 +0200 Subject: [PATCH] docs(16.3-03): complete Journal scopes and v0.1.21 release plan --- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 17 +- .../16.3-03-SUMMARY.md | 221 ++++++++++++++++++ 3 files changed, 233 insertions(+), 9 deletions(-) create mode 100644 .planning/phases/16.3-backend-admin-personal-api-tokens-with-scopes/16.3-03-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index bfe437a..e402cb2 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -1044,7 +1044,7 @@ Plans: 5. Module READMEs and `docs/` cover the token API, scopes and CLI commands. 6. The new code has unit tests, delivered in the phase's last plan. -**Plans:** 2/4 plans executed +**Plans:** 3/4 plans executed Plans: **Wave 1** @@ -1054,7 +1054,7 @@ Plans: - [x] 16.3-02-PLAN.md — Admin SPA API tokens card on My account per UI-SPEC: list states, two-step create with show-once plaintext and copy, revoke, phrase keys, dist, docs **Wave 3** *(blocked on Wave 2 completion)* -- [ ] 16.3-03-PLAN.md — Journal: journal and journal:read scopes, token auth through ResolveBackend with byte-identical bodies (reverses Phase 15 D-15), Journal README and the ResolveBackend docs example; release gate (human), summercms tag after v0.1.20, Journal go.mod and host gitlink bumps +- [x] 16.3-03-PLAN.md — Journal: journal and journal:read scopes, token auth through ResolveBackend with byte-identical bodies (reverses Phase 15 D-15), Journal README and the ResolveBackend docs example; release gate (human), summercms tag after v0.1.20, Journal go.mod and host gitlink bumps **Wave 4** *(blocked on Wave 3 completion)* - [ ] 16.3-04-PLAN.md — Unit tests: scope rules, route classification, guard, resolver, account API, CLI, migration, SPA backstops, Journal token matrix; Postgres tests for a Docker host; phase gate scripts/check-phase16.3.sh; validation map diff --git a/.planning/STATE.md b/.planning/STATE.md index 0366964..6ccc861 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -4,16 +4,16 @@ milestone: v1.0 current_phase: "16.3" current_phase_name: Backend admin personal API tokens with scopes status: executing -stopped_at: Completed 16.3-02-PLAN.md -last_updated: "2026-10-11T00:07:52.680Z" +stopped_at: Completed 16.3-03-PLAN.md +last_updated: "2026-10-11T11:08:53.900Z" last_activity: 2026-10-11 last_activity_desc: Completed 16.3-02 admin SPA API tokens card -state_head: fd07e2637fce8ca9bd6294ca611e6acc4137ef4a +state_head: 2030fd881aa08347931c638a90548b16bc188f86 progress: total_phases: 40 completed_phases: 13 total_plans: 162 - completed_plans: 156 + completed_plans: 157 gsd_state_version: "1.0" milestone_name: milestone --- @@ -30,7 +30,7 @@ See: .planning/PROJECT.md (updated 2026-09-16) ## Current Position Phase: 16.3 (Backend admin personal API tokens with scopes) — EXECUTING -Plan: 3 of 4 +Plan: 4 of 4 Status: Ready to execute Last activity: 2026-10-11 — Completed 16.3-02 (admin SPA API tokens card) @@ -211,6 +211,7 @@ Progress: [█████░░░░░] 48% | Phase 16.2 P06 | 43min | 3 tasks | - files | | Phase 16.3 P01 | 95 | 4 tasks | 43 files | | Phase 16.3 P02 | 9 min | 3 tasks | 17 files | +| Phase 16.3 P03 | 658 min | 4 tasks | 12 files | ## Accumulated Context @@ -690,6 +691,8 @@ Recent decisions affecting current work: - [Phase 16.3]: ResolveBackend is Bearer-only (cookie-less JWT guard) — Plugin write routes have no CSRF; cookie auth must not drive them - [Phase 16.3]: 16.3-02: ApiTokensPanel + ApiTokenCreateDialog on /account; plaintext dialog-local only; shared ConfirmDialog for revoke and close-without-copy — UI-SPEC component split - [Phase 16.3]: 16.3-02: expired from API drives Expired chip; dates use CellValue local YYYY-MM-DD / YYYY-MM-DD HH:mm — Plan decisions; no new date format +- [Phase 16.3]: Released summercms v0.1.21 after human resume release v0.1.21; Journal requires it; grzybyfunkcjonalne journal gitlink bumped; summercmsio not bumped +- [Phase 16.3]: Journal API uses cabana.ResolveBackend with cover golem15.journal.*; ErrTokenScope maps to PHP Insufficient permissions ### Pending Todos @@ -762,6 +765,6 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-10-11T00:07:52.680Z -Stopped at: Completed 16.3-02-PLAN.md +Last session: 2026-10-11T11:08:53.266Z +Stopped at: Completed 16.3-03-PLAN.md Resume file: None diff --git a/.planning/phases/16.3-backend-admin-personal-api-tokens-with-scopes/16.3-03-SUMMARY.md b/.planning/phases/16.3-backend-admin-personal-api-tokens-with-scopes/16.3-03-SUMMARY.md new file mode 100644 index 0000000..8d3f79f --- /dev/null +++ b/.planning/phases/16.3-backend-admin-personal-api-tokens-with-scopes/16.3-03-SUMMARY.md @@ -0,0 +1,221 @@ +--- +phase: 16.3-backend-admin-personal-api-tokens-with-scopes +plan: 03 +subsystem: auth +tags: [api-tokens, journal, ResolveBackend, release, g15, scopes] + +requires: + - phase: 16.3-backend-admin-personal-api-tokens-with-scopes + provides: cabana.ResolveBackend, account token API, admin SPA tokens card +provides: + - "journal and journal:read token scopes on sm-journal-plugin" + - "Journal API auth via cabana.ResolveBackend with cover golem15.journal.*" + - "ExampleResolveBackend docs example and Journal README token docs" + - "summercms v0.1.21 release with Journal go.mod and host gitlink bumps" +affects: [16.3-04, sm-journal-plugin, sm-grzybyfunkcjonalne-app] + +actuals: + tokens: 20568 + tasks: 4 + commits: 2 +plan_head_before: 611f98e33ba45b1f7718ead84cb8f8474e879f33 +plan_head_after: 2030fd881aa08347931c638a90548b16bc188f86 + +tech-stack: + added: [] + patterns: + - "Journal principals only via cabana.ResolveBackend(cover golem15.journal.*)" + - "ErrTokenScope → 403 Insufficient permissions; other resolver errors → 401 Authentication required" + - "Optional-auth reads treat cover/auth failure as anonymous" + +key-files: + created: + - ../sm-journal-plugin/token_scopes.go + - ../sm-journal-plugin/controllers/api/auth_test.go + - ../sm-journal-plugin/journal_api_token_smoke_test.go + - modules/cabana/example_tokens_test.go + modified: + - ../sm-journal-plugin/controllers/api/auth.go + - ../sm-journal-plugin/lang/en/lang.yaml + - ../sm-journal-plugin/lang/pl/lang.yaml + - ../sm-journal-plugin/README.md + - ../sm-journal-plugin/go.mod + - docs/services/authentication.md + - modules/cabana/phase10_csrf_test.go + - ../sm-grzybyfunkcjonalne-app/plugins/golem15/journal + +key-decisions: + - "Human resume: release v0.1.21 (release-now); no sm-summercmsio-app bump" + - "Probe test scope acme.probe registered for cover-failure cases because admin:read is Full on GET" + - "CSRF walk count updated 30→32 for account token create/revoke routes" + +patterns-established: + - "Plugin API writes: ResolveBackend + resolveError mapping to PHP bodies" + - "Release sheet at blocking-human gate before any tag/push" + +requirements-completed: [SC-2, SC-4, SC-5] + +coverage: + - id: D1 + description: "journal-scoped token minted via admin API creates a Journal post as its owner" + requirement: SC-4 + verification: + - kind: unit + ref: ../sm-journal-plugin/controllers/api/auth_test.go#TestResolveErrorMapping + status: pass + - kind: integration + ref: ../sm-journal-plugin/journal_api_token_smoke_test.go#TestJournalTokenTracer + status: pass + human_judgment: false + - id: D2 + description: "Read/unrelated/revoked tokens, optional draft unlock, featured-image canEdit parity, code-declared roles" + requirement: SC-2 + verification: + - kind: integration + ref: ../sm-journal-plugin/journal_api_token_smoke_test.go#TestJournalTokenExpansion + status: pass + human_judgment: false + - id: D3 + description: "Journal README and ExampleResolveBackend docs" + requirement: SC-5 + verification: + - kind: other + ref: go test ./cmd/summer -run TestDocsTree; go run ./cmd/summer docs:build --check + status: pass + human_judgment: false + - id: D4 + description: "Human-approved release v0.1.21 with Journal require and host gitlink" + verification: + - kind: other + ref: git ls-remote --tags origin refs/tags/v0.1.21; release-ok verify + status: pass + human_judgment: true + rationale: "Tag and push require human approval at blocking-human gate" + +duration: 658min +completed: 2026-10-11 +status: complete +--- + +# Phase 16.3 Plan 03: Journal scopes, ResolveBackend and v0.1.21 release Summary + +**Journal registers `journal` / `journal:read`, authenticates writes through `cabana.ResolveBackend`, documents the path, and ships as summercms `v0.1.21` with plugin and host bumps.** + +## Performance + +- **Duration:** 658 min (includes overnight pause at the blocking-human release gate) +- **Started:** 2026-10-11T00:09:06Z +- **Completed:** 2026-10-11T11:07:50Z +- **Tasks:** 4 +- **Files modified:** 12 (across summercms.go, sm-journal-plugin, sm-grzybyfunkcjonalne-app) + +## Accomplishments + +- Journal `TokenScopes` + lang keys; API auth switched to `cabana.ResolveBackend` with cover `golem15.journal.*` +- Postgres tracer and expansion matrix (read scope, probe cover, drafts, featured images, revoke, developer role grants) +- `ExampleResolveBackend` in cabana docs; Journal README scopes / Phase 15 D-15 reversal +- Human-approved release: annotated tag `v0.1.21`, Journal `go.mod` require, host journal gitlink + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Tracer** — `4ec64a3` (sm-journal-plugin, feat) +2. **Task 2: Matrix + docs** — `f2026c5` (sm-journal-plugin, feat); `60873a3` (summercms.go, docs) +3. **Task 3: Release gate** — gate `release-gate-ok`; human reply `release v0.1.21`; CSRF inventory fix `2030fd8` (summercms.go, fix) +4. **Task 4: Release** — tag `v0.1.21` object `dc181e6` on `2030fd8`; Journal bump `09308d9`; host gitlink `e44cfde` + +**Plan metadata:** (this commit) + +## Human reply (Task 3, verbatim) + +``` +release v0.1.21 +``` + +No `and summercmsio` — sm-summercmsio-app was not bumped. + +## Release + +| Item | Value | +|------|-------| +| Proposed / shipped tag | `v0.1.21` | +| Tag object | `dc181e6224389647ce378ac1420e5df48eea2e04` | +| Tag points at | `2030fd881aa08347931c638a90548b16bc188f86` | +| summercms.go master (pushed) | `2030fd8` | +| sm-journal-plugin main (pushed) | `09308d9` (requires `summercms v0.1.21`) | +| sm-grzybyfunkcjonalne-app master (pushed) | `e44cfde` (journal gitlink `09308d9`) | +| sm-summercmsio-app | not bumped | +| UAT redeploy | follow-up (not this plan) | + +### One-way surfaces published + +`pact.TokenScope` / `HasTokenScopes`; `bouncer.ScopeLimit` / `Principal.Scope`; `party.Activated`; `cabana.BackendAPIToken`, `APITokenPrefix`, `ResolveBackend`, `ErrUnauthenticated`, `ErrTokenScope`; account token routes; `g15_` format; `backend_api_tokens` / migration `202610110001_backend_api_tokens`. + +### Release sheet (pre-approval) + +- Trees clean and not behind origin; tag absent on origin before create +- Gate printed `release-gate-ok` (after CSRF count 30→32) +- Open high findings: none (`16.3-REVIEW.md` / `16.3-SECURITY.md` absent) + +## Postgres verify status + +| Suite | Status | +|-------|--------| +| 16.3-01 cabana/lagoon Postgres | **RUN** (prior SUMMARY) | +| `TestJournalTokenTracer` | **RUN** pass | +| `TestJournalTokenExpansion` | **RUN** pass | +| NOT RUN | none on this host for 16.3-03 | + +## Decisions Made + +- Followed D-04/D-01/D-15 and featured-image PHP parity (CanEdit only). +- Registered test-only `acme.probe` scope for unrelated-cover cases (`admin:read` is Full on GET). +- Human chose release-now `v0.1.21` without summercmsio. + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] CSRF state-changing route count stale after token API** +- **Found during:** Task 3 release gate (`TestPhase10CSRF`) +- **Issue:** Walk counted 32 routes (account token create/revoke) but expected 30 +- **Fix:** Updated expected count and comment to 32 +- **Files modified:** `modules/cabana/phase10_csrf_test.go` +- **Verification:** Six cabana gate tests pass; `release-gate-ok` +- **Committed in:** `2030fd8` + +**2. [Rule 3 - Blocking] Probe scope for cover-failure GET path** +- **Found during:** Task 2 expansion (`admin:read` on GET is Full, unlocks drafts as owner) +- **Issue:** Plan suggested `admin:read` for anonymous GET; Full scopes skip cover +- **Fix:** Test plugin `acme.probe` with `acme.probe.*` scope for cover refuse → anonymous GET +- **Files modified:** `journal_api_token_smoke_test.go` +- **Verification:** `TestJournalTokenExpansion` pass +- **Committed in:** `f2026c5` + +--- + +**Total deviations:** 2 auto-fixed (1 bug, 1 blocking) +**Impact on plan:** Required for green release gate and correct cover semantics; no scope creep. + +## Issues Encountered + +None beyond the deviations above. Overnight pause at Task 3 until human resume. + +## User Setup Required + +None - no external service configuration required. UAT redeploy remains a separate follow-up. + +## Next Phase Readiness + +Ready for 16.3-04 (unit/backstop matrix). Framework + Journal token path released; hosts can mint `journal`-scoped tokens after migrate/redeploy. + +## Self-Check: PASSED + +- Key files exist on disk +- Tag `v0.1.21` on origin; Journal main = origin/main; host gitlink = Journal main; `release-ok` +- Commits grepped for 16.3-03 present in both repos + +--- +*Phase: 16.3-backend-admin-personal-api-tokens-with-scopes* +*Completed: 2026-10-11*