Add Slack post-to-X workflow - #22
Conversation
TheGreatAxios
left a comment
There was a problem hiding this comment.
Self-review (agent)
Verdict: Request changes
What this PR does
Adds starter/slack-post-to-x: one inference draft, deterministic validate/publish, Slack approval before a capability-gated X write. Defaults to dry-run (X_LIVE=1 required for live). Reuses the shared Corbits Tag workspace from the stack.
Also ships a stalled-session hardening for slack-approval-flow (see below) and branding/license touch-ups on sibling starters.
X write safety — looks good
- Dry-run unless
X_LIVEis exactly"1"; missing OAuth + live fails at config resolve - No auto-retry when X write outcome is unknown (network/body/id missing)
- Publish uses workflow
steps.policy.output, not editable card text - Effect + authorize:
x:postcapability, deny-by-default - Approval correlation:
approvalId+ message id + unset decision; decision set before signal
Findings that block merge
| Severity | Finding |
|---|---|
| major | Commit cef0c3f added approval-flow session tests (failed draft, timeout, stale action); 0a2d4f6 deletes them. Production fix ships with no regression coverage — please restore. |
| major | New post-to-x starter has zero tests on the highest-risk write path (dry-run, unknown outcome, validation, authorize deny, session decide). |
| major (scope) | Branding rename (interchange → corbits*) and MIT → LGPL-2.1-only on sibling starters are not needed for post-to-X. Split into their own PR or drop from this stack. |
Other findings
| Severity | Finding |
|---|---|
| minor | post-to-x did not inherit the stalled-session hardening applied to approval-flow (draft timeout, failed-draft observer, ephemeral on stale approve). The write-capable starter is the more important place for it. |
| minor | bun.lock is committed while listed in .gitignore (confusing for contributors). |
| history | Revert/reapply/merge thrash + triple branding commits — please squash before merge. |
Stalled-session hardening (what landed on approval-flow)
Before this PR, a draft that never finished or failed quietly could leave the thread’s active map entry stuck, and stale Approve/Reject buttons did nothing with no user feedback. This PR adds:
- 60s draft timeout — fails the wait instead of hanging forever
- Draft failure observer — draft step errors surface instead of racing only on success
- Ephemeral on unavailable actions — “This approval is no longer active.”
- Clearer map ownership (
clear(pending)) so a failed run frees the thread
That production change is good; the deleted tests are what make it a request-changes.
Residual risks (documented, OK for a demo)
- Process-local effect ledger +
activemap: after restart old buttons are ignored, but a new live run of the same text after an unknown X outcome can still double-post — operator must inspect X first - Any channel member who can click Approve can publish live (no requester/role check)
Checks
- Full incremental review of 27 files (+1890/−48)
- Read of
x-client.ts,actions.ts,session.ts,workflow.ts,post.ts+ approval-flow session delta - Commit graph verified for test add/delete
Please restore the approval-flow tests, add minimal post-to-x coverage (or justify omission), and move branding/LGPL out of this PR — then happy to re-review.
16e5a1e to
5e63e7f
Compare
TheGreatAxios
left a comment
There was a problem hiding this comment.
Review · Approve
Adds starter/slack-post-to-x: one inference draft, deterministic validate/publish, Slack approval before a capability-gated X write (dry-run default). Also hardens stalled approval sessions on slack-approval-flow with tests, and ports the same session hardening to the write-capable starter.
Findings
None that block merge.
Prior request-changes (resolved)
- Approval-flow session tests restored (
session.test.ts);bun test→ 3 pass - Write-path coverage added in
x-client.test.ts(dry-run default, live OAuth gate, unknown outcome not retried);bun test→ 4 pass - Branding/LGPL scope creep gone from this fork head vs base
- Post-to-x now has draft timeout, failed-draft surface, ephemeral on stale actions
bun.lockno longer gitignored while committed
Checks
- Diff vs
agent/use-corbits-tag-for-slack-workflow(21 files, +2114/−34); no unexpected binaries - 4 commits, plain-English subjects, bodies empty, none over 72 chars
bun install --frozen-lockfile,bun run typecheck,bun run start --helpinslack-post-to-xbun test+typecheckinslack-approval-flow
Residual (documented / acceptable for a starter)
- Process-local
activemap and effect ledger: restart invalidates old buttons; operator must inspect X after an unknown live outcome before re-running - Any channel member who can click Approve can publish when live
- Validation failures surface under “Workflow failed” rather than the unused “Validation failed” branch in
session.ts(validationErroris set but the reject path never reaches that card) - Post-to-x session correlation path is untested (write safety is covered in
x-client.test.ts; approval-flow has the session suite)
3d69c08
into
corbitsdev:agent/use-corbits-tag-for-slack-workflow
Summary
Stack
Depends on #15 and targets its head branch,
agent/use-corbits-tag-for-slack-workflow.This branch is authored directly on top of PR #15's head commit,
7bd009c1aa58737e490c5ab00f24ee45ee0fa66c.Verification
bun install --frozen-lockfilebun run typecheckbun run start --helptwitter-textdependencyNo live Slack or X request was made.