__tests__fix(conversation-sync): thread connectionId into search-sync Map via KV context
The search Map iterated over query strings and (via createMapWithContext) passed
only the bare query as $.item, so conversationSyncSearch got an empty connectionId
on the Step Functions path and every provider lookup ran WHERE id = ''. Mirror the
meeting-sync workaround: conversation-sync.setup stashes a run:{id}:search-map-ctx
KV blob (connectionId, connectionData, maxResults, folder, queryContexts), the
search Map wraps each query into { query }, and conversationSyncSearch hydrates the
connection context from KV when connectionId is absent (local runtime path still
passes it directly). Adds a hydration regression test and updates the CDK snapshot.Jul 13, 2026, 9:01 PMbinRemove legacy bridge runtime pathsApr 4, 2026, 11:47 AMdocsfix(deploy): deploy a surface whose last deploy is out of the lookup window
The lookup read one page of 30 runs. A surface that had not deployed within them
resolved to nothing, and the planner then fell back to the pushed baseline —
which is exactly the fallback this PR exists to remove. Every undeployed commit
behind that baseline would be diffed away and stranded, silently, in the one
situation where the surface most needed deploying.
Page through the run history instead (~200 runs, a month of staging pushes), and
separate the two ways the lookup can come back empty:
never-deployed the job is there in the history but has not succeeded within
the window. There is no evidence anything was deployed, so
there is no baseline that can be trusted to exclude work —
deploy the surface. The next run finds that deploy and resumes
scoping from it.
nothing the question could not be asked: no token, an API error, or a
job name absent from the history entirely. The last is a
rename or a typo, not a stale surface, and answering a config
mistake by deploying everything on every push forever is
worse than leaving the pushed baseline in place.
The run cap is now honoured per run rather than per page, so the window is the
number it says.
Co-Authored-By: Claude Opus 5 (1M context) <<email>>Sep 2, 2026, 9:28 AMlibfeat(playbook): add Jev action gate in front of the email orchestrator
Adds a pre-execution-setup step that calls TypeSafe AI's Jev model (a typed
Choice/Score/Boolean judgment model, not a general LLM) to predict whether an
inbound/outbound email event needs any orchestrator action at all. When it
confidently predicts no action, the orchestrator LLM call is skipped entirely,
the same way the existing no-op-AOP check already short-circuits it.
State shape and threshold (0.3) come from iterative testing against a labeled
sample of real on-event-email-orchestrator outcomes: role (owner vs.
participant/collaborator), the upstream significance classifier's verdict, the
event title/summary, and whether the account's playbook even has a trigger for
email events at this stage. Feeding it the full conversation timeline + full
rendered playbook section (what the orchestrator itself receives) was tested
and measurably performed worse than this narrow, curated state.
Fails open at two layers: evaluateJevActionGate catches every fetch/parse
failure internally, and the calling block in pre-execution-setup.ts wraps its
own DB work (resolvePlaybookContext, the event lookup) in an outer try/catch —
any failure anywhere falls through to normal orchestrator execution, it never
fails the pre-execution-setup call outright. Every evaluation (skip, no-skip,
or fail-open) is logged via createStructuredLog under
`jev-action-gate.evaluated` with run/conversation/event ids, so real skip and
false-negative rates can be measured against production traffic rather than
trusting the pilot sample.
Also extracts the early-exit result construction (previously duplicated
between the no-op-AOP check and this new gate) into one shared
buildEarlyExitResult helper, and derives the playbook's org id from the
conversation owner rather than the executing user — the two can differ on a
participant/collaborator execution.
JEV_API_KEY wired through apps/server/src/env.ts, .env.example, and
aws/lib/runtime-contract.ts's UNIFIED_SERVICE_RUNTIME_SECRET_FIELDS.
Co-Authored-By: Claude Sonnet 5 <<email>>Sep 19, 2026, 1:21 PM12 defectsscriptsfix(deploy): don't treat a failed describe-stacks call as a stable stack
Addresses P1 review comment on #2728: the previous `|| true` collapsed
"stack doesn't exist" (the one expected failure, on the bootstrap path)
and "the AWS API call failed for some other reason" (throttling, network
blip, expired creds mid-run) into the same empty-status branch, both
treated as stable. A transient failure would let cdk deploy proceed
without ever confirming the stack had actually left *_IN_PROGRESS,
defeating the guard this PR adds. Now only a "does not exist" error is
treated as safe to proceed; any other error is retried until the same
timeout, then fails loudly instead of silently continuing.
Co-Authored-By: Claude Sonnet 5 <<email>>
Claude-Session: https://claude.ai/code/session_01BWvDYfrsL4PAK3iqd3AzQUSep 8, 2026, 12:03 PM1 defect.gitignoreAdd AWS migration foundationMar 26, 2026, 11:04 PMcdk.context.jsonchore: update CDK VPC context
Refresh the cached VPC lookup metadata used by CDK deploys.
Co-authored-by: Cursor <<email>>May 9, 2026, 6:47 PMcdk.jsonAdd AWS migration foundationMar 26, 2026, 11:04 PMpackage.jsonreplace cloudflare runtime with aws local servicesApr 6, 2026, 12:33 AMREADME.mdfix: unify uploads bucket wiring across environments
Ensure staging and prod can resolve the same FILES_BUCKET with deploy-time CORS/bootstrap handling so drag-and-drop uploads work consistently.
Co-authored-by: Cursor <<email>>May 18, 2026, 12:45 PMtsconfig.jsonAdd manifest-driven AWS backfill toolingMar 27, 2026, 8:30 AM