@openrig/cli 0.4.7 → 0.4.8
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/daemon/assets/plugins/openrig-core/skills/applying-a-permission-policy/SKILL.md +120 -0
- package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/precompact-hook.mjs +0 -0
- package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/restore-from-jsonl.mjs +0 -0
- package/daemon/assets/plugins/openrig-core/skills/delegating-work/SKILL.md +43 -0
- package/daemon/assets/plugins/openrig-core/skills/forming-an-openrig-mental-model/SKILL.md +2 -0
- package/daemon/assets/plugins/openrig-core/skills/mission-slice-sop/SKILL.md +4 -7
- package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +50 -57
- package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +16 -2
- package/daemon/dist/adapters/claude-code-adapter.d.ts +0 -9
- package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/claude-code-adapter.js +13 -46
- package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
- package/daemon/dist/adapters/claude-resume.d.ts +1 -1
- package/daemon/dist/adapters/claude-resume.d.ts.map +1 -1
- package/daemon/dist/adapters/claude-resume.js +8 -2
- package/daemon/dist/adapters/claude-resume.js.map +1 -1
- package/daemon/dist/adapters/codex-resume.d.ts +1 -1
- package/daemon/dist/adapters/codex-resume.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-resume.js +4 -2
- package/daemon/dist/adapters/codex-resume.js.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.js +10 -5
- package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
- package/daemon/dist/adapters/pi-resume.d.ts +1 -1
- package/daemon/dist/adapters/pi-resume.d.ts.map +1 -1
- package/daemon/dist/adapters/pi-resume.js +7 -2
- package/daemon/dist/adapters/pi-resume.js.map +1 -1
- package/daemon/dist/adapters/pi-runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/pi-runtime-adapter.js +4 -1
- package/daemon/dist/adapters/pi-runtime-adapter.js.map +1 -1
- package/daemon/dist/adapters/yolo-mode.d.ts +23 -0
- package/daemon/dist/adapters/yolo-mode.d.ts.map +1 -0
- package/daemon/dist/adapters/yolo-mode.js +49 -0
- package/daemon/dist/adapters/yolo-mode.js.map +1 -0
- package/daemon/dist/build-info.js +3 -3
- package/daemon/dist/db/migrations/055_node_permission_policy.d.ts +13 -0
- package/daemon/dist/db/migrations/055_node_permission_policy.d.ts.map +1 -0
- package/daemon/dist/db/migrations/055_node_permission_policy.js +17 -0
- package/daemon/dist/db/migrations/055_node_permission_policy.js.map +1 -0
- package/daemon/dist/db/migrations/056_rig_permission_policy.d.ts +13 -0
- package/daemon/dist/db/migrations/056_rig_permission_policy.d.ts.map +1 -0
- package/daemon/dist/db/migrations/056_rig_permission_policy.js +17 -0
- package/daemon/dist/db/migrations/056_rig_permission_policy.js.map +1 -0
- package/daemon/dist/db/migrations/057_node_policy_provenance.d.ts +19 -0
- package/daemon/dist/db/migrations/057_node_policy_provenance.d.ts.map +1 -0
- package/daemon/dist/db/migrations/057_node_policy_provenance.js +26 -0
- package/daemon/dist/db/migrations/057_node_policy_provenance.js.map +1 -0
- package/daemon/dist/db/migrations/058_rig_policy_provenance.d.ts +15 -0
- package/daemon/dist/db/migrations/058_rig_policy_provenance.d.ts.map +1 -0
- package/daemon/dist/db/migrations/058_rig_policy_provenance.js +22 -0
- package/daemon/dist/db/migrations/058_rig_policy_provenance.js.map +1 -0
- package/daemon/dist/domain/builtin-policy-reference.d.ts +13 -0
- package/daemon/dist/domain/builtin-policy-reference.d.ts.map +1 -0
- package/daemon/dist/domain/builtin-policy-reference.js +58 -0
- package/daemon/dist/domain/builtin-policy-reference.js.map +1 -0
- package/daemon/dist/domain/native-resume-probe.d.ts +1 -1
- package/daemon/dist/domain/native-resume-probe.d.ts.map +1 -1
- package/daemon/dist/domain/native-resume-probe.js +11 -4
- package/daemon/dist/domain/native-resume-probe.js.map +1 -1
- package/daemon/dist/domain/node-inventory.js +2 -2
- package/daemon/dist/domain/node-inventory.js.map +1 -1
- package/daemon/dist/domain/permission-policy/policy-ref.d.ts +89 -0
- package/daemon/dist/domain/permission-policy/policy-ref.d.ts.map +1 -0
- package/daemon/dist/domain/permission-policy/policy-ref.js +171 -0
- package/daemon/dist/domain/permission-policy/policy-ref.js.map +1 -0
- package/daemon/dist/domain/permission-policy/policy-spec.d.ts +34 -0
- package/daemon/dist/domain/permission-policy/policy-spec.d.ts.map +1 -0
- package/daemon/dist/domain/permission-policy/policy-spec.js +106 -0
- package/daemon/dist/domain/permission-policy/policy-spec.js.map +1 -0
- package/daemon/dist/domain/restore-orchestrator.d.ts +14 -0
- package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/restore-orchestrator.js +90 -6
- package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.js +10 -1
- package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
- package/daemon/dist/domain/rig-repository.d.ts +45 -0
- package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
- package/daemon/dist/domain/rig-repository.js +75 -1
- package/daemon/dist/domain/rig-repository.js.map +1 -1
- package/daemon/dist/domain/rigspec-codec.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-codec.js +6 -0
- package/daemon/dist/domain/rigspec-codec.js.map +1 -1
- package/daemon/dist/domain/rigspec-exporter.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-exporter.js +8 -0
- package/daemon/dist/domain/rigspec-exporter.js.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.d.ts +18 -1
- package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.js +187 -8
- package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
- package/daemon/dist/domain/rigspec-preflight.d.ts +11 -0
- package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-preflight.js +35 -1
- package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
- package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-schema.js +25 -0
- package/daemon/dist/domain/rigspec-schema.js.map +1 -1
- package/daemon/dist/domain/runtime-adapter.d.ts +5 -0
- package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/domain/runtime-adapter.js.map +1 -1
- package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
- package/daemon/dist/domain/seat-handover-service.js +7 -1
- package/daemon/dist/domain/seat-handover-service.js.map +1 -1
- package/daemon/dist/domain/successor-session-launcher.d.ts +4 -0
- package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
- package/daemon/dist/domain/successor-session-launcher.js +2 -0
- package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
- package/daemon/dist/domain/types.d.ts +17 -0
- package/daemon/dist/domain/types.d.ts.map +1 -1
- package/daemon/dist/domain/types.js.map +1 -1
- package/daemon/dist/routes/agent-images.d.ts.map +1 -1
- package/daemon/dist/routes/agent-images.js +2 -0
- package/daemon/dist/routes/agent-images.js.map +1 -1
- package/daemon/dist/routes/rigs.js +8 -0
- package/daemon/dist/routes/rigs.js.map +1 -1
- package/daemon/dist/startup.d.ts.map +1 -1
- package/daemon/dist/startup.js +17 -1
- package/daemon/dist/startup.js.map +1 -1
- package/daemon/docs/reference/rig-spec.md +19 -0
- package/daemon/policies/builtin/locked.policy.md +24 -0
- package/daemon/policies/builtin/open.policy.md +24 -0
- package/daemon/policies/builtin/standard.policy.md +25 -0
- package/daemon/policies/builtin/yolo.policy.md +20 -0
- package/daemon/policies/examples/my-cautious-dev.policy.md +40 -0
- package/daemon/specs/agents/shared/runtime/claude-settings.fragment.json +1 -20
- package/daemon/specs/agents/shared/skills/core/openrig-architect/SKILL.md +0 -2
- package/daemon/specs/agents/shared/skills/process/systematic-debugging/find-polluter.sh +0 -0
- package/daemon/specs/agents/shared/skills/process/verification-before-completion/SKILL.md +1 -0
- package/dist/build-info.js +3 -3
- package/dist/commands/setup.d.ts +14 -0
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +131 -8
- package/dist/commands/setup.js.map +1 -1
- package/package.json +1 -1
- package/daemon/specs/agents/shared/skills/pm/backlog-capture/SKILL.md +0 -43
- package/daemon/specs/agents/shared/skills/pm/context-builder/SKILL.md +0 -87
- package/daemon/specs/agents/shared/skills/pm/exec-summary/SKILL.md +0 -84
- package/daemon/specs/agents/shared/skills/pm/office-hours/SKILL.md +0 -129
- package/daemon/specs/agents/shared/skills/pm/plan-review/SKILL.md +0 -98
- package/daemon/specs/agents/shared/skills/pm/requirements-writer/SKILL.md +0 -113
- package/daemon/specs/agents/shared/skills/pm/ui-mockup/SKILL.md +0 -76
- package/daemon/specs/agents/shared/skills/pods/development-team/SKILL.md +0 -148
- package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +0 -266
- package/daemon/specs/agents/shared/skills/pods/review-team/SKILL.md +0 -213
- package/daemon/specs/agents/shared/skills/process/systematic-debugging/CREATION-LOG.md +0 -119
- package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-academic.md +0 -14
- package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-pressure-1.md +0 -58
- package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-pressure-2.md +0 -68
- package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-pressure-3.md +0 -69
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import nodePath from "node:path";
|
|
2
2
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { assembleBundle } from "./context-packs/bundle-assembler.js";
|
|
4
|
+
import { resolvePermissionPolicyAttachment, resolvePermissionPolicyRefValue, } from "./permission-policy/policy-ref.js";
|
|
4
5
|
import { deriveCanonicalSessionName, validateSessionComponents } from "./session-name.js";
|
|
5
6
|
import { LegacyRigSpecSchema as RigSpecSchema } from "./rigspec-schema.js"; // TODO: AS-T08b — migrate to pod-aware RigSpec
|
|
6
7
|
import { LegacyRigSpecCodec as RigSpecCodec } from "./rigspec-codec.js"; // TODO: AS-T08b — migrate to pod-aware RigSpec
|
|
@@ -277,6 +278,20 @@ export class PodRigInstantiator {
|
|
|
277
278
|
this.db = deps.db;
|
|
278
279
|
this.deps = deps;
|
|
279
280
|
}
|
|
281
|
+
inheritedPermissionPolicy(targetRigId) {
|
|
282
|
+
if (!targetRigId)
|
|
283
|
+
return undefined;
|
|
284
|
+
const provenance = this.deps.rigRepo.getRigPolicyProvenance(targetRigId);
|
|
285
|
+
if (!provenance?.rigRef)
|
|
286
|
+
return undefined;
|
|
287
|
+
return {
|
|
288
|
+
ref: provenance.rigRef,
|
|
289
|
+
origin: provenance.origin,
|
|
290
|
+
launchPosture: provenance.launchPosture,
|
|
291
|
+
...(provenance.resolvedTarget ? { resolvedTarget: provenance.resolvedTarget } : {}),
|
|
292
|
+
...(provenance.declaringDir ? { declaringDir: provenance.declaringDir } : {}),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
280
295
|
async materialize(rigSpecYaml, rigRoot, opts) {
|
|
281
296
|
let raw;
|
|
282
297
|
try {
|
|
@@ -303,6 +318,7 @@ export class PodRigInstantiator {
|
|
|
303
318
|
fsOps: this.deps.fsOps,
|
|
304
319
|
rigNameOverride: targetRig?.rig.name,
|
|
305
320
|
externalQualifiedIds: targetRig?.nodes.map((node) => node.logicalId),
|
|
321
|
+
inheritedPermissionPolicy: this.inheritedPermissionPolicy(opts?.targetRigId),
|
|
306
322
|
exec: this.deps.exec,
|
|
307
323
|
});
|
|
308
324
|
if (!preflight.ready) {
|
|
@@ -312,7 +328,7 @@ export class PodRigInstantiator {
|
|
|
312
328
|
// persistence CORE (createPod + create-node + edges + events, in one tx)
|
|
313
329
|
// takes the already-parsed+validated spec so `expand` and the `add_member`
|
|
314
330
|
// converge op compose it WITHOUT fabricating a synthetic rig spec.
|
|
315
|
-
return this.materializeValidatedSpec(rigSpec, rigRoot, opts);
|
|
331
|
+
return this.materializeValidatedSpec(rigSpec, rigRoot, preflight.warnings, opts);
|
|
316
332
|
}
|
|
317
333
|
/**
|
|
318
334
|
* materialize with a STRUCTURED front (OPR.0.3.3.24): the YAML-free sibling of
|
|
@@ -342,12 +358,13 @@ export class PodRigInstantiator {
|
|
|
342
358
|
cwdOverride: opts?.cwdOverride,
|
|
343
359
|
fsOps: this.deps.fsOps,
|
|
344
360
|
rigNameOverride: targetRig?.rig.name,
|
|
361
|
+
inheritedPermissionPolicy: this.inheritedPermissionPolicy(opts?.targetRigId),
|
|
345
362
|
exec: this.deps.exec,
|
|
346
363
|
});
|
|
347
364
|
if (!preflight.ready) {
|
|
348
365
|
return { ok: false, code: "preflight_failed", errors: preflight.errors, warnings: preflight.warnings };
|
|
349
366
|
}
|
|
350
|
-
return this.materializeValidatedSpec(rigSpec, rigRoot, opts);
|
|
367
|
+
return this.materializeValidatedSpec(rigSpec, rigRoot, preflight.warnings, opts);
|
|
351
368
|
}
|
|
352
369
|
/**
|
|
353
370
|
* materialize CORE (OPR.0.3.3.24): the persistence body of materialize, taking
|
|
@@ -359,7 +376,7 @@ export class PodRigInstantiator {
|
|
|
359
376
|
* `add_member` reuse the exact create path — create+launch only, no identity
|
|
360
377
|
* migration.
|
|
361
378
|
*/
|
|
362
|
-
async materializeValidatedSpec(rigSpec, rigRoot, opts) {
|
|
379
|
+
async materializeValidatedSpec(rigSpec, rigRoot, preflightWarnings, opts) {
|
|
363
380
|
const persistedEvents = [];
|
|
364
381
|
const nodeResults = [];
|
|
365
382
|
try {
|
|
@@ -374,6 +391,24 @@ export class PodRigInstantiator {
|
|
|
374
391
|
if (rigSpec.workspace) {
|
|
375
392
|
this.deps.rigRepo.setRigWorkspace(materializedRigId, rigSpec.workspace);
|
|
376
393
|
}
|
|
394
|
+
// OPR.0.4.8.3 Seam B: persist the rig-level permission_policy REF (raw, like role) —
|
|
395
|
+
// this is ONE of TWO rig-persist sites (materializeValidatedSpec + instantiate); missing
|
|
396
|
+
// either drops the rig ref on that path (map correction, independently verified).
|
|
397
|
+
// Guard-F1: the RESOLVED rig attachment persists too (declaringDir = THIS rigRoot,
|
|
398
|
+
// the original declaring RigSpec dir) — restart-complete for organic seats,
|
|
399
|
+
// add-member under a different root, and successor continuity. STRICT (load-bearing).
|
|
400
|
+
if (rigSpec.permissionPolicy) {
|
|
401
|
+
this.deps.rigRepo.setRigPermissionPolicy(materializedRigId, rigSpec.permissionPolicy);
|
|
402
|
+
const rigAttachment = resolvePermissionPolicyAttachment(rigSpec.permissionPolicy, rigRoot, {
|
|
403
|
+
readFile: (p) => this.deps.fsOps.readFile(p),
|
|
404
|
+
});
|
|
405
|
+
this.deps.rigRepo.setRigPolicyProvenance(materializedRigId, {
|
|
406
|
+
origin: rigAttachment.origin,
|
|
407
|
+
resolvedTarget: rigAttachment.resolvedTarget ?? null,
|
|
408
|
+
declaringDir: rigAttachment.origin === "custom" ? rigRoot : null,
|
|
409
|
+
launchPosture: rigAttachment.launchPosture,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
377
412
|
const currentRig = this.deps.rigRepo.getRig(materializedRigId);
|
|
378
413
|
const logicalIdToNodeId = new Map(currentRig.nodes.map((node) => [node.logicalId, node.id]));
|
|
379
414
|
const existingPodIds = new Set(currentRig.nodes
|
|
@@ -415,6 +450,26 @@ export class PodRigInstantiator {
|
|
|
415
450
|
cwdOverride: opts?.cwdOverride,
|
|
416
451
|
});
|
|
417
452
|
logicalIdToNodeId.set(qualifiedId, node.id);
|
|
453
|
+
// Seam B R2: restart-stable provenance persists AT MATERIALIZE (a
|
|
454
|
+
// materialized-but-never-launched seat must still restore its posture).
|
|
455
|
+
// R2 HIGH-1: expansion into an EXISTING rig materializes through a SYNTHETIC
|
|
456
|
+
// fragment with no rig-level ref — a ref-less member must inherit the
|
|
457
|
+
// PERSISTED target-rig attachment (original declaring dir), never lose it.
|
|
458
|
+
const materializeAttachment = this.resolveMemberPolicyAttachment(member.permissionPolicy, rigSpec.permissionPolicy, rigRoot);
|
|
459
|
+
if (materializeAttachment) {
|
|
460
|
+
this.persistNodePolicyProvenanceStrict(node.id, materializeAttachment);
|
|
461
|
+
}
|
|
462
|
+
else if (opts?.targetRigId) {
|
|
463
|
+
const rigProv = this.deps.rigRepo.getRigPolicyProvenance(materializedRigId);
|
|
464
|
+
if (rigProv) {
|
|
465
|
+
this.deps.rigRepo.setNodePolicyProvenance(node.id, {
|
|
466
|
+
origin: rigProv.origin,
|
|
467
|
+
resolvedTarget: rigProv.resolvedTarget,
|
|
468
|
+
declaringDir: rigProv.declaringDir,
|
|
469
|
+
launchPosture: rigProv.launchPosture,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
418
473
|
nodeResults.push({ logicalId: qualifiedId, status: "materialized" });
|
|
419
474
|
persistedEvents.push(event);
|
|
420
475
|
}
|
|
@@ -457,6 +512,7 @@ export class PodRigInstantiator {
|
|
|
457
512
|
specName: rigSpec.name,
|
|
458
513
|
specVersion: rigSpec.version,
|
|
459
514
|
nodes: nodeResults,
|
|
515
|
+
warnings: preflightWarnings,
|
|
460
516
|
},
|
|
461
517
|
};
|
|
462
518
|
}
|
|
@@ -632,6 +688,7 @@ export class PodRigInstantiator {
|
|
|
632
688
|
cwdOverride: opts?.cwdOverride,
|
|
633
689
|
fsOps: this.deps.fsOps,
|
|
634
690
|
rigNameOverride: rig.rig.name,
|
|
691
|
+
inheritedPermissionPolicy: this.inheritedPermissionPolicy(rigId),
|
|
635
692
|
exec: this.deps.exec,
|
|
636
693
|
});
|
|
637
694
|
if (!preflight.ready) {
|
|
@@ -692,6 +749,28 @@ export class PodRigInstantiator {
|
|
|
692
749
|
});
|
|
693
750
|
createdNodeId = node.id;
|
|
694
751
|
createdEvent = event;
|
|
752
|
+
// Seam B Guard-F1: add_member runs under the CURRENT operation's root, which may
|
|
753
|
+
// differ from the ORIGINAL declaring RigSpec dir. A member OVERRIDE resolves against
|
|
754
|
+
// this operation's root (it is declared HERE); an INHERITED rig policy must reuse the
|
|
755
|
+
// PERSISTED rig attachment (original declaring root) — never re-resolve the raw rig
|
|
756
|
+
// ref against an unrelated root. STRICT persistence (load-bearing).
|
|
757
|
+
if (member.permissionPolicy) {
|
|
758
|
+
const memberAttachment = resolvePermissionPolicyAttachment(member.permissionPolicy, rigRoot, {
|
|
759
|
+
readFile: (p) => this.deps.fsOps.readFile(p),
|
|
760
|
+
});
|
|
761
|
+
this.persistNodePolicyProvenanceStrict(node.id, memberAttachment);
|
|
762
|
+
}
|
|
763
|
+
else {
|
|
764
|
+
const rigProv = this.deps.rigRepo.getRigPolicyProvenance(rigId);
|
|
765
|
+
if (rigProv) {
|
|
766
|
+
this.deps.rigRepo.setNodePolicyProvenance(node.id, {
|
|
767
|
+
origin: rigProv.origin,
|
|
768
|
+
resolvedTarget: rigProv.resolvedTarget,
|
|
769
|
+
declaringDir: rigProv.declaringDir,
|
|
770
|
+
launchPosture: rigProv.launchPosture,
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
}
|
|
695
774
|
if (resolvedEdges.length > 0) {
|
|
696
775
|
const logicalIdToNodeId = new Map(rig.nodes.map((n) => [n.logicalId, n.id]));
|
|
697
776
|
logicalIdToNodeId.set(qualifiedId, node.id);
|
|
@@ -730,7 +809,7 @@ export class PodRigInstantiator {
|
|
|
730
809
|
sessionName: launched.sessionName,
|
|
731
810
|
},
|
|
732
811
|
edges: resolvedEdges,
|
|
733
|
-
warnings: launched.warnings,
|
|
812
|
+
warnings: [...preflight.warnings, ...(launched.warnings ?? [])],
|
|
734
813
|
},
|
|
735
814
|
};
|
|
736
815
|
}
|
|
@@ -777,6 +856,21 @@ export class PodRigInstantiator {
|
|
|
777
856
|
if (rigSpec.workspace) {
|
|
778
857
|
this.deps.rigRepo.setRigWorkspace(rigId, rigSpec.workspace);
|
|
779
858
|
}
|
|
859
|
+
// OPR.0.4.8.3 Seam B: the SECOND rig-persist site (bootstrap instantiate path) —
|
|
860
|
+
// both sites must write or the rig ref silently drops on one instantiate path.
|
|
861
|
+
// Guard-F1: resolved rig attachment persists here too (declaringDir = rigRoot).
|
|
862
|
+
if (rigSpec.permissionPolicy) {
|
|
863
|
+
this.deps.rigRepo.setRigPermissionPolicy(rigId, rigSpec.permissionPolicy);
|
|
864
|
+
const rigAttachment = resolvePermissionPolicyAttachment(rigSpec.permissionPolicy, rigRoot, {
|
|
865
|
+
readFile: (p) => this.deps.fsOps.readFile(p),
|
|
866
|
+
});
|
|
867
|
+
this.deps.rigRepo.setRigPolicyProvenance(rigId, {
|
|
868
|
+
origin: rigAttachment.origin,
|
|
869
|
+
resolvedTarget: rigAttachment.resolvedTarget ?? null,
|
|
870
|
+
declaringDir: rigAttachment.origin === "custom" ? rigRoot : null,
|
|
871
|
+
launchPosture: rigAttachment.launchPosture,
|
|
872
|
+
});
|
|
873
|
+
}
|
|
780
874
|
}
|
|
781
875
|
catch (err) {
|
|
782
876
|
return { ok: false, code: "instantiate_error", message: err.message };
|
|
@@ -785,7 +879,7 @@ export class PodRigInstantiator {
|
|
|
785
879
|
const nodeResults = [];
|
|
786
880
|
const nodeIdMap = {}; // "pod.member" -> node DB id
|
|
787
881
|
const launchedSessionNames = []; // Track for orphan cleanup on total failure
|
|
788
|
-
const podInstantiateWarnings =
|
|
882
|
+
const podInstantiateWarnings = preflight.warnings;
|
|
789
883
|
// Store per-member context for deferred launch
|
|
790
884
|
const memberContext = new Map();
|
|
791
885
|
// Phase 1: Create all pods and collect member entries
|
|
@@ -858,8 +952,7 @@ export class PodRigInstantiator {
|
|
|
858
952
|
continue;
|
|
859
953
|
}
|
|
860
954
|
// Create node
|
|
861
|
-
|
|
862
|
-
try {
|
|
955
|
+
const createUnit = this.db.transaction(() => {
|
|
863
956
|
const node = this.deps.rigRepo.addNode(rigId, qualifiedId, {
|
|
864
957
|
// OPR.0.4.6.FAC1 (VM-caught): the pod-aware bootstrap
|
|
865
958
|
// instantiate-from-YAML path (`rig up <spec>`) creates agent
|
|
@@ -874,6 +967,10 @@ export class PodRigInstantiator {
|
|
|
874
967
|
runtime: member.runtime,
|
|
875
968
|
model: member.model,
|
|
876
969
|
codexConfigProfile: member.codexConfigProfile,
|
|
970
|
+
// OPR.0.4.8.3 Seam B: bootstrap inline addNode is the FOURTH node-creation
|
|
971
|
+
// site (see the role wire note above) — same member-ref persistence as
|
|
972
|
+
// createMemberNode or `rig up <spec>` seats lose their policy ref.
|
|
973
|
+
permissionPolicy: member.permissionPolicy,
|
|
877
974
|
cwd: configResult.config.cwd,
|
|
878
975
|
restorePolicy: configResult.config.restorePolicy,
|
|
879
976
|
podId,
|
|
@@ -884,7 +981,21 @@ export class PodRigInstantiator {
|
|
|
884
981
|
resolvedSpecVersion: configResult.config.resolvedSpecVersion,
|
|
885
982
|
resolvedSpecHash: configResult.config.resolvedSpecHash,
|
|
886
983
|
});
|
|
887
|
-
|
|
984
|
+
// Guard multi-seat correction (16e853a7): node creation + required provenance
|
|
985
|
+
// are ONE ATOMIC UNIT (SQLite savepoint). A setter fault rolls the INSERT back
|
|
986
|
+
// too — under partial-success semantics the sibling may proceed, but a failed
|
|
987
|
+
// member can never survive as a half-created node whose restore posture would
|
|
988
|
+
// widen to the rig attachment. (Previously the row survived with provenance
|
|
989
|
+
// null, and resolveRestorePosture fell through to rig full_bypass.)
|
|
990
|
+
const bootstrapAttachment = this.resolveMemberPolicyAttachment(member.permissionPolicy, rigSpec.permissionPolicy, rigRoot);
|
|
991
|
+
if (bootstrapAttachment)
|
|
992
|
+
this.persistNodePolicyProvenanceStrict(node.id, bootstrapAttachment);
|
|
993
|
+
return node.id;
|
|
994
|
+
});
|
|
995
|
+
let nodeId;
|
|
996
|
+
try {
|
|
997
|
+
nodeId = createUnit();
|
|
998
|
+
// nodeIdMap only AFTER the atomic unit succeeds (Guard contract item 2).
|
|
888
999
|
nodeIdMap[qualifiedId] = nodeId;
|
|
889
1000
|
}
|
|
890
1001
|
catch (err) {
|
|
@@ -1158,6 +1269,9 @@ export class PodRigInstantiator {
|
|
|
1158
1269
|
runtime: input.member.runtime,
|
|
1159
1270
|
model: input.member.model,
|
|
1160
1271
|
codexConfigProfile: input.member.codexConfigProfile,
|
|
1272
|
+
// OPR.0.4.8.3 Seam B: the member's OWN raw ref persists on the node (like role);
|
|
1273
|
+
// rig-level lives on the rig row; precedence applies at RESOLUTION, not storage.
|
|
1274
|
+
permissionPolicy: input.member.permissionPolicy,
|
|
1161
1275
|
cwd: effectiveCwd,
|
|
1162
1276
|
restorePolicy: input.member.restorePolicy,
|
|
1163
1277
|
podId: input.podId,
|
|
@@ -1187,6 +1301,40 @@ export class PodRigInstantiator {
|
|
|
1187
1301
|
? this.launchExistingTerminalMember(input)
|
|
1188
1302
|
: this.launchExistingAgentMember(input);
|
|
1189
1303
|
}
|
|
1304
|
+
/**
|
|
1305
|
+
* OPR.0.4.8.3 Seam B — the ONE precedence + resolution point for a seat's permission
|
|
1306
|
+
* policy at launch: member ref > rig ref > absent (undefined = the env-driven floor).
|
|
1307
|
+
* Custom refs resolve relative to the rig root (the declaring RigSpec's directory in a
|
|
1308
|
+
* materialized rig). Returns undefined when no ref is attached at either level.
|
|
1309
|
+
*/
|
|
1310
|
+
resolveMemberPolicyAttachment(memberRef, rigRef, rigRoot) {
|
|
1311
|
+
const ref = resolvePermissionPolicyRefValue(memberRef, rigRef);
|
|
1312
|
+
if (!ref)
|
|
1313
|
+
return undefined;
|
|
1314
|
+
return resolvePermissionPolicyAttachment(ref, rigRoot, {
|
|
1315
|
+
readFile: (p) => this.deps.fsOps.readFile(p),
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
/** Seam B Guard-F2: the STRICT materialize/add-member persist — provenance here is
|
|
1319
|
+
* LOAD-BEARING restart state; a real write failure must fail the surrounding
|
|
1320
|
+
* transaction, never commit a node without it. (The repository setter itself still
|
|
1321
|
+
* no-ops on pre-057 legacy fixture DBs — that narrow compatibility is preserved.) */
|
|
1322
|
+
persistNodePolicyProvenanceStrict(nodeId, attachment) {
|
|
1323
|
+
this.deps.rigRepo.setNodePolicyProvenance(nodeId, {
|
|
1324
|
+
origin: attachment.origin,
|
|
1325
|
+
resolvedTarget: attachment.resolvedTarget ?? null,
|
|
1326
|
+
declaringDir: attachment.declaringDir ?? null,
|
|
1327
|
+
launchPosture: attachment.launchPosture,
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
/** Seam B: the LAUNCH-time refresh stays best-effort (idempotent re-write on an already-
|
|
1331
|
+
* materialized node; a transient failure must not block a launch). */
|
|
1332
|
+
persistNodePolicyProvenance(nodeId, attachment) {
|
|
1333
|
+
try {
|
|
1334
|
+
this.persistNodePolicyProvenanceStrict(nodeId, attachment);
|
|
1335
|
+
}
|
|
1336
|
+
catch { /* best-effort on launch refresh only */ }
|
|
1337
|
+
}
|
|
1190
1338
|
async launchExistingAgentMember(input) {
|
|
1191
1339
|
const resolveResult = input.resolveResult ?? resolveAgentRef(input.member.agentRef, input.rigRoot, this.deps.fsOps);
|
|
1192
1340
|
if (!resolveResult.ok) {
|
|
@@ -1210,6 +1358,24 @@ export class PodRigInstantiator {
|
|
|
1210
1358
|
return { status: "failed", error: configResult.errors.join("; ") };
|
|
1211
1359
|
}
|
|
1212
1360
|
this.updateNodeResolvedConfig(input.nodeId, configResult.config);
|
|
1361
|
+
// OPR.0.4.8.3 Seam B: resolve the seat's permission-policy attachment once for this
|
|
1362
|
+
// launch (member > rig precedence; declaring dir = the rig root, where the declaring
|
|
1363
|
+
// RigSpec + its relative policy files live). Also persists restart-stable provenance.
|
|
1364
|
+
// R2 HIGH-1: the LIVE binding must AGREE with persisted provenance — structured
|
|
1365
|
+
// add-member/expansion launch with a SYNTHETIC minimal spec (no rig-level ref), so
|
|
1366
|
+
// when the in-memory spec resolves nothing, the PERSISTED node provenance (written in
|
|
1367
|
+
// the creation tx) and then the PERSISTED rig attachment are the binding's truth.
|
|
1368
|
+
const policyAttachment = this.resolveMemberPolicyAttachment(input.member.permissionPolicy, input.rigSpec.permissionPolicy, input.rigRoot);
|
|
1369
|
+
if (policyAttachment)
|
|
1370
|
+
this.persistNodePolicyProvenance(input.nodeId, policyAttachment);
|
|
1371
|
+
// R2 terminal (954d97a0): TRUE ABSENCE binds the locked MINIMUM FLOOR explicitly
|
|
1372
|
+
// (README v4 "DEFAULT IF NONE ATTACHED = the minimum floor"; FINAL2) — ambient
|
|
1373
|
+
// OPENRIG_YOLO must never widen a seat with no attachment. Absence stays honest
|
|
1374
|
+
// (no fabricated attachment/provenance); only the lifecycle BINDING is explicit.
|
|
1375
|
+
const launchPosture = policyAttachment?.launchPosture
|
|
1376
|
+
?? this.deps.rigRepo.getNodePolicyProvenance(input.nodeId)?.launchPosture
|
|
1377
|
+
?? this.deps.rigRepo.getRigPolicyProvenance(input.rigId)?.launchPosture
|
|
1378
|
+
?? "floor";
|
|
1213
1379
|
const sessionNameErrors = validateSessionComponents(input.pod.id, input.member.id, input.rigSpec.name);
|
|
1214
1380
|
if (sessionNameErrors.length > 0) {
|
|
1215
1381
|
return { status: "failed", error: sessionNameErrors.join("; ") };
|
|
@@ -1256,6 +1422,9 @@ export class PodRigInstantiator {
|
|
|
1256
1422
|
cwd: configResult.config.cwd,
|
|
1257
1423
|
model: configResult.config.model,
|
|
1258
1424
|
codexConfigProfile: input.member.codexConfigProfile,
|
|
1425
|
+
// OPR.0.4.8.3 Seam B: resolved launch posture (member > rig > persisted > FLOOR)
|
|
1426
|
+
// binds per-seat explicitly; adapters thread it into the yolo-mode helpers.
|
|
1427
|
+
launchPosture,
|
|
1259
1428
|
};
|
|
1260
1429
|
// session_source dispatch: fork (native runtime fork) vs rebuild (artifact-
|
|
1261
1430
|
// injected fresh launch) vs agent_image (PL-016 Item 4: dispatch through
|
|
@@ -1418,6 +1587,13 @@ export class PodRigInstantiator {
|
|
|
1418
1587
|
}
|
|
1419
1588
|
async launchExistingTerminalMember(input) {
|
|
1420
1589
|
const effectiveCwd = resolveLaunchCwd(input.member.cwd, input.rigRoot, input.cwdOverride);
|
|
1590
|
+
const terminalPolicyAttachment = this.resolveMemberPolicyAttachment(input.member.permissionPolicy, input.rigSpec.permissionPolicy, input.rigRoot);
|
|
1591
|
+
if (terminalPolicyAttachment)
|
|
1592
|
+
this.persistNodePolicyProvenance(input.nodeId, terminalPolicyAttachment);
|
|
1593
|
+
const terminalLaunchPosture = terminalPolicyAttachment?.launchPosture
|
|
1594
|
+
?? this.deps.rigRepo.getNodePolicyProvenance(input.nodeId)?.launchPosture
|
|
1595
|
+
?? this.deps.rigRepo.getRigPolicyProvenance(input.rigId)?.launchPosture
|
|
1596
|
+
?? "floor"; // R2 terminal: absence = the locked floor, explicitly
|
|
1421
1597
|
const sessionNameErrors = validateSessionComponents(input.pod.id, input.member.id, input.rigSpec.name);
|
|
1422
1598
|
if (sessionNameErrors.length > 0) {
|
|
1423
1599
|
return { status: "failed", error: sessionNameErrors.join("; ") };
|
|
@@ -1457,6 +1633,9 @@ export class PodRigInstantiator {
|
|
|
1457
1633
|
cmuxSurface: null,
|
|
1458
1634
|
updatedAt: "",
|
|
1459
1635
|
cwd: effectiveCwd,
|
|
1636
|
+
// Seam B: a terminal seat has no harness posture flag, but the resolved/persisted
|
|
1637
|
+
// posture (floor when absent) still binds for provenance-consuming consumers.
|
|
1638
|
+
launchPosture: terminalLaunchPosture,
|
|
1460
1639
|
};
|
|
1461
1640
|
const adapter = this.deps.adapters["terminal"];
|
|
1462
1641
|
if (!adapter) {
|