docs(19.1): revise phase plans
This commit is contained in:
@@ -49,6 +49,7 @@ estimate:
|
||||
raw_tokens: 200000
|
||||
tasks: 3
|
||||
confidence: low
|
||||
# Estimates are uncalibrated (0 phase actuals). The user locked exactly this 6-plan split; do not split further. Stay tracer-then-expand inside this plan.
|
||||
must_haves:
|
||||
truths:
|
||||
- "D-01: module git.golem15.com/golem15/sm-userfriends-plugin, package userfriends, plugin ID golem15.userfriends, Requires golem15.user only; frozen PHP userfriends 182b514."
|
||||
|
||||
@@ -3,7 +3,9 @@ phase: 19.1-chat-satellites
|
||||
plan: 02
|
||||
type: execute
|
||||
wave: 2
|
||||
# Scheduler grouping only: D-17 Render/Purify is an external summercms.go /msd-quick gate (CONTEXT deferred; not a 19.1 plan id).
|
||||
depends_on: []
|
||||
# Empty on purpose: no 19.1 plan predecessor and no files_modified overlap with 19.1-01. D-17 is asserted on Task 1 verify and the tracer precondition.
|
||||
files_modified:
|
||||
- .planning/notes/2026-10-18-bluemonday-forum-policy.md
|
||||
- ../sm-forum-plugin/.gitignore
|
||||
@@ -39,13 +41,14 @@ files_modified:
|
||||
- ../sm-forum-plugin/harness_test.go
|
||||
- ../sm-forum-plugin/fixture_plugin_test.go
|
||||
- ../sm-forum-plugin/http_tracer_test.go
|
||||
autonomous: true
|
||||
autonomous: false
|
||||
requirements: [SC-19.1-1, D-01, D-02, D-03, D-04, D-05, D-08, D-16, D-17, D-18]
|
||||
estimate:
|
||||
tokens: 200000
|
||||
raw_tokens: 200000
|
||||
tasks: 3
|
||||
tasks: 4
|
||||
confidence: low
|
||||
# Estimates are uncalibrated (0 phase actuals). The user locked exactly this 6-plan split; do not split further. Stay tracer-then-expand. The fourth task is the identifier checkpoint, not a scope split.
|
||||
must_haves:
|
||||
truths:
|
||||
- "D-17: forum execution starts only after a summercms.go module exports Render(markdown) and Purify(html); sm-forum-plugin go.mod never requires bluemonday or goldmark."
|
||||
@@ -174,15 +177,45 @@ Then assert D-17: a summercms.go package exports Render and Purify (grep modules
|
||||
<done>The forum-policy note exists and D-17 Render/Purify are importable.</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:decision" gate="blocking-human">
|
||||
<name>Task 2: Confirm D-02 forum baseline id and D-05 prefix before the new repo exists</name>
|
||||
<read_first>.planning/phases/19.1-chat-satellites/19.1-CONTEXT.md (D-02, D-05), .planning/phases/19.1-chat-satellites/19.1-01-PLAN.md (Task 1 remote reply)</read_first>
|
||||
<action>Print a short identifier sheet, then stop. Do not create ../sm-forum-plugin. The sheet lists: module git.golem15.com/golem15/sm-forum-plugin, package forum, PluginID golem15.forum, migration id 202610180001_create_golem15_forum_baseline, published prefix /_forum/api/v1. Remote policy follows the plan 01 Task 1 reply (tea-create only on proceed-and-push). D-17 Render/Purify remains the external gate already asserted in Task 1.</action>
|
||||
<decision>Lock D-02 baseline id 202610180001_create_golem15_forum_baseline and D-05 prefix /_forum/api/v1, then implement?</decision>
|
||||
<context>These names land in every adopting app's database and in published clients. Changing the migration id or prefix after an app migrates needs a new migration and a client change.</context>
|
||||
<options>
|
||||
<option id="proceed">
|
||||
<name>Lock the identifiers and implement; remote follows plan 01</name>
|
||||
<pros>Forum contract matches CONTEXT D-02/D-05.</pros>
|
||||
<cons>Undo needs a new migration and a client change.</cons>
|
||||
</option>
|
||||
<option id="abort">
|
||||
<name>Stop; do not create the repository</name>
|
||||
<pros>The one-way door stays closed.</pros>
|
||||
<cons>Forum cannot start until identifiers are confirmed.</cons>
|
||||
</option>
|
||||
</options>
|
||||
<resume-signal>Reply proceed or abort.</resume-signal>
|
||||
<verify>
|
||||
<automated>test -f .planning/phases/19.1-chat-satellites/19.1-CONTEXT.md && grep -q "D-05" .planning/phases/19.1-chat-satellites/19.1-CONTEXT.md && echo forum-ids-ready</automated>
|
||||
<fails_when>non-zero exit or "forum-ids-ready" absent</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- SUMMARY records the reply verbatim.
|
||||
- After abort, ../sm-forum-plugin does not exist.
|
||||
</acceptance_criteria>
|
||||
<done>The human confirmed the forum baseline id and published prefix before any forum repo file was written.</done>
|
||||
</task>
|
||||
|
||||
<task type="tracer">
|
||||
<name>Task 2: End-to-end forum post — category, thread, GFM table, no script element</name>
|
||||
<name>Task 3: End-to-end forum post — category, thread, GFM table, no script element</name>
|
||||
<reversibility rating="one-way">D-02 forum baseline id and D-05 /_forum/api/v1 become the shared contract.</reversibility>
|
||||
<precondition>D-17 exports Render and Purify (Task 1 printed d17-ready). ../sm-forum-plugin does not already exist as a foreign module.</precondition>
|
||||
<precondition>Task 2 reply is proceed. D-17 exports Render and Purify (Task 1 printed d17-ready; external /msd-quick gate, not a 19.1 plan). ../sm-forum-plugin does not already exist as a foreign module.</precondition>
|
||||
<files>../sm-forum-plugin/go.mod, ../sm-forum-plugin/go.work, ../sm-forum-plugin/go.sum, ../sm-forum-plugin/.gitignore, ../sm-forum-plugin/README.md, ../sm-forum-plugin/plugin.go, ../sm-forum-plugin/boot.go, ../sm-forum-plugin/routes.go, ../sm-forum-plugin/config/config.yaml, ../sm-forum-plugin/lang/en/lang.yaml, ../sm-forum-plugin/lang/pl/lang.yaml, ../sm-forum-plugin/contracts/access_resolver.go, ../sm-forum-plugin/classes/deny_all.go, ../sm-forum-plugin/classes/forum_service.go, ../sm-forum-plugin/models/category.go, ../sm-forum-plugin/models/thread.go, ../sm-forum-plugin/models/post.go, ../sm-forum-plugin/models/thread_read.go, ../sm-forum-plugin/models/registry.go, ../sm-forum-plugin/api/auth.go, ../sm-forum-plugin/api/errors.go, ../sm-forum-plugin/api/json.go, ../sm-forum-plugin/api/categories.go, ../sm-forum-plugin/api/threads.go, ../sm-forum-plugin/api/posts.go, ../sm-forum-plugin/updates/registry.go, ../sm-forum-plugin/updates/202610180001_create_golem15_forum_baseline.go, ../sm-forum-plugin/updates/baseline_test.go, ../sm-forum-plugin/testmain_test.go, ../sm-forum-plugin/harness_test.go, ../sm-forum-plugin/fixture_plugin_test.go, ../sm-forum-plugin/http_tracer_test.go</files>
|
||||
<read_first>../sm-chatchannels-plugin/plugin.go, ../sm-chatchannels-plugin/contracts/access_resolver.go, ../sm-chatchannels-plugin/classes/deny_all.go, ../sm-chatchannels-plugin/boot.go, ../sm-chatchannels-plugin/routes.go, ../sm-chat-plugin/go.mod, ../sm-chat-plugin/http_tracer_test.go, /media/nvme/dev/jz/wavepath.org/plugins/golem15/forum/Plugin.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/forum/classes/ForumService.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/forum/classes/DenyAllForumAccessResolver.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/forum/updates/, /media/nvme/dev/jz/wavepath.org/plugins/golem15/forum/tests/security/ForumMarkdownRenderTest.php</read_first>
|
||||
<action>Per D-01 and D-02, create ../sm-forum-plugin as a sibling. Analog go.mod pins; replace summercms => ../summercms.go; go.work replaces sm-user-plugin. go.mod stays on analog pins plus the user plugin. Consume D-17 from summercms; do not add markdown libraries or the friends module.
|
||||
|
||||
plugin.go: package forum, PluginID golem15.forum, Requires golem15.user, HasRoutes, BucketProvider, HasCommands (rewrite lands in Task 3). README H1 Forum; plugin.name Forum / Forum. SetAccessResolver analog chatchannels.
|
||||
plugin.go: package forum, PluginID golem15.forum, Requires golem15.user, HasRoutes, BucketProvider, HasCommands (rewrite lands in Task 4). README H1 Forum, one-sentence summary, import line, **Name:** mnemonic, standard sections; names only acme / blog; plugin.name Forum / Forum. Per D-03 / PATTERNS Docs/README, production sources, comments, lang and README never contain QuestStream, family, parent, child, Wavepath, or Fonoteka; copy TestFixtureAbsentFromProduction (retired-token grep) from the chat analog. SetAccessResolver analog chatchannels.
|
||||
|
||||
Baseline 202610180001_create_golem15_forum_baseline: four PHP v1.1.0 tables from RESEARCH. categories.context_type NOT NULL, no FK; unique (context_type, context_id, slug); threads.user_id and posts.user_id nullable SET NULL; deletion_reason varchar check self|moderator or null. TestBaseline greps the four table names.
|
||||
|
||||
@@ -212,7 +245,7 @@ Remote policy follows plan 01 Task 1: tea-create only on proceed-and-push; other
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: DeleteContext, morph rewrite, remaining routes, GDPR null authorship</name>
|
||||
<name>Task 4: DeleteContext, morph rewrite, remaining routes, GDPR null authorship</name>
|
||||
<reversibility rating="one-way">forum:rewrite-context-types changes stored context_type rows; PHP cannot resolve rewritten aliases.</reversibility>
|
||||
<files>../sm-forum-plugin/classes/forum_service.go, ../sm-forum-plugin/console/rewrite_context_types.go, ../sm-forum-plugin/api/categories.go, ../sm-forum-plugin/api/threads.go, ../sm-forum-plugin/api/posts.go, ../sm-forum-plugin/routes.go, ../sm-forum-plugin/boot.go, ../sm-forum-plugin/plugin.go, ../sm-forum-plugin/README.md</files>
|
||||
<read_first>../sm-forum-plugin/classes/forum_service.go, ../sm-chat-plugin/console/rewrite_context_types.go, ../sm-chat-plugin/classes/writes.go, ../sm-chatchannels-plugin/boot.go, /media/nvme/dev/jz/wavepath.org/plugins/golem15/forum/Plugin.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/forum/classes/ForumService.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/wavepath/controllers/api/CommunityForumController.php</read_first>
|
||||
|
||||
@@ -35,13 +35,14 @@ files_modified:
|
||||
- ../sm-chatbots-plugin/harness_test.go
|
||||
- ../sm-chatbots-plugin/fixture_plugin_test.go
|
||||
- ../sm-chatbots-plugin/http_tracer_test.go
|
||||
autonomous: true
|
||||
autonomous: false
|
||||
requirements: [SC-19.1-1, SC-19.1-2, D-01, D-02, D-03, D-04, D-05]
|
||||
estimate:
|
||||
tokens: 160000
|
||||
raw_tokens: 160000
|
||||
tasks: 2
|
||||
tasks: 3
|
||||
confidence: low
|
||||
# Estimates are uncalibrated (0 phase actuals). The user locked exactly this 6-plan split; do not split further. Stay tracer-then-expand inside this plan.
|
||||
must_haves:
|
||||
truths:
|
||||
- "D-01 / SC-19.1-2: module git.golem15.com/golem15/sm-chatbots-plugin, package chatbots, PluginID golem15.chatbots, Requires golem15.chat and golem15.user; go.mod never requires the AI plugin."
|
||||
@@ -134,15 +135,45 @@ Analog:
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="checkpoint:decision" gate="blocking-human">
|
||||
<name>Task 1: Confirm D-02 chatbots baseline id and D-05 prefix before the new repo exists</name>
|
||||
<read_first>.planning/phases/19.1-chat-satellites/19.1-CONTEXT.md (D-02, D-05), .planning/phases/19.1-chat-satellites/19.1-01-PLAN.md (Task 1 remote reply)</read_first>
|
||||
<action>Print a short identifier sheet, then stop. Do not create ../sm-chatbots-plugin. The sheet lists: module git.golem15.com/golem15/sm-chatbots-plugin, package chatbots, PluginID golem15.chatbots, migration id 202610180001_create_golem15_chatbots_baseline, published prefix /_chatbots/api/v1. Remote policy follows the plan 01 Task 1 reply (tea-create only on proceed-and-push).</action>
|
||||
<decision>Lock D-02 baseline id 202610180001_create_golem15_chatbots_baseline and D-05 prefix /_chatbots/api/v1, then implement?</decision>
|
||||
<context>These names land in every adopting app's database and in published clients. Changing the migration id or prefix after an app migrates needs a new migration and a client change.</context>
|
||||
<options>
|
||||
<option id="proceed">
|
||||
<name>Lock the identifiers and implement; remote follows plan 01</name>
|
||||
<pros>Chatbots contract matches CONTEXT D-02/D-05.</pros>
|
||||
<cons>Undo needs a new migration and a client change.</cons>
|
||||
</option>
|
||||
<option id="abort">
|
||||
<name>Stop; do not create the repository</name>
|
||||
<pros>The one-way door stays closed.</pros>
|
||||
<cons>Chatbots cannot start until identifiers are confirmed.</cons>
|
||||
</option>
|
||||
</options>
|
||||
<resume-signal>Reply proceed or abort.</resume-signal>
|
||||
<verify>
|
||||
<automated>test -f .planning/phases/19.1-chat-satellites/19.1-CONTEXT.md && grep -q "D-05" .planning/phases/19.1-chat-satellites/19.1-CONTEXT.md && echo chatbots-ids-ready</automated>
|
||||
<fails_when>non-zero exit or "chatbots-ids-ready" absent</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- SUMMARY records the reply verbatim.
|
||||
- After abort, ../sm-chatbots-plugin does not exist.
|
||||
</acceptance_criteria>
|
||||
<done>The human confirmed the chatbots baseline id and published prefix before any chatbots repo file was written.</done>
|
||||
</task>
|
||||
|
||||
<task type="tracer">
|
||||
<name>Task 1: End-to-end /ping — registry, dispatcher, JWT actor, ephemeral, /help</name>
|
||||
<name>Task 2: End-to-end /ping — registry, dispatcher, JWT actor, ephemeral, /help</name>
|
||||
<reversibility rating="one-way">D-02 bot_flags baseline and D-05 /_chatbots/api/v1 become the shared contract.</reversibility>
|
||||
<precondition>../sm-chat-plugin exists (Phase 19) and ../sm-chatbots-plugin does not already exist as a foreign module.</precondition>
|
||||
<precondition>Task 1 reply is proceed. ../sm-chat-plugin exists (Phase 19) and ../sm-chatbots-plugin does not already exist as a foreign module.</precondition>
|
||||
<files>../sm-chatbots-plugin/go.mod, ../sm-chatbots-plugin/go.work, ../sm-chatbots-plugin/go.sum, ../sm-chatbots-plugin/.gitignore, ../sm-chatbots-plugin/README.md, ../sm-chatbots-plugin/plugin.go, ../sm-chatbots-plugin/boot.go, ../sm-chatbots-plugin/routes.go, ../sm-chatbots-plugin/config/config.yaml, ../sm-chatbots-plugin/lang/en/lang.yaml, ../sm-chatbots-plugin/lang/pl/lang.yaml, ../sm-chatbots-plugin/contracts/slash_command.go, ../sm-chatbots-plugin/contracts/bot_auth_resolver.go, ../sm-chatbots-plugin/classes/deny_all.go, ../sm-chatbots-plugin/classes/registry.go, ../sm-chatbots-plugin/classes/dispatcher.go, ../sm-chatbots-plugin/classes/help.go, ../sm-chatbots-plugin/models/bot_flag.go, ../sm-chatbots-plugin/models/registry.go, ../sm-chatbots-plugin/api/auth.go, ../sm-chatbots-plugin/api/errors.go, ../sm-chatbots-plugin/api/json.go, ../sm-chatbots-plugin/api/commands.go, ../sm-chatbots-plugin/updates/registry.go, ../sm-chatbots-plugin/updates/202610180001_create_golem15_chatbots_baseline.go, ../sm-chatbots-plugin/updates/baseline_test.go, ../sm-chatbots-plugin/testmain_test.go, ../sm-chatbots-plugin/harness_test.go, ../sm-chatbots-plugin/fixture_plugin_test.go, ../sm-chatbots-plugin/http_tracer_test.go</files>
|
||||
<read_first>../sm-chatchannels-plugin/plugin.go, ../sm-chatchannels-plugin/go.work, ../sm-chatchannels-plugin/classes/deny_all.go, ../sm-chat-plugin/contracts/registry.go, ../sm-chat-plugin/api/auth.go, ../sm-chat-plugin/http_tracer_test.go, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatbots/Plugin.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatbots/classes/SlashCommandRegistry.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatbots/classes/CommandDispatcher.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatbots/classes/CommandResult.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatbots/classes/commands/HelpCommand.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatbots/contracts/SlashCommand.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatbots/contracts/BotAuthResolver.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatbots/updates/create_bot_flags_table.php</read_first>
|
||||
<action>Per D-01 and D-02, create ../sm-chatbots-plugin. Analog pins; replace summercms => ../summercms.go; go.work replaces sm-user-plugin and sm-chat-plugin. Require sm-chat-plugin. Do not require the AI plugin module (SC-19.1-2).
|
||||
|
||||
plugin.go: package chatbots, PluginID golem15.chatbots, Requires golem15.chat and golem15.user. README H1 Chat bots; plugin.name Chat bots. SetBotAuthResolver analog SetAccessResolver.
|
||||
plugin.go: package chatbots, PluginID golem15.chatbots, Requires golem15.chat and golem15.user. README H1 Chat bots, one-sentence summary, import line, **Name:** mnemonic, standard sections; names only acme / blog; plugin.name Chat bots / Boty czatu. Per D-03 / PATTERNS Docs/README, production sources, comments, lang and README never contain QuestStream, family, parent, child, Wavepath, or Fonoteka; copy TestFixtureAbsentFromProduction (retired-token grep) from the chat analog. SetBotAuthResolver analog SetAccessResolver.
|
||||
|
||||
Baseline 202610180001_create_golem15_chatbots_baseline: golem15_chatbots_bot_flags (id, user_id unique chatbots_bot_flags_user_unique, is_bot bool default true, timestamps, FK user_id cascade). TestBaseline greps that table.
|
||||
|
||||
@@ -173,7 +204,7 @@ Remote: stay local unless plan 01 already chose proceed-and-push and tea is avai
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: GDPR bot_flags delete and catalog/auth expansion</name>
|
||||
<name>Task 3: GDPR bot_flags delete and catalog/auth expansion</name>
|
||||
<files>../sm-chatbots-plugin/boot.go, ../sm-chatbots-plugin/classes/registry.go, ../sm-chatbots-plugin/api/commands.go, ../sm-chatbots-plugin/README.md</files>
|
||||
<read_first>../sm-chatbots-plugin/boot.go, ../sm-chat-plugin/boot.go, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatbots/Plugin.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/wavepath/controllers/api/CommunityCommandController.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/wavepath/controllers/api/BotRestController.php</read_first>
|
||||
<action>Per D-03, Listen user.Deleting and delete golem15_chatbots_bot_flags for that user_id inside ev.Tx.
|
||||
|
||||
@@ -38,13 +38,14 @@ files_modified:
|
||||
- ../sm-herald-plugin/harness_test.go
|
||||
- ../sm-herald-plugin/fixture_plugin_test.go
|
||||
- ../sm-herald-plugin/http_tracer_test.go
|
||||
autonomous: true
|
||||
autonomous: false
|
||||
requirements: [SC-19.1-1, SC-19.1-2, D-04, D-05, D-06, D-09, D-10, D-11, D-12]
|
||||
estimate:
|
||||
tokens: 200000
|
||||
raw_tokens: 200000
|
||||
tasks: 3
|
||||
tasks: 4
|
||||
confidence: low
|
||||
# Estimates are uncalibrated (0 phase actuals). The user locked exactly this 6-plan split; do not split further. Stay tracer-then-expand. The fourth task is the identifier checkpoint, not a scope split.
|
||||
must_haves:
|
||||
truths:
|
||||
- "D-09 / SC-19.1-2: .planning/notes/2026-10-18-webpush-go.md exists and names github.com/SherClockHolmes/webpush-go v1.4.0, jwt/v5 share, Options.HTTPClient = *fetchguard.Client Do, and does not name the in-tree Web Push module as the sender."
|
||||
@@ -164,15 +165,45 @@ Analog:
|
||||
<done>The decision note exists and no herald go.mod yet requires webpush-go.</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:decision" gate="blocking-human">
|
||||
<name>Task 2: Confirm D-02 herald baseline id and D-05 prefix before the new repo exists</name>
|
||||
<read_first>.planning/phases/19.1-chat-satellites/19.1-CONTEXT.md (D-02, D-05, D-06), .planning/phases/19.1-chat-satellites/19.1-01-PLAN.md (Task 1 remote reply)</read_first>
|
||||
<action>Print a short identifier sheet, then stop. Do not create ../sm-herald-plugin. The sheet lists: module git.golem15.com/golem15/sm-herald-plugin, package herald, PluginID golem15.herald, migration id 202610180001_create_golem15_herald_baseline, published prefix /_herald/api/v1. Remote policy follows the plan 01 Task 1 reply (tea-create only on proceed-and-push).</action>
|
||||
<decision>Lock D-02 baseline id 202610180001_create_golem15_herald_baseline and D-05 prefix /_herald/api/v1, then implement?</decision>
|
||||
<context>These names land in every adopting app's database and in published clients. D-06 also publishes routes PHP did not ship. Changing the migration id or prefix after an app migrates needs a new migration and a client change.</context>
|
||||
<options>
|
||||
<option id="proceed">
|
||||
<name>Lock the identifiers and implement; remote follows plan 01</name>
|
||||
<pros>Herald contract matches CONTEXT D-02/D-05/D-06.</pros>
|
||||
<cons>Undo needs a new migration and a client change.</cons>
|
||||
</option>
|
||||
<option id="abort">
|
||||
<name>Stop; do not create the repository</name>
|
||||
<pros>The one-way door stays closed.</pros>
|
||||
<cons>Herald cannot start until identifiers are confirmed.</cons>
|
||||
</option>
|
||||
</options>
|
||||
<resume-signal>Reply proceed or abort.</resume-signal>
|
||||
<verify>
|
||||
<automated>test -f .planning/phases/19.1-chat-satellites/19.1-CONTEXT.md && grep -q "D-05" .planning/phases/19.1-chat-satellites/19.1-CONTEXT.md && echo herald-ids-ready</automated>
|
||||
<fails_when>non-zero exit or "herald-ids-ready" absent</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- SUMMARY records the reply verbatim.
|
||||
- After abort, ../sm-herald-plugin does not exist.
|
||||
</acceptance_criteria>
|
||||
<done>The human confirmed the herald baseline id and published prefix before any herald repo file was written.</done>
|
||||
</task>
|
||||
|
||||
<task type="tracer">
|
||||
<name>Task 2: End-to-end push — subscribe https, SendUnconditional after commit, 410 prune, rollback sends 0</name>
|
||||
<name>Task 3: End-to-end push — subscribe https, SendUnconditional after commit, 410 prune, rollback sends 0</name>
|
||||
<reversibility rating="one-way">D-02 herald baseline and D-05 /_herald/api/v1 become the shared contract; D-06 publishes routes PHP did not ship.</reversibility>
|
||||
<precondition>Task 1 printed webpush-note-ready. ../sm-herald-plugin does not already exist as a foreign module.</precondition>
|
||||
<precondition>Task 2 reply is proceed. Task 1 printed webpush-note-ready. ../sm-herald-plugin does not already exist as a foreign module.</precondition>
|
||||
<files>../sm-herald-plugin/go.mod, ../sm-herald-plugin/go.work, ../sm-herald-plugin/go.sum, ../sm-herald-plugin/.gitignore, ../sm-herald-plugin/README.md, ../sm-herald-plugin/plugin.go, ../sm-herald-plugin/boot.go, ../sm-herald-plugin/routes.go, ../sm-herald-plugin/config/config.yaml, ../sm-herald-plugin/lang/en/lang.yaml, ../sm-herald-plugin/lang/pl/lang.yaml, ../sm-herald-plugin/classes/subscription_service.go, ../sm-herald-plugin/classes/sender.go, ../sm-herald-plugin/jobs/send.go, ../sm-herald-plugin/models/subscription.go, ../sm-herald-plugin/models/registry.go, ../sm-herald-plugin/api/auth.go, ../sm-herald-plugin/api/errors.go, ../sm-herald-plugin/api/json.go, ../sm-herald-plugin/api/push.go, ../sm-herald-plugin/updates/registry.go, ../sm-herald-plugin/updates/202610180001_create_golem15_herald_baseline.go, ../sm-herald-plugin/updates/baseline_test.go, ../sm-herald-plugin/testmain_test.go, ../sm-herald-plugin/harness_test.go, ../sm-herald-plugin/fixture_plugin_test.go, ../sm-herald-plugin/http_tracer_test.go</files>
|
||||
<read_first>../sm-chat-plugin/plugin.go, ../sm-chat-plugin/jobs/maintain_thread_summary.go, ../sm-chat-plugin/classes/service.go, ../sm-chat-plugin/http_tracer_test.go, modules/fetchguard/client.go, modules/fetchguard/policy.go, /media/nvme/dev/jz/wavepath.org/plugins/golem15/herald/Plugin.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/herald/classes/PushSender.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/herald/classes/services/SubscriptionService.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/herald/updates/create_push_subscriptions_table.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/herald/config/herald.php, .planning/notes/2026-10-18-webpush-go.md</read_first>
|
||||
<action>Only after the note exists, create ../sm-herald-plugin and go get github.com/SherClockHolmes/webpush-go@v1.4.0. Analog pins; replace summercms => ../summercms.go. Requires() empty. Do not import user models. Do not import the in-tree Web Push module.
|
||||
|
||||
plugin.go: package herald, PluginID golem15.herald, HasJobs, HasRoutes, HasCommands (command in Task 3), BucketProvider. README H1 Herald; rewrite the PHP reuse contract around the generic API (D-06).
|
||||
plugin.go: package herald, PluginID golem15.herald, HasJobs, HasRoutes, HasCommands (command in Task 4), BucketProvider. README H1 Herald, one-sentence summary, import line, **Name:** mnemonic, standard sections; names only acme / blog; plugin.name Herald / Herald. Per D-03 / PATTERNS Docs/README, production sources, comments, lang and README never contain QuestStream, family, parent, child, Wavepath, or Fonoteka; copy TestFixtureAbsentFromProduction (retired-token grep) from the chat analog. Rewrite the PHP reuse contract around the generic API (D-06).
|
||||
|
||||
Baseline 202610180001_create_golem15_herald_baseline: golem15_herald_push_subscriptions (endpoint varchar 500, keys text JSON p256dh/auth, unique (user_id, endpoint) herald_push_user_endpoint_unique, FK user_id cascade because the test host has users). TestBaseline greps the table.
|
||||
|
||||
@@ -201,7 +232,7 @@ Remote: stay local unless plan 01 chose proceed-and-push; never force-push.</act
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: PresenceGate, NeutralHeraldProfile, vapid-generate, remaining push routes</name>
|
||||
<name>Task 4: PresenceGate, NeutralHeraldProfile, vapid-generate, remaining push routes</name>
|
||||
<files>../sm-herald-plugin/contracts/herald_profile.go, ../sm-herald-plugin/contracts/presence_gate.go, ../sm-herald-plugin/classes/deny_all.go, ../sm-herald-plugin/classes/neutral_profile.go, ../sm-herald-plugin/classes/sender.go, ../sm-herald-plugin/console/vapid_generate.go, ../sm-herald-plugin/api/push.go, ../sm-herald-plugin/routes.go, ../sm-herald-plugin/boot.go, ../sm-herald-plugin/plugin.go, ../sm-herald-plugin/config/config.yaml, ../sm-herald-plugin/README.md</files>
|
||||
<read_first>../sm-herald-plugin/classes/sender.go, ../sm-chatchannels-plugin/classes/deny_all.go, ../sm-chat-plugin/console/rewrite_context_types.go, /media/nvme/dev/jz/wavepath.org/plugins/golem15/herald/classes/DenyAllPresenceGate.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/herald/classes/NeutralHeraldProfile.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/herald/console/GenerateVapidKeys.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/herald/config/herald.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/wavepath/controllers/api/PushSubscriptionController.php</read_first>
|
||||
<action>Per D-03, PresenceGate default DenyAll ShouldSend always false; SetPresenceGate; Boot Warn while DenyAll is active. HeraldProfile default NeutralHeraldProfile (app name only) — no Warn for the profile.
|
||||
|
||||
@@ -3,7 +3,9 @@ phase: 19.1-chat-satellites
|
||||
plan: 05
|
||||
type: execute
|
||||
wave: 2
|
||||
# Scheduler grouping only: sm-chat-plugin (Phase 19) is already shipped. Not a 19.1 plan edge.
|
||||
depends_on: []
|
||||
# Empty on purpose: Phase 19 chat is a prior-phase artifact, asserted on the tracer precondition. No 19.1 plan predecessor.
|
||||
files_modified:
|
||||
- .planning/notes/2026-10-18-livekit-server-sdk-go.md
|
||||
- ../sm-chatvideo-plugin/.gitignore
|
||||
@@ -39,18 +41,20 @@ files_modified:
|
||||
- ../sm-chatvideo-plugin/harness_test.go
|
||||
- ../sm-chatvideo-plugin/fixture_plugin_test.go
|
||||
- ../sm-chatvideo-plugin/http_tracer_test.go
|
||||
autonomous: true
|
||||
- ../sm-chatvideo-plugin/reconcile_test.go
|
||||
autonomous: false
|
||||
requirements: [SC-19.1-1, SC-19.1-2, D-04, D-05, D-07, D-13, D-14, D-15]
|
||||
estimate:
|
||||
tokens: 200000
|
||||
raw_tokens: 200000
|
||||
tasks: 3
|
||||
tasks: 4
|
||||
confidence: low
|
||||
# Estimates are uncalibrated (0 phase actuals). The user locked exactly this 6-plan split; do not split further. Stay tracer-then-expand. The fourth task is the identifier checkpoint, not a scope split.
|
||||
must_haves:
|
||||
truths:
|
||||
- "D-13 / SC-19.1-2: .planning/notes/2026-10-18-livekit-server-sdk-go.md names github.com/livekit/server-sdk-go/v2 v2.19.0, flags pion/media-sdk/buildkit, RoomAPI interface, TrustedMode for the operator URL, and jwt/v5 MapClaims if SDK grant JSON differs."
|
||||
- "D-02: baseline 202610180001_create_golem15_chatvideo_baseline creates golem15_chatvideo_sessions (unique active_conversation_id, join_code, no updated_at, CREATED_AT=started_at) and participants; demo-seed v1.0.1 is a comment."
|
||||
- "D-05 / D-15: paths /_chatvideo/api/v1/conversations/{id}/video/{start,join,leave,end,status} and /call-links/{code}; video-initiate 5/min on start only; authorizer splits segment 2 of video:session:{id} and never uses the segment-1 helper; capabilities prs."
|
||||
- "D-02 / D-15: baseline 202610180001_create_golem15_chatvideo_baseline creates golem15_chatvideo_sessions (unique active_conversation_id, join_code, card_message_id nullable uint, no updated_at, CREATED_AT=started_at) and participants; demo-seed v1.0.1 is a comment."
|
||||
- "D-05 / D-15: paths /_chatvideo/api/v1/conversations/{id}/video/{start,join,leave,end,status} and /call-links/{code}; video-initiate 5/min on start only; authorizer splits segment 2 of video:session:{id} and never uses the segment-1 helper; capabilities prs; sessions.card_message_id is a nullable uint that carries over from PHP."
|
||||
- "D-14: summer chatvideo:reconcile-sessions plus conga Kind golem15.chatvideo.reconcile_sessions MaxAttempts 1 every 5 minutes; generic only (empty/gone room or max_duration); no GuestCall, call cards, or CallNotifier."
|
||||
- "D-13 token golden: HS256, iss API key, sub user id string, name, iat/nbf/exp token_ttl 900, video grant room/roomJoin/canPublish/canSubscribe, optional metadata JSON avatar."
|
||||
artifacts:
|
||||
@@ -184,17 +188,47 @@ Analog:
|
||||
<done>The LiveKit note exists and no chatvideo go.mod yet requires the SDK.</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:decision" gate="blocking-human">
|
||||
<name>Task 2: Confirm D-02 chatvideo baseline id and D-05 prefix before the new repo exists</name>
|
||||
<read_first>.planning/phases/19.1-chat-satellites/19.1-CONTEXT.md (D-02, D-05, D-15), .planning/phases/19.1-chat-satellites/19.1-01-PLAN.md (Task 1 remote reply)</read_first>
|
||||
<action>Print a short identifier sheet, then stop. Do not create ../sm-chatvideo-plugin. The sheet lists: module git.golem15.com/golem15/sm-chatvideo-plugin, package chatvideo, PluginID golem15.chatvideo, migration id 202610180001_create_golem15_chatvideo_baseline, published prefix /_chatvideo/api/v1, sessions.card_message_id nullable uint (D-15). Remote policy follows the plan 01 Task 1 reply (tea-create only on proceed-and-push). Phase 19 sm-chat-plugin is already shipped and is an external precondition, not a 19.1 plan edge.</action>
|
||||
<decision>Lock D-02 baseline id 202610180001_create_golem15_chatvideo_baseline and D-05 prefix /_chatvideo/api/v1, then implement?</decision>
|
||||
<context>These names land in every adopting app's database and in published clients. Changing the migration id or prefix after an app migrates needs a new migration and a client change.</context>
|
||||
<options>
|
||||
<option id="proceed">
|
||||
<name>Lock the identifiers and implement; remote follows plan 01</name>
|
||||
<pros>Chatvideo contract matches CONTEXT D-02/D-05/D-15.</pros>
|
||||
<cons>Undo needs a new migration and a client change.</cons>
|
||||
</option>
|
||||
<option id="abort">
|
||||
<name>Stop; do not create the repository</name>
|
||||
<pros>The one-way door stays closed.</pros>
|
||||
<cons>Chatvideo cannot start until identifiers are confirmed.</cons>
|
||||
</option>
|
||||
</options>
|
||||
<resume-signal>Reply proceed or abort.</resume-signal>
|
||||
<verify>
|
||||
<automated>test -f .planning/phases/19.1-chat-satellites/19.1-CONTEXT.md && grep -q "D-15" .planning/phases/19.1-chat-satellites/19.1-CONTEXT.md && echo chatvideo-ids-ready</automated>
|
||||
<fails_when>non-zero exit or "chatvideo-ids-ready" absent</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- SUMMARY records the reply verbatim.
|
||||
- After abort, ../sm-chatvideo-plugin does not exist.
|
||||
</acceptance_criteria>
|
||||
<done>The human confirmed the chatvideo baseline id and published prefix before any chatvideo repo file was written.</done>
|
||||
</task>
|
||||
|
||||
<task type="tracer">
|
||||
<name>Task 2: End-to-end video start — unique active session, token golden, authorizer stranger deny</name>
|
||||
<name>Task 3: End-to-end video start — unique active session, token golden, authorizer stranger deny</name>
|
||||
<reversibility rating="one-way">D-02 chatvideo baseline and D-05 /_chatvideo/api/v1 become the shared contract.</reversibility>
|
||||
<precondition>Task 1 printed livekit-note-ready. ../sm-chat-plugin exists. ../sm-chatvideo-plugin does not already exist as a foreign module.</precondition>
|
||||
<precondition>Task 2 reply is proceed. Task 1 printed livekit-note-ready. ../sm-chat-plugin exists (Phase 19 already shipped). ../sm-chatvideo-plugin does not already exist as a foreign module.</precondition>
|
||||
<files>../sm-chatvideo-plugin/go.mod, ../sm-chatvideo-plugin/go.work, ../sm-chatvideo-plugin/go.sum, ../sm-chatvideo-plugin/.gitignore, ../sm-chatvideo-plugin/README.md, ../sm-chatvideo-plugin/plugin.go, ../sm-chatvideo-plugin/boot.go, ../sm-chatvideo-plugin/routes.go, ../sm-chatvideo-plugin/config/config.yaml, ../sm-chatvideo-plugin/lang/en/lang.yaml, ../sm-chatvideo-plugin/lang/pl/lang.yaml, ../sm-chatvideo-plugin/classes/livekit.go, ../sm-chatvideo-plugin/classes/authorizer.go, ../sm-chatvideo-plugin/classes/video_service.go, ../sm-chatvideo-plugin/models/session.go, ../sm-chatvideo-plugin/models/participant.go, ../sm-chatvideo-plugin/models/registry.go, ../sm-chatvideo-plugin/api/auth.go, ../sm-chatvideo-plugin/api/errors.go, ../sm-chatvideo-plugin/api/json.go, ../sm-chatvideo-plugin/api/video.go, ../sm-chatvideo-plugin/updates/registry.go, ../sm-chatvideo-plugin/updates/202610180001_create_golem15_chatvideo_baseline.go, ../sm-chatvideo-plugin/updates/baseline_test.go, ../sm-chatvideo-plugin/testmain_test.go, ../sm-chatvideo-plugin/harness_test.go, ../sm-chatvideo-plugin/fixture_plugin_test.go, ../sm-chatvideo-plugin/http_tracer_test.go</files>
|
||||
<read_first>../sm-chat-plugin/classes/authorizer.go, ../sm-chat-plugin/boot.go, ../sm-chat-plugin/routes.go, ../sm-chat-plugin/http_tracer_test.go, modules/lighthouse/channel.go, modules/fetchguard/policy.go, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatvideo/Plugin.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatvideo/classes/LiveKitService.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatvideo/classes/VideoChannelAuthorizer.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatvideo/models/VideoSession.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatvideo/updates/, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatvideo/config/config.php, .planning/notes/2026-10-18-livekit-server-sdk-go.md</read_first>
|
||||
<action>Only after the note exists, create ../sm-chatvideo-plugin and go get github.com/livekit/server-sdk-go/v2@v2.19.0. Analog pins; replace summercms and sm-chat-plugin and sm-user-plugin. Requires golem15.chat.
|
||||
|
||||
plugin.go: package chatvideo, PluginID golem15.chatvideo, HasRoutes, HasJobs, HasCommands, HasSchedule (schedule in Task 3), BucketProvider. README H1 Chat video.
|
||||
plugin.go: package chatvideo, PluginID golem15.chatvideo, HasRoutes, HasJobs, HasCommands, HasSchedule (schedule in Task 4), BucketProvider. README H1 Chat video, one-sentence summary, import line, **Name:** mnemonic, standard sections; names only acme / blog; plugin.name Chat video / Czat wideo. Per D-03 / PATTERNS Docs/README, production sources, comments, lang and README never contain QuestStream, family, parent, child, Wavepath, or Fonoteka; copy TestFixtureAbsentFromProduction (retired-token grep) from the chat analog.
|
||||
|
||||
Baseline 202610180001_create_golem15_chatvideo_baseline: sessions and participants from RESEARCH. unique active_conversation_id uniq_chatvideo_active_conversation; join_code varchar 12 unique; status pending|active|ended; no updated_at; comment demo-seed v1.0.1. Model CREATED_AT=started_at. TestBaseline greps both tables.
|
||||
Baseline 202610180001_create_golem15_chatvideo_baseline: sessions and participants from RESEARCH. unique active_conversation_id uniq_chatvideo_active_conversation; join_code varchar 12 unique; card_message_id nullable uint (D-15 carry-over; the generic plugin stores the column and does not write call cards); status pending|active|ended; no updated_at; comment demo-seed v1.0.1. Model CREATED_AT=started_at. TestBaseline greps both tables and card_message_id.
|
||||
|
||||
RoomAPI interface as RESEARCH. Production client: NewRoomServiceClient with HTTP through fetchguard TrustedMode (operator URL, may be loopback). Admin URL: livekit_admin_url else rewrite wss/ws to https/http. DeleteRoom swallows missing-room (D-13). ParticipantCount missing-room returns 0. Tests: in-memory fake; do not import the WebRTC stack the note flagged; do not construct the realtime room client.
|
||||
|
||||
@@ -224,24 +258,27 @@ Remote: stay local unless plan 01 chose proceed-and-push; never force-push.</act
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: leave/end/status/call-links, generic reconciler, realtime events</name>
|
||||
<files>../sm-chatvideo-plugin/classes/video_service.go, ../sm-chatvideo-plugin/classes/notifier.go, ../sm-chatvideo-plugin/jobs/reconcile.go, ../sm-chatvideo-plugin/console/reconcile.go, ../sm-chatvideo-plugin/schedule.go, ../sm-chatvideo-plugin/api/video.go, ../sm-chatvideo-plugin/api/call_links.go, ../sm-chatvideo-plugin/routes.go, ../sm-chatvideo-plugin/plugin.go, ../sm-chatvideo-plugin/boot.go, ../sm-chatvideo-plugin/README.md</files>
|
||||
<name>Task 4: leave/end/status/call-links, generic reconciler, realtime events</name>
|
||||
<files>../sm-chatvideo-plugin/classes/video_service.go, ../sm-chatvideo-plugin/classes/notifier.go, ../sm-chatvideo-plugin/jobs/reconcile.go, ../sm-chatvideo-plugin/console/reconcile.go, ../sm-chatvideo-plugin/schedule.go, ../sm-chatvideo-plugin/api/video.go, ../sm-chatvideo-plugin/api/call_links.go, ../sm-chatvideo-plugin/routes.go, ../sm-chatvideo-plugin/plugin.go, ../sm-chatvideo-plugin/boot.go, ../sm-chatvideo-plugin/README.md, ../sm-chatvideo-plugin/reconcile_test.go</files>
|
||||
<read_first>../sm-chatvideo-plugin/classes/video_service.go, ../sm-chat-plugin/classes/emit.go, ../sm-chat-plugin/jobs/maintain_thread_summary.go, ../sm-paymentgateway-plugin/schedule.go, /media/nvme/dev/jz/wavepath.org/plugins/golem15/chatvideo/classes/VideoCallNotifier.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/wavepath/console/ReconcileVideoSessions.php, /media/nvme/dev/jz/wavepath.org/plugins/golem15/wavepath/controllers/api/CommunityVideoController.php</read_first>
|
||||
<action>Per D-05, add leave, end, status on /_chatvideo/api/v1/conversations/{id}/video/{leave,end,status} and GET /_chatvideo/api/v1/call-links/{code} with bucket call-link 10/min. join_code alphabet abcdefghijklmnopqrstuvwxyz0123456789 length 10. Uniform 404 for unknown codes.
|
||||
|
||||
Per D-15, notifier publishes video:call:incoming to user:{id}; accepted/declined/ended and participant joined/left to video:session:{id}. Payload keys from RESEARCH. Publish failure is logged and not raised. Do not port host close-push extras.
|
||||
|
||||
Per D-14, Reconcile: if the LiveKit room is missing or empty, or started_at + max_duration elapsed, end the session, DeleteRoom (swallowed), emit video:call:ended. Command chatvideo:reconcile-sessions. Job Kind golem15.chatvideo.reconcile_sessions, MaxAttempts 1. Plugin.Schedule pact.Every(5 * time.Minute) on that command (5 minutes divides 24h). Keep only empty-or-gone room and max_duration. Drop host-only extras (guest rooms, chat cards, grace seconds) and the host command name.
|
||||
Per D-14, Reconcile: if the LiveKit room is missing or empty, or started_at + max_duration elapsed, end the session, DeleteRoom (swallowed), emit video:call:ended. Command chatvideo:reconcile-sessions. Job Kind golem15.chatvideo.reconcile_sessions, MaxAttempts 1. Plugin.Schedule pact.Every(5 * time.Minute) on that command (5 minutes divides 24h). Keep only empty-or-gone room and max_duration. Drop host-only extras (guest rooms, chat cards, grace seconds) and the host command name. Add TestReconcileEmptyRoom (short, RoomAPI fake): an active session whose fake room is missing or has ParticipantCount 0 is ended; a room that is still occupied stays active.
|
||||
|
||||
After APIs exist, note in the SUMMARY that execute should run the security-review agent (CONTEXT). Do not spawn it from this task.</action>
|
||||
<verify>
|
||||
<automated>go -C ../sm-chatvideo-plugin vet ./... && go -C ../sm-chatvideo-plugin test -count=1 -short ./...</automated>
|
||||
<fails_when>non-zero exit or a package reports FAIL</fails_when>
|
||||
<automated>go -C ../sm-chatvideo-plugin test -count=1 -short -run '^TestReconcileEmptyRoom$' .</automated>
|
||||
<fails_when>non-zero exit, or TestReconcileEmptyRoom is missing, or an empty/gone room stays active</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- grep -n 'chatvideo:reconcile-sessions' ../sm-chatvideo-plugin/console/reconcile.go prints one line.
|
||||
- grep -n 'golem15.chatvideo.reconcile_sessions' ../sm-chatvideo-plugin/jobs/reconcile.go prints one line.
|
||||
- grep -n 'Every(5' ../sm-chatvideo-plugin/schedule.go prints one line.
|
||||
- grep -n 'func TestReconcileEmptyRoom' ../sm-chatvideo-plugin/*.go prints one line.
|
||||
- grep -n 'GuestCall\|CallNotifier\|start_grace_seconds' ../sm-chatvideo-plugin/*.go ../sm-chatvideo-plugin/classes/*.go ../sm-chatvideo-plugin/jobs/*.go prints 0 lines.
|
||||
- grep -n 'call-links' ../sm-chatvideo-plugin/routes.go prints at least one line.
|
||||
</acceptance_criteria>
|
||||
@@ -272,7 +309,7 @@ After APIs exist, note in the SUMMARY that execute should run the security-revie
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
The note exists before go get. go -C ../sm-chatvideo-plugin test -short stays green including TestLiveKitTokenClaims and TestVideoAuthorizer. TestHTTPTracer proves one active session.
|
||||
The note exists before go get. go -C ../sm-chatvideo-plugin test -short stays green including TestLiveKitTokenClaims, TestVideoAuthorizer, and TestReconcileEmptyRoom. TestHTTPTracer proves one active session.
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
@@ -38,6 +38,7 @@ estimate:
|
||||
raw_tokens: 180000
|
||||
tasks: 3
|
||||
confidence: low
|
||||
# Estimates are uncalibrated (0 phase actuals). The user locked exactly this 6-plan split; do not split further. Stay tracer-then-expand inside this plan.
|
||||
must_haves:
|
||||
truths:
|
||||
- "SC-19.1-4 / D-04: each plugin has testdata/PHP_METHOD_MAP.md plus TestPHPMethodMap; counts are chatbots 22, forum 25, herald 14, userfriends 31, chatvideo 0 in-plugin (Wavepath host methods mapped to generic-API Go or explicit N/A)."
|
||||
@@ -90,7 +91,7 @@ This plan's slice (plan 6 of 6, wave 3): unit tests last — maps, goldens, `scr
|
||||
## Decisions taken in this plan (Claude's discretion)
|
||||
|
||||
- Gate env overrides: USERFRIENDS, FORUM, CHATBOTS, HERALD, CHATVIDEO (sibling checkouts).
|
||||
- Named short tests from RESEARCH/VALIDATION: TestBaseline ×5, TestHTTPTracer ×5, TestAccessResolverDefault, TestLiveKitTokenClaims, TestVideoAuthorizer, TestSubscribeEndpoint, TestNoGolem, TestNoUserfriendsImport, TestPHPMethodMap, TestFixtureAbsentFromProduction.
|
||||
- Named short tests from RESEARCH/VALIDATION: TestBaseline ×5, TestHTTPTracer ×5, TestAccessResolverDefault, TestLiveKitTokenClaims, TestVideoAuthorizer, TestReconcileEmptyRoom, TestSubscribeEndpoint, TestNoGolem, TestNoUserfriendsImport, TestPHPMethodMap, TestFixtureAbsentFromProduction.
|
||||
- Postgres stage: tracers + TestSendEventRollback + GDPR cascades.
|
||||
- Decision-note paths grepped for locked module path + version.
|
||||
- Execute should run the security-review agent after this plan (APIs + push + tokens + HTML + GDPR all exist). This planner does not spawn it.
|
||||
@@ -140,7 +141,7 @@ Analog:
|
||||
<precondition>Plans 01-05 have created the five sibling plugin roots with TestHTTPTracer and TestBaseline names.</precondition>
|
||||
<files>scripts/check-phase19.1.sh, ../sm-userfriends-plugin/testdata/PHP_METHOD_MAP.md, ../sm-userfriends-plugin/testdata/php_methods.txt, ../sm-userfriends-plugin/php_method_map_test.go</files>
|
||||
<read_first>scripts/check-phase19.sh, ../sm-chat-plugin/php_method_map_test.go, ../sm-chat-plugin/testdata/PHP_METHOD_MAP.md, .planning/phases/19.1-chat-satellites/19.1-VALIDATION.md</read_first>
|
||||
<action>Copy scripts/check-phase19.sh shape into scripts/check-phase19.1.sh. Stages: self-test, plugins, docs, postgres. Sibling env USERFRIENDS / FORUM / CHATBOTS / HERALD / CHATVIDEO defaulting to $ROOT/../sm-<name>-plugin. Fail-closed: a skip, miss, red, or "no tests to run" fails. --self-test plants JSON the detectors must refuse. Named short tests from VALIDATION (TestBaseline, TestHTTPTracer, TestNoGolem, TestNoUserfriendsImport, TestSubscribeEndpoint, TestLiveKitTokenClaims, TestVideoAuthorizer, TestAccessResolverDefault, TestPHPMethodMap, TestFixtureAbsentFromProduction). Postgres: the five tracers plus TestSendEventRollback and GDPR cascade names. Docs stage greps the three note paths for SherClockHolmes/webpush-go, livekit/server-sdk-go/v2, and the forum-policy bluemonday pin.
|
||||
<action>Copy scripts/check-phase19.sh shape into scripts/check-phase19.1.sh. Stages: self-test, plugins, docs, postgres. Sibling env USERFRIENDS / FORUM / CHATBOTS / HERALD / CHATVIDEO defaulting to $ROOT/../sm-<name>-plugin. Fail-closed: a skip, miss, red, or "no tests to run" fails. --self-test plants JSON the detectors must refuse. Named short tests from VALIDATION (TestBaseline, TestHTTPTracer, TestNoGolem, TestNoUserfriendsImport, TestSubscribeEndpoint, TestLiveKitTokenClaims, TestVideoAuthorizer, TestReconcileEmptyRoom, TestAccessResolverDefault, TestPHPMethodMap, TestFixtureAbsentFromProduction). Postgres: the five tracers plus TestSendEventRollback and GDPR cascade names. Docs stage greps the three note paths for SherClockHolmes/webpush-go, livekit/server-sdk-go/v2, and the forum-policy bluemonday pin.
|
||||
|
||||
Also write userfriends testdata/PHP_METHOD_MAP.md for all 31 PHP test methods (GroupPolicy, GroupVisibilityGate, GroupModels). Components and demo seeders are not-applicable (D-07). php_method_map_test.go copies the chat analog. This tracer proves the gate can require TestPHPMethodMap on one repo.</action>
|
||||
<verify>
|
||||
@@ -152,6 +153,7 @@ Also write userfriends testdata/PHP_METHOD_MAP.md for all 31 PHP test methods (G
|
||||
<acceptance_criteria>
|
||||
- grep -n 'USERFRIENDS' scripts/check-phase19.1.sh prints at least one line.
|
||||
- grep -n 'TestPHPMethodMap' scripts/check-phase19.1.sh prints at least one line.
|
||||
- grep -n 'TestReconcileEmptyRoom' scripts/check-phase19.1.sh prints at least one line.
|
||||
- wc -l ../sm-userfriends-plugin/testdata/PHP_METHOD_MAP.md is greater than 31.
|
||||
</acceptance_criteria>
|
||||
<done>The phase gate self-test refuses planted failures, and userfriends TestPHPMethodMap is green.</done>
|
||||
|
||||
@@ -593,29 +593,35 @@ app.Events.Listen[*userclasses.DeletingEvent](PluginID, p.onUserDeleting)
|
||||
| A3 | D-17 will export `Render`/`Purify` + named policy before forum execute | CONTEXT | Forum plan blocks if missing |
|
||||
| A4 | classify-confidence webfetch=LOW even `--verified` | seam output | Library versions are checkpoints inside locked names |
|
||||
|
||||
## Open Questions
|
||||
## Open Questions (RESOLVED)
|
||||
|
||||
1. **LiveKit JWT: SDK vs jwt/v5**
|
||||
1. **LiveKit JWT: SDK vs jwt/v5** (RESOLVED — plan 05)
|
||||
- What we know: PHP payload is explicit MapClaims [VERIFIED: LiveKitService.php:80-99]. Official Go samples use `auth.AccessToken`.
|
||||
- What's unclear: extra claims (`jti`, grant nesting).
|
||||
- Recommendation: first chatvideo task is a golden round-trip; pick mint path that matches PHP. Do not reopen D-13.
|
||||
- RESOLVED: plan 05 Task 3 `TestLiveKitTokenClaims`; prefer jwt/v5 MapClaims if SDK ToJWT fails the golden. D-13 stays locked.
|
||||
|
||||
2. **D-17 module shape**
|
||||
2. **D-17 module shape** (RESOLVED — plan 02)
|
||||
- What we know: not landed; must not be cabana or seaglass.
|
||||
- What's unclear: package name (beach-theme), whether `Purify` policies are a registry.
|
||||
- Recommendation: forum consumes whatever the quick task exports; document the call in the forum plan, do not specify the package name here.
|
||||
- RESOLVED: plan 02 Task 1 consumes whatever the `/msd-quick` task exports (`func Render(` / `func Purify(`) and does not name the package.
|
||||
|
||||
3. **Morph rewrite ownership**
|
||||
3. **Morph rewrite ownership** (RESOLVED — plan 02)
|
||||
- Discretion. Recommendation: forum owns `forum:rewrite-context-types` for `golem15_forum_categories.context_type`; chat already rewrites conversation context_type.
|
||||
- RESOLVED: plan 02 Task 4 ships `forum:rewrite-context-types` for `golem15_forum_categories.context_type`.
|
||||
|
||||
4. **chatvideo generic addressing**
|
||||
4. **chatvideo generic addressing** (RESOLVED — plan 05)
|
||||
- Discretion: conversation id vs context alias. Recommendation: **conversation id** as primary (`/_chatvideo/api/v1/conversations/{id}/video/...`) plus optional context lookup through chat's registry so Wavepath group-video payloads stay reproducible.
|
||||
- RESOLVED: plan 05 uses conversation id as primary plus optional context lookup through chat Registry.
|
||||
|
||||
5. **Herald NeutralHeraldProfile vs deny-all**
|
||||
5. **Herald NeutralHeraldProfile vs deny-all** (RESOLVED — plan 04)
|
||||
- PHP binds NeutralHeraldProfile + DenyAllPresenceGate. Go should keep both defaults. PresenceGate is the fail-closed send gate.
|
||||
- RESOLVED: plan 04 Task 4 keeps both defaults; PresenceGate DenyAll is the fail-closed send gate; NeutralHeraldProfile has no Warn.
|
||||
|
||||
6. **OBS-01 cooldown without Laravel Cache**
|
||||
6. **OBS-01 cooldown without Laravel Cache** (RESOLVED — plan 04)
|
||||
- PHP `Cache::add('obs:warn:herald.delivery', 1, 60)` [VERIFIED: PushSender.php:213]. Recommendation: process-local sync.Map 60s (PHP already has an in-process fallback [VERIFIED: PushSender.php:227-246]) plus optional cooler if already in the plugin test host. Do not add Redis as a herald dependency.
|
||||
- RESOLVED: plan 04 Task 4 uses process-local sync.Map 60s.
|
||||
|
||||
## Environment Availability
|
||||
|
||||
@@ -704,7 +710,7 @@ Five repos means a task that "finishes forum" is not evidence for herald. Nyquis
|
||||
|
||||
### Wave 0 Gaps
|
||||
|
||||
- [ ] Five repos: `go.mod` with `replace` to `../../../../summercms.go`, `plugin.go`, baseline, `harness_test.go` / `testmain_test.go`
|
||||
- [ ] Five repos: `go.mod` with `replace` to `../summercms.go` (sibling checkout; live measurement `sm-chat-plugin/go.mod:147`. The older `../../../../summercms.go` path is stale — that is for an app submodule mount, not these sibling repos), `plugin.go`, baseline, `harness_test.go` / `testmain_test.go`
|
||||
- [ ] `testdata/goldens/` per plugin (serializers, events, LiveKit JWT, forum HTML)
|
||||
- [ ] `acme` fixture plugin (test files only) where a context is needed (forum, userfriends adapter)
|
||||
- [ ] LiveKit `RoomAPI` + push `HTTPClient` fakes
|
||||
|
||||
@@ -66,7 +66,7 @@ Task IDs assume the research-recommended 6-plan split (confirm at the plan-count
|
||||
|
||||
## Wave 0 Requirements
|
||||
|
||||
- [ ] Five repos: `go.mod` with `replace` to `../../../../summercms.go`, `plugin.go`, baseline, `harness_test.go` / `testmain_test.go` (`flag.Parse` + `testing.Short`)
|
||||
- [ ] Five repos: `go.mod` with `replace` to `../summercms.go` (sibling checkout; live measurement `sm-chat-plugin/go.mod:147`. The older `../../../../summercms.go` path is stale — that is for an app submodule mount, not these sibling repos), `plugin.go`, baseline, `harness_test.go` / `testmain_test.go` (`flag.Parse` + `testing.Short`)
|
||||
- [ ] `testdata/goldens/` per plugin (serializers, events, LiveKit JWT, forum HTML)
|
||||
- [ ] `acme` fixture plugin (test files only) where a context is needed (forum, userfriends adapter)
|
||||
- [ ] LiveKit `RoomAPI` + push `HTTPClient` fakes
|
||||
|
||||
Reference in New Issue
Block a user