feat(platform): generic category_routing replaces hardcoded audit dispatch (#51) - #75
Merged
Merged
Conversation
…patch (#51) Add a category_routing block to org.yaml schema (defaults + per-workspace, UNION semantics with per-key replace). The merged routing table is rendered into each workspace's config.yaml at import time. PM's system prompt loses the hardcoded security/ui/infra → role mapping from PR #50; instead it reads category_routing from /configs/config.yaml and delegates to whatever roles the org template lists for the incoming audit-summary's category. Future org templates ship their own routing without prompt churn. Tests: 4 new TestCategoryRouting_* cases covering YAML parse, UNION+drop semantics, deterministic config.yaml render, and empty-map handling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
HongmingWang-Rabbit
marked this pull request as ready for review
April 14, 2026 21:07
… appends Addresses code-review warnings on PR #75: - renderCategoryRoutingYAML now builds yaml.Node + yaml.Marshal, escaping YAML-reserved chars in role names correctly (was JSON-as-YAML, fragile on unicode line separators). - New appendYAMLBlock helper guarantees a newline boundary when concatenating YAML fragments into config.yaml (category_routing + initial_prompt both used to risk merging into the previous line). - Fixed struct comment (replace-per-key, not UNION). - Added TestCategoryRouting_EscapesYAMLSpecials and TestAppendYAMLBlock_NewlineGuard. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 14, 2026
- CLAUDE.md: Go test count 731 → 740; migration count 16 → 23; workspace_schedules.source column documented in Database section. - PLAN.md: new "Recently launched (2026-04-14 tick-7)" section for PRs #74/#75/#76 and closed issues #24/#51. - docs/edit-history/2026-04-14.md: per-PR breakdown of tick-7 merges. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3 tasks
HongmingWang-Rabbit
added a commit
that referenced
this pull request
Apr 15, 2026
…te / channels Today's crons are all REVIEW (Security audit, UIUX audit, QA tests). Nothing actively pushes the team to EVOLVE the four levers CEO named: templates, plugins, channels, watchlist. The team-runs-24/7 goal needs both — defensive reviews AND offensive evolution. Adds 4 new schedules: 1. Research Lead — Daily ecosystem watch (0 8 * * *) Survey github.com/trending + HN + AI-blogs for new agent-infra projects from the last 24h. Add 1-3 entries to docs/ecosystem-watch.md per day, commit to chore/eco-watch-YYYY-MM-DD branch + push + PR. Re-enables the watchlist pipeline that was paused earlier today. 2. Technical Researcher — Weekly plugin curation (0 9 * * 1, Mondays) Inventory plugins/ + builtin_tools/ + recent landings. Identify gaps (builtin not exposed as plugin; role missing extras; rarely-used plugin in defaults). Survey upstream (claude.ai cookbook, MCP servers, anthropic/openai/langchain blogs). File 1-3 plugin proposals per week as GH issues with concrete integration sketches. 3. Dev Lead — Daily template fitness audit (30 8 * * *) Health-check the template itself: stale system prompts, schedules not firing (catches the #85 scheduler-died failure mode), roles missing plugins they should have, missing crons, channel gaps. File issues for any drift. Designed to catch the silent-stall pattern from today's incident. 4. DevOps Engineer — Weekly channel expansion survey (0 10 * * 1, Mondays) PM is the only role with a channel today (Telegram). Survey what channel infra the platform supports + what role-channel pairings would actually help (Security→email-on-critical, DevOps→Slack-on-CI-break, etc). File channel-proposal issues. All four crons end with the structured audit_summary routing per #51/#75 (category, severity, issues, top_recommendation) so they integrate with the platform-level category_routing PM uses to fan out work. The template's existing category_routing block already maps research / plugins / template / channels — these new crons consume exactly those slots. Also drops three stale "# UNION with defaults (#71)" comments left from the cleanup PR — those plugins lists are now self-documenting after #71. Aligns with north-star goal: team should run 24/7 AND keep getting better across templates / plugins / channels / watchlist. This PR closes the gap where the "review" half of the loop was running but the "evolve" half had no active driver.
This was referenced Apr 15, 2026
HongmingWang-Rabbit
added a commit
that referenced
this pull request
Apr 15, 2026
…ch PM Found via deep workspace inspection during a maintenance cycle: Security Auditor's hourly cron correctly tries to delegate_task its audit_summary to PM, the platform proxy rejects with "access denied: workspaces cannot communicate per hierarchy", the agent falls back to delegating to its direct parent (Dev Lead), and PM's category_routing dispatcher (#75) is never reached. This breaks the audit-routing contract end-to-end. Every audit cycle was landing on Dev Lead instead of being fanned out via PM's category_routing to the right dev role (security → BE+DevOps, ui/ux → FE, etc). ## Root cause `registry.CanCommunicate()` only allowed: - self → self - siblings (same parent) - root-level siblings - direct parent → child - direct child → parent A grandchild → grandparent (Security Auditor → PM, where parent is Dev Lead and grandparent is PM) was DENIED. The original design wanted strict hierarchy to prevent rogue horizontal A2A — but it also broke the fundamental "child can talk to its leadership chain" pattern that any audit/escalation flow needs. ## Fix Generalise to ancestor ↔ descendant. Any workspace can talk to any ancestor (any depth) and any descendant (any depth). Direct parent/child remains a fast path that avoids the walk. Sibling rules unchanged. Cousins still cannot directly communicate (would need to go through their shared ancestor). Cross-subtree A2A is still rejected. Implementation: `isAncestorOf(ancestorID, childID)` walks the parent chain in Go with a maxAncestorWalk=32 safety cap so a malformed cycle in the workspaces table cannot loop forever. One DB lookup per step. For a typical 3-deep tree, this adds 1-2 extra lookups vs the old direct-parent fast path. Could be optimized to a single recursive CTE if profiling shows it matters; not now. ## Tests - TestCanCommunicate_Denied_Grandchild → REPLACED with two new tests: - TestCanCommunicate_Allowed_GrandparentToGrandchild - TestCanCommunicate_Allowed_GrandchildToGrandparent (the actual bug) - TestCanCommunicate_Allowed_DeepAncestor — 4-level chain - TestCanCommunicate_Denied_UnrelatedAncestors — ensures cross-subtree walks still terminate denied - TestCanCommunicate_Denied_DifferentParents — extended with the walk lookup mocks so sqlmock doesn't log warnings - TestCanCommunicate_Denied_CousinToRoot — same All 13 tests pass clean. The previous direct parent/child / siblings / self tests are unchanged (fast paths preserved). ## Why platform-level Per the "platform-wide fixes are mine to ship" rule. Every org template hits the same broken audit-routing chain — fixing it at the platform benefits all users, not just molecule-dev. This unblocks #50 (PM dispatcher prompt) and #75 (category_routing).
This was referenced Apr 15, 2026
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
… appends Addresses code-review warnings on PR #75: - renderCategoryRoutingYAML now builds yaml.Node + yaml.Marshal, escaping YAML-reserved chars in role names correctly (was JSON-as-YAML, fragile on unicode line separators). - New appendYAMLBlock helper guarantees a newline boundary when concatenating YAML fragments into config.yaml (category_routing + initial_prompt both used to risk merging into the previous line). - Fixed struct comment (replace-per-key, not UNION). - Added TestCategoryRouting_EscapesYAMLSpecials and TestAppendYAMLBlock_NewlineGuard. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
feat(platform): generic category_routing replaces hardcoded audit dispatch (#51)
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
- CLAUDE.md: Go test count 731 → 740; migration count 16 → 23; workspace_schedules.source column documented in Database section. - PLAN.md: new "Recently launched (2026-04-14 tick-7)" section for PRs #74/#75/#76 and closed issues #24/#51. - docs/edit-history/2026-04-14.md: per-PR breakdown of tick-7 merges. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
…te / channels Today's crons are all REVIEW (Security audit, UIUX audit, QA tests). Nothing actively pushes the team to EVOLVE the four levers CEO named: templates, plugins, channels, watchlist. The team-runs-24/7 goal needs both — defensive reviews AND offensive evolution. Adds 4 new schedules: 1. Research Lead — Daily ecosystem watch (0 8 * * *) Survey github.com/trending + HN + AI-blogs for new agent-infra projects from the last 24h. Add 1-3 entries to docs/ecosystem-watch.md per day, commit to chore/eco-watch-YYYY-MM-DD branch + push + PR. Re-enables the watchlist pipeline that was paused earlier today. 2. Technical Researcher — Weekly plugin curation (0 9 * * 1, Mondays) Inventory plugins/ + builtin_tools/ + recent landings. Identify gaps (builtin not exposed as plugin; role missing extras; rarely-used plugin in defaults). Survey upstream (claude.ai cookbook, MCP servers, anthropic/openai/langchain blogs). File 1-3 plugin proposals per week as GH issues with concrete integration sketches. 3. Dev Lead — Daily template fitness audit (30 8 * * *) Health-check the template itself: stale system prompts, schedules not firing (catches the #85 scheduler-died failure mode), roles missing plugins they should have, missing crons, channel gaps. File issues for any drift. Designed to catch the silent-stall pattern from today's incident. 4. DevOps Engineer — Weekly channel expansion survey (0 10 * * 1, Mondays) PM is the only role with a channel today (Telegram). Survey what channel infra the platform supports + what role-channel pairings would actually help (Security→email-on-critical, DevOps→Slack-on-CI-break, etc). File channel-proposal issues. All four crons end with the structured audit_summary routing per #51/#75 (category, severity, issues, top_recommendation) so they integrate with the platform-level category_routing PM uses to fan out work. The template's existing category_routing block already maps research / plugins / template / channels — these new crons consume exactly those slots. Also drops three stale "# UNION with defaults (#71)" comments left from the cleanup PR — those plugins lists are now self-documenting after #71. Aligns with north-star goal: team should run 24/7 AND keep getting better across templates / plugins / channels / watchlist. This PR closes the gap where the "review" half of the loop was running but the "evolve" half had no active driver.
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
…ch PM Found via deep workspace inspection during a maintenance cycle: Security Auditor's hourly cron correctly tries to delegate_task its audit_summary to PM, the platform proxy rejects with "access denied: workspaces cannot communicate per hierarchy", the agent falls back to delegating to its direct parent (Dev Lead), and PM's category_routing dispatcher (#75) is never reached. This breaks the audit-routing contract end-to-end. Every audit cycle was landing on Dev Lead instead of being fanned out via PM's category_routing to the right dev role (security → BE+DevOps, ui/ux → FE, etc). ## Root cause `registry.CanCommunicate()` only allowed: - self → self - siblings (same parent) - root-level siblings - direct parent → child - direct child → parent A grandchild → grandparent (Security Auditor → PM, where parent is Dev Lead and grandparent is PM) was DENIED. The original design wanted strict hierarchy to prevent rogue horizontal A2A — but it also broke the fundamental "child can talk to its leadership chain" pattern that any audit/escalation flow needs. ## Fix Generalise to ancestor ↔ descendant. Any workspace can talk to any ancestor (any depth) and any descendant (any depth). Direct parent/child remains a fast path that avoids the walk. Sibling rules unchanged. Cousins still cannot directly communicate (would need to go through their shared ancestor). Cross-subtree A2A is still rejected. Implementation: `isAncestorOf(ancestorID, childID)` walks the parent chain in Go with a maxAncestorWalk=32 safety cap so a malformed cycle in the workspaces table cannot loop forever. One DB lookup per step. For a typical 3-deep tree, this adds 1-2 extra lookups vs the old direct-parent fast path. Could be optimized to a single recursive CTE if profiling shows it matters; not now. ## Tests - TestCanCommunicate_Denied_Grandchild → REPLACED with two new tests: - TestCanCommunicate_Allowed_GrandparentToGrandchild - TestCanCommunicate_Allowed_GrandchildToGrandparent (the actual bug) - TestCanCommunicate_Allowed_DeepAncestor — 4-level chain - TestCanCommunicate_Denied_UnrelatedAncestors — ensures cross-subtree walks still terminate denied - TestCanCommunicate_Denied_DifferentParents — extended with the walk lookup mocks so sqlmock doesn't log warnings - TestCanCommunicate_Denied_CousinToRoot — same All 13 tests pass clean. The previous direct parent/child / siblings / self tests are unchanged (fast paths preserved). ## Why platform-level Per the "platform-wide fixes are mine to ship" rule. Every org template hits the same broken audit-routing chain — fixing it at the platform benefits all users, not just molecule-dev. This unblocks #50 (PM dispatcher prompt) and #75 (category_routing).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #51 per CEO direction (resolve root, don't hardcode).
Change
category_routingblock inorg.yamlschema — underdefaults:AND per-workspaceconfig.yamlat import time (deterministic, sorted-key YAML)org-templates/molecule-dev/org.yamlships the existingsecurity / ui / ux / infra / qa / performance / mixedmappings underdefaults.category_routingorg-templates/molecule-dev/pm/system-prompt.mdloses the hardcodedsecurity→BE / ui→FE / infra→DevOpsblock from PR chore(template): PM system prompt — treat audit summaries as dispatch triggers, not FYIs #50 — replaced with generic "look up category in/configs/config.yamlcategory_routing, delegate to listed roles, log misses"Why
PR #50's hardcoded mapping breaks every time someone adds, renames, or removes a role; and every other org template would have to re-author the same prompt section. Pushing the mapping into config means each org template owns its own routing and the PM prompt is identical across orgs.
Test plan
TestCategoryRouting_*cases inorg_test.go(parse, UNION+drop, render, empty)go test -race ./...greenorg.yamlships the same categories the old hardcoded prompt covered (subtractive change in the prompt)🤖 Generated with Claude Code