@etiquekit/etq 1.0.13 → 1.0.15
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/AGENTS.md +26 -19
- package/LICENSE +3 -2
- package/NOTICE +4 -6
- package/QuickStart.md +46 -35
- package/README.md +57 -55
- package/bin/etiquette +5 -1
- package/bin/etiquette-core +5 -1
- package/docs/ARCHITECTURE.md +17 -20
- package/docs/CONCEPTS.md +5 -5
- package/docs/CORE_PROFILE.md +15 -7
- package/docs/LANE_PROVISIONING.md +2 -7
- package/docs/README.md +14 -13
- package/docs/RELEASE_SURFACE_AUDIT.md +6 -7
- package/docs/SEAT_DISCIPLINE.md +91 -55
- package/docs/SEAT_PROVISIONING.md +19 -16
- package/docs/TEAM_HANDOFF.md +21 -21
- package/docs/WORKTREE_QOL.md +0 -7
- package/docs/contracts/ledger-entry/README.md +11 -11
- package/docs/contracts/ledger-entry/ledger-entry.v0.2.md +2 -2
- package/docs/contracts/ledger-entry/ledger-entry.v0.md +8 -8
- package/lib/etiquette-core.js +313 -0
- package/lib/etiquette.js +1151 -0
- package/package.json +13 -12
- package/templates/etiquette-vanilla-v0/README.md +3 -2
- package/templates/etiquette-vanilla-v0/source/control-seat/README.md +6 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/access-assurance-check +55 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/seat-doctor +5 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/ACCESS-ASSURANCE.md +39 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/workspace-secure-profile.v0.json +53 -0
- package/templates/etiquette-vanilla-v0/validate-vanilla.sh +5 -0
- package/templates/hosted-receiver/README.md +41 -0
- package/templates/hosted-receiver/w1-github-webhook-receiver.mjs +129 -0
- package/templates/seat-packs-v0/README.md +2 -3
- package/templates/seat-packs-v0/source/claude-code-seat/README.md +3 -3
- package/templates/seat-packs-v0/source/codex-seat/README.md +3 -3
- package/templates/seat-packs-v0/source/gemini-seat/README.md +3 -3
- package/templates/seat-packs-v0/source/ollama-seat/README.md +3 -3
- package/templates/seat-packs-v0/source/openrouter-seat/README.md +3 -3
- package/docs/CONCEPT_STATUS.md +0 -66
- package/packages/control/src/authority/lease.ts +0 -261
- package/packages/control/src/authority/node-delegation.ts +0 -257
- package/packages/control/src/authority/rig-conductor.ts +0 -632
- package/packages/control/src/cli/argv.ts +0 -155
- package/packages/control/src/cli/commands/console.ts +0 -200
- package/packages/control/src/cli/commands/dispatch-core.ts +0 -89
- package/packages/control/src/cli/commands/dispatch.ts +0 -279
- package/packages/control/src/cli/commands/harness.ts +0 -89
- package/packages/control/src/cli/commands/hook.ts +0 -50
- package/packages/control/src/cli/commands/ledger.ts +0 -91
- package/packages/control/src/cli/commands/local-workflow.ts +0 -4686
- package/packages/control/src/cli/commands/memory.ts +0 -445
- package/packages/control/src/cli/commands/release.ts +0 -108
- package/packages/control/src/cli/commands/rubric.ts +0 -103
- package/packages/control/src/cli/commands/seat.ts +0 -179
- package/packages/control/src/cli/commands/session.ts +0 -127
- package/packages/control/src/cli/commands/supervision.ts +0 -246
- package/packages/control/src/cli/commands/sync.ts +0 -119
- package/packages/control/src/cli/commands/workflow.ts +0 -86
- package/packages/control/src/cli/commands/workspace.ts +0 -50
- package/packages/control/src/cli/core-usage.ts +0 -34
- package/packages/control/src/cli/prompt.ts +0 -67
- package/packages/control/src/cli/supervision-deps.ts +0 -44
- package/packages/control/src/cli/usage.ts +0 -241
- package/packages/control/src/cli.ts +0 -207
- package/packages/control/src/core-cli.ts +0 -50
- package/packages/control/src/dispatch/decision.ts +0 -202
- package/packages/control/src/dispatch/projection.ts +0 -293
- package/packages/control/src/dispatch/record.ts +0 -153
- package/packages/control/src/engagement/project.ts +0 -170
- package/packages/control/src/fs.ts +0 -19
- package/packages/control/src/harness/pruning.ts +0 -406
- package/packages/control/src/hooks/dispatcher.ts +0 -117
- package/packages/control/src/hooks/outbox.ts +0 -86
- package/packages/control/src/hooks/sanitize.ts +0 -6
- package/packages/control/src/hooks/types.ts +0 -34
- package/packages/control/src/index.ts +0 -384
- package/packages/control/src/ledger/entry.ts +0 -303
- package/packages/control/src/ledger/indexer.ts +0 -542
- package/packages/control/src/memory/context.ts +0 -149
- package/packages/control/src/memory/drain-import.ts +0 -207
- package/packages/control/src/memory/indexer.ts +0 -284
- package/packages/control/src/memory/query.ts +0 -75
- package/packages/control/src/memory/sanitize.ts +0 -50
- package/packages/control/src/memory/sharded-drain-import.ts +0 -212
- package/packages/control/src/memory/status.ts +0 -211
- package/packages/control/src/memory/store-lifecycle.ts +0 -509
- package/packages/control/src/memory/store.ts +0 -284
- package/packages/control/src/memory/types.ts +0 -146
- package/packages/control/src/parity/surfaces.ts +0 -748
- package/packages/control/src/project.ts +0 -141
- package/packages/control/src/projection/local-ledger-view.ts +0 -373
- package/packages/control/src/projection/return-enforcement.ts +0 -48
- package/packages/control/src/projection/timeline-preview.ts +0 -539
- package/packages/control/src/projection/timeline.ts +0 -708
- package/packages/control/src/release/readiness.ts +0 -831
- package/packages/control/src/rubric/loader.ts +0 -326
- package/packages/control/src/rubric/promotion.ts +0 -54
- package/packages/control/src/rubric/runner.ts +0 -159
- package/packages/control/src/rubric/types.ts +0 -158
- package/packages/control/src/seat/owner-card.ts +0 -388
- package/packages/control/src/seat/readiness.ts +0 -834
- package/packages/control/src/session/runbook.ts +0 -431
- package/packages/control/src/shared/sanitize.ts +0 -49
- package/packages/control/src/supervision/action-classes.ts +0 -192
- package/packages/control/src/supervision/command-apply.ts +0 -378
- package/packages/control/src/supervision/errors.ts +0 -14
- package/packages/control/src/supervision/event-replay.ts +0 -155
- package/packages/control/src/supervision/events.ts +0 -109
- package/packages/control/src/supervision/index.ts +0 -16
- package/packages/control/src/supervision/manifest.ts +0 -127
- package/packages/control/src/supervision/paths.ts +0 -49
- package/packages/control/src/supervision/projection-adapter.ts +0 -274
- package/packages/control/src/supervision/projection.ts +0 -75
- package/packages/control/src/supervision/rebuild.ts +0 -99
- package/packages/control/src/supervision/session-open.ts +0 -131
- package/packages/control/src/supervision/session-read.ts +0 -99
- package/packages/control/src/supervision/sqlite-impl.ts +0 -71
- package/packages/control/src/supervision/sqlite.ts +0 -121
- package/packages/control/src/supervision/store-rows.ts +0 -371
- package/packages/control/src/supervision/turn-close.ts +0 -154
- package/packages/control/src/supervision/turn-open.ts +0 -284
- package/packages/control/src/sync/event-log-merge-driver.ts +0 -263
- package/packages/control/src/sync/join-plan.ts +0 -375
- package/packages/control/src/sync/outbox.ts +0 -492
- package/packages/control/src/workflow/evaluator.ts +0 -140
- package/packages/control/src/workflow/loader.ts +0 -200
- package/packages/control/src/workflow/types.ts +0 -90
- package/packages/control/src/workspace/authority.ts +0 -499
- package/packages/protocol/src/guards.ts +0 -119
- package/packages/protocol/src/huddle-board.ts +0 -198
- package/packages/protocol/src/huddle.ts +0 -295
- package/packages/protocol/src/incident.ts +0 -251
- package/packages/protocol/src/index.ts +0 -8
- package/packages/protocol/src/interfaces.ts +0 -107
- package/packages/protocol/src/packet-profile.ts +0 -195
- package/packages/protocol/src/state.ts +0 -81
- package/packages/protocol/src/types.ts +0 -434
- package/release/lineage.v0.json +0 -14
- package/scripts/release-candidate-verify.sh +0 -175
- package/scripts/release-checksum.sh +0 -25
- package/scripts/release-pack-canary.sh +0 -97
- package/scripts/release-scan.sh +0 -249
- package/scripts/release-sign.sh +0 -34
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import { appendFile, readFile } from 'node:fs/promises';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import type {
|
|
5
|
-
SupervisionDeps,
|
|
6
|
-
SupervisionSession,
|
|
7
|
-
} from '../../../protocol/src/index';
|
|
8
|
-
import { SupervisionRuntimeError } from './errors';
|
|
9
|
-
import { appendSupervisionEvent, buildEvent } from './events';
|
|
10
|
-
import { loadSeatManifest } from './manifest';
|
|
11
|
-
import { supervisionRuntimePaths } from './paths';
|
|
12
|
-
import { renderProjection, writeLatestState } from './projection';
|
|
13
|
-
import { applySupervisionSchema } from './sqlite';
|
|
14
|
-
import { withSupervisionTransaction } from './sqlite-impl';
|
|
15
|
-
import { insertEventRow, insertSessionRow } from './store-rows';
|
|
16
|
-
|
|
17
|
-
export interface SessionOpenArgs {
|
|
18
|
-
sessionId: string;
|
|
19
|
-
campaignRoot: string;
|
|
20
|
-
topic: string;
|
|
21
|
-
objective: string;
|
|
22
|
-
leadSeat: string;
|
|
23
|
-
responderSeat: string;
|
|
24
|
-
escalationOwner: string;
|
|
25
|
-
timeCapMinutes: number;
|
|
26
|
-
turnCap: number;
|
|
27
|
-
sourceRefs: string[];
|
|
28
|
-
seatManifestOverride?: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Open a new supervision session.
|
|
33
|
-
*
|
|
34
|
-
* Per PHASE1.md canonical ordering: events.jsonl first (rebuild authority),
|
|
35
|
-
* then SQLite mirror inside a single transaction, then artifacts
|
|
36
|
-
* (latest-state.json + projection renders).
|
|
37
|
-
*/
|
|
38
|
-
export async function openSupervisionSession(
|
|
39
|
-
args: SessionOpenArgs,
|
|
40
|
-
deps: SupervisionDeps,
|
|
41
|
-
): Promise<SupervisionSession> {
|
|
42
|
-
// Validate seat manifest exists and is well-formed before any state lands.
|
|
43
|
-
await loadSeatManifest(args.seatManifestOverride);
|
|
44
|
-
|
|
45
|
-
const paths = supervisionRuntimePaths(args.campaignRoot);
|
|
46
|
-
await deps.mkdirp(paths.runtimeDir);
|
|
47
|
-
await maybeAddGitExclude(args.campaignRoot);
|
|
48
|
-
|
|
49
|
-
const db = deps.openSqlite(paths.sqlitePath);
|
|
50
|
-
try {
|
|
51
|
-
applySupervisionSchema(db);
|
|
52
|
-
|
|
53
|
-
const existing = db.get<{ session_id: string }>(
|
|
54
|
-
'SELECT session_id FROM sessions WHERE session_id = ?',
|
|
55
|
-
[args.sessionId],
|
|
56
|
-
);
|
|
57
|
-
if (existing) {
|
|
58
|
-
throw new SupervisionRuntimeError(
|
|
59
|
-
`session ${args.sessionId} already exists in ${paths.sqlitePath}`,
|
|
60
|
-
'SESSION_EXISTS',
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const now = deps.now().toISOString();
|
|
65
|
-
const session: SupervisionSession = {
|
|
66
|
-
sessionId: args.sessionId,
|
|
67
|
-
campaignRoot: paths.campaignRoot,
|
|
68
|
-
topic: args.topic,
|
|
69
|
-
objective: args.objective,
|
|
70
|
-
status: 'running',
|
|
71
|
-
leadSeat: args.leadSeat,
|
|
72
|
-
responderSeat: args.responderSeat,
|
|
73
|
-
escalationOwner: args.escalationOwner,
|
|
74
|
-
timeCapMinutes: args.timeCapMinutes,
|
|
75
|
-
turnCap: args.turnCap,
|
|
76
|
-
currentTurnId: null,
|
|
77
|
-
nextOwnerHint: null,
|
|
78
|
-
approvedNextTurnJson: null,
|
|
79
|
-
lastBlockerJson: null,
|
|
80
|
-
sourceRefs: [...args.sourceRefs],
|
|
81
|
-
createdAt: now,
|
|
82
|
-
updatedAt: now,
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// Canonical ordering: events.jsonl first (rebuild authority),
|
|
86
|
-
// then SQLite mirror inside a single transaction, then artifacts.
|
|
87
|
-
const event = buildEvent(deps, {
|
|
88
|
-
eventType: 'session.opened',
|
|
89
|
-
sessionId: session.sessionId,
|
|
90
|
-
turnId: null,
|
|
91
|
-
commandId: null,
|
|
92
|
-
actor: args.leadSeat,
|
|
93
|
-
audience: 'all',
|
|
94
|
-
at: now,
|
|
95
|
-
payload: session,
|
|
96
|
-
});
|
|
97
|
-
await appendSupervisionEvent(paths.eventsPath, event);
|
|
98
|
-
|
|
99
|
-
withSupervisionTransaction(db, () => {
|
|
100
|
-
insertSessionRow(db, session);
|
|
101
|
-
insertEventRow(db, event);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
await writeLatestState(paths.latestStatePath, session, null);
|
|
105
|
-
await renderProjection(deps, paths, session, null, []);
|
|
106
|
-
|
|
107
|
-
return session;
|
|
108
|
-
} finally {
|
|
109
|
-
db.close();
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* If the campaign root is a git worktree, add `.etiquette/runtime/`
|
|
115
|
-
* to `.git/info/exclude` so the hot state never becomes an accidental
|
|
116
|
-
* tracked change. Best-effort — unwritable excludes do not fail session-open.
|
|
117
|
-
*/
|
|
118
|
-
async function maybeAddGitExclude(campaignRoot: string): Promise<void> {
|
|
119
|
-
const excludePath = join(campaignRoot, '.git', 'info', 'exclude');
|
|
120
|
-
if (!existsSync(excludePath)) return;
|
|
121
|
-
try {
|
|
122
|
-
const existing = await readFile(excludePath, 'utf-8');
|
|
123
|
-
const line = '.etiquette/runtime/';
|
|
124
|
-
if (!existing.split('\n').some((l) => l.trim() === line)) {
|
|
125
|
-
const newline = existing.endsWith('\n') ? '' : '\n';
|
|
126
|
-
await appendFile(excludePath, `${newline}${line}\n`);
|
|
127
|
-
}
|
|
128
|
-
} catch {
|
|
129
|
-
// Best-effort; if .git/info/exclude is unwritable we do not fail session-open.
|
|
130
|
-
}
|
|
131
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
SupervisionDeps,
|
|
3
|
-
SupervisionProjection,
|
|
4
|
-
} from '../../../protocol/src/index';
|
|
5
|
-
import { appendSupervisionEvent, buildEvent } from './events';
|
|
6
|
-
import { supervisionRuntimePaths } from './paths';
|
|
7
|
-
import { renderProjection } from './projection';
|
|
8
|
-
import { applySupervisionSchema } from './sqlite';
|
|
9
|
-
import { withSupervisionTransaction } from './sqlite-impl';
|
|
10
|
-
import {
|
|
11
|
-
insertEventRow,
|
|
12
|
-
loadCurrentTurn,
|
|
13
|
-
loadPendingCommands,
|
|
14
|
-
loadSession,
|
|
15
|
-
} from './store-rows';
|
|
16
|
-
|
|
17
|
-
export interface SessionStatusArgs {
|
|
18
|
-
sessionId: string;
|
|
19
|
-
campaignRoot: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Read the current session snapshot (pure read; no state change, no
|
|
24
|
-
* projection render, no event emit). Used by `session-status` CLI and
|
|
25
|
-
* conformance tests that need to observe state without triggering a
|
|
26
|
-
* projection cycle.
|
|
27
|
-
*/
|
|
28
|
-
export async function readSupervisionSession(
|
|
29
|
-
args: SessionStatusArgs,
|
|
30
|
-
deps: SupervisionDeps,
|
|
31
|
-
): Promise<SupervisionProjection> {
|
|
32
|
-
const paths = supervisionRuntimePaths(args.campaignRoot);
|
|
33
|
-
const db = deps.openSqlite(paths.sqlitePath);
|
|
34
|
-
try {
|
|
35
|
-
applySupervisionSchema(db);
|
|
36
|
-
const session = loadSession(db, args.sessionId);
|
|
37
|
-
const currentTurn = loadCurrentTurn(db, session);
|
|
38
|
-
const pendingCommands = loadPendingCommands(db, args.sessionId);
|
|
39
|
-
return {
|
|
40
|
-
sessionId: session.sessionId,
|
|
41
|
-
renderedAt: deps.now().toISOString(),
|
|
42
|
-
sessionSnapshot: session,
|
|
43
|
-
currentTurn,
|
|
44
|
-
pendingCommands,
|
|
45
|
-
};
|
|
46
|
-
} finally {
|
|
47
|
-
db.close();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface SessionProjectArgs {
|
|
52
|
-
sessionId: string;
|
|
53
|
-
campaignRoot: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Render the projection artifacts (STATUS_BOARD.md + seat channels +
|
|
58
|
-
* latest-projection.json) from current SQLite state, and emit a
|
|
59
|
-
* `projection.rendered` event so replay stays complete.
|
|
60
|
-
*
|
|
61
|
-
* Idempotent per PHASE1.md § Projection rules — rerunning does not duplicate
|
|
62
|
-
* channel entries (meta-events like `projection.rendered` are filtered from
|
|
63
|
-
* seat-channel output by the adapter).
|
|
64
|
-
*/
|
|
65
|
-
export async function projectSupervisionSession(
|
|
66
|
-
args: SessionProjectArgs,
|
|
67
|
-
deps: SupervisionDeps,
|
|
68
|
-
): Promise<SupervisionProjection> {
|
|
69
|
-
const paths = supervisionRuntimePaths(args.campaignRoot);
|
|
70
|
-
const db = deps.openSqlite(paths.sqlitePath);
|
|
71
|
-
try {
|
|
72
|
-
applySupervisionSchema(db);
|
|
73
|
-
const session = loadSession(db, args.sessionId);
|
|
74
|
-
const currentTurn = loadCurrentTurn(db, session);
|
|
75
|
-
const pendingCommands = loadPendingCommands(db, args.sessionId);
|
|
76
|
-
const projection = await renderProjection(deps, paths, session, currentTurn, pendingCommands);
|
|
77
|
-
|
|
78
|
-
// Emit projection.rendered event (after render so we know the render succeeded).
|
|
79
|
-
const renderedAt = projection.renderedAt;
|
|
80
|
-
const event = buildEvent(deps, {
|
|
81
|
-
eventType: 'projection.rendered',
|
|
82
|
-
sessionId: session.sessionId,
|
|
83
|
-
turnId: session.currentTurnId,
|
|
84
|
-
commandId: null,
|
|
85
|
-
actor: 'system',
|
|
86
|
-
audience: 'all',
|
|
87
|
-
at: renderedAt,
|
|
88
|
-
payload: { renderedAt },
|
|
89
|
-
});
|
|
90
|
-
await appendSupervisionEvent(paths.eventsPath, event);
|
|
91
|
-
withSupervisionTransaction(db, () => {
|
|
92
|
-
insertEventRow(db, event);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
return projection;
|
|
96
|
-
} finally {
|
|
97
|
-
db.close();
|
|
98
|
-
}
|
|
99
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { Database } from 'bun:sqlite';
|
|
2
|
-
import type { SupervisionSqliteHandle } from '../../../protocol/src/index';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Wrap a synchronous SQLite mutation bundle in a `BEGIN IMMEDIATE` /
|
|
6
|
-
* `COMMIT` transaction. On throw, issue `ROLLBACK` best-effort and rethrow.
|
|
7
|
-
*
|
|
8
|
-
* Per PHASE1.md and the Phase D addendum: session row + event row +
|
|
9
|
-
* command row updates should commit atomically on the SQLite side for
|
|
10
|
-
* each logical command operation. Events in `events.jsonl` remain the
|
|
11
|
-
* canonical rebuild authority; SQLite is a derived mirror.
|
|
12
|
-
*
|
|
13
|
-
* Do NOT wrap PRAGMA statements or DDL inside this helper — apply the
|
|
14
|
-
* schema before opening a transaction.
|
|
15
|
-
*/
|
|
16
|
-
export function withSupervisionTransaction<T>(
|
|
17
|
-
handle: SupervisionSqliteHandle,
|
|
18
|
-
fn: () => T,
|
|
19
|
-
): T {
|
|
20
|
-
handle.run('BEGIN IMMEDIATE');
|
|
21
|
-
try {
|
|
22
|
-
const result = fn();
|
|
23
|
-
handle.run('COMMIT');
|
|
24
|
-
return result;
|
|
25
|
-
} catch (err) {
|
|
26
|
-
try {
|
|
27
|
-
handle.run('ROLLBACK');
|
|
28
|
-
} catch {
|
|
29
|
-
// Best-effort rollback; the real error is re-thrown below.
|
|
30
|
-
}
|
|
31
|
-
throw err;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Open (or create) a SQLite database at `path` and wrap it as a
|
|
37
|
-
* SupervisionSqliteHandle. Multi-statement DDL (schema init) goes through
|
|
38
|
-
* `.exec()`; single-statement parameterized queries go through prepared
|
|
39
|
-
* statements via `.query()`.
|
|
40
|
-
*
|
|
41
|
-
* Usage in tests: pass ":memory:" for an in-process DB without filesystem.
|
|
42
|
-
*/
|
|
43
|
-
export function openSupervisionSqlite(path: string): SupervisionSqliteHandle {
|
|
44
|
-
const db = new Database(path);
|
|
45
|
-
return {
|
|
46
|
-
run(sql: string, params?: unknown[]): void {
|
|
47
|
-
if (!params || params.length === 0) {
|
|
48
|
-
db.exec(sql);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
db.query(sql).run(...(params as never[]));
|
|
52
|
-
},
|
|
53
|
-
all<T = unknown>(sql: string, params?: unknown[]): T[] {
|
|
54
|
-
const stmt = db.query(sql);
|
|
55
|
-
if (!params || params.length === 0) {
|
|
56
|
-
return stmt.all() as T[];
|
|
57
|
-
}
|
|
58
|
-
return stmt.all(...(params as never[])) as T[];
|
|
59
|
-
},
|
|
60
|
-
get<T = unknown>(sql: string, params?: unknown[]): T | undefined {
|
|
61
|
-
const stmt = db.query(sql);
|
|
62
|
-
const row = !params || params.length === 0
|
|
63
|
-
? stmt.get()
|
|
64
|
-
: stmt.get(...(params as never[]));
|
|
65
|
-
return (row as T | null) ?? undefined;
|
|
66
|
-
},
|
|
67
|
-
close(): void {
|
|
68
|
-
db.close();
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import type { SupervisionSqliteHandle } from '../../../protocol/src/index';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* SQLite schema for Phase 1 supervision hot state. See
|
|
5
|
-
* etiquette/internal/docs/supervision/PHASE1.md for column semantics.
|
|
6
|
-
*
|
|
7
|
-
* The schema is applied once on session-open. Re-applying is a no-op
|
|
8
|
-
* (`CREATE TABLE IF NOT EXISTS`). WAL mode is enabled unconditionally.
|
|
9
|
-
*/
|
|
10
|
-
export const SUPERVISION_SCHEMA_SQL = `
|
|
11
|
-
PRAGMA journal_mode = WAL;
|
|
12
|
-
|
|
13
|
-
CREATE TABLE IF NOT EXISTS sessions (
|
|
14
|
-
session_id TEXT PRIMARY KEY,
|
|
15
|
-
campaign_root TEXT NOT NULL,
|
|
16
|
-
topic TEXT NOT NULL,
|
|
17
|
-
objective TEXT NOT NULL,
|
|
18
|
-
status TEXT NOT NULL CHECK (status IN ('running','paused','blocked','awaiting_human','closed')),
|
|
19
|
-
lead_seat TEXT NOT NULL,
|
|
20
|
-
responder_seat TEXT NOT NULL,
|
|
21
|
-
escalation_owner TEXT NOT NULL,
|
|
22
|
-
time_cap_minutes INTEGER NOT NULL,
|
|
23
|
-
turn_cap INTEGER NOT NULL,
|
|
24
|
-
current_turn_id TEXT,
|
|
25
|
-
next_owner_hint TEXT,
|
|
26
|
-
approved_next_turn_json TEXT,
|
|
27
|
-
last_blocker_json TEXT,
|
|
28
|
-
source_refs_json TEXT NOT NULL,
|
|
29
|
-
created_at TEXT NOT NULL,
|
|
30
|
-
updated_at TEXT NOT NULL
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
CREATE TABLE IF NOT EXISTS turns (
|
|
34
|
-
turn_id TEXT PRIMARY KEY,
|
|
35
|
-
session_id TEXT NOT NULL REFERENCES sessions(session_id),
|
|
36
|
-
sequence_no INTEGER NOT NULL,
|
|
37
|
-
status TEXT NOT NULL CHECK (status IN ('open','closed')),
|
|
38
|
-
owner_seat TEXT NOT NULL,
|
|
39
|
-
allowed_action_class TEXT NOT NULL CHECK (allowed_action_class IN (
|
|
40
|
-
'coordination_only','read_only_local','bounded_verification','bounded_product_mutation','human_only'
|
|
41
|
-
)),
|
|
42
|
-
max_duration_minutes INTEGER NOT NULL,
|
|
43
|
-
allowed_commands_json TEXT NOT NULL,
|
|
44
|
-
repo_roots_json TEXT NOT NULL,
|
|
45
|
-
owned_paths_json TEXT NOT NULL,
|
|
46
|
-
forbidden_paths_json TEXT NOT NULL,
|
|
47
|
-
verify_commands_json TEXT NOT NULL,
|
|
48
|
-
requires_human_approval INTEGER NOT NULL CHECK (requires_human_approval IN (0,1)),
|
|
49
|
-
projection_policy TEXT NOT NULL CHECK (projection_policy IN ('on_state_change','on_command_only')),
|
|
50
|
-
started_at TEXT NOT NULL,
|
|
51
|
-
ended_at TEXT,
|
|
52
|
-
result TEXT CHECK (result IS NULL OR result IN ('done','blocked','handed_off','stopped','timed_out')),
|
|
53
|
-
summary TEXT,
|
|
54
|
-
evidence_refs_json TEXT NOT NULL,
|
|
55
|
-
UNIQUE (session_id, sequence_no)
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
CREATE TABLE IF NOT EXISTS commands (
|
|
59
|
-
command_id TEXT PRIMARY KEY,
|
|
60
|
-
session_id TEXT NOT NULL REFERENCES sessions(session_id),
|
|
61
|
-
turn_id TEXT REFERENCES turns(turn_id),
|
|
62
|
-
issued_by TEXT NOT NULL,
|
|
63
|
-
command TEXT NOT NULL CHECK (command IN (
|
|
64
|
-
'status','pause','resume','stop','approve_next_turn','redirect_owner',
|
|
65
|
-
'request_summary','mark_blocked','escalate_to_human'
|
|
66
|
-
)),
|
|
67
|
-
payload_json TEXT NOT NULL,
|
|
68
|
-
status TEXT NOT NULL CHECK (status IN ('queued','applied','rejected','expired')),
|
|
69
|
-
issued_at TEXT NOT NULL,
|
|
70
|
-
applied_at TEXT,
|
|
71
|
-
rejection_reason TEXT
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
CREATE TABLE IF NOT EXISTS events (
|
|
75
|
-
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
76
|
-
event_id TEXT UNIQUE NOT NULL,
|
|
77
|
-
session_id TEXT NOT NULL,
|
|
78
|
-
turn_id TEXT,
|
|
79
|
-
command_id TEXT,
|
|
80
|
-
event_type TEXT NOT NULL CHECK (event_type IN (
|
|
81
|
-
'session.opened','session.status_changed','session.next_owner_changed',
|
|
82
|
-
'turn.opened','turn.closed',
|
|
83
|
-
'command.queued','command.applied','command.rejected',
|
|
84
|
-
'projection.rendered','rebuild.completed'
|
|
85
|
-
)),
|
|
86
|
-
actor TEXT NOT NULL,
|
|
87
|
-
audience TEXT NOT NULL,
|
|
88
|
-
at TEXT NOT NULL,
|
|
89
|
-
payload_json TEXT NOT NULL
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
CREATE VIEW IF NOT EXISTS latest_session_state AS
|
|
93
|
-
SELECT
|
|
94
|
-
s.*,
|
|
95
|
-
t.turn_id AS current_turn_id_verified,
|
|
96
|
-
t.sequence_no AS current_turn_sequence_no,
|
|
97
|
-
t.status AS current_turn_status,
|
|
98
|
-
t.owner_seat AS current_turn_owner
|
|
99
|
-
FROM sessions s
|
|
100
|
-
LEFT JOIN turns t ON t.turn_id = s.current_turn_id;
|
|
101
|
-
|
|
102
|
-
CREATE VIEW IF NOT EXISTS latest_turn_state AS
|
|
103
|
-
SELECT * FROM turns
|
|
104
|
-
WHERE status = 'open'
|
|
105
|
-
ORDER BY started_at DESC;
|
|
106
|
-
|
|
107
|
-
CREATE VIEW IF NOT EXISTS pending_commands AS
|
|
108
|
-
SELECT * FROM commands
|
|
109
|
-
WHERE status = 'queued'
|
|
110
|
-
ORDER BY issued_at ASC;
|
|
111
|
-
`;
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Apply the schema to a SQLite handle. Idempotent; safe to call on every
|
|
115
|
-
* session-open.
|
|
116
|
-
*/
|
|
117
|
-
export function applySupervisionSchema(handle: SupervisionSqliteHandle): void {
|
|
118
|
-
// SQLite CLI wrappers generally accept multi-statement SQL on run(); this
|
|
119
|
-
// matches the shape used by bun:sqlite and better-sqlite3's .exec().
|
|
120
|
-
handle.run(SUPERVISION_SCHEMA_SQL);
|
|
121
|
-
}
|