Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
c261ee7
ref(conversations): Cut over to canonical event history
dcramer Jul 15, 2026
1fd8397
ref(conversations): Decouple reporting from Pi projection
dcramer Jul 15, 2026
ec2bc43
ref(conversations): Canonicalize visible message history
dcramer Jul 15, 2026
235099c
ref(conversations): Read visible history from events
dcramer Jul 15, 2026
5f72744
feat(conversations): Record correlated turn lifecycle
dcramer Jul 15, 2026
ac68fce
feat(conversations): Add immutable child lineage
dcramer Jul 15, 2026
8237be0
fix(migrations): Validate legacy adoption baseline
dcramer Jul 15, 2026
f2f9acb
feat(conversations): Compose shared child context
dcramer Jul 15, 2026
fede194
feat(conversations): Add safe reporting events
dcramer Jul 15, 2026
697ee29
feat(conversations): Cut reporting over to event history
dcramer Jul 15, 2026
766825d
ref(conversations): Remove lazy legacy history
dcramer Jul 15, 2026
3ceed61
docs(conversations): Clarify event log authority
dcramer Jul 15, 2026
1374d23
test(migrations): Apply lineage schema in event fixture
dcramer Jul 15, 2026
e0fd813
docs(migrations): Remove completed event plan
dcramer Jul 15, 2026
688fb9b
fix(dashboard): Preserve error and location semantics
dcramer Jul 15, 2026
721992c
ref(migrations): Remove dead event compatibility phase
dcramer Jul 15, 2026
2ff7285
ref(conversations): Remove speculative event machinery
dcramer Jul 15, 2026
45992bc
ref(api): Hide internal conversation epochs
dcramer Jul 15, 2026
e124305
ref(conversations): Trim redundant event storage
dcramer Jul 15, 2026
b099bf0
fix(migrations): Read usage role from event payload
dcramer Jul 15, 2026
415cdec
test(dashboard): Match profile activity horizon
dcramer Jul 15, 2026
7e9aa4e
fix(dashboard): Align mock feed with production roots
dcramer Jul 15, 2026
419874a
test(dashboard): Follow canonical child navigation
dcramer Jul 15, 2026
f8f5fc2
fix(dashboard): Correlate imported child outcomes
dcramer Jul 15, 2026
6df7502
ref(runtime): Remove obsolete child projection offset
dcramer Jul 15, 2026
552ef1c
ref(conversations): Simplify immutable lineage locking
dcramer Jul 15, 2026
86d9f4c
ref(dashboard): Remove unreachable transcript shapes
dcramer Jul 15, 2026
9e0e4e7
test(dashboard): Preserve activity tooltip coverage
dcramer Jul 15, 2026
6ef1c35
fix(dashboard): Search tool rows by name
dcramer Jul 15, 2026
f1f9ceb
ref(migrations): Collapse conversation event cutover
dcramer Jul 15, 2026
ecdb3c8
ref(migrations): Move event rewrite into SQL cutover
dcramer Jul 15, 2026
28f3a9c
test(evals): Focus transcript coverage on model behavior
dcramer Jul 15, 2026
738cf60
test(runtime): Trim redundant recovery coverage
dcramer Jul 15, 2026
9c9e82c
test(dashboard): Remove duplicate transcript assertions
dcramer Jul 15, 2026
6607d8f
docs(testing): Require distinct coverage ownership
dcramer Jul 16, 2026
5cc3795
feat(conversations): Correlate handoffs with tool calls
dcramer Jul 16, 2026
ccb4b7a
fix(conversations): Complete canonical transcript cutover
dcramer Jul 16, 2026
5625c83
ref(dashboard): Remove unused byte formatter
dcramer Jul 17, 2026
62474a5
fix(dashboard): Reconcile subagent drawer status
dcramer Jul 17, 2026
f7404d4
docs(migrations): Simplify migration guide
dcramer Jul 17, 2026
d4055bd
ref(api): collapse conversation detail route helpers
dcramer Jul 17, 2026
741b417
perf(runtime): Narrow conversation event reads
dcramer Jul 17, 2026
e4e7b26
perf(api): Read conversation detail directly from SQL
dcramer Jul 17, 2026
d05616f
fix(runtime): Bound compacted conversation reads
dcramer Jul 17, 2026
1d1f6ed
fix(upgrade): Normalize compacted suffix cursors
dcramer Jul 17, 2026
bf7a748
fix(conversations): Ignore duplicate append activity
dcramer Jul 17, 2026
2c81bd9
fix(conversations): Drop persisted tool arguments
dcramer Jul 17, 2026
36508ec
fix(api): Read conversation privacy with event payloads
dcramer Jul 17, 2026
2778e77
fix(conversations): Preserve canonical cutover after rebase
dcramer Jul 18, 2026
1d860bf
fix(conversations): Isolate canonical transcript cutover
dcramer Jul 18, 2026
17da788
fix(migrations): Align event cutover snapshot
dcramer Jul 18, 2026
aa734a6
test(dashboard): Remove deferred delivery fixtures
dcramer Jul 18, 2026
515289d
fix(migrations): Preserve historical snapshot
dcramer Jul 18, 2026
a8d10eb
fix(conversations): Record direct turn lifecycle
dcramer Jul 18, 2026
028b4e9
fix(runtime): Preserve resumed failure fallback
dcramer Jul 18, 2026
22c4b80
fix(migrations): Preserve compacted transcript suffix
dcramer Jul 18, 2026
5bae595
fix(migrations): Discover unindexed turn cursors
dcramer Jul 18, 2026
b063024
fix(migrations): Skip cursor cleanup after cutover
dcramer Jul 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .agents/skills/junior-qa/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,19 @@ pnpm --filter @sentry/junior exec vitest run tests/integration/mcp-oauth-callbac
For SQL conversation storage changes, verify the resumed turn rebuilds context
from SQL, not `thread-state` mirrors: conversation context must hydrate from
`junior_conversation_messages` (`hydrateConversationMessages`) and pi history
from `junior_agent_steps` (`loadProjection`). In those tests, transcripts
seeded only into `thread-state` must also be persisted to SQL
(`persistConversationMessages`) before the callback runs, and the resumed
agent-run input `conversationContext` must contain the SQL-seeded messages.
from `junior_conversation_events` through the Pi adapter (`loadProjection`). In
those tests, transcripts seeded only into `thread-state` must also be persisted
to SQL (`persistConversationMessages`) before the callback runs, and the
resumed agent-run input `conversationContext` must contain the SQL-seeded
messages.

## Failure Handling

If local chat fails because credentials are missing or expired, refresh the
environment when appropriate with `pnpm dev:env`, then rerun the same command.
If local chat fails with a `junior_conversation_messages` or
`junior_agent_steps` query error, the local Postgres schema predates the SQL
conversation storage cutover; run `pnpm cli -- upgrade`, then rerun.
`junior_conversation_events` query error, the local Postgres schema predates the
SQL conversation storage cutover; run `pnpm cli -- upgrade`, then rerun.
If Redis errors appear during ordinary local QA, check whether
`JUNIOR_STATE_ADAPTER=redis` was set; local chat normally defaults to memory
state.
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

34 changes: 20 additions & 14 deletions packages/docs/src/content/docs/cli/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,32 @@ The command takes no extra arguments.

- Move legacy `junior:conversation-work:*` Redis state into the newer conversation record and index state used by the durable worker and dashboard feed.
- Backfill retained conversation records into the shared Junior SQL database. The upgrade requires `DATABASE_URL`.
- Repair legacy token and estimated-cost rollups from durable SQL agent steps in bounded batches. Conversations that are active during the repair are left unchanged and can be repaired by rerunning the command after they become idle.
- Apply the SQL schema cutover and rewrite legacy Pi-message rows into canonical conversation events.
- Repair legacy token and estimated-cost rollups from durable SQL conversation events in bounded batches. Conversations that are active during the repair are left unchanged and can be repaired by rerunning the command after they become idle.

The migrations are idempotent: rerunning them skips records that were already moved, removes stale legacy index entries that no longer have a record, and upserts SQL conversation rows. The SQL conversation backfill copies a bounded legacy slice of Redis conversation metadata; after cutover, durable conversation metadata is written to SQL while Redis remains the transcript and execution/cache store.
The migrations are idempotent: rerunning them skips records that were already moved, removes stale legacy index entries that no longer have a record, and upserts SQL conversation rows. The conversation-history import paginates through every conversation in the retained activity index; orphaned or expired Redis keys outside that index are not treated as retained history. After cutover, SQL owns durable conversation metadata and event history.

## Vercel deploys
## Hard-cutover upgrade sequence

Run `junior upgrade` from the Vercel build command when the deployment has access to the same `REDIS_URL`, `JUNIOR_STATE_KEY_PREFIX`, and `DATABASE_URL` used by production.
The canonical conversation-event cutover is not rolling-compatible. Do not run it inside a Vercel build while the previous deployment can still accept work. Use this operator sequence:

Use a build command like:
1. Block new ingress and enqueueing while leaving the previous release's workers and continuation consumers running.
2. Let existing work drain, then verify that no turns remain running or awaiting resume.
3. Stop every old worker, queue consumer, and heartbeat. Keep the old deployment stopped for the rest of the procedure.
4. Run the upgrade from an operator environment with the production `REDIS_URL`, `JUNIOR_STATE_KEY_PREFIX`, and `DATABASE_URL`.
5. Confirm the history import and visible-message seal complete with no missing rows.
6. Run `junior check`, deploy the new release, and only then reopen ingress and start the new workers.

```bash
pnpm exec junior upgrade && pnpm build
```

For monorepos, keep the same prefix and replace the build command with the app-specific build:
Run the upgrade as a separate operator command:

```bash
pnpm exec junior upgrade && pnpm --filter <app> build
pnpm exec junior upgrade
pnpm exec junior check
```

This keeps schema creation and SQL backfills out of request handlers. Runtime code trusts that the deployment ran `junior upgrade`; if schema is missing, the deployment is misconfigured and should fail clearly.
The visible-message seal fails closed if resumable work remains. After the drain succeeds, the upgrade invalidates stale resume state before it resequences conversation history while preserving reporting summaries.

If the command exits nonzero, leave the deployment stopped, correct the reported state, and rerun it. Do not restart workers after only part of the sequence completes.

## Example output

Expand Down Expand Up @@ -81,8 +86,9 @@ Treat that as a deploy blocker for the affected environment. Check `REDIS_URL`,
After running the command:

1. Confirm the final log line includes `Junior upgrade complete`.
2. Confirm the migration summary has the expected `scanned` and `migrated` counts.
3. Run `pnpm exec junior check` before building or deploying the app.
2. Confirm `backfill-conversation-events-sql` scanned the complete retained activity index and did not stop at one page.
3. Confirm `backfill-conversation-visible-message-events` reports `missing=0`; this is the canonical-history seal.
4. Run `pnpm exec junior check` before building or deploying the app.

A nonzero `missing` count for `repair-conversation-usage` means retained SQL assistant messages did not contain usable, schema-safe usage values. Junior leaves those totals unchanged.

Expand Down
Loading
Loading