feat(logic): establish derived-activity engine and agent-session protocols
Today we reached a major architectural conclusion: project history shouldn't be stored, it should be derived. We rejected the overhead of a separate SQLite event store in favor of an O(N) snapshot-diffing engine that computes human-readable narratives directly from the issues.jsonl source of truth. Key Triumphs: - Implemented O(N) diffing algorithm in src/lib/snapshot-differ.ts that transforms raw JSONL into 16 distinct social event types. - Engineered a file-based persistence layer (src/lib/activity-persistence.ts) to solve the 'Next.js HMR Wiped My Memory' bug, ensuring project heartbeat survives server restarts. - Developed the agent-session data model that unifies Beads, Activity, and Cross-Agent Mail into a single 'Mission' context. Raw Honest Moment: We struggled for over an hour with 'missing history' before realizing that development-mode reloads were purging our in-memory buffers. The shift to a file-backed ring buffer was a reactive pivot that became a core project strength.
This commit is contained in:
parent
4f8f3006e9
commit
ab051952bd
12 changed files with 1923 additions and 27 deletions
57
tests/lib/activity.test.ts
Normal file
57
tests/lib/activity.test.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import { describe, it } from 'node:test';
|
||||
import assert from 'node:assert';
|
||||
import type { ActivityEvent, ActivityEventKind } from '../../src/lib/activity';
|
||||
|
||||
describe('Activity Event Model (bb-xhm.1)', () => {
|
||||
it('should support all 16 required transition types in ActivityEventKind', () => {
|
||||
const kinds: ActivityEventKind[] = [
|
||||
'created',
|
||||
'closed',
|
||||
'reopened',
|
||||
'status_changed',
|
||||
'priority_changed',
|
||||
'assignee_changed',
|
||||
'type_changed',
|
||||
'title_changed',
|
||||
'description_changed',
|
||||
'labels_changed',
|
||||
'dependency_added',
|
||||
'dependency_removed',
|
||||
'comment_added',
|
||||
'due_date_changed',
|
||||
'estimate_changed',
|
||||
'field_changed',
|
||||
];
|
||||
|
||||
assert.strictEqual(kinds.length, 16, 'Should have exactly 16 transition types');
|
||||
|
||||
// Verify specific important types are present
|
||||
assert.ok(kinds.includes('created'));
|
||||
assert.ok(kinds.includes('closed'));
|
||||
assert.ok(kinds.includes('reopened'));
|
||||
assert.ok(kinds.includes('comment_added'));
|
||||
});
|
||||
|
||||
it('should allow creating a valid ActivityEvent object', () => {
|
||||
const event: ActivityEvent = {
|
||||
id: 'evt-123',
|
||||
kind: 'status_changed',
|
||||
beadId: 'bb-1',
|
||||
beadTitle: 'Test Bead',
|
||||
projectId: 'proj-1',
|
||||
projectName: 'Test Project',
|
||||
timestamp: new Date().toISOString(),
|
||||
actor: 'zenchantlive',
|
||||
payload: {
|
||||
field: 'status',
|
||||
from: 'open',
|
||||
to: 'in_progress',
|
||||
},
|
||||
};
|
||||
|
||||
assert.strictEqual(event.kind, 'status_changed');
|
||||
assert.strictEqual(event.payload.field, 'status');
|
||||
assert.strictEqual(event.payload.from, 'open');
|
||||
assert.strictEqual(event.payload.to, 'in_progress');
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue