@irisrun/host 0.1.0 → 0.2.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 ADDED
@@ -0,0 +1,37 @@
1
+ # @irisrun/host
2
+
3
+ **Same image, a different host — made explicit.** A host is just
4
+ `{name, capabilities, store, scheduler}`. Once the engine is pure and durability
5
+ lives in the journal, "run anywhere" stops being a slogan: any host that supplies
6
+ a store + scheduler can resume the same image, and a capability diff decides — at
7
+ deploy time, loudly — whether it's allowed to. Host-side; the core stays pure.
8
+
9
+ ## What it is
10
+
11
+ `HostAdapter` is the four-field surface (`name`, `capabilities`, `store`,
12
+ `scheduler`). `runTurnOn(adapter, opts)` runs ONE turn on that host's store +
13
+ scheduler — a thin call into the engine's `runTurn` with the adapter's ports
14
+ injected, defaulting the writer `holderId` to the host name.
15
+
16
+ The deploy gate is two functions over an image's `CapabilityProfile`:
17
+ `diffCapabilities` returns the structured `CapabilityGap[]` (booleans like
18
+ `filesystem`/`websockets`, plus `tool_locality` ranked `remote < local <
19
+ in-process` against the host's ceiling); `assertDeployable` throws — joining every
20
+ gap's message — if the image can't run. `checkHostCapabilities` is the narrower
21
+ tool-level boolean refusal. Refuse LOUDLY, never silently degrade. Zero external
22
+ deps; depends on `@irisrun/core` + `@irisrun/agent` only.
23
+
24
+ ## Use it
25
+
26
+ ```ts
27
+ import { runTurnOn, assertDeployable, type HostAdapter } from "@irisrun/host";
28
+
29
+ assertDeployable(image.requires, host); // throws naming every gap, or returns
30
+ const outcome = await runTurnOn(host, { sessionId, defDigest, program, performers, clock });
31
+ ```
32
+
33
+ See **[docs/Architecture](../../docs/architecture.md)** and
34
+ **[docs/Deploy](../../docs/deploy.md)**.
35
+
36
+ ---
37
+ Part of [Iris](../../README.md) — own, portable, verifiable state.
package/dist/adapter.d.ts CHANGED
@@ -24,10 +24,10 @@ export interface RunTurnOnOptions<S extends Json> {
24
24
  * on any host → the engine's deterministic replay does the rest. */
25
25
  export declare function runTurnOn<S extends Json>(adapter: HostAdapter, opts: RunTurnOnOptions<S>): Promise<TurnOutcome<S>>;
26
26
  /**
27
- * Tool/host-level capability check (ADR-0008): for every capability the image
27
+ * Tool/host-level capability check: for every capability the image
28
28
  * REQUIRES (`requires[k] === true`), the host must PROVIDE it (`capabilities[k]
29
29
  * === true`). `undefined`/`false` on the host means NOT satisfied — never silently
30
30
  * widened (cf. the secure-floor posture). Refuses LOUDLY, naming the gaps; the
31
- * full host capability-diff gate is deferred to M6.
31
+ * full host capability-diff gate is deferred.
32
32
  */
33
33
  export declare function checkHostCapabilities(requires: CapabilityProfile, capabilities: CapabilityProfile, hostName?: string): void;
package/dist/adapter.js CHANGED
@@ -1,10 +1,10 @@
1
- // HostAdapter (Spec 04 §3): a host is just {name, capabilities, store, scheduler}.
1
+ // HostAdapter: a host is just {name, capabilities, store, scheduler}.
2
2
  // `runTurnOn` runs a turn ON a host's store+scheduler — the host convenience that
3
3
  // makes "the SAME image, a DIFFERENT host" explicit. It REPLACES the framework's
4
4
  // enterTurn(sessionId,event) member (there is nothing to replace — no core type);
5
5
  // it is a thin call into the engine's runTurn with the adapter's ports injected.
6
- // `checkHostCapabilities` is the tool/host-level ADR-0008 refusal (the FULL host
7
- // capability-diff gate stays deferred to M6). Host-side; core stays pure.
6
+ // `checkHostCapabilities` is the tool/host-level capability refusal (the FULL host
7
+ // capability-diff gate stays deferred). Host-side; core stays pure.
8
8
  import { runTurn } from "@irisrun/core";
9
9
  /** Run one turn on `adapter`'s store + scheduler. Same image (defDigest) + program
10
10
  * on any host → the engine's deterministic replay does the rest. */
@@ -26,7 +26,7 @@ export async function runTurnOn(adapter, opts) {
26
26
  }, opts.sessionId);
27
27
  }
28
28
  // The boolean capability keys (tool_locality is a profile STRING, not a gateable
29
- // boolean, so it is not part of this refusal — the full degrade/refuse matrix is M6).
29
+ // boolean, so it is not part of this refusal — the full degrade/refuse matrix is deferred).
30
30
  const BOOLEAN_CAPS = [
31
31
  "long_running",
32
32
  "local_subprocess",
@@ -34,11 +34,11 @@ const BOOLEAN_CAPS = [
34
34
  "websockets",
35
35
  ];
36
36
  /**
37
- * Tool/host-level capability check (ADR-0008): for every capability the image
37
+ * Tool/host-level capability check: for every capability the image
38
38
  * REQUIRES (`requires[k] === true`), the host must PROVIDE it (`capabilities[k]
39
39
  * === true`). `undefined`/`false` on the host means NOT satisfied — never silently
40
40
  * widened (cf. the secure-floor posture). Refuses LOUDLY, naming the gaps; the
41
- * full host capability-diff gate is deferred to M6.
41
+ * full host capability-diff gate is deferred.
42
42
  */
43
43
  export function checkHostCapabilities(requires, capabilities, hostName = "host") {
44
44
  const unmet = [];
@@ -48,6 +48,6 @@ export function checkHostCapabilities(requires, capabilities, hostName = "host")
48
48
  }
49
49
  }
50
50
  if (unmet.length > 0) {
51
- throw new Error(`checkHostCapabilities: '${hostName}' cannot satisfy required capabilities (ADR-0008): ${unmet.join("; ")}`);
51
+ throw new Error(`checkHostCapabilities: '${hostName}' cannot satisfy required capabilities: ${unmet.join("; ")}`);
52
52
  }
53
53
  }
@@ -12,7 +12,7 @@ export interface CapabilityGap {
12
12
  * checkHostCapabilities rule; tool_locality compares the image's DEMAND to the
13
13
  * host's CEILING by the fixed rank remote<local<in-process. The local-tools-on-edge
14
14
  * gap (local_subprocess required, OR tool_locality over ceiling) carries the
15
- * literal ADR-0008 message; every other boolean gap carries the precise per-cap
15
+ * literal refusal message; every other boolean gap carries the precise per-cap
16
16
  * message. Never silently widens: undefined/false on the host = NOT satisfied.
17
17
  */
18
18
  export declare function diffCapabilities(requires: CapabilityProfile, host: HostAdapter): CapabilityGap[];
@@ -21,9 +21,9 @@ function localityRank(v) {
21
21
  // An absent demand defaults to `remote` (the least-demanding, edge-safe floor).
22
22
  return LOCALITY_RANK[v ?? "remote"];
23
23
  }
24
- /** The literal ADR-0008 refusal (agent-framework.md:682), interpolating the host
24
+ /** The literal host-capability refusal, interpolating the host
25
25
  * label. With `name === "Cloudflare"` the result is byte-identical to the example. */
26
- function adr0008Refusal(hostName) {
26
+ function localToolsRefusal(hostName) {
27
27
  return `this agent requires local_subprocess tools; the ${hostName} target supports remote MCP tools only. Set tool_locality: remote or choose a VPS/serverless target.`;
28
28
  }
29
29
  /**
@@ -32,7 +32,7 @@ function adr0008Refusal(hostName) {
32
32
  * checkHostCapabilities rule; tool_locality compares the image's DEMAND to the
33
33
  * host's CEILING by the fixed rank remote<local<in-process. The local-tools-on-edge
34
34
  * gap (local_subprocess required, OR tool_locality over ceiling) carries the
35
- * literal ADR-0008 message; every other boolean gap carries the precise per-cap
35
+ * literal refusal message; every other boolean gap carries the precise per-cap
36
36
  * message. Never silently widens: undefined/false on the host = NOT satisfied.
37
37
  */
38
38
  export function diffCapabilities(requires, host) {
@@ -52,7 +52,7 @@ export function diffCapabilities(requires, host) {
52
52
  }
53
53
  // The local-tools-on-edge dimension: local_subprocess demanded, OR the
54
54
  // requested tool_locality is more host-demanding than the host's ceiling. Both
55
- // surface as the literal ADR-0008 refusal.
55
+ // surface as the literal refusal.
56
56
  const ceiling = caps.tool_locality;
57
57
  const wantsLocalSubprocess = requires.local_subprocess === true && caps.local_subprocess !== true;
58
58
  const localityOverCeiling = localityRank(requires.tool_locality) > localityRank(ceiling);
@@ -61,7 +61,7 @@ export function diffCapabilities(requires, host) {
61
61
  capability: "local_subprocess",
62
62
  required: true,
63
63
  hostProvides: caps.local_subprocess,
64
- message: adr0008Refusal(host.name),
64
+ message: localToolsRefusal(host.name),
65
65
  });
66
66
  }
67
67
  if (localityOverCeiling) {
@@ -69,7 +69,7 @@ export function diffCapabilities(requires, host) {
69
69
  capability: "tool_locality",
70
70
  required: requires.tool_locality,
71
71
  hostProvides: ceiling,
72
- message: adr0008Refusal(host.name),
72
+ message: localToolsRefusal(host.name),
73
73
  });
74
74
  }
75
75
  return gaps;
@@ -84,7 +84,7 @@ export function assertDeployable(requires, host) {
84
84
  if (gaps.length > 0) {
85
85
  // De-duplicate identical messages before joining: an image demanding BOTH
86
86
  // local_subprocess AND an over-ceiling tool_locality is ONE root cause (local
87
- // tools on a remote-only host) and both gaps carry the same literal ADR-0008
87
+ // tools on a remote-only host) and both gaps carry the same literal
88
88
  // refusal — the user-facing message must render that sentence ONCE, not twice.
89
89
  // (diffCapabilities still returns both structured gaps for programmatic inspection.)
90
90
  const messages = [...new Set(gaps.map((g) => g.message))];
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@irisrun/host",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
- "description": "Iris host adapter surface — HostAdapter {name, capabilities, store, scheduler}, runTurnOn (run a turn ON a host's store+scheduler), and checkHostCapabilities (the tool/host-level ADR-0008 refusal). Makes 'same image, different host' explicit for the portability proof. Host-side; zero external deps.",
5
+ "description": "Iris host adapter surface — HostAdapter {name, capabilities, store, scheduler}, runTurnOn (run a turn ON a host's store+scheduler), and checkHostCapabilities (the tool/host-level refusal). Makes 'same image, different host' explicit for the portability proof. Host-side; zero external deps.",
6
6
  "exports": {
7
7
  ".": {
8
8
  "iris-src": "./src/index.ts",
@@ -11,8 +11,8 @@
11
11
  }
12
12
  },
13
13
  "dependencies": {
14
- "@irisrun/core": "^0.1.0",
15
- "@irisrun/agent": "^0.1.0"
14
+ "@irisrun/core": "^0.2.0",
15
+ "@irisrun/agent": "^0.2.0"
16
16
  },
17
17
  "license": "MIT",
18
18
  "engines": {