docs(19.1): re-verify after review fixes; mark WR-04 and WR-05 fixed
This commit is contained in:
@@ -17,11 +17,11 @@ findings:
|
||||
title: "Reconcile ends empty rooms with no grace, including ringing calls"
|
||||
- id: WR-04
|
||||
severity: warning
|
||||
disposition: open
|
||||
disposition: fixed
|
||||
title: "Generic chatbots dispatch ignores IsAvailable"
|
||||
- id: WR-05
|
||||
severity: warning
|
||||
disposition: open
|
||||
disposition: fixed
|
||||
title: "Chatvideo starter delete cascades the whole session and skips LiveKit cleanup"
|
||||
- id: IN-01
|
||||
severity: info
|
||||
@@ -51,8 +51,8 @@ recorded: 2026-10-18T14:16:00Z
|
||||
| WR-01 | warning | open | 19.1-REVIEW.md |
|
||||
| WR-02 | warning | open | 19.1-REVIEW.md |
|
||||
| WR-03 | warning | open | 19.1-REVIEW.md |
|
||||
| WR-04 | warning | open | 19.1-REVIEW.md |
|
||||
| WR-05 | warning | open | 19.1-REVIEW.md |
|
||||
| WR-04 | warning | fixed | 19.1-REVIEW.md |
|
||||
| WR-05 | warning | fixed | 19.1-REVIEW.md |
|
||||
| IN-01 | info | open | 19.1-REVIEW.md |
|
||||
| IN-02 | info | open | 19.1-REVIEW.md |
|
||||
| IN-03 | info | open | 19.1-REVIEW.md |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
phase: 19.1-chat-satellites
|
||||
verified: 2026-10-18T14:15:00Z
|
||||
verified: 2026-10-18T17:23:38Z
|
||||
status: passed
|
||||
score: 16/16 must-haves verified
|
||||
covered_files:
|
||||
@@ -21,13 +21,14 @@ covered_files:
|
||||
- .planning/phases/19.1-chat-satellites/19.1-06-PLAN.md
|
||||
- .planning/phases/19.1-chat-satellites/19.1-06-SUMMARY.md
|
||||
- README.md
|
||||
- docs/plugins/extending.md
|
||||
- docs/services/markdown.md
|
||||
- modules/breakwater/README.md
|
||||
- modules/breakwater/breakwater.go
|
||||
- modules/breakwater/breakwater_test.go
|
||||
- modules/breakwater/example_test.go
|
||||
- scripts/check-phase19.1.sh
|
||||
covered_digest: "v2:sha256:2311abea5e82d375f2b20a2ae8ba39cb0849574ac0d8cdfc27ac48b689d72069"
|
||||
covered_digest: "v2:sha256:797292f0aec9329d38baf6ef682dfde8a386bc45e4d44f6eb73db115470cc310"
|
||||
behavior_unverified: 0
|
||||
overrides_applied: 1
|
||||
overrides:
|
||||
@@ -35,223 +36,184 @@ overrides:
|
||||
reason: "D-08 soft adapter is a typed Lookup of sm-chat-plugin/contracts.Registry; go.mod must list the module (docs/plugins/extending.md: the consumer imports the package that declares the interface). Requires() stays golem15.user only; missing chat is a Boot skip."
|
||||
accepted_by: "Jakub Zych"
|
||||
accepted_at: "2026-10-18T15:54:48Z"
|
||||
re_verification:
|
||||
previous_status: passed
|
||||
previous_score: 16/16
|
||||
trigger: "stale (covered_changed): scripts/check-phase19.1.sh and docs/plugins/extending.md changed after the UAT; sibling fixes sm-chatbots-plugin b723f2f and sm-chatvideo-plugin 492c45f landed"
|
||||
gaps_closed: []
|
||||
gaps_remaining: []
|
||||
regressions: []
|
||||
decision_coverage:
|
||||
honored: 18
|
||||
total: 18
|
||||
not_honored: []
|
||||
human_verification:
|
||||
human_verified:
|
||||
- test: "Accept an override that ../sm-userfriends-plugin/go.mod may require sm-chat-plugin so Boot can Lookup[*chatcontracts.Registry], while Plugin.Requires() stays []string{\"golem15.user\"} only."
|
||||
expected: "Override recorded. No code change. Removing the go.mod require would make the D-08 soft adapter uncompilable."
|
||||
why_human: "Plan 01 prohibition literally says go.mod never require sm-chat-plugin. The same plan's D-08 truth requires a typed Lookup of the chat Registry. Those two statements cannot both be true in Go. Implementation honors D-08 (Requires() is user-only; missing chat is a skip). A human must accept the deviation."
|
||||
uat_row: 1
|
||||
recorded_at: "2026-10-18T15:54:54.000Z"
|
||||
---
|
||||
|
||||
# Phase 19.1: Chat satellites Verification Report
|
||||
|
||||
**Phase Goal:** The remaining shared plugins that Wavepath's app plugin requires run on SummerCMS: chatbots, chatvideo, forum, herald and userfriends.
|
||||
**Verified:** 2026-10-18T14:15:00Z
|
||||
**Status:** human_needed
|
||||
**Re-verification:** No — initial verification
|
||||
**Verified:** 2026-10-18T17:23:38Z
|
||||
**Status:** passed
|
||||
**Re-verification:** Yes. The earlier report went stale (`covered_changed`) after the UAT. Since then: a goldens secret scan was added to the gate (8643195), the gate now requires the chatvideo user-deletion test (533fb7c), a docs paragraph was added (97daec5), and two review fixes landed in sibling repos: chatbots WR-04 (b723f2f) and chatvideo WR-05 (492c45f).
|
||||
|
||||
Roadmap `**Mode:** mvp` is set, but the ROADMAP goal is not a user-story sentence (`user-story.validate` → `false`). Verification proceeded because execute-phase `verify_phase_goal` asked for this report and each plan already carries an application-mounts-satellites user story. A `/msd mvp-phase 19.1` rewrite of the ROADMAP goal is optional bookkeeping, not a code gap.
|
||||
Roadmap `**Mode:** mvp` is set, but the ROADMAP goal is not a user-story sentence. Each plan carries its own application-mounts-satellite user story, and those stories are aggregated below. Rewriting the goal as a user story would only be bookkeeping. No code is missing.
|
||||
|
||||
This is an infrastructure/plugin-port phase (sibling repos, generic JWT APIs, no end-user UI). Human verification is therefore limited to the one planner-prohibition contradiction below — not invented UI walkthroughs.
|
||||
## What changed since the previous report, and what was re-checked
|
||||
|
||||
| Change | Repo / commit | Re-check performed | Result |
|
||||
|--------|---------------|--------------------|--------|
|
||||
| Gate docs stage: `detect_secrets` over five `testdata/goldens` trees; six `--self-test` plants | summercms.go 8643195 | `--self-test` exit 0; `--docs` exit 0 printing `goldens: no secrets in five sibling fixture trees` | ✓ |
|
||||
| Gate postgres stage requires `TestUserDeletionReassignsSession`; anchored self-test pin on `PG_CHATVIDEO_TESTS` | summercms.go 533fb7c | `--postgres` (Docker) ran it: `3 top-level tests passed in ../sm-chatvideo-plugin (... TestUserDeletionReassignsSession)` | ✓ |
|
||||
| Optional-dependency `go.mod` paragraph | summercms.go 97daec5 | `go test ./cmd/summer -run '^TestDocsTree$'` ok | ✓ |
|
||||
| Chatbots: `Dispatch` returns nil when `!cmd.IsAvailable(actor, cmdCtx)` | sm-chatbots-plugin b723f2f | Read `classes/dispatcher.go:42`; `TestDispatchRefusesUnavailable` PASS (-short); `TestHTTPTracer` (postgres) posts `/secret` + `/no-such-trigger` and passed | ✓ |
|
||||
| Chatvideo: `user.Deleting` listener (boot step `listeners`), `started_by` heir, LiveKit cleanup in `lagoon.AfterCommit` | sm-chatvideo-plugin 492c45f | Read `classes/user_deletion.go`, `boot.go`; `TestUserDeletionReassignsSession` (fires `DeletingEvent` through `app.Events` inside `lagoon.Transaction`, real FK CASCADE) passed in the postgres stage | ✓ |
|
||||
|
||||
sm-userfriends-plugin, sm-forum-plugin and sm-herald-plugin have no commits since the previous report (14:15Z) and no uncommitted edits. All five sibling working trees are clean.
|
||||
|
||||
## User Flow Coverage
|
||||
|
||||
Aggregated from the six plan user stories (ROADMAP goal is not a user story):
|
||||
|
||||
| Step | Expected | Evidence | Status |
|
||||
|------|----------|----------|--------|
|
||||
| Mount Friends | Host binds no extra seam; JWT `/_userfriends/api/v1` request/accept/list works | `../sm-userfriends-plugin/routes.go`; `TestHTTPTracer` passed (postgres) | ✓ |
|
||||
| Mount Forum | Host binds `ForumAccessResolver`; context-scoped categories; GFM stored, XSS stripped | `../sm-forum-plugin/routes.go`; `breakwater.Render` on write; `TestHTTPTracer` passed | ✓ |
|
||||
| Mount Chat bots | Host registers slash commands; dispatch invoker is the JWT actor | `../sm-chatbots-plugin/api/commands.go` uses `actor()` / `bouncer.User`; `TestHTTPTracer` passed | ✓ |
|
||||
| Mount Herald | Host stores subscriptions and sends Web Push without PHP | `../sm-herald-plugin/routes.go`; `TestHTTPTracer` + `TestSendEventRollback` passed | ✓ |
|
||||
| Mount Chat video | Host starts/joins/ends conversation video; stale sessions reconcile | `../sm-chatvideo-plugin/routes.go`; `TestHTTPTracer` + `TestReconcileEmptyRoom` passed | ✓ |
|
||||
| Fail-closed gate | Skipped/missing named tests fail `scripts/check-phase19.1.sh` | `--self-test`, `--plugins`, `--docs`, `--postgres` all exit 0 this session | ✓ |
|
||||
| Mount Friends | JWT `/_userfriends/api/v1` request/accept/list; no extra host seam | `routes.go` (`APIPrefix = "/_userfriends/api/v1"`); `TestHTTPTracer` passed (postgres, this run) | ✓ |
|
||||
| Mount Forum | Host binds `ForumAccessResolver`; context-scoped categories; GFM stored, XSS stripped | `breakwater.Render` on write only (`forum_service.go:281,330`, `lifecycle.go:232`, preview `:387`); `TestHTTPTracer` passed | ✓ |
|
||||
| Mount Chat bots | Host registers slash commands; dispatch invoker is the JWT actor; restricted commands refused | `api/commands.go` `actor()` → `Dispatch(..., userID, ...)`; `IsAvailable` gate; `TestHTTPTracer` + `TestDispatchRefusesUnavailable` passed | ✓ |
|
||||
| Mount Herald | Host stores subscriptions and sends Web Push without PHP | `TestHTTPTracer` + `TestSendEventRollback` passed (postgres) | ✓ |
|
||||
| Mount Chat video | Start/join/end; stale sessions reconcile; deleting a user keeps others' call history | `TestHTTPTracer`, `TestReconcileEmptyRoom`, `TestUserDeletionReassignsSession` passed (postgres) | ✓ |
|
||||
| Fail-closed gate | Skipped/missing named tests or secret-shaped goldens fail `scripts/check-phase19.1.sh` | `--self-test`, `--plugins`, `--docs`, `--postgres` all exit 0 this session | ✓ |
|
||||
|
||||
## Goal Achievement
|
||||
|
||||
### Observable Truths
|
||||
|
||||
Merged from ROADMAP success criteria (SC-19.1-1..4) plus PLAN `must_haves.truths` (D-01..D-18). Roadmap wording kept where a plan restated an SC.
|
||||
|
||||
| # | Truth | Status | Evidence |
|
||||
| --- | ------- | ---------- | -------------- |
|
||||
| 1 | SC-19.1-1: each plugin ports schema, models, routes and events 1:1 against its PHP original | ✓ VERIFIED | Five sibling repos exist with Winter layout, `202610180001_create_golem15_*_baseline`, models, JWT routes, and (where applicable) festival/lighthouse events. PHP method maps: userfriends 31, forum 25, chatbots 22, herald 14 declarations / 13 unique, chatvideo 0 in-plugin + Wavepath generic-or-N/A. |
|
||||
| 2 | SC-19.1-2: webpush-go, LiveKit, and bluemonday decision notes exist and name the locked modules/versions | ✓ VERIFIED | `.planning/notes/2026-10-18-webpush-go.md` (`SherClockHolmes/webpush-go` v1.4.0); `2026-10-18-livekit-server-sdk-go.md` (`server-sdk-go/v2` v2.19.0, pion/media-sdk/buildkit flag); `2026-10-18-bluemonday-forum-policy.md` (v1.0.27, PHP allow-list, not UGC). `check-phase19.1.sh --docs` passed. |
|
||||
| 3 | SC-19.1-3: ROADMAP marks criterion 3 already met; fonoteka.go has no userfriends port | ✓ VERIFIED | ROADMAP criterion 3 text is the “already met” wording; Repos line names `summercms.go`. Grep of `../fonoteka.go` for `userfriends` / `golem15.userfriends` returned no matches. |
|
||||
| 4 | SC-19.1-4 / D-04: last plan delivers unit tests, PHP method maps, goldens, fail-closed gate | ✓ VERIFIED | `TestPHPMethodMap` ×5, goldens in all five repos, `scripts/check-phase19.1.sh` self-test/plugins/docs/postgres all green this session. |
|
||||
| 5 | D-01: module paths, plugin IDs, Requires() match the frozen contract | ✓ VERIFIED | `golem15.userfriends` Requires `golem15.user` only; `golem15.forum` Requires user; `golem15.chatbots` Requires chat+user (no AI plugin; `TestNoGolem` passed); `golem15.herald` Requires empty; `golem15.chatvideo` Requires chat. |
|
||||
| 6 | D-02: one idempotent IF NOT EXISTS baseline per plugin; demo-seed IDs are comments | ✓ VERIFIED | Baseline IDs `202610180001_create_golem15_{userfriends,forum,chatbots,herald,chatvideo}_baseline`. Userfriends comment records v1.0.1 demo-seed and inserts no demo rows. `TestBaseline` ×5 passed under `-short`. |
|
||||
| 7 | D-03: DenyAll access seams with Boot Warn + setter; GDPR cascades | ✓ VERIFIED | Forum/chatbots/herald DenyAll + Warn + setter. `TestAccessResolverDefault`, `TestBotAuthResolverDefault`, `TestPresenceGateDefault` exist. Postgres: `TestUserDeletingHeir` (admin then member by `role ASC, created_at ASC`), `TestUserDeletionAnonymizes` (null `user_id`, keep bodies), `TestUserDeletionCascadesBotFlag`. |
|
||||
| 8 | D-05: generic JWT APIs under documented prefixes; actor from token; named buckets | ✓ VERIFIED | `/_userfriends/api/v1` (`community-join` 10/min on request/join); `/_forum/api/v1/contexts/{type}/{id}/...`; `/_chatbots/api/v1` commands+dispatch; `/_herald/api/v1/push/*`; `/_chatvideo/api/v1/conversations/{id}/video/{start,join,leave,end,status}` + `/call-links/{code}` (`video-initiate` 5/min on start only). Five `TestHTTPTracer` runs passed (postgres). |
|
||||
| 9 | D-06: herald ships the generic API (PHP “no routes” reversed) | ✓ VERIFIED | `routes.go` mounts subscription + vapid-public-key. README states the reversal and D-06. |
|
||||
| 10 | D-07: legacy `/api/friends`, `/api/video`, Winter components, bundled JS, demo seeders not registered | ✓ VERIFIED | Userfriends and chatvideo `Routes()` only mount `/_* /api/v1`. No `FriendsList` / `VideoCall` components. Demo seeders are comments. |
|
||||
| 11 | D-08: group festival events; soft chat adapter; forum `DeleteContext`; forum never imports userfriends | ✓ VERIFIED | `userfriends.GroupCreated/GroupDeleted/MemberJoined/MemberLeft`; `Fire` inside write tx; `Lookup[*chatcontracts.Registry]` skip if absent; `Requires()` omits chat. `ForumService.DeleteContext` soft-deletes the morph pair. `TestNoUserfriendsImport` passed. |
|
||||
| 12 | D-10 / D-11: PublicOnly subscribe/send; enqueue on caller tx; rollback sends 0; 410/404 prune | ✓ VERIFIED | `ValidateEndpoint` rejects non-HTTPS; `NewSender` uses `fetchguard.PublicOnlyMode`; `Options.HTTPClient = s.http`; `jobs.Enqueue` on caller `tx`; `TestSendEventRollback` passed; `Deliver` prunes 404/410. No `EndpointGuard` type. |
|
||||
| 13 | D-12: VAPID config keys + `herald:vapid-generate`; private key not logged | ✓ VERIFIED | `golem15.herald.vapid.{subject,public_key,private_key}`. Command prints `VAPID_PUBLIC_KEY=` / `VAPID_PRIVATE_KEY=` via `bonfire.Output`, not slog. GET vapid-public-key returns public key only. |
|
||||
| 14 | D-13 / D-14 / D-15: LiveKit RoomAPI, token golden, video authorizer segment 2, 5-minute reconciler | ✓ VERIFIED | `type RoomAPI interface`; `TrustedMode` to operator URL; `parseVideoSessionChannel` splits segment 2 (`video:session:{id}`), capabilities `["prs"]`; `TestLiveKitTokenClaims` + `TestVideoAuthorizer` passed (`-short`); `chatvideo:reconcile-sessions` + `golem15.chatvideo.reconcile_sessions` MaxAttempts 1 + `Every(5 * time.Minute)`; `TestReconcileEmptyRoom` passed. Unique `active_conversation_id`, `join_code`, nullable `card_message_id`. |
|
||||
| 15 | D-16 / D-17 / D-18: breakwater `Render`/`Purify`; forum write-path render; adopted `content_html` served stored | ✓ VERIFIED | `modules/breakwater` exports both funcs; forum `go.mod` has no direct bluemonday/goldmark require (indirect via summercms). `forum_service.go` / `lifecycle.go` call `breakwater.Render` on write. `api/json.go` copies stored `ContentHTML`. `TestAdoptedContentHTML` + forum `TestHTTPTracer` (table present, no `<script>`). |
|
||||
| 16 | Gate: `scripts/check-phase19.1.sh` fail-closed named tests across five sibling roots | ✓ VERIFIED | This session: `--self-test` passed (refuses planted skip/miss/zero); `--plugins` passed (`go vet` + `-short` + named tests); `--docs` passed; `--postgres` passed (Docker up). |
|
||||
| 1 | SC-19.1-1: each plugin ports schema, models, routes and events 1:1 against its PHP original | ✓ VERIFIED | Five sibling repos with baselines, models, JWT routes, events; `TestPHPMethodMap` ×5 passed (`--plugins`, this run). |
|
||||
| 2 | SC-19.1-2: webpush-go, LiveKit and bluemonday decision notes exist and name the locked modules/versions | ✓ VERIFIED | Three notes present; `--docs` greps the pins (webpush-go, server-sdk-go/v2, bluemonday v1.0.27) and passed. |
|
||||
| 3 | SC-19.1-3: already met; fonoteka.go has no userfriends port | ✓ VERIFIED | Regression grep of `../fonoteka.go` for `golem15.userfriends` / `sm-userfriends` in `.go`/`.yaml`/`go.mod`: no matches. |
|
||||
| 4 | SC-19.1-4 / D-04: last plan delivers unit tests, PHP maps, goldens, fail-closed gate | ✓ VERIFIED | Gate all four stages green this run; goldens now also scanned for secrets. |
|
||||
| 5 | D-01: module paths, plugin IDs, Requires() per frozen contract | ✓ VERIFIED | userfriends `{"golem15.user"}`; herald `nil`; chatvideo `{"golem15.chat"}` (unchanged by 492c45f); `TestNoGolem` passed. |
|
||||
| 6 | D-02: one idempotent baseline per plugin; demo seeds are comments | ✓ VERIFIED | `TestBaseline` ×5 passed (`--plugins`). 492c45f touched no `updates/`. |
|
||||
| 7 | D-03: DenyAll seams with Boot Warn + setter; GDPR cascades | ✓ VERIFIED | `TestAccessResolverDefault` passed; postgres `TestUserDeletingHeir`, `TestUserDeletionAnonymizes`, `TestUserDeletionCascadesBotFlag`, and now chatvideo `TestUserDeletionReassignsSession` passed. |
|
||||
| 8 | D-05: generic JWT APIs under documented prefixes; actor from token; named buckets | ✓ VERIFIED | Five `TestHTTPTracer` passed (postgres, this run). The chatbots tracer also asserts that a restricted command and an unknown trigger return byte-identical 422 bodies. |
|
||||
| 9 | D-06: herald ships the generic API | ✓ VERIFIED | `routes.go:28` mounts `/push/vapid-public-key` plus subscription routes; unchanged. |
|
||||
| 10 | D-07: legacy `/api/friends`, `/api/video`, components, bundled JS, demo seeders not registered | ✓ VERIFIED | Grep for `"/api/friends`, `"/api/video`, `FriendsList`, `FriendRequests`, `.js"`/`.css"` in production `.go` returned nothing. Both `Routes()` mount only `APIPrefix` groups. The only `embed` uses are `config` and `lang`. |
|
||||
| 11 | D-08: group events; soft chat adapter; forum `DeleteContext`; forum never imports userfriends | ✓ VERIFIED | userfriends unchanged since the prior pass; `TestNoUserfriendsImport` passed; forum `go.mod` has no `sm-userfriends`. |
|
||||
| 12 | D-10 / D-11: PublicOnly subscribe/send; enqueue on caller tx; rollback sends 0; 410/404 prune | ✓ VERIFIED | `TestSubscribeEndpoint` (-short) and `TestSendEventRollback` (postgres) passed this run. |
|
||||
| 13 | D-12: VAPID config keys + `herald:vapid-generate`; private key not logged | ✓ VERIFIED | `console/vapid_generate.go` prints through `bonfire.Output` only. All herald `slog` calls (`boot.go:79,89`, `sender.go:239,242`, `api/errors.go:33`) carry no key material. `api/push.go:123` returns `publicKey` only. |
|
||||
| 14 | D-13 / D-14 / D-15: RoomAPI, token golden, segment-2 authorizer, 5-minute reconciler | ✓ VERIFIED | `TestLiveKitTokenClaims`, `TestVideoAuthorizer` (-short), `TestReconcileEmptyRoom` (postgres) passed. The new user-deletion path calls `RoomAPI` only inside `lagoon.AfterCommit`. |
|
||||
| 15 | D-16 / D-17 / D-18: breakwater `Render`/`Purify`; forum write-path render; stored `content_html` served as-is | ✓ VERIFIED | `go test ./modules/breakwater` ok; `TestAdoptedContentHTML` passed; `api/json.go:134` copies stored `ContentHTML`; no `breakwater.` call in any read path. |
|
||||
| 16 | Gate: `scripts/check-phase19.1.sh` fail-closed named tests across five sibling roots | ✓ VERIFIED | This run: `--self-test` exit 0, `--plugins` exit 0, `--docs` exit 0, `--postgres` exit 0 (Docker reachable, 12 named postgres tests ran). |
|
||||
|
||||
**Score:** 16/16 truths verified (0 present, behavior-unverified)
|
||||
|
||||
### Prohibitions (`must_haves.prohibitions`)
|
||||
|
||||
| Plan | Prohibition | Tier | Status | Evidence |
|
||||
|------|-------------|------|--------|----------|
|
||||
| 01 | No QuestStream/family/parent/child/consuming-app names; plugin.name Friends / Przyjaciele | grep | ✓ held | Production grep empty; `lang/en` `"Friends"`, `lang/pl` `"Przyjaciele"`. |
|
||||
| 01 | Requires() and go.mod never require sm-chat-plugin | grep | PASSED (override) | `go.mod:6` requires sm-chat-plugin (needed for D-08 typed Lookup); `Requires()` = `{"golem15.user"}`. Override accepted by Jakub Zych on 2026-10-18T15:54:48Z; UAT row 1 passed; userfriends code unchanged since. |
|
||||
| 01 | Legacy `/api/friends` routes and Winter components not registered | judgment | ✓ held (deterministic) | Route/component grep empty; only `/_userfriends/api/v1` groups. |
|
||||
| 02 | Forum does not vendor goldmark/bluemonday or import UGC policy / `cabana.RenderMarkdown` | grep | ✓ held | Both are `// indirect` in `go.mod`; no production import. |
|
||||
| 02 | Forum go.mod never requires sm-userfriends-plugin | grep | ✓ held | No match. |
|
||||
| 02 | Adopted `content_html` never re-rendered on read | judgment | ✓ held (test) | `TestAdoptedContentHTML` passed. All `breakwater.Render` calls are on write or preview paths. |
|
||||
| 03 | No AI-plugin import; invoker id never from body | grep | ✓ held | No AI import; `Dispatch` takes `userID` from `actor()`, and `DispatchBody` carries only `input`. |
|
||||
| 03 | Reserved help cannot be `Register()`ed; `registerBuiltin` installs it | judgment | ✓ held (test) | `TestRegisterReserved` passed (`ErrReserved`). |
|
||||
| 04 | No in-tree Web Push module, no `push.*` keys | grep | ✓ held | No match. |
|
||||
| 04 | Private VAPID key never in slog, payloads or README examples | judgment | ✓ held (deterministic) | See truth 13; the README mentions the private key only as `VAPID_PRIVATE_KEY=` / "never logged". |
|
||||
| 04 | Requires() empty; no user-model import | grep | ✓ held | `Requires()` returns `nil`; no production import of sm-user-plugin. |
|
||||
| 05 | Never construct `lksdk.Room`; tests never import pion | grep | ✓ held | Only `lksdk.RoomServiceClient`; no `pion/` import anywhere (new `user_deletion_test.go` included). |
|
||||
| 05 | Authorizer never calls the segment-1 helper | grep | ✓ held | `authorizer.go` mentions `lighthouse.ChannelID` only in a comment. |
|
||||
| 05 | Reconciler imports no GuestCall / call cards / CallNotifier / start_grace | grep | ✓ held | No match in `jobs/`, `console/`, `classes/`. |
|
||||
| 05 | Legacy `/api/video` and bundled JS/CSS not registered | judgment | ✓ held (deterministic) | See truth 10. |
|
||||
| 06 | No re-implementation of D-17, vue-community-layer or `/_wave` routes | judgment | ✓ held (deterministic) | The only `/_wave` hit is a negative needle in herald `map_support_test.go:52`. |
|
||||
| 06 | Goldens never contain a VAPID private key or LiveKit secret | grep | ✓ held (test) | Now enforced: `--docs` `detect_secrets` passed over all five trees. Self-test refuses all six planted patterns. |
|
||||
|
||||
The judgment-tier prohibitions were settled with deterministic evidence (named tests or empty greps), not with an LLM opinion. None is left flagged.
|
||||
|
||||
### Required Artifacts
|
||||
|
||||
`msd_run query verify.artifacts` on all six plans: **29/29 passed** (exists, non-stub).
|
||||
All 29 artifacts from the previous report are still present. New artifacts from the post-UAT fixes:
|
||||
|
||||
| Artifact | Expected | Status | Details |
|
||||
| -------- | -------- | ------ | ------- |
|
||||
| `../sm-userfriends-plugin/plugin.go` | golem15.userfriends | ✓ VERIFIED | Requires user only |
|
||||
| `../sm-userfriends-plugin/updates/202610180001_create_golem15_userfriends_baseline.go` | IF NOT EXISTS baseline | ✓ VERIFIED | six tables |
|
||||
| `../sm-userfriends-plugin/events/events.go` | group festival events | ✓ VERIFIED | four names |
|
||||
| `../sm-userfriends-plugin/http_tracer_test.go` | JWT tracer | ✓ VERIFIED | postgres pass |
|
||||
| `.planning/ROADMAP.md` | SC2/SC3 wording | ✓ VERIFIED | webpush-go / already met |
|
||||
| `../sm-forum-plugin/plugin.go` | golem15.forum | ✓ VERIFIED | |
|
||||
| `../sm-forum-plugin/classes/forum_service.go` | DeleteContext | ✓ VERIFIED | + Render on write |
|
||||
| `../sm-forum-plugin/contracts/access_resolver.go` | CanRead seam | ✓ VERIFIED | |
|
||||
| `../sm-forum-plugin/console/rewrite_context_types.go` | forum:rewrite-context-types | ✓ VERIFIED | |
|
||||
| `.planning/notes/2026-10-18-bluemonday-forum-policy.md` | D-16 note | ✓ VERIFIED | |
|
||||
| `../sm-chatbots-plugin/plugin.go` | golem15.chatbots | ✓ VERIFIED | |
|
||||
| `../sm-chatbots-plugin/classes/registry.go` | registerBuiltin | ✓ VERIFIED | reserved help |
|
||||
| `../sm-chatbots-plugin/classes/dispatcher.go` | Dispatch | ✓ VERIFIED | |
|
||||
| `../sm-chatbots-plugin/http_tracer_test.go` | /ping tracer | ✓ VERIFIED | postgres pass |
|
||||
| `.planning/notes/2026-10-18-webpush-go.md` | D-09 note | ✓ VERIFIED | |
|
||||
| `../sm-herald-plugin/jobs/send.go` | golem15.herald.send | ✓ VERIFIED | |
|
||||
| `../sm-herald-plugin/console/vapid_generate.go` | herald:vapid-generate | ✓ VERIFIED | |
|
||||
| `../sm-herald-plugin/http_tracer_test.go` | rollback tracer | ✓ VERIFIED | postgres pass |
|
||||
| `.planning/notes/2026-10-18-livekit-server-sdk-go.md` | D-13 note | ✓ VERIFIED | |
|
||||
| `../sm-chatvideo-plugin/classes/livekit.go` | RoomAPI | ✓ VERIFIED | |
|
||||
| `../sm-chatvideo-plugin/classes/authorizer.go` | parseVideoSessionChannel | ✓ VERIFIED | |
|
||||
| `../sm-chatvideo-plugin/jobs/reconcile.go` | reconcile job | ✓ VERIFIED | |
|
||||
| `../sm-chatvideo-plugin/console/reconcile.go` | chatvideo:reconcile-sessions | ✓ VERIFIED | |
|
||||
| `scripts/check-phase19.1.sh` | USERFRIENDS env | ✓ VERIFIED | |
|
||||
| five `testdata/PHP_METHOD_MAP.md` | mapped PHP methods | ✓ VERIFIED | counts match plan |
|
||||
| `../sm-chatvideo-plugin/classes/user_deletion.go` | `VideoService.OnUserDeleting` | ✓ VERIFIED | 155 lines; heir query `joined_at ASC NULLS LAST, id ASC`; `lagoon.AfterCommit` for RoomAPI; 10 s per-call bound |
|
||||
| `../sm-chatvideo-plugin/user_deletion_test.go` | heir / empty / last_participant / continuing | ✓ VERIFIED | Passed in the postgres stage |
|
||||
| `../sm-chatvideo-plugin/boot.go` `bootListeners` | `Listen[*userclasses.DeletingEvent]` | ✓ VERIFIED | Registered via `registerBootStep("listeners", ...)` |
|
||||
| `../sm-chatbots-plugin/classes/dispatcher.go` | `IsAvailable` gate | ✓ VERIFIED | Line 42 |
|
||||
| `scripts/check-phase19.1.sh` `detect_secrets` | goldens secret scan | ✓ VERIFIED | Wired into `run_docs` and `run_self_test` |
|
||||
|
||||
### Key Link Verification
|
||||
|
||||
`msd_run query verify.key-links` rejected sibling `../sm-*-plugin` paths (`Source path rejected — resolves outside the project directory`). Links were re-checked by reading the files. The one in-repo link (`scripts/check-phase19.1.sh` → `TestHTTPTracer`) verified automatically.
|
||||
|
||||
| From | To | Via | Status | Details |
|
||||
| ---- | --- | --- | ------ | ------- |
|
||||
| `../sm-userfriends-plugin/boot.go` | `events/events.go` | Fire GroupCreated; Listen user.Deleting | WIRED | `onUserDeleting` → `GroupService.OnUserDeleting`; Create fires `GroupCreated` in tx |
|
||||
| `../sm-userfriends-plugin/routes.go` | `api/friends.go` | jwt.auth + community-join | WIRED | JoinBucket on POST `/friends/request` |
|
||||
| `../sm-userfriends-plugin/classes/friends_context_adapter.go` | chat Registry | Lookup; alias friendcontext | WIRED | `bootChatAdapter` skip if absent |
|
||||
| `../sm-forum-plugin/classes/forum_service.go` | breakwater.Render | write-path render | WIRED | CreateThread/Reply/Edit |
|
||||
| `../sm-forum-plugin/boot.go` | `classes/deny_all.go` | Boot Warn deny-all | WIRED | Warn string contains `deny-all` |
|
||||
| `../sm-forum-plugin/console/rewrite_context_types.go` | baseline context_type | morph rewrite | WIRED | UPDATEs `golem15_forum_categories.context_type` |
|
||||
| `../sm-chatbots-plugin/api/commands.go` | dispatcher | actor from bouncer.User | WIRED | `Dispatch(ctx, input, userID, ...)` |
|
||||
| `../sm-chatbots-plugin/boot.go` | deny_all | BotAuthResolver Warn | WIRED | |
|
||||
| `../sm-herald-plugin/classes/sender.go` | fetchguard | HTTPClient PublicOnly | WIRED | `Options.HTTPClient = s.http` |
|
||||
| `../sm-herald-plugin/classes/sender.go` | `jobs/send.go` | Enqueue on caller tx | WIRED | `s.jobs.Enqueue(ctx, db, args, ...)` |
|
||||
| `../sm-chatvideo-plugin/boot.go` | authorizer | Register("video") | WIRED | `Registry.Register("video", ...)` |
|
||||
| `../sm-chatvideo-plugin/classes/livekit.go` | fetchguard TrustedMode | operator URL | WIRED | `NewProductionRooms` |
|
||||
| `../sm-chatvideo-plugin/routes.go` | `api/video.go` | video-initiate on start | WIRED | |
|
||||
| `scripts/check-phase19.1.sh` | userfriends TestHTTPTracer | postgres stage | WIRED | automated |
|
||||
| herald PHP_METHOD_MAP | fetchguard | EndpointGuard N/A D-10 | WIRED | three not-applicable rows + fetchguard pointer |
|
||||
| chatvideo `boot.go` | `classes.VideoService.OnUserDeleting` | `app.Events.Listen[*userclasses.DeletingEvent]` → `p.onUserDeleting` → `ev.Tx` | WIRED | Test fires the event through `env.app.Events` inside `lagoon.Transaction` |
|
||||
| chatvideo `OnUserDeleting` | `RoomAPI.DeleteRoom` / `RemoveParticipant` | `lagoon.AfterCommit` | WIRED | Subtests assert the room is gone after commit and still present inside the tx |
|
||||
| chatbots `api/commands.go` Dispatch | `Dispatcher.Dispatch` | `IsAvailable(actor, cmdCtx)` → nil → 422 `unknown_command` | WIRED | Tracer compares bodies byte for byte |
|
||||
| `scripts/check-phase19.1.sh` `run_docs` | five `testdata/goldens` | `require_dir` + `detect_secrets` | WIRED | Missing tree or a hit is refused |
|
||||
| `scripts/check-phase19.1.sh` postgres | chatvideo `TestUserDeletionReassignsSession` | `PG_CHATVIDEO_TESTS` + anchored self-test grep | WIRED | Ran this session |
|
||||
| All previous links (userfriends events/adapter, forum render/deny-all/rewrite, chatbots actor, herald fetchguard/enqueue, chatvideo authorizer/TrustedMode/bucket) | | | WIRED | No commits to those files since the previous pass; their tests passed again |
|
||||
|
||||
### Data-Flow Trace (Level 4)
|
||||
|
||||
| Artifact | Data Variable | Source | Produces Real Data | Status |
|
||||
| -------- | ------------- | ------ | ------------------ | ------ |
|
||||
| userfriends friends/groups API | friendship/group rows | GORM on baseline tables | yes (TestHTTPTracer) | ✓ FLOWING |
|
||||
| forum posts | content / content_html | write-path `breakwater.Render`; read returns stored HTML | yes | ✓ FLOWING |
|
||||
| chatbots dispatch | CommandResult | Registry + Dispatcher; JWT actor | yes | ✓ FLOWING |
|
||||
| herald subscriptions / send | subscription rows + webpush | GORM + fetchguard PublicOnly + conga job | yes (rollback tracer) | ✓ FLOWING |
|
||||
| chatvideo sessions | session / participant / JWT | GORM + RoomAPI fake in tests | yes | ✓ FLOWING |
|
||||
|
||||
No static `[]` / hardcoded empty payload on the published handlers.
|
||||
| userfriends API | friendship/group rows | GORM on baseline tables | yes (`TestHTTPTracer`) | ✓ FLOWING |
|
||||
| forum posts | content / content_html | `breakwater.Render` on write; stored HTML on read | yes | ✓ FLOWING |
|
||||
| chatbots dispatch | `CommandResult` | Registry + Dispatcher, JWT actor, `IsAvailable` | yes | ✓ FLOWING |
|
||||
| herald | subscriptions + webpush | GORM + fetchguard PublicOnly + conga job | yes | ✓ FLOWING |
|
||||
| chatvideo | sessions / participants on user delete | GORM on `ev.Tx`, RoomAPI after commit | yes (`TestUserDeletionReassignsSession`) | ✓ FLOWING |
|
||||
|
||||
### Behavioral Spot-Checks
|
||||
|
||||
| Behavior | Command | Result | Status |
|
||||
| -------- | ------- | ------ | ------ |
|
||||
| Gate self-test refuses planted skip/miss/zero | `bash scripts/check-phase19.1.sh --self-test` | `phase19.1 self-test passed` | ✓ PASS |
|
||||
| Decision-note pins | `bash scripts/check-phase19.1.sh --docs` | `phase19.1 docs passed` | ✓ PASS |
|
||||
| Short named tests ×5 repos | `bash scripts/check-phase19.1.sh --plugins` | vet + short + named tests; `phase19.1 plugins passed` | ✓ PASS |
|
||||
| HTTP tracers, GDPR, rollback, reconcile | `bash scripts/check-phase19.1.sh --postgres` | 11 named tests passed; `phase19.1 postgres passed` | ✓ PASS |
|
||||
| breakwater exports | grep `func Render` / `func Purify` | both present | ✓ PASS |
|
||||
| Gate self-test, including secret plants and the chatvideo pin | `bash scripts/check-phase19.1.sh --self-test` | exit 0, `phase19.1 self-test passed` | ✓ PASS |
|
||||
| Notes pins + goldens secret scan | `bash scripts/check-phase19.1.sh --docs` | exit 0, `goldens: no secrets in five sibling fixture trees` | ✓ PASS |
|
||||
| vet + short + named tests ×5 repos | `bash scripts/check-phase19.1.sh --plugins` | exit 0, `phase19.1 plugins passed` | ✓ PASS |
|
||||
| Docker suites: tracers, GDPR, rollback, reconcile, user deletion | `bash scripts/check-phase19.1.sh --postgres` | exit 0, 12 named tests passed across 5 repos | ✓ PASS |
|
||||
| WR-04 refusal | `go test -short -run '^TestDispatchRefusesUnavailable$' .` (chatbots) | PASS | ✓ PASS |
|
||||
| Reserved help | `go test -short -run '^TestRegisterReserved$' .` (chatbots) | ok | ✓ PASS |
|
||||
| D-18 stored HTML | `go test -short -run '^TestAdoptedContentHTML$' ./api` (forum) | ok | ✓ PASS |
|
||||
| Docs checker | `go test -short -run '^TestDocsTree$' ./cmd/summer` | ok | ✓ PASS |
|
||||
| breakwater | `go test -short ./modules/breakwater` | ok | ✓ PASS |
|
||||
|
||||
### Probe Execution
|
||||
|
||||
| Probe | Command | Result | Status |
|
||||
| ------ | ------- | ------ | ------ |
|
||||
| — | — | Phase is spec-less (REQUIREMENTS TBD; plan 01 recorded no probe predicates). No `scripts/*/tests/probe-*.sh`. Gate script above is the named check. | SKIP |
|
||||
| ----- | ------- | ------ | ------ |
|
||||
| — | — | No `scripts/*/tests/probe-*.sh`, and no plan declares a probe. The phase gate script above serves as the named check. | SKIP |
|
||||
|
||||
### Requirements Coverage
|
||||
|
||||
`.planning/REQUIREMENTS.md` has **Requirements: TBD** for Phase 19.1 and no `SC-19.1-*` rows. No orphaned REQUIREMENTS IDs. PLAN frontmatter IDs accounted for:
|
||||
`.planning/REQUIREMENTS.md` lists no requirement IDs for Phase 19.1 ("Requirements: TBD"), so no requirement is orphaned. The ROADMAP success criteria SC-19.1-1..4 and CONTEXT decisions D-01..D-18 are covered by truths 1-16 (decision coverage 18/18).
|
||||
|
||||
| Requirement | Source Plan | Description | Status | Evidence |
|
||||
| ----------- | ---------- | ----------- | ------ | -------- |
|
||||
| SC-19.1-1 | 01–06 | 1:1 schema/models/routes/events | ✓ SATISFIED | five repos + maps |
|
||||
| SC-19.1-2 | 03, 04, 05 | decision notes; chatbots not wired to AI plugin | ✓ SATISFIED | three notes; `TestNoGolem` |
|
||||
| SC-19.1-3 | 01 | fonoteka already met | ✓ SATISFIED | ROADMAP + no fonoteka.go port |
|
||||
| SC-19.1-4 | 06 | unit tests last | ✓ SATISFIED | maps, goldens, gate |
|
||||
| D-01..D-18 | 01–06 | CONTEXT decisions | ✓ SATISFIED | 18/18 decision-coverage honored; see truths |
|
||||
### Human UAT Evidence (Step 8b)
|
||||
|
||||
### Decision Coverage
|
||||
|
||||
All 18 trackable CONTEXT.md decisions are honored by shipped artifacts (`check.decision-coverage-verify`: honored 18 / total 18, `not_honored: []`).
|
||||
|
||||
### Test Quality Audit
|
||||
|
||||
| Test File | Linked Req | Active | Skipped | Circular | Assertion Level | Verdict |
|
||||
|-----------|-----------|--------|---------|----------|-----------------|---------|
|
||||
| five `http_tracer_test.go` | D-05 | yes (postgres) | skip only via testmain `-short` | no | behavioral | OK |
|
||||
| five `updates/baseline_test.go` | D-02 | yes | no | no | value (IF NOT EXISTS / IDs) | OK |
|
||||
| five `php_method_map_test.go` | D-04 | yes | no | no | value (map completeness) | OK |
|
||||
| forum `golden_test.go` / `api/json_test.go` | D-18 | yes | no | no — `_source` is PHP corpus / “live capture NOT RUN” | value (normalized DOM / stored HTML) | OK |
|
||||
| chatvideo `classes/livekit_token_test.go` | D-13 | yes | no | no — PHP LiveKitService.php claims fixture | value | OK |
|
||||
| herald `http_tracer_test.go` TestSendEventRollback | D-11 | yes (postgres) | short-skip in testmain | no | behavioral | OK |
|
||||
| userfriends `user_deleting_test.go` | D-03 | yes (postgres) | short-skip | no | behavioral | OK |
|
||||
|
||||
**Disabled tests on requirements:** 0 → no blocker
|
||||
**Circular patterns detected:** 0 → goldens cite PHP fixtures, not live capture of the Go SUT
|
||||
**Insufficient assertions:** 0
|
||||
|
||||
`t.Skip("requires testcontainers postgres")` lives only in each repo’s `testmain_test.go` for `-short`. Those names are required in the postgres stage, which ran and passed.
|
||||
`verification.uat-evidence` reports UAT row 1 (`pass`, recorded 2026-10-18T15:54:54Z). Files changed since the UAT: `docs/plugins/extending.md` and `scripts/check-phase19.1.sh`. Neither bears on what the row checked. The docs paragraph documents the accepted pattern. The script changes touch only goldens scanning and the chatvideo test list. The row checked `../sm-userfriends-plugin/go.mod` and `Plugin.Requires()`, and sm-userfriends-plugin has no commits since 14:15Z and a clean tree. The row therefore stands, and the item is recorded under `human_verified`. No new human item arose.
|
||||
|
||||
### Anti-Patterns Found
|
||||
|
||||
| File | Line | Pattern | Severity | Impact |
|
||||
| ---- | ---- | ------- | -------- | ------ |
|
||||
| `../sm-userfriends-plugin/go.mod` | 6 | direct `require sm-chat-plugin` | ⚠️ Warning | Plan 01 prohibition says go.mod never require chat. Needed for typed `Lookup[*chatcontracts.Registry]` (D-08). Requires() still omits chat. See Human Verification. |
|
||||
| `../sm-forum-plugin/go.mod` | 85, 120 | bluemonday/goldmark **indirect** | ℹ️ Info | Not a direct require. D-17 “never requires” is met. |
|
||||
| `../sm-chatvideo-plugin/go.mod` | pion lines | pion **indirect** via LiveKit SDK | ℹ️ Info | Tests do not import pion; no `lksdk.Room` construct. |
|
||||
| `../sm-herald-plugin/go.mod` | sm-user-plugin | test-harness require | ℹ️ Info | Production `.go` files do not import user models. Requires() empty. |
|
||||
| five `*-SUMMARY.md` (03–06) | frontmatter | `commits:` vs summercms.go `plan_head_before..after` | ⚠️ Warning | Plan 03 claimed 2 / window 0; 04 claimed 3 / window 1; 05 claimed 3 / window 1; 06 claimed 12 / window 1. Work landed in sibling repos (git logs show the feat/test commits). Instrument measures this repo only. Not a missing-implementation gap. |
|
||||
| Phase directory | — | no `*-SECURITY.md` | ⚠️ Warning | Plan 06 / CONTEXT asked for a security-review pass after APIs+push+tokens+HTML+GDPR exist. Planner did not spawn it. Discretion, not a must-have truth. |
|
||||
|
||||
No `TBD` / `FIXME` / `XXX` in phase-touched Go or the gate script.
|
||||
|
||||
**This looks intentional** (userfriends go.mod). To accept the deviation, add to this file’s frontmatter:
|
||||
|
||||
```yaml
|
||||
overrides:
|
||||
- must_have: "Requires() and go.mod never require sm-chat-plugin"
|
||||
reason: "D-08 soft adapter is a typed Lookup of sm-chat-plugin/contracts.Registry; go.mod must list the module. Requires() stays golem15.user only; missing chat is a Boot skip."
|
||||
accepted_by: "{name}"
|
||||
accepted_at: "{ISO timestamp}"
|
||||
```
|
||||
|
||||
Then re-run verification so the prohibition can become PASSED (override).
|
||||
| changed files (`dispatcher.go`, `user_deletion.go`, `video_service.go`, chatvideo `boot.go`, `user_deletion_test.go`, both READMEs, `check-phase19.1.sh`, `extending.md`, breakwater) | — | TBD/FIXME/XXX/TODO/HACK | — | None found |
|
||||
| `19.1-REVIEW-DISPOSITION.md` | frontmatter | WR-04/WR-05 still `open`; WR-01..03 and IN-01..04 `open` | ℹ️ Info | Bookkeeping. WR-04/05 are fixed (b723f2f, 492c45f; SECURITY T-19.1-13..15 closed). WR-01..03 are warning-level review findings and not must-haves. |
|
||||
| `../sm-chatvideo-plugin/go.mod` | 9 | `replace sm-user-plugin => ../fonoteka.go/plugins/golem15/user` | ℹ️ Info | Present before this phase's fixes. `boot.go` now imports `sm-user-plugin/classes` for `DeletingEvent`, and `Requires()` stays `{"golem15.chat"}`, so a host without the user plugin just never fires the event. |
|
||||
| `../sm-userfriends-plugin/go.mod` | 6 | direct require sm-chat-plugin | ℹ️ Info | Covered by the accepted override. |
|
||||
| sm-chatbots / sm-chatvideo `main` | — | ahead of origin by 1, unpushed | ℹ️ Info | Not pushed or tagged, which is expected without the user's go-ahead. |
|
||||
|
||||
### Human Verification Required
|
||||
|
||||
### 1. Accept userfriends go.mod chat import (planner contradiction)
|
||||
|
||||
**Test:** Confirm that `../sm-userfriends-plugin/go.mod` requiring `sm-chat-plugin` is acceptable because Boot does `Lookup[*chatcontracts.Registry]` and skips when chat is absent, while `Plugin.Requires()` remains `[]string{"golem15.user"}`.
|
||||
**Expected:** Override recorded. No production code change.
|
||||
**Why human:** Plan 01 `must_haves.prohibitions` forbids the go.mod require in the same breath as D-08 requiring a typed Registry Lookup. Grep cannot resolve a planner contradiction.
|
||||
None. UAT row 1 settles the only human item (see Step 8b above).
|
||||
|
||||
### Gaps Summary
|
||||
|
||||
No implementation gaps. All 16 merged truths are present, wired, data-flowing, and (where behavior-dependent) exercised by named tests that passed this session, including Docker postgres tracers.
|
||||
|
||||
The phase is **not** `passed` solely because a grep-tier prohibition failed as written and must not be silently absorbed. Accept the override above (or rewrite the prohibition) and re-verify.
|
||||
No gaps. All 16 merged truths and all 17 prohibitions hold: 16 with deterministic evidence, plus the userfriends `go.mod` prohibition, which passes by override and is backed by UAT row 1. The post-UAT changes are verified: the chatbots IsAvailable gate, the chatvideo user-deletion listener with after-commit LiveKit cleanup, the goldens secret scan, and the extra gate test. Every gate stage passed in this session, and the Docker suites really ran.
|
||||
|
||||
---
|
||||
|
||||
_Verified: 2026-10-18T14:15:00Z_
|
||||
_Verified: 2026-10-18T17:23:38Z_
|
||||
_Verifier: Claude (msd-verifier)_
|
||||
|
||||
Reference in New Issue
Block a user