@knpkv/herdr-fleet 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
  Fleet job protocol and local decision authority for Herdr hosts.
4
4
 
5
- The host that receives a job owns its durable SQLite record and every state transition. Risky work starts as `pending_approval`; approval is bound to the job's canonical hash and one-time nonce. Rejection and expiry clear that nonce. Safe work queues immediately. Recovery resumes queued jobs and expires stale approvals without moving authority to a coordinator.
5
+ The host that receives a job owns its durable SQLite record and every state transition. Risky work starts as `pending_approval`; approval is bound to the job's canonical hash and one-time nonce. Rejection and expiry clear that nonce. Safe work queues immediately. `submit` takes a `SubmissionProvenance`, defaulting to `authenticated_remote`. With `verified_local_listener`, the `nix.*` and `agent.*` kinds in `LocalListenerApprovalExemptKind` queue without approval; Work authority kinds and `browser.mcp.recover` still start as `pending_approval`. The exempt list is typed to exclude every Work kind, so adding one fails to compile. Recovery resumes queued jobs and expires stale approvals without moving authority to a coordinator.
6
6
 
7
7
  `JobRecord.hash` persists a lowercase hex SHA-256 digest. Its canonical JSON input contains the host, actor, payload discriminant, and every identity field for that variant: `ref` for `nix.apply`; `repository`, `prompt`, `mode`, and the optional `channel` for `agent.delegate`; `session` and `message` for `agent.message`; no extra field for `nix.check` or `browser.mcp.recover`. Raw credentials and provider secrets never enter this hash or the persisted job payload.
8
8
 
9
+ `AgentDelegate.mode` is the explicit model-dispatch intent. `consult` is a bounded Luna consultation at medium reasoning effort; `transition_summary` is a Luna summary at low effort. `review` and `work`, including coding, recovery, escalation, mutation, and public-contract changes, remain Sol work at high effort. Status and wait use their non-delegating operations and never become model dispatches. Adapters must switch on this required discriminator; prompt inference and a default route are invalid.
10
+
9
11
  The package exports:
10
12
 
11
13
  - Schema contracts for configuration, jobs, status, and agent inventory
@@ -18,8 +20,20 @@ The package exports:
18
20
 
19
21
  `HostConfiguration.machines` stores `{ host, nodeId }` for every fleet machine. Both fields must be unique. Tailscale adapters use the stable node ID as authority and treat the hostname only as a consistency check.
20
22
 
21
- Callers provide `HostOperations`. This keeps Nix, Git, and Herdr command execution out of the protocol package.
23
+ `HostConfiguration.workBindAddress` is the explicit IPv4 address for the local-only Work listener. It defaults to loopback; wildcard addresses are invalid. The Work and local listeners must use distinct ports when `crossHost` is disabled.
24
+
25
+ `HostConfiguration.lanWork` is an opt-in LAN Work listener configuration with an explicit bind `address`, browser `host`, and TCP `port`. Its port must not collide with the local, Work, or approval listeners. The approvals runtime exposes only the read-only Work pairing boundary on this listener; it prints a five-minute single-use code after startup, accepts pairing only from the exact configured origin, and keeps approvals, Connect, chat, secrets, agent control, and job submission unavailable. LAN Work uses plain HTTP and therefore requires a trusted LAN or an authenticated TLS boundary before credentials cross an untrusted link.
26
+
27
+ Callers provide `HostOperations`. This keeps Nix, Git, and Herdr command execution out of the protocol package. `run` and `runCoordinatorChat` receive the accepted job ID and actor after the fleet service has enforced submission and approval. They also receive a typed lifecycle callback. Existing synchronous adapters may ignore these trailing arguments. A durable adapter supplies `recovery.matches` and `recovery.resume`, calls `accepted` once with its receipt before returning, then calls `terminal` once after the coordinator persists `settled`, `delivery_failed`, or `task_failed`. Fleet marks the job durable before invoking the adapter, stores the receipt in `acceptedReceipt`, and keeps the wrapper running between acceptance and terminal observation. If receipt validation or persistence fails after the adapter calls `accepted`, Fleet leaves the job running with a null receipt so restart recovery can idempotently rejoin the committed coordinator request. After restart, `recovery.resume` receives the deterministic job ID, either the persisted receipt or `null`, and the exact persisted worker identity or `null`. The `null` receipt case must idempotently rejoin or complete submission across a crash between the coordinator commit and Fleet receipt persistence. When a worker is present, recovery reattaches that worker and replays `workerStarted` without prompting or discovering another worker. Exact replay is accepted only during recovery, with Fleet host casing normalized; a different agent, pane, name, or relationship remains a conflict. The job ID and actor remain the idempotency and command-identity inputs.
28
+
29
+ Work authority jobs (`work.reconcile`, `work.admit`, `work.recover`, `work.reassign`) run only through a composed Work adapter. That adapter is wired by the host's operations composer, not by the default operations. An adapter declares the kinds it executes in `HostOperations.workJobKinds`. `submit` refuses any other Work kind with `FleetOperationUnavailableError` before a job or approval request exists, so an approver is never asked to approve a job that this host cannot run. When `workJobKinds` is absent, the host runs no Work kinds.
30
+
31
+ Fleet stores a bounded terminal summary, not the coordinator's authoritative result. Pass coordinator results and failure details through `summarizeHostOperationTerminalDetail` before calling `terminal`; the authoritative full value remains in the coordinator event store. Summaries are limited to 20,000 UTF-8 bytes so successful coordinator-chat results retain the existing `CoordinatorReply` contract. The lifecycle callback validates its receipt and terminal schema before persistence, so every admitted value fits the complete Fleet record envelope.
32
+
33
+ The receipt is client-visible: Fleet stores it in both `acceptedReceipt` and `result`, and authorized raw `JobRecord` job and history responses expose both fields. Durable adapters must emit a normalized client-safe identifier. Provider callback URLs, bearer tokens, credentials, and other server-private locators are invalid receipt material. A matched durable operation that returns without calling `accepted` fails with `fleet.operation_acceptance_missing` and stays recoverable. `recovery.resume` must register observation through the hostd-owned lifetime function and return promptly; it must not wait for a terminal event, because hostd completes recovery before opening listeners.
22
34
 
23
35
  When an `agent.delegate` worker starts, `JobRecord` persists its exact identity and matching `AgentConnectTarget` in the same transition. Records before start, including pending, rejected, expired, and failed-before-start jobs, contain neither field. Terminal observation time remains separate and appears only after that exact started job succeeds or fails.
24
36
 
25
37
  `agent.delegate.prompt` and `agent.message.message` are capped at the exported `jobTextMaxLength` (16 KiB). Repository, session, and ref fields have smaller identifier/path bounds. These limits keep every schema-valid payload executable through the host command adapter without crossing the operating system's single-argument limit after JSON escaping and UTF-8 encoding.
38
+
39
+ Recovery with a persisted worker rejects `terminal` until the adapter has replayed that exact worker through `workerStarted`. Relationship-free coordinator roots are valid only for consultation and transition summaries; review and work still require an exact delegated-child relationship even when the job uses the coordinator-chat channel.
package/dist/config.d.ts CHANGED
@@ -7,7 +7,13 @@ export declare const loadConfiguration: (path: string) => Effect.Effect<{
7
7
  readonly crossHost: boolean;
8
8
  readonly port: number;
9
9
  readonly localPort: number;
10
+ readonly workBindAddress?: string;
10
11
  readonly approvalPort: number;
12
+ readonly lanWork?: {
13
+ readonly address: string;
14
+ readonly host: string;
15
+ readonly port: number;
16
+ };
11
17
  readonly allowedUsers: readonly string[];
12
18
  readonly approvalNodes: readonly string[];
13
19
  readonly machines: readonly {
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAU,MAAM,QAAQ,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAGlD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+CA4B7B,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAU,MAAM,QAAQ,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAGlD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+CA4B7B,CAAA"}
package/dist/errors.d.ts CHANGED
@@ -37,6 +37,13 @@ declare const FleetApprovalError_base: Schema.Class<FleetApprovalError, Schema.T
37
37
  }>, import("effect/Cause").YieldableError>;
38
38
  export declare class FleetApprovalError extends FleetApprovalError_base {
39
39
  }
40
+ declare const FleetOperationUnavailableError_base: Schema.Class<FleetOperationUnavailableError, Schema.TaggedStruct<"FleetOperationUnavailableError", {
41
+ readonly kind: Schema.String;
42
+ readonly detail: Schema.String;
43
+ }>, import("effect/Cause").YieldableError>;
44
+ /** The host cannot execute this job kind, so it is refused before any approval request exists. */
45
+ export declare class FleetOperationUnavailableError extends FleetOperationUnavailableError_base {
46
+ }
40
47
  declare const FleetOperationError_base: Schema.Class<FleetOperationError, Schema.TaggedStruct<"FleetOperationError", {
41
48
  readonly operation: Schema.String;
42
49
  readonly detail: Schema.String;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;;;;AAE/B,qBAAa,oBAAqB,SAAQ,yBAGzC;CAAG;;;;AAEJ,qBAAa,uBAAwB,SAAQ,4BAG5C;CAAG;;;;;;AAEJ,qBAAa,eAAgB,SAAQ,oBAOpC;CAAG;;;;AAEJ,qBAAa,4BAA6B,SAAQ,iCAGjD;CAAG;;;;AAEJ,qBAAa,qBAAsB,SAAQ,0BAG1C;CAAG;;;;AAEJ,qBAAa,qBAAsB,SAAQ,0BAG1C;CAAG;;;;;AAEJ,qBAAa,kBAAmB,SAAQ,uBAGvC;CAAG;;;;;;AAEJ,qBAAa,mBAAoB,SAAQ,wBAOxC;CAAG;;;;;;AAEJ,qBAAa,sBAAuB,SAAQ,2BAO3C;CAAG;;;;;;AAEJ,qBAAa,yBAA0B,SAAQ,8BAO9C;CAAG;;;;;AAEJ,qBAAa,sBAAuB,SAAQ,2BAG3C;CAAG;;;;;;AAEJ,qBAAa,sBAAuB,SAAQ,2BAO3C;CAAG;;;;;AAEJ,qBAAa,4BAA6B,SAAQ,iCAGjD;CAAG;;;;;AAEJ,qBAAa,uBAAwB,SAAQ,4BAG5C;CAAG;;;;;AAEJ,qBAAa,2BAA4B,SAAQ,gCAMhD;CAAG"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;;;;AAE/B,qBAAa,oBAAqB,SAAQ,yBAGzC;CAAG;;;;AAEJ,qBAAa,uBAAwB,SAAQ,4BAG5C;CAAG;;;;;;AAEJ,qBAAa,eAAgB,SAAQ,oBAOpC;CAAG;;;;AAEJ,qBAAa,4BAA6B,SAAQ,iCAGjD;CAAG;;;;AAEJ,qBAAa,qBAAsB,SAAQ,0BAG1C;CAAG;;;;AAEJ,qBAAa,qBAAsB,SAAQ,0BAG1C;CAAG;;;;;AAEJ,qBAAa,kBAAmB,SAAQ,uBAGvC;CAAG;;;;;AAEJ,kGAAkG;AAClG,qBAAa,8BAA+B,SAAQ,mCAGnD;CAAG;;;;;;AAEJ,qBAAa,mBAAoB,SAAQ,wBAOxC;CAAG;;;;;;AAEJ,qBAAa,sBAAuB,SAAQ,2BAO3C;CAAG;;;;;;AAEJ,qBAAa,yBAA0B,SAAQ,8BAO9C;CAAG;;;;;AAEJ,qBAAa,sBAAuB,SAAQ,2BAG3C;CAAG;;;;;;AAEJ,qBAAa,sBAAuB,SAAQ,2BAO3C;CAAG;;;;;AAEJ,qBAAa,4BAA6B,SAAQ,iCAGjD;CAAG;;;;;AAEJ,qBAAa,uBAAwB,SAAQ,4BAG5C;CAAG;;;;;AAEJ,qBAAa,2BAA4B,SAAQ,gCAMhD;CAAG"}
package/dist/errors.js CHANGED
@@ -17,6 +17,9 @@ export class FleetJobNotFoundError extends Schema.TaggedError()("FleetJobNotFoun
17
17
  }
18
18
  export class FleetApprovalError extends Schema.TaggedError()("FleetApprovalError", { jobId: Schema.String, detail: Schema.String }) {
19
19
  }
20
+ /** The host cannot execute this job kind, so it is refused before any approval request exists. */
21
+ export class FleetOperationUnavailableError extends Schema.TaggedError()("FleetOperationUnavailableError", { kind: Schema.String, detail: Schema.String }) {
22
+ }
20
23
  export class FleetOperationError extends Schema.TaggedError()("FleetOperationError", {
21
24
  operation: Schema.String,
22
25
  detail: Schema.String,
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,MAAM,OAAO,oBAAqB,SAAQ,MAAM,CAAC,WAAW,EAAwB,CAClF,sBAAsB,EACtB,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAC1B;CAAG;AAEJ,MAAM,OAAO,uBAAwB,SAAQ,MAAM,CAAC,WAAW,EAA2B,CACxF,yBAAyB,EACzB,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CACzB;CAAG;AAEJ,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,WAAW,EAAmB,CACxE,iBAAiB,EACjB;IACE,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;CACvB,CACF;CAAG;AAEJ,MAAM,OAAO,4BAA6B,SAAQ,MAAM,CAAC,WAAW,EAAgC,CAClG,8BAA8B,EAC9B,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CACzB;CAAG;AAEJ,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,WAAW,EAAyB,CACpF,uBAAuB,EACvB,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CACzB;CAAG;AAEJ,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,WAAW,EAAyB,CACpF,uBAAuB,EACvB,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CACzB;CAAG;AAEJ,MAAM,OAAO,kBAAmB,SAAQ,MAAM,CAAC,WAAW,EAAsB,CAC9E,oBAAoB,EACpB,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAChD;CAAG;AAEJ,kGAAkG;AAClG,MAAM,OAAO,8BAA+B,SAAQ,MAAM,CAAC,WAAW,EAAkC,CACtG,gCAAgC,EAChC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAC/C;CAAG;AAEJ,MAAM,OAAO,mBAAoB,SAAQ,MAAM,CAAC,WAAW,EAAuB,CAChF,qBAAqB,EACrB;IACE,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;CACvB,CACF;CAAG;AAEJ,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,WAAW,EAA0B,CACtF,wBAAwB,EACxB;IACE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;CAC9D,CACF;CAAG;AAEJ,MAAM,OAAO,yBAA0B,SAAQ,MAAM,CAAC,WAAW,EAA6B,CAC5F,2BAA2B,EAC3B;IACE,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;CACvB,CACF;CAAG;AAEJ,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,WAAW,EAA0B,CACtF,wBAAwB,EACxB,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAC/C;CAAG;AAEJ,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,WAAW,EAA0B,CACtF,wBAAwB,EACxB;IACE,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;CACvB,CACF;CAAG;AAEJ,MAAM,OAAO,4BAA6B,SAAQ,MAAM,CAAC,WAAW,EAAgC,CAClG,8BAA8B,EAC9B,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,CAC7D;CAAG;AAEJ,MAAM,OAAO,uBAAwB,SAAQ,MAAM,CAAC,WAAW,EAA2B,CACxF,yBAAyB,EACzB,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAClD;CAAG;AAEJ,MAAM,OAAO,2BAA4B,SAAQ,MAAM,CAAC,WAAW,EAA+B,CAChG,6BAA6B,EAC7B;IACE,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;CACpD,CACF;CAAG"}
package/dist/hash.d.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  import { Crypto, Effect } from "effect";
2
2
  import { FleetOperationError } from "./errors.js";
3
+ import type { JobPayload } from "./model.js";
4
+ /**
5
+ * The exact payload text bound into a job's approval hash. Approval displays
6
+ * use it to prove that every hash-bound field is shown to the approver.
7
+ */
8
+ export declare const canonicalJobPayload: (payload: JobPayload) => string;
3
9
  export declare const jobHash: (host: string, actor: string, payload: {
4
10
  readonly kind: "nix.check";
5
11
  } | {
@@ -9,12 +15,136 @@ export declare const jobHash: (host: string, actor: string, payload: {
9
15
  readonly kind: "agent.delegate";
10
16
  readonly repository: string;
11
17
  readonly prompt: string;
12
- readonly mode: "consult" | "review" | "work";
18
+ readonly mode: "consult" | "review" | "transition_summary" | "work";
13
19
  readonly channel?: "coordinator_chat";
14
20
  } | {
15
21
  readonly kind: "agent.message";
16
22
  readonly session: string;
17
23
  readonly message: string;
24
+ } | {
25
+ readonly kind: "work.reconcile";
26
+ readonly repository: string;
27
+ readonly pullRequest: number;
28
+ readonly goalId: string;
29
+ readonly laneId: string;
30
+ readonly operationId: string;
31
+ readonly expectedRevision: number;
32
+ readonly expectedHead: string;
33
+ readonly newHead: string;
34
+ readonly expectedOwner: {
35
+ readonly id: string;
36
+ readonly name: string;
37
+ };
38
+ readonly expectedGoalEventId: string;
39
+ readonly bindingDispatchRequestId: string;
40
+ readonly sessionId: string;
41
+ readonly expectedWork: string;
42
+ readonly worker: {
43
+ readonly host: string;
44
+ readonly agentId: string;
45
+ readonly name: string;
46
+ readonly paneId: string;
47
+ readonly relationship?: {
48
+ readonly parentAgentId: string;
49
+ readonly relation: "delegated" | "pair" | "review";
50
+ };
51
+ };
52
+ readonly worktree: string;
53
+ readonly branch: string;
54
+ } | {
55
+ readonly kind: "work.admit";
56
+ readonly repository: string;
57
+ readonly pullRequest: number;
58
+ readonly reviewUrl: string;
59
+ readonly goalId: string;
60
+ readonly laneId: string;
61
+ readonly operationId: string;
62
+ readonly expectedAbsenceToken: string;
63
+ readonly head: string;
64
+ readonly baseHead: string;
65
+ readonly owner: {
66
+ readonly id: string;
67
+ readonly name: string;
68
+ };
69
+ readonly sessionId: string;
70
+ readonly expectedWork: string;
71
+ readonly worker: {
72
+ readonly host: string;
73
+ readonly agentId: string;
74
+ readonly name: string;
75
+ readonly paneId: string;
76
+ readonly relationship?: {
77
+ readonly parentAgentId: string;
78
+ readonly relation: "delegated" | "pair" | "review";
79
+ };
80
+ };
81
+ readonly worktree: string;
82
+ readonly branch: string;
83
+ readonly title: string;
84
+ readonly summary: string;
85
+ readonly detail: string;
86
+ } | {
87
+ readonly kind: "work.recover";
88
+ readonly repository: string;
89
+ readonly pullRequest: number;
90
+ readonly reviewUrl: string;
91
+ readonly goalId: string;
92
+ readonly laneId: string;
93
+ readonly operationId: string;
94
+ readonly expectedGoalEventId: string;
95
+ readonly expectedGoalUpdatedAt: number;
96
+ readonly expectedHistoryToken: string;
97
+ readonly head: string;
98
+ readonly baseHead: string;
99
+ readonly owner: {
100
+ readonly id: string;
101
+ readonly name: string;
102
+ };
103
+ readonly sessionId: string;
104
+ readonly expectedWork: string;
105
+ readonly worker: {
106
+ readonly host: string;
107
+ readonly agentId: string;
108
+ readonly name: string;
109
+ readonly paneId: string;
110
+ readonly relationship?: {
111
+ readonly parentAgentId: string;
112
+ readonly relation: "delegated" | "pair" | "review";
113
+ };
114
+ };
115
+ readonly worktree: string;
116
+ readonly branch: string;
117
+ } | {
118
+ readonly kind: "work.reassign";
119
+ readonly goalId: string;
120
+ readonly from: {
121
+ readonly id: string;
122
+ readonly name: string;
123
+ };
124
+ readonly to: {
125
+ readonly id: string;
126
+ readonly name: string;
127
+ };
128
+ readonly toAgent: {
129
+ readonly _tag: "clear";
130
+ } | {
131
+ readonly _tag: "keep";
132
+ } | {
133
+ readonly _tag: "set";
134
+ readonly agent: {
135
+ readonly host: string;
136
+ readonly agentId: string;
137
+ readonly name: string;
138
+ readonly paneId: string;
139
+ readonly relationship?: {
140
+ readonly parentAgentId: string;
141
+ readonly relation: "delegated" | "pair" | "review";
142
+ };
143
+ };
144
+ };
145
+ readonly reason: string;
146
+ readonly expectedGoalEventId: string;
147
+ readonly expectedGoalUpdatedAt: number;
18
148
  } | {
19
149
  readonly kind: "browser.mcp.recover";
20
150
  }) => Effect.Effect<string, FleetOperationError, Crypto.Crypto>;
@@ -1 +1 @@
1
- {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAY,MAAM,QAAQ,CAAA;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAsBjD,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;+DAkBlB,CAAA"}
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAI5C;;;GAGG;AACH,eAAO,MAAM,mBAAmB,YAAa,UAAU,KAAG,MAwIzD,CAAA;AAED,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+DAkBlB,CAAA"}
package/dist/hash.js CHANGED
@@ -1,7 +1,12 @@
1
- import { Crypto, Effect, Encoding } from "effect";
1
+ import { Crypto, Effect } from "effect";
2
+ import { Hex } from "effect/encoding";
2
3
  import { FleetOperationError } from "./errors.js";
3
4
  const text = (value) => JSON.stringify(value);
4
- const canonicalPayload = (payload) => {
5
+ /**
6
+ * The exact payload text bound into a job's approval hash. Approval displays
7
+ * use it to prove that every hash-bound field is shown to the approver.
8
+ */
9
+ export const canonicalJobPayload = (payload) => {
5
10
  switch (payload.kind) {
6
11
  case "browser.mcp.recover":
7
12
  return `{"kind":${text(payload.kind)}}`;
@@ -13,16 +18,135 @@ const canonicalPayload = (payload) => {
13
18
  return `{"channel":${payload.channel === undefined ? "null" : text(payload.channel)},"kind":${text(payload.kind)},"mode":${text(payload.mode)},"prompt":${text(payload.prompt)},"repository":${text(payload.repository)}}`;
14
19
  case "agent.message":
15
20
  return `{"kind":${text(payload.kind)},"message":${text(payload.message)},"session":${text(payload.session)}}`;
21
+ case "work.reconcile":
22
+ return JSON.stringify({
23
+ kind: payload.kind,
24
+ repository: payload.repository,
25
+ pullRequest: payload.pullRequest,
26
+ goalId: payload.goalId,
27
+ laneId: payload.laneId,
28
+ operationId: payload.operationId,
29
+ expectedRevision: payload.expectedRevision,
30
+ expectedHead: payload.expectedHead,
31
+ newHead: payload.newHead,
32
+ expectedOwner: { id: payload.expectedOwner.id, name: payload.expectedOwner.name },
33
+ expectedGoalEventId: payload.expectedGoalEventId,
34
+ bindingDispatchRequestId: payload.bindingDispatchRequestId,
35
+ sessionId: payload.sessionId,
36
+ expectedWork: payload.expectedWork,
37
+ worker: {
38
+ host: payload.worker.host,
39
+ agentId: payload.worker.agentId,
40
+ name: payload.worker.name,
41
+ paneId: payload.worker.paneId,
42
+ relationship: payload.worker.relationship === undefined ? null : {
43
+ parentAgentId: payload.worker.relationship.parentAgentId,
44
+ relation: payload.worker.relationship.relation
45
+ }
46
+ },
47
+ worktree: payload.worktree,
48
+ branch: payload.branch
49
+ });
50
+ case "work.admit":
51
+ return JSON.stringify({
52
+ kind: payload.kind,
53
+ repository: payload.repository,
54
+ pullRequest: payload.pullRequest,
55
+ reviewUrl: payload.reviewUrl,
56
+ goalId: payload.goalId,
57
+ laneId: payload.laneId,
58
+ operationId: payload.operationId,
59
+ expectedAbsenceToken: payload.expectedAbsenceToken,
60
+ head: payload.head,
61
+ baseHead: payload.baseHead,
62
+ owner: { id: payload.owner.id, name: payload.owner.name },
63
+ sessionId: payload.sessionId,
64
+ expectedWork: payload.expectedWork,
65
+ worker: {
66
+ host: payload.worker.host,
67
+ agentId: payload.worker.agentId,
68
+ name: payload.worker.name,
69
+ paneId: payload.worker.paneId,
70
+ relationship: payload.worker.relationship === undefined ? null : {
71
+ parentAgentId: payload.worker.relationship.parentAgentId,
72
+ relation: payload.worker.relationship.relation
73
+ }
74
+ },
75
+ worktree: payload.worktree,
76
+ branch: payload.branch,
77
+ title: payload.title,
78
+ summary: payload.summary,
79
+ detail: payload.detail
80
+ });
81
+ case "work.recover":
82
+ return JSON.stringify({
83
+ kind: payload.kind,
84
+ repository: payload.repository,
85
+ pullRequest: payload.pullRequest,
86
+ reviewUrl: payload.reviewUrl,
87
+ goalId: payload.goalId,
88
+ laneId: payload.laneId,
89
+ operationId: payload.operationId,
90
+ expectedGoalEventId: payload.expectedGoalEventId,
91
+ expectedGoalUpdatedAt: payload.expectedGoalUpdatedAt,
92
+ expectedHistoryToken: payload.expectedHistoryToken,
93
+ head: payload.head,
94
+ baseHead: payload.baseHead,
95
+ owner: { id: payload.owner.id, name: payload.owner.name },
96
+ sessionId: payload.sessionId,
97
+ expectedWork: payload.expectedWork,
98
+ worker: {
99
+ host: payload.worker.host,
100
+ agentId: payload.worker.agentId,
101
+ name: payload.worker.name,
102
+ paneId: payload.worker.paneId,
103
+ relationship: payload.worker.relationship === undefined
104
+ ? null
105
+ : {
106
+ parentAgentId: payload.worker.relationship.parentAgentId,
107
+ relation: payload.worker.relationship.relation
108
+ }
109
+ },
110
+ worktree: payload.worktree,
111
+ branch: payload.branch
112
+ });
113
+ case "work.reassign":
114
+ return JSON.stringify({
115
+ kind: payload.kind,
116
+ goalId: payload.goalId,
117
+ from: { id: payload.from.id, name: payload.from.name },
118
+ to: { id: payload.to.id, name: payload.to.name },
119
+ toAgent: payload.toAgent._tag === "set"
120
+ ? {
121
+ _tag: payload.toAgent._tag,
122
+ agent: {
123
+ host: payload.toAgent.agent.host,
124
+ agentId: payload.toAgent.agent.agentId,
125
+ name: payload.toAgent.agent.name,
126
+ paneId: payload.toAgent.agent.paneId,
127
+ relationship: payload.toAgent.agent.relationship === undefined
128
+ ? null
129
+ : {
130
+ parentAgentId: payload.toAgent.agent.relationship.parentAgentId,
131
+ relation: payload.toAgent.agent.relationship.relation
132
+ }
133
+ }
134
+ }
135
+ : { _tag: payload.toAgent._tag },
136
+ reason: payload.reason,
137
+ expectedGoalEventId: payload.expectedGoalEventId,
138
+ expectedGoalUpdatedAt: payload.expectedGoalUpdatedAt
139
+ });
16
140
  }
17
141
  };
18
142
  export const jobHash = Effect.fn("Fleet.jobHash")(function* (host, actor, payload) {
19
143
  const cryptoService = yield* Crypto.Crypto;
20
- const canonical = `{"actor":${text(actor)},"host":${text(host)},"payload":${canonicalPayload(payload)}}`;
144
+ const canonical = `{"actor":${text(actor)},"host":${text(host)},"payload":${canonicalJobPayload(payload)}}`;
21
145
  const digest = yield* cryptoService.digest("SHA-256", new TextEncoder().encode(canonical)).pipe(Effect.mapError((cause) => new FleetOperationError({
22
146
  cause,
23
147
  detail: "could not hash fleet job payload",
24
148
  operation: "fleet.job_hash"
25
149
  })));
26
- return Encoding.encodeHex(digest);
150
+ return Hex.encode(digest);
27
151
  });
28
152
  //# sourceMappingURL=hash.js.map
package/dist/hash.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAGjD,MAAM,IAAI,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;AAE7D,MAAM,gBAAgB,GAAG,CAAC,OAAmB,EAAU,EAAE;IACvD,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,qBAAqB;YACxB,OAAO,WAAW,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAA;QACzC,KAAK,WAAW;YACd,OAAO,WAAW,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAA;QACzC,KAAK,WAAW;YACd,OAAO,WAAW,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAA;QACpE,KAAK,gBAAgB;YACnB,OAAO,cAAc,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WACjF,IAAI,CAAC,OAAO,CAAC,IAAI,CACnB,WAAW,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAA;QAC5G,KAAK,eAAe;YAClB,OAAO,WAAW,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAA;IACjH,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,EACzD,IAAY,EACZ,KAAa,EACb,OAAmB;IAEnB,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAA;IAC1C,MAAM,SAAS,GAAG,YAAY,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,cAAc,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAA;IACxG,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAC7F,MAAM,CAAC,QAAQ,CACb,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,mBAAmB,CAAC;QACtB,KAAK;QACL,MAAM,EAAE,kCAAkC;QAC1C,SAAS,EAAE,gBAAgB;KAC5B,CAAC,CACL,CACF,CAAA;IACD,OAAO,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;AACnC,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"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"}