@dharma-ai-labs/agent-fabric 0.2.135 → 0.2.137

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 (42) hide show
  1. package/AGENT_FABRIC_ONBOARDING.md +9 -9
  2. package/README.md +13 -2
  3. package/dist/containerDockerInit.test.d.ts +2 -0
  4. package/dist/containerDockerInit.test.d.ts.map +1 -0
  5. package/dist/containerDockerInit.test.js +200 -0
  6. package/dist/containerDockerInit.test.js.map +1 -0
  7. package/dist/containerRelayLifecycle.d.ts +9 -0
  8. package/dist/containerRelayLifecycle.d.ts.map +1 -1
  9. package/dist/containerRelayLifecycle.js +151 -32
  10. package/dist/containerRelayLifecycle.js.map +1 -1
  11. package/dist/containerRelayLifecycle.test.js +8 -1
  12. package/dist/containerRelayLifecycle.test.js.map +1 -1
  13. package/dist/containerRelayPublicCommand.test.js +3 -0
  14. package/dist/containerRelayPublicCommand.test.js.map +1 -1
  15. package/dist/containerRelaySchema.test.js +9 -0
  16. package/dist/containerRelaySchema.test.js.map +1 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +55 -6
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.test.js +6 -5
  21. package/dist/index.test.js.map +1 -1
  22. package/dist/onboardingContract.test.js +10 -8
  23. package/dist/onboardingContract.test.js.map +1 -1
  24. package/dist/privateGrantInput.d.ts +1 -1
  25. package/dist/privateGrantInput.d.ts.map +1 -1
  26. package/dist/privateGrantInput.js +10 -0
  27. package/dist/privateGrantInput.js.map +1 -1
  28. package/dist/privateGrantInput.test.js +8 -0
  29. package/dist/privateGrantInput.test.js.map +1 -1
  30. package/dist/schemas/container-relay-lifecycle.v1.schema.json +39 -0
  31. package/dist/schemas/setup-claim-challenge.schema.json +28 -0
  32. package/dist/schemas/setup-claim-credential.schema.json +20 -0
  33. package/dist/schemas/setup-claim-request.schema.json +37 -0
  34. package/dist/schemas/setup-claim-response.schema.json +38 -0
  35. package/dist/setupReference.test.d.ts +2 -0
  36. package/dist/setupReference.test.d.ts.map +1 -0
  37. package/dist/setupReference.test.js +34 -0
  38. package/dist/setupReference.test.js.map +1 -0
  39. package/dist/usage.d.ts.map +1 -1
  40. package/dist/usage.js +1 -1
  41. package/dist/usage.js.map +1 -1
  42. package/package.json +3 -3
@@ -1,13 +1,13 @@
1
1
  # Agent Fabric: repository onboarding and team operation
2
2
 
3
- This contract supports connecting a new source repository and joining an existing organization repository agent. Follow the explicit mode and repository selection in the grant-free agent instructions copied from the portal. In **join existing** mode, the organization already has a signed repository package: do not request GitHub access, locate or clone source, or invent a local checkout. The CLI creates only isolated managed state for this device. In **connect new source** mode, the selected source checkout and its explicit policy are required. Perform supported checks with your tools. The recipient must personally complete the private terminal grant entry and browser device approval; an agent must not impersonate either action. Other native action-time approvals and explicit authority decisions remain required where applicable.
3
+ The current portal setup-reference flow connects the exact selected source repository from one prompt in an actual authenticated coding-agent conversation. Follow its intended recipient, source selection, pinned release and bounded policy. The agent performs supported setup; the intended recipient approves only the matching browser device request. Never request a human terminal command, grant paste or keyring troubleshooting. Technical prerequisites must use the supported current client and protected store; unavailable prerequisites are a blocked stage, not permission to copy credentials or weaken protection. Existing join-only endpoints described below retain their separately qualified contract; the source-only setup reference does not authorize a join, source expansion or a writable peer task.
4
4
 
5
- The portal supplies grant-free instructions containing the organization, intended recipient, explicit mode, repository selection, policy revision and pinned CLI release. The short-lived grant is a separate recipient-only private field, not part of the agent prompt. Never receive, print, save, commit, place in argv or environment, send through agent tools or transport, or record that grant. The recipient runs the exact generated grant-free `--grant-prompt` command directly in their own private, unrecorded interactive terminal and enters the grant only at its non-echoing prompt. Do not use a pipe, redirect, file, agent-controlled terminal or clipboard tool as a fallback. The CLI cannot detect an external recorder or prove the human owns a TTY. After enrollment, use the enrolled identity and supported secure storage; never reuse the grant.
5
+ The portal supplies a public setup reference with the organization, intended recipient, exact repository, policy, scope digest, contract digest and pinned CLI release. The public setup reference is not a bearer credential. The agent runs the exact generated `--setup-reference` command from its legitimate native context; a plain unrelated shell or a forged harness marker is not a substitute. The native client proves possession of its protected device key and opens the same-origin recipient approval page. Organization credentials move only from the trusted HTTPS endpoint into the native protected store, using the approved device and its signed ephemeral encryption key. Never put credentials in agent output, argv, environment, files, clipboard or tool messages. The agent does not receive a private grant field. Legacy private-input options are not a fallback for this one-prompt contract.
6
6
 
7
7
  ## 1. Connect safely
8
8
 
9
- 1. Read the repository selection in the grant-free agent instructions. If it names an **existing binding ID**, the recipient uses its exact generated join command in their own private terminal as described in step 2, from the current directory, including an empty or unrelated directory. It needs no source Git access. If it supplies a **new source HTTPS remote**, the CLI uses a matching current checkout or clones only that selected remote into an isolated managed checkout, verifies its commit, tracked files and remote, and leaves the starting folder untouched. Do not scan parent directories or unrelated repositories. If neither selection was supplied, confirm that the current directory is the intended eligible source Git repository before bootstrap.
10
- 2. Verify the pinned release and public provenance before private entry. The recipient runs the portal's exact generated `--grant-prompt` bootstrap command once in their own private interactive terminal, enters the separate grant when prompted, and keeps that same process attached through browser approval and final readiness. This human terminal step is part of initial setup, not a supplemental command after approval. An unsupported or noninteractive terminal must stop safely; do not switch to `--grant`, pipes, files, environment variables or agent input. Only **new source** mode can return a pre-redemption checkout or Git-access failure with `repository_selection` and `grantRedeemed: false`. Correct only the selected repository's Git access; the recipient may retry the unchanged command once before expiry when the receipt explicitly proves non-redemption. Do not ask a join-only member to correct Git access. After redemption, approval or another error, use only the supported cause-specific grant-free recovery; never replay the grant. An expired grant requires fresh recipient instructions through the portal.
9
+ 1. Read the exact source selection in the portal prompt. The CLI uses a matching current checkout or clones only the selected hosted HTTPS remote into an isolated managed checkout, verifies its commit, tracked files and remote, and leaves the starting folder untouched. A disclosed prepared checkout may satisfy the starting prerequisite; that does not prove fresh remote authentication or cloning. Do not scan parent directories or unrelated repositories. An existing join-only binding needs no source Git access, but it must use its own separately qualified join contract rather than a source setup reference.
10
+ 2. Verify the pinned release and public provenance. Use the legitimate current coding-agent context and its intended protected homes; a selected isolated test fixture must already have genuine provider authentication and isolated state, not copied default credentials. Execute the portal's exact public setup command once through the agent's supported tools and keep the same owned process attached through recipient approval and final JSON. Noninteractive native execution is supported; it must not request private terminal input. Do not change provider detection, invent environment markers, switch to a bearer grant, or ask the user to run a supplemental command. Before approval, a typed pending result identifies the exact local fingerprint, repository and bounded expiry. Pending inspection is not credential issuance. After enrollment, use supported cause-specific grant-free recovery; never replay an expired or spent setup. If expiry occurs before enrollment, request a fresh portal prompt only after the failed process is terminal and its disposition is known.
11
11
  3. Complete the browser device approval when the CLI opens the same-origin approval page. The approving account must be the intended active organization member. A copied prompt, invitation, or administrator session cannot replace recipient approval.
12
12
  4. Read the complete JSON result. Verify `repositorySelection.workspace`. In join mode it is an isolated managed state directory, **not** a source checkout; do not edit product code there. In source mode use its verified checkout for follow-up work. Verify the organization, member, device, repository identity, provider, and enrollment state. If the command returns a pending or blocked stage, preserve the correlation data and continue only through the supported recovery path.
13
13
  Keep the original command attached through browser approval and signed repository publication, which may take up to five minutes after local setup. If the host shell yields a running session, poll that session for the final JSON; do not start a second bootstrap command.
@@ -107,7 +107,7 @@ After the recipient has approved and the device is enrolled, an `agent_fabric_on
107
107
 
108
108
  If an initial repository candidate is `shared_repository_blocked`, obtain its typed cause and wait for the applicable platform or CLI fix. On the same enrolled device, a supported grant-free resume may submit one deterministic replacement candidate under the still-active source policy; repeated resumes address that same candidate. If it remains blocked, stop and report the candidate ID, stage, and correlation ID. Never alter source hashes, raise limits, or request another device approval to force publication.
109
109
 
110
- An expired bootstrap grant requires fresh grant-free recipient instructions and a separately issued recipient-only grant through the portal; it must never be pasted into agent chat. An expired device trust anchor requires normal browser-authorized re-enrollment. Revoked policy or membership must remain revoked. Cross-tenant, cross-repository, and stale-recipient requests must fail closed.
110
+ An expired setup reference requires a fresh recipient-bound portal prompt after the prior process is terminal; no private grant paste is part of that flow. A lost final response may recover only through the same approved protected device key, exact immutable setup context and a fresh native signed request within the fixed deadline. Interrupted protected-store writes may leave partial protected state; they are not transactional rollback or readiness. Do not delete or rotate history to repair them. Use the supported same-key recovery and inspect the final result before a grant-free resume. An expired device trust anchor requires normal browser-authorized re-enrollment. Revoked policy or membership must remain revoked. Cross-tenant, cross-repository, and stale-recipient requests must fail closed.
111
111
 
112
112
  Named Linux sessions refresh their verifier from protected current trust at signed operation boundaries. Their local execution deadline can renew under current enrollment, signed workspace policy and verified remote ownership without replacing the conversation. This never extends a signing key or revives expired trust; unsupported transitions stop dispatch and require supported recovery.
113
113
 
@@ -128,9 +128,9 @@ Report `complete` only when identity, shared package, native skill, role, first
128
128
 
129
129
  ## 10. Team runbook and command reference
130
130
 
131
- **First member, new repository.** Work in the intended checkout; use only the recipient-bound prompt copied from the Dharma portal. The recipient runs its exact generated grant-free `--grant-prompt` command directly in their own private unrecorded terminal and enters the separate grant at the non-echoing prompt; wait for that same recipient's browser approval and the same process's final JSON. Agents receive only grant-free instructions. After approval, no supplementary manual setup command is part of the normal complete workflow. The CLI creates or reuses the logical repository agent and permanent control branch, inventories approved skills and content, records the first-learning disposition, registers this endpoint's role, and starts its relay. Verify the signed package, manifest, catalog, endpoint, and relay before reporting success. If no eligible local trajectory exists, report `no_eligible_history`, not a fabricated Atlas analysis.
131
+ **First member, new repository.** Paste one recipient-bound portal prompt into the actual authenticated coding agent working in the intended context. The agent runs the generated public-reference setup and waits for that recipient's matching browser approval and the same process's final JSON. No supplementary manual setup command is part of the normal complete workflow. The CLI creates or reuses the logical repository agent and permanent control branch, inventories only approved skills and content, records the first-learning disposition, registers this endpoint's role, and starts its relay. Verify the signed package, manifest, catalog, endpoint, and relay before reporting success. If no eligible local trajectory exists, report `no_eligible_history`, not a fabricated Atlas analysis.
132
132
 
133
- **Additional member, same repository.** The recipient accepts the organization invitation and signs into their own Dharma account. An eligible active member obtains a recipient-bound **Join existing** prompt from People, selects the organization's ready repository, personally runs its grant-free `--grant-prompt` command from any directory in a private unrecorded interactive terminal, enters the separate grant at the non-echoing prompt, and approves their own device. No GitHub permission or source checkout is needed to use its signed skills, catalog, lexicon and peer messaging. Confirm a distinct member, device, workspace and endpoint with the same organization, normalized repository identity, logical repository agent, signed release, manifest hash and catalog hash. A join-only endpoint cannot make source changes or publish new repository knowledge; those actions require separate source authorization. Do not share another member's key, prompt, bootstrap grant or local home.
133
+ **Additional member, same repository.** The active intended recipient obtains their own source-connected public-reference prompt for the exact already-authorized repository and uses their own authenticated coding agent, protected homes and checkout. They approve only their matching browser device. Confirm a distinct member, device, workspace and endpoint with the same organization, normalized repository identity, logical repository agent, signed release, manifest hash and catalog hash. Incoming peer questions remain read-only and independently policy-bounded; source connection does not silently authorize local coding writes or publication beyond the existing policy. **Join existing** remains a separate, presently unqualified setup-reference route: No GitHub permission or source checkout is needed for an already-qualified knowledge-only endpoint, but do not substitute it for a selected retained named source-connected Codex session. Do not share another member's key, prompt, credentials or local home.
134
134
 
135
135
  **Another repository in the same organization.** Resolve its remote independently. A standing organization policy may let eligible members initialize it without a new administrator action, but it does not merge its skills, knowledge, Atlas, or endpoint roles with the first repository. If the policy does not authorize the new source, stop and request a specific scope decision; do not copy another repository's package.
136
136
 
@@ -152,11 +152,11 @@ Report `complete` only when identity, shared package, native skill, role, first
152
152
  - Resume onboarding from the exact grant-free command in the recipient prompt; a join must retain its binding selection.
153
153
  - Stop the receiver intentionally, preserving enrollment and vault: `dharma relay stop`.
154
154
 
155
- Replace placeholders with IDs and the managed path from the CLI receipt, not guessed names. A join-only endpoint has no source checkout and must use its managed workspace path for workspace-scoped commands. Use the enrolled device's secure home and exact CLI release pinned by the portal prompt. A recipient's browser approval is required for a new device; neither private terminal grant entry nor browser device approval may be performed or impersonated by an agent.
155
+ Replace placeholders with IDs and the managed path from the CLI receipt, not guessed names. A join-only endpoint has no source checkout and must use its managed workspace path for workspace-scoped commands. Use the enrolled device's secure home and exact CLI release pinned by the portal prompt. A recipient's browser approval is required for a new device; browser device approval may not be performed or impersonated by an agent.
156
156
 
157
157
  ## Demo private-repository member
158
158
 
159
- This legacy Demo command contract does not establish `--grant-prompt` support. Follow only its separately verified caller contract; do not add bootstrap flags to Demo commands or transmit grants through an agent.
159
+ This legacy Demo command contract does not establish setup-reference support. Follow only its separately verified caller contract; do not add bootstrap flags to Demo commands or transmit grants through an agent.
160
160
 
161
161
  A Demo participant joins only the repository for which they accepted an invitation. Use the exact `demo connect` command in their private portal prompt once and wait for their browser device approval. If the prompt selects `--knowledge-only`, first create the specified persistent private workspace outside every Git checkout. Pass its absolute `--workspace` path and `--knowledge-only` to every subsequent `demo` command. This endpoint receives the owner's signed package without cloning source, obtaining a GitHub seat, scanning its workspace, or submitting a source candidate.
162
162
 
package/README.md CHANGED
@@ -37,7 +37,18 @@ command accepts no grant, policy, provider or task arguments. Inspect the
37
37
  credential-free plan with `relay container-entrypoint --dry-run` before image
38
38
  installation; it makes no local changes. Set an explicit
39
39
  private `DHARMA_HOME` before launch. An npm wrapper, shell that does not exec,
40
- `sleep` or init shim as PID1 does not qualify.
40
+ `sleep` or an arbitrary init shim as PID1 does not qualify. A narrowly verified
41
+ Docker `--init` route also supports the canonical CLI as the non-root direct
42
+ child of Docker's root-owned, non-writable `/sbin/docker-init` executable. This
43
+ route retains the existing official Node-image command
44
+ `docker-entrypoint.sh sleep infinity`; an explicitly approved public entrypoint
45
+ migration must exec the canonical Node/CLI command as that init's main child.
46
+ The CLI checks the executable inode, UID, both process start times and the
47
+ kernel's first init-child identity, retaining zombies rather than promoting
48
+ adopted processes. The controller must also retain init's session and its own
49
+ process group. The main-child and process identities are checked again before
50
+ control is admitted; a foreground or orphaned `docker exec` or a fabricated
51
+ marker cannot claim startup.
41
52
 
42
53
  The image/operator must provide its own protected Secret Service, private
43
54
  session bus and durable private home. Never mount a host bus or copy another
@@ -52,7 +63,7 @@ The entrypoint owns one relay for that container OS user. It never creates a
52
63
  second host service or changes an existing systemd user unit. Owned start/stop
53
64
  controls use atomic private receipts; disable removes the registration. It
54
65
  reaps its child on normal shutdown and retries an exited child with a bounded
55
- delay. A new container boot renews only its own PID1 lease while retaining its
66
+ delay. A new container boot renews only its own entrypoint lease while retaining its
56
67
  configuration and encrypted state. Runtime-version mismatch blocks restart;
57
68
  upgrade the reviewed image/runtime together through the normal release path.
58
69
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=containerDockerInit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"containerDockerInit.test.d.ts","sourceRoot":"","sources":["../src/containerDockerInit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,200 @@
1
+ import assert from 'node:assert/strict';
2
+ import { spawn } from 'node:child_process';
3
+ import { mkdtemp, mkdir, readFile, writeFile } from 'node:fs/promises';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import test from 'node:test';
7
+ import * as lifecycle from './containerRelayLifecycle.js';
8
+ import { enableRelayAutostart, relayAutostartStatus } from './relayAutostart.js';
9
+ const linux = { skip: process.platform !== 'linux' };
10
+ async function fixture() {
11
+ const root = await mkdtemp(join(tmpdir(), 'dharma-docker-init-'));
12
+ const home = join(root, 'device');
13
+ const workspace = join(root, 'checkout');
14
+ await mkdir(join(home, 'relay'), { recursive: true, mode: 0o700 });
15
+ await mkdir(join(workspace, '.dharma'), { recursive: true, mode: 0o700 });
16
+ const uid = process.getuid();
17
+ const init = { pid: 1, parentPid: 0, processGroupId: 1, sessionId: 1, uid, startTicks: '123', argv: ['/sbin/docker-init', '--', 'docker-entrypoint.sh', 'sleep', 'infinity'] };
18
+ const controller = { pid: 42, parentPid: 1, processGroupId: 42, sessionId: 1, uid, startTicks: '124',
19
+ argv: ['/usr/local/bin/node', '/fixture/cli/dist/bin.js', 'relay', 'container-entrypoint'] };
20
+ const marker = { schema: 'dharma.container-entrypoint/v2', home, pid: controller.pid, uid,
21
+ startTicks: controller.startTicks, initStartTicks: init.startTicks };
22
+ await writeFile(join(home, 'relay', 'container-entrypoint.json'), JSON.stringify(marker), { mode: 0o600 });
23
+ let verifiedInit = true;
24
+ let verifiedNode = true;
25
+ let mainChild = controller.pid;
26
+ const runtime = { identity: async () => init, canonicalEntrypoint: controller.argv[1], runtimeVersion: '0.2.135',
27
+ controllerIdentity: async (pid) => { assert.equal(pid, controller.pid); return controller; },
28
+ dockerInitVerified: async () => verifiedInit,
29
+ dockerInitMainChild: async () => mainChild,
30
+ controllerExecutableVerified: async () => verifiedNode,
31
+ childIdentity: async (pid) => ({ ...await lifecycle.readContainerChildIdentity(pid), parentPid: controller.pid }) };
32
+ const options = { platform: 'linux', home, uid, userHome: root, workspace,
33
+ launcher: join(workspace, '.dharma', 'bin', 'dharma'), policy: join(workspace, '.dharma', 'approved-policy.json'),
34
+ version: '0.2.135', containerRuntime: runtime,
35
+ run: async () => { throw new Error('must never use systemd for the owned init child'); } };
36
+ return { root, home, init, controller, marker, runtime, options,
37
+ untrustInit: () => { verifiedInit = false; }, untrustNode: () => { verifiedNode = false; },
38
+ setMainChild: (pid) => { mainChild = pid; } };
39
+ }
40
+ async function until(check) {
41
+ const deadline = Date.now() + 3000;
42
+ while (!await check()) {
43
+ if (Date.now() > deadline)
44
+ throw new Error('fixture did not progress');
45
+ await new Promise(r => setTimeout(r, 10));
46
+ }
47
+ }
48
+ async function receiptReady(path, matches) {
49
+ return until(async () => {
50
+ try {
51
+ return matches(JSON.parse(await readFile(path, 'utf8')));
52
+ }
53
+ catch (error) {
54
+ if (error.code === 'ENOENT')
55
+ return false;
56
+ throw error;
57
+ }
58
+ });
59
+ }
60
+ test('canonical direct child of verified Docker init can own persistent container startup', linux, async () => {
61
+ const f = await fixture();
62
+ assert.equal((await enableRelayAutostart(f.options)).backend, 'container-entrypoint');
63
+ assert.equal((await relayAutostartStatus(f.options)).state, 'enabled');
64
+ });
65
+ test('adopted canonical exec child cannot replace the Docker init main startup child', linux, async () => {
66
+ for (const kind of ['different-main-child', 'foreign-session', 'foreign-process-group', 'missing-main-child']) {
67
+ const f = await fixture();
68
+ if (kind === 'different-main-child')
69
+ f.setMainChild(7);
70
+ if (kind === 'missing-main-child')
71
+ f.setMainChild(0);
72
+ if (kind === 'foreign-session')
73
+ f.controller.sessionId = 99;
74
+ if (kind === 'foreign-process-group')
75
+ f.controller.processGroupId = 99;
76
+ await assert.rejects(enableRelayAutostart(f.options), /container_startup_unavailable/, kind);
77
+ }
78
+ });
79
+ test('Docker init main-child identity is checked again before control is admitted', linux, async () => {
80
+ const f = await fixture();
81
+ let reads = 0;
82
+ f.runtime.dockerInitMainChild = async () => ++reads === 1 ? f.controller.pid : 7;
83
+ await assert.rejects(enableRelayAutostart(f.options), /container_startup_unavailable/);
84
+ });
85
+ test('Docker init session and controller process group cannot change during attribution', linux, async () => {
86
+ for (const kind of ['init-session', 'init-group', 'controller-session', 'controller-group']) {
87
+ const f = await fixture();
88
+ let reads = 0;
89
+ if (kind.startsWith('init-'))
90
+ f.runtime.identity = async () => {
91
+ reads++;
92
+ return { ...f.init, ...(reads > 1 ? kind === 'init-session' ? { sessionId: 99 } : { processGroupId: 99 } : {}) };
93
+ };
94
+ else
95
+ f.runtime.controllerIdentity = async () => {
96
+ reads++;
97
+ return { ...f.controller, ...(reads > 1 ? kind === 'controller-session' ? { sessionId: 99 } : { processGroupId: 99 } : {}) };
98
+ };
99
+ await assert.rejects(enableRelayAutostart(f.options), /container_startup_unavailable/, kind);
100
+ }
101
+ });
102
+ test('Docker init route rejects foreign parent owner argv executable boot and controller ticks', linux, async () => {
103
+ for (const kind of ['parent', 'uid', 'argv', 'executable', 'node-executable', 'init-parent', 'init-argv', 'init-boot', 'controller-boot', 'extra-argument']) {
104
+ const f = await fixture();
105
+ if (kind === 'parent')
106
+ f.controller.parentPid = 9;
107
+ if (kind === 'uid')
108
+ f.controller.uid++;
109
+ if (kind === 'argv')
110
+ f.controller.argv[1] = '/foreign/cli/dist/bin.js';
111
+ if (kind === 'executable')
112
+ f.untrustInit();
113
+ if (kind === 'node-executable')
114
+ f.untrustNode();
115
+ if (kind === 'init-parent')
116
+ f.init.parentPid = 3;
117
+ if (kind === 'init-argv')
118
+ f.init.argv[3] = 'foreign-command';
119
+ if (kind === 'init-boot')
120
+ f.init.startTicks = '999';
121
+ if (kind === 'controller-boot')
122
+ f.controller.startTicks = '999';
123
+ if (kind === 'extra-argument')
124
+ f.controller.argv.push('--grant');
125
+ await assert.rejects(enableRelayAutostart(f.options), /container_startup_unavailable/, kind);
126
+ }
127
+ });
128
+ test('init marker cannot omit the Docker boot identity or promote an ordinary exec child to the entrypoint', linux, async () => {
129
+ const f = await fixture();
130
+ await writeFile(join(f.home, 'relay', 'container-entrypoint.json'), JSON.stringify({ ...f.marker, initStartTicks: undefined }));
131
+ await assert.rejects(enableRelayAutostart(f.options), /container_startup_unavailable/);
132
+ });
133
+ test('controller identity changes during executable verification are rejected before startup control', linux, async () => {
134
+ const f = await fixture();
135
+ let reads = 0;
136
+ f.runtime.controllerIdentity = async (pid) => {
137
+ assert.equal(pid, f.controller.pid);
138
+ reads++;
139
+ return { ...f.controller, startTicks: reads > 1 ? 'CANARY_REUSED_PROCESS' : f.controller.startTicks };
140
+ };
141
+ await assert.rejects(enableRelayAutostart(f.options), error => {
142
+ assert.match(String(error), /container_startup_unavailable/);
143
+ assert.doesNotMatch(String(error), /CANARY_REUSED_PROCESS/);
144
+ return true;
145
+ });
146
+ });
147
+ test('same Docker-init boot cannot take over another controller lease', linux, async () => {
148
+ const f = await fixture();
149
+ await writeFile(join(f.home, 'relay', 'container-entrypoint.lock'), JSON.stringify({ ...f.marker, pid: 77, startTicks: '99' }), { mode: 0o600 });
150
+ const abort = new AbortController();
151
+ await assert.rejects(lifecycle.runOwnedContainerEntrypoint({ home: f.home, uid: f.options.uid, signal: abort.signal,
152
+ containerRuntime: { ...f.runtime, currentControllerPid: f.controller.pid } }), /container_entrypoint_busy/);
153
+ });
154
+ test('different verified Docker-init boot renews only its own previous lifecycle metadata', linux, async () => {
155
+ const f = await fixture();
156
+ await writeFile(join(f.home, 'relay', 'container-entrypoint.lock'), JSON.stringify(f.marker), { mode: 0o600 });
157
+ f.init.startTicks = '223';
158
+ f.controller.startTicks = '224';
159
+ const abort = new AbortController();
160
+ const result = lifecycle.runOwnedContainerEntrypoint({ home: f.home, uid: f.options.uid, signal: abort.signal,
161
+ containerRuntime: { ...f.runtime, currentControllerPid: f.controller.pid }, pollMs: 10,
162
+ spawnRelay: () => { throw new Error('unconfigured controller cannot launch'); } });
163
+ try {
164
+ await receiptReady(join(f.home, 'relay', 'container-entrypoint.json'), marker => marker.initStartTicks === '223' && marker.startTicks === '224');
165
+ const marker = JSON.parse(await readFile(join(f.home, 'relay', 'container-entrypoint.json'), 'utf8'));
166
+ assert.equal(marker.initStartTicks, '223');
167
+ assert.equal(marker.startTicks, '224');
168
+ }
169
+ finally {
170
+ abort.abort();
171
+ }
172
+ await result;
173
+ });
174
+ test('Docker init controller fences its own supervisor and remains blocked while the consumer is locked', linux, async () => {
175
+ const f = await fixture();
176
+ await enableRelayAutostart(f.options);
177
+ const abort = new AbortController();
178
+ let ready = false;
179
+ const children = [];
180
+ const result = lifecycle.runOwnedContainerEntrypoint({ home: f.home, uid: f.options.uid, signal: abort.signal,
181
+ containerRuntime: { ...f.runtime, currentControllerPid: f.controller.pid }, pollMs: 10,
182
+ consumerStoreReady: async () => ready,
183
+ spawnRelay: () => { const child = spawn(process.execPath, ['-e', 'setInterval(() => {}, 1000)'], { stdio: 'ignore' }); children.push(child); return child; } });
184
+ try {
185
+ await receiptReady(join(f.home, 'relay', 'container-heartbeat.json'), heartbeat => heartbeat.lifecycle === 'blocked');
186
+ const heartbeat = JSON.parse(await readFile(join(f.home, 'relay', 'container-heartbeat.json'), 'utf8'));
187
+ assert.equal(heartbeat.lifecycle, 'blocked');
188
+ assert.equal(children.length, 0);
189
+ ready = true;
190
+ await until(() => children.length === 1);
191
+ await until(async () => (await relayAutostartStatus(f.options)).lifecycle === 'running');
192
+ assert.equal((await relayAutostartStatus(f.options)).lifecycle, 'running');
193
+ }
194
+ finally {
195
+ abort.abort();
196
+ }
197
+ await result;
198
+ assert.equal(children.every(child => child.exitCode !== null || child.signalCode !== null), true);
199
+ });
200
+ //# sourceMappingURL=containerDockerInit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"containerDockerInit.test.js","sourceRoot":"","sources":["../src/containerDockerInit.test.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,9 @@ export interface ContainerProcessIdentity {
4
4
  uid: number;
5
5
  startTicks: string;
6
6
  argv: string[];
7
+ parentPid?: number;
8
+ processGroupId?: number;
9
+ sessionId?: number;
7
10
  }
8
11
  export interface ContainerChildIdentity {
9
12
  pid: number;
@@ -16,6 +19,11 @@ export interface ContainerRuntime {
16
19
  childIdentity?: (pid: number) => Promise<ContainerChildIdentity>;
17
20
  canonicalEntrypoint?: string;
18
21
  runtimeVersion?: string;
22
+ controllerIdentity?: (pid: number) => Promise<ContainerProcessIdentity>;
23
+ dockerInitVerified?: () => Promise<boolean>;
24
+ dockerInitMainChild?: () => Promise<number>;
25
+ controllerExecutableVerified?: (identity: ContainerProcessIdentity) => Promise<boolean>;
26
+ currentControllerPid?: number;
19
27
  }
20
28
  export interface ContainerLifecycleOptions {
21
29
  home: string;
@@ -32,6 +40,7 @@ export interface ContainerRelayRegistration {
32
40
  taskName: null;
33
41
  }
34
42
  export declare function readContainerPid1Identity(): Promise<ContainerProcessIdentity>;
43
+ export declare function readContainerProcessIdentity(pid: number): Promise<ContainerProcessIdentity>;
35
44
  export declare function readContainerChildIdentity(pid: number): Promise<ContainerChildIdentity>;
36
45
  export declare function containerEntrypointAvailable(options: ContainerLifecycleOptions): Promise<boolean>;
37
46
  export declare function containerStartupControl(options: ContainerLifecycleOptions, registration: ContainerRelayRegistration, running: boolean): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"containerRelayLifecycle.d.ts","sourceRoot":"","sources":["../src/containerRelayLifecycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAOxE,MAAM,WAAW,wBAAwB;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE;AAC1G,MAAM,WAAW,sBAAsB;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;AAE3G,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACnD,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,yBAAyB;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CAAE;AAC9G,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,2BAA2B,CAAC;IAAC,OAAO,EAAE,sBAAsB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IACvF,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAC;CACpE;AA+CD,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAQnF;AAyCD,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAO7F;AASD,wBAAsB,4BAA4B,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,OAAO,CAAC,CASvG;AAmBD,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,yBAAyB,EAC9E,YAAY,EAAE,0BAA0B,EAAE,OAAO,EAAE,OAAO,iBAM3D;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,0BAA0B;;;;;;GA2BvH;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,0BAA0B,oBAUtH;AAED,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,0BAA0B,iBAE5H;AAYD,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,yBAAyB,8CAKjF;AA0BD,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,OAAO,CAAC,CAapE;AAoBD,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,yBAAyB,GAAG;IACrF,MAAM,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,0BAA0B,KAAK,YAAY,CAAC;IAC7F,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CACvF;;;GAoFA"}
1
+ {"version":3,"file":"containerRelayLifecycle.d.ts","sourceRoot":"","sources":["../src/containerRelayLifecycle.ts"],"names":[],"mappings":"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"}