diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 2e9947a9..3fd83d6d 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -1235,12 +1235,12 @@ Plans: 3. Already met: fonoteka's PHP userfriends tree equals Wavepath 182b514; fonoteka.go has no port and Wavepath's copy is the single source. 4. The new code has unit tests, delivered in the phase's last plan. -**Plans:** 1/6 plans executed +**Plans:** 2/6 plans executed Plans: **Wave 1** - [x] 19.1-01-PLAN.md — userfriends repo, baseline, friends HTTP tracer, group events, soft chat adapter, GDPR -- [ ] 19.1-03-PLAN.md — chatbots repo, bot_flags, slash-command dispatcher, /ping tracer (no AI-plugin import) +- [x] 19.1-03-PLAN.md — chatbots repo, bot_flags, slash-command dispatcher, /ping tracer (no AI-plugin import) - [ ] 19.1-04-PLAN.md — webpush-go note, then herald subscriptions, PublicOnly send, rollback-sends-0 tracer **Wave 2** *(D-17 gate for forum; chatvideo after chat)* @@ -1434,7 +1434,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → | 18. Payment Gateway | 8/8 | Complete | 2026-10-14 | | 18.1. Payment Gateway Subscriptions | 9/9 | Complete | 2026-10-16 | | 19. Chat and ChatChannels | 7/7 | Complete | 2026-10-17 | -| 19.1. Chat satellites | 1/6 | In Progress| | +| 19.1. Chat satellites | 2/6 | In Progress| | | 19.2. Chat polish against WavePath clients | 0/TBD | Not started | - | | 19.3. Framework transport and infrastructure for WavePath | 6/6 | In Progress| | | 19.4. OIDC provider on wristband | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 645fd32c..425a1734 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -4,16 +4,16 @@ milestone: v1.0 current_phase: "19.1" current_phase_name: Chat satellites status: executing -stopped_at: 19.1-02 Task 1 done; blocked on D-17 Render/Purify -last_updated: "2026-10-18T11:24:39.168Z" +stopped_at: Completed 19.1-03-PLAN.md +last_updated: "2026-10-18T11:36:12.092Z" last_activity: 2026-10-18 last_activity_desc: Phase 19.1 execution started -state_head: 2740ab276cc82e0e905f115602a232ccfc136a04 +state_head: ceabc9ccbc6b6075b36e9efad3656edf9db05e44 progress: total_phases: 41 completed_phases: 33 total_plans: 204 - completed_plans: 199 + completed_plans: 200 gsd_state_version: "1.0" milestone_name: milestone --- @@ -252,6 +252,7 @@ Progress: [████████░░] 80% | Phase 18.1 P09 | 60min | 5 tasks | 27 files | | Phase 19 P01 | 80min | 3 tasks | 34 files | | Phase 19.1 P01 | 12min | 3 tasks | 37 files | +| Phase 19.1 P19.1-03 | 7 min | 3 tasks | 32 files | ## Accumulated Context @@ -851,6 +852,8 @@ Recent decisions affecting current work: - [Phase 19.1]: Task 1 reply verbatim: proceed-and-push - [Phase 19.1]: Locked D-01 names, D-02 baseline 202610180001_create_golem15_userfriends_baseline, D-05 prefix /_userfriends/api/v1 - [Phase 19.1]: tea repos create --owner golem15 --name sm-userfriends-plugin succeeded; main pushed at 2480ff0 (never force). summercms.go was not pushed. +- [Phase 19.1]: Task 1 reply verbatim: proceed. Locked D-02 baseline 202610180001_create_golem15_chatbots_baseline and D-05 prefix /_chatbots/api/v1; remote follows plan 01 proceed-and-push. +- [Phase 19.1]: tea repos create --owner golem15 --name sm-chatbots-plugin succeeded; main pushed at c7d9108 (never force). summercms.go was not pushed. ### Pending Todos @@ -934,6 +937,6 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-10-18T11:24:30.748Z -Stopped at: 19.1-02 Task 1 done; blocked on D-17 Render/Purify -Resume file: .planning/phases/19.1-chat-satellites/19.1-02-PLAN.md +Last session: 2026-10-18T11:36:11.338Z +Stopped at: Completed 19.1-03-PLAN.md +Resume file: None diff --git a/.planning/phases/19.1-chat-satellites/19.1-03-SUMMARY.md b/.planning/phases/19.1-chat-satellites/19.1-03-SUMMARY.md new file mode 100644 index 00000000..5aa6cf8a --- /dev/null +++ b/.planning/phases/19.1-chat-satellites/19.1-03-SUMMARY.md @@ -0,0 +1,207 @@ +--- +phase: 19.1-chat-satellites +plan: 03 +subsystem: chatbots +tags: [chatbots, slash-command, jwt, postgres, gorm, testcontainers, deny-all] + +# Dependency graph +requires: + - phase: 19 + provides: analog sibling-plugin layout (boot steps, IF NOT EXISTS baseline, jwt.auth generic API, test-only proof host) + - phase: 19.1 + provides: plan 01 tea-create / proceed-and-push remote policy +provides: + - "new repository sm-chatbots-plugin (module git.golem15.com/golem15/sm-chatbots-plugin, package chatbots, plugin golem15.chatbots), pushed to git.golem15.com at c7d9108" + - "idempotent baseline 202610180001_create_golem15_chatbots_baseline (golem15_chatbots_bot_flags, unique user_id chatbots_bot_flags_user_unique)" + - "SlashCommand registry/dispatcher with reserved help, RegisterBuiltin HelpCommand, deny-all BotAuthResolver, JWT /_chatbots/api/v1 /ping tracer" + - "user.Deleting deletes bot_flags for user_id inside ev.Tx" +affects: [19.1-06] + +actuals: + tokens: 23805 + tasks: 3 + commits: 2 +plan_head_before: ceabc9ccbc6b6075b36e9efad3656edf9db05e44 +plan_head_after: ceabc9ccbc6b6075b36e9efad3656edf9db05e44 + +tech-stack: + added: [] + patterns: + - "SlashCommandRegistry: Register rejects reserved help and duplicates; RegisterBuiltin skips the reserved check" + - "Generic chatbots API: actor from bouncer.User only (CMD-06); GET /commands filters IsAvailable; POST /dispatch {input}" + - "BotAuthResolver DenyAll default + setter nil→DenyAll + Boot Warn; GDPR user.Deleting deletes bot_flags in ev.Tx" + +key-files: + created: + - ../sm-chatbots-plugin/plugin.go + - ../sm-chatbots-plugin/boot.go + - ../sm-chatbots-plugin/routes.go + - ../sm-chatbots-plugin/classes/registry.go + - ../sm-chatbots-plugin/classes/dispatcher.go + - ../sm-chatbots-plugin/classes/deny_all.go + - ../sm-chatbots-plugin/classes/help.go + - ../sm-chatbots-plugin/contracts/slash_command.go + - ../sm-chatbots-plugin/contracts/bot_auth_resolver.go + - ../sm-chatbots-plugin/api/commands.go + - ../sm-chatbots-plugin/updates/202610180001_create_golem15_chatbots_baseline.go + - ../sm-chatbots-plugin/http_tracer_test.go + - ../sm-chatbots-plugin/README.md + modified: [] + +key-decisions: + - "Task 1 reply verbatim: proceed" + - "Locked D-02 baseline id 202610180001_create_golem15_chatbots_baseline and D-05 prefix /_chatbots/api/v1; remote policy follows plan 01 proceed-and-push" + - "tea repos create --owner golem15 --name sm-chatbots-plugin succeeded; main pushed at c7d9108 (never force). summercms.go was not pushed." + +patterns-established: + - "chatbots proof host: golem15.user + golem15.chat + golem15.chatbots + a test-only teams fixture that Registers /ping; production Boot registers only help via RegisterBuiltin" + +requirements-completed: [SC-19.1-1, SC-19.1-2, D-01, D-02, D-03, D-04, D-05] + +coverage: + - id: D1 + description: "Human lock of D-02 baseline id 202610180001_create_golem15_chatbots_baseline and D-05 prefix /_chatbots/api/v1 before the sibling repo existed" + requirement: D-02 + verification: [] + human_judgment: true + rationale: "Task 1 was checkpoint:decision gate=blocking-human; the user replied proceed and that lock cannot be asserted by a unit test" + - id: D2 + description: "sm-chatbots-plugin with bot_flags baseline, SlashCommand registry/dispatcher, deny-all BotAuthResolver, JWT /ping ephemeral tracer under /_chatbots/api/v1" + requirement: D-05 + verification: + - kind: unit + ref: "go -C ../sm-chatbots-plugin test -count=1 -short ./..." + status: pass + - kind: integration + ref: "../sm-chatbots-plugin/http_tracer_test.go#TestHTTPTracer" + status: pass + human_judgment: false + - id: D3 + description: "user.Deleting deletes golem15_chatbots_bot_flags for that user_id inside ev.Tx; catalog stays IsAvailable-filtered; jwt.auth for humans" + requirement: D-03 + verification: + - kind: unit + ref: "go -C ../sm-chatbots-plugin vet ./... && go -C ../sm-chatbots-plugin test -count=1 -short ./..." + status: pass + - kind: other + ref: "grep DeletingEvent and bot_flags in ../sm-chatbots-plugin/boot.go" + status: pass + human_judgment: false + - id: D4 + description: "No AI plugin module in go.mod or production sources (SC-19.1-2)" + requirement: SC-19.1-2 + verification: + - kind: unit + ref: "../sm-chatbots-plugin/tracer_test.go#TestNoGolem" + status: pass + human_judgment: false + - id: D5 + description: "Gitea remote golem15/sm-chatbots-plugin created and main pushed (never force)" + requirement: SC-19.1-1 + verification: + - kind: other + ref: "tea repos create --owner golem15 --name sm-chatbots-plugin; git push -u origin main" + status: pass + human_judgment: false + +duration: 7min +completed: 2026-10-18 +status: complete +--- + +# Phase 19.1 Plan 03: Chatbots repo, flags, registry, /ping tracer Summary + +**Sibling `sm-chatbots-plugin` with the bot_flags IF NOT EXISTS baseline, reserved-help slash-command registry, deny-all BotAuthResolver, a JWT `/ping` ephemeral tracer, and GDPR delete of bot_flags on `user.Deleting`.** + +## Performance + +- **Duration:** 7 min +- **Started:** 2026-10-18T11:28:15Z +- **Completed:** 2026-10-18T11:35:09Z +- **Tasks:** 3 +- **Files modified:** 32 (all in the sibling plugin) + +## Task 1 human reply (verbatim) + +proceed + +Meaning recorded at resume: lock D-02 baseline id `202610180001_create_golem15_chatbots_baseline` and D-05 prefix `/_chatbots/api/v1`; implement; remote policy follows plan 01 proceed-and-push. After Task 3 is green, tea-create the remote and push main (never force). summercms.go is not pushed. Task 1 was not re-asked. + +## Accomplishments + +- New independent git repo `../sm-chatbots-plugin` (not a submodule): module `git.golem15.com/golem15/sm-chatbots-plugin`, package `chatbots`, PluginID `golem15.chatbots`, `Requires()` = `golem15.chat` and `golem15.user`. Never requires the AI plugin. +- Idempotent baseline `202610180001_create_golem15_chatbots_baseline` for `golem15_chatbots_bot_flags` (`id`, `user_id` unique `chatbots_bot_flags_user_unique`, `is_bot` bool default true, timestamps, FK `user_id` cascade). +- `classes.Registry`: reserved trigger `help`; `Register` rejects reserved and duplicates; `RegisterBuiltin` skips the reserved check and installs `HelpCommand`. Production Boot registers only help via `RegisterBuiltin`. +- `classes.Dispatcher.Dispatch(input, actor, ctx)` parses the trigger; unrecognized returns nil; actor is never read from the body (CMD-06). Modes ephemeral and announce. +- `BotAuthResolver` default `classes.DenyAll` (Resolve empty, IsElevated false). `SetBotAuthResolver(nil)` becomes DenyAll. Boot Warns while default is active. +- Generic API `chatbots.APIPrefix` (`/_chatbots/api/v1`) behind `jwt.auth` and `chatbots-api` 120/min: `GET /commands` (IsAvailable), `POST /dispatch` `{input}`. +- Test host registers `/ping` ephemeral pong. `TestHTTPTracer` (Docker): JWT actor POST `{input:"/ping"}` returns ephemeral pong; chat message count for that conversation stays 0; GET `/commands` includes help. +- GDPR: Listen `user.Deleting`; delete `golem15_chatbots_bot_flags` for that `user_id` inside `ev.Tx`. +- Remote created: `https://git.golem15.com/golem15/sm-chatbots-plugin`. `git push -u origin main` succeeded (never force). summercms.go was not pushed. + +## Task Commits + +Each task was committed atomically in the sibling repo: + +1. **Task 1: Confirm D-02 chatbots baseline id and D-05 prefix** - none (decision only; human: proceed) +2. **Task 2: End-to-end /ping — registry, dispatcher, JWT actor, ephemeral, /help** - `f8af791` (feat) +3. **Task 3: GDPR bot_flags delete and catalog/auth expansion** - `c7d9108` (feat) + +**Sibling HEAD:** `c7d9108` on `origin/main`. + +## Files Created/Modified + +- `../sm-chatbots-plugin/` - full plugin tree (go.mod Go 1.27.0, analog pins, replace summercms => ../summercms.go; go.work also replaces sm-user-plugin and sm-chat-plugin) + +## Decisions Made + +- Task 1 reply verbatim: proceed. +- Locked D-02 / D-05 as named in the continuation. Remote policy follows plan 01 proceed-and-push. +- After Task 3 verify was green, `tea repos create --owner golem15 --name sm-chatbots-plugin` then `git push -u origin main` (never force). + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 3 - Blocking] go.mod local replaces for chat and user** +- **Found during:** Task 2 +- **Issue:** `go mod tidy` tried to fetch `sm-chat-plugin@v0.0.0` (unknown revision) even with go.work replaces. +- **Fix:** Added `replace …/sm-chat-plugin => ../sm-chat-plugin` and `replace …/sm-user-plugin => ../fonoteka.go/plugins/golem15/user` to go.mod, matching the chatchannels analog for chat. +- **Files modified:** `../sm-chatbots-plugin/go.mod` +- **Verification:** `go vet ./...` and `go test -short ./...` pass +- **Committed in:** `f8af791` + +--- + +**Total deviations:** 1 auto-fixed (Rule 3 blocking) +**Impact on plan:** Required so tidy/vet resolve local analog modules. No scope creep. + +## Issues Encountered + +The environment injects a `Co-authored-by: Cursor` trailer on plugin commits; it was not added in the commit message source. Task 1 was not re-asked. The sibling directory did not exist at Task 2 start. `../sm-chat-plugin` existed. + +## TDD Gate Compliance + +N/A — TDD is not applicable for this plan. Tracer verify is automated-only (`HUMAN_VERIFY_MODE=end-of-phase`). After Task 2 automated verify passed: Tracer verified end-to-end — expanding. + +## Auth gates + +Task 1 `checkpoint:decision` `blocking-human` — user replied `proceed`. No further auth gates. + +## Known Stubs + +None. + +## User Setup Required + +None - no external service configuration required. The Gitea repo was created in-session. + +## Next Phase Readiness + +Ready for 19.1-04 (herald) on its own gate. Chatbots tracer is green; PHP method map and goldens stay plan 06. + +--- +*Phase: 19.1-chat-satellites* +*Completed: 2026-10-18* + +## Self-Check: PASSED