feat: shared supervisor timeline, story assignment and time-spiral view

Each source version is extracted once for every review scope; events carry spans and projects from their sources, and attention density is counted from messages. After publication, events are assigned to project features and sub-threads (cross-project stories only when enabled), with user rename, merge, remove, move and undo. The story graph gains a lazily loaded Three.js time-spiral view. Includes the 3D concept demo, real-data DeepSeek check scripts and docs.
This commit is contained in:
mesalogo
2026-10-02 15:21:48 +08:00
parent 3d4e9577b5
commit 5dc65457d9
53 changed files with 4051 additions and 83 deletions
@@ -330,11 +330,11 @@ it('resolves a supplied source token to its unique input fragment without expand
for (const batch of batches) expect(batch.output.events[0]!.sourceReferenceIds).toEqual([batch.evidence[0]!.id])
})
it('continues an existing schema-46 automatic checkpoint without rereading its successful prefix', async () => {
it('continues an existing automatic timeline checkpoint without rereading its successful prefix', async () => {
const f = await fixture([['x'.repeat(3300)]], { concurrency: 1 })
const old = f.db.collectIncrementalReview({ ...request, trigger: 'heartbeat' }, 'supervisor')
const checkpoint = old.checkpoints[0]!
f.sql.prepare('INSERT INTO review_checkpoints VALUES (?, ?, ?, ?, ?, ?)').run('supervisor', old.scope,
f.sql.prepare('INSERT INTO review_checkpoints VALUES (?, ?, ?, ?, ?, ?)').run('supervisor', 'timeline',
checkpoint.source, checkpoint.revision, checkpoint.offset, checkpoint.length)
const result = await f.service().run({ ...request, trigger: 'heartbeat' })
const evidence = f.db.supervisionReviewStore().batches(result.runId!).flatMap(batch => batch.evidence)