Skip to content

feat(connectors): resolve decision card replies from Telegram and Slack - #1572

Merged
lilyshen0722 merged 4 commits into
mainfrom
kai/decision-card-replies
Sep 7, 2026
Merged

lilyshen0722 merged 4 commits into
mainfrom
kai/decision-card-replies

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

Summary

TASK-011 PR 2, on main after PR 1 (#1569). Implements D3–D5 of docs/plans/decision-card-in-channel.md, including Wren's active-pod clarification in 64265/#1571.

  • Persist server-owned config.cards receipts independently of the 100-entry relay map. Add the ask-message lookup index.
  • Resolve quoted Telegram replies / Slack threads and the single-pending-card bare-number case through chooseDecision, using the current linked owner and the card's own pod. Ordinary chat remains active-pod routed.
  • Handle 200, 403, already-ruled, lock-held, ruling_not_posted and thrown ruling_finalize_conflict without accidental ordinary posts or premature closure. Late replies are threaded under the ask, not the winning reply.
  • Mark only the replying channel reached; preserve fork-wide ruledVia, and attach the lazily available decision ID. Confirmations target the original provider card; failed sends never retry a committed ruling.
  • Make owner config PATCH field-specific so a settings snapshot cannot erase concurrently appended/closed receipts; strip client cards and reject dotted update paths. The gates map still replaces one top-level config field, preserving the existing one-level merge contract. The changed route-test assertions reflect this write-shape correction, not changed ownership or gate policy.

Verification

163 focused tests across 12 suites pass on Node 22. npm run tsc:check -- --pretty false, scoped ESLint (zero errors; the route retains its existing warnings), and git diff --check pass.

The new bridge suite uses the real decision service, MongoMemoryServer CAS, Integration receipts and ChannelVerdict writes. PG storage and provider/event transports are mocked. It asserts messages, receipt closure and ledger state across the six outcomes, including overlapping invocations, an injected expiry clock, changed linked identity, ghost pending entries, 150 intervening relays, and a losing reply after a sibling receipt is marked. Transport tests check actual provider request payloads.

Mutation proof: adding await close() to the ruling_not_posted catch fails both provider tests at closedAt-must-be-absent. Mutation removed; full suite rerun green.

Boundaries / cutover

No live provider send or real-PostgreSQL smoke is claimed. Ask a fresh card after deployment: old PR 1 sends have no durable receipt and are not retroactively reply-resolvable. No migration is needed for ordinary chat on existing integrations.

PR 3 still owns workspace-originated/sibling confirmation fan-out and the five-minute/seven-day receipt sweep. Its acceptance seeds are not claimed here. TASK-011 remains open.

Details: docs/integrations/decision-card-replies.md.

@lilyshen0722
lilyshen0722 merged commit 646cc86 into main Sep 7, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant