@dharma-ai-labs/agent-fabric 0.2.197 → 0.2.199

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 (34) hide show
  1. package/AGENT_FABRIC_ONBOARDING.md +2 -0
  2. package/dist/bootstrapRelayOrdering.test.js +28 -2
  3. package/dist/bootstrapRelayOrdering.test.js.map +1 -1
  4. package/dist/bootstrapStartupPreflight.test.js +10 -0
  5. package/dist/bootstrapStartupPreflight.test.js.map +1 -1
  6. package/dist/codexBootstrapCompletion.test.js +13 -0
  7. package/dist/codexBootstrapCompletion.test.js.map +1 -1
  8. package/dist/codexSetupPortalIngress.test.js +2 -0
  9. package/dist/codexSetupPortalIngress.test.js.map +1 -1
  10. package/dist/codexSetupSessionHandoff.test.js +4 -2
  11. package/dist/codexSetupSessionHandoff.test.js.map +1 -1
  12. package/dist/codexSetupSourceRequalification.test.d.ts +2 -0
  13. package/dist/codexSetupSourceRequalification.test.d.ts.map +1 -0
  14. package/dist/codexSetupSourceRequalification.test.js +109 -0
  15. package/dist/codexSetupSourceRequalification.test.js.map +1 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +32 -10
  18. package/dist/index.js.map +1 -1
  19. package/dist/relayAutostart.d.ts +4 -2
  20. package/dist/relayAutostart.d.ts.map +1 -1
  21. package/dist/relayAutostart.js +20 -3
  22. package/dist/relayAutostart.js.map +1 -1
  23. package/dist/schemas/wsl-relay-host.v1.schema.json +18 -0
  24. package/dist/startupCommitScope.test.js +6 -0
  25. package/dist/startupCommitScope.test.js.map +1 -1
  26. package/dist/wslRelayHost.d.ts +30 -0
  27. package/dist/wslRelayHost.d.ts.map +1 -0
  28. package/dist/wslRelayHost.js +269 -0
  29. package/dist/wslRelayHost.js.map +1 -0
  30. package/dist/wslRelayHost.test.d.ts +2 -0
  31. package/dist/wslRelayHost.test.d.ts.map +1 -0
  32. package/dist/wslRelayHost.test.js +308 -0
  33. package/dist/wslRelayHost.test.js.map +1 -0
  34. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -104,7 +104,7 @@ import { assertCodexSetupExecutionLease } from './codexSetupAdmission.js';
104
104
  import { parseLocalCodexSetupReadiness } from '@dharma-ai-labs/agent-fabric-local-vault/setup-readiness';
105
105
  import { writeBootstrapHostJson, writeBootstrapHostText } from './bootstrapHostFiles.js';
106
106
  export { openCooperativeInboxSession } from './cooperativeInboxSession.js';
107
- const VERSION = '0.2.197';
107
+ const VERSION = '0.2.199';
108
108
  const USAGE = CLI_USAGE;
109
109
  const execFileAsync = promisify(execFile);
110
110
  const LOCAL_PROVIDER_IDS = ['codex', 'claude', 'agy', 'hermes'];
@@ -1491,6 +1491,20 @@ export async function preflightBootstrapWorkspaceIdentity(workspace, explicitKey
1491
1491
  const remote = await gitValue(workspace, ['config', '--get', 'remote.origin.url']);
1492
1492
  return sourceRepositoryFingerprint(remote, explicitKey);
1493
1493
  }
1494
+ // Requalification is itself the scope fence. Calling gitValue here would
1495
+ // re-enter that fence before dispatching either read-only metadata command.
1496
+ async function readBootstrapSourceIdentityForRequalification(workspace, signal) {
1497
+ const options = { timeout: 10_000, maxBuffer: 65_536, windowsHide: true, signal,
1498
+ env: providerProcessEnvironment(process.env) };
1499
+ signal.throwIfAborted();
1500
+ const root = await execFileAsync('git', ['-C', workspace, 'rev-parse', '--show-toplevel'], options);
1501
+ signal.throwIfAborted();
1502
+ if (!root.stdout.trim())
1503
+ throw new Error('Bootstrap workspace must be a Git repository.');
1504
+ const remote = await execFileAsync('git', ['-C', workspace, 'config', '--get', 'remote.origin.url'], options);
1505
+ signal.throwIfAborted();
1506
+ return sourceRepositoryFingerprint(remote.stdout.trim() || null);
1507
+ }
1494
1508
  export function responseTextFromEvent(value) {
1495
1509
  if (!value || typeof value !== 'object' || Array.isArray(value))
1496
1510
  return null;
@@ -2069,8 +2083,10 @@ async function startRelayDaemon(policyPath) {
2069
2083
  const supervisorState = await relaySupervisorProcessState();
2070
2084
  if (supervisorState === 'unknown')
2071
2085
  throw new Error('Relay supervisor process state is unknown.');
2072
- if (supervisorState === 'stopped') {
2073
- const startupBackend = (await relayAutostartStatus({ home: dharmaHome() })).backend;
2086
+ const startup = await step(() => relayAutostartStatus({ home: dharmaHome() }));
2087
+ const hostPending = startup.restartCoverage === 'wsl-host-logon' && startup.hostLifecycle !== 'running';
2088
+ if (supervisorState === 'stopped' || hostPending) {
2089
+ const startupBackend = startup.backend;
2074
2090
  // A setup turn cannot own a supervisor intended to outlive that turn.
2075
2091
  if (hostScope || startupBackend === 'container-entrypoint' || startupBackend === 'systemd-user') {
2076
2092
  await step(() => startRelayAutostart({ home: dharmaHome() }));
@@ -2701,7 +2717,8 @@ async function observeCodexBootstrapRuntime(prepared, vault, firstLearning, inte
2701
2717
  || resolve(startup.workspace) !== startup.workspace
2702
2718
  || startup.policy !== resolve(startup.workspace, '.dharma', 'approved-policy.json')
2703
2719
  || startup.launcher !== resolve(startup.workspace, '.dharma', 'bin', 'dharma')
2704
- || startup.backend === 'container-entrypoint' && startupState.lifecycle !== 'running') {
2720
+ || startup.backend === 'container-entrypoint' && startupState.lifecycle !== 'running'
2721
+ || startupState.restartCoverage === 'wsl-host-logon' && startupState.hostLifecycle !== 'running') {
2705
2722
  throw new Error('setup_runtime_startup_unconfirmed');
2706
2723
  }
2707
2724
  // A standard relay can retain another repository as its same-device anchor.
@@ -3163,7 +3180,8 @@ async function codexPortalSetup(flags) {
3163
3180
  && (info.mode & (privateMode ? 0o077 : 0o022)) === 0 && await realpath(path) === path;
3164
3181
  };
3165
3182
  const current = async () => {
3166
- if (controller.signal.aborted || Date.now() >= Date.parse(prepared.intent.expiresAt)
3183
+ const qualificationSignal = currentBootstrapHostScope()?.signal ?? controller.signal;
3184
+ if (qualificationSignal.aborted || Date.now() >= Date.parse(prepared.intent.expiresAt)
3167
3185
  || process.getuid?.() !== uid || process.cwd() !== currentDirectory
3168
3186
  || process.env.DHARMA_HOME !== environment.home || process.env.CODEX_HOME !== environment.provider)
3169
3187
  return false;
@@ -3172,7 +3190,7 @@ async function codexPortalSetup(flags) {
3172
3190
  return now.isFile() && !now.isSymbolicLink() && now.dev === runtime.dev && now.ino === runtime.ino
3173
3191
  && now.size === runtime.size && now.mtimeNs === runtime.mtimeNs && now.ctimeNs === runtime.ctimeNs
3174
3192
  && await privateDirectory(home, true) && await privateDirectory(providerHome, false)
3175
- && (await preflightBootstrapWorkspaceIdentity(workspace)).fingerprint === prepared.intent.repositoryFingerprint;
3193
+ && (await readBootstrapSourceIdentityForRequalification(workspace, qualificationSignal)).fingerprint === prepared.intent.repositoryFingerprint;
3176
3194
  }
3177
3195
  catch {
3178
3196
  return false;
@@ -3433,7 +3451,8 @@ async function bootstrap(flags, hostScope) {
3433
3451
  const code = error instanceof Error && error.message.startsWith('autostart_conflict:')
3434
3452
  ? 'autostart_conflict' : error instanceof Error && error.message.startsWith('relay_runtime_upgrade_required:')
3435
3453
  ? 'relay_runtime_upgrade_required' : error instanceof Error && error.message.startsWith('relay_workspace_conflict:')
3436
- ? 'relay_workspace_conflict' : 'startup_preflight_unavailable';
3454
+ ? 'relay_workspace_conflict' : error instanceof Error && error.message === 'wsl_host_startup_unavailable'
3455
+ ? 'wsl_host_startup_unavailable' : 'startup_preflight_unavailable';
3437
3456
  return { ok: false, stage: 'startup_preflight', code, grantRedeemed: false, enrollmentChanged: false,
3438
3457
  message: code === 'relay_runtime_upgrade_required'
3439
3458
  ? 'Upgrade the existing enrolled startup runtime through the supported same-device update flow before retrying; setup has not redeemed authority or changed enrollment.'
@@ -3441,7 +3460,9 @@ async function bootstrap(flags, hostScope) {
3441
3460
  ? 'This Linux user already has a startup entry owned by another installation. Use the existing enrolled installation or an eligible clean client; setup has not redeemed authority or changed enrollment.'
3442
3461
  : code === 'relay_workspace_conflict'
3443
3462
  ? 'The existing startup anchor does not match this device and its approved repository policy. Recover that enrolled repository through the supported same-device flow before retrying; setup has not redeemed authority or changed enrollment.'
3444
- : 'Startup ownership could not be verified. Resolve the supported startup prerequisite before retrying; setup has not redeemed authority or changed enrollment.' };
3463
+ : code === 'wsl_host_startup_unavailable'
3464
+ ? 'The WSL host startup owner could not be verified. Restore the supported user-logon host binding before retrying; setup has not redeemed authority or changed enrollment.'
3465
+ : 'Startup ownership could not be verified. Resolve the supported startup prerequisite before retrying; setup has not redeemed authority or changed enrollment.' };
3445
3466
  }
3446
3467
  }
3447
3468
  if (grantMode === 'prompt')
@@ -3744,11 +3765,12 @@ async function bootstrap(flags, hostScope) {
3744
3765
  const role = repositoryReceipt.repositoryRole;
3745
3766
  const roleReady = Boolean(role);
3746
3767
  const relayReady = relay.state === 'running';
3747
- const observedAutostart = autostart.backend === 'container-entrypoint'
3768
+ const observedAutostart = autostart.backend === 'container-entrypoint' || autostart.restartCoverage === 'wsl-host-logon'
3748
3769
  ? await step(() => relayAutostartStatus({ home: dharmaHome() })) : autostart;
3749
3770
  const startupReady = !['win32', 'linux', 'darwin'].includes(process.platform)
3750
3771
  || observedAutostart.state === 'enabled'
3751
- && (observedAutostart.backend !== 'container-entrypoint' || observedAutostart.lifecycle === 'running');
3772
+ && (observedAutostart.backend !== 'container-entrypoint' || observedAutostart.lifecycle === 'running')
3773
+ && (observedAutostart.restartCoverage !== 'wsl-host-logon' || observedAutostart.hostLifecycle === 'running');
3752
3774
  const complete = sharedRepositoryReady && namedSessionReady && firstLearningReady
3753
3775
  && roleReady && relayReady && startupReady;
3754
3776
  return {