sept-agent 0.1.3 → 0.1.4

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.
Files changed (48) hide show
  1. package/CONTRIBUTING.md +8 -4
  2. package/README.md +33 -8
  3. package/dist/src/cli/commands.js +4 -0
  4. package/dist/src/cli/commands.js.map +1 -1
  5. package/dist/src/cli/hands-docker.d.ts +7 -0
  6. package/dist/src/cli/hands-docker.js +182 -0
  7. package/dist/src/cli/hands-docker.js.map +1 -0
  8. package/dist/src/cli/hands-finish.d.ts +2 -0
  9. package/dist/src/cli/hands-finish.js +164 -0
  10. package/dist/src/cli/hands-finish.js.map +1 -0
  11. package/dist/src/cli/hands-owner.d.ts +10 -0
  12. package/dist/src/cli/hands-owner.js +83 -0
  13. package/dist/src/cli/hands-owner.js.map +1 -0
  14. package/dist/src/cli/hands-record.d.ts +33 -0
  15. package/dist/src/cli/hands-record.js +164 -0
  16. package/dist/src/cli/hands-record.js.map +1 -0
  17. package/dist/src/cli/hands.d.ts +3 -0
  18. package/dist/src/cli/hands.js +169 -0
  19. package/dist/src/cli/hands.js.map +1 -0
  20. package/dist/src/cli/options.d.ts +1 -0
  21. package/dist/src/cli/options.js +2 -1
  22. package/dist/src/cli/options.js.map +1 -1
  23. package/dist/src/cli.js +1 -1
  24. package/dist/src/cli.js.map +1 -1
  25. package/dist/src/execution/index.d.ts +4 -0
  26. package/dist/src/execution/index.js +4 -0
  27. package/dist/src/execution/index.js.map +1 -1
  28. package/examples/incident-investigator/README.md +4 -4
  29. package/examples/incident-investigator/package.json +1 -1
  30. package/examples/node-app/README.md +4 -4
  31. package/examples/node-app/package.json +1 -1
  32. package/package.json +1 -8
  33. package/src/cli/commands.ts +4 -0
  34. package/src/cli/hands-docker.ts +198 -0
  35. package/src/cli/hands-finish.ts +204 -0
  36. package/src/cli/hands-owner.ts +118 -0
  37. package/src/cli/hands-record.ts +213 -0
  38. package/src/cli/hands.ts +207 -0
  39. package/src/cli/options.ts +3 -1
  40. package/src/cli.ts +1 -1
  41. package/src/execution/index.ts +10 -0
  42. package/docs/architecture.md +0 -168
  43. package/docs/index.md +0 -55
  44. package/docs/models.md +0 -78
  45. package/docs/observability.md +0 -63
  46. package/docs/pi-contract.md +0 -482
  47. package/docs/sdk.md +0 -180
  48. package/docs/worker-api.md +0 -138
@@ -0,0 +1,83 @@
1
+ /** Exact Engine, setup label, image and kernel lifetime checks precede every setup finalizer. */
2
+ import { join } from "node:path";
3
+ import { atomicWrite, SeptError } from "../durable/index.js";
4
+ import { DockerEngineControl, captureNamespaceLifetime, stopCapturedNamespace, parseNamespaceLifetime, } from "../execution/index.js";
5
+ import { handsDocker } from "./hands-docker.js";
6
+ import { readHandsMetadata, writeHandsReceipt } from "./hands-record.js";
7
+ function isRecord(value) {
8
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9
+ }
10
+ function record(value) {
11
+ if (!isRecord(value)) {
12
+ throw new SeptError("Hands setup inspection is malformed");
13
+ }
14
+ return value;
15
+ }
16
+ /** Open the originally captured socket/daemon only; ambient context and replacement daemons refuse. */
17
+ export async function openHandsEngine(receipt) {
18
+ const engine = await DockerEngineControl.open(receipt.engineSocket);
19
+ if (engine.socketIdentity !== receipt.socketIdentity || engine.daemonId !== receipt.daemonId) {
20
+ await engine.close();
21
+ throw new SeptError("Hands setup Engine ownership changed");
22
+ }
23
+ return engine;
24
+ }
25
+ /** A pre-create receipt can recover only its unique setup-labelled container, never a foreign name. */
26
+ export async function inspectHandsOwner(root, receipt, engine) {
27
+ const containerId = receipt.containerId ??
28
+ handsDocker(root, receipt, ["inspect", "--format", "{{.Id}}", `sept-hands-${receipt.owner}`]);
29
+ if (!/^[a-f0-9]{64}$/.test(containerId)) {
30
+ throw new SeptError("Hands setup container identity is malformed");
31
+ }
32
+ const inspected = record(await engine.inspect(containerId));
33
+ const labels = record(record(inspected.Config).Labels);
34
+ const state = record(inspected.State);
35
+ if (labels["sept.setup.owner"] !== receipt.owner ||
36
+ inspected.Image !== receipt.image ||
37
+ inspected.Id !== containerId ||
38
+ (receipt.generation !== undefined && state.StartedAt !== receipt.generation)) {
39
+ throw new SeptError("Hands setup container ownership or generation changed");
40
+ }
41
+ receipt.containerId = containerId;
42
+ writeHandsReceipt(root, receipt);
43
+ return state;
44
+ }
45
+ /** Capture the native pinned stop receipt before granting the first permission revision. */
46
+ export async function captureHandsOwner(root, receipt, configuration, engine) {
47
+ const lifetime = await captureNamespaceLifetime(configuration, engine);
48
+ atomicWrite(join(root, "evidence", "lifetime.json"), lifetime);
49
+ receipt.phase = "running";
50
+ writeHandsReceipt(root, receipt);
51
+ }
52
+ /** Stop only the captured namespace lifetime, independently verifying stopped/PID0 after helper teardown. */
53
+ export async function stopHandsOwner(root, receipt, engine) {
54
+ const state = await inspectHandsOwner(root, receipt, engine);
55
+ if (state.Running === false && state.Pid === 0) {
56
+ return;
57
+ }
58
+ if (receipt.containerId === undefined || receipt.generation === undefined) {
59
+ throw new SeptError("Hands generation was not captured; manual reconciliation required");
60
+ }
61
+ const path = join(root, "evidence", "lifetime.json");
62
+ const raw = readHandsMetadata(path, 1024);
63
+ const lifetime = parseNamespaceLifetime(raw);
64
+ try {
65
+ await stopCapturedNamespace({ containerId: receipt.containerId, generation: receipt.generation }, lifetime, engine);
66
+ }
67
+ catch {
68
+ // A successful pinned namespace stop also tears down its own helper; closure decides success.
69
+ }
70
+ await verifyStopped(root, receipt, engine);
71
+ }
72
+ async function verifyStopped(root, receipt, engine) {
73
+ const deadline = performance.now() + 30_000;
74
+ while (performance.now() < deadline) {
75
+ const state = await inspectHandsOwner(root, receipt, engine);
76
+ if (state.Running === false && state.Pid === 0) {
77
+ return;
78
+ }
79
+ await new Promise((resolve) => setTimeout(resolve, 100));
80
+ }
81
+ throw new SeptError("Hands setup shutdown could not be verified");
82
+ }
83
+ //# sourceMappingURL=hands-owner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hands-owner.js","sourceRoot":"","sources":["../../../src/cli/hands-owner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /** Fixed paths returned directly as existing createWorker options; no credential is generated. */
2
+ export interface HandsPaths {
3
+ stateRoot: string;
4
+ agentDir: string;
5
+ workspaceRoot: string;
6
+ handsConfigurationPath: string;
7
+ }
8
+ /** Durable exclusive setup identity survives partial creation and never grants task authority. */
9
+ export interface HandsReceipt {
10
+ version: 1;
11
+ owner: string;
12
+ engineSocket: string;
13
+ socketIdentity: string;
14
+ daemonId: string;
15
+ image: string;
16
+ containerId?: string;
17
+ generation?: string;
18
+ phase: "prepared" | "creating" | "running" | "ready" | "failed" | "finished";
19
+ }
20
+ /** Derive the sole supported fresh-instance layout. */
21
+ export declare function handsPaths(root: string): HandsPaths;
22
+ /** Refuse lexical aliases and mutable ancestors before creating or reading ownership. */
23
+ export declare function trustedHandsRoot(value: string | undefined, fresh?: boolean): string;
24
+ /** Create only a new root: a failed or foreign instance is never overwritten or adopted by init. */
25
+ export declare function createHandsRoot(root: string): HandsPaths;
26
+ /** Persist recovery ownership before creating a container and after every identity transition. */
27
+ export declare function writeHandsReceipt(root: string, receipt: HandsReceipt): void;
28
+ /** Read bounded private ownership, refusing edited schema, symlinks, hardlinks or broad permissions. */
29
+ export declare function readHandsReceipt(root: string): HandsReceipt;
30
+ /** Read private bounded setup metadata without presenting hostile JSON or filesystem diagnostics. */
31
+ export declare function readHandsMetadata(path: string, maximum: number): unknown;
32
+ /** Generate the unguessable container ownership label before any Engine effect. */
33
+ export declare function newHandsOwner(): string;
@@ -0,0 +1,164 @@
1
+ /** Private ownership receipts for the optional local hands setup commands. */
2
+ import { lstatSync, mkdirSync, readFileSync, realpathSync, chmodSync, openSync, fsyncSync, closeSync, } from "node:fs";
3
+ import { dirname, isAbsolute, join, normalize } from "node:path";
4
+ import { randomUUID } from "node:crypto";
5
+ import { atomicWrite, SeptError } from "../durable/index.js";
6
+ /** Derive the sole supported fresh-instance layout. */
7
+ export function handsPaths(root) {
8
+ return {
9
+ stateRoot: join(root, "state"),
10
+ agentDir: join(root, "agent"),
11
+ workspaceRoot: join(root, "workspace"),
12
+ handsConfigurationPath: join(root, "hands.json"),
13
+ };
14
+ }
15
+ /** Refuse lexical aliases and mutable ancestors before creating or reading ownership. */
16
+ export function trustedHandsRoot(value, fresh = false) {
17
+ if (value === undefined ||
18
+ !isAbsolute(value) ||
19
+ value.length > 4096 ||
20
+ /[\x00-\x1f,]/.test(value)) {
21
+ throw new SeptError("hands requires a canonical absolute --root without control characters or commas");
22
+ }
23
+ const existing = fresh ? dirname(value) : value;
24
+ if (realpathSync(existing) !== existing || normalize(value) !== value) {
25
+ throw new SeptError("Hands root must be canonical");
26
+ }
27
+ validateAncestors(existing);
28
+ return value;
29
+ }
30
+ function validateAncestors(existing) {
31
+ for (let path = existing;; path = dirname(path)) {
32
+ const stat = lstatSync(path);
33
+ const owner = stat.uid === 0 || stat.uid === process.getuid?.();
34
+ const sticky = stat.uid === 0 && (stat.mode & 0o1000) !== 0;
35
+ if (!stat.isDirectory() || !owner || ((stat.mode & 0o022) !== 0 && !sticky)) {
36
+ throw new SeptError("Hands root ancestry is not trusted");
37
+ }
38
+ if (path === dirname(path)) {
39
+ return;
40
+ }
41
+ }
42
+ }
43
+ /** Create only a new root: a failed or foreign instance is never overwritten or adopted by init. */
44
+ export function createHandsRoot(root) {
45
+ mkdirSync(root, { mode: 0o755 });
46
+ chmodSync(root, 0o755);
47
+ const paths = handsPaths(root);
48
+ for (const directory of [
49
+ paths.stateRoot,
50
+ paths.agentDir,
51
+ paths.workspaceRoot,
52
+ join(root, "evidence"),
53
+ join(root, "docker-cli"),
54
+ ]) {
55
+ mkdirSync(directory, { mode: 0o700 });
56
+ }
57
+ mkdirSync(join(root, "resources"), { mode: 0o755 });
58
+ chmodSync(join(root, "resources"), 0o755);
59
+ syncSetupDirectory(root);
60
+ syncSetupDirectory(dirname(root));
61
+ return paths;
62
+ }
63
+ function syncSetupDirectory(path) {
64
+ const descriptor = openSync(path, "r");
65
+ try {
66
+ fsyncSync(descriptor);
67
+ }
68
+ finally {
69
+ closeSync(descriptor);
70
+ }
71
+ }
72
+ /** Persist recovery ownership before creating a container and after every identity transition. */
73
+ export function writeHandsReceipt(root, receipt) {
74
+ atomicWrite(join(root, "evidence", "setup.json"), receipt);
75
+ }
76
+ /** Read bounded private ownership, refusing edited schema, symlinks, hardlinks or broad permissions. */
77
+ export function readHandsReceipt(root) {
78
+ const path = join(root, "evidence", "setup.json");
79
+ const raw = readHandsMetadata(path, 16 * 1024);
80
+ if (!isRecord(raw)) {
81
+ throw new SeptError("Hands setup ownership is malformed");
82
+ }
83
+ return decodeReceipt(raw);
84
+ }
85
+ /** Read private bounded setup metadata without presenting hostile JSON or filesystem diagnostics. */
86
+ export function readHandsMetadata(path, maximum) {
87
+ try {
88
+ const file = lstatSync(path);
89
+ if (!file.isFile() ||
90
+ file.nlink !== 1 ||
91
+ file.uid !== process.getuid?.() ||
92
+ (file.mode & 0o077) !== 0 ||
93
+ file.size > maximum) {
94
+ throw new SeptError("Hands metadata must be a bounded private owned regular file");
95
+ }
96
+ const raw = JSON.parse(readFileSync(path, "utf8"));
97
+ return raw;
98
+ }
99
+ catch (error) {
100
+ throw new SeptError("Hands setup metadata is unavailable or malformed", { cause: error });
101
+ }
102
+ }
103
+ function isRecord(value) {
104
+ return typeof value === "object" && value !== null && !Array.isArray(value);
105
+ }
106
+ function decodeReceipt(raw) {
107
+ const keys = [
108
+ "version",
109
+ "owner",
110
+ "engineSocket",
111
+ "socketIdentity",
112
+ "daemonId",
113
+ "image",
114
+ "containerId",
115
+ "generation",
116
+ "phase",
117
+ ];
118
+ if (Object.keys(raw).some((key) => !keys.includes(key)) || raw.version !== 1) {
119
+ throw new SeptError("Hands setup ownership is malformed");
120
+ }
121
+ const containerId = raw.containerId === undefined ? undefined : text(raw.containerId, /^[a-f0-9]{64}$/);
122
+ const generation = raw.generation === undefined ? undefined : text(raw.generation);
123
+ return {
124
+ version: 1,
125
+ owner: text(raw.owner, /^[a-f0-9-]{36}$/),
126
+ engineSocket: text(raw.engineSocket),
127
+ socketIdentity: text(raw.socketIdentity),
128
+ daemonId: text(raw.daemonId),
129
+ image: text(raw.image, /^sha256:[a-f0-9]{64}$/),
130
+ phase: receiptPhase(raw.phase),
131
+ ...(containerId === undefined ? {} : { containerId }),
132
+ ...(generation === undefined ? {} : { generation }),
133
+ };
134
+ }
135
+ function text(value, pattern) {
136
+ if (typeof value !== "string" ||
137
+ value.length === 0 ||
138
+ value.length > 4096 ||
139
+ /[\x00-\x1f]/.test(value)) {
140
+ throw new SeptError("Hands setup ownership text is malformed");
141
+ }
142
+ if (pattern !== undefined && !pattern.test(value)) {
143
+ throw new SeptError("Hands setup ownership identity is malformed");
144
+ }
145
+ return value;
146
+ }
147
+ function receiptPhase(value) {
148
+ switch (value) {
149
+ case "prepared":
150
+ case "creating":
151
+ case "running":
152
+ case "ready":
153
+ case "failed":
154
+ case "finished":
155
+ return value;
156
+ default:
157
+ throw new SeptError("Hands setup phase is malformed");
158
+ }
159
+ }
160
+ /** Generate the unguessable container ownership label before any Engine effect. */
161
+ export function newHandsOwner() {
162
+ return randomUUID();
163
+ }
164
+ //# sourceMappingURL=hands-record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hands-record.js","sourceRoot":"","sources":["../../../src/cli/hands-record.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CliInvocation } from "./options.js";
2
+ /** Execute the two installed operator commands; signals join cleanup before the process exits. */
3
+ export declare function runHands(invocation: CliInvocation): Promise<unknown>;
@@ -0,0 +1,169 @@
1
+ /** Optional local setup composition; the existing worker and policy authority remain unchanged. */
2
+ import { realpathSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { acquireStateRootLease, atomicWrite, SeptError } from "../durable/index.js";
5
+ import { DockerEngineControl, loadHandsConfiguration } from "../execution/index.js";
6
+ import { finishHands } from "./hands-finish.js";
7
+ import { runPermissions } from "./permissions.js";
8
+ import { createHandsRoot, handsPaths, newHandsOwner, trustedHandsRoot, writeHandsReceipt, } from "./hands-record.js";
9
+ import { createHandsArguments, handsDocker } from "./hands-docker.js";
10
+ import { captureHandsOwner, inspectHandsOwner, stopHandsOwner } from "./hands-owner.js";
11
+ /** Execute the two installed operator commands; signals join cleanup before the process exits. */
12
+ export async function runHands(invocation) {
13
+ if (invocation.action !== "init" && invocation.action !== "finish") {
14
+ throw new SeptError("Usage: sept hands init|finish --root <absolute-new-instance>");
15
+ }
16
+ const abort = new AbortController();
17
+ const cancel = () => {
18
+ abort.abort();
19
+ };
20
+ process.on("SIGINT", cancel);
21
+ process.on("SIGTERM", cancel);
22
+ try {
23
+ return invocation.action === "init"
24
+ ? await initialize(invocation.options, abort.signal)
25
+ : await finishHands(invocation.options);
26
+ }
27
+ finally {
28
+ process.off("SIGINT", cancel);
29
+ process.off("SIGTERM", cancel);
30
+ }
31
+ }
32
+ function assertNotCancelled(signal) {
33
+ if (signal.aborted) {
34
+ throw new SeptError("Hands setup cancelled; ownership and recovery receipts retained");
35
+ }
36
+ }
37
+ async function initialize(options, signal) {
38
+ const root = trustedHandsRoot(options.root, true);
39
+ if (options.access !== "files" && options.access !== "none") {
40
+ throw new SeptError("hands init requires explicit --access files|none");
41
+ }
42
+ if (options.image === undefined ||
43
+ options.image.length > 512 ||
44
+ options.image.startsWith("-") ||
45
+ options["engine-socket"] === undefined) {
46
+ throw new SeptError("hands init requires --image and explicit local --engine-socket");
47
+ }
48
+ const engine = await DockerEngineControl.open(options["engine-socket"]);
49
+ try {
50
+ assertNotCancelled(signal);
51
+ createHandsRoot(root);
52
+ return await initializeOwned(root, options, engine, signal);
53
+ }
54
+ finally {
55
+ await engine.close();
56
+ }
57
+ }
58
+ async function initializeOwned(root, options, engine, signal) {
59
+ const release = acquireStateRootLease(join(root, "evidence"));
60
+ const receipt = initialReceipt(options, engine);
61
+ try {
62
+ writeHandsReceipt(root, receipt);
63
+ resolveImage(root, receipt, options.image ?? "");
64
+ await createContainer(root, receipt, engine, signal);
65
+ await activatePermissions(root, options.access === "files");
66
+ assertNotCancelled(signal);
67
+ receipt.phase = "ready";
68
+ writeHandsReceipt(root, receipt);
69
+ return {
70
+ ...handsPaths(root),
71
+ containerId: receipt.containerId,
72
+ generation: receipt.generation,
73
+ access: options.access,
74
+ };
75
+ }
76
+ catch (error) {
77
+ await initializationFailure(root, receipt, engine);
78
+ throw new SeptError("Hands initialization failed; recovery evidence retained under --root", {
79
+ cause: error,
80
+ });
81
+ }
82
+ finally {
83
+ release();
84
+ }
85
+ }
86
+ function resolveImage(root, receipt, imageName) {
87
+ const image = handsDocker(root, receipt, ["image", "inspect", "--format", "{{.Id}}", imageName]);
88
+ if (!/^sha256:[a-f0-9]{64}$/.test(image)) {
89
+ throw new SeptError("Hands image must already be locally available with immutable identity");
90
+ }
91
+ receipt.image = image;
92
+ }
93
+ function initialReceipt(options, engine) {
94
+ return {
95
+ version: 1,
96
+ owner: newHandsOwner(),
97
+ engineSocket: realpathSync(options["engine-socket"] ?? ""),
98
+ socketIdentity: engine.socketIdentity,
99
+ daemonId: engine.daemonId,
100
+ image: `sha256:${"0".repeat(64)}`,
101
+ phase: "prepared",
102
+ };
103
+ }
104
+ async function createContainer(root, receipt, engine, signal) {
105
+ receipt.phase = "creating";
106
+ writeHandsReceipt(root, receipt);
107
+ receipt.containerId = handsDocker(root, receipt, createHandsArguments(root, receipt));
108
+ await inspectHandsOwner(root, receipt, engine);
109
+ assertNotCancelled(signal);
110
+ handsDocker(root, receipt, ["start", receipt.containerId]);
111
+ const state = await inspectHandsOwner(root, receipt, engine);
112
+ if (typeof state.StartedAt !== "string" || state.Running !== true) {
113
+ throw new SeptError("Hands start generation was not established");
114
+ }
115
+ receipt.generation = state.StartedAt;
116
+ writeHandsReceipt(root, receipt);
117
+ const paths = handsPaths(root);
118
+ atomicWrite(paths.handsConfigurationPath, {
119
+ profile: "docker-linux-warm-v1",
120
+ engineSocket: receipt.engineSocket,
121
+ containerId: receipt.containerId,
122
+ generation: receipt.generation,
123
+ workspace: paths.workspaceRoot,
124
+ resources: join(root, "resources"),
125
+ dataDomain: "private",
126
+ workspaceLimits: { bytes: 134217728, inodes: 32768 },
127
+ shell: false,
128
+ readOnlyMounts: [],
129
+ });
130
+ await captureHandsOwner(root, receipt, loadHandsConfiguration(paths.handsConfigurationPath), engine);
131
+ assertNotCancelled(signal);
132
+ }
133
+ async function activatePermissions(root, files) {
134
+ const paths = handsPaths(root);
135
+ const policy = join(root, "evidence", "initial-policy.json");
136
+ atomicWrite(policy, {
137
+ mode: "scoped",
138
+ workspace: { read: files, write: files },
139
+ selected: [],
140
+ execute: false,
141
+ network: false,
142
+ });
143
+ await runPermissions({
144
+ command: "permissions",
145
+ action: "set",
146
+ options: { hands: paths.handsConfigurationPath, policy, revision: "0" },
147
+ }, paths.stateRoot, paths.agentDir);
148
+ }
149
+ async function initializationFailure(root, receipt, engine) {
150
+ let stopped = receipt.phase === "prepared";
151
+ try {
152
+ if (!stopped) {
153
+ await stopHandsOwner(root, receipt, engine);
154
+ stopped = true;
155
+ }
156
+ }
157
+ catch {
158
+ // Unknown ownership never authorizes a broader stop; retain evidence for explicit reconciliation.
159
+ }
160
+ finally {
161
+ receipt.phase = "failed";
162
+ writeHandsReceipt(root, receipt);
163
+ atomicWrite(join(root, "evidence", "initialization-failure.json"), {
164
+ stopped,
165
+ reconciliationRequired: !stopped,
166
+ });
167
+ }
168
+ }
169
+ //# sourceMappingURL=hands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hands.js","sourceRoot":"","sources":["../../../src/cli/hands.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  * strings toward command composition without interpreting runtime or credential semantics.
4
4
  */
5
5
  declare const OPTION_KEYS: {
6
+ readonly hands: readonly ["root", "engine-socket", "image", "access"];
6
7
  readonly worker: readonly ["hands", "agent-dir", "host", "port", "state-dir", "workspace-root"];
7
8
  readonly run: readonly ["hands", "agent-dir", "resume", "message", "max-epochs", "max-invocations", "model", "provider", "role", "state-dir", "task", "thinking", "timeout", "workspace"];
8
9
  readonly doctor: readonly ["agent-dir", "provider"];
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import { CliError } from "./errors.js";
6
6
  const OPTION_KEYS = {
7
+ hands: ["root", "engine-socket", "image", "access"],
7
8
  worker: ["hands", "agent-dir", "host", "port", "state-dir", "workspace-root"],
8
9
  run: [
9
10
  "hands",
@@ -68,7 +69,7 @@ export function parseCliInvocation(argv) {
68
69
  if (!isCommand(command)) {
69
70
  return undefined;
70
71
  }
71
- const hasAction = command === "models" || command === "auth" || command === "permissions";
72
+ const hasAction = command === "models" || command === "auth" || command === "permissions" || command === "hands";
72
73
  const action = hasAction ? argv[3] : undefined;
73
74
  const options = parseOptions(argv.slice(hasAction ? 4 : 3), OPTION_KEYS[command]);
74
75
  return action === undefined ? { command, options } : { command, action, options };
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/cli/options.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,MAAM,WAAW,GAAG;IAClB,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,CAAC;IAC7E,GAAG,EAAE;QACH,OAAO;QACP,WAAW;QACX,QAAQ;QACR,SAAS;QACT,YAAY;QACZ,iBAAiB;QACjB,OAAO;QACP,UAAU;QACV,MAAM;QACN,WAAW;QACX,MAAM;QACN,UAAU;QACV,SAAS;QACT,WAAW;KACZ;IACD,MAAM,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC;IACjC,MAAM,EAAE,CAAC,KAAK,CAAC;IACf,MAAM,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,UAAU,CAAC;IAC1C,WAAW,EAAE;QACX,WAAW;QACX,WAAW;QACX,OAAO;QACP,QAAQ;QACR,MAAM;QACN,UAAU;QACV,SAAS;QACT,QAAQ;QACR,SAAS;KACV;IACD,IAAI,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,UAAU,CAAC;CACjC,CAAC;AAYX,SAAS,SAAS,CAAC,KAAyB;IAC1C,OAAO,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,YAAY,CAAC,MAAgB,EAAE,OAA0B;IAChE,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,QAAQ,CAAC,gCAAgC,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,QAAQ,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;QAClD,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,QAAQ,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,kBAAkB,CAAC,IAAc;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,aAAa,CAAC;IAC1F,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAClF,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACpF,CAAC"}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/cli/options.ts"],"names":[],"mappings":"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"}
package/dist/src/cli.js CHANGED
@@ -11,7 +11,7 @@ let telemetry = NOOP_TELEMETRY;
11
11
  async function main() {
12
12
  const invocation = parseCliInvocation(process.argv);
13
13
  if (invocation === undefined) {
14
- process.stderr.write("Usage: sept worker|run|doctor|health|models|auth|permissions [action] [options]\n");
14
+ process.stderr.write("Usage: sept worker|run|doctor|health|models|auth|permissions|hands [action] [options]\n");
15
15
  process.exitCode = 2;
16
16
  return;
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,IAAI,SAAS,GAAG,cAAc,CAAC;AAE/B,KAAK,UAAU,IAAI;IACjB,MAAM,UAAU,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mFAAmF,CACpF,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,IAAI,UAAU,CAAC,OAAO,KAAK,QAAQ,IAAI,UAAU,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QACpE,SAAS,GAAG,eAAe,CAAC;YAC1B,cAAc,EAAE,QAAQ,CAAC,WAAW;YACpC,OAAO,EAAE,UAAU,CAAC,OAAO;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,CAAC,KAAK,GAAG,QAAQ,UAAU,CAAC,OAAO,EAAE,CAAC;IAC7C,MAAM,cAAc,CAAC;QACnB,GAAG,UAAU;QACb,GAAG,QAAQ;QACX,QAAQ,EAAE,qBAAqB,CAAC,UAAU,CAAC,OAAO,CAAC;QACnD,SAAS;KACV,CAAC,CAAC;AACL,CAAC;AAED,MAAM,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE;IAC1C,SAAS,CAAC,GAAG,CACX,gBAAgB,EAChB,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EACjE,OAAO,CACR,CAAC;IACF,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,IAAI,SAAS,GAAG,cAAc,CAAC;AAE/B,KAAK,UAAU,IAAI;IACjB,MAAM,UAAU,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yFAAyF,CAC1F,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,IAAI,UAAU,CAAC,OAAO,KAAK,QAAQ,IAAI,UAAU,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QACpE,SAAS,GAAG,eAAe,CAAC;YAC1B,cAAc,EAAE,QAAQ,CAAC,WAAW;YACpC,OAAO,EAAE,UAAU,CAAC,OAAO;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,CAAC,KAAK,GAAG,QAAQ,UAAU,CAAC,OAAO,EAAE,CAAC;IAC7C,MAAM,cAAc,CAAC;QACnB,GAAG,UAAU;QACb,GAAG,QAAQ;QACX,QAAQ,EAAE,qBAAqB,CAAC,UAAU,CAAC,OAAO,CAAC;QACnD,SAAS;KACV,CAAC,CAAC;AACL,CAAC;AAED,MAAM,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE;IAC1C,SAAS,CAAC,GAAG,CACX,gBAAgB,EAChB,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EACjE,OAAO,CACR,CAAC;IACF,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -9,3 +9,7 @@ export { capabilityBinding, defaultCapabilities, validateCapabilities, capabilit
9
9
  export { initializeCapabilityEngine, validateDockerConfiguration, revokeDockerBinding, revokeRecordedHandsBinding, reconcileDockerBinding, assertHandsRunProfile, } from "./docker-control.js";
10
10
  /** Exact-family filter generation for trusted consumer-owned network setup. */
11
11
  export { networkFirewall } from "./network-profile.js";
12
+ /** Local setup uses the same authenticated Engine and pinned namespace cleanup as the worker. */
13
+ export { DockerEngineControl } from "./docker-engine.js";
14
+ export { captureNamespaceLifetime, stopCapturedNamespace, parseNamespaceLifetime, } from "./hands-processes.js";
15
+ export { guardedCommand } from "./hands-guarded-command.js";
@@ -9,4 +9,8 @@ export { capabilityBinding, defaultCapabilities, validateCapabilities, capabilit
9
9
  export { initializeCapabilityEngine, validateDockerConfiguration, revokeDockerBinding, revokeRecordedHandsBinding, reconcileDockerBinding, assertHandsRunProfile, } from "./docker-control.js";
10
10
  /** Exact-family filter generation for trusted consumer-owned network setup. */
11
11
  export { networkFirewall } from "./network-profile.js";
12
+ /** Local setup uses the same authenticated Engine and pinned namespace cleanup as the worker. */
13
+ export { DockerEngineControl } from "./docker-engine.js";
14
+ export { captureNamespaceLifetime, stopCapturedNamespace, parseNamespaceLifetime, } from "./hands-processes.js";
15
+ export { guardedCommand } from "./hands-guarded-command.js";
12
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/index.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,OAAO,EACL,4BAA4B,GAO7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1E,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AAEnC,qGAAqG;AACrG,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,0BAA0B,EAC1B,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAE7B,+EAA+E;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/index.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,OAAO,EACL,4BAA4B,GAO7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1E,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AAEnC,qGAAqG;AACrG,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,0BAA0B,EAC1B,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAE7B,+EAA+E;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,iGAAiG;AACjG,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC"}
@@ -10,9 +10,9 @@ npm install --omit=dev --save-exact "$SEPT_TARBALL"
10
10
  npm ls --omit=dev --json > production-dependencies.json
11
11
  ```
12
12
 
13
- Follow the [supplied-hands setup](../../docs/pi-contract.md#executable-supplied-hands-setup) using **separate fresh** brain/agent/state/workspace/initially-empty resources/profile/generation from the native file example. Valid hands is mandatory even for inline text. Before any worker/factory/direct initialization, installed `permissions show` must show absent policy/revision0; installed `permissions set --revision 0` sets scoped workspace read/write false, selected empty, execute/network false. Assert `freshBackendRequired:false` and unchanged running generation. Keep network none and `shell:false`; do not grant file/shell/network rights to make this app pass.
13
+ Follow the [fresh-instance setup](../../README.md#install-and-prepare) with `--root "$SEPT_INCIDENT_APP/instance" --access none`, choosing the actual local Engine socket and locally available image. Use an instance separate from the native file example. Valid hands is mandatory even for inline text. The helper activates zero workspace/selected/execute/network rights before worker initialization; do not grant file/shell/network rights to make this app pass.
14
14
 
15
- Configure a suitable provider/model in the private agent directory using [models](../../docs/models.md). Start the installed complete worker with explicit paths and a privately supplied token (or use the [Node host](../node-app/worker.mjs) with these incident roots). The app's five explicit inputs are the authenticated worker origin, token, workspace, provider and model; a stable event ID identifies the logical investigation.
15
+ Set `SEPT_STATE_DIR`, `PI_CODING_AGENT_DIR`, `SEPT_WORKSPACE_ROOT` and `SEPT_HANDS_CONFIGURATION` from setup's `stateRoot`, `agentDir`, `workspaceRoot` and `handsConfigurationPath` fields. Configure a suitable provider/model through [model authentication](../../README.md#model-authentication). Start the installed complete worker with explicit paths and a privately supplied token (or use the [Node host](../node-app/worker.mjs) with these incident roots). The app's five explicit inputs are the authenticated worker origin, token, workspace, provider and model; a stable event ID identifies the logical investigation.
16
16
 
17
17
  ```sh
18
18
  sept worker --state-dir "$SEPT_STATE_DIR" --agent-dir "$PI_CODING_AGENT_DIR" \
@@ -32,7 +32,7 @@ node investigate.mjs wait
32
32
 
33
33
  The `wait` command prints authoritative WAIT and exits, deliberately retaining the coherent waiting run. Stop/join the worker. Export any needed workspace, then stop and verify its exact owned generation using the supplied-hands guards. Create a **fresh minimal** generation and a dedicated initially-empty resources root/profile; preserve the same private state/agent/workspace roots and model selection. Use installed `permissions show` to obtain the current revision and `permissions set --revision CURRENT` with the same zero-rights policy and fresh profile; confirm `freshBackendRequired:false` and the fresh running generation. Start the worker again with that profile and the same persistent roots. The earlier generation must remain stopped/PID0; never reuse it.
34
34
 
35
- With the original setup's explicit-socket `sept_docker`/`sept_socket_matches` functions and exported roots/image still in this operator shell, the fresh generation and current-revision activation are:
35
+ The fresh-instance helper does not orchestrate this durable restart/rebind. The advanced operator-managed snippet below requires separately supplied `sept_docker`/`sept_socket_matches` guards pinned to the original local socket identity and daemon, `SEPT_ENGINE_ID`, immutable `SEPT_IMAGE`, private `SEPT_OPERATOR_ROOT`, `SEPT_EVIDENCE/socket.json`, and `SEPT_OPERATOR_ROOT/minimal-policy.json` containing the same zero-rights policy. These guards, receipts and exact-generation finalizers are prerequisites, not outputs of the helper. With those existing operator inputs, the fresh generation and current-revision activation are:
36
36
 
37
37
  ```sh
38
38
  set -eu
@@ -105,4 +105,4 @@ Expected output is a `WAIT` record from `getTask`, followed by a `report` record
105
105
 
106
106
  On failure or SIGINT/SIGTERM, `finally` independently attempts bounded cancellation of an unfinished admitted run. Cancellation can return while settlement continues; inspect authoritative state and reconcile an ambiguous request. The app does not own an external worker/provider/hands process. Their operator must independently stop/join each worker/provider/listener/attachment/lease and the exact owned generation using the setup's authority guards, verify stopped/PID0, and retain mutexes/stopped resources/recovery. A successful wait command retains WAIT; a successful report retains the terminal run. The external worker remains under its caller's lifecycle control.
107
107
 
108
- Persistent WAIT/stop/reopen is supported by the [SDK lifecycle](../../docs/sdk.md#worker-lifecycle): await stop, supply a fresh hands generation under current revision CAS, reopen the same persistent roots, and then send later evidence. Do not reuse a stopped generation or reset the task's budget/history. Provider outages/OAuth refresh, full Darwin/Intel/Windows and arbitrary Docker hosts remain unqualified.
108
+ Persistent WAIT/stop/reopen requires the existing SDK lifecycle: await stop, supply a fresh hands generation under current revision CAS, reopen the same persistent roots, and then send later evidence. Do not reuse a stopped generation or reset the task's budget/history. Provider outages/OAuth refresh, full Darwin/Intel/Windows and arbitrary Docker hosts remain unqualified.
@@ -10,6 +10,6 @@
10
10
  "report": "node investigate.mjs report"
11
11
  },
12
12
  "dependencies": {
13
- "sept-agent": "0.1.3"
13
+ "sept-agent": "0.1.4"
14
14
  }
15
15
  }