humanish 0.95.0 → 0.96.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/README.md +4 -2
- package/dist/comms-agentmail.d.ts +25 -0
- package/dist/comms-agentmail.js +418 -0
- package/dist/comms-agentmail.js.map +1 -0
- package/dist/comms-connections.d.ts +4 -2
- package/dist/comms-connections.js +3 -3
- package/dist/comms-connections.js.map +1 -1
- package/dist/comms-lease-store.d.ts +90 -0
- package/dist/comms-lease-store.js +489 -0
- package/dist/comms-lease-store.js.map +1 -0
- package/dist/comms-receiving-evidence.d.ts +46 -0
- package/dist/comms-receiving-evidence.js +35 -0
- package/dist/comms-receiving-evidence.js.map +1 -0
- package/dist/comms-receiving-inbox.d.ts +16 -0
- package/dist/comms-receiving-inbox.js +410 -0
- package/dist/comms-receiving-inbox.js.map +1 -0
- package/dist/comms-receiving-runtime.d.ts +25 -0
- package/dist/comms-receiving-runtime.js +45 -0
- package/dist/comms-receiving-runtime.js.map +1 -0
- package/dist/comms-receiving-types.d.ts +98 -0
- package/dist/comms-receiving-types.js +2 -0
- package/dist/comms-receiving-types.js.map +1 -0
- package/dist/comms-receiving.d.ts +58 -0
- package/dist/comms-receiving.js +554 -0
- package/dist/comms-receiving.js.map +1 -0
- package/dist/comms-setup.d.ts +40 -0
- package/dist/comms-setup.js +121 -0
- package/dist/comms-setup.js.map +1 -0
- package/dist/concurrent-shared-world-lab.js +662 -624
- package/dist/concurrent-shared-world-lab.js.map +1 -1
- package/dist/cua-actor-lab.d.ts +4 -1
- package/dist/cua-actor-lab.js +98 -17
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/doctor-lab.js +11 -0
- package/dist/doctor-lab.js.map +1 -1
- package/dist/e2b-terminal-lab.js +3 -0
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lab-config.d.ts +20 -3
- package/dist/lab-config.js +59 -6
- package/dist/lab-config.js.map +1 -1
- package/dist/lab-engine.js +8 -3
- package/dist/lab-engine.js.map +1 -1
- package/dist/lab-summary.d.ts +1 -0
- package/dist/lab-summary.js +8 -2
- package/dist/lab-summary.js.map +1 -1
- package/dist/observer-app.html +1 -1
- package/dist/observer-data.js +14 -1
- package/dist/observer-data.js.map +1 -1
- package/dist/oss-lab.d.ts +1 -1
- package/dist/oss-lab.js.map +1 -1
- package/dist/oss-meta-lab.d.ts +1 -1
- package/dist/oss-meta-lab.js.map +1 -1
- package/dist/program.d.ts +2 -0
- package/dist/program.js +100 -4
- package/dist/program.js.map +1 -1
- package/dist/run-narration-secrets.d.ts +5 -0
- package/dist/run-narration-secrets.js +68 -0
- package/dist/run-narration-secrets.js.map +1 -0
- package/dist/run.d.ts +7 -2
- package/dist/run.js +25 -3
- package/dist/run.js.map +1 -1
- package/dist/scripted-browser-lab.js +7 -0
- package/dist/scripted-browser-lab.js.map +1 -1
- package/dist/shared-world-lab.js +4 -0
- package/dist/shared-world-lab.js.map +1 -1
- package/dist/study-analysis-engine.js +30 -1
- package/dist/study-analysis-engine.js.map +1 -1
- package/dist/study-analysis-evidence.js +9 -1
- package/dist/study-analysis-evidence.js.map +1 -1
- package/dist/tui-app.js +134 -134
- package/dist/tui-contract.d.ts +13 -0
- package/dist/tui-contract.js.map +1 -1
- package/dist/tui-launch.d.ts +2 -0
- package/dist/tui-launch.js +9 -1
- package/dist/tui-launch.js.map +1 -1
- package/docs/architecture/comms-inbox.md +4 -0
- package/docs/architecture/real-email-receiving.md +135 -0
- package/docs/contracts/run-bundle.md +9 -1
- package/docs/contracts/schemas.md +20 -3
- package/docs/goals/current.md +5 -5
- package/docs/ramp/README.md +9 -5
- package/docs/release/0.96.0-real-email-receiving.md +47 -0
- package/package.json +2 -1
- package/skills/humanish/SKILL.md +33 -13
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { ReceivingIdentity, ReceivingLease } from "./comms-receiving-types.js";
|
|
2
|
+
declare const SCHEMA = "humanish.comms-lease-journal.v1";
|
|
3
|
+
type PhysicalIdentity = {
|
|
4
|
+
path: string;
|
|
5
|
+
dev: number;
|
|
6
|
+
ino: number;
|
|
7
|
+
};
|
|
8
|
+
type Owner = {
|
|
9
|
+
pid: number;
|
|
10
|
+
host: string;
|
|
11
|
+
token: string;
|
|
12
|
+
active: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type CommsLeaseState = "planned" | "intent" | "active" | "closing" | "not-created" | "absent" | "deleting" | "unresolved";
|
|
15
|
+
export interface CommsLeaseRecord {
|
|
16
|
+
participantId: string;
|
|
17
|
+
leaseId: string;
|
|
18
|
+
clientId: string;
|
|
19
|
+
ownership: "fresh";
|
|
20
|
+
state: CommsLeaseState;
|
|
21
|
+
lease?: ReceivingLease;
|
|
22
|
+
}
|
|
23
|
+
export interface CommsLeaseJournal {
|
|
24
|
+
schema: typeof SCHEMA;
|
|
25
|
+
project: PhysicalIdentity;
|
|
26
|
+
runId: string;
|
|
27
|
+
incarnation: string;
|
|
28
|
+
connectionName: string;
|
|
29
|
+
apiKeyEnv: string;
|
|
30
|
+
identity: ReceivingIdentity;
|
|
31
|
+
owner: Owner;
|
|
32
|
+
state: "active" | "closed" | "unresolved";
|
|
33
|
+
createdAt: string;
|
|
34
|
+
updatedAt: string;
|
|
35
|
+
leases: CommsLeaseRecord[];
|
|
36
|
+
}
|
|
37
|
+
export interface CommsRecoveryEntry {
|
|
38
|
+
id: string;
|
|
39
|
+
runId: string;
|
|
40
|
+
connectionName: string;
|
|
41
|
+
status: "active" | "closed" | "unresolved";
|
|
42
|
+
participantCount: number;
|
|
43
|
+
unresolvedCount: number;
|
|
44
|
+
activeOwner: boolean | null;
|
|
45
|
+
}
|
|
46
|
+
export declare class CommsAuthorityError extends Error {
|
|
47
|
+
readonly code: "authority_unavailable" | "authority_changed" | "owner_active" | "owner_unknown" | "binding_mismatch";
|
|
48
|
+
constructor(code: "authority_unavailable" | "authority_changed" | "owner_active" | "owner_unknown" | "binding_mismatch");
|
|
49
|
+
}
|
|
50
|
+
export declare function sameReceivingIdentity(a: ReceivingIdentity, b: ReceivingIdentity): boolean;
|
|
51
|
+
export declare function validReceivingIdentity(value: unknown): value is ReceivingIdentity;
|
|
52
|
+
export declare function validReceivingLease(value: unknown, clientId: string): value is ReceivingLease;
|
|
53
|
+
export declare class CommsLeaseStore {
|
|
54
|
+
private readonly dir;
|
|
55
|
+
private readonly name;
|
|
56
|
+
private readonly lock;
|
|
57
|
+
private journal;
|
|
58
|
+
private text;
|
|
59
|
+
private serial;
|
|
60
|
+
private released;
|
|
61
|
+
private constructor();
|
|
62
|
+
snapshot(): CommsLeaseJournal;
|
|
63
|
+
assertOwnership(): Promise<void>;
|
|
64
|
+
private update;
|
|
65
|
+
bind(participantId: string, lease: ReceivingLease): Promise<void>;
|
|
66
|
+
setState(participantId: string, state: CommsLeaseState): Promise<void>;
|
|
67
|
+
close(): Promise<void>;
|
|
68
|
+
releaseLock(): Promise<void>;
|
|
69
|
+
static create(options: {
|
|
70
|
+
cwd: string;
|
|
71
|
+
runId: string;
|
|
72
|
+
connectionName: string;
|
|
73
|
+
apiKeyEnv: string;
|
|
74
|
+
identity: ReceivingIdentity;
|
|
75
|
+
participants: string[];
|
|
76
|
+
stateDir?: string;
|
|
77
|
+
}): Promise<CommsLeaseStore>;
|
|
78
|
+
static recover(options: {
|
|
79
|
+
cwd: string;
|
|
80
|
+
runId: string;
|
|
81
|
+
connectionName: string;
|
|
82
|
+
apiKeyEnv: string;
|
|
83
|
+
stateDir?: string;
|
|
84
|
+
}): Promise<CommsLeaseStore>;
|
|
85
|
+
}
|
|
86
|
+
export declare function inspectCommsLeaseStore(options: {
|
|
87
|
+
cwd: string;
|
|
88
|
+
stateDir?: string;
|
|
89
|
+
}): Promise<CommsRecoveryEntry[]>;
|
|
90
|
+
export {};
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
/** Private cleanup authority. Never read this state from a run or an exported bundle. */
|
|
2
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
3
|
+
import { constants } from "node:fs";
|
|
4
|
+
import { lstat, mkdir, open, readdir, realpath, rename, unlink } from "node:fs/promises";
|
|
5
|
+
import { homedir, hostname } from "node:os";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
const SCHEMA = "humanish.comms-lease-journal.v1";
|
|
8
|
+
const MAX_BYTES = 1_048_576;
|
|
9
|
+
const UUID = /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/;
|
|
10
|
+
const LOCAL_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,159}$/;
|
|
11
|
+
const CONNECTION = /^[a-z][a-z0-9-]{0,47}$/;
|
|
12
|
+
const KEY_ENV = /^[A-Z][A-Z0-9_]{0,99}$/;
|
|
13
|
+
export class CommsAuthorityError extends Error {
|
|
14
|
+
code;
|
|
15
|
+
constructor(code) {
|
|
16
|
+
super(code === "owner_active" ? "Communications cleanup is owned by a live process."
|
|
17
|
+
: code === "owner_unknown" ? "Communications cleanup ownership cannot be established."
|
|
18
|
+
: code === "binding_mismatch" ? "Communications recovery does not match the recorded project, connection or account."
|
|
19
|
+
: "Communications authority is unavailable or changed. Inspect private local state before retrying.");
|
|
20
|
+
this.code = code;
|
|
21
|
+
this.name = "CommsAuthorityError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function fail(code = "authority_unavailable") { throw new CommsAuthorityError(code); }
|
|
25
|
+
const digest = (value) => createHash("sha256").update(value).digest("hex");
|
|
26
|
+
const clone = (value) => structuredClone(value);
|
|
27
|
+
const plain = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28
|
+
const safeString = (value, max = 512) => typeof value === "string" && value.length > 0 && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
29
|
+
const owned = (uid) => !process.getuid || uid === process.getuid();
|
|
30
|
+
const missing = (error) => error.code === "ENOENT";
|
|
31
|
+
const samePhysical = (a, b) => a.path === b.path && a.dev === b.dev && a.ino === b.ino;
|
|
32
|
+
export function sameReceivingIdentity(a, b) {
|
|
33
|
+
return a.provider === b.provider && a.accountId === b.accountId && a.scopeType === b.scopeType && a.scopeId === b.scopeId;
|
|
34
|
+
}
|
|
35
|
+
export function validReceivingIdentity(value) {
|
|
36
|
+
return plain(value) && value.provider === "agentmail" && safeString(value.accountId)
|
|
37
|
+
&& ["organization", "pod", "inbox"].includes(String(value.scopeType)) && safeString(value.scopeId);
|
|
38
|
+
}
|
|
39
|
+
export function validReceivingLease(value, clientId) {
|
|
40
|
+
return plain(value) && value.clientId === clientId && safeString(value.resourceId)
|
|
41
|
+
&& safeString(value.address, 320) && /^[^\s@]+@[^\s@]+$/.test(value.address);
|
|
42
|
+
}
|
|
43
|
+
async function physicalProject(cwd) {
|
|
44
|
+
const resolved = await realpath(path.resolve(cwd));
|
|
45
|
+
const info = await lstat(resolved);
|
|
46
|
+
if (!info.isDirectory() || info.isSymbolicLink())
|
|
47
|
+
fail();
|
|
48
|
+
return { path: resolved, dev: info.dev, ino: info.ino };
|
|
49
|
+
}
|
|
50
|
+
function ownerLiveness(owner) {
|
|
51
|
+
if (!owner.active)
|
|
52
|
+
return false;
|
|
53
|
+
if (owner.host !== hostname())
|
|
54
|
+
return null;
|
|
55
|
+
try {
|
|
56
|
+
process.kill(owner.pid, 0);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
return error.code === "ESRCH" ? false : null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function validateOwner(value) {
|
|
64
|
+
return plain(value) && Number.isSafeInteger(value.pid) && value.pid > 0
|
|
65
|
+
&& safeString(value.host) && typeof value.token === "string" && UUID.test(value.token) && typeof value.active === "boolean";
|
|
66
|
+
}
|
|
67
|
+
function parseJournal(text) {
|
|
68
|
+
let value;
|
|
69
|
+
try {
|
|
70
|
+
value = JSON.parse(text);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return fail();
|
|
74
|
+
}
|
|
75
|
+
if (!plain(value) || value.schema !== SCHEMA || !plain(value.project) || !safeString(value.project.path, 4096)
|
|
76
|
+
|| !path.isAbsolute(value.project.path) || !Number.isSafeInteger(value.project.dev) || !Number.isSafeInteger(value.project.ino)
|
|
77
|
+
|| typeof value.runId !== "string" || !LOCAL_ID.test(value.runId)
|
|
78
|
+
|| typeof value.incarnation !== "string" || !UUID.test(value.incarnation)
|
|
79
|
+
|| typeof value.connectionName !== "string" || !CONNECTION.test(value.connectionName)
|
|
80
|
+
|| typeof value.apiKeyEnv !== "string" || !KEY_ENV.test(value.apiKeyEnv)
|
|
81
|
+
|| !validReceivingIdentity(value.identity) || !validateOwner(value.owner)
|
|
82
|
+
|| !["active", "closed", "unresolved"].includes(String(value.state))
|
|
83
|
+
|| !safeString(value.createdAt) || !safeString(value.updatedAt)
|
|
84
|
+
|| !Array.isArray(value.leases) || value.leases.length < 1 || value.leases.length > 64)
|
|
85
|
+
fail();
|
|
86
|
+
const participants = new Set();
|
|
87
|
+
const leaseIds = new Set();
|
|
88
|
+
const resources = new Set();
|
|
89
|
+
for (const item of value.leases) {
|
|
90
|
+
if (!plain(item) || typeof item.participantId !== "string" || !LOCAL_ID.test(item.participantId)
|
|
91
|
+
|| participants.has(item.participantId) || typeof item.leaseId !== "string" || !UUID.test(item.leaseId)
|
|
92
|
+
|| leaseIds.has(item.leaseId) || item.ownership !== "fresh"
|
|
93
|
+
|| item.clientId !== `humanish-${value.incarnation}-${item.leaseId}`
|
|
94
|
+
|| !["planned", "intent", "active", "closing", "not-created", "absent", "deleting", "unresolved"].includes(String(item.state)))
|
|
95
|
+
fail();
|
|
96
|
+
if (item.lease !== undefined) {
|
|
97
|
+
if (!validReceivingLease(item.lease, item.clientId) || resources.has(item.lease.resourceId)
|
|
98
|
+
|| item.state === "planned" || item.state === "not-created")
|
|
99
|
+
fail();
|
|
100
|
+
resources.add(item.lease.resourceId);
|
|
101
|
+
}
|
|
102
|
+
else if (["active", "deleting", "absent"].includes(String(item.state)))
|
|
103
|
+
fail();
|
|
104
|
+
participants.add(item.participantId);
|
|
105
|
+
leaseIds.add(item.leaseId);
|
|
106
|
+
}
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
109
|
+
/** Pin every existing path component; never follow a symlink into operator authority. */
|
|
110
|
+
async function bindStateDirectory(directory, create) {
|
|
111
|
+
const target = path.resolve(directory);
|
|
112
|
+
const components = target.slice(path.parse(target).root.length).split(path.sep).filter(Boolean);
|
|
113
|
+
let cursor = path.parse(target).root;
|
|
114
|
+
const identities = [];
|
|
115
|
+
for (const component of components) {
|
|
116
|
+
cursor = path.join(cursor, component);
|
|
117
|
+
let info;
|
|
118
|
+
try {
|
|
119
|
+
info = await lstat(cursor);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (!missing(error))
|
|
123
|
+
throw error;
|
|
124
|
+
if (!create)
|
|
125
|
+
return null;
|
|
126
|
+
await mkdir(cursor, { mode: 0o700 });
|
|
127
|
+
info = await lstat(cursor);
|
|
128
|
+
}
|
|
129
|
+
if (!info.isDirectory() || info.isSymbolicLink())
|
|
130
|
+
fail();
|
|
131
|
+
identities.push({ path: cursor, dev: info.dev, ino: info.ino });
|
|
132
|
+
}
|
|
133
|
+
const last = await lstat(target);
|
|
134
|
+
if (!owned(last.uid) || (last.mode & 0o077) !== 0)
|
|
135
|
+
fail();
|
|
136
|
+
return identities;
|
|
137
|
+
}
|
|
138
|
+
function defaultStateDir() {
|
|
139
|
+
const env = process.env.XDG_STATE_HOME?.trim();
|
|
140
|
+
return path.join(env && path.isAbsolute(env) ? env : path.join(homedir(), ".local", "state"), "humanish", "comms");
|
|
141
|
+
}
|
|
142
|
+
class AuthorityDirectory {
|
|
143
|
+
project;
|
|
144
|
+
root;
|
|
145
|
+
components;
|
|
146
|
+
constructor(project, root, components) {
|
|
147
|
+
this.project = project;
|
|
148
|
+
this.root = root;
|
|
149
|
+
this.components = components;
|
|
150
|
+
}
|
|
151
|
+
async assert() {
|
|
152
|
+
if (!samePhysical(this.project, await physicalProject(this.project.path)))
|
|
153
|
+
fail("authority_changed");
|
|
154
|
+
for (const bound of this.components) {
|
|
155
|
+
const info = await lstat(bound.path);
|
|
156
|
+
if (!info.isDirectory() || info.isSymbolicLink() || info.dev !== bound.dev || info.ino !== bound.ino)
|
|
157
|
+
fail("authority_changed");
|
|
158
|
+
}
|
|
159
|
+
const info = await lstat(this.root);
|
|
160
|
+
if (!owned(info.uid) || (info.mode & 0o077) !== 0)
|
|
161
|
+
fail("authority_changed");
|
|
162
|
+
}
|
|
163
|
+
name(runId) { return `run-${digest(`${this.project.path}\n${this.project.dev}:${this.project.ino}\n${runId}`)}.json`; }
|
|
164
|
+
async read(name) {
|
|
165
|
+
await this.assert();
|
|
166
|
+
let handle;
|
|
167
|
+
try {
|
|
168
|
+
handle = await open(path.join(this.root, name), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
if (missing(error))
|
|
172
|
+
return null;
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const info = await handle.stat();
|
|
177
|
+
if (!info.isFile() || !owned(info.uid) || info.nlink !== 1 || (info.mode & 0o077) !== 0 || info.size > MAX_BYTES)
|
|
178
|
+
fail();
|
|
179
|
+
const bytes = await handle.readFile();
|
|
180
|
+
const current = await lstat(path.join(this.root, name));
|
|
181
|
+
if (current.dev !== info.dev || current.ino !== info.ino || bytes.length > MAX_BYTES)
|
|
182
|
+
fail("authority_changed");
|
|
183
|
+
await this.assert();
|
|
184
|
+
return bytes.toString("utf8");
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
await handle.close();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async sync() {
|
|
191
|
+
const dir = await open(this.root, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
192
|
+
try {
|
|
193
|
+
await dir.sync();
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
await dir.close();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async function authority(cwd, stateDir, create) {
|
|
201
|
+
const project = await physicalProject(cwd);
|
|
202
|
+
const root = path.resolve(stateDir ?? defaultStateDir());
|
|
203
|
+
// An explicit test/operator override still cannot turn project artifacts into authority.
|
|
204
|
+
const relative = path.relative(project.path, root);
|
|
205
|
+
if (relative === "" || (!relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative)))
|
|
206
|
+
fail();
|
|
207
|
+
const components = await bindStateDirectory(root, create);
|
|
208
|
+
return components ? new AuthorityDirectory(project, root, components) : null;
|
|
209
|
+
}
|
|
210
|
+
async function takeLock(dir, name, takeover) {
|
|
211
|
+
if (takeover) {
|
|
212
|
+
// Serialize stale-lock replacement. An interrupted takeover guard is intentionally not
|
|
213
|
+
// guessed away: unlike a live run lock, it can be between unlink and exclusive creation.
|
|
214
|
+
const guardName = `${name}.takeover`;
|
|
215
|
+
await dir.assert();
|
|
216
|
+
let guard;
|
|
217
|
+
try {
|
|
218
|
+
guard = await open(path.join(dir.root, guardName), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
return fail("owner_unknown");
|
|
222
|
+
}
|
|
223
|
+
const identity = await guard.stat();
|
|
224
|
+
try {
|
|
225
|
+
return await takeLockInner(dir, name, true);
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
await guard.close();
|
|
229
|
+
await dir.assert();
|
|
230
|
+
const current = await lstat(path.join(dir.root, guardName));
|
|
231
|
+
if (current.dev !== identity.dev || current.ino !== identity.ino)
|
|
232
|
+
fail("authority_changed");
|
|
233
|
+
await unlink(path.join(dir.root, guardName));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return takeLockInner(dir, name, false);
|
|
237
|
+
}
|
|
238
|
+
async function takeLockInner(dir, name, takeover) {
|
|
239
|
+
const lockName = `${name}.lock`;
|
|
240
|
+
await dir.assert();
|
|
241
|
+
const previous = await dir.read(lockName);
|
|
242
|
+
if (previous !== null) {
|
|
243
|
+
let owner;
|
|
244
|
+
try {
|
|
245
|
+
owner = JSON.parse(previous);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
return fail("owner_unknown");
|
|
249
|
+
}
|
|
250
|
+
if (!validateOwner(owner))
|
|
251
|
+
fail("owner_unknown");
|
|
252
|
+
const live = ownerLiveness(owner);
|
|
253
|
+
if (live === true)
|
|
254
|
+
fail("owner_active");
|
|
255
|
+
if (live === null || !takeover)
|
|
256
|
+
fail("owner_unknown");
|
|
257
|
+
// Compare exact bytes immediately before removing a dead owner's lock.
|
|
258
|
+
if (await dir.read(lockName) !== previous)
|
|
259
|
+
fail("authority_changed");
|
|
260
|
+
await unlink(path.join(dir.root, lockName));
|
|
261
|
+
}
|
|
262
|
+
const owner = { pid: process.pid, host: hostname(), token: randomUUID(), active: true };
|
|
263
|
+
const file = await open(path.join(dir.root, lockName), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
264
|
+
try {
|
|
265
|
+
await file.writeFile(JSON.stringify(owner));
|
|
266
|
+
await file.sync();
|
|
267
|
+
const info = await file.stat();
|
|
268
|
+
await dir.sync();
|
|
269
|
+
return { owner, dev: info.dev, ino: info.ino, name: lockName };
|
|
270
|
+
}
|
|
271
|
+
finally {
|
|
272
|
+
await file.close();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
export class CommsLeaseStore {
|
|
276
|
+
dir;
|
|
277
|
+
name;
|
|
278
|
+
lock;
|
|
279
|
+
journal;
|
|
280
|
+
text;
|
|
281
|
+
serial = Promise.resolve();
|
|
282
|
+
released = false;
|
|
283
|
+
constructor(dir, name, lock, journal, text) {
|
|
284
|
+
this.dir = dir;
|
|
285
|
+
this.name = name;
|
|
286
|
+
this.lock = lock;
|
|
287
|
+
this.journal = journal;
|
|
288
|
+
this.text = text;
|
|
289
|
+
}
|
|
290
|
+
snapshot() { return clone(this.journal); }
|
|
291
|
+
async assertOwnership() {
|
|
292
|
+
if (this.released)
|
|
293
|
+
fail("authority_changed");
|
|
294
|
+
await this.dir.assert();
|
|
295
|
+
const info = await lstat(path.join(this.dir.root, this.lock.name));
|
|
296
|
+
if (info.dev !== this.lock.dev || info.ino !== this.lock.ino || await this.dir.read(this.lock.name) !== JSON.stringify(this.lock.owner))
|
|
297
|
+
fail("authority_changed");
|
|
298
|
+
if (await this.dir.read(this.name) !== this.text)
|
|
299
|
+
fail("authority_changed");
|
|
300
|
+
}
|
|
301
|
+
update(change) {
|
|
302
|
+
const operation = this.serial.then(async () => {
|
|
303
|
+
await this.assertOwnership();
|
|
304
|
+
const next = clone(this.journal);
|
|
305
|
+
change(next);
|
|
306
|
+
next.updatedAt = new Date().toISOString();
|
|
307
|
+
const text = JSON.stringify(next);
|
|
308
|
+
parseJournal(text);
|
|
309
|
+
if (Buffer.byteLength(text) > MAX_BYTES)
|
|
310
|
+
fail();
|
|
311
|
+
const temporary = `${this.name}.${randomUUID()}.tmp`;
|
|
312
|
+
const file = await open(path.join(this.dir.root, temporary), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
313
|
+
try {
|
|
314
|
+
await file.writeFile(text);
|
|
315
|
+
await file.sync();
|
|
316
|
+
await this.assertOwnership();
|
|
317
|
+
await rename(path.join(this.dir.root, temporary), path.join(this.dir.root, this.name));
|
|
318
|
+
// Update memory after rename, even if the following directory flush fails.
|
|
319
|
+
this.journal = next;
|
|
320
|
+
this.text = text;
|
|
321
|
+
await this.dir.sync();
|
|
322
|
+
}
|
|
323
|
+
finally {
|
|
324
|
+
await file.close();
|
|
325
|
+
try {
|
|
326
|
+
await unlink(path.join(this.dir.root, temporary));
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
if (!missing(error))
|
|
330
|
+
throw error;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
this.serial = operation.catch(() => undefined);
|
|
335
|
+
return operation;
|
|
336
|
+
}
|
|
337
|
+
async bind(participantId, lease) {
|
|
338
|
+
await this.update(journal => {
|
|
339
|
+
const entry = journal.leases.find(item => item.participantId === participantId);
|
|
340
|
+
if (!entry || !validReceivingLease(lease, entry.clientId)
|
|
341
|
+
|| entry.state === "planned" || entry.state === "absent" || entry.state === "not-created"
|
|
342
|
+
|| (entry.lease && (entry.lease.resourceId !== lease.resourceId || entry.lease.address !== lease.address))
|
|
343
|
+
|| journal.leases.some(item => item !== entry && item.lease?.resourceId === lease.resourceId))
|
|
344
|
+
fail("binding_mismatch");
|
|
345
|
+
entry.lease = clone(lease);
|
|
346
|
+
entry.state = "active";
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
async setState(participantId, state) {
|
|
350
|
+
await this.update(journal => {
|
|
351
|
+
const entry = journal.leases.find(item => item.participantId === participantId);
|
|
352
|
+
if (!entry)
|
|
353
|
+
fail();
|
|
354
|
+
if ((entry.state === "absent" || entry.state === "not-created") && state !== entry.state)
|
|
355
|
+
fail("binding_mismatch");
|
|
356
|
+
if (state === "not-created" && entry.state !== "planned" && entry.state !== "not-created")
|
|
357
|
+
fail("binding_mismatch");
|
|
358
|
+
entry.state = state;
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
async close() {
|
|
362
|
+
if (this.released)
|
|
363
|
+
return;
|
|
364
|
+
try {
|
|
365
|
+
await this.update(journal => {
|
|
366
|
+
journal.owner.active = false;
|
|
367
|
+
journal.state = journal.leases.every(item => item.state === "absent" || item.state === "not-created") ? "closed" : "unresolved";
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
finally {
|
|
371
|
+
await this.releaseLock();
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
async releaseLock() {
|
|
375
|
+
if (this.released)
|
|
376
|
+
return;
|
|
377
|
+
await this.serial;
|
|
378
|
+
await this.dir.assert();
|
|
379
|
+
const info = await lstat(path.join(this.dir.root, this.lock.name));
|
|
380
|
+
if (info.dev !== this.lock.dev || info.ino !== this.lock.ino || await this.dir.read(this.lock.name) !== JSON.stringify(this.lock.owner))
|
|
381
|
+
fail("authority_changed");
|
|
382
|
+
await unlink(path.join(this.dir.root, this.lock.name));
|
|
383
|
+
this.released = true;
|
|
384
|
+
await this.dir.sync();
|
|
385
|
+
}
|
|
386
|
+
static async create(options) {
|
|
387
|
+
if (!LOCAL_ID.test(options.runId) || !CONNECTION.test(options.connectionName) || !KEY_ENV.test(options.apiKeyEnv)
|
|
388
|
+
|| !validReceivingIdentity(options.identity) || options.participants.length < 1 || options.participants.length > 64
|
|
389
|
+
|| new Set(options.participants).size !== options.participants.length || options.participants.some(id => !LOCAL_ID.test(id)))
|
|
390
|
+
fail();
|
|
391
|
+
const dir = await authority(options.cwd, options.stateDir, true);
|
|
392
|
+
if (!dir)
|
|
393
|
+
return fail();
|
|
394
|
+
const name = dir.name(options.runId);
|
|
395
|
+
if (await dir.read(name) !== null)
|
|
396
|
+
fail("binding_mismatch");
|
|
397
|
+
const lock = await takeLock(dir, name, false);
|
|
398
|
+
const incarnation = randomUUID();
|
|
399
|
+
const now = new Date().toISOString();
|
|
400
|
+
const journal = { schema: SCHEMA, project: dir.project, runId: options.runId, incarnation,
|
|
401
|
+
connectionName: options.connectionName, apiKeyEnv: options.apiKeyEnv, identity: clone(options.identity), owner: lock.owner,
|
|
402
|
+
state: "active", createdAt: now, updatedAt: now,
|
|
403
|
+
leases: options.participants.map(participantId => {
|
|
404
|
+
const leaseId = randomUUID();
|
|
405
|
+
return { participantId, leaseId,
|
|
406
|
+
clientId: `humanish-${incarnation}-${leaseId}`, ownership: "fresh", state: "planned" };
|
|
407
|
+
}) };
|
|
408
|
+
const text = JSON.stringify(journal);
|
|
409
|
+
const store = new CommsLeaseStore(dir, name, lock, journal, text);
|
|
410
|
+
try {
|
|
411
|
+
await dir.assert();
|
|
412
|
+
const file = await open(path.join(dir.root, name), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
413
|
+
try {
|
|
414
|
+
await file.writeFile(text);
|
|
415
|
+
await file.sync();
|
|
416
|
+
}
|
|
417
|
+
finally {
|
|
418
|
+
await file.close();
|
|
419
|
+
}
|
|
420
|
+
await dir.sync();
|
|
421
|
+
return store;
|
|
422
|
+
}
|
|
423
|
+
catch (error) {
|
|
424
|
+
await store.releaseLock();
|
|
425
|
+
throw error;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
static async recover(options) {
|
|
429
|
+
if (!LOCAL_ID.test(options.runId))
|
|
430
|
+
fail();
|
|
431
|
+
const dir = await authority(options.cwd, options.stateDir, false);
|
|
432
|
+
if (!dir)
|
|
433
|
+
return fail("binding_mismatch");
|
|
434
|
+
const name = dir.name(options.runId);
|
|
435
|
+
const text = await dir.read(name);
|
|
436
|
+
if (text === null)
|
|
437
|
+
return fail("binding_mismatch");
|
|
438
|
+
const journal = parseJournal(text);
|
|
439
|
+
if (!samePhysical(journal.project, dir.project) || journal.runId !== options.runId
|
|
440
|
+
|| journal.connectionName !== options.connectionName || journal.apiKeyEnv !== options.apiKeyEnv)
|
|
441
|
+
fail("binding_mismatch");
|
|
442
|
+
const live = ownerLiveness(journal.owner);
|
|
443
|
+
if (live === true)
|
|
444
|
+
fail("owner_active");
|
|
445
|
+
if (live === null)
|
|
446
|
+
fail("owner_unknown");
|
|
447
|
+
const lock = await takeLock(dir, name, true);
|
|
448
|
+
const store = new CommsLeaseStore(dir, name, lock, journal, text);
|
|
449
|
+
try {
|
|
450
|
+
await store.update(next => { next.owner = lock.owner; next.state = "active"; });
|
|
451
|
+
return store;
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
await store.releaseLock();
|
|
455
|
+
throw error;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
export async function inspectCommsLeaseStore(options) {
|
|
460
|
+
try {
|
|
461
|
+
const dir = await authority(options.cwd, options.stateDir, false);
|
|
462
|
+
if (!dir)
|
|
463
|
+
return [];
|
|
464
|
+
const names = (await readdir(dir.root)).filter(name => /^run-[a-f0-9]{64}\.json$/.test(name));
|
|
465
|
+
if (names.length > 10_000)
|
|
466
|
+
fail();
|
|
467
|
+
const result = [];
|
|
468
|
+
for (const name of names.sort()) {
|
|
469
|
+
const text = await dir.read(name);
|
|
470
|
+
if (text === null)
|
|
471
|
+
continue;
|
|
472
|
+
const journal = parseJournal(text);
|
|
473
|
+
if (!samePhysical(journal.project, dir.project))
|
|
474
|
+
continue;
|
|
475
|
+
if (name !== dir.name(journal.runId))
|
|
476
|
+
fail("binding_mismatch");
|
|
477
|
+
result.push({ id: name.slice(4, -5), runId: journal.runId, connectionName: journal.connectionName,
|
|
478
|
+
status: journal.state, participantCount: journal.leases.length,
|
|
479
|
+
unresolvedCount: journal.leases.filter(item => item.state !== "absent" && item.state !== "not-created").length, activeOwner: ownerLiveness(journal.owner) });
|
|
480
|
+
}
|
|
481
|
+
return result;
|
|
482
|
+
}
|
|
483
|
+
catch (error) {
|
|
484
|
+
if (error instanceof CommsAuthorityError)
|
|
485
|
+
throw error;
|
|
486
|
+
return fail();
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
//# sourceMappingURL=comms-lease-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comms-lease-store.js","sourceRoot":"","sources":["../src/comms-lease-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type CommsReceivingEvidence } from "./comms-receiving-types.js";
|
|
3
|
+
export declare const commsReceivingEvidenceSchema: z.ZodObject<{
|
|
4
|
+
schema: z.ZodLiteral<"humanish.comms-receiving.v2">;
|
|
5
|
+
channel: z.ZodLiteral<"email">;
|
|
6
|
+
provider: z.ZodLiteral<"agentmail">;
|
|
7
|
+
publication: z.ZodLiteral<"restricted-real-communications">;
|
|
8
|
+
state: z.ZodEnum<{
|
|
9
|
+
acquiring: "acquiring";
|
|
10
|
+
running: "running";
|
|
11
|
+
finished: "finished";
|
|
12
|
+
}>;
|
|
13
|
+
browserConfinement: z.ZodLiteral<"mail-surface-only">;
|
|
14
|
+
limitations: z.ZodArray<z.ZodString>;
|
|
15
|
+
participants: z.ZodArray<z.ZodObject<{
|
|
16
|
+
participantId: z.ZodString;
|
|
17
|
+
leaseId: z.ZodString;
|
|
18
|
+
acquisition: z.ZodEnum<{
|
|
19
|
+
failed: "failed";
|
|
20
|
+
pending: "pending";
|
|
21
|
+
active: "active";
|
|
22
|
+
}>;
|
|
23
|
+
cleanup: z.ZodEnum<{
|
|
24
|
+
absent: "absent";
|
|
25
|
+
deleting: "deleting";
|
|
26
|
+
pending: "pending";
|
|
27
|
+
unresolved: "unresolved";
|
|
28
|
+
}>;
|
|
29
|
+
observed: z.ZodNumber;
|
|
30
|
+
published: z.ZodNumber;
|
|
31
|
+
linkCount: z.ZodNumber;
|
|
32
|
+
codeCount: z.ZodNumber;
|
|
33
|
+
blockedAssetCount: z.ZodNumber;
|
|
34
|
+
blockedLinkCount: z.ZodNumber;
|
|
35
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
36
|
+
id: z.ZodString;
|
|
37
|
+
firstObservedAt: z.ZodString;
|
|
38
|
+
providerTimestamp: z.ZodOptional<z.ZodString>;
|
|
39
|
+
publishedAt: z.ZodOptional<z.ZodString>;
|
|
40
|
+
}, z.core.$strict>>;
|
|
41
|
+
limitations: z.ZodArray<z.ZodString>;
|
|
42
|
+
}, z.core.$strict>>;
|
|
43
|
+
}, z.core.$strict>;
|
|
44
|
+
export declare function isCommsReceivingEvidence(value: unknown): value is CommsReceivingEvidence;
|
|
45
|
+
/** Safe operational context for findings; no raw content or provider identity reaches this projection. */
|
|
46
|
+
export declare function receivingAnalysisContext(evidence: CommsReceivingEvidence, laneId: string | undefined): string;
|