Skip to content

feat(api): wire extractCommitments into the live digest (#475)#500

Merged
jayzalowitz merged 1 commit into
mainfrom
auto/issue-475
Jun 15, 2026
Merged

feat(api): wire extractCommitments into the live digest (#475)#500
jayzalowitz merged 1 commit into
mainfrom
auto/issue-475

Conversation

@jayzalowitz

Copy link
Copy Markdown
Owner

What changed

Wires the previously-unconsumed extractCommitments rule extractor (built + tested in packages/decision-engine/src/commitment-extractor.ts under #484) into the live digest path, so the user's OWN stated commitments surface as to-dos.

apps/api/src/services/live-digest.ts (buildLiveDigest) now, for every decision whose underlying signal the user authored (SignalText.authoredByUser), runs extractCommitments(signalText) and turns each distinct commitment into a to-do DigestItem. A phrasing like "I'll send over the draft tomorrow" in a sent email becomes a first-class to-do.

Each commitment to-do:

  • carries ActionProvenance = user_originated (highest trust) in its power-view detail
  • gets an explanation citing the user's verbatim sentence (rawSpan) — safety invariant Make SkyTwin usable by a non-technical person end-to-end #2
  • forwards the raw deadlineHint when present (null otherwise)
  • uses a synthetic unique ref <decisionId>#commit-N so it never collides with the decision's own digest item

Security boundary holds (safety invariant #8): extractCommitments itself gates on authoredByUser AND the capability×source matrix, so inbound "you agreed to X" content (a poisoning vector) is never read for commitments. Provenance is never weakened to a default. Restated commitments collapse to one to-do. Extraction is on by default and pure-when-off behind the issue's rollback flag COMMITMENT_EXTRACTION=off; any extractor throw is caught so it can never break the digest.

Acceptance criteria

Tests added

Four new integration cases in apps/api/src/__tests__/live-digest.test.ts:

  1. user-authored commitments → from-you to-dos with citation + deadline hint
  2. identical phrasing on inbound content → no commitment to-do (gating)
  3. same-body restatement → one to-do (dedup)
  4. COMMITMENT_EXTRACTION=off → no commitment to-dos (rollback flag)

Verification

Run in an isolated worktree (no install/build permitted) using a source-alias vitest config and source-path tsc:

  • live-digest.test.ts: 12/12 pass (8 prior + 4 new)
  • commitment-extractor.test.ts (decision-engine): 10/10 pass
  • tsc --noEmit on live-digest.ts against the @skytwin/* source chain: 0 type errors

Closes #475

🤖 Generated with Claude Code

Surface the user's OWN stated commitments ("I'll send the draft tomorrow")
from authored content (sent mail, calendar descriptions, voice notes) as
first-class to-dos in the daily digest.

`extractCommitments` was built + tested in
packages/decision-engine/src/commitment-extractor.ts under #484 but never
consumed in the live path. buildLiveDigest now runs it over every decision
whose underlying signal the user authored (SignalText.authoredByUser) and
turns each distinct commitment into a to-do DigestItem.

Each commitment to-do:
- carries ActionProvenance = user_originated (highest trust)
- gets an ExplanationRecord citing the user's verbatim sentence (rawSpan)
  (safety invariant #2)
- forwards the raw deadlineHint when present
- uses a synthetic unique ref (<decisionId>#commit-N) so it never collides
  with the decision's own digest item

Security boundary holds (safety invariant #8): extractCommitments gates on
authoredByUser AND the capability x source matrix, so inbound "you agreed to
X" content is never read for commitments. Restated commitments collapse to
one to-do. Extraction is on by default, pure-when-off behind the rollback
flag COMMITMENT_EXTRACTION=off, and any extractor throw is caught so it can
never break the digest.

Tests: 4 new live-digest integration cases — happy path (two commitments ->
two from-you to-dos with citation + deadline hint), gating fallback
(identical phrasing on inbound content -> no to-do), same-body restatement
dedup, and the rollback flag. All 12 live-digest tests pass; the file
type-checks clean against the @Skytwin source chain.

Closes #475

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 15, 2026 04:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR wires the existing extractCommitments rule extractor into the API’s live-digest generation so that commitments explicitly stated by the user in authored content (e.g., sent email / authored calendar descriptions / voice notes) appear as first-class digest to-dos, with “from you” provenance and source-sentence citation.

Changes:

  • Invoke extractCommitments(signalText) during buildLiveDigest for user-authored signals and emit one digest to-do per distinct commitment, with synthetic refs (<decisionId>#commit-N) and power-view detail.
  • Add a rollback flag (COMMITMENT_EXTRACTION=off) that disables commitment extraction and prevents extractor invocation.
  • Add four integration tests covering: happy path, inbound gating, same-body dedup, and rollback behavior; update changelog entry.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
CHANGELOG.md Documents commitment to-dos being wired into the live digest path and lists behavior guarantees/rollback flag.
apps/api/src/services/live-digest.ts Generates commitment-based to-dos from authored SignalText and attaches power-view detail; adds env-flag gate.
apps/api/src/tests/live-digest.test.ts Adds integration coverage for commitment to-dos, authored-only gating, dedup behavior, and rollback flag.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 417 to 419
});

// Coverage for the power-view panel, from the user's connected accounts.
@jayzalowitz jayzalowitz merged commit efeaa36 into main Jun 15, 2026
10 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.

Commitment extraction from user-authored content

2 participants