diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 0a1e84e6..b4984614 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -1198,7 +1198,7 @@ Plans: 3. Golden tests show that the serializers (`Message.toApiArray` with attachments, thread summaries, channel, category, pref, pin and mention arrays) and every realtime event (name, channel and payload) match PHP output captured from Wavepath. Route-level parity of `/_wave` is checked at the Wavepath port. 4. The new code has unit tests, delivered in the phase's last plan. -**Plans:** 6/7 plans executed +**Plans:** 7/7 plans complete Plans: **Wave 1** @@ -1218,7 +1218,7 @@ Plans: - [x] 19-06-PLAN.md — Participant-only canSend (CR-01) and created_by reassignment on user.Deleting (CR-02) **Wave 6** *(gap closure, tests last)* -- [ ] 19-07-PLAN.md — TestTeammateDMWriteIDOR, TestDeletingCascade creator path, check-phase19.sh names +- [x] 19-07-PLAN.md — TestTeammateDMWriteIDOR, TestDeletingCascade creator path, check-phase19.sh names ### Phase 19.1: Chat satellites diff --git a/.planning/phases/19-chat-and-chatchannels/19-07-SUMMARY.md b/.planning/phases/19-chat-and-chatchannels/19-07-SUMMARY.md new file mode 100644 index 00000000..ae9213d6 --- /dev/null +++ b/.planning/phases/19-chat-and-chatchannels/19-07-SUMMARY.md @@ -0,0 +1,176 @@ +--- +phase: 19-chat-and-chatchannels +plan: 07 +subsystem: testing +tags: [chat, chatchannels, IDOR, GDPR, TestTeammateDMWriteIDOR, TestDeletingCascade, check-phase19] + +requires: + - phase: 19-06 + provides: participant-only SendMessage (HTTP 404) and ReassignCreatedBy on user.Deleting +provides: + - "CR-01 named postgres test: TestTeammateDMWriteIDOR (third teammate POST into pair DM is 404)" + - "CR-02 creator-delete assertions on TestDeletingCascade (FormAfterDelete sequence)" + - "scripts/check-phase19.sh PG_CHAT_TESTS requires TestTeammateDMWriteIDOR" +affects: [Wavepath port, 19.1] + +actuals: + tokens: 1428 + tasks: 3 + commits: 2 +plan_head_before: d1852f6cdafbeffc7599aebfbb2cef92316c27ab +plan_head_after: pending-summary-commit + +tech-stack: + added: [] + patterns: + - "Slash-free top-level postgres names so go_named -run regex stays valid" + - "FormAfterDelete in tests is Fire DeletingEvent then Unscoped delete of the user row" + +key-files: + created: [] + modified: + - ../sm-chat-plugin/http_tracer_test.go + - ../sm-chatchannels-plugin/http_tracer_test.go + - scripts/check-phase19.sh + - .planning/ROADMAP.md + +key-decisions: + - "TestTeammateDMWriteIDOR is a top-level test, not a slash subtest" + - "TestDeletingCascade stays one function: Bob-as-member block then a second private channel for Alice-as-creator" + - "WR-01..WR-04 and IN-01..IN-02 stay open" + +patterns-established: + - "Gap-closure HTTP IDOR cases reuse bootWeb/call/frontendToken and skip via TestMain -short" + - "Creator-delete GDPR cases match FormAfterDelete: Fire then Unscoped delete" + +requirements-completed: [SC-19-1, D-08, D-13] + +coverage: + - id: D1 + description: "Two context members open a DM; a third teammate POSTing into that conversation id gets 404; the pair can still send (CR-01 / D-08 / SC-19-1)" + requirement: SC-19-1 + verification: + - kind: integration + ref: "../sm-chat-plugin/http_tracer_test.go#TestTeammateDMWriteIDOR" + status: pass + - kind: other + ref: "bash scripts/check-phase19.sh --all" + status: pass + human_judgment: false + - id: D2 + description: "Deleting Alice the creator (Fire DeletingEvent then Unscoped delete) leaves Bob's member row, the channel row, and the conversation with created_by = Bob (CR-02 / D-13)" + requirement: D-13 + verification: + - kind: integration + ref: "../sm-chatchannels-plugin/http_tracer_test.go#TestDeletingCascade" + status: pass + - kind: other + ref: "bash scripts/check-phase19.sh --all" + status: pass + human_judgment: false + - id: D3 + description: "check-phase19.sh requires TestTeammateDMWriteIDOR and TestDeletingCascade by name; --self-test and --all pass" + requirement: D-08 + verification: + - kind: other + ref: "bash scripts/check-phase19.sh --self-test" + status: pass + - kind: other + ref: "bash scripts/check-phase19.sh --all" + status: pass + human_judgment: false + +duration: 5min +completed: 2026-10-17 +status: complete +--- + +# Phase 19 Plan 07: Chat/ChatChannels Gap-Closure Tests Summary + +**Named postgres tests lock teammate DM write-IDOR as HTTP 404 and creator-delete CASCADE, and check-phase19.sh requires those names** + +## Performance + +- **Duration:** 5 min +- **Started:** 2026-10-17T20:31:59Z +- **Completed:** 2026-10-17T20:37:09Z +- **Tasks:** 3 +- **Files modified:** 4 + +## Accomplishments + +- `TestTeammateDMWriteIDOR` POSTs a two-person DM as A, counts exactly two participants (A and B), then C (same `acme.teams` host) POSTing `/conversations/{id}/messages` is 404 while A is 200 or 201. `TestChatHTTPTracer` is unchanged. +- `TestDeletingCascade` keeps the Bob-as-member block. Alice then creates a second private channel with Bob; Fire `DeletingEvent` for Alice and Unscoped-delete Alice like `FormAfterDelete`. Bob's member row, the channel row, and the conversation row remain; `created_by` is Bob, not Alice. +- `scripts/check-phase19.sh` `PG_CHAT_TESTS` includes `TestTeammateDMWriteIDOR` (slash-free); `TestDeletingCascade` stays in `PG_CHATCHANNELS_TESTS`. The self-test token loop greps the new name. `--self-test` and `--all` (plugins + docs + postgres) passed on Docker. + +## Task Commits + +Each task was committed atomically: + +1. **Task 1 (sm-chat-plugin):** `f4aeb87` (test) — `TestTeammateDMWriteIDOR` +2. **Task 2 (sm-chatchannels-plugin):** `3738f45` (test) — `TestDeletingCascade` creator-delete path +3. **Task 3 (summercms.go):** `bd301a1` (test) — `PG_CHAT_TESTS` + self-test token `TestTeammateDMWriteIDOR` + +**Plan metadata:** this commit (docs) + +_Plugin SHAs are local only. No remotes were pushed. fonoteka submodule pointers were not bumped._ + +## Files Created/Modified + +- `../sm-chat-plugin/http_tracer_test.go` — `TestTeammateDMWriteIDOR` (bootWeb/call/frontendToken) +- `../sm-chatchannels-plugin/http_tracer_test.go` — second private channel + Unscoped Alice delete + `created_by` assertions +- `scripts/check-phase19.sh` — `TestTeammateDMWriteIDOR` in `PG_CHAT_TESTS` and the self-test token loop +- `.planning/ROADMAP.md` — 19-07 checked; Plans 7/7 + +## Decisions Made + +- Top-level `TestTeammateDMWriteIDOR` so `go_named` `-run` does not split on `/`. `TestChatHTTPTracer` remains a required postgres name. +- Extend `TestDeletingCascade` in place with a second channel so Bob-as-member cannot empty the only remaining participant set. +- WR-01, WR-02, WR-03, WR-04, IN-01 and IN-02 stay open. + +## Deviations from Plan + +None - plan executed exactly as written. + +**Total deviations:** 0 auto-fixed +**Impact on plan:** None. + +## Issues Encountered + +None. + +## User Setup Required + +None - no external service configuration required. + +## Verification Results + +- `grep -n 'func TestTeammateDMWriteIDOR' ../sm-chat-plugin/http_tracer_test.go` — PASS (one line) +- `grep -n 'func TestChatHTTPTracer' ../sm-chat-plugin/http_tracer_test.go` — PASS (one line) +- `go -C ../sm-chat-plugin vet ./... && go -C ../sm-chat-plugin test -count=1 -short ./...` — PASS +- `go -C ../sm-chat-plugin test -count=1 -run '^TestTeammateDMWriteIDOR$' -v .` — PASS (`--- PASS: TestTeammateDMWriteIDOR (0.87s)`) +- `grep -n 'func TestDeletingCascade' ../sm-chatchannels-plugin/http_tracer_test.go` — PASS (one line) +- `grep -n 'Unscoped' ../sm-chatchannels-plugin/http_tracer_test.go` — PASS +- `grep -n 'created_by' ../sm-chatchannels-plugin/http_tracer_test.go` — PASS +- `go -C ../sm-chatchannels-plugin vet ./... && go -C ../sm-chatchannels-plugin test -count=1 -short ./...` — PASS +- `go -C ../sm-chatchannels-plugin test -count=1 -run '^TestDeletingCascade$' -v .` — PASS (`--- PASS: TestDeletingCascade (0.80s)`) +- `bash -n scripts/check-phase19.sh && bash scripts/check-phase19.sh --self-test` — PASS (`phase19 self-test passed`) +- `bash scripts/check-phase19.sh --all` — PASS (`phase19 postgres passed`; 6 chat + 4 chatchannels named tests; `Phase 19 gate passed`) +- No remotes pushed; `sm-chat-plugin` and `sm-chatchannels-plugin` remain local-ahead only +- WR-01..WR-04 and IN-01..IN-02 unread + +## Next Phase Readiness + +Phase 19 plans are 7/7. Ready for `/msd-verify-work 19` and Phase 19.1 (chat satellites). Unit tests were the last plan. WR-01..WR-04 and IN-01..IN-02 stay open. + +--- +*Phase: 19-chat-and-chatchannels* +*Completed: 2026-10-17* + +## Self-Check: PASSED + +- FOUND: `.planning/phases/19-chat-and-chatchannels/19-07-SUMMARY.md` +- FOUND: `../sm-chat-plugin/http_tracer_test.go` commit `f4aeb87` +- FOUND: `../sm-chatchannels-plugin/http_tracer_test.go` commit `3738f45` +- FOUND: `scripts/check-phase19.sh` commit `bd301a1` +- FOUND: ROADMAP 19-07 checked; Plans 7/7