let-them-talk 5.2.5 → 5.4.0
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/CHANGELOG.md +3 -1
- package/README.md +158 -592
- package/SECURITY.md +3 -3
- package/USAGE.md +151 -0
- package/agent-contracts.js +447 -0
- package/api-agents.js +760 -0
- package/autonomy/decision-v2.js +380 -0
- package/autonomy/watchdog-policy.js +572 -0
- package/cli.js +454 -298
- package/conversation-templates/autonomous-feature.json +83 -22
- package/conversation-templates/code-review.json +69 -21
- package/conversation-templates/debug-squad.json +69 -21
- package/conversation-templates/feature-build.json +69 -21
- package/conversation-templates/research-write.json +69 -21
- package/dashboard.html +3148 -174
- package/dashboard.js +823 -786
- package/data-dir.js +58 -0
- package/docs/architecture/branch-semantics.md +157 -0
- package/docs/architecture/canonical-event-schema.md +88 -0
- package/docs/architecture/markdown-workspace.md +183 -0
- package/docs/architecture/runtime-contract.md +459 -0
- package/docs/architecture/runtime-migration-hardening.md +64 -0
- package/events/hooks.js +154 -0
- package/events/log.js +457 -0
- package/events/replay.js +33 -0
- package/events/schema.js +432 -0
- package/managed-team-integration.js +261 -0
- package/office/agents.js +704 -597
- package/office/animation.js +1 -1
- package/office/assets/arcade-cabinet.js +141 -0
- package/office/assets/archway.js +77 -0
- package/office/assets/bar-counter.js +91 -0
- package/office/assets/bar-stool.js +71 -0
- package/office/assets/beanbag.js +64 -0
- package/office/assets/bench.js +99 -0
- package/office/assets/bollard.js +87 -0
- package/office/assets/cactus.js +100 -0
- package/office/assets/carpet-tile.js +46 -0
- package/office/assets/chair.js +123 -0
- package/office/assets/chandelier.js +107 -0
- package/office/assets/coffee-machine.js +95 -0
- package/office/assets/coffee-table.js +81 -0
- package/office/assets/column.js +95 -0
- package/office/assets/desk-lamp.js +102 -0
- package/office/assets/desk.js +76 -0
- package/office/assets/dining-table.js +105 -0
- package/office/assets/door.js +70 -0
- package/office/assets/dual-monitor.js +72 -0
- package/office/assets/fence.js +76 -0
- package/office/assets/filing-cabinet.js +111 -0
- package/office/assets/floor-lamp.js +69 -0
- package/office/assets/floor-tile.js +54 -0
- package/office/assets/flower-pot.js +76 -0
- package/office/assets/foosball.js +95 -0
- package/office/assets/fridge.js +99 -0
- package/office/assets/gaming-chair.js +154 -0
- package/office/assets/gaming-desk.js +105 -0
- package/office/assets/glass-door.js +72 -0
- package/office/assets/glass-wall.js +64 -0
- package/office/assets/half-wall.js +49 -0
- package/office/assets/hanging-plant.js +112 -0
- package/office/assets/index.js +151 -0
- package/office/assets/indoor-tree.js +90 -0
- package/office/assets/l-sofa.js +153 -0
- package/office/assets/marble-floor.js +64 -0
- package/office/assets/materials.js +40 -0
- package/office/assets/meeting-table.js +88 -0
- package/office/assets/microwave.js +94 -0
- package/office/assets/monitor.js +67 -0
- package/office/assets/neon-strip.js +73 -0
- package/office/assets/painting.js +84 -0
- package/office/assets/palm-tree.js +108 -0
- package/office/assets/pc-tower.js +91 -0
- package/office/assets/pendant-light.js +67 -0
- package/office/assets/ping-pong.js +114 -0
- package/office/assets/plant.js +72 -0
- package/office/assets/planter-box.js +95 -0
- package/office/assets/pool-table.js +94 -0
- package/office/assets/printer.js +113 -0
- package/office/assets/reception-desk.js +133 -0
- package/office/assets/rug.js +78 -0
- package/office/assets/sculpture.js +85 -0
- package/office/assets/server-rack.js +98 -0
- package/office/assets/sink.js +109 -0
- package/office/assets/sofa.js +106 -0
- package/office/assets/speaker.js +83 -0
- package/office/assets/spotlight.js +83 -0
- package/office/assets/street-lamp.js +97 -0
- package/office/assets/trash-can.js +83 -0
- package/office/assets/treadmill.js +126 -0
- package/office/assets/trophy.js +89 -0
- package/office/assets/tv-screen.js +79 -0
- package/office/assets/vase.js +84 -0
- package/office/assets/wall-clock.js +84 -0
- package/office/assets/wall.js +53 -0
- package/office/assets/water-cooler.js +146 -0
- package/office/assets/whiteboard.js +115 -0
- package/office/assets.js +3 -431
- package/office/builder.js +791 -355
- package/office/campus-env.js +1012 -1119
- package/office/environment.js +2 -0
- package/office/gallery.js +997 -0
- package/office/index.js +165 -61
- package/office/navigation.js +173 -152
- package/office/player.js +178 -68
- package/office/robot-character.js +272 -0
- package/office/spectator-camera.js +33 -10
- package/office/state.js +2 -0
- package/office/world-save.js +35 -4
- package/package.json +57 -3
- package/providers/comfyui.js +383 -0
- package/providers/dalle.js +79 -0
- package/providers/gemini.js +181 -0
- package/providers/ollama.js +184 -0
- package/providers/replicate.js +115 -0
- package/providers/zai.js +183 -0
- package/runtime-descriptor.js +270 -0
- package/scripts/check-agent-contract-advisory.js +132 -0
- package/scripts/check-api-agent-parity.js +277 -0
- package/scripts/check-autonomy-v2-decision.js +207 -0
- package/scripts/check-autonomy-v2-execution.js +588 -0
- package/scripts/check-autonomy-v2-watchdog.js +224 -0
- package/scripts/check-branch-fork-snapshot.js +337 -0
- package/scripts/check-branch-isolation.js +787 -0
- package/scripts/check-branch-semantics.js +139 -0
- package/scripts/check-dashboard-control-plane.js +1304 -0
- package/scripts/check-docs-onboarding.js +490 -0
- package/scripts/check-event-schema.js +276 -0
- package/scripts/check-evidence-completion.js +239 -0
- package/scripts/check-invariants.js +992 -0
- package/scripts/check-lifecycle-hooks.js +525 -0
- package/scripts/check-managed-team-integration.js +166 -0
- package/scripts/check-markdown-workspace-export.js +548 -0
- package/scripts/check-markdown-workspace-safety.js +347 -0
- package/scripts/check-markdown-workspace.js +136 -0
- package/scripts/check-message-replay.js +429 -0
- package/scripts/check-migration-hardening.js +300 -0
- package/scripts/check-performance-indexing.js +272 -0
- package/scripts/check-provider-capabilities.js +316 -0
- package/scripts/check-runtime-contract.js +109 -0
- package/scripts/check-session-aware-context.js +172 -0
- package/scripts/check-session-lifecycle.js +210 -0
- package/scripts/export-markdown-workspace.js +84 -0
- package/scripts/fixtures/message-replay/clean.jsonl +2 -0
- package/scripts/fixtures/message-replay/corrupt-correction-payload.jsonl +1 -0
- package/scripts/fixtures/message-replay/corrupt-jsonl.jsonl +1 -0
- package/scripts/fixtures/message-replay/corrupt-payload.jsonl +1 -0
- package/scripts/fixtures/message-replay/out-of-order.jsonl +2 -0
- package/scripts/migrate-legacy-to-canonical.js +201 -0
- package/scripts/run-verification-suite.js +242 -0
- package/scripts/sync-packaged-docs.js +69 -0
- package/server.js +9546 -7214
- package/state/agents.js +161 -0
- package/state/canonical.js +3068 -0
- package/state/dashboard-queries.js +441 -0
- package/state/evidence.js +56 -0
- package/state/io.js +69 -0
- package/state/markdown-workspace.js +951 -0
- package/state/messages.js +669 -0
- package/state/sessions.js +683 -0
- package/state/tasks-workflows.js +92 -0
- package/templates/debate.json +2 -2
- package/templates/managed.json +4 -4
- package/templates/pair.json +2 -2
- package/templates/review.json +2 -2
- package/templates/team.json +3 -3
package/data-dir.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const DEFAULT_DATA_DIR_NAME = '.agent-bridge';
|
|
5
|
+
const DEFAULT_MARKDOWN_WORKSPACE_DIR_NAME = '.agent-bridge-markdown';
|
|
6
|
+
const DATA_DIR_ENV_KEYS = Object.freeze(['AGENT_BRIDGE_DATA_DIR', 'AGENT_BRIDGE_DATA']);
|
|
7
|
+
|
|
8
|
+
function resolveExplicitDataDir(env = process.env) {
|
|
9
|
+
for (const key of DATA_DIR_ENV_KEYS) {
|
|
10
|
+
const value = env[key];
|
|
11
|
+
if (typeof value === 'string' && value.trim()) return value;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function isWithinDir(parentDir, childDir) {
|
|
17
|
+
const relative = path.relative(parentDir, childDir);
|
|
18
|
+
return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function resolveRepoRootForLocalDev(moduleDir = __dirname) {
|
|
22
|
+
const packageDir = path.resolve(moduleDir);
|
|
23
|
+
const repoRoot = path.resolve(packageDir, '..');
|
|
24
|
+
|
|
25
|
+
if (path.basename(packageDir) !== 'agent-bridge') return null;
|
|
26
|
+
if (path.resolve(repoRoot, 'agent-bridge') !== packageDir) return null;
|
|
27
|
+
|
|
28
|
+
const packageJson = path.join(packageDir, 'package.json');
|
|
29
|
+
const rootPackageJson = path.join(repoRoot, 'package.json');
|
|
30
|
+
if (!fs.existsSync(packageJson) || !fs.existsSync(rootPackageJson)) return null;
|
|
31
|
+
|
|
32
|
+
return repoRoot;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function resolveDefaultDataRoot({ cwd = process.cwd(), moduleDir = __dirname } = {}) {
|
|
36
|
+
const resolvedCwd = path.resolve(cwd);
|
|
37
|
+
const packageDir = path.resolve(moduleDir);
|
|
38
|
+
const repoRoot = resolveRepoRootForLocalDev(moduleDir);
|
|
39
|
+
|
|
40
|
+
if (repoRoot && isWithinDir(packageDir, resolvedCwd)) {
|
|
41
|
+
return repoRoot;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return resolvedCwd;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function resolveDataDir({ env = process.env, cwd = process.cwd(), moduleDir = __dirname } = {}) {
|
|
48
|
+
return resolveExplicitDataDir(env) || path.join(resolveDefaultDataRoot({ cwd, moduleDir }), DEFAULT_DATA_DIR_NAME);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = {
|
|
52
|
+
DEFAULT_DATA_DIR_NAME,
|
|
53
|
+
DEFAULT_MARKDOWN_WORKSPACE_DIR_NAME,
|
|
54
|
+
isWithinDir,
|
|
55
|
+
resolveExplicitDataDir,
|
|
56
|
+
resolveDefaultDataRoot,
|
|
57
|
+
resolveDataDir,
|
|
58
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
<!-- Generated from ../docs/architecture/branch-semantics.md by scripts/sync-packaged-docs.js for published package consumers. -->
|
|
2
|
+
|
|
3
|
+
# LetThemTalk Branch Semantics Reference
|
|
4
|
+
|
|
5
|
+
Status: normative current-runtime branch reference
|
|
6
|
+
Normative parent: `docs/architecture/runtime-contract.md`
|
|
7
|
+
Schema companion: `docs/architecture/canonical-event-schema.md`
|
|
8
|
+
Current-code anchors: `server.js`, `state/canonical.js`, `state/tasks-workflows.js`, `state/agents.js`, `dashboard.js`
|
|
9
|
+
Last updated: 2026-04-17
|
|
10
|
+
|
|
11
|
+
This document freezes the implementation-driving meaning of the runtime-contract rule that a branch is a full-context namespace. It reflects the shipped runtime after the branch-local isolation work for delivery and read state, conversation control, non-general channels, workspaces, tasks, workflows, governance surfaces, sessions, and evidence.
|
|
12
|
+
|
|
13
|
+
Legacy compatibility filenames remain implementation details during migration. They are not a third semantic bucket, and they do not change the rule that agent-visible collaboration state belongs to the branch-local bucket.
|
|
14
|
+
|
|
15
|
+
## Two-bucket scope model
|
|
16
|
+
|
|
17
|
+
### Runtime-global bucket
|
|
18
|
+
|
|
19
|
+
Runtime-global state is the small set that describes the shared local runtime or shared working tree rather than branch reasoning state.
|
|
20
|
+
|
|
21
|
+
Canonical runtime-global state:
|
|
22
|
+
- agent registry, liveness, heartbeat, branch pointer, and session/branch discovery indexes,
|
|
23
|
+
- profiles,
|
|
24
|
+
- file locks,
|
|
25
|
+
- branch registry plus runtime manifest/migration metadata.
|
|
26
|
+
|
|
27
|
+
Runtime-owned but non-canonical shared state:
|
|
28
|
+
- plugin registry/code,
|
|
29
|
+
- dashboard discovery, LAN/auth/operator settings, and project lists,
|
|
30
|
+
- temp files, lock files, migration backups, and similar operational artifacts.
|
|
31
|
+
|
|
32
|
+
Forking or switching branches MUST NOT clone, fork, or reinterpret this bucket.
|
|
33
|
+
|
|
34
|
+
### Branch-local bucket
|
|
35
|
+
|
|
36
|
+
Branch-local state is every agent-visible collaboration or reasoning surface.
|
|
37
|
+
|
|
38
|
+
Shipped branch-local state today:
|
|
39
|
+
- messages/history and canonical branch message events,
|
|
40
|
+
- delivery/read state such as consumed offsets, acknowledgements, read receipts, and compressed history,
|
|
41
|
+
- conversation mode, managed-floor state, phase state, and non-general channel state,
|
|
42
|
+
- workspaces,
|
|
43
|
+
- decisions, KB, reviews, dependencies, votes, rules, and progress,
|
|
44
|
+
- sessions and evidence,
|
|
45
|
+
- tasks and workflows.
|
|
46
|
+
|
|
47
|
+
Derived branch-local read models:
|
|
48
|
+
- channel projections and other per-branch read models derived from branch-local events.
|
|
49
|
+
|
|
50
|
+
Switching branches MUST replace the whole migrated branch-local bucket at once. It MUST NOT switch only message/history while leaving the rest shared. The shipped runtime already does that for the branch-local domains above.
|
|
51
|
+
|
|
52
|
+
## Fork-time snapshot semantics
|
|
53
|
+
|
|
54
|
+
### Inherited branch-local state
|
|
55
|
+
|
|
56
|
+
Branch creation snapshots the migrated branch-local state that the current fork implementation explicitly copies from the source branch at the fork point. Snapshot inheritance is copy-on-fork, not a live overlay.
|
|
57
|
+
|
|
58
|
+
The inherited snapshot includes:
|
|
59
|
+
- visible messages/history at the fork point,
|
|
60
|
+
- delivery/read state and channel projections needed to preserve what each agent had already consumed, acknowledged, or read at the fork point,
|
|
61
|
+
- conversation metadata and non-general channel state,
|
|
62
|
+
- governance state such as decisions, KB, reviews, dependencies, votes, rules, and progress,
|
|
63
|
+
- task/workflow state,
|
|
64
|
+
- historical evidence context relevant to the copied branch-local state, including preserved session references inside copied evidence.
|
|
65
|
+
|
|
66
|
+
Implementations may materialize the snapshot eagerly or lazily, but reads in the new branch MUST behave as if this full snapshot existed from branch creation onward.
|
|
67
|
+
|
|
68
|
+
### Non-inherited / shared runtime state
|
|
69
|
+
|
|
70
|
+
The runtime-global bucket remains shared across branches and is not copied into a new namespace. That includes agent liveness, profiles, locks, branch registry, manifest/migration state, and runtime-owned operator/discovery files.
|
|
71
|
+
|
|
72
|
+
File locks stay global because the working tree is shared. Lock records may carry branch/session metadata for audit or UI explanation, but the lock scope itself is runtime-global.
|
|
73
|
+
|
|
74
|
+
### Session and evidence snapshot rules
|
|
75
|
+
|
|
76
|
+
Historical evidence records are inherited as branch-local context. Active sessions do not stay live across a fork, and the target branch does not start with copied session manifests or cloned live execution.
|
|
77
|
+
|
|
78
|
+
The first post-fork action on the target branch MUST create or resume a distinct branch-scoped session. After the fork, new evidence recorded in one branch MUST NOT appear in the other branch unless a later explicit cross-branch feature is introduced.
|
|
79
|
+
|
|
80
|
+
## Branch-local read/write resolution
|
|
81
|
+
|
|
82
|
+
### Read resolution
|
|
83
|
+
|
|
84
|
+
A branch-local read resolves against exactly one branch namespace.
|
|
85
|
+
|
|
86
|
+
Resolution order:
|
|
87
|
+
1. explicit `branch_id`, if provided;
|
|
88
|
+
2. otherwise the caller's active session branch;
|
|
89
|
+
3. otherwise reject the read as under-scoped.
|
|
90
|
+
|
|
91
|
+
A branch-local read MUST NOT fall back to another branch, to `main`, or to a shared global collaboration file. If a projection is missing or stale, the runtime rebuilds it from the target branch snapshot/events for that same branch.
|
|
92
|
+
|
|
93
|
+
### Write resolution
|
|
94
|
+
|
|
95
|
+
A branch-local write resolves against exactly one target branch.
|
|
96
|
+
|
|
97
|
+
Rules:
|
|
98
|
+
- mutating collaboration commands write to the caller's explicit `branch_id` or active session branch,
|
|
99
|
+
- the write appends canonical events and/or updates projections for that branch only,
|
|
100
|
+
- branch-local writes in branch `B` MUST NOT mutate branch `A`,
|
|
101
|
+
- compatibility-shared legacy filenames during migration are leak points, not semantic exceptions.
|
|
102
|
+
|
|
103
|
+
Runtime-global writes ignore branch switching for scope purposes, although they may record origin branch/session metadata when that helps explain the action.
|
|
104
|
+
|
|
105
|
+
### Missing projection / rebuild behavior
|
|
106
|
+
|
|
107
|
+
Projection absence does not widen scope. Missing branch-local projections are rebuilt from the target branch snapshot and subsequent branch-local events. They are never reconstructed by reading another branch's projection or by treating a global legacy file as the branch source of truth.
|
|
108
|
+
|
|
109
|
+
## Domain matrix
|
|
110
|
+
|
|
111
|
+
| Domain | Current storage/runtime reality | Frozen target scope | Fork-time inheritance | Read/write resolution | Migration priority |
|
|
112
|
+
| --- | --- | --- | --- | --- | --- |
|
|
113
|
+
| Messages / history / canonical message events | `server.js` and `state/canonical.js` resolve branch-specific message/history files and branch-local canonical message events | Branch-local | Snapshot visible conversation at fork point, then diverge independently | Read/write only against the selected branch stream/projections | Shipped |
|
|
114
|
+
| Delivery/read markers (`consumed-*`, acknowledgements, read receipts, compressed history) | `state/canonical.js` resolves branch-specific `acks.json`, `read_receipts.json`, `compressed.json`, and `consumed-*` files | Branch-local derived state | Snapshot marker state at fork point | Resolve inside the active branch namespace; no cross-branch fallback | Shipped |
|
|
115
|
+
| Conversation metadata and non-general channels | `state/canonical.js` resolves branch-specific `config.json`, `channels.json`, and non-general channel message/history files | Branch-local | Snapshot mode, phase, manager/floor, membership, and channel history state | Branch switch flips the whole conversation namespace at once | Shipped |
|
|
116
|
+
| Tasks | `state/tasks-workflows.js` and `state/canonical.js` resolve `tasks.json` on `main` and `branch-<branch>-tasks.json` elsewhere through branch-aware mutators and dashboard reads | Branch-local | Snapshot copied at fork point | Read/write only inside target branch | Shipped |
|
|
117
|
+
| Workflows | `state/tasks-workflows.js`, `state/canonical.js`, and `dashboard.js` resolve branch-specific workflow files and branch-aware plan reads | Branch-local | Snapshot copied at fork point | Read/write only inside target branch | Shipped |
|
|
118
|
+
| Workspaces | `state/canonical.js`, `server.js`, and `dashboard.js` resolve `workspaces/<agent>.json` on `main` and `branch-<branch>-workspaces/<agent>.json` elsewhere through branch-aware reads, writes, and export paths | Branch-local per-agent state | Snapshot copied at fork point | Read/write only inside the selected branch workspace namespace | Shipped |
|
|
119
|
+
| Decisions / KB / reviews / dependencies / votes / rules / progress | `state/canonical.js`, `server.js`, `dashboard.js`, and markdown/export validators resolve branch-specific governance projections through canonical branch-aware helpers (`decisions.json` on `main`, `branch-<branch>-*.json` elsewhere) | Branch-local | Snapshot copied at fork point | Read/write only inside target branch; cross-branch summaries iterate branch-local views explicitly | Shipped |
|
|
120
|
+
| Sessions / evidence | Runtime branch session manifests live under `.agent-bridge/runtime/branches/<branch>/sessions/`, with a runtime-global `sessions-index.json` plus branch-specific evidence stores | Branch-local with a runtime-global discovery index | Historical evidence context copies; live sessions do not stay active in the forked branch, and session manifests are not fork-copied | Branch switch suspends one branch session and creates/resumes another | Shipped |
|
|
121
|
+
| Agent registry / profiles | `state/agents.js` persists shared `agents.json`, `profiles.json`, and heartbeat files | Runtime-global | Shared, not copied | Branch switch updates discovery metadata, not branch-local collaboration state | Stay global |
|
|
122
|
+
| Locks / branch registry / manifest / migration metadata | Shared working-tree/runtime surfaces | Runtime-global | Shared, not copied | Never branch-local | Stay global |
|
|
123
|
+
|
|
124
|
+
## Current leak points / migration-first priorities
|
|
125
|
+
|
|
126
|
+
### Former P0 leaks now closed
|
|
127
|
+
|
|
128
|
+
The following Task 4 P0 leak statements are historical reference points now, not current runtime truth:
|
|
129
|
+
|
|
130
|
+
1. Delivery/read state is still effectively global.
|
|
131
|
+
2. Conversation control and non-general channels still leak.
|
|
132
|
+
3. Forking is still message-centric.
|
|
133
|
+
|
|
134
|
+
The shipped runtime now isolates those domains with branch-scoped files and branch-aware reads. `check-branch-isolation.js` is the current proof surface for that shipped behavior.
|
|
135
|
+
|
|
136
|
+
### Remaining compatibility-shared gaps
|
|
137
|
+
|
|
138
|
+
There are no remaining agent-visible collaboration surfaces that intentionally resolve through shared compatibility governance files in the shipped runtime.
|
|
139
|
+
|
|
140
|
+
### Next domains to move branch-local
|
|
141
|
+
|
|
142
|
+
Tasks, workflows, delivery/read state, conversation control, non-general channels, workspaces, governance surfaces, sessions, and evidence are already in the shipped branch-local slice. Future branch work can focus on new features rather than finishing compatibility-shared governance migration.
|
|
143
|
+
|
|
144
|
+
## Validation path
|
|
145
|
+
|
|
146
|
+
Run the Task 4A checker with:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
node scripts/check-branch-semantics.js
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
That validator proves the reference still contains:
|
|
153
|
+
- the two-bucket model,
|
|
154
|
+
- fork-time snapshot rules,
|
|
155
|
+
- branch-local read/write resolution rules,
|
|
156
|
+
- the domain matrix,
|
|
157
|
+
- the named closed P0 leaks, remaining compatibility gaps, and migration priorities.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<!-- Generated from ../docs/architecture/canonical-event-schema.md by scripts/sync-packaged-docs.js for published package consumers. -->
|
|
2
|
+
|
|
3
|
+
# Canonical Event Schema Reference
|
|
4
|
+
|
|
5
|
+
Status: Task 3A schema-first reference
|
|
6
|
+
Normative source: `docs/architecture/runtime-contract.md`
|
|
7
|
+
Code source: `events/schema.js`
|
|
8
|
+
|
|
9
|
+
This page freezes the first explicit canonical event layer for LetThemTalk without introducing replay or projection rebuilding yet.
|
|
10
|
+
|
|
11
|
+
## Shared event envelope
|
|
12
|
+
|
|
13
|
+
All canonical events use one shared envelope shape across both streams.
|
|
14
|
+
|
|
15
|
+
Required envelope fields:
|
|
16
|
+
|
|
17
|
+
- `event_id`
|
|
18
|
+
- `stream`
|
|
19
|
+
- `branch_id`
|
|
20
|
+
- `seq`
|
|
21
|
+
- `type`
|
|
22
|
+
- `occurred_at`
|
|
23
|
+
- `schema_version`
|
|
24
|
+
- `actor_agent`
|
|
25
|
+
- `session_id`
|
|
26
|
+
- `command_id`
|
|
27
|
+
- `causation_id`
|
|
28
|
+
- `correlation_id`
|
|
29
|
+
- `payload`
|
|
30
|
+
|
|
31
|
+
Task 3A keeps one envelope for both streams and allows `branch_id` / `session_id` to be present with `null` when they do not apply yet. Unknown fields are allowed so later replay/projection work can preserve forward-compatible data.
|
|
32
|
+
|
|
33
|
+
## Scope split
|
|
34
|
+
|
|
35
|
+
The stream split is explicit in code:
|
|
36
|
+
|
|
37
|
+
- runtime-global exceptions: `agent.*`, `profile.*`, `lock.*`, `branch.*`, `migration.*`
|
|
38
|
+
- branch-local default for collaboration state: `session.*`, `conversation.*`, `message.*`, `task.*`, `workflow.*`, `workspace.*`, `decision.*`, `kb.*`, `review.*`, `dependency.*`, `vote.*`, `rule.*`, `progress.*`, `evidence.*`
|
|
39
|
+
|
|
40
|
+
This mirrors the runtime contract rule that shared local-runtime metadata stays global while collaboration-shaped state is branch-local.
|
|
41
|
+
|
|
42
|
+
## Branch semantics companion
|
|
43
|
+
|
|
44
|
+
This schema reference freezes which families belong to which stream. Task 4A freezes the rest of the branch contract in `docs/architecture/branch-semantics.md`: the two-bucket model, fork snapshot inheritance, branch-local read/write resolution, and the rule that derived delivery/read state (consumed offsets, acknowledgements, read receipts, compressed history, and non-general channel projections) follows the branch-local message/conversation namespace even before those surfaces are fully rewired.
|
|
45
|
+
|
|
46
|
+
## Seed family/type registry
|
|
47
|
+
|
|
48
|
+
The first registry is intentionally small and grounded in current runtime surfaces:
|
|
49
|
+
|
|
50
|
+
| Family | Stream | Seed event types | Projection targets |
|
|
51
|
+
| --- | --- | --- | --- |
|
|
52
|
+
| `agent` | `runtime` | `agent.registered`, `agent.unregistered`, `agent.status_updated`, `agent.heartbeat_recorded`, `agent.branch_assigned`, `agent.listening_updated` | `agents-index`, `sessions-index` |
|
|
53
|
+
| `profile` | `runtime` | `profile.updated` | `profiles` |
|
|
54
|
+
| `lock` | `runtime` | `lock.acquired`, `lock.released` | `locks` |
|
|
55
|
+
| `branch` | `runtime` | `branch.created` | `branch-index` |
|
|
56
|
+
| `migration` | `runtime` | `migration.started`, `migration.completed`, `migration.failed` | `manifest` |
|
|
57
|
+
| `session` | `branch` | `session.started`, `session.resumed`, `session.interrupted`, `session.completed`, `session.failed`, `session.abandoned` | `sessions`, `sessions-index` |
|
|
58
|
+
| `conversation` | `branch` | `conversation.mode_updated`, `conversation.channel_joined`, `conversation.channel_left`, `conversation.manager_claimed`, `conversation.phase_updated`, `conversation.floor_yielded` | `conversation` |
|
|
59
|
+
| `message` | `branch` | `message.sent`, `message.corrected`, `message.redacted` | `messages`, `history` |
|
|
60
|
+
| `task` | `branch` | `task.created`, `task.updated`, `task.claimed`, `task.completed` | `tasks` |
|
|
61
|
+
| `workflow` | `branch` | `workflow.created`, `workflow.step_started`, `workflow.step_completed`, `workflow.step_reassigned`, `workflow.completed`, `workflow.paused`, `workflow.resumed`, `workflow.stopped` | `workflows` |
|
|
62
|
+
| `workspace` | `branch` | `workspace.written` | `workspaces` |
|
|
63
|
+
| `decision` | `branch` | `decision.logged` | `decisions` |
|
|
64
|
+
| `kb` | `branch` | `kb.written` | `kb` |
|
|
65
|
+
| `review` | `branch` | `review.requested`, `review.submitted` | `reviews` |
|
|
66
|
+
| `dependency` | `branch` | `dependency.declared`, `dependency.resolved` | `dependencies` |
|
|
67
|
+
| `vote` | `branch` | `vote.called`, `vote.cast`, `vote.resolved` | `votes` |
|
|
68
|
+
| `rule` | `branch` | `rule.added`, `rule.toggled`, `rule.removed` | `rules` |
|
|
69
|
+
| `progress` | `branch` | `progress.updated` | `progress` |
|
|
70
|
+
| `evidence` | `branch` | `evidence.recorded` | `evidence` |
|
|
71
|
+
|
|
72
|
+
These types are the Task 3A seed set for later replay/projection work. They are not a full migration of writes yet.
|
|
73
|
+
|
|
74
|
+
## Validation path
|
|
75
|
+
|
|
76
|
+
Run the narrow schema check with:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
node scripts/check-event-schema.js
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
That validator proves:
|
|
83
|
+
|
|
84
|
+
- the shared envelope fields exist,
|
|
85
|
+
- the required family registry exists,
|
|
86
|
+
- the runtime-vs-branch split is encoded,
|
|
87
|
+
- the Task 3A seed event types are registered,
|
|
88
|
+
- sample canonical events validate against the shared envelope.
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
<!-- Generated from ../docs/architecture/markdown-workspace.md by scripts/sync-packaged-docs.js for published package consumers. -->
|
|
2
|
+
|
|
3
|
+
# Markdown Workspace Reference
|
|
4
|
+
|
|
5
|
+
Status: Task 9A projection-first reference
|
|
6
|
+
Normative parents: `docs/architecture/runtime-contract.md`, `docs/architecture/branch-semantics.md`
|
|
7
|
+
Schema companion: `docs/architecture/canonical-event-schema.md`
|
|
8
|
+
Current code anchors: `state/canonical.js`, `state/dashboard-queries.js`, `dashboard.js`, `dashboard.html`
|
|
9
|
+
Last updated: 2026-04-17
|
|
10
|
+
|
|
11
|
+
This document freezes the first markdown-workspace contract for LetThemTalk. It is intentionally narrow and implementation-driving for Task 9B: it defines the generated markdown workspace structure, the authority boundary between markdown and runtime state, the current export-source mapping, and the minimum validation markers that must stay true after the branch-local workflow and plan-view export work.
|
|
12
|
+
|
|
13
|
+
This slice does **not** implement write-back, live sync, watcher loops, or markdown import.
|
|
14
|
+
|
|
15
|
+
## Non-authoritative authority model
|
|
16
|
+
|
|
17
|
+
Markdown files are rebuilt from canonical and legacy-compat read models and never treated as runtime inputs.
|
|
18
|
+
|
|
19
|
+
Authority is frozen as follows:
|
|
20
|
+
|
|
21
|
+
- Canonical runtime truth remains the broker-owned event/projection model defined in `docs/architecture/runtime-contract.md`.
|
|
22
|
+
- Markdown export is one-way by default: runtime -> markdown workspace.
|
|
23
|
+
- Every exported markdown file MUST set `authoritative: false` in frontmatter.
|
|
24
|
+
- Task 9B MUST NOT implement write-back or live sync loops.
|
|
25
|
+
- The dashboard, CLI, or broker MUST NOT watch markdown edits and reinterpret them as canonical updates.
|
|
26
|
+
- Any future import must be explicit and broker-mediated.
|
|
27
|
+
- Missing, stale, deleted, or manually edited markdown files MUST NOT change runtime behavior.
|
|
28
|
+
|
|
29
|
+
## Workspace root / layout
|
|
30
|
+
|
|
31
|
+
Default export root: `<repo>/.agent-bridge-markdown/`
|
|
32
|
+
|
|
33
|
+
The first safe workspace root lives outside `.agent-bridge/` so runtime storage and markdown projections stay visibly separate.
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
.agent-bridge-markdown/
|
|
37
|
+
README.md
|
|
38
|
+
branches/
|
|
39
|
+
index.md
|
|
40
|
+
<branch>/
|
|
41
|
+
metadata.md
|
|
42
|
+
conversations/
|
|
43
|
+
index.md
|
|
44
|
+
channels/
|
|
45
|
+
general.md
|
|
46
|
+
<channel>.md
|
|
47
|
+
decisions/
|
|
48
|
+
index.md
|
|
49
|
+
sessions/
|
|
50
|
+
index.md
|
|
51
|
+
<session-id>.md
|
|
52
|
+
evidence/
|
|
53
|
+
index.md
|
|
54
|
+
workspaces/
|
|
55
|
+
index.md
|
|
56
|
+
agents/
|
|
57
|
+
<agent>.md
|
|
58
|
+
plans/
|
|
59
|
+
status.md
|
|
60
|
+
report.md
|
|
61
|
+
project/
|
|
62
|
+
notes/
|
|
63
|
+
project-notes.md
|
|
64
|
+
team-notes.md
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Required meaning of the first safe structure:
|
|
68
|
+
|
|
69
|
+
- `README.md` is the generated workspace landing page and repeats the non-authoritative rule.
|
|
70
|
+
- `branches/index.md` lists known branches and points at `branches/<branch>/metadata.md`.
|
|
71
|
+
- `branches/<branch>/metadata.md` is the first branch metadata page.
|
|
72
|
+
- `conversations/` is the conversation export area for that branch.
|
|
73
|
+
- `decisions/`, `sessions/`, `evidence/`, `workspaces/`, and `plans/` are exported from branch-local read surfaces for every branch.
|
|
74
|
+
- `project/notes/project-notes.md` and `project/notes/team-notes.md` are generated cross-branch summaries built from branch-local governance surfaces, not editable runtime inputs.
|
|
75
|
+
|
|
76
|
+
## Required generated frontmatter
|
|
77
|
+
|
|
78
|
+
### Common frontmatter
|
|
79
|
+
|
|
80
|
+
Every exported markdown file MUST carry this minimum frontmatter contract:
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
ltt_schema: markdown-workspace/v1
|
|
84
|
+
doc_kind: <kind>
|
|
85
|
+
authoritative: false
|
|
86
|
+
branch: <branch-id-or-null>
|
|
87
|
+
projection_of: <domain-or-view>
|
|
88
|
+
source_surface: <read-surface>
|
|
89
|
+
source_scope: <branch_local|runtime_global|compatibility_shared|main_branch_only>
|
|
90
|
+
source_sequence: <stream-seq-or-null>
|
|
91
|
+
generated_at: <iso-timestamp>
|
|
92
|
+
generated_by: let-them-talk-markdown-export
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The key meanings are frozen:
|
|
96
|
+
|
|
97
|
+
- `doc_kind` identifies the page role.
|
|
98
|
+
- `projection_of` names the runtime domain or export view being projected.
|
|
99
|
+
- `source_surface` names the read seam used to build the file.
|
|
100
|
+
- `source_scope` states whether the source is already branch-local or still compatibility-shared.
|
|
101
|
+
- `source_sequence` records the event-stream or projection sequence the markdown snapshot was generated from when one exists.
|
|
102
|
+
|
|
103
|
+
### Kind-specific frontmatter
|
|
104
|
+
|
|
105
|
+
Task 9B MUST add the following kind-specific keys on the first safe pages:
|
|
106
|
+
|
|
107
|
+
| File kind | Required extra keys |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| `branch-metadata` | `branch_parent`, `branch_source` |
|
|
110
|
+
| `conversation-index` | `channel_count`, `message_count` |
|
|
111
|
+
| `conversation-transcript` | `channel`, `message_count` |
|
|
112
|
+
| `decision-index` | `decision_count` |
|
|
113
|
+
| `session-index` | `session_count` |
|
|
114
|
+
| `session-detail` | `session_id`, `session_state` |
|
|
115
|
+
| `evidence-index` | `evidence_count` |
|
|
116
|
+
| `workspace-index` | `agent_count` |
|
|
117
|
+
| `workspace-agent` | `agent`, `key_count` |
|
|
118
|
+
| `plan-status` | `workflow_id`, `workflow_status` |
|
|
119
|
+
| `plan-report` | `workflow_id`, `workflow_status` |
|
|
120
|
+
| `project-note` | `note_scope` |
|
|
121
|
+
| `team-note` | `note_scope` |
|
|
122
|
+
|
|
123
|
+
For aggregated plan pages that summarize more than one workflow, `workflow_id` and `workflow_status` MAY be `null`.
|
|
124
|
+
|
|
125
|
+
## Export-source mapping
|
|
126
|
+
|
|
127
|
+
Task 9B should assemble markdown through `state/canonical.js` and add thin read-only wrappers there for domains that still live in legacy compatibility files today.
|
|
128
|
+
|
|
129
|
+
| Markdown output | Current source surface | Current scope rule | Task 9B note |
|
|
130
|
+
| --- | --- | --- | --- |
|
|
131
|
+
| `branches/index.md` | `.agent-bridge/branches.json` plus branch directories under `.agent-bridge/runtime/branches/` | runtime-global branch registry | Build one branch registry page; do not infer hidden branches. |
|
|
132
|
+
| `branches/<branch>/metadata.md` | `.agent-bridge/branches.json` plus branch runtime presence | runtime-global branch registry with branch identity | Safe for every known branch. |
|
|
133
|
+
| `branches/<branch>/conversations/index.md` and `branches/<branch>/conversations/channels/*.md` | `createCanonicalState().getConversationMessages({ branch })`, `getHistoryView({ branch })`, `getChannelsView({ branch })` | branch-local | Use the selected branch only. |
|
|
134
|
+
| `branches/<branch>/decisions/index.md` | `createCanonicalState().listDecisions({ branch })` | branch-local | Export the selected branch decision log only. |
|
|
135
|
+
| `branches/<branch>/sessions/index.md` and `branches/<branch>/sessions/<session-id>.md` | `.agent-bridge/runtime/projections/sessions-index.json` and `.agent-bridge/runtime/branches/<branch>/sessions/*.json` | branch-local with runtime-global discovery index | Index pages summarize branch-local sessions; detail pages point at branch session manifests. |
|
|
136
|
+
| `branches/<branch>/evidence/index.md` | `createCanonicalState().readEvidence(branch)` plus `projectEvidence(...)` enrichment | branch-local | Export evidence indexes from the branch evidence store only. |
|
|
137
|
+
| `branches/<branch>/workspaces/index.md` and `branches/<branch>/workspaces/agents/<agent>.md` | `createCanonicalState().listWorkspaces({ branch })` over `workspaces/<agent>.json` on `main` and `branch-<branch>-workspaces/<agent>.json` elsewhere | branch-local | Export workspace pages for the selected branch only. |
|
|
138
|
+
| `branches/<branch>/plans/status.md` | `createCanonicalState().getPlanStatusView({ branch })` | branch-local | Build the plan status page from the selected branch workflow view. Do not treat this surface as `main`-only anymore. |
|
|
139
|
+
| `branches/<branch>/plans/report.md` | `createCanonicalState().getPlanReportView({ branch })` | branch-local | Build the plan report page from the selected branch workflow report view. Do not treat this surface as `main`-only anymore. |
|
|
140
|
+
| `project/notes/project-notes.md` | `createCanonicalState().listMarkdownBranches()` + `createCanonicalState().getProjectNotesView({ branch })` | runtime-global summary over branch-local sources | Summarize branch-local project guidance across all exported branches without claiming runtime authority. |
|
|
141
|
+
| `project/notes/team-notes.md` | `createCanonicalState().listMarkdownBranches()` + `createCanonicalState().getTeamNotesView({ branch })` | runtime-global summary over branch-local sources | Summarize branch-local collaboration governance across all exported branches without inventing shared copies. |
|
|
142
|
+
|
|
143
|
+
## Branch and compatibility safety rules
|
|
144
|
+
|
|
145
|
+
Task 9B MUST follow these safety guards when the markdown workspace is generated:
|
|
146
|
+
|
|
147
|
+
- Branch-local pages MUST be generated from the selected branch only.
|
|
148
|
+
- Governance pages and cross-branch note summaries MUST read branch-local governance views; they MUST NOT fall back to shared legacy governance files.
|
|
149
|
+
- Branch-local workspace pages MUST read `listWorkspaces({ branch })` for the selected branch. They are no longer part of the compatibility-shared or `main`-only bucket.
|
|
150
|
+
- Branch-local plan pages MUST read `getPlanStatusView({ branch })` and `getPlanReportView({ branch })` for the selected branch. They are no longer part of the shared or `main`-only bucket.
|
|
151
|
+
- Project and team notes may summarize multiple branch-local surfaces at once, but they MUST keep `authoritative: false` and a truthful `source_scope` value.
|
|
152
|
+
- Re-export MAY replace previously generated markdown files. Preservation of manual edits is not part of this contract slice.
|
|
153
|
+
- Markdown export failure MUST NOT block canonical runtime writes.
|
|
154
|
+
|
|
155
|
+
## Task 9B implementation seam
|
|
156
|
+
|
|
157
|
+
The best low-churn export assembly point is `state/canonical.js`.
|
|
158
|
+
|
|
159
|
+
The best outward-facing seam is the existing dashboard export family (`/api/export-json`, `/api/export`, and `/api/export-replay`), not a watcher loop.
|
|
160
|
+
|
|
161
|
+
Task 9B should therefore:
|
|
162
|
+
|
|
163
|
+
- add read-only markdown-export helpers or wrappers to `createCanonicalState(...)`,
|
|
164
|
+
- reuse the existing dashboard export shape conventions for branch/version/exported-at metadata,
|
|
165
|
+
- treat the current `dashboard.html` markdown export as conversation-only compatibility behavior rather than the authority model for the workspace,
|
|
166
|
+
- avoid introducing a second side channel that bypasses broker-owned read surfaces.
|
|
167
|
+
|
|
168
|
+
## Validation path
|
|
169
|
+
|
|
170
|
+
Run the Task 9A checker with:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
node scripts/check-markdown-workspace.js
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
That validator proves the reference still contains:
|
|
177
|
+
|
|
178
|
+
- the non-authoritative markdown rule,
|
|
179
|
+
- the default workspace root and first safe layout,
|
|
180
|
+
- the required frontmatter contract,
|
|
181
|
+
- the export-source mapping,
|
|
182
|
+
- the branch/main-only compatibility safety rules,
|
|
183
|
+
- the Task 9B implementation seam.
|