@openrig/cli 0.4.2 → 0.4.4
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/guidance/openrig-start.md +6 -0
- package/daemon/assets/plugins/openrig-core/hooks/scripts/activity-relay.cjs +42 -2
- package/daemon/assets/plugins/openrig-core/skills/mission-slice-sop/SKILL.md +115 -0
- package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +12 -12
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts +46 -0
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.js +167 -3
- package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
- package/daemon/dist/adapters/tmux.d.ts +31 -0
- package/daemon/dist/adapters/tmux.d.ts.map +1 -1
- package/daemon/dist/adapters/tmux.js +62 -0
- package/daemon/dist/adapters/tmux.js.map +1 -1
- package/daemon/dist/build-info.d.ts +12 -0
- package/daemon/dist/build-info.d.ts.map +1 -0
- package/daemon/dist/build-info.js +11 -0
- package/daemon/dist/build-info.js.map +1 -0
- package/daemon/dist/db/migrations/045_resume_verification.d.ts +29 -0
- package/daemon/dist/db/migrations/045_resume_verification.d.ts.map +1 -0
- package/daemon/dist/db/migrations/045_resume_verification.js +34 -0
- package/daemon/dist/db/migrations/045_resume_verification.js.map +1 -0
- package/daemon/dist/db/migrations/046_seat_identity_verdicts.d.ts +41 -0
- package/daemon/dist/db/migrations/046_seat_identity_verdicts.d.ts.map +1 -0
- package/daemon/dist/db/migrations/046_seat_identity_verdicts.js +56 -0
- package/daemon/dist/db/migrations/046_seat_identity_verdicts.js.map +1 -0
- package/daemon/dist/db/migrations/047_events_node_type_index.d.ts +48 -0
- package/daemon/dist/db/migrations/047_events_node_type_index.d.ts.map +1 -0
- package/daemon/dist/db/migrations/047_events_node_type_index.js +52 -0
- package/daemon/dist/db/migrations/047_events_node_type_index.js.map +1 -0
- package/daemon/dist/db/migrations/048_queue_item_evidence_ref.d.ts +18 -0
- package/daemon/dist/db/migrations/048_queue_item_evidence_ref.d.ts.map +1 -0
- package/daemon/dist/db/migrations/048_queue_item_evidence_ref.js +22 -0
- package/daemon/dist/db/migrations/048_queue_item_evidence_ref.js.map +1 -0
- package/daemon/dist/domain/activity-endpoint.d.ts +25 -0
- package/daemon/dist/domain/activity-endpoint.d.ts.map +1 -0
- package/daemon/dist/domain/activity-endpoint.js +91 -0
- package/daemon/dist/domain/activity-endpoint.js.map +1 -0
- package/daemon/dist/domain/claim-service.d.ts +36 -0
- package/daemon/dist/domain/claim-service.d.ts.map +1 -1
- package/daemon/dist/domain/claim-service.js +90 -0
- package/daemon/dist/domain/claim-service.js.map +1 -1
- package/daemon/dist/domain/claude-compaction-enforcer.d.ts +57 -0
- package/daemon/dist/domain/claude-compaction-enforcer.d.ts.map +1 -1
- package/daemon/dist/domain/claude-compaction-enforcer.js +149 -3
- package/daemon/dist/domain/claude-compaction-enforcer.js.map +1 -1
- package/daemon/dist/domain/event-loop-monitor.d.ts +100 -0
- package/daemon/dist/domain/event-loop-monitor.d.ts.map +1 -0
- package/daemon/dist/domain/event-loop-monitor.js +127 -0
- package/daemon/dist/domain/event-loop-monitor.js.map +1 -0
- package/daemon/dist/domain/feed/attention-aggregator.d.ts +31 -0
- package/daemon/dist/domain/feed/attention-aggregator.d.ts.map +1 -0
- package/daemon/dist/domain/feed/attention-aggregator.js +119 -0
- package/daemon/dist/domain/feed/attention-aggregator.js.map +1 -0
- package/daemon/dist/domain/files/file-write-service.d.ts +11 -2
- package/daemon/dist/domain/files/file-write-service.d.ts.map +1 -1
- package/daemon/dist/domain/files/file-write-service.js +77 -0
- package/daemon/dist/domain/files/file-write-service.js.map +1 -1
- package/daemon/dist/domain/gate-predicate.d.ts +29 -0
- package/daemon/dist/domain/gate-predicate.d.ts.map +1 -0
- package/daemon/dist/domain/gate-predicate.js +73 -0
- package/daemon/dist/domain/gate-predicate.js.map +1 -0
- package/daemon/dist/domain/graph-projection.d.ts +7 -1
- package/daemon/dist/domain/graph-projection.d.ts.map +1 -1
- package/daemon/dist/domain/graph-projection.js +19 -1
- package/daemon/dist/domain/graph-projection.js.map +1 -1
- package/daemon/dist/domain/hosts/fanout-contract.d.ts +33 -0
- package/daemon/dist/domain/hosts/fanout-contract.d.ts.map +1 -0
- package/daemon/dist/domain/hosts/fanout-contract.js +23 -0
- package/daemon/dist/domain/hosts/fanout-contract.js.map +1 -0
- package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts +49 -0
- package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts.map +1 -0
- package/daemon/dist/domain/hosts/hosts-registry-reader.js +165 -0
- package/daemon/dist/domain/hosts/hosts-registry-reader.js.map +1 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.d.ts +35 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.d.ts.map +1 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.js +105 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.js.map +1 -0
- package/daemon/dist/domain/human-route-enforcer.d.ts +71 -0
- package/daemon/dist/domain/human-route-enforcer.d.ts.map +1 -0
- package/daemon/dist/domain/human-route-enforcer.js +80 -0
- package/daemon/dist/domain/human-route-enforcer.js.map +1 -0
- package/daemon/dist/domain/mission-control/audit-browse.d.ts +8 -0
- package/daemon/dist/domain/mission-control/audit-browse.d.ts.map +1 -1
- package/daemon/dist/domain/mission-control/audit-browse.js +19 -0
- package/daemon/dist/domain/mission-control/audit-browse.js.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-action-log.d.ts +1 -1
- package/daemon/dist/domain/mission-control/mission-control-action-log.d.ts.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-action-log.js +4 -0
- package/daemon/dist/domain/mission-control/mission-control-action-log.js.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-fleet-cli-capability.js +1 -1
- package/daemon/dist/domain/mission-control/mission-control-fleet-cli-capability.js.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-read-layer.js +1 -1
- package/daemon/dist/domain/mission-control/mission-control-read-layer.js.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-write-contract.d.ts +28 -0
- package/daemon/dist/domain/mission-control/mission-control-write-contract.d.ts.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-write-contract.js +125 -0
- package/daemon/dist/domain/mission-control/mission-control-write-contract.js.map +1 -1
- package/daemon/dist/domain/node-inventory.d.ts +7 -1
- package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
- package/daemon/dist/domain/node-inventory.js +84 -5
- package/daemon/dist/domain/node-inventory.js.map +1 -1
- package/daemon/dist/domain/periodic-snapshot-scheduler.d.ts +4 -0
- package/daemon/dist/domain/periodic-snapshot-scheduler.d.ts.map +1 -1
- package/daemon/dist/domain/periodic-snapshot-scheduler.js +11 -0
- package/daemon/dist/domain/periodic-snapshot-scheduler.js.map +1 -1
- package/daemon/dist/domain/policies/idle-gate-qitem.d.ts +14 -0
- package/daemon/dist/domain/policies/idle-gate-qitem.d.ts.map +1 -0
- package/daemon/dist/domain/policies/idle-gate-qitem.js +114 -0
- package/daemon/dist/domain/policies/idle-gate-qitem.js.map +1 -0
- package/daemon/dist/domain/ps-projection.d.ts +28 -1
- package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
- package/daemon/dist/domain/ps-projection.js +39 -0
- package/daemon/dist/domain/ps-projection.js.map +1 -1
- package/daemon/dist/domain/queue-repository.d.ts +25 -1
- package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
- package/daemon/dist/domain/queue-repository.js +111 -7
- package/daemon/dist/domain/queue-repository.js.map +1 -1
- package/daemon/dist/domain/restore-orchestrator.d.ts +8 -0
- package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/restore-orchestrator.js +109 -27
- package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
- package/daemon/dist/domain/restore-plan-preview.d.ts +25 -1
- package/daemon/dist/domain/restore-plan-preview.d.ts.map +1 -1
- package/daemon/dist/domain/restore-plan-preview.js +72 -4
- package/daemon/dist/domain/restore-plan-preview.js.map +1 -1
- package/daemon/dist/domain/resume-metadata-refresher.d.ts +44 -2
- package/daemon/dist/domain/resume-metadata-refresher.d.ts.map +1 -1
- package/daemon/dist/domain/resume-metadata-refresher.js +92 -6
- package/daemon/dist/domain/resume-metadata-refresher.js.map +1 -1
- package/daemon/dist/domain/resume-token-capture.d.ts +50 -0
- package/daemon/dist/domain/resume-token-capture.d.ts.map +1 -0
- package/daemon/dist/domain/resume-token-capture.js +63 -0
- package/daemon/dist/domain/resume-token-capture.js.map +1 -0
- package/daemon/dist/domain/review/brief-spine.d.ts +19 -0
- package/daemon/dist/domain/review/brief-spine.d.ts.map +1 -0
- package/daemon/dist/domain/review/brief-spine.js +86 -0
- package/daemon/dist/domain/review/brief-spine.js.map +1 -0
- package/daemon/dist/domain/review/compose.d.ts +228 -0
- package/daemon/dist/domain/review/compose.d.ts.map +1 -0
- package/daemon/dist/domain/review/compose.js +773 -0
- package/daemon/dist/domain/review/compose.js.map +1 -0
- package/daemon/dist/domain/review/freeze.d.ts +31 -0
- package/daemon/dist/domain/review/freeze.d.ts.map +1 -0
- package/daemon/dist/domain/review/freeze.js +257 -0
- package/daemon/dist/domain/review/freeze.js.map +1 -0
- package/daemon/dist/domain/review/gather.d.ts +100 -0
- package/daemon/dist/domain/review/gather.d.ts.map +1 -0
- package/daemon/dist/domain/review/gather.js +676 -0
- package/daemon/dist/domain/review/gather.js.map +1 -0
- package/daemon/dist/domain/review/types.d.ts +258 -0
- package/daemon/dist/domain/review/types.d.ts.map +1 -0
- package/daemon/dist/domain/review/types.js +35 -0
- package/daemon/dist/domain/review/types.js.map +1 -0
- package/daemon/dist/domain/rig-status-compose.d.ts +62 -0
- package/daemon/dist/domain/rig-status-compose.d.ts.map +1 -0
- package/daemon/dist/domain/rig-status-compose.js +149 -0
- package/daemon/dist/domain/rig-status-compose.js.map +1 -0
- package/daemon/dist/domain/rig-teardown.d.ts +3 -1
- package/daemon/dist/domain/rig-teardown.d.ts.map +1 -1
- package/daemon/dist/domain/rig-teardown.js +4 -19
- package/daemon/dist/domain/rig-teardown.js.map +1 -1
- package/daemon/dist/domain/route-timing-recorder.d.ts +42 -0
- package/daemon/dist/domain/route-timing-recorder.d.ts.map +1 -0
- package/daemon/dist/domain/route-timing-recorder.js +62 -0
- package/daemon/dist/domain/route-timing-recorder.js.map +1 -0
- package/daemon/dist/domain/scope/scope-approve.d.ts +64 -0
- package/daemon/dist/domain/scope/scope-approve.d.ts.map +1 -0
- package/daemon/dist/domain/scope/scope-approve.js +153 -0
- package/daemon/dist/domain/scope/scope-approve.js.map +1 -0
- package/daemon/dist/domain/scope/scope-audit.d.ts +11 -1
- package/daemon/dist/domain/scope/scope-audit.d.ts.map +1 -1
- package/daemon/dist/domain/scope/scope-audit.js +203 -2
- package/daemon/dist/domain/scope/scope-audit.js.map +1 -1
- package/daemon/dist/domain/seat-handover-service.d.ts +50 -7
- package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
- package/daemon/dist/domain/seat-handover-service.js +273 -33
- package/daemon/dist/domain/seat-handover-service.js.map +1 -1
- package/daemon/dist/domain/seat-identity-reconciler.d.ts +59 -0
- package/daemon/dist/domain/seat-identity-reconciler.d.ts.map +1 -0
- package/daemon/dist/domain/seat-identity-reconciler.js +207 -0
- package/daemon/dist/domain/seat-identity-reconciler.js.map +1 -0
- package/daemon/dist/domain/seat-identity-store.d.ts +27 -0
- package/daemon/dist/domain/seat-identity-store.d.ts.map +1 -0
- package/daemon/dist/domain/seat-identity-store.js +106 -0
- package/daemon/dist/domain/seat-identity-store.js.map +1 -0
- package/daemon/dist/domain/seat-switch-client-service.d.ts +57 -0
- package/daemon/dist/domain/seat-switch-client-service.d.ts.map +1 -0
- package/daemon/dist/domain/seat-switch-client-service.js +168 -0
- package/daemon/dist/domain/seat-switch-client-service.js.map +1 -0
- package/daemon/dist/domain/self-attach-service.d.ts +8 -0
- package/daemon/dist/domain/self-attach-service.d.ts.map +1 -1
- package/daemon/dist/domain/self-attach-service.js +20 -7
- package/daemon/dist/domain/self-attach-service.js.map +1 -1
- package/daemon/dist/domain/session-registry.d.ts +35 -4
- package/daemon/dist/domain/session-registry.d.ts.map +1 -1
- package/daemon/dist/domain/session-registry.js +89 -10
- package/daemon/dist/domain/session-registry.js.map +1 -1
- package/daemon/dist/domain/session-transport.d.ts +8 -1
- package/daemon/dist/domain/session-transport.d.ts.map +1 -1
- package/daemon/dist/domain/session-transport.js +143 -37
- package/daemon/dist/domain/session-transport.js.map +1 -1
- package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/startup-orchestrator.js +34 -2
- package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
- package/daemon/dist/domain/startup-proof.d.ts +63 -0
- package/daemon/dist/domain/startup-proof.d.ts.map +1 -0
- package/daemon/dist/domain/startup-proof.js +165 -0
- package/daemon/dist/domain/startup-proof.js.map +1 -0
- package/daemon/dist/domain/successor-session-launcher.d.ts +103 -0
- package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -0
- package/daemon/dist/domain/successor-session-launcher.js +246 -0
- package/daemon/dist/domain/successor-session-launcher.js.map +1 -0
- package/daemon/dist/domain/topology/multi-rig-launcher.d.ts +49 -0
- package/daemon/dist/domain/topology/multi-rig-launcher.d.ts.map +1 -0
- package/daemon/dist/domain/topology/multi-rig-launcher.js +132 -0
- package/daemon/dist/domain/topology/multi-rig-launcher.js.map +1 -0
- package/daemon/dist/domain/topology/remote-up-leaf.d.ts +29 -0
- package/daemon/dist/domain/topology/remote-up-leaf.d.ts.map +1 -0
- package/daemon/dist/domain/topology/remote-up-leaf.js +60 -0
- package/daemon/dist/domain/topology/remote-up-leaf.js.map +1 -0
- package/daemon/dist/domain/topology/topology-manifest.d.ts +34 -0
- package/daemon/dist/domain/topology/topology-manifest.d.ts.map +1 -0
- package/daemon/dist/domain/topology/topology-manifest.js +195 -0
- package/daemon/dist/domain/topology/topology-manifest.js.map +1 -0
- package/daemon/dist/domain/types.d.ts +86 -0
- package/daemon/dist/domain/types.d.ts.map +1 -1
- package/daemon/dist/domain/types.js +8 -0
- package/daemon/dist/domain/types.js.map +1 -1
- package/daemon/dist/domain/up-command-router.d.ts +1 -1
- package/daemon/dist/domain/up-command-router.d.ts.map +1 -1
- package/daemon/dist/domain/up-command-router.js +34 -2
- package/daemon/dist/domain/up-command-router.js.map +1 -1
- package/daemon/dist/domain/user-settings/settings-store.d.ts +17 -0
- package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
- package/daemon/dist/domain/user-settings/settings-store.js +109 -0
- package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
- package/daemon/dist/domain/watchdog-jobs-repository.d.ts +2 -2
- package/daemon/dist/domain/watchdog-jobs-repository.d.ts.map +1 -1
- package/daemon/dist/domain/watchdog-jobs-repository.js +4 -0
- package/daemon/dist/domain/watchdog-jobs-repository.js.map +1 -1
- package/daemon/dist/domain/watchdog-policy-engine.d.ts.map +1 -1
- package/daemon/dist/domain/watchdog-policy-engine.js +19 -0
- package/daemon/dist/domain/watchdog-policy-engine.js.map +1 -1
- package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
- package/daemon/dist/domain/workspace/default-workspace-scaffold.js +51 -6
- package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
- package/daemon/dist/domain/workspace/workspace-doctor.d.ts +11 -0
- package/daemon/dist/domain/workspace/workspace-doctor.d.ts.map +1 -1
- package/daemon/dist/domain/workspace/workspace-doctor.js +82 -0
- package/daemon/dist/domain/workspace/workspace-doctor.js.map +1 -1
- package/daemon/dist/index.d.ts.map +1 -1
- package/daemon/dist/index.js +18 -1
- package/daemon/dist/index.js.map +1 -1
- package/daemon/dist/routes/activity.d.ts.map +1 -1
- package/daemon/dist/routes/activity.js +26 -0
- package/daemon/dist/routes/activity.js.map +1 -1
- package/daemon/dist/routes/agent-images.d.ts.map +1 -1
- package/daemon/dist/routes/agent-images.js +139 -0
- package/daemon/dist/routes/agent-images.js.map +1 -1
- package/daemon/dist/routes/compaction.d.ts +17 -0
- package/daemon/dist/routes/compaction.d.ts.map +1 -0
- package/daemon/dist/routes/compaction.js +125 -0
- package/daemon/dist/routes/compaction.js.map +1 -0
- package/daemon/dist/routes/config.d.ts.map +1 -1
- package/daemon/dist/routes/config.js +15 -6
- package/daemon/dist/routes/config.js.map +1 -1
- package/daemon/dist/routes/files.d.ts.map +1 -1
- package/daemon/dist/routes/files.js +45 -1
- package/daemon/dist/routes/files.js.map +1 -1
- package/daemon/dist/routes/mission-control.d.ts.map +1 -1
- package/daemon/dist/routes/mission-control.js +67 -2
- package/daemon/dist/routes/mission-control.js.map +1 -1
- package/daemon/dist/routes/queue.d.ts +8 -2
- package/daemon/dist/routes/queue.d.ts.map +1 -1
- package/daemon/dist/routes/queue.js +44 -4
- package/daemon/dist/routes/queue.js.map +1 -1
- package/daemon/dist/routes/restore-check.d.ts +10 -0
- package/daemon/dist/routes/restore-check.d.ts.map +1 -1
- package/daemon/dist/routes/restore-check.js +46 -37
- package/daemon/dist/routes/restore-check.js.map +1 -1
- package/daemon/dist/routes/review.d.ts +3 -0
- package/daemon/dist/routes/review.d.ts.map +1 -0
- package/daemon/dist/routes/review.js +169 -0
- package/daemon/dist/routes/review.js.map +1 -0
- package/daemon/dist/routes/rigs.d.ts.map +1 -1
- package/daemon/dist/routes/rigs.js +70 -1
- package/daemon/dist/routes/rigs.js.map +1 -1
- package/daemon/dist/routes/scope-approve.d.ts +3 -0
- package/daemon/dist/routes/scope-approve.d.ts.map +1 -0
- package/daemon/dist/routes/scope-approve.js +55 -0
- package/daemon/dist/routes/scope-approve.js.map +1 -0
- package/daemon/dist/routes/scope-audit.d.ts.map +1 -1
- package/daemon/dist/routes/scope-audit.js +28 -1
- package/daemon/dist/routes/scope-audit.js.map +1 -1
- package/daemon/dist/routes/seat.d.ts.map +1 -1
- package/daemon/dist/routes/seat.js +53 -2
- package/daemon/dist/routes/seat.js.map +1 -1
- package/daemon/dist/routes/sessions.d.ts.map +1 -1
- package/daemon/dist/routes/sessions.js +44 -9
- package/daemon/dist/routes/sessions.js.map +1 -1
- package/daemon/dist/routes/slices.d.ts.map +1 -1
- package/daemon/dist/routes/slices.js +49 -9
- package/daemon/dist/routes/slices.js.map +1 -1
- package/daemon/dist/routes/snapshots.d.ts.map +1 -1
- package/daemon/dist/routes/snapshots.js +16 -1
- package/daemon/dist/routes/snapshots.js.map +1 -1
- package/daemon/dist/routes/terminal-ws.d.ts.map +1 -1
- package/daemon/dist/routes/terminal-ws.js +58 -21
- package/daemon/dist/routes/terminal-ws.js.map +1 -1
- package/daemon/dist/routes/transport.d.ts.map +1 -1
- package/daemon/dist/routes/transport.js +12 -5
- package/daemon/dist/routes/transport.js.map +1 -1
- package/daemon/dist/routes/up.d.ts.map +1 -1
- package/daemon/dist/routes/up.js +84 -0
- package/daemon/dist/routes/up.js.map +1 -1
- package/daemon/dist/routes/workspace.js +2 -2
- package/daemon/dist/server.d.ts +33 -0
- package/daemon/dist/server.d.ts.map +1 -1
- package/daemon/dist/server.js +41 -1
- package/daemon/dist/server.js.map +1 -1
- package/daemon/dist/startup.d.ts +1 -0
- package/daemon/dist/startup.d.ts.map +1 -1
- package/daemon/dist/startup.js +108 -20
- package/daemon/dist/startup.js.map +1 -1
- package/daemon/docs/reference/agent-startup-guide.md +1 -1
- package/daemon/docs/reference/product-factory-vps-runbook.md +132 -0
- package/daemon/docs/reference/sdlc-conventions.md +187 -0
- package/daemon/specs/agents/conveyor/builder/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/builder/guidance/role.md +1 -0
- package/daemon/specs/agents/conveyor/lead/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/lead/guidance/role.md +1 -0
- package/daemon/specs/agents/conveyor/planner/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/planner/guidance/role.md +1 -0
- package/daemon/specs/agents/conveyor/reviewer/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/reviewer/guidance/role.md +1 -0
- package/daemon/specs/agents/design/product-designer/agent.yaml +1 -1
- package/daemon/specs/agents/design/product-designer/guidance/role.md +1 -0
- package/daemon/specs/agents/development/implementer/agent.yaml +1 -1
- package/daemon/specs/agents/development/implementer/guidance/role.md +1 -0
- package/daemon/specs/agents/development/qa/agent.yaml +1 -1
- package/daemon/specs/agents/development/qa/guidance/role.md +1 -0
- package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +1 -1
- package/daemon/specs/agents/orchestration/orchestrator/guidance/role.md +1 -0
- package/daemon/specs/agents/product-management/pm/agent.yaml +1 -0
- package/daemon/specs/agents/product-management/pm/guidance/role.md +13 -0
- package/daemon/specs/agents/review/independent-reviewer/agent.yaml +1 -1
- package/daemon/specs/agents/review/independent-reviewer/guidance/role.md +1 -0
- package/daemon/specs/agents/shared/agent.yaml +2 -0
- package/daemon/specs/agents/shared/skills/core/mission-slice-sop/SKILL.md +115 -0
- package/daemon/specs/agents/shared/skills/core/openrig-operator/SKILL.md +4 -4
- package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +69 -23
- package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +3 -3
- package/daemon/specs/rigs/focused/pm-team/CULTURE.md +4 -0
- package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +1 -1
- package/daemon/specs/rigs/launch/kernel/agents/operator/agent/startup/context.md +1 -1
- package/daemon/specs/rigs/preview/product-team/CULTURE.md +4 -0
- package/dist/build-info.d.ts +8 -0
- package/dist/build-info.d.ts.map +1 -0
- package/dist/build-info.js +11 -0
- package/dist/build-info.js.map +1 -0
- package/dist/commands/compact.d.ts +15 -0
- package/dist/commands/compact.d.ts.map +1 -0
- package/dist/commands/compact.js +62 -0
- package/dist/commands/compact.js.map +1 -0
- package/dist/commands/config-init-workspace.d.ts.map +1 -1
- package/dist/commands/config-init-workspace.js +20 -4
- package/dist/commands/config-init-workspace.js.map +1 -1
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +18 -2
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/expand.js +1 -1
- package/dist/commands/expand.js.map +1 -1
- package/dist/commands/file.d.ts +7 -0
- package/dist/commands/file.d.ts.map +1 -0
- package/dist/commands/file.js +77 -0
- package/dist/commands/file.js.map +1 -0
- package/dist/commands/fork.d.ts +4 -0
- package/dist/commands/fork.d.ts.map +1 -0
- package/dist/commands/fork.js +101 -0
- package/dist/commands/fork.js.map +1 -0
- package/dist/commands/host.d.ts +34 -0
- package/dist/commands/host.d.ts.map +1 -0
- package/dist/commands/host.js +448 -0
- package/dist/commands/host.js.map +1 -0
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +34 -4
- package/dist/commands/launch.js.map +1 -1
- package/dist/commands/proof.d.ts +54 -0
- package/dist/commands/proof.d.ts.map +1 -0
- package/dist/commands/proof.js +311 -0
- package/dist/commands/proof.js.map +1 -0
- package/dist/commands/ps.d.ts +41 -7
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +357 -135
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/queue.d.ts +6 -0
- package/dist/commands/queue.d.ts.map +1 -1
- package/dist/commands/queue.js +154 -4
- package/dist/commands/queue.js.map +1 -1
- package/dist/commands/reconcile-session.d.ts.map +1 -1
- package/dist/commands/reconcile-session.js +2 -2
- package/dist/commands/reconcile-session.js.map +1 -1
- package/dist/commands/restore-check.d.ts.map +1 -1
- package/dist/commands/restore-check.js +93 -0
- package/dist/commands/restore-check.js.map +1 -1
- package/dist/commands/scope.d.ts.map +1 -1
- package/dist/commands/scope.js +191 -4
- package/dist/commands/scope.js.map +1 -1
- package/dist/commands/seat.d.ts +17 -0
- package/dist/commands/seat.d.ts.map +1 -1
- package/dist/commands/seat.js +145 -32
- package/dist/commands/seat.js.map +1 -1
- package/dist/commands/send.d.ts.map +1 -1
- package/dist/commands/send.js +161 -11
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/start.d.ts +5 -0
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/startup-proof.d.ts +24 -0
- package/dist/commands/startup-proof.d.ts.map +1 -0
- package/dist/commands/startup-proof.js +100 -0
- package/dist/commands/startup-proof.js.map +1 -0
- package/dist/commands/unclaim.js +2 -2
- package/dist/commands/unclaim.js.map +1 -1
- package/dist/commands/up.d.ts +2 -0
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +79 -2
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/watchdog.js +2 -2
- package/dist/commands/watchdog.js.map +1 -1
- package/dist/commands/workspace.js +6 -6
- package/dist/commands/workspace.js.map +1 -1
- package/dist/config-store.d.ts +4 -0
- package/dist/config-store.d.ts.map +1 -1
- package/dist/config-store.js +68 -0
- package/dist/config-store.js.map +1 -1
- package/dist/cross-host-executor.d.ts +1 -0
- package/dist/cross-host-executor.d.ts.map +1 -1
- package/dist/cross-host-executor.js +4 -1
- package/dist/cross-host-executor.js.map +1 -1
- package/dist/daemon-lifecycle.d.ts +23 -0
- package/dist/daemon-lifecycle.d.ts.map +1 -1
- package/dist/daemon-lifecycle.js +54 -6
- package/dist/daemon-lifecycle.js.map +1 -1
- package/dist/host-registry.d.ts +9 -0
- package/dist/host-registry.d.ts.map +1 -1
- package/dist/host-registry.js +32 -2
- package/dist/host-registry.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/codex-auth.d.ts +24 -0
- package/dist/lib/codex-auth.d.ts.map +1 -1
- package/dist/lib/codex-auth.js +89 -17
- package/dist/lib/codex-auth.js.map +1 -1
- package/dist/lib/file-transfer.d.ts +89 -0
- package/dist/lib/file-transfer.d.ts.map +1 -0
- package/dist/lib/file-transfer.js +300 -0
- package/dist/lib/file-transfer.js.map +1 -0
- package/dist/lib/hosts/fanout-contract.d.ts +33 -0
- package/dist/lib/hosts/fanout-contract.d.ts.map +1 -0
- package/dist/lib/hosts/fanout-contract.js +23 -0
- package/dist/lib/hosts/fanout-contract.js.map +1 -0
- package/dist/lib/scope/scope-audit.d.ts +11 -1
- package/dist/lib/scope/scope-audit.d.ts.map +1 -1
- package/dist/lib/scope/scope-audit.js +203 -2
- package/dist/lib/scope/scope-audit.js.map +1 -1
- package/dist/lib/scope/templates.d.ts +1 -0
- package/dist/lib/scope/templates.d.ts.map +1 -1
- package/dist/lib/scope/templates.js +9 -0
- package/dist/lib/scope/templates.js.map +1 -1
- package/dist/lib/scope-templates/backlog-deprecation.md +16 -0
- package/dist/lib/scope-templates/backlog-tech-debt.md +16 -0
- package/dist/lib/scope-templates/bug-fix.md +16 -0
- package/dist/lib/scope-templates/implementation-prd.md +33 -0
- package/dist/lib/scope-templates/mission-placeholder.md +41 -0
- package/dist/lib/scope-templates/mission-progress.md +2 -0
- package/dist/lib/scope-templates/mission-release.md +41 -0
- package/dist/lib/scope-templates/placeholder.md +12 -4
- package/dist/lib/scope-templates/proof.md +6 -0
- package/dist/lib/scope-templates/release-feature.md +14 -6
- package/dist/lib/scope-templates/research.md +16 -0
- package/dist/lib/scope-templates/slice-progress.md +2 -0
- package/dist/openrig-compat.d.ts +19 -0
- package/dist/openrig-compat.d.ts.map +1 -1
- package/dist/openrig-compat.js +31 -1
- package/dist/openrig-compat.js.map +1 -1
- package/dist/version.d.ts +5 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +11 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/ui/dist/assets/index-D69ZhNIr.js +598 -0
- package/ui/dist/assets/index-DJYun-8d.css +32 -0
- package/ui/dist/index.html +23 -2
- package/ui/dist/assets/index-CnqRX7A3.css +0 -32
- package/ui/dist/assets/index-CtL9jXFt.js +0 -582
|
@@ -17,6 +17,12 @@ That skill covers the broader surface, including chatroom, discovery, adopt/bind
|
|
|
17
17
|
Your per-session startup guidance may also name additional packaged skills for your role and pod.
|
|
18
18
|
Load those too. This shared overlay is only the common bootstrap floor, not the full operating manual for your seat.
|
|
19
19
|
|
|
20
|
+
## Working missions and slices (the SDLC)
|
|
21
|
+
|
|
22
|
+
If your seat works missions or slices, load the packaged `mission-slice-sop` skill BEFORE authoring or building — it teaches the flow the Living Notes UI projects: intent → mini-requirements + proof contract (→ mockups for UI slices) → plan-lock (`rig scope slice approve --scope spec`) → build the locked set → QA visual compare → `rig proof add … --media` drops (the C1 drop verb — never hand-place proof files) → proof-lock (`--scope delivery`).
|
|
23
|
+
|
|
24
|
+
The conventions themselves (section names, proof-contract format, the two locks, C1 proof headers) live in ONE shipped document: `docs/reference/sdlc-conventions.md` (in the CLI package). `rig scope slice create` scaffolds the convention sections for every template kind; `rig scope audit` is the advisory backstop — it records and advises, it never blocks your work.
|
|
25
|
+
|
|
20
26
|
## Identity
|
|
21
27
|
|
|
22
28
|
Run this first after launch or compaction to recover your identity:
|
|
@@ -75,9 +75,48 @@ function buildOpenRigPayload(providerPayload, env = process.env, now = () => new
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
// OPR.0.4.3.28 B1+B3 — resolve the ingest base URL + token without depending on
|
|
79
|
+
// the operator seeding OPENRIG_URL/OPENRIG_ACTIVITY_HOOK_TOKEN into the shell:
|
|
80
|
+
// 1. env OPENRIG_URL / token (unchanged fast path).
|
|
81
|
+
// 2. B1: synthesize the base URL from OPENRIG_HOST + OPENRIG_PORT (both present
|
|
82
|
+
// in a launched seat's env) when the URL is absent.
|
|
83
|
+
// 3. B3: file-discovery — read {baseUrl, token} from
|
|
84
|
+
// OPENRIG_HOME/activity-endpoint.json (default ~/.openrig) for reconcile /
|
|
85
|
+
// restored seats whose frozen process env lacks the activity vars. The
|
|
86
|
+
// daemon writes this file at startup. Identity (session/node/runtime) still
|
|
87
|
+
// comes from env, which previously-launched-then-reconciled seats inherit
|
|
88
|
+
// from the tmux session env.
|
|
89
|
+
function resolveEndpoint(env = process.env) {
|
|
90
|
+
let baseUrl = firstString(env.OPENRIG_URL, env.RIGGED_URL);
|
|
91
|
+
let token = firstString(env.OPENRIG_ACTIVITY_HOOK_TOKEN, env.RIGGED_ACTIVITY_HOOK_TOKEN);
|
|
92
|
+
|
|
93
|
+
if (!baseUrl) {
|
|
94
|
+
const port = firstString(env.OPENRIG_PORT, env.RIGGED_PORT);
|
|
95
|
+
if (port) {
|
|
96
|
+
const host = firstString(env.OPENRIG_HOST, env.RIGGED_HOST) || "127.0.0.1";
|
|
97
|
+
baseUrl = `http://${host}:${port}`;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!baseUrl || !token) {
|
|
102
|
+
try {
|
|
103
|
+
const fs = require("node:fs");
|
|
104
|
+
const path = require("node:path");
|
|
105
|
+
const os = require("node:os");
|
|
106
|
+
const home = firstString(env.OPENRIG_HOME, env.RIGGED_HOME) || path.join(os.homedir(), ".openrig");
|
|
107
|
+
const parsed = JSON.parse(fs.readFileSync(path.join(home, "activity-endpoint.json"), "utf8"));
|
|
108
|
+
if (!baseUrl && typeof parsed.baseUrl === "string" && parsed.baseUrl.length > 0) baseUrl = parsed.baseUrl;
|
|
109
|
+
if (!token && typeof parsed.token === "string" && parsed.token.length > 0) token = parsed.token;
|
|
110
|
+
} catch {
|
|
111
|
+
// absent/malformed — the caller no-ops safely below.
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return { baseUrl, token };
|
|
116
|
+
}
|
|
117
|
+
|
|
78
118
|
async function postHookPayload(payload, env = process.env) {
|
|
79
|
-
const baseUrl =
|
|
80
|
-
const token = firstString(env.OPENRIG_ACTIVITY_HOOK_TOKEN, env.RIGGED_ACTIVITY_HOOK_TOKEN);
|
|
119
|
+
const { baseUrl, token } = resolveEndpoint(env);
|
|
81
120
|
if (!baseUrl || !token || !payload || typeof fetch !== "function") return;
|
|
82
121
|
|
|
83
122
|
const controller = new AbortController();
|
|
@@ -147,4 +186,5 @@ module.exports = {
|
|
|
147
186
|
buildSessionIdentityPayload,
|
|
148
187
|
parseJson,
|
|
149
188
|
postHookPayload,
|
|
189
|
+
resolveEndpoint,
|
|
150
190
|
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mission-slice-sop
|
|
3
|
+
description: Use when working a mission or slice — the full SDLC flow (intent → mini-requirements + proof contract → mockups → plan-lock → build → QA visual compare → `rig proof` drops → proof-lock) plus how to track, prove, hand off, and carry state across agents and compaction via the canonical files (PROGRESS.md / PROOF.md / MISSION_NOTES.md / MISSION_BRIEF.md / README.md / IMPLEMENTATION-PRD.md). Covers the convention sections the Living Notes UI projects, the two locks, the three role contracts, per-file WHO/WHEN/HOW rules, the four-legs lifecycle, hot-potato queue handoffs, the moment-of-truth checklist, the deterministic `rig scope audit` backstop, and the ghost-text capture gotcha.
|
|
4
|
+
metadata:
|
|
5
|
+
openrig:
|
|
6
|
+
stage: shipped
|
|
7
|
+
last_verified: "2026-07-06"
|
|
8
|
+
distribution_scope: product-bound
|
|
9
|
+
source_evidence: |
|
|
10
|
+
Authored + embedded in release-0.4.3 slice 32 (mission-slice-sop);
|
|
11
|
+
moved into the canonical product skill source and updated in
|
|
12
|
+
release-0.4.4 slice 23 (operationalize the SDLC control plane) to
|
|
13
|
+
teach the full SDLC flow the Living Notes UI projects: the convention
|
|
14
|
+
sections, the proof-contract pairing, the two staged-approval locks,
|
|
15
|
+
C1 proof drops, and the three role contracts. Conventions SSOT:
|
|
16
|
+
docs/reference/sdlc-conventions.md (shipped with the CLI package).
|
|
17
|
+
The deterministic backstop is the `rig scope audit` classifier.
|
|
18
|
+
sibling_skills:
|
|
19
|
+
- queue-handoff
|
|
20
|
+
- seat-continuity-and-handover
|
|
21
|
+
- claude-compaction-restore
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Mission/Slice SOP — how you work a mission & slice
|
|
25
|
+
|
|
26
|
+
Use this skill to actually **do** mission/slice work the way OpenRig expects: author the convention sections, track on the canonical files, prove on them, hand off through them, and survive compaction on them. **Do the work described here; do not merely explain the protocol.** The deterministic backstop is `rig scope audit` — the audit classifier is the source of truth for adherence. The conventions themselves live in ONE place: **`docs/reference/sdlc-conventions.md`** (shipped with the CLI package) — this skill teaches the flow; the SSOT defines the formats.
|
|
27
|
+
|
|
28
|
+
## The SDLC flow (intent → proof)
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
intent → mini-requirements + proof contract → (UI slices: mockups)
|
|
32
|
+
→ plan-lock (rig scope slice approve --scope spec)
|
|
33
|
+
→ build the LOCKED set
|
|
34
|
+
→ QA: mockup ↔ delivered VISUAL compare
|
|
35
|
+
→ proof drops (rig proof add <slice> …)
|
|
36
|
+
→ proof-lock (rig scope slice approve --scope delivery)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
1. **Record intent** verbatim in the slice's `## Intent` section (`rig scope slice create` scaffolds it — every template kind).
|
|
40
|
+
2. **Author the mini-requirements + proof contract**: `## Mini-requirements` is the concise one-glance tier (approval starts there); `## Proof contract` is a checkbox list of promised deliverables, each written as an observable outcome. UI deliverables name their planned mockup. The IMPLEMENTATION-PRD opens with the mini-requirements; everything between intent and proof is **elastic** — for a small slice the mini-requirements may BE the whole PRD.
|
|
41
|
+
3. **Plan-lock**: `rig scope slice approve <slice> --scope spec` — "the PRD matches the intent; THIS artifact set is what gets built." One daemon-side write: frontmatter stamp + append-only audit row.
|
|
42
|
+
4. **Build the locked set** — look at the mockups, not just the spec text.
|
|
43
|
+
5. **QA visual compare**: for each deliverable, load the planned mockup, produce the real artifact in a test/demo environment, visually compare, and record the verdict.
|
|
44
|
+
6. **Drop proof**: `rig proof add <slice> --artifact-type qa --verdict PASS --candidate-sha <tip> --money-evidence "…" --evidences "1,3" --media "walk.webm,panel.png" --self-check "…"` — the C1 header's closed sets validate at drop time; `--evidences` joins the drop to its proof-contract items and `--media` names the curated proof/-relative media the drop stands behind (that pairing + media set is what the UI's DELIVERED section renders).
|
|
45
|
+
7. **Proof-lock**: `rig scope slice approve <slice> --scope delivery` — the terminal sign-off. Approval is freeze/sign-off, **never** proven-green: proven-green requires the recorded C1 verdicts.
|
|
46
|
+
|
|
47
|
+
## The three role contracts
|
|
48
|
+
|
|
49
|
+
- **Planning agent:** authors intent + mini-requirements + the proof contract; produces mockups for UI deliverables and attaches them to the locked set (a UI slice with no mockup is an incomplete plan; non-UI slices have none — not a gate); locks the plan.
|
|
50
|
+
- **Build agent:** builds against the LOCKED set only; looks at the mockups.
|
|
51
|
+
- **QA agent (owns the compare):** visually compares planned vs delivered per deliverable, records verdict + note via proof drops, and **curates** the canonical proof set (bounded, mapped to deliverables; the fix-loop pile stays in `proof/`, one drill-in down). On mismatch: fix-and-re-review or kick back with the reason — never escalate a raw mismatch to the human.
|
|
52
|
+
|
|
53
|
+
## The canonical files (the operating surface)
|
|
54
|
+
|
|
55
|
+
> The canonical files below are the **operating surface of the work** — you track on them, prove on them, hand off through them, and survive compaction on them. They are NOT side-artifacts to "maintain"; keeping them current *is* the work.
|
|
56
|
+
|
|
57
|
+
- **README.md** (mission + slice) — the overview, OPENING with the convention sections (`## Intent` / `## Mini-requirements` / `## Proof contract`). The **mission README carries this SOP at its bottom.**
|
|
58
|
+
- **IMPLEMENTATION-PRD.md** — the full PRD; opens with the mini-requirements; the `## Proof contract` here is what the UI's DELIVERED pairing joins proof against.
|
|
59
|
+
- **PROGRESS.md** — the live delivery state. One line per outcome; links down for detail.
|
|
60
|
+
- **MISSION_NOTES.md** — the accruing handoff + tribal-knowledge doc. Blank-slate onboarding + **compaction-restore** read it. `§1` top-of-mind + per-seat `§A–§X`.
|
|
61
|
+
- **MISSION_BRIEF.md** — the steering doc (the UI "Steering" tab). The 7-section schema.
|
|
62
|
+
- **PROOF.md** (+ `proof/`) — acceptance evidence. **A slice is not done until every proof-contract item has evidence.**
|
|
63
|
+
|
|
64
|
+
## Per-file rules — WHO / WHEN / HOW
|
|
65
|
+
|
|
66
|
+
### PROGRESS.md
|
|
67
|
+
- **WHO:** the orchestrator owns `§1` (current state); every agent logs its own outcomes.
|
|
68
|
+
- **WHEN:** after every slice-done **AND every commit**; on any material state change.
|
|
69
|
+
- **HOW:** one line per outcome (checkbox), link down for detail (workstream-continuity format); keep frontmatter `stage`/`verified` honest.
|
|
70
|
+
|
|
71
|
+
### PROOF.md + proof/
|
|
72
|
+
- **WHO:** the impl/QA pair that worked the slice.
|
|
73
|
+
- **WHEN:** a slice is **NOT "done"** until every proof-contract item has evidence.
|
|
74
|
+
- **HOW:** proof maps **1:1 to the proof contract's deliverables** — put media under `proof/`, then ATTACH it with `rig proof add <slice> … --evidences <item> --media <files>` (the drop writes the C1 header the DELIVERED pairing joins on) + a line in PROOF.md stating what it proves. **Hand-placing files in `proof/` without a drop is the anti-pattern** — the deliverable stays unpaired and `unverified`. No proof → not done.
|
|
75
|
+
|
|
76
|
+
### MISSION_NOTES.md
|
|
77
|
+
- **WHO:** any agent updates `§1` (top-of-mind); each seat owns + appends to its own `§A–§X` section.
|
|
78
|
+
- **WHEN:** on any material change; a compacting agent **files its state here BEFORE compaction and reads it on restore.**
|
|
79
|
+
- **HOW:** accruing tribal knowledge — `§1` ≤ 5–15 lines (gates, open decisions, surprises); per-seat continuation entries (latest = truth; other seats read-only). Pointer-first; don't duplicate.
|
|
80
|
+
|
|
81
|
+
### MISSION_BRIEF.md
|
|
82
|
+
- **WHO:** product/design (steering owner).
|
|
83
|
+
- **WHEN:** when steering changes.
|
|
84
|
+
- **HOW:** the 7-section steering schema (the UI "Steering" tab reads it).
|
|
85
|
+
|
|
86
|
+
### README.md
|
|
87
|
+
- **WHO:** the author at creation; refreshed on rescope.
|
|
88
|
+
- **WHEN:** at mission/slice creation + when scope/theme changes.
|
|
89
|
+
- **HOW:** overview + honest frontmatter (`id`/`stage`/`verified`) + the convention sections up top; the mission README carries this SOP at its bottom.
|
|
90
|
+
|
|
91
|
+
## The lifecycle (4 legs)
|
|
92
|
+
|
|
93
|
+
**SCAFFOLD** (`rig scope` creates the files from templates — every slice kind emits the convention sections + `proof/` + the IMPLEMENTATION-PRD skeleton) → **POPULATE** (agents fill them as work happens, per the rules above) → **PROJECT** (the Living Notes UI reads them into INTENT → PLAN → DELIVERED) → **VERIFY** (`rig scope audit` checks adherence). "Loose freeform write + deterministic verify."
|
|
94
|
+
|
|
95
|
+
## Hot-potato (handoffs)
|
|
96
|
+
|
|
97
|
+
End every turn by passing the ball — a `rig queue` handoff to the next agent (close the qitem with a `closure_reason`). The **durable ball-pass is the queue close, not a chat message.** Never go idle without a handoff.
|
|
98
|
+
|
|
99
|
+
## Verify (deterministic backstop)
|
|
100
|
+
|
|
101
|
+
Run `rig scope audit` at slice-close. It flags: committed-without-touching-PROGRESS; slice-marked-done-without-PROOF; active-mission-without-MISSION_NOTES; MISSION_BRIEF off-schema; proof artifacts violating the C1 header; missing IMPLEMENTATION-PRD on a building slice; missing convention sections (`## Intent`, a well-formed `## Proof contract`, the UI-slice mockup ref). Every convention check is **advisory / fail-open** — it records and advises, never blocks a write. **Fix the flag, don't suppress it.**
|
|
102
|
+
|
|
103
|
+
## Reading terminal captures — KNOWN GOTCHA: ghost-text autocomplete is NOT real
|
|
104
|
+
|
|
105
|
+
When you `rig capture` a pane, **greyed / ghost autocomplete suggestions are NOT real content** — they are autocomplete *previews* (shell autosuggestion, the input-box ghost-text completion), not typed, staged, or committed input. **This is known, expected, and has been faking agents out a lot** — reading a ghost suggestion in a peer's input box as "staged text they're about to send," or as a real prompt, and then reasoning/acting on a string that was never actually there.
|
|
106
|
+
|
|
107
|
+
**Rule:** ignore ghost/autosuggest text entirely. Only *committed/rendered* pane output is real. If a `❯` input line shows text, treat it as an autocomplete artifact unless you have independent evidence it was actually entered. Do not build decisions (or worry about "colliding with staged text") on ghost text. When it matters, verify at source (git, the queue, the actual event) — never off a capture's ghost line.
|
|
108
|
+
|
|
109
|
+
## Moment-of-truth checklist
|
|
110
|
+
|
|
111
|
+
- **Starting a slice?** → intent recorded verbatim? mini-requirements + proof contract authored? mockups attached (UI slices)? plan locked (`--scope spec`)?
|
|
112
|
+
- **Finishing a slice?** → every proof-contract item has curated evidence via `rig proof add … --evidences --media` (C1 drops — never only hand-placed files)? PROGRESS updated? MISSION_NOTES `§1` refreshed? proof locked (`--scope delivery`)? Handed off via queue?
|
|
113
|
+
- **Committing?** → PROGRESS updated?
|
|
114
|
+
- **Compacting?** → filed your state in MISSION_NOTES?
|
|
115
|
+
- **Starting on a mission?** → read the mission README (incl. this SOP) + MISSION_NOTES + `docs/reference/sdlc-conventions.md`?
|
|
@@ -61,7 +61,7 @@ Default posture on this host now:
|
|
|
61
61
|
|
|
62
62
|
Most work in OpenRig reduces to this loop:
|
|
63
63
|
- recover identity: `rig whoami --json`
|
|
64
|
-
- inspect inventory: `rig ps --nodes --json`
|
|
64
|
+
- inspect inventory: `rig ps` (fleet map) / `rig ps --nodes -A --json` (fleet nodes)
|
|
65
65
|
- read context: `rig transcript ...`, `rig ask ...`, `rig chatroom history ...`
|
|
66
66
|
- act: `rig send`, `rig capture`, `rig broadcast`, lifecycle commands
|
|
67
67
|
|
|
@@ -90,13 +90,13 @@ If the daemon is unreachable but identity can still be inferred, `--json` may re
|
|
|
90
90
|
## Inventory and Monitoring
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
|
-
rig ps
|
|
94
|
-
rig ps --json
|
|
95
|
-
rig ps --nodes
|
|
96
|
-
rig ps --nodes --json
|
|
93
|
+
rig ps # ALL active rigs, one compact row each (v0.4.4 default)
|
|
94
|
+
rig ps --json # bare array, all non-archived rigs
|
|
95
|
+
rig ps --nodes # current rig's nodes (session default, local only)
|
|
96
|
+
rig ps --nodes -A --json # fleet node inventory (explicit)
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
Use `rig ps --nodes --json` for the current node inventory across rigs. It is the best machine-readable operator surface for:
|
|
99
|
+
Use `rig ps --nodes -A --json` for the current node inventory across rigs (v0.4.4: `--nodes` needs an explicit scope outside a managed session). It is the best machine-readable operator surface for:
|
|
100
100
|
- session name
|
|
101
101
|
- runtime
|
|
102
102
|
- session/startup status
|
|
@@ -386,7 +386,7 @@ rig whoami --json
|
|
|
386
386
|
|
|
387
387
|
Notes:
|
|
388
388
|
- for tmux-backed self-attach, `rig whoami --json` is the right verification
|
|
389
|
-
- for raw/external self-attach, `rig ps --nodes --json` is currently the more reliable verification surface
|
|
389
|
+
- for raw/external self-attach, `rig ps --nodes -A --json` is currently the more reliable verification surface
|
|
390
390
|
- if the current shell is outside tmux, pass `--display-name <name>` when you want a stable human session label recorded
|
|
391
391
|
|
|
392
392
|
### Adopt a topology and bind live sessions
|
|
@@ -453,13 +453,13 @@ Verification loop:
|
|
|
453
453
|
```bash
|
|
454
454
|
rig discover --json
|
|
455
455
|
rig adopt <fragment.yaml> --bindings-file <bindings.yaml> --target-rig <rigId>
|
|
456
|
-
rig ps --nodes --json
|
|
456
|
+
rig ps --nodes -A --json
|
|
457
457
|
rig export <rigId> -o rig.yaml
|
|
458
458
|
```
|
|
459
459
|
|
|
460
460
|
Success looks like:
|
|
461
461
|
- the new sessions stop appearing in `rig discover`
|
|
462
|
-
- the new logical IDs appear in `rig ps --nodes --json`
|
|
462
|
+
- the new logical IDs appear in `rig ps --nodes -A --json`
|
|
463
463
|
- `rig export` includes the new pod
|
|
464
464
|
|
|
465
465
|
### Mixed-origin rigs are allowed
|
|
@@ -477,7 +477,7 @@ Current safety rule:
|
|
|
477
477
|
The proven operator pattern is:
|
|
478
478
|
- keep one OpenRig manager session outside the rig it manages
|
|
479
479
|
- address the target by rig name, not cached rig ID
|
|
480
|
-
- resolve the current owner from fresh `rig ps --nodes --json`
|
|
480
|
+
- resolve the current owner from fresh `rig ps --nodes -A --json`
|
|
481
481
|
- send the manager the spec path, bindings path, and verification steps with `rig send`
|
|
482
482
|
|
|
483
483
|
This lets ordinary agents ask the manager for OpenRig help instead of every agent needing to be an OpenRig expert.
|
|
@@ -548,7 +548,7 @@ When the CLI behaves strangely, use the smallest truthful check first:
|
|
|
548
548
|
```bash
|
|
549
549
|
rig whoami --json
|
|
550
550
|
rig daemon status
|
|
551
|
-
rig ps --nodes --json
|
|
551
|
+
rig ps --nodes -A --json
|
|
552
552
|
```
|
|
553
553
|
|
|
554
554
|
Specific operator rules:
|
|
@@ -584,7 +584,7 @@ Design assumptions that hold in the shipped CLI:
|
|
|
584
584
|
|
|
585
585
|
1. `rig whoami --json`
|
|
586
586
|
2. `rig transcript <your-session> --tail 100`
|
|
587
|
-
3. `rig ps --nodes --json`
|
|
587
|
+
3. `rig ps --nodes -A --json`
|
|
588
588
|
4. `rig chatroom history <rig> --limit 50`
|
|
589
589
|
|
|
590
590
|
## Commands That Do Not Exist
|
|
@@ -73,6 +73,17 @@ export declare class CodexRuntimeAdapter implements RuntimeAdapter {
|
|
|
73
73
|
* launches seats.)
|
|
74
74
|
*/
|
|
75
75
|
ensureCodexActivityHooks(): void;
|
|
76
|
+
/**
|
|
77
|
+
* OPR.0.4.3.33 — compute + splice Codex's `[hooks.state."<key>"] trusted_hash` for our 4
|
|
78
|
+
* authored activity hooks into `content`. `key_source` is the canonicalized config path
|
|
79
|
+
* (Codex keys trust by `std::fs::canonicalize(config.toml).display()`); we best-effort
|
|
80
|
+
* `realpathSync` the config path to match — on a miss (file not yet on real disk, or a mock
|
|
81
|
+
* fs in tests) we fall back to the plain absolute path, and any resulting key mismatch just
|
|
82
|
+
* degrades to the launch-time trust gate (Layer-2 floor), never a broken run. The command
|
|
83
|
+
* string is the value Codex deserializes from our TOML literal `'node "<relay>"'` — i.e.
|
|
84
|
+
* `node "<relay>"` WITHOUT the outer TOML quote delimiters. Timeout=5, matcher/status None.
|
|
85
|
+
*/
|
|
86
|
+
private applyCodexActivityHookTrust;
|
|
76
87
|
/**
|
|
77
88
|
* OPR.0.4.1.10 B3 — durable disable. When runtime.codex.hooks_enabled is false, strip the
|
|
78
89
|
* OpenRig-managed activity-hooks sentinel block from ~/.codex/config.toml so a seat that was
|
|
@@ -117,5 +128,40 @@ export declare class CodexRuntimeAdapter implements RuntimeAdapter {
|
|
|
117
128
|
private findCodexDescendantPids;
|
|
118
129
|
private readThreadIdFromLogs;
|
|
119
130
|
}
|
|
131
|
+
export interface CodexHookTrustInput {
|
|
132
|
+
/** Codex hook_key source identity: canonicalized `~/.codex/config.toml` path. */
|
|
133
|
+
keySource: string;
|
|
134
|
+
/** The command as Codex DESERIALIZES it — `node "<relay>"` (no outer TOML quote delimiters). */
|
|
135
|
+
command: string;
|
|
136
|
+
/** Our authored hook timeout (seconds). */
|
|
137
|
+
timeoutSec: number;
|
|
138
|
+
/** None for our hooks; folded into the hash when present (kept for faithful reproduction). */
|
|
139
|
+
matcher?: string | null;
|
|
140
|
+
/** None for our hooks; folded into the hash when present. */
|
|
141
|
+
statusMessage?: string | null;
|
|
142
|
+
/** Positional group index within the event's matcher-group list (our hooks: 0). */
|
|
143
|
+
groupIndex?: number;
|
|
144
|
+
/** Positional handler index within the group's handler list (our hooks: 0). */
|
|
145
|
+
handlerIndex?: number;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Reproduce Codex's persisted hook trust `{ key, trusted_hash }` for one authored activity
|
|
149
|
+
* hook. Pure + deterministic. See the block comment above for the full RTFM derivation and the
|
|
150
|
+
* PROVISIONAL-until-VM-read-back caveat.
|
|
151
|
+
*/
|
|
152
|
+
export declare function computeCodexHookTrust(event: (typeof OPENRIG_ACTIVITY_HOOK_EVENTS)[number], input: CodexHookTrustInput): {
|
|
153
|
+
key: string;
|
|
154
|
+
hash: string;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* OPR.0.4.3.33 — idempotent, non-clobbering, section-scoped writer for a single
|
|
158
|
+
* `[hooks.state."<key>"] trusted_hash = "<hash>"` record. Mirrors upsertCodexProjectTrust:
|
|
159
|
+
* find/create the exact table header, splice ONLY its `trusted_hash` line, leave every other
|
|
160
|
+
* `[hooks.state]` / `[projects]` entry and the managed hook block byte-identical. Same key+hash
|
|
161
|
+
* ⇒ no-op. Only ever called for OUR 4 authored hook keys (never a blanket/wildcard trust).
|
|
162
|
+
*/
|
|
163
|
+
export declare function upsertCodexHookTrust(content: string, key: string, hash: string): string;
|
|
120
164
|
export declare function isCodex013xOrLater(version: string): boolean;
|
|
165
|
+
declare const OPENRIG_ACTIVITY_HOOK_EVENTS: readonly ["SessionStart", "UserPromptSubmit", "Stop", "PermissionRequest"];
|
|
166
|
+
export {};
|
|
121
167
|
//# sourceMappingURL=codex-runtime-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-runtime-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/codex-runtime-adapter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EACV,cAAc,EAAE,WAAW,EAAE,mBAAmB,EAChD,iBAAiB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,eAAe,EAC3E,mBAAmB,EACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,8BAA8B,CAAC;AAKtC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,cAAc;IACxD,QAAQ,CAAC,OAAO,WAAW;IAC3B,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,aAAa,CAA8D;IACnF,OAAO,CAAC,iBAAiB,CAAsC;IAC/D,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,mBAAmB,CAAsB;IAKjD,OAAO,CAAC,iBAAiB,CAAC,CAAS;gBAEvB,IAAI,EAAE;QAChB,IAAI,EAAE,WAAW,CAAC;QAClB,KAAK,EAAE,iBAAiB,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC5E,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;QACxD,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;QAC1C,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B;IAUD;;;;;;;;;;;OAWG;IACH,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAehF;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,wBAAwB,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"codex-runtime-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/codex-runtime-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -98,12 +98,51 @@ export class CodexRuntimeAdapter {
|
|
|
98
98
|
return;
|
|
99
99
|
const configPath = nodePath.join(homedir, ".codex", "config.toml");
|
|
100
100
|
const existing = this.fs.exists(configPath) ? this.fs.readFile(configPath) : "";
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
101
|
+
const withHooks = upsertCodexActivityHooks(existing, relay);
|
|
102
|
+
if (withHooks !== existing) {
|
|
103
103
|
this.fs.mkdirp(nodePath.dirname(configPath));
|
|
104
|
-
this.fs.writeFile(configPath,
|
|
104
|
+
this.fs.writeFile(configPath, withHooks);
|
|
105
|
+
}
|
|
106
|
+
// OPR.0.4.3.33 hook-trust-autoclear — pre-write Codex's OWN hook trust record
|
|
107
|
+
// ([hooks.state."<key>"] trusted_hash) for exactly our 4 authored hooks, on the SAME
|
|
108
|
+
// seam that provisions them, so the daemon's unmanaged inline hooks are trusted from
|
|
109
|
+
// clean config on EVERY path a fresh Codex process reads config (launch/adopt/reconcile)
|
|
110
|
+
// — not just the launch keystroke gate. Layer-2 floor (dismissCodexInteractiveGates)
|
|
111
|
+
// stays as the fail-safe if a Codex-version drift changes the identity/hash. Idempotent
|
|
112
|
+
// + non-clobbering; only touches our 4 keys. See applyCodexActivityHookTrust for the RTFM.
|
|
113
|
+
const trusted = this.applyCodexActivityHookTrust(withHooks, configPath, relay);
|
|
114
|
+
if (trusted !== withHooks) {
|
|
115
|
+
this.fs.mkdirp(nodePath.dirname(configPath));
|
|
116
|
+
this.fs.writeFile(configPath, trusted);
|
|
105
117
|
}
|
|
106
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* OPR.0.4.3.33 — compute + splice Codex's `[hooks.state."<key>"] trusted_hash` for our 4
|
|
121
|
+
* authored activity hooks into `content`. `key_source` is the canonicalized config path
|
|
122
|
+
* (Codex keys trust by `std::fs::canonicalize(config.toml).display()`); we best-effort
|
|
123
|
+
* `realpathSync` the config path to match — on a miss (file not yet on real disk, or a mock
|
|
124
|
+
* fs in tests) we fall back to the plain absolute path, and any resulting key mismatch just
|
|
125
|
+
* degrades to the launch-time trust gate (Layer-2 floor), never a broken run. The command
|
|
126
|
+
* string is the value Codex deserializes from our TOML literal `'node "<relay>"'` — i.e.
|
|
127
|
+
* `node "<relay>"` WITHOUT the outer TOML quote delimiters. Timeout=5, matcher/status None.
|
|
128
|
+
*/
|
|
129
|
+
applyCodexActivityHookTrust(content, configPath, relay) {
|
|
130
|
+
let keySource = configPath;
|
|
131
|
+
try {
|
|
132
|
+
keySource = fs.realpathSync(configPath);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// config.toml not on the real filesystem (first write / unit-test mock fs) — the plain
|
|
136
|
+
// absolute path is the honest best guess; a canonicalization delta is fail-safe (gate reappears).
|
|
137
|
+
}
|
|
138
|
+
const command = `node "${relay}"`;
|
|
139
|
+
let next = content;
|
|
140
|
+
for (const event of OPENRIG_ACTIVITY_HOOK_EVENTS) {
|
|
141
|
+
const { key, hash } = computeCodexHookTrust(event, { keySource, command, timeoutSec: 5 });
|
|
142
|
+
next = upsertCodexHookTrust(next, key, hash);
|
|
143
|
+
}
|
|
144
|
+
return next;
|
|
145
|
+
}
|
|
107
146
|
/**
|
|
108
147
|
* OPR.0.4.1.10 B3 — durable disable. When runtime.codex.hooks_enabled is false, strip the
|
|
109
148
|
* OpenRig-managed activity-hooks sentinel block from ~/.codex/config.toml so a seat that was
|
|
@@ -693,6 +732,131 @@ function upsertCodexProjectTrust(content, projectPath) {
|
|
|
693
732
|
}
|
|
694
733
|
return `${lines.join("\n").replace(/\n*$/, "\n")}`;
|
|
695
734
|
}
|
|
735
|
+
// ── OPR.0.4.3.33 hook-trust-autoclear ────────────────────────────────────────────────────
|
|
736
|
+
// Pre-write Codex's OWN hook trust record so the daemon's provisioned (unmanaged) inline
|
|
737
|
+
// activity hooks are trusted on every path (launch/adopt/reconcile) without a manual `/hooks`
|
|
738
|
+
// "Trust all" keystroke. Codex is a private impl; the key+hash below are REPRODUCED from the
|
|
739
|
+
// open source (RTFM, cited) and are PROVISIONAL until pinned by a byte-for-byte read-back of a
|
|
740
|
+
// real Codex `[hooks.state]` after `/hooks`->"Trust all" (the QA VM proof — see the unit test
|
|
741
|
+
// fixture marked PIN-TO-VM). A mismatch is fail-safe: Codex re-shows the gate and the launch-time
|
|
742
|
+
// Layer-2 keystroke floor (dismissCodexInteractiveGates) clears it — never a false-trusted run.
|
|
743
|
+
//
|
|
744
|
+
// RTFM sources (cite):
|
|
745
|
+
// - https://developers.openai.com/codex/hooks
|
|
746
|
+
// - openai/codex PR #20321 "hook trust metadata and enforcement" (merge commit 0452dca;
|
|
747
|
+
// typed-identity commit ffcc9cc) — key file codex-rs/hooks/src/engine/discovery.rs.
|
|
748
|
+
// - openai/codex issue #21615 (the `[hooks.state]` pre-write workaround for exactly this
|
|
749
|
+
// local-wrapper-installer case) + #23259 (positional path-keying fragility).
|
|
750
|
+
//
|
|
751
|
+
// KEY — codex-rs/hooks/src/lib.rs `hook_key`:
|
|
752
|
+
// `{key_source}:{event_label}:{group_index}:{handler_index}`
|
|
753
|
+
// - key_source: `std::fs::canonicalize(~/.codex/config.toml).display()` (the config source
|
|
754
|
+
// layer identity; confirmed by codex-rs/app-server/tests/suite/v2/hooks_list.rs which keys
|
|
755
|
+
// `{canonicalize(config.toml).display()}:pre_tool_use:0:0`).
|
|
756
|
+
// - event_label: `hook_event_key_label()` — SessionStart→session_start,
|
|
757
|
+
// UserPromptSubmit→user_prompt_submit, Stop→stop, PermissionRequest→permission_request.
|
|
758
|
+
// - group_index/handler_index: positional. Our managed block writes exactly one
|
|
759
|
+
// `[[hooks.<Ev>]]` group (0) with one `[[hooks.<Ev>.hooks]]` handler (0) per event ⇒ 0:0.
|
|
760
|
+
// (Positional keying is a known upstream fragility (#23259); if a user pre-authored hooks
|
|
761
|
+
// for the same event in the same layer our index would shift → gate reappears → fail-safe.)
|
|
762
|
+
//
|
|
763
|
+
// HASH — codex-rs/hooks/src/engine/discovery.rs `command_hook_hash`
|
|
764
|
+
// → codex-rs/config/src/fingerprint.rs `version_for_toml`:
|
|
765
|
+
// hash = "sha256:" + hex( sha256( canonical_json( toml_value( NormalizedHookIdentity ) ) ) )
|
|
766
|
+
// NormalizedHookIdentity { event_name: <label>, #[serde(flatten)] group: MatcherGroup }
|
|
767
|
+
// MatcherGroup { matcher: Option<String>, hooks: Vec<HookHandlerConfig> }
|
|
768
|
+
// HookHandlerConfig::Command (codex-rs/config/src/hook_config.rs, `#[serde(tag="type")]`,
|
|
769
|
+
// rename "command"): { command: String, commandWindows: Option, timeout(=timeout_sec):
|
|
770
|
+
// Option<u64>, async: bool, statusMessage: Option }
|
|
771
|
+
// Load-bearing serialization facts:
|
|
772
|
+
// * `TomlValue::try_from` DROPS None fields (TOML has no null) → matcher / commandWindows /
|
|
773
|
+
// statusMessage are omitted for our hooks; `async` is a plain bool (not Option) so
|
|
774
|
+
// `async = false` IS present.
|
|
775
|
+
// * event_name uses the snake_case label (session_start …), NOT the CamelCase event.
|
|
776
|
+
// * `version_for_toml` converts the TomlValue → serde_json Value, `canonical_json` sorts
|
|
777
|
+
// every object's keys recursively, then sha256's the COMPACT JSON bytes. serde_json's
|
|
778
|
+
// compact output (no spaces, `/` unescaped, `"`/`\` JSON-escaped) matches JSON.stringify.
|
|
779
|
+
// CONFIDENCE: the HASH is fully deterministic from the open source (JSON+sha256) — HIGH.
|
|
780
|
+
// The KEY's exact key_source canonical form + the positional indices are what the VM
|
|
781
|
+
// read-back must confirm — PROVISIONAL until then.
|
|
782
|
+
/** Recursively sort object keys (mirrors codex-rs fingerprint.rs `canonical_json`). */
|
|
783
|
+
function canonicalizeJsonValue(value) {
|
|
784
|
+
if (Array.isArray(value))
|
|
785
|
+
return value.map(canonicalizeJsonValue);
|
|
786
|
+
if (value !== null && typeof value === "object") {
|
|
787
|
+
const src = value;
|
|
788
|
+
const out = {};
|
|
789
|
+
for (const key of Object.keys(src).sort())
|
|
790
|
+
out[key] = canonicalizeJsonValue(src[key]);
|
|
791
|
+
return out;
|
|
792
|
+
}
|
|
793
|
+
return value;
|
|
794
|
+
}
|
|
795
|
+
const CODEX_HOOK_EVENT_KEY_LABEL = {
|
|
796
|
+
SessionStart: "session_start",
|
|
797
|
+
UserPromptSubmit: "user_prompt_submit",
|
|
798
|
+
Stop: "stop",
|
|
799
|
+
PermissionRequest: "permission_request",
|
|
800
|
+
};
|
|
801
|
+
/**
|
|
802
|
+
* Reproduce Codex's persisted hook trust `{ key, trusted_hash }` for one authored activity
|
|
803
|
+
* hook. Pure + deterministic. See the block comment above for the full RTFM derivation and the
|
|
804
|
+
* PROVISIONAL-until-VM-read-back caveat.
|
|
805
|
+
*/
|
|
806
|
+
export function computeCodexHookTrust(event, input) {
|
|
807
|
+
const label = CODEX_HOOK_EVENT_KEY_LABEL[event];
|
|
808
|
+
const groupIndex = input.groupIndex ?? 0;
|
|
809
|
+
const handlerIndex = input.handlerIndex ?? 0;
|
|
810
|
+
const key = `${input.keySource}:${label}:${groupIndex}:${handlerIndex}`;
|
|
811
|
+
// Build NormalizedHookIdentity exactly as `TomlValue::try_from` would: None fields dropped.
|
|
812
|
+
const handler = {
|
|
813
|
+
type: "command",
|
|
814
|
+
command: input.command,
|
|
815
|
+
timeout: input.timeoutSec,
|
|
816
|
+
async: false,
|
|
817
|
+
};
|
|
818
|
+
if (input.statusMessage != null)
|
|
819
|
+
handler.statusMessage = input.statusMessage;
|
|
820
|
+
const identity = { event_name: label, hooks: [handler] };
|
|
821
|
+
if (input.matcher != null)
|
|
822
|
+
identity.matcher = input.matcher;
|
|
823
|
+
const serialized = JSON.stringify(canonicalizeJsonValue(identity));
|
|
824
|
+
const hex = createHash("sha256").update(serialized, "utf8").digest("hex");
|
|
825
|
+
return { key, hash: `sha256:${hex}` };
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* OPR.0.4.3.33 — idempotent, non-clobbering, section-scoped writer for a single
|
|
829
|
+
* `[hooks.state."<key>"] trusted_hash = "<hash>"` record. Mirrors upsertCodexProjectTrust:
|
|
830
|
+
* find/create the exact table header, splice ONLY its `trusted_hash` line, leave every other
|
|
831
|
+
* `[hooks.state]` / `[projects]` entry and the managed hook block byte-identical. Same key+hash
|
|
832
|
+
* ⇒ no-op. Only ever called for OUR 4 authored hook keys (never a blanket/wildcard trust).
|
|
833
|
+
*/
|
|
834
|
+
export function upsertCodexHookTrust(content, key, hash) {
|
|
835
|
+
const header = `[hooks.state.${JSON.stringify(key)}]`;
|
|
836
|
+
const trustLine = `trusted_hash = ${JSON.stringify(hash)}`;
|
|
837
|
+
const lines = content.length > 0 ? content.split("\n") : [];
|
|
838
|
+
const headerIndex = lines.findIndex((line) => line.trim() === header);
|
|
839
|
+
if (headerIndex === -1) {
|
|
840
|
+
const trimmed = content.trimEnd();
|
|
841
|
+
const prefix = trimmed.length > 0 ? `${trimmed}\n\n` : "";
|
|
842
|
+
return `${prefix}${header}\n${trustLine}\n`;
|
|
843
|
+
}
|
|
844
|
+
let nextSectionIndex = lines.length;
|
|
845
|
+
for (let i = headerIndex + 1; i < lines.length; i++) {
|
|
846
|
+
if (lines[i].trim().startsWith("[")) {
|
|
847
|
+
nextSectionIndex = i;
|
|
848
|
+
break;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
const hashIndex = lines.findIndex((line, index) => index > headerIndex && index < nextSectionIndex && line.trim().startsWith("trusted_hash"));
|
|
852
|
+
if (hashIndex >= 0) {
|
|
853
|
+
lines[hashIndex] = trustLine;
|
|
854
|
+
}
|
|
855
|
+
else {
|
|
856
|
+
lines.splice(headerIndex + 1, 0, trustLine);
|
|
857
|
+
}
|
|
858
|
+
return `${lines.join("\n").replace(/\n*$/, "\n")}`;
|
|
859
|
+
}
|
|
696
860
|
function parseCanonicalSessionName(sessionName) {
|
|
697
861
|
const trimmed = sessionName.trim();
|
|
698
862
|
const atIndex = trimmed.indexOf("@");
|