agent-relay 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -6
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +344 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/daemon/agent-registry.d.ts +60 -0
- package/dist/daemon/agent-registry.d.ts.map +1 -0
- package/dist/daemon/agent-registry.js +158 -0
- package/dist/daemon/agent-registry.js.map +1 -0
- package/dist/daemon/connection.d.ts +11 -1
- package/dist/daemon/connection.d.ts.map +1 -1
- package/dist/daemon/connection.js +31 -2
- package/dist/daemon/connection.js.map +1 -1
- package/dist/daemon/index.d.ts +2 -0
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +2 -0
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/registry.d.ts +9 -0
- package/dist/daemon/registry.d.ts.map +1 -0
- package/dist/daemon/registry.js +9 -0
- package/dist/daemon/registry.js.map +1 -0
- package/dist/daemon/router.d.ts +34 -2
- package/dist/daemon/router.d.ts.map +1 -1
- package/dist/daemon/router.js +111 -1
- package/dist/daemon/router.js.map +1 -1
- package/dist/daemon/server.d.ts +1 -0
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +60 -13
- package/dist/daemon/server.js.map +1 -1
- package/dist/dashboard/public/index.html +625 -16
- package/dist/dashboard/server.d.ts +1 -1
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +125 -7
- package/dist/dashboard/server.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/protocol/types.d.ts +15 -1
- package/dist/protocol/types.d.ts.map +1 -1
- package/dist/storage/adapter.d.ts +53 -0
- package/dist/storage/adapter.d.ts.map +1 -1
- package/dist/storage/adapter.js +3 -0
- package/dist/storage/adapter.js.map +1 -1
- package/dist/storage/sqlite-adapter.d.ts +58 -1
- package/dist/storage/sqlite-adapter.d.ts.map +1 -1
- package/dist/storage/sqlite-adapter.js +374 -47
- package/dist/storage/sqlite-adapter.js.map +1 -1
- package/dist/utils/project-namespace.d.ts.map +1 -1
- package/dist/utils/project-namespace.js +22 -1
- package/dist/utils/project-namespace.js.map +1 -1
- package/dist/wrapper/client.d.ts +22 -3
- package/dist/wrapper/client.d.ts.map +1 -1
- package/dist/wrapper/client.js +59 -9
- package/dist/wrapper/client.js.map +1 -1
- package/dist/wrapper/parser.d.ts +110 -4
- package/dist/wrapper/parser.d.ts.map +1 -1
- package/dist/wrapper/parser.js +296 -84
- package/dist/wrapper/parser.js.map +1 -1
- package/dist/wrapper/tmux-wrapper.d.ts +100 -9
- package/dist/wrapper/tmux-wrapper.d.ts.map +1 -1
- package/dist/wrapper/tmux-wrapper.js +441 -83
- package/dist/wrapper/tmux-wrapper.js.map +1 -1
- package/docs/AGENTS.md +27 -27
- package/docs/CHANGELOG.md +1 -1
- package/docs/DESIGN_V2.md +1079 -0
- package/docs/INTEGRATION-GUIDE.md +926 -0
- package/docs/PROPOSAL-trajectories.md +1582 -0
- package/docs/PROTOCOL.md +3 -3
- package/docs/SCALING_ANALYSIS.md +280 -0
- package/docs/TMUX_IMPLEMENTATION_NOTES.md +9 -9
- package/docs/TMUX_IMPROVEMENTS.md +968 -0
- package/docs/competitive-analysis-mcp-agent-mail.md +389 -0
- package/package.json +6 -2
|
@@ -0,0 +1,1582 @@
|
|
|
1
|
+
# Train of Thought Trajectories: Design Proposal
|
|
2
|
+
|
|
3
|
+
## Executive Summary
|
|
4
|
+
|
|
5
|
+
Store the complete "trajectory" of agent work on tasks - prompts, reasoning, inter-agent messages, tool calls, decisions, and retrospectives - as first-class artifacts that travel with the code and provide long-term value for debugging, code review, onboarding, and institutional memory.
|
|
6
|
+
|
|
7
|
+
**Key principle: Platform agnostic.** Trajectories are a universal format - like Markdown for documentation. They work with any task system (Beads, Linear, Jira, GitHub Issues, plain text) and export to any reading format (Notion-like pages, Linear-like timelines, raw JSON).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## The Bigger Picture: Notion for Agents
|
|
12
|
+
|
|
13
|
+
Trajectories are one piece of a larger vision: **a knowledge workspace where agents can read, write, and learn** - just like Notion is for humans.
|
|
14
|
+
|
|
15
|
+
### What Notion Does for Humans
|
|
16
|
+
|
|
17
|
+
| Capability | How Humans Use It |
|
|
18
|
+
|------------|-------------------|
|
|
19
|
+
| **Knowledge base** | Company wiki, documentation, runbooks |
|
|
20
|
+
| **Linked documents** | Connect related ideas, reference past work |
|
|
21
|
+
| **Templates** | Reusable structures for common tasks |
|
|
22
|
+
| **Databases** | Structured data with multiple views |
|
|
23
|
+
| **Search** | Find anything across all content |
|
|
24
|
+
| **Collaboration** | Comments, mentions, shared editing |
|
|
25
|
+
|
|
26
|
+
### What Agents Need (Agent Notion)
|
|
27
|
+
|
|
28
|
+
| Capability | Agent Equivalent |
|
|
29
|
+
|------------|------------------|
|
|
30
|
+
| **Trajectory archive** | Past work with full reasoning history |
|
|
31
|
+
| **Codebase knowledge** | Architecture docs, patterns, conventions |
|
|
32
|
+
| **Decision log** | Why things are the way they are |
|
|
33
|
+
| **Team context** | Who knows what, who's working on what |
|
|
34
|
+
| **Pattern library** | Reusable approaches to common problems |
|
|
35
|
+
| **Communication history** | Past agent-to-agent conversations |
|
|
36
|
+
|
|
37
|
+
### How Agent Notion Helps
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
41
|
+
│ AGENT NOTION WORKSPACE │
|
|
42
|
+
├─────────────────────────────────────────────────────────────────────────┤
|
|
43
|
+
│ │
|
|
44
|
+
│ 📚 KNOWLEDGE BASE 🛤️ TRAJECTORIES │
|
|
45
|
+
│ ├── Architecture decisions ├── Active (3) │
|
|
46
|
+
│ ├── Code patterns we use ├── This week (12) │
|
|
47
|
+
│ ├── API conventions └── Archive (156) │
|
|
48
|
+
│ └── Testing philosophy │
|
|
49
|
+
│ │
|
|
50
|
+
│ 🧠 DECISION LOG 👥 TEAM CONTEXT │
|
|
51
|
+
│ ├── "Why we use Postgres" ├── Alice: auth expert │
|
|
52
|
+
│ ├── "Why no Redux" ├── Bob: API design │
|
|
53
|
+
│ └── "Error handling approach" └── Carol: testing lead │
|
|
54
|
+
│ │
|
|
55
|
+
│ 📋 PATTERNS 💬 CONVERSATIONS │
|
|
56
|
+
│ ├── API endpoint template ├── Today's discussions │
|
|
57
|
+
│ ├── React component pattern ├── Decisions made │
|
|
58
|
+
│ └── Test file structure └── Open questions │
|
|
59
|
+
│ │
|
|
60
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Use Cases: How Agent Notion Helps
|
|
64
|
+
|
|
65
|
+
#### 1. New Agent Onboarding
|
|
66
|
+
|
|
67
|
+
**Without Agent Notion:**
|
|
68
|
+
```
|
|
69
|
+
New agent spawns → Reads codebase → Makes assumptions →
|
|
70
|
+
Possibly repeats past mistakes → Violates conventions
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**With Agent Notion:**
|
|
74
|
+
```
|
|
75
|
+
New agent spawns → Queries workspace:
|
|
76
|
+
"How do we handle authentication in this codebase?"
|
|
77
|
+
→ Gets: trajectory of auth implementation + decision log + patterns
|
|
78
|
+
→ Understands context in seconds
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### 2. Consistent Decision Making
|
|
82
|
+
|
|
83
|
+
**Without:** Each agent reinvents approaches, leading to inconsistent code.
|
|
84
|
+
|
|
85
|
+
**With:** Agent queries pattern library:
|
|
86
|
+
```
|
|
87
|
+
Agent: "I need to add a new API endpoint"
|
|
88
|
+
|
|
89
|
+
Workspace returns:
|
|
90
|
+
- Template: Standard endpoint structure
|
|
91
|
+
- Pattern: Error handling approach
|
|
92
|
+
- Trajectory: How /api/users was built (for reference)
|
|
93
|
+
- Decision: "We use Zod for validation (see decision-2024-03)"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### 3. Learning from Past Work
|
|
97
|
+
|
|
98
|
+
**Query:** "How have we solved caching problems before?"
|
|
99
|
+
|
|
100
|
+
**Returns:**
|
|
101
|
+
- 3 trajectories involving caching
|
|
102
|
+
- Key decisions: Redis for sessions, in-memory for hot data
|
|
103
|
+
- Gotchas: "Cache invalidation was tricky in trajectory-abc, see retrospective"
|
|
104
|
+
|
|
105
|
+
#### 4. Cross-Agent Collaboration
|
|
106
|
+
|
|
107
|
+
When Alice asks Bob a question:
|
|
108
|
+
```
|
|
109
|
+
Alice → Bob: "How should I structure the payment webhook handler?"
|
|
110
|
+
|
|
111
|
+
Bob can reference:
|
|
112
|
+
- Past trajectory where similar webhook was built
|
|
113
|
+
- Pattern for webhook handlers
|
|
114
|
+
- Known issues from retrospectives
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The answer becomes **reusable knowledge**, not ephemeral chat.
|
|
118
|
+
|
|
119
|
+
### Data Model: Agent Workspace
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
interface AgentWorkspace {
|
|
123
|
+
projectId: string;
|
|
124
|
+
|
|
125
|
+
// The layers of knowledge
|
|
126
|
+
trajectories: TrajectoryStore; // Work history
|
|
127
|
+
decisions: DecisionLog; // Why things are
|
|
128
|
+
patterns: PatternLibrary; // How to do things
|
|
129
|
+
knowledge: KnowledgeBase; // What things are
|
|
130
|
+
conversations: ConversationArchive; // Who said what
|
|
131
|
+
team: TeamContext; // Who knows what
|
|
132
|
+
|
|
133
|
+
// Cross-cutting
|
|
134
|
+
search: UnifiedSearch; // Find across all layers
|
|
135
|
+
links: LinkGraph; // Connections between items
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
interface DecisionLog {
|
|
139
|
+
decisions: Decision[];
|
|
140
|
+
|
|
141
|
+
// Query interface
|
|
142
|
+
getDecision(topic: string): Decision | null;
|
|
143
|
+
findRelated(context: string): Decision[];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface Decision {
|
|
147
|
+
id: string;
|
|
148
|
+
title: string; // "Use PostgreSQL for primary database"
|
|
149
|
+
context: string; // Why this came up
|
|
150
|
+
decision: string; // What was decided
|
|
151
|
+
alternatives: Alternative[]; // What was rejected
|
|
152
|
+
consequences: string[]; // What this means going forward
|
|
153
|
+
relatedTrajectories: string[]; // Where this was implemented
|
|
154
|
+
date: string;
|
|
155
|
+
participants: string[]; // Who was involved
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
interface PatternLibrary {
|
|
159
|
+
patterns: Pattern[];
|
|
160
|
+
|
|
161
|
+
// Query interface
|
|
162
|
+
findPattern(task: string): Pattern | null;
|
|
163
|
+
suggestPatterns(context: string): Pattern[];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
interface Pattern {
|
|
167
|
+
id: string;
|
|
168
|
+
name: string; // "API Endpoint"
|
|
169
|
+
description: string; // When to use this
|
|
170
|
+
template: string; // The actual pattern/template
|
|
171
|
+
examples: string[]; // File paths showing real usage
|
|
172
|
+
relatedTrajectories: string[]; // Where this was used
|
|
173
|
+
tags: string[];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
interface KnowledgeBase {
|
|
177
|
+
documents: KnowledgeDoc[];
|
|
178
|
+
|
|
179
|
+
// Query interface
|
|
180
|
+
query(question: string): KnowledgeDoc[];
|
|
181
|
+
getContext(topic: string): string;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
interface KnowledgeDoc {
|
|
185
|
+
id: string;
|
|
186
|
+
title: string;
|
|
187
|
+
content: string; // Markdown content
|
|
188
|
+
source: 'manual' | 'extracted' | 'generated';
|
|
189
|
+
relatedFiles: string[]; // Code files this relates to
|
|
190
|
+
lastUpdated: string;
|
|
191
|
+
tags: string[];
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### How It Gets Populated
|
|
196
|
+
|
|
197
|
+
#### 1. Automatic Extraction
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
// After each trajectory completes
|
|
201
|
+
async function extractKnowledge(trajectory: Trajectory): Promise<void> {
|
|
202
|
+
// Extract decisions
|
|
203
|
+
for (const decision of trajectory.retrospective?.decisions ?? []) {
|
|
204
|
+
await decisionLog.add({
|
|
205
|
+
...decision,
|
|
206
|
+
relatedTrajectories: [trajectory.id],
|
|
207
|
+
date: trajectory.completedAt
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Extract patterns (if agent documented any)
|
|
212
|
+
const patterns = extractPatternsFromTrajectory(trajectory);
|
|
213
|
+
for (const pattern of patterns) {
|
|
214
|
+
await patternLibrary.add(pattern);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Update knowledge base with new understanding
|
|
218
|
+
await knowledgeBase.updateFromTrajectory(trajectory);
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### 2. Agent Contribution
|
|
223
|
+
|
|
224
|
+
Agents can explicitly add to the workspace:
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
[[KNOWLEDGE:decision]]
|
|
228
|
+
{
|
|
229
|
+
"title": "Use React Query for server state",
|
|
230
|
+
"context": "Needed to manage API data fetching",
|
|
231
|
+
"decision": "React Query over Redux for server state",
|
|
232
|
+
"alternatives": ["Redux + RTK Query", "SWR", "Custom hooks"],
|
|
233
|
+
"reasoning": "Better caching, less boilerplate, team familiarity"
|
|
234
|
+
}
|
|
235
|
+
[[/KNOWLEDGE]]
|
|
236
|
+
|
|
237
|
+
[[KNOWLEDGE:pattern]]
|
|
238
|
+
{
|
|
239
|
+
"name": "Feature Flag Check",
|
|
240
|
+
"description": "How to check feature flags in components",
|
|
241
|
+
"template": "const isEnabled = useFeatureFlag('flag-name');\nif (!isEnabled) return null;"
|
|
242
|
+
}
|
|
243
|
+
[[/KNOWLEDGE]]
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
#### 3. Human Curation
|
|
247
|
+
|
|
248
|
+
Humans can add/edit knowledge directly:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
# Add a decision
|
|
252
|
+
agent-relay knowledge add-decision "Why we don't use GraphQL" \
|
|
253
|
+
--context "Evaluated for API layer" \
|
|
254
|
+
--decision "REST with OpenAPI" \
|
|
255
|
+
--reasoning "Team experience, tooling maturity"
|
|
256
|
+
|
|
257
|
+
# Add a pattern
|
|
258
|
+
agent-relay knowledge add-pattern "Error Boundary" \
|
|
259
|
+
--file templates/error-boundary.tsx
|
|
260
|
+
|
|
261
|
+
# Add documentation
|
|
262
|
+
agent-relay knowledge add-doc "Architecture Overview" \
|
|
263
|
+
--file docs/architecture.md
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Query Interface for Agents
|
|
267
|
+
|
|
268
|
+
Agents query the workspace naturally:
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
interface WorkspaceQuery {
|
|
272
|
+
// Natural language queries
|
|
273
|
+
ask(question: string): Promise<QueryResult>;
|
|
274
|
+
|
|
275
|
+
// Specific lookups
|
|
276
|
+
getTrajectory(id: string): Promise<Trajectory>;
|
|
277
|
+
getDecision(topic: string): Promise<Decision | null>;
|
|
278
|
+
getPattern(name: string): Promise<Pattern | null>;
|
|
279
|
+
|
|
280
|
+
// Contextual suggestions
|
|
281
|
+
suggestForTask(taskDescription: string): Promise<Suggestions>;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
interface Suggestions {
|
|
285
|
+
relevantTrajectories: TrajectorySummary[];
|
|
286
|
+
applicablePatterns: Pattern[];
|
|
287
|
+
relatedDecisions: Decision[];
|
|
288
|
+
teamExperts: AgentInfo[]; // Who might help
|
|
289
|
+
potentialGotchas: string[]; // From past retrospectives
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Example agent interaction:**
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
Agent starting task: "Add rate limiting to API endpoints"
|
|
297
|
+
|
|
298
|
+
Agent queries: workspace.suggestForTask("Add rate limiting to API endpoints")
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
{
|
|
302
|
+
relevantTrajectories: [
|
|
303
|
+
{ id: "traj-abc", title: "Implemented auth rate limiting", confidence: 0.9 }
|
|
304
|
+
],
|
|
305
|
+
applicablePatterns: [
|
|
306
|
+
{ name: "Middleware Pattern", description: "How we add cross-cutting concerns" }
|
|
307
|
+
],
|
|
308
|
+
relatedDecisions: [
|
|
309
|
+
{ title: "Use Redis for distributed state", relevant: true }
|
|
310
|
+
],
|
|
311
|
+
teamExperts: [
|
|
312
|
+
{ name: "Alice", expertise: "Previously implemented rate limiting" }
|
|
313
|
+
],
|
|
314
|
+
potentialGotchas: [
|
|
315
|
+
"Previous rate limiting had issues with Redis connection pooling - see traj-abc retrospective"
|
|
316
|
+
]
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Storage: Where Does It Live?
|
|
321
|
+
|
|
322
|
+
```
|
|
323
|
+
.agent-workspace/
|
|
324
|
+
├── trajectories/ # Work history (detailed above)
|
|
325
|
+
├── decisions/
|
|
326
|
+
│ ├── index.json
|
|
327
|
+
│ └── decisions.jsonl # Append-only decision log
|
|
328
|
+
├── patterns/
|
|
329
|
+
│ ├── index.json
|
|
330
|
+
│ └── api-endpoint.md
|
|
331
|
+
│ └── react-component.md
|
|
332
|
+
├── knowledge/
|
|
333
|
+
│ ├── index.json
|
|
334
|
+
│ ├── architecture.md
|
|
335
|
+
│ └── conventions.md
|
|
336
|
+
├── conversations/
|
|
337
|
+
│ └── 2024-01-15.jsonl # Daily conversation logs
|
|
338
|
+
└── team/
|
|
339
|
+
└── context.json # Team member expertise/status
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### The Flywheel Effect
|
|
343
|
+
|
|
344
|
+
```
|
|
345
|
+
More trajectories → More extracted knowledge → Better agent context →
|
|
346
|
+
Better decisions → Better retrospectives → Richer trajectories → ...
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Over time, the workspace becomes increasingly valuable:
|
|
350
|
+
- Agents make fewer mistakes
|
|
351
|
+
- Decisions are more consistent
|
|
352
|
+
- Onboarding is instant
|
|
353
|
+
- Institutional memory persists
|
|
354
|
+
- Humans can audit and understand agent work
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Integration: claude-mem
|
|
359
|
+
|
|
360
|
+
[claude-mem](https://github.com/thedotmack/claude-mem) is a persistent memory system for Claude Code that captures tool usage and observations. It's solving a similar problem at a different layer.
|
|
361
|
+
|
|
362
|
+
### How They Compare
|
|
363
|
+
|
|
364
|
+
| Aspect | claude-mem | Trajectories |
|
|
365
|
+
|--------|------------|--------------|
|
|
366
|
+
| **Focus** | Tool observations | Task narratives |
|
|
367
|
+
| **Granularity** | Per-tool-call | Per-task |
|
|
368
|
+
| **Scope** | Single agent | Multi-agent |
|
|
369
|
+
| **Structure** | Observations + concepts | Chapters + decisions |
|
|
370
|
+
| **Query** | Semantic search | Task/decision lookup |
|
|
371
|
+
| **Persistence** | SQLite + Chroma | File + SQLite |
|
|
372
|
+
|
|
373
|
+
### They're Complementary, Not Competing
|
|
374
|
+
|
|
375
|
+
```
|
|
376
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
377
|
+
│ AGENT MEMORY STACK │
|
|
378
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
379
|
+
│ │
|
|
380
|
+
│ TRAJECTORIES (Task Layer) │
|
|
381
|
+
│ "The story of the work" │
|
|
382
|
+
│ - Multi-agent coordination │
|
|
383
|
+
│ - Decisions & retrospectives │
|
|
384
|
+
│ - Human-readable narratives │
|
|
385
|
+
│ │ │
|
|
386
|
+
│ │ aggregates │
|
|
387
|
+
│ ▼ │
|
|
388
|
+
│ CLAUDE-MEM (Observation Layer) │
|
|
389
|
+
│ "What happened during the work" │
|
|
390
|
+
│ - Tool call observations │
|
|
391
|
+
│ - Semantic concepts │
|
|
392
|
+
│ - Session continuity │
|
|
393
|
+
│ │ │
|
|
394
|
+
│ │ captures │
|
|
395
|
+
│ ▼ │
|
|
396
|
+
│ RAW EVENTS (Execution Layer) │
|
|
397
|
+
│ - Tool calls │
|
|
398
|
+
│ - File changes │
|
|
399
|
+
│ - Messages │
|
|
400
|
+
│ │
|
|
401
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Integration Strategy
|
|
405
|
+
|
|
406
|
+
#### 1. Use claude-mem as Observation Source
|
|
407
|
+
|
|
408
|
+
claude-mem already captures tool observations via hooks. Trajectories can aggregate these:
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
// When trajectory chapter ends, pull observations from claude-mem
|
|
412
|
+
async function enrichChapterFromClaudeMem(chapter: Chapter): Promise<void> {
|
|
413
|
+
const observations = await claudeMemClient.search({
|
|
414
|
+
timeRange: { start: chapter.startedAt, end: chapter.endedAt },
|
|
415
|
+
types: ['decision', 'discovery', 'bugfix']
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
chapter.events.push(...observations.map(obs => ({
|
|
419
|
+
ts: obs.timestamp,
|
|
420
|
+
type: 'observation',
|
|
421
|
+
content: obs.content,
|
|
422
|
+
source: 'claude-mem',
|
|
423
|
+
concepts: obs.concepts
|
|
424
|
+
})));
|
|
425
|
+
}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
#### 2. Shared Storage Layer
|
|
429
|
+
|
|
430
|
+
Both could use the same SQLite database with different tables:
|
|
431
|
+
|
|
432
|
+
```sql
|
|
433
|
+
-- claude-mem tables
|
|
434
|
+
CREATE TABLE observations (...);
|
|
435
|
+
CREATE TABLE sessions (...);
|
|
436
|
+
|
|
437
|
+
-- trajectory tables
|
|
438
|
+
CREATE TABLE trajectories (...);
|
|
439
|
+
CREATE TABLE chapters (...);
|
|
440
|
+
|
|
441
|
+
-- linking table
|
|
442
|
+
CREATE TABLE trajectory_observations (
|
|
443
|
+
trajectory_id TEXT,
|
|
444
|
+
observation_id TEXT,
|
|
445
|
+
FOREIGN KEY ...
|
|
446
|
+
);
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
#### 3. Cross-Query Support
|
|
450
|
+
|
|
451
|
+
Query trajectories, get relevant observations:
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
# "What observations were captured during task bd-123?"
|
|
455
|
+
agent-relay trajectory bd-123 --show-observations
|
|
456
|
+
|
|
457
|
+
# "What tasks used these concepts?"
|
|
458
|
+
agent-relay search --concept "authentication" --include-trajectories
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
#### 4. Export/Import
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
# Export claude-mem session as trajectory
|
|
465
|
+
claude-mem export session-123 --format trajectory > traj.json
|
|
466
|
+
|
|
467
|
+
# Import trajectory into claude-mem for observation search
|
|
468
|
+
agent-relay trajectory export bd-123 --format claude-mem | claude-mem import
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Proposed Hook Integration
|
|
472
|
+
|
|
473
|
+
claude-mem uses Claude Code hooks. Trajectories can add complementary hooks:
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
// SessionStart: Load active trajectory context
|
|
477
|
+
hooks.onSessionStart(async () => {
|
|
478
|
+
const active = await trajectoryStore.getActive();
|
|
479
|
+
if (active) {
|
|
480
|
+
return {
|
|
481
|
+
context: `Active trajectory: ${active.task.title}\n` +
|
|
482
|
+
`Chapter: ${active.currentChapter.title}\n` +
|
|
483
|
+
`Decisions so far: ${active.decisions.map(d => d.title).join(', ')}`
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
// SessionEnd: Prompt for trajectory update
|
|
489
|
+
hooks.onSessionEnd(async () => {
|
|
490
|
+
const active = await trajectoryStore.getActive();
|
|
491
|
+
if (active) {
|
|
492
|
+
return {
|
|
493
|
+
prompt: 'Before ending, update the trajectory with key decisions/learnings.'
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Why Both Together
|
|
500
|
+
|
|
501
|
+
| Use Case | claude-mem | Trajectories | Together |
|
|
502
|
+
|----------|------------|--------------|----------|
|
|
503
|
+
| "What tool did I use for X?" | ✅ | ❌ | ✅ |
|
|
504
|
+
| "Why did we build it this way?" | ❌ | ✅ | ✅ |
|
|
505
|
+
| "What happened in this session?" | ✅ | partial | ✅ |
|
|
506
|
+
| "What's the full story of feature X?" | ❌ | ✅ | ✅ |
|
|
507
|
+
| "What concepts are relevant to Y?" | ✅ | ❌ | ✅ |
|
|
508
|
+
| "Who worked on what?" | ❌ | ✅ | ✅ |
|
|
509
|
+
|
|
510
|
+
**claude-mem = operational memory** (detailed, semantic, per-agent)
|
|
511
|
+
**Trajectories = narrative memory** (structured, task-centric, multi-agent)
|
|
512
|
+
|
|
513
|
+
Together they create a complete memory stack.
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
## Architecture: Separate Providers in a Stack
|
|
518
|
+
|
|
519
|
+
Each layer is a **separate project** that can be used independently or together:
|
|
520
|
+
|
|
521
|
+
```
|
|
522
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
523
|
+
│ AGENT INFRASTRUCTURE STACK │
|
|
524
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
525
|
+
│ │
|
|
526
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
527
|
+
│ │ AGENT-TRAJECTORIES (Layer 3) ◄── THIS PROJECT │ │
|
|
528
|
+
│ │ github.com/???/agent-trajectories │ │
|
|
529
|
+
│ │ │ │
|
|
530
|
+
│ │ ┌─────────────────────────────────────────────────┐ │ │
|
|
531
|
+
│ │ │ Workspace (built-in feature) │ │ │
|
|
532
|
+
│ │ │ Patterns, decisions, knowledge extraction │ │ │
|
|
533
|
+
│ │ └─────────────────────────────────────────────────┘ │ │
|
|
534
|
+
│ │ │ │
|
|
535
|
+
│ │ Task narratives, decisions, retrospectives │ │
|
|
536
|
+
│ │ Platform-agnostic .trajectory format │ │
|
|
537
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
538
|
+
│ ▲ │
|
|
539
|
+
│ │ aggregates │
|
|
540
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
541
|
+
│ │ CLAUDE-MEM (Layer 2) │ │
|
|
542
|
+
│ │ github.com/thedotmack/claude-mem │ │
|
|
543
|
+
│ │ Tool observations, semantic concepts, sessions │ │
|
|
544
|
+
│ │ Already exists - we integrate with it │ │
|
|
545
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
546
|
+
│ ▲ │
|
|
547
|
+
│ │ captures │
|
|
548
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
549
|
+
│ │ AGENT-RELAY (Layer 1) │ │
|
|
550
|
+
│ │ github.com/khaliqgant/agent-relay │ │
|
|
551
|
+
│ │ Real-time messaging, message persistence │ │
|
|
552
|
+
│ │ The communication substrate │ │
|
|
553
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
554
|
+
│ │
|
|
555
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### Each Project is Independent
|
|
559
|
+
|
|
560
|
+
| Project | Can Use Alone? | Depends On |
|
|
561
|
+
|---------|----------------|------------|
|
|
562
|
+
| **agent-relay** | ✅ Yes | Nothing |
|
|
563
|
+
| **claude-mem** | ✅ Yes | Nothing (Claude Code hooks) |
|
|
564
|
+
| **agent-trajectories** | ✅ Yes | Nothing (but richer with relay/claude-mem) |
|
|
565
|
+
|
|
566
|
+
### agent-trajectories Structure
|
|
567
|
+
|
|
568
|
+
Workspace is a **built-in feature**, not a separate project:
|
|
569
|
+
|
|
570
|
+
```
|
|
571
|
+
agent-trajectories/
|
|
572
|
+
├── src/
|
|
573
|
+
│ ├── core/ # .trajectory format, types
|
|
574
|
+
│ ├── capture/ # CLI, event capture
|
|
575
|
+
│ ├── adapters/ # beads, linear, github, plain
|
|
576
|
+
│ ├── workspace/ # Patterns, decisions, knowledge (opt-in)
|
|
577
|
+
│ │ ├── decisions.ts # Decision log
|
|
578
|
+
│ │ ├── patterns.ts # Pattern library
|
|
579
|
+
│ │ ├── knowledge.ts # Knowledge base
|
|
580
|
+
│ │ └── extract.ts # Auto-extraction from trajectories
|
|
581
|
+
│ └── export/ # Markdown, timeline views
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
**Why combined:**
|
|
585
|
+
1. Workspace is derived data from trajectories - not a separate concern
|
|
586
|
+
2. Flywheel only works if tightly coupled (trajectory complete → extract → enrich next)
|
|
587
|
+
3. Users expect "trajectory complete" → "knowledge extracted" to be automatic
|
|
588
|
+
4. Single install, single config, simpler for users
|
|
589
|
+
|
|
590
|
+
### Integration Points
|
|
591
|
+
|
|
592
|
+
```typescript
|
|
593
|
+
// agent-trajectories can pull from multiple sources:
|
|
594
|
+
|
|
595
|
+
// 1. Messages from agent-relay
|
|
596
|
+
import { RelayClient } from 'agent-relay';
|
|
597
|
+
const messages = await relay.getMessages({ topic: taskId });
|
|
598
|
+
|
|
599
|
+
// 2. Observations from claude-mem
|
|
600
|
+
import { ClaudeMemClient } from 'claude-mem';
|
|
601
|
+
const observations = await claudeMem.search({ timeRange, types });
|
|
602
|
+
|
|
603
|
+
// 3. Or work standalone with just explicit agent output
|
|
604
|
+
// [[TRAJECTORY:decision]] ... [[/TRAJECTORY]]
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
### Why Separate Projects?
|
|
608
|
+
|
|
609
|
+
1. **Independent adoption** - Use trajectories without relay, or relay without trajectories
|
|
610
|
+
2. **Different maintainers** - claude-mem is already external
|
|
611
|
+
3. **Different release cycles** - Each can evolve independently
|
|
612
|
+
4. **Cleaner dependencies** - No monolith, composable pieces
|
|
613
|
+
5. **Community contributions** - Easier to contribute to focused projects
|
|
614
|
+
|
|
615
|
+
### The Glue
|
|
616
|
+
|
|
617
|
+
agent-relay serves as the **communication substrate** - it's what agents use to talk to each other. The other layers build on top:
|
|
618
|
+
|
|
619
|
+
- claude-mem hooks into Claude Code directly
|
|
620
|
+
- agent-trajectories can consume relay messages as events
|
|
621
|
+
- agent-workspace queries trajectories for patterns
|
|
622
|
+
|
|
623
|
+
---
|
|
624
|
+
|
|
625
|
+
## Vision: Notion/Linear for Agent Work
|
|
626
|
+
|
|
627
|
+
Think of trajectories as **the document layer for agent work**:
|
|
628
|
+
|
|
629
|
+
| Tool | For Humans | Trajectory Equivalent for Agents |
|
|
630
|
+
|------|------------|----------------------------------|
|
|
631
|
+
| Notion | Knowledge base, docs | Readable narrative of work |
|
|
632
|
+
| Linear | Issue tracking, timelines | Task progress with full context |
|
|
633
|
+
| Git | Version history | Decision history with reasoning |
|
|
634
|
+
|
|
635
|
+
A trajectory is a **living document** that:
|
|
636
|
+
- Agents write to as they work
|
|
637
|
+
- Humans read to understand
|
|
638
|
+
- Tools index for search and analysis
|
|
639
|
+
- Systems import/export freely
|
|
640
|
+
|
|
641
|
+
---
|
|
642
|
+
|
|
643
|
+
## Reading Experience: Multiple Views
|
|
644
|
+
|
|
645
|
+
The same trajectory data can be rendered in multiple ways for different audiences:
|
|
646
|
+
|
|
647
|
+
### Notion-style Page (Human Documentation)
|
|
648
|
+
|
|
649
|
+
A rich, readable document with collapsible sections:
|
|
650
|
+
|
|
651
|
+
```
|
|
652
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
653
|
+
│ 🛤️ Implement User Authentication │
|
|
654
|
+
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
|
655
|
+
│ │
|
|
656
|
+
│ 📋 Summary │
|
|
657
|
+
│ JWT-based auth with refresh tokens. 2h 34m. Confidence: 85% │
|
|
658
|
+
│ │
|
|
659
|
+
│ ▶ Key Decisions (3) │
|
|
660
|
+
│ ▶ Chapters (4) │
|
|
661
|
+
│ ▶ Retrospective │
|
|
662
|
+
│ │
|
|
663
|
+
│ 🔗 Links: ENG-456 • PR #123 • 3 commits │
|
|
664
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
### Linear-style Timeline (Progress Tracking)
|
|
668
|
+
|
|
669
|
+
Chronological view with status:
|
|
670
|
+
|
|
671
|
+
```
|
|
672
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
673
|
+
│ ● 10:00 Started: Implement User Authentication │
|
|
674
|
+
│ │ │
|
|
675
|
+
│ ├─ 10:05 Chapter: Research existing patterns │
|
|
676
|
+
│ │ Found 3 auth approaches, chose JWT │
|
|
677
|
+
│ │ │
|
|
678
|
+
│ ├─ 10:30 Decision: JWT over sessions │
|
|
679
|
+
│ │ "Stateless scaling requirement" │
|
|
680
|
+
│ │ │
|
|
681
|
+
│ ├─ 11:00 Chapter: Implementation │
|
|
682
|
+
│ │ Modified 8 files │
|
|
683
|
+
│ │ │
|
|
684
|
+
│ ├─ 12:00 Message: @Bob review request │
|
|
685
|
+
│ │ │
|
|
686
|
+
│ ○ 12:30 Completed with retrospective │
|
|
687
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
### Git-integrated View (Code Review)
|
|
691
|
+
|
|
692
|
+
Embedded in PRs and commits:
|
|
693
|
+
|
|
694
|
+
```markdown
|
|
695
|
+
## 📍 Trajectory Context
|
|
696
|
+
|
|
697
|
+
This PR implements [ENG-456] as part of trajectory `traj_abc123`.
|
|
698
|
+
|
|
699
|
+
**Why this approach:** JWT chosen over sessions for stateless scaling.
|
|
700
|
+
See [full trajectory](link) for decision history.
|
|
701
|
+
|
|
702
|
+
**Agent confidence:** 85% - solid implementation, suggest load testing
|
|
703
|
+
the refresh token rotation.
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
### CLI View (Agent/Developer)
|
|
707
|
+
|
|
708
|
+
```bash
|
|
709
|
+
$ agent-relay trajectory status
|
|
710
|
+
|
|
711
|
+
Active Trajectory: traj_abc123
|
|
712
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
713
|
+
Task: Implement user authentication
|
|
714
|
+
Source: linear:ENG-456
|
|
715
|
+
Started: 2h 34m ago
|
|
716
|
+
Agents: Alice (active), Bob (reviewing)
|
|
717
|
+
Chapters: 4 (current: "Testing")
|
|
718
|
+
Decisions: 3 recorded
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
---
|
|
722
|
+
|
|
723
|
+
## The Problem
|
|
724
|
+
|
|
725
|
+
When an agent completes a task today, the only artifacts are:
|
|
726
|
+
1. **Code changes** - the what, but not the why
|
|
727
|
+
2. **Commit messages** - brief summaries
|
|
728
|
+
3. **PR descriptions** - static snapshots
|
|
729
|
+
4. **Chat logs** - ephemeral, lost when sessions end
|
|
730
|
+
|
|
731
|
+
The rich context of *how* the work happened disappears:
|
|
732
|
+
- Why was approach A chosen over B?
|
|
733
|
+
- What dead ends were explored?
|
|
734
|
+
- What assumptions were made?
|
|
735
|
+
- How did agents coordinate?
|
|
736
|
+
- What would the agent do differently?
|
|
737
|
+
|
|
738
|
+
This is the "train of thought trajectory" - the complete story of the work.
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
|
|
742
|
+
## Core Concept: Trajectories
|
|
743
|
+
|
|
744
|
+
A **trajectory** is a structured record of an agent's work on a task:
|
|
745
|
+
|
|
746
|
+
```typescript
|
|
747
|
+
interface Trajectory {
|
|
748
|
+
id: string; // UUID
|
|
749
|
+
version: 1; // Schema version (for forward compat)
|
|
750
|
+
|
|
751
|
+
// Task reference (platform-agnostic)
|
|
752
|
+
task: TaskReference;
|
|
753
|
+
|
|
754
|
+
// Timeline
|
|
755
|
+
startedAt: string; // ISO timestamp
|
|
756
|
+
completedAt?: string;
|
|
757
|
+
status: 'active' | 'completed' | 'abandoned';
|
|
758
|
+
|
|
759
|
+
// Participants
|
|
760
|
+
agents: AgentParticipation[]; // Who worked on this
|
|
761
|
+
|
|
762
|
+
// The trajectory itself
|
|
763
|
+
chapters: Chapter[]; // Logical segments of work
|
|
764
|
+
|
|
765
|
+
// Synthesis
|
|
766
|
+
retrospective?: Retrospective; // Agent reflection
|
|
767
|
+
|
|
768
|
+
// Artifacts
|
|
769
|
+
commits: string[]; // Git SHAs produced
|
|
770
|
+
filesChanged: string[]; // Paths modified
|
|
771
|
+
|
|
772
|
+
// Metadata
|
|
773
|
+
projectId: string;
|
|
774
|
+
tags: string[]; // User-defined tags
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Platform-agnostic task reference.
|
|
779
|
+
* Trajectories work with ANY task system.
|
|
780
|
+
*/
|
|
781
|
+
interface TaskReference {
|
|
782
|
+
// Human-readable
|
|
783
|
+
title: string;
|
|
784
|
+
description?: string;
|
|
785
|
+
|
|
786
|
+
// External system reference (optional)
|
|
787
|
+
source?: {
|
|
788
|
+
system: 'beads' | 'linear' | 'jira' | 'github' | 'plain' | string;
|
|
789
|
+
id: string; // e.g., "bd-123", "ENG-456", "GH#789"
|
|
790
|
+
url?: string; // Link to external system
|
|
791
|
+
};
|
|
792
|
+
|
|
793
|
+
// If no external system, trajectory IS the task
|
|
794
|
+
// (standalone mode - like a Notion page)
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
interface Chapter {
|
|
798
|
+
id: string;
|
|
799
|
+
title: string; // "Initial exploration", "Implementation", etc.
|
|
800
|
+
agentName: string;
|
|
801
|
+
startedAt: string;
|
|
802
|
+
endedAt?: string;
|
|
803
|
+
|
|
804
|
+
events: TrajectoryEvent[]; // Ordered list of events
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
interface TrajectoryEvent {
|
|
808
|
+
ts: number;
|
|
809
|
+
type: 'prompt' | 'thinking' | 'tool_call' | 'tool_result' |
|
|
810
|
+
'message_sent' | 'message_received' | 'decision' | 'error';
|
|
811
|
+
|
|
812
|
+
// Type-specific data
|
|
813
|
+
content: string; // Human-readable summary
|
|
814
|
+
raw?: unknown; // Full data (optional, for debugging)
|
|
815
|
+
|
|
816
|
+
// Annotations
|
|
817
|
+
significance?: 'low' | 'medium' | 'high' | 'critical';
|
|
818
|
+
tags?: string[];
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
interface Retrospective {
|
|
822
|
+
summary: string; // What was accomplished
|
|
823
|
+
approach: string; // How it was done
|
|
824
|
+
decisions: Decision[]; // Key decision points
|
|
825
|
+
challenges: string[]; // What was hard
|
|
826
|
+
learnings: string[]; // What was learned
|
|
827
|
+
suggestions: string[]; // What could be improved
|
|
828
|
+
confidence: number; // 0-1, agent's confidence in solution
|
|
829
|
+
timeSpent?: string; // Duration
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
interface Decision {
|
|
833
|
+
question: string; // What was the choice?
|
|
834
|
+
chosen: string; // What was picked
|
|
835
|
+
alternatives: string[]; // What was rejected
|
|
836
|
+
reasoning: string; // Why
|
|
837
|
+
}
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
---
|
|
841
|
+
|
|
842
|
+
## Universal File Format: `.trajectory`
|
|
843
|
+
|
|
844
|
+
Trajectories are stored as **self-contained documents** in a simple, portable format:
|
|
845
|
+
|
|
846
|
+
### File Structure
|
|
847
|
+
|
|
848
|
+
```
|
|
849
|
+
my-feature.trajectory.json # Machine-readable (primary)
|
|
850
|
+
my-feature.trajectory.md # Human-readable (generated)
|
|
851
|
+
```
|
|
852
|
+
|
|
853
|
+
Or bundled:
|
|
854
|
+
```
|
|
855
|
+
my-feature.trajectory/
|
|
856
|
+
├── trajectory.json # Full data
|
|
857
|
+
├── README.md # Human summary
|
|
858
|
+
├── chapters/
|
|
859
|
+
│ ├── 01-exploration.md # Chapter narratives
|
|
860
|
+
│ └── 02-implementation.md
|
|
861
|
+
└── artifacts/ # Referenced files (optional)
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
### JSON Format (Primary)
|
|
865
|
+
|
|
866
|
+
```json
|
|
867
|
+
{
|
|
868
|
+
"$schema": "https://agent-relay.dev/schemas/trajectory-v1.json",
|
|
869
|
+
"version": 1,
|
|
870
|
+
"id": "traj_abc123",
|
|
871
|
+
"task": {
|
|
872
|
+
"title": "Implement user authentication",
|
|
873
|
+
"source": {
|
|
874
|
+
"system": "linear",
|
|
875
|
+
"id": "ENG-456",
|
|
876
|
+
"url": "https://linear.app/team/issue/ENG-456"
|
|
877
|
+
}
|
|
878
|
+
},
|
|
879
|
+
"startedAt": "2024-01-15T10:00:00Z",
|
|
880
|
+
"status": "completed",
|
|
881
|
+
"agents": [...],
|
|
882
|
+
"chapters": [...],
|
|
883
|
+
"retrospective": {...}
|
|
884
|
+
}
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
### Markdown Format (Human-Readable)
|
|
888
|
+
|
|
889
|
+
Auto-generated, Notion-like document:
|
|
890
|
+
|
|
891
|
+
```markdown
|
|
892
|
+
# 🛤️ Trajectory: Implement user authentication
|
|
893
|
+
|
|
894
|
+
> **Task:** [ENG-456](https://linear.app/team/issue/ENG-456)
|
|
895
|
+
> **Status:** ✅ Completed
|
|
896
|
+
> **Duration:** 2h 34m
|
|
897
|
+
> **Agents:** Alice, Bob
|
|
898
|
+
> **Confidence:** 85%
|
|
899
|
+
|
|
900
|
+
---
|
|
901
|
+
|
|
902
|
+
## 📋 Summary
|
|
903
|
+
|
|
904
|
+
Implemented JWT-based authentication with refresh tokens. Chose JWTs over
|
|
905
|
+
sessions for stateless scaling. Key challenge was fixing existing type
|
|
906
|
+
definitions that were incorrect.
|
|
907
|
+
|
|
908
|
+
---
|
|
909
|
+
|
|
910
|
+
## 🎯 Key Decisions
|
|
911
|
+
|
|
912
|
+
### JWT vs Sessions
|
|
913
|
+
- **Chose:** JWT with refresh tokens
|
|
914
|
+
- **Rejected:** Server-side sessions
|
|
915
|
+
- **Why:** Stateless scaling requirement, multi-server deployment planned
|
|
916
|
+
|
|
917
|
+
---
|
|
918
|
+
|
|
919
|
+
## 📖 Chapters
|
|
920
|
+
|
|
921
|
+
### 1. Initial Exploration (10:00 - 10:30)
|
|
922
|
+
Researched existing auth patterns in codebase. Found 3 different approaches
|
|
923
|
+
already in use. Decided to follow the pattern in `src/auth/oauth.ts`.
|
|
924
|
+
|
|
925
|
+
### 2. Implementation (10:30 - 12:00)
|
|
926
|
+
[Detailed narrative...]
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
930
|
+
## 🔄 Retrospective
|
|
931
|
+
|
|
932
|
+
**What went well:** Clean implementation, good test coverage.
|
|
933
|
+
**Challenges:** UserContext types were wrong, had to fix first.
|
|
934
|
+
**Would do differently:** Check existing types earlier in process.
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
---
|
|
938
|
+
|
|
939
|
+
## Task Source Adapters
|
|
940
|
+
|
|
941
|
+
Trajectories are **decoupled from task systems**. Adapters translate between systems:
|
|
942
|
+
|
|
943
|
+
```typescript
|
|
944
|
+
interface TaskSourceAdapter {
|
|
945
|
+
name: string; // 'beads', 'linear', 'github', etc.
|
|
946
|
+
|
|
947
|
+
// Detect if this source is available
|
|
948
|
+
detect(): Promise<boolean>;
|
|
949
|
+
|
|
950
|
+
// Get task details for trajectory
|
|
951
|
+
getTask(id: string): Promise<TaskReference>;
|
|
952
|
+
|
|
953
|
+
// Listen for task state changes (optional)
|
|
954
|
+
onTaskStart?(callback: (task: TaskReference) => void): void;
|
|
955
|
+
onTaskComplete?(callback: (taskId: string) => void): void;
|
|
956
|
+
|
|
957
|
+
// Sync trajectory status back to source (optional)
|
|
958
|
+
updateTaskStatus?(taskId: string, status: string): Promise<void>;
|
|
959
|
+
}
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
### Built-in Adapters
|
|
963
|
+
|
|
964
|
+
| Adapter | Detection | Features |
|
|
965
|
+
|---------|-----------|----------|
|
|
966
|
+
| `beads` | `.beads/` dir | Full sync, auto-start on `bd update` |
|
|
967
|
+
| `github` | `.git` + `gh` CLI | Link to issues/PRs |
|
|
968
|
+
| `linear` | `LINEAR_API_KEY` env | Two-way sync |
|
|
969
|
+
| `jira` | `JIRA_URL` env | Read-only (start) |
|
|
970
|
+
| `plain` | Always available | Manual task creation |
|
|
971
|
+
|
|
972
|
+
### Example: Standalone Mode (No External System)
|
|
973
|
+
|
|
974
|
+
```bash
|
|
975
|
+
# Create a trajectory without any task system
|
|
976
|
+
agent-relay trajectory new "Refactor payment module"
|
|
977
|
+
|
|
978
|
+
# The trajectory IS the task - like a Notion page
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
### Example: Beads Integration
|
|
982
|
+
|
|
983
|
+
```bash
|
|
984
|
+
# Beads task triggers trajectory automatically
|
|
985
|
+
bd update bd-123 --status=in_progress
|
|
986
|
+
# → Trajectory starts, linked to bd-123
|
|
987
|
+
|
|
988
|
+
bd close bd-123
|
|
989
|
+
# → Trajectory completes, retrospective prompted
|
|
990
|
+
```
|
|
991
|
+
|
|
992
|
+
### Example: Linear/Jira Integration
|
|
993
|
+
|
|
994
|
+
```bash
|
|
995
|
+
# Explicit link to external task
|
|
996
|
+
agent-relay trajectory start --linear ENG-456 "Implement feature"
|
|
997
|
+
|
|
998
|
+
# Or auto-detect from branch name
|
|
999
|
+
git checkout -b feature/ENG-456-auth
|
|
1000
|
+
agent-relay trajectory start # Auto-links to ENG-456
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
---
|
|
1004
|
+
|
|
1005
|
+
## How Trajectories Help
|
|
1006
|
+
|
|
1007
|
+
### 1. Code Review
|
|
1008
|
+
|
|
1009
|
+
**Before:** Reviewer sees a PR with 500 lines changed. Has to guess at intent.
|
|
1010
|
+
|
|
1011
|
+
**After:** Reviewer can:
|
|
1012
|
+
- Read the trajectory summary
|
|
1013
|
+
- See what alternatives were considered
|
|
1014
|
+
- Understand why specific patterns were chosen
|
|
1015
|
+
- Ask pointed questions based on documented decisions
|
|
1016
|
+
- Trust the agent's confidence score
|
|
1017
|
+
|
|
1018
|
+
```markdown
|
|
1019
|
+
## Trajectory Summary for bd-123
|
|
1020
|
+
|
|
1021
|
+
**Approach:** Used React Query instead of Redux for server state because
|
|
1022
|
+
the codebase already has 3 different state management patterns and RQ
|
|
1023
|
+
is isolated to this feature.
|
|
1024
|
+
|
|
1025
|
+
**Key Decisions:**
|
|
1026
|
+
1. Cache invalidation: Chose optimistic updates over refetch because
|
|
1027
|
+
user feedback latency was the primary concern
|
|
1028
|
+
2. Error handling: Retry 3x with exponential backoff, then show inline
|
|
1029
|
+
error (not toast) per UX guidelines in docs/STYLE.md
|
|
1030
|
+
|
|
1031
|
+
**Challenges:** The existing UserContext wasn't typed properly. Fixed
|
|
1032
|
+
types as prerequisite work.
|
|
1033
|
+
|
|
1034
|
+
**Confidence:** 0.85 - Solid solution, but cache invalidation edge cases
|
|
1035
|
+
should be tested under load.
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
### 2. Bug Diagnosis
|
|
1039
|
+
|
|
1040
|
+
**Scenario:** A bug is found 3 months after the feature shipped.
|
|
1041
|
+
|
|
1042
|
+
**Before:** Developer has to:
|
|
1043
|
+
- Read git blame
|
|
1044
|
+
- Guess at original intent
|
|
1045
|
+
- Maybe find a stale PR description
|
|
1046
|
+
- Reconstruct reasoning from scratch
|
|
1047
|
+
|
|
1048
|
+
**After:** Developer can:
|
|
1049
|
+
- Query: "show me the trajectory for the commit that introduced this function"
|
|
1050
|
+
- See the original requirements
|
|
1051
|
+
- See what edge cases were considered (and maybe missed)
|
|
1052
|
+
- See the agent's confidence and caveats
|
|
1053
|
+
- Understand the context that led to this code
|
|
1054
|
+
|
|
1055
|
+
```bash
|
|
1056
|
+
# Find trajectory for a specific change
|
|
1057
|
+
agent-relay trajectory --commit abc123
|
|
1058
|
+
agent-relay trajectory --file src/auth/session.ts --since 2024-01
|
|
1059
|
+
|
|
1060
|
+
# See what the agent was thinking
|
|
1061
|
+
agent-relay trajectory bd-456 --show-thinking
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
### 3. Future Changes
|
|
1065
|
+
|
|
1066
|
+
**Scenario:** Need to extend a feature built by a different agent/developer.
|
|
1067
|
+
|
|
1068
|
+
**Before:** Start from scratch understanding the code.
|
|
1069
|
+
|
|
1070
|
+
**After:**
|
|
1071
|
+
- Read the trajectory to understand architectural decisions
|
|
1072
|
+
- See what approaches were rejected (and why - so you don't repeat them)
|
|
1073
|
+
- Understand the constraints that shaped the original design
|
|
1074
|
+
- Build on documented reasoning rather than guessing
|
|
1075
|
+
|
|
1076
|
+
### 4. Institutional Memory
|
|
1077
|
+
|
|
1078
|
+
Over time, trajectories become a knowledge base:
|
|
1079
|
+
- "How have we solved caching problems before?"
|
|
1080
|
+
- "What patterns did we use for authentication?"
|
|
1081
|
+
- "What libraries did we evaluate for X?"
|
|
1082
|
+
|
|
1083
|
+
```bash
|
|
1084
|
+
# Search across all trajectories
|
|
1085
|
+
agent-relay trajectory search "rate limiting"
|
|
1086
|
+
agent-relay trajectory search --tag "api-design"
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
### 5. Packaging with Code
|
|
1090
|
+
|
|
1091
|
+
Trajectories should live **with the code**, not in a separate system:
|
|
1092
|
+
|
|
1093
|
+
```
|
|
1094
|
+
project/
|
|
1095
|
+
├── src/
|
|
1096
|
+
├── .beads/
|
|
1097
|
+
│ └── issues.jsonl
|
|
1098
|
+
├── .trajectories/
|
|
1099
|
+
│ ├── index.json # Index of all trajectories
|
|
1100
|
+
│ ├── bd-123.json # Full trajectory
|
|
1101
|
+
│ ├── bd-123.summary.md # Human-readable summary
|
|
1102
|
+
│ └── bd-456.json
|
|
1103
|
+
└── README.md
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
**Git integration:**
|
|
1107
|
+
- Trajectories are committed with the code
|
|
1108
|
+
- They're part of the repo's history
|
|
1109
|
+
- They can be reviewed in PRs
|
|
1110
|
+
- They're searchable via git grep
|
|
1111
|
+
|
|
1112
|
+
**Alternatively**, for large repos, store only summaries in git and full trajectories in external storage (S3, database) with references:
|
|
1113
|
+
|
|
1114
|
+
```json
|
|
1115
|
+
{
|
|
1116
|
+
"id": "bd-123",
|
|
1117
|
+
"summary": "...",
|
|
1118
|
+
"fullTrajectoryUrl": "s3://trajectories/project/bd-123.json"
|
|
1119
|
+
}
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
---
|
|
1123
|
+
|
|
1124
|
+
## Storage Architecture
|
|
1125
|
+
|
|
1126
|
+
### Storage Backends
|
|
1127
|
+
|
|
1128
|
+
Trajectories support multiple storage backends:
|
|
1129
|
+
|
|
1130
|
+
| Backend | Use Case | Notes |
|
|
1131
|
+
|---------|----------|-------|
|
|
1132
|
+
| **File system** | Default, git-friendly | `.trajectories/` in repo |
|
|
1133
|
+
| **SQLite** | Local indexing, search | Same DB as messages |
|
|
1134
|
+
| **PostgreSQL** | Multi-user, cloud | Shared team access |
|
|
1135
|
+
| **S3/GCS** | Archive, large teams | Cold storage for old trajectories |
|
|
1136
|
+
|
|
1137
|
+
### File System (Default)
|
|
1138
|
+
|
|
1139
|
+
```
|
|
1140
|
+
.trajectories/
|
|
1141
|
+
├── index.json # Quick lookup index
|
|
1142
|
+
├── active/ # In-progress trajectories
|
|
1143
|
+
│ └── traj_abc123.json
|
|
1144
|
+
├── completed/ # Finished trajectories
|
|
1145
|
+
│ ├── 2024-01/
|
|
1146
|
+
│ │ ├── traj_def456.json
|
|
1147
|
+
│ │ └── traj_def456.md # Human-readable export
|
|
1148
|
+
│ └── 2024-02/
|
|
1149
|
+
└── archive/ # Compressed old trajectories
|
|
1150
|
+
```
|
|
1151
|
+
|
|
1152
|
+
### SQLite Schema
|
|
1153
|
+
|
|
1154
|
+
For search and querying:
|
|
1155
|
+
|
|
1156
|
+
```sql
|
|
1157
|
+
CREATE TABLE trajectories (
|
|
1158
|
+
id TEXT PRIMARY KEY,
|
|
1159
|
+
task_source TEXT, -- 'beads', 'linear', 'github', etc.
|
|
1160
|
+
task_id TEXT, -- External task ID (nullable for standalone)
|
|
1161
|
+
task_title TEXT NOT NULL,
|
|
1162
|
+
project_id TEXT NOT NULL,
|
|
1163
|
+
|
|
1164
|
+
started_at INTEGER NOT NULL,
|
|
1165
|
+
completed_at INTEGER,
|
|
1166
|
+
|
|
1167
|
+
-- Denormalized for queries
|
|
1168
|
+
agent_names TEXT, -- JSON array
|
|
1169
|
+
commit_shas TEXT, -- JSON array
|
|
1170
|
+
files_changed TEXT, -- JSON array
|
|
1171
|
+
|
|
1172
|
+
-- Full data
|
|
1173
|
+
chapters TEXT NOT NULL, -- JSON
|
|
1174
|
+
retrospective TEXT, -- JSON
|
|
1175
|
+
|
|
1176
|
+
-- Metadata
|
|
1177
|
+
version INTEGER DEFAULT 1,
|
|
1178
|
+
created_at INTEGER NOT NULL,
|
|
1179
|
+
updated_at INTEGER NOT NULL
|
|
1180
|
+
);
|
|
1181
|
+
|
|
1182
|
+
CREATE INDEX idx_trajectories_task ON trajectories(task_id);
|
|
1183
|
+
CREATE INDEX idx_trajectories_project ON trajectories(project_id);
|
|
1184
|
+
CREATE INDEX idx_trajectories_started ON trajectories(started_at);
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
### New Table: `trajectory_events`
|
|
1188
|
+
|
|
1189
|
+
For efficient querying of individual events:
|
|
1190
|
+
|
|
1191
|
+
```sql
|
|
1192
|
+
CREATE TABLE trajectory_events (
|
|
1193
|
+
id TEXT PRIMARY KEY,
|
|
1194
|
+
trajectory_id TEXT NOT NULL,
|
|
1195
|
+
chapter_id TEXT NOT NULL,
|
|
1196
|
+
|
|
1197
|
+
ts INTEGER NOT NULL,
|
|
1198
|
+
type TEXT NOT NULL,
|
|
1199
|
+
agent_name TEXT NOT NULL,
|
|
1200
|
+
|
|
1201
|
+
content TEXT NOT NULL,
|
|
1202
|
+
raw TEXT, -- Full JSON (optional)
|
|
1203
|
+
significance TEXT,
|
|
1204
|
+
tags TEXT, -- JSON array
|
|
1205
|
+
|
|
1206
|
+
FOREIGN KEY (trajectory_id) REFERENCES trajectories(id)
|
|
1207
|
+
);
|
|
1208
|
+
|
|
1209
|
+
CREATE INDEX idx_events_trajectory ON trajectory_events(trajectory_id);
|
|
1210
|
+
CREATE INDEX idx_events_type ON trajectory_events(type);
|
|
1211
|
+
CREATE INDEX idx_events_ts ON trajectory_events(ts);
|
|
1212
|
+
```
|
|
1213
|
+
|
|
1214
|
+
### Storage Adapter Extension
|
|
1215
|
+
|
|
1216
|
+
```typescript
|
|
1217
|
+
interface TrajectoryStorageAdapter extends StorageAdapter {
|
|
1218
|
+
// Trajectory CRUD
|
|
1219
|
+
saveTrajectory(trajectory: Trajectory): Promise<void>;
|
|
1220
|
+
getTrajectory(id: string): Promise<Trajectory | null>;
|
|
1221
|
+
getTrajectoryByTaskId(taskId: string): Promise<Trajectory | null>;
|
|
1222
|
+
|
|
1223
|
+
// Queries
|
|
1224
|
+
listTrajectories(query: TrajectoryQuery): Promise<TrajectorySummary[]>;
|
|
1225
|
+
searchTrajectories(text: string): Promise<TrajectorySummary[]>;
|
|
1226
|
+
|
|
1227
|
+
// Events (for streaming/incremental updates)
|
|
1228
|
+
appendEvent(trajectoryId: string, event: TrajectoryEvent): Promise<void>;
|
|
1229
|
+
getEvents(trajectoryId: string, since?: number): Promise<TrajectoryEvent[]>;
|
|
1230
|
+
|
|
1231
|
+
// Export
|
|
1232
|
+
exportTrajectory(id: string, format: 'json' | 'markdown'): Promise<string>;
|
|
1233
|
+
}
|
|
1234
|
+
```
|
|
1235
|
+
|
|
1236
|
+
---
|
|
1237
|
+
|
|
1238
|
+
## Capture Mechanisms
|
|
1239
|
+
|
|
1240
|
+
### 1. Automatic Capture (Wrapper-Level)
|
|
1241
|
+
|
|
1242
|
+
The tmux wrapper already intercepts output. Extend it to capture:
|
|
1243
|
+
|
|
1244
|
+
```typescript
|
|
1245
|
+
// In tmux-wrapper.ts
|
|
1246
|
+
class TrajectoryCapture {
|
|
1247
|
+
private currentTrajectory?: Trajectory;
|
|
1248
|
+
private currentChapter?: Chapter;
|
|
1249
|
+
|
|
1250
|
+
// Called when agent starts work on a task
|
|
1251
|
+
startTrajectory(taskId: string, taskTitle: string): void;
|
|
1252
|
+
|
|
1253
|
+
// Called for each significant event
|
|
1254
|
+
recordEvent(event: Omit<TrajectoryEvent, 'ts'>): void;
|
|
1255
|
+
|
|
1256
|
+
// Called when switching focus
|
|
1257
|
+
startChapter(title: string): void;
|
|
1258
|
+
|
|
1259
|
+
// Called when task completes
|
|
1260
|
+
endTrajectory(): void;
|
|
1261
|
+
}
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
### 2. Explicit Agent Output
|
|
1265
|
+
|
|
1266
|
+
Agents can emit structured trajectory data:
|
|
1267
|
+
|
|
1268
|
+
```
|
|
1269
|
+
[[TRAJECTORY:event]]
|
|
1270
|
+
{
|
|
1271
|
+
"type": "decision",
|
|
1272
|
+
"content": "Chose PostgreSQL over SQLite for production scaling",
|
|
1273
|
+
"significance": "high",
|
|
1274
|
+
"alternatives": ["SQLite with read replicas", "MySQL"],
|
|
1275
|
+
"reasoning": "Team already has PG expertise, and we need JSONB for the schema"
|
|
1276
|
+
}
|
|
1277
|
+
[[/TRAJECTORY]]
|
|
1278
|
+
```
|
|
1279
|
+
|
|
1280
|
+
### 3. Message Integration
|
|
1281
|
+
|
|
1282
|
+
Inter-agent messages are automatically captured:
|
|
1283
|
+
|
|
1284
|
+
```typescript
|
|
1285
|
+
// When routing a message
|
|
1286
|
+
router.on('message', (envelope) => {
|
|
1287
|
+
trajectoryCapture.recordEvent({
|
|
1288
|
+
type: envelope.from === currentAgent ? 'message_sent' : 'message_received',
|
|
1289
|
+
content: envelope.payload.body,
|
|
1290
|
+
agentName: envelope.from,
|
|
1291
|
+
significance: 'medium'
|
|
1292
|
+
});
|
|
1293
|
+
});
|
|
1294
|
+
```
|
|
1295
|
+
|
|
1296
|
+
### 4. Task System Integration
|
|
1297
|
+
|
|
1298
|
+
Trajectories link to external task systems via adapters:
|
|
1299
|
+
|
|
1300
|
+
```typescript
|
|
1301
|
+
// Any adapter can trigger trajectory lifecycle
|
|
1302
|
+
taskAdapter.onTaskStart((task: TaskReference) => {
|
|
1303
|
+
trajectoryCapture.startTrajectory(task);
|
|
1304
|
+
});
|
|
1305
|
+
|
|
1306
|
+
taskAdapter.onTaskComplete((taskId: string) => {
|
|
1307
|
+
trajectoryCapture.endTrajectory();
|
|
1308
|
+
promptForRetrospective();
|
|
1309
|
+
});
|
|
1310
|
+
|
|
1311
|
+
// Example: Beads adapter watches for 'bd update/close'
|
|
1312
|
+
// Example: Linear adapter polls API or uses webhooks
|
|
1313
|
+
// Example: GitHub adapter watches for issue state changes
|
|
1314
|
+
```
|
|
1315
|
+
|
|
1316
|
+
---
|
|
1317
|
+
|
|
1318
|
+
## Retrospectives
|
|
1319
|
+
|
|
1320
|
+
Encourage agents to reflect by:
|
|
1321
|
+
|
|
1322
|
+
### 1. Automatic Prompting
|
|
1323
|
+
|
|
1324
|
+
When an agent completes a task (via any task system or manually), inject:
|
|
1325
|
+
|
|
1326
|
+
```
|
|
1327
|
+
📝 RETROSPECTIVE REQUEST
|
|
1328
|
+
|
|
1329
|
+
You just completed: "Implement user authentication"
|
|
1330
|
+
|
|
1331
|
+
Please reflect on your work by outputting a retrospective:
|
|
1332
|
+
|
|
1333
|
+
[[RETROSPECTIVE]]
|
|
1334
|
+
{
|
|
1335
|
+
"summary": "What did you accomplish?",
|
|
1336
|
+
"approach": "How did you approach it?",
|
|
1337
|
+
"decisions": [
|
|
1338
|
+
{"question": "...", "chosen": "...", "alternatives": [...], "reasoning": "..."}
|
|
1339
|
+
],
|
|
1340
|
+
"challenges": ["What was difficult?"],
|
|
1341
|
+
"learnings": ["What did you learn?"],
|
|
1342
|
+
"suggestions": ["What could be improved?"],
|
|
1343
|
+
"confidence": 0.85
|
|
1344
|
+
}
|
|
1345
|
+
[[/RETROSPECTIVE]]
|
|
1346
|
+
```
|
|
1347
|
+
|
|
1348
|
+
### 2. Structured Templates
|
|
1349
|
+
|
|
1350
|
+
Provide templates that make it easy:
|
|
1351
|
+
|
|
1352
|
+
```typescript
|
|
1353
|
+
const RETROSPECTIVE_TEMPLATE = {
|
|
1354
|
+
prompts: {
|
|
1355
|
+
summary: "Summarize what was accomplished in 1-2 sentences",
|
|
1356
|
+
approach: "Describe the high-level approach taken",
|
|
1357
|
+
decisions: "List the key decisions made and why",
|
|
1358
|
+
challenges: "What was unexpectedly difficult?",
|
|
1359
|
+
learnings: "What would you do differently next time?",
|
|
1360
|
+
suggestions: "Any improvements for the codebase or process?",
|
|
1361
|
+
confidence: "Rate your confidence in the solution (0-1)"
|
|
1362
|
+
}
|
|
1363
|
+
};
|
|
1364
|
+
```
|
|
1365
|
+
|
|
1366
|
+
### 3. Gamification (Optional)
|
|
1367
|
+
|
|
1368
|
+
- Track retrospective completion rates per agent
|
|
1369
|
+
- Show "trajectory completeness" scores
|
|
1370
|
+
- Surface trajectories that lack retrospectives
|
|
1371
|
+
|
|
1372
|
+
---
|
|
1373
|
+
|
|
1374
|
+
## CLI Commands
|
|
1375
|
+
|
|
1376
|
+
```bash
|
|
1377
|
+
# Start tracking a task
|
|
1378
|
+
agent-relay trajectory start bd-123 "Implement auth module"
|
|
1379
|
+
|
|
1380
|
+
# View current trajectory
|
|
1381
|
+
agent-relay trajectory status
|
|
1382
|
+
|
|
1383
|
+
# Add a decision point manually
|
|
1384
|
+
agent-relay trajectory decision "Chose JWT over sessions" \
|
|
1385
|
+
--reasoning "Stateless scaling requirements" \
|
|
1386
|
+
--alternatives "sessions" "oauth tokens"
|
|
1387
|
+
|
|
1388
|
+
# Complete and generate retrospective
|
|
1389
|
+
agent-relay trajectory complete bd-123
|
|
1390
|
+
|
|
1391
|
+
# Export for code review
|
|
1392
|
+
agent-relay trajectory export bd-123 --format markdown > trajectory.md
|
|
1393
|
+
|
|
1394
|
+
# Search trajectories
|
|
1395
|
+
agent-relay trajectory search "authentication"
|
|
1396
|
+
agent-relay trajectory list --agent Alice --since 2024-01-01
|
|
1397
|
+
|
|
1398
|
+
# View trajectory for a commit
|
|
1399
|
+
agent-relay trajectory --commit abc123
|
|
1400
|
+
|
|
1401
|
+
# Package trajectories for PR
|
|
1402
|
+
agent-relay trajectory bundle bd-123 bd-124 --output pr-trajectories.md
|
|
1403
|
+
```
|
|
1404
|
+
|
|
1405
|
+
---
|
|
1406
|
+
|
|
1407
|
+
## Export Formats
|
|
1408
|
+
|
|
1409
|
+
### Markdown (for PRs and docs)
|
|
1410
|
+
|
|
1411
|
+
```markdown
|
|
1412
|
+
# Trajectory: Implement User Authentication (bd-123)
|
|
1413
|
+
|
|
1414
|
+
**Duration:** 2 hours 34 minutes
|
|
1415
|
+
**Agents:** Alice (lead), Bob (review)
|
|
1416
|
+
**Commits:** abc123, def456
|
|
1417
|
+
**Confidence:** 0.85
|
|
1418
|
+
|
|
1419
|
+
## Summary
|
|
1420
|
+
|
|
1421
|
+
Implemented JWT-based authentication with refresh tokens...
|
|
1422
|
+
|
|
1423
|
+
## Key Decisions
|
|
1424
|
+
|
|
1425
|
+
### 1. JWT vs Sessions
|
|
1426
|
+
**Chose:** JWT with refresh tokens
|
|
1427
|
+
**Rejected:** Server-side sessions
|
|
1428
|
+
**Reasoning:** Stateless scaling requirement, multiple server deployment planned
|
|
1429
|
+
|
|
1430
|
+
### 2. Token Storage
|
|
1431
|
+
**Chose:** HttpOnly cookies
|
|
1432
|
+
**Rejected:** localStorage
|
|
1433
|
+
**Reasoning:** XSS protection more important than API flexibility
|
|
1434
|
+
|
|
1435
|
+
## Challenges
|
|
1436
|
+
|
|
1437
|
+
- Existing UserContext types were incorrect, required fixing first
|
|
1438
|
+
- Rate limiting middleware had race condition, refactored
|
|
1439
|
+
|
|
1440
|
+
## Retrospective
|
|
1441
|
+
|
|
1442
|
+
The implementation is solid but the refresh token rotation logic
|
|
1443
|
+
should be tested more thoroughly under load. Consider adding
|
|
1444
|
+
integration tests for the token refresh flow.
|
|
1445
|
+
```
|
|
1446
|
+
|
|
1447
|
+
### JSON (for tooling)
|
|
1448
|
+
|
|
1449
|
+
Full structured format for programmatic access.
|
|
1450
|
+
|
|
1451
|
+
### Git Notes (experimental)
|
|
1452
|
+
|
|
1453
|
+
Attach trajectory summaries to commits via git notes:
|
|
1454
|
+
|
|
1455
|
+
```bash
|
|
1456
|
+
git notes add -m "$(agent-relay trajectory export abc123 --format summary)" abc123
|
|
1457
|
+
```
|
|
1458
|
+
|
|
1459
|
+
---
|
|
1460
|
+
|
|
1461
|
+
## Privacy & Security Considerations
|
|
1462
|
+
|
|
1463
|
+
1. **Thinking blocks:** May contain sensitive reasoning. Option to redact or summarize.
|
|
1464
|
+
|
|
1465
|
+
2. **Credentials:** Trajectory capture must never log secrets. Sanitize:
|
|
1466
|
+
- Environment variables
|
|
1467
|
+
- API keys
|
|
1468
|
+
- Passwords in commands
|
|
1469
|
+
|
|
1470
|
+
3. **Retention:** Configurable retention periods. Old trajectories can be:
|
|
1471
|
+
- Archived (compressed, moved to cold storage)
|
|
1472
|
+
- Summarized (keep retrospective, delete events)
|
|
1473
|
+
- Deleted
|
|
1474
|
+
|
|
1475
|
+
4. **Access control:** In multi-tenant scenarios, trajectories should respect permissions.
|
|
1476
|
+
|
|
1477
|
+
---
|
|
1478
|
+
|
|
1479
|
+
## Migration Path
|
|
1480
|
+
|
|
1481
|
+
### Phase 1: Foundation
|
|
1482
|
+
- Define trajectory JSON schema (v1)
|
|
1483
|
+
- File-based storage (`.trajectories/` directory)
|
|
1484
|
+
- CLI: `trajectory new`, `trajectory status`, `trajectory complete`
|
|
1485
|
+
- Manual capture via `[[TRAJECTORY:*]]` blocks
|
|
1486
|
+
|
|
1487
|
+
### Phase 2: Task Adapters
|
|
1488
|
+
- Beads adapter (auto-start on `bd update --status=in_progress`)
|
|
1489
|
+
- GitHub adapter (link to issues/PRs)
|
|
1490
|
+
- Plain adapter (standalone trajectories)
|
|
1491
|
+
- Adapter plugin interface for custom systems
|
|
1492
|
+
|
|
1493
|
+
### Phase 3: Automatic Capture
|
|
1494
|
+
- Message capture from router
|
|
1495
|
+
- Retrospective prompting on task complete
|
|
1496
|
+
- SQLite indexing for search
|
|
1497
|
+
|
|
1498
|
+
### Phase 4: Human-Readable Layer
|
|
1499
|
+
- Markdown export (Notion-style pages)
|
|
1500
|
+
- Timeline view (Linear-style)
|
|
1501
|
+
- PR/commit integration
|
|
1502
|
+
- Trajectory viewer in dashboard
|
|
1503
|
+
|
|
1504
|
+
### Phase 5: Intelligence
|
|
1505
|
+
- Auto-summarization (LLM-generated summaries)
|
|
1506
|
+
- Decision extraction from conversation
|
|
1507
|
+
- Cross-trajectory search and analysis
|
|
1508
|
+
- Similarity detection ("how did we solve this before?")
|
|
1509
|
+
|
|
1510
|
+
---
|
|
1511
|
+
|
|
1512
|
+
## Open Questions
|
|
1513
|
+
|
|
1514
|
+
1. **Storage location:** `.trajectories/` in repo vs external database?
|
|
1515
|
+
- In-repo: Versioned with code, but bloats repo
|
|
1516
|
+
- External: Scalable, but requires infra
|
|
1517
|
+
|
|
1518
|
+
2. **Granularity:** How much detail to capture?
|
|
1519
|
+
- Every tool call? Just summaries?
|
|
1520
|
+
- Full thinking blocks? Summarized?
|
|
1521
|
+
|
|
1522
|
+
3. **Multi-agent coordination:** How to merge trajectories when agents collaborate?
|
|
1523
|
+
- One trajectory per task, multiple chapters per agent?
|
|
1524
|
+
- Separate trajectories with cross-references?
|
|
1525
|
+
|
|
1526
|
+
4. **Real-time vs batch:** Capture incrementally or at end?
|
|
1527
|
+
- Incremental: Survives crashes, but more I/O
|
|
1528
|
+
- Batch: Simpler, but loses data on failure
|
|
1529
|
+
|
|
1530
|
+
5. **Retrospective quality:** How to encourage thoughtful retrospectives?
|
|
1531
|
+
- Structured prompts?
|
|
1532
|
+
- Required fields?
|
|
1533
|
+
- Quality scoring?
|
|
1534
|
+
|
|
1535
|
+
---
|
|
1536
|
+
|
|
1537
|
+
## Success Metrics
|
|
1538
|
+
|
|
1539
|
+
1. **Adoption:** % of closed tasks with trajectories
|
|
1540
|
+
2. **Completeness:** Avg retrospective quality score
|
|
1541
|
+
3. **Utility:** How often trajectories are referenced in code review
|
|
1542
|
+
4. **Bug resolution:** Time to understand bugs in code with trajectories vs without
|
|
1543
|
+
5. **Onboarding:** Time for new developers to understand features with trajectories
|
|
1544
|
+
|
|
1545
|
+
---
|
|
1546
|
+
|
|
1547
|
+
## Conclusion
|
|
1548
|
+
|
|
1549
|
+
Train of thought trajectories transform ephemeral agent work into durable knowledge. By capturing the *why* alongside the *what*, we create a searchable, reviewable, portable record that:
|
|
1550
|
+
|
|
1551
|
+
- Makes code review meaningful
|
|
1552
|
+
- Accelerates bug diagnosis
|
|
1553
|
+
- Preserves institutional knowledge
|
|
1554
|
+
- Enables learning from past work
|
|
1555
|
+
- Builds trust in agent-generated code
|
|
1556
|
+
|
|
1557
|
+
The key insight is that **the trajectory is as valuable as the code**. Just as we version control source, we should version control the reasoning that produced it.
|
|
1558
|
+
|
|
1559
|
+
---
|
|
1560
|
+
|
|
1561
|
+
## References & Inspiration
|
|
1562
|
+
|
|
1563
|
+
### Industry Context
|
|
1564
|
+
|
|
1565
|
+
**Gergely Orosz (Pragmatic Engineer)** on agent trajectories:
|
|
1566
|
+
- Tweet: https://x.com/gergelyorosz/status/2002160432841097239
|
|
1567
|
+
- From ["How do AI software engineering agents work?"](https://newsletter.pragmaticengineer.com/p/ai-coding-agents):
|
|
1568
|
+
> "The trajectory of the run. Trajectory refers to the full history log of the run. It usually takes the agent about 10 'turns' to reach the point of attempting to submit a solution."
|
|
1569
|
+
|
|
1570
|
+
**SWE-agent (Princeton)** - Open-source coding agent that popularized the "trajectory" terminology for agent run histories.
|
|
1571
|
+
|
|
1572
|
+
### Related Observations
|
|
1573
|
+
|
|
1574
|
+
From Gergely's tweets on AI agents:
|
|
1575
|
+
- "A BIG difference with AI agents: they will write more code, faster than before, and ship a LOT more code to prod! So ship more bugs as well."
|
|
1576
|
+
- "AI agents being able to run unit tests is SUCH a massive unlock."
|
|
1577
|
+
- "Working with multiple AI agents comes VERY natural to senior+ engineers who worked at large companies - you already got used to overseeing parallel work."
|
|
1578
|
+
|
|
1579
|
+
These insights reinforce why trajectory capture matters:
|
|
1580
|
+
1. **More code, faster** → Need better traceability
|
|
1581
|
+
2. **Parallel agent work** → Need coordination history
|
|
1582
|
+
3. **Bug diagnosis** → Need to understand what the agent was thinking
|