Skip to content

feat(lane-dispatch): council stances on dispatch packets before a fan-out - #339

Open
lidge-jun wants to merge 6 commits into
devfrom
feat/quorum-lane-council
Open

lidge-jun wants to merge 6 commits into
devfrom
feat/quorum-lane-council

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Nov 9, 2026 •

Copy link
Copy Markdown
Owner

Closes #338

Problem

When a coordinator fans work out across lanes, check-lane-packet.mjs only checks that each packet is coherent (lane id, branch and write-scope collisions, loop and merge authority). Two lanes with the same objective under different branches both validate, and so does a lane whose objective says "deploy", "publish", "post to Slack" or "wipe the state" when nothing in the packet declares that action. The coordinator finds the duplicate when two PRs fix the same thing, and the outbound action when it has already happened.

Change

check-lane-packet.mjs <set.json> --council adds deterministic role stances to every dispatch lane of a valid packet or set, after Quorum's council (rules.ts decide(), dedup.ts):

Role Stance
CEO hold when the lane has no work.objective
Reviewer reject when the normalized objective equals another lane's; hold at character-bigram Dice >= 0.8 or when one objective contains the other
QA keep; names the field that defines done
CSO hold when objective or criteria ask for merge, push, a PR, deploy, release, publish, send, destroy or pay (English and Korean) and the packet does not declare it

Any cut rejects, then any escalate holds, otherwise pass. pending/bound lanes are not evaluated but are peers a new lane must not repeat. Exit codes: 0 all pass, 2 any hold, 1 invalid or any reject. --json returns the validator's envelope plus council (rulesVersion, per-lane stances with stable rule ids). Without --council, output and exit codes are unchanged.

Example on a four-lane set:

[codexclaw lane-council] rules v1: pass=2 hold=2 reject=0 not-evaluated=0
  HOLD ci-flake-2: REVIEWER-NEAR-DUPLICATE (reviewer) objective is 83% similar to lane ci-flake: confirm they are separate slices
  HOLD docs: CSO-OUTBOUND-deploy (cso) "deploy" asks for deploy, which authority.outbound does not declare: the user decides before dispatch

Packets gain an optional authority.outbound list (deploy, release, publish, send, destroy, pay); merge, push and PR stay with their existing fields. A declared action records the user's answer; the council's pass is never treated as approval. lane-dispatch.md adds LANE-COUNCIL-01 (DEFAULT): run the council before creating two or more lanes, rewrite rejected lanes, settle CEO/Reviewer holds by sharpening objectives, and ask the user once for CSO holds.

Matching notes: word boundaries keep identifiers such as mergeLanes out. An English verb followed within two words by a code-only noun names code ("the delete endpoint", "send a request", "publish the type definitions", "pay attention"), as does a Korean action noun followed by a code noun ("결제 모듈", "게시판", "전송 속도"); nouns a real action also takes as its object (report, results, list, form) are kept off that list, so "send the error report to the vendor" holds. A negation that governs the verb ("do not merge", "make sure not to deploy", "merge is not allowed", "병합은 하지 마요") suppresses that one mention, so "do not merge until CI passes, then merge" still holds. Cache clearing holds because cxc-dev lists it as Destruction (ESCALATE). The 0.8 threshold comes from measured pairs: distinct slices scored 0.63-0.72, reworded copies 0.825-0.923 (devlog/_plan/261109_quorum_lane_council/000_plan.md).

Left out on purpose: Quorum's verdict memory reuse. In codexclaw an approval belongs to a person and a session, and a fuzzy match on an old verdict must not stand in for one.

Verification

  • Red first: node --test plugins/codexclaw/test/lane-council.test.mjs failed with ERR_MODULE_NOT_FOUND before lane-council.mjs existed; now 18 tests, 18 pass. The tests cover duplicates, near duplicates, containment, created-lane peers, every outbound category in English and Korean with and without its declaration, false-positive wording, adversarial wording from the review in both directions, negation scope, authority.outbound validation and the CLI exit codes and output.
  • node plugins/codexclaw/scripts/gate.mjs OK, node plugins/codexclaw/scripts/check-prompt-architecture.mjs OK, node plugins/codexclaw/scripts/sync-readme-badges.mjs ok, npm run build exit 0.
  • Review round 1 (fresh reviewer, GO-WITH-FIXES, 2 blockers on CSO precision) folded in 0cedf47 and f98fe2b; round 2 by the same reviewer: GO-WITH-FIXES (blockers=0), its one real class (deploy/delete of code objects passing) folded in the head commit; dispositions in devlog/_plan/261109_quorum_lane_council/010_review_round1.md. The adversarial tests failed before each fix.
  • npm test locally (at 84982d3): 3890 tests, 3883 pass, 5 skipped, 2 fail. Neither failure is from this change. gui/test/router.test.ts cannot resolve react because GUI dependencies are not installed in this worktree. lane-packet.test.mjs "a drifted value is reported as drift" fails the same way on dev with this change stashed, because it reads a local host artifact.

Risks

  • Matching is lexical. Semantic duplicates below 0.8 pass (two measured pairs at 0.58 and 0.765), and code wording such as "fix the delete endpoint" holds. A false hold costs one rewrite or question. RULES_VERSION and the rule ids make later tuning visible.
  • Advisory only, the same tier as the validator: nothing intercepts create_thread, and wording outside the packet fields escapes the CSO.
  • authority.outbound is validated without --council too, so a malformed list now fails. The field is new, so no existing packet carries it.

Hosted CI was green on 84982d3 (all legs and ci); the current head's run is in progress.

NOT RUN: full local npm test on the current head (focused council and lane-packet tests, gate and prompt-architecture run), Windows and macOS legs locally.

…-out (#338)

check-lane-packet.mjs --council gives each dispatch lane of a valid packet set deterministic CEO, Reviewer, QA and CSO stances after Quorum: duplicate objectives reject, near duplicates and undeclared outbound actions hold. Adds the optional authority.outbound packet field and LANE-COUNCIL-01.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T04:46:24.229473Z 84982d3 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added the enhancement New feature or request label Nov 9, 2026
…review)

Everyday dev wording (the delete endpoint, send a request, pay attention, 게시판) no longer holds; destroy, sent, emailed, gh pr create/merge, gh release create, land the changes and upload to prod now do. Negation covers not to, apostrophe-less contractions and is not allowed. authority.outbound refuses inherited names and repeats; councilLane throws a contract error without a lane id.
send the error report to the vendor and similar sentences hold again; pinned by a test.
…s code

Round 2 review: the two-word code-noun guard let "deploy the script to staging" and "delete the helpers directory" pass. Deploy and delete/destroy now use the next-word guard only.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant