@openrig/cli 0.4.6 → 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/guidance/CULTURE-default.md +19 -0
- package/daemon/assets/guidance/openrig-start.md +20 -5
- package/daemon/assets/plugins/openrig-core/README.md +1 -1
- 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/SKILL.md +9 -6
- package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/precompact-hook.mjs +11 -72
- 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 +36 -22
- package/daemon/assets/plugins/openrig-core/skills/messaging-the-human/SKILL.md +108 -0
- package/daemon/assets/plugins/openrig-core/skills/mission-slice-sop/SKILL.md +7 -13
- package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +88 -0
- package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +189 -105
- package/daemon/assets/plugins/openrig-core/skills/queue-handoff/SKILL.md +26 -9
- package/daemon/assets/plugins/openrig-core/skills/seat-continuity-and-handover/SKILL.md +11 -9
- package/daemon/assets/plugins/openrig-core/skills/session-compaction-and-restore/SKILL.md +162 -0
- package/daemon/assets/plugins/openrig-core/skills/software-for-agents/SKILL.md +165 -0
- 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/cmux-transport.d.ts.map +1 -1
- package/daemon/dist/adapters/cmux-transport.js +8 -1
- package/daemon/dist/adapters/cmux-transport.js.map +1 -1
- package/daemon/dist/adapters/cmux.d.ts +9 -0
- package/daemon/dist/adapters/cmux.d.ts.map +1 -1
- package/daemon/dist/adapters/cmux.js +21 -0
- package/daemon/dist/adapters/cmux.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 +3 -0
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.js +30 -9
- 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/claude-compaction-enforcer.d.ts +3 -0
- package/daemon/dist/domain/claude-compaction-enforcer.d.ts.map +1 -1
- package/daemon/dist/domain/claude-compaction-enforcer.js +19 -3
- package/daemon/dist/domain/claude-compaction-enforcer.js.map +1 -1
- package/daemon/dist/domain/cmux-layout-service.d.ts +36 -0
- package/daemon/dist/domain/cmux-layout-service.d.ts.map +1 -1
- package/daemon/dist/domain/cmux-layout-service.js +100 -28
- package/daemon/dist/domain/cmux-layout-service.js.map +1 -1
- package/daemon/dist/domain/context-monitor.d.ts +2 -0
- package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
- package/daemon/dist/domain/context-monitor.js +14 -0
- package/daemon/dist/domain/context-monitor.js.map +1 -1
- package/daemon/dist/domain/feed/attention-aggregator.js +1 -1
- package/daemon/dist/domain/feed/attention-aggregator.js.map +1 -1
- package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts.map +1 -1
- package/daemon/dist/domain/hosts/hosts-registry-reader.js +12 -10
- package/daemon/dist/domain/hosts/hosts-registry-reader.js.map +1 -1
- package/daemon/dist/domain/hosts/hosts-registry-writer.d.ts.map +1 -1
- package/daemon/dist/domain/hosts/hosts-registry-writer.js +3 -2
- package/daemon/dist/domain/hosts/hosts-registry-writer.js.map +1 -1
- package/daemon/dist/domain/hosts/read-through.js +1 -1
- package/daemon/dist/domain/hosts/read-through.js.map +1 -1
- package/daemon/dist/domain/hosts/remote-daemon-http.d.ts.map +1 -1
- package/daemon/dist/domain/hosts/remote-daemon-http.js +8 -5
- package/daemon/dist/domain/hosts/remote-daemon-http.js.map +1 -1
- 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.d.ts +3 -12
- package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
- package/daemon/dist/domain/node-inventory.js +57 -15
- 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/plugin-vendor-service.d.ts +2 -0
- package/daemon/dist/domain/plugin-vendor-service.d.ts.map +1 -1
- package/daemon/dist/domain/plugin-vendor-service.js +23 -0
- package/daemon/dist/domain/plugin-vendor-service.js.map +1 -1
- package/daemon/dist/domain/projection-lane.d.ts +7 -0
- package/daemon/dist/domain/projection-lane.d.ts.map +1 -0
- package/daemon/dist/domain/projection-lane.js +28 -0
- package/daemon/dist/domain/projection-lane.js.map +1 -0
- package/daemon/dist/domain/ps-projection.d.ts +19 -0
- package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
- package/daemon/dist/domain/ps-projection.js +46 -6
- package/daemon/dist/domain/ps-projection.js.map +1 -1
- package/daemon/dist/domain/queue-repository.d.ts +14 -10
- package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
- package/daemon/dist/domain/queue-repository.js +33 -12
- package/daemon/dist/domain/queue-repository.js.map +1 -1
- 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/review/compose.d.ts +77 -4
- package/daemon/dist/domain/review/compose.d.ts.map +1 -1
- package/daemon/dist/domain/review/compose.js +152 -16
- package/daemon/dist/domain/review/compose.js.map +1 -1
- package/daemon/dist/domain/review/fleet-compose.js +1 -1
- package/daemon/dist/domain/review/fleet-compose.js.map +1 -1
- package/daemon/dist/domain/review/gather.d.ts +1 -1
- package/daemon/dist/domain/review/gather.d.ts.map +1 -1
- package/daemon/dist/domain/review/gather.js +92 -67
- package/daemon/dist/domain/review/gather.js.map +1 -1
- package/daemon/dist/domain/review/proof-io.d.ts +2 -0
- package/daemon/dist/domain/review/proof-io.d.ts.map +1 -0
- package/daemon/dist/domain/review/proof-io.js +38 -0
- package/daemon/dist/domain/review/proof-io.js.map +1 -0
- 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 +202 -10
- 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/scope/plan-lock-artifacts.d.ts +8 -0
- package/daemon/dist/domain/scope/plan-lock-artifacts.d.ts.map +1 -0
- package/daemon/dist/domain/scope/plan-lock-artifacts.js +57 -0
- package/daemon/dist/domain/scope/plan-lock-artifacts.js.map +1 -0
- package/daemon/dist/domain/scope/scaffold-placeholder.d.ts +38 -0
- package/daemon/dist/domain/scope/scaffold-placeholder.d.ts.map +1 -0
- package/daemon/dist/domain/scope/scaffold-placeholder.js +98 -0
- package/daemon/dist/domain/scope/scaffold-placeholder.js.map +1 -0
- package/daemon/dist/domain/scope/scope-approve.d.ts.map +1 -1
- package/daemon/dist/domain/scope/scope-approve.js +22 -1
- package/daemon/dist/domain/scope/scope-approve.js.map +1 -1
- package/daemon/dist/domain/scope/scope-audit.d.ts.map +1 -1
- package/daemon/dist/domain/scope/scope-audit.js +57 -20
- package/daemon/dist/domain/scope/scope-audit.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/session-transport.d.ts +17 -0
- package/daemon/dist/domain/session-transport.d.ts.map +1 -1
- package/daemon/dist/domain/session-transport.js +44 -0
- package/daemon/dist/domain/session-transport.js.map +1 -1
- package/daemon/dist/domain/slices/qitem-membership.d.ts +17 -0
- package/daemon/dist/domain/slices/qitem-membership.d.ts.map +1 -0
- package/daemon/dist/domain/slices/qitem-membership.js +60 -0
- package/daemon/dist/domain/slices/qitem-membership.js.map +1 -0
- package/daemon/dist/domain/slices/slice-detail-projector.d.ts +5 -0
- package/daemon/dist/domain/slices/slice-detail-projector.d.ts.map +1 -1
- package/daemon/dist/domain/slices/slice-detail-projector.js +157 -11
- package/daemon/dist/domain/slices/slice-detail-projector.js.map +1 -1
- package/daemon/dist/domain/slices/slice-indexer.d.ts +86 -0
- package/daemon/dist/domain/slices/slice-indexer.d.ts.map +1 -1
- package/daemon/dist/domain/slices/slice-indexer.js +422 -45
- package/daemon/dist/domain/slices/slice-indexer.js.map +1 -1
- package/daemon/dist/domain/startup-orchestrator.d.ts +9 -0
- package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/startup-orchestrator.js +71 -3
- package/daemon/dist/domain/startup-orchestrator.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/terminal/cmux-provider-adapter.d.ts +12 -11
- package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts.map +1 -1
- package/daemon/dist/domain/terminal/cmux-provider-adapter.js +61 -28
- package/daemon/dist/domain/terminal/cmux-provider-adapter.js.map +1 -1
- package/daemon/dist/domain/terminal/herdr-adapter.d.ts +27 -10
- package/daemon/dist/domain/terminal/herdr-adapter.d.ts.map +1 -1
- package/daemon/dist/domain/terminal/herdr-adapter.js +74 -33
- package/daemon/dist/domain/terminal/herdr-adapter.js.map +1 -1
- package/daemon/dist/domain/transcript-capture.d.ts +3 -0
- package/daemon/dist/domain/transcript-capture.d.ts.map +1 -1
- package/daemon/dist/domain/transcript-capture.js +28 -0
- package/daemon/dist/domain/transcript-capture.js.map +1 -1
- package/daemon/dist/domain/transcript-store.d.ts +10 -0
- package/daemon/dist/domain/transcript-store.d.ts.map +1 -1
- package/daemon/dist/domain/transcript-store.js +26 -0
- package/daemon/dist/domain/transcript-store.js.map +1 -1
- package/daemon/dist/domain/types.d.ts +21 -0
- package/daemon/dist/domain/types.d.ts.map +1 -1
- package/daemon/dist/domain/types.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 +9 -4
- package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
- package/daemon/dist/domain/workspace/workspace-doctor.js +1 -1
- package/daemon/dist/domain/workspace/workspace-doctor.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/mission-control.js +1 -1
- package/daemon/dist/routes/mission-control.js.map +1 -1
- package/daemon/dist/routes/missions.d.ts +7 -0
- package/daemon/dist/routes/missions.d.ts.map +1 -1
- package/daemon/dist/routes/missions.js +6 -1
- package/daemon/dist/routes/missions.js.map +1 -1
- package/daemon/dist/routes/ps.d.ts.map +1 -1
- package/daemon/dist/routes/ps.js +5 -1
- package/daemon/dist/routes/ps.js.map +1 -1
- package/daemon/dist/routes/queue.d.ts.map +1 -1
- package/daemon/dist/routes/queue.js +9 -2
- package/daemon/dist/routes/queue.js.map +1 -1
- package/daemon/dist/routes/rigs.d.ts.map +1 -1
- package/daemon/dist/routes/rigs.js +29 -10
- package/daemon/dist/routes/rigs.js.map +1 -1
- package/daemon/dist/routes/scope-audit.d.ts.map +1 -1
- package/daemon/dist/routes/scope-audit.js +141 -135
- package/daemon/dist/routes/scope-audit.js.map +1 -1
- package/daemon/dist/routes/sessions.js +2 -1
- 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 +48 -38
- package/daemon/dist/routes/slices.js.map +1 -1
- package/daemon/dist/routes/transcripts.d.ts.map +1 -1
- package/daemon/dist/routes/transcripts.js +62 -33
- package/daemon/dist/routes/transcripts.js.map +1 -1
- package/daemon/dist/startup.d.ts.map +1 -1
- package/daemon/dist/startup.js +42 -12
- package/daemon/dist/startup.js.map +1 -1
- package/daemon/docs/reference/agent-startup-guide.md +1 -0
- 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/apps/vault-specialist/agent.yaml +2 -1
- package/daemon/specs/agents/conveyor/builder/agent.yaml +2 -1
- package/daemon/specs/agents/conveyor/lead/agent.yaml +2 -1
- package/daemon/specs/agents/conveyor/planner/agent.yaml +2 -1
- package/daemon/specs/agents/conveyor/reviewer/agent.yaml +2 -1
- package/daemon/specs/agents/design/product-designer/agent.yaml +12 -2
- package/daemon/specs/agents/development/implementer/agent.yaml +12 -2
- package/daemon/specs/agents/development/qa/agent.yaml +12 -2
- package/daemon/specs/agents/development/qa/guidance/role.md +1 -0
- package/daemon/specs/agents/factory-rsi/dogfood/agent.yaml +2 -1
- package/daemon/specs/agents/factory-rsi/release-manager/agent.yaml +2 -1
- package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +12 -2
- package/daemon/specs/agents/product-management/pm/agent.yaml +1 -2
- package/daemon/specs/agents/research/analyst/agent.yaml +2 -1
- package/daemon/specs/agents/research/synthesizer/agent.yaml +2 -1
- package/daemon/specs/agents/review/independent-reviewer/agent.yaml +12 -2
- package/daemon/specs/agents/shared/agent.yaml +5 -8
- package/daemon/specs/agents/shared/runtime/claude-settings.fragment.json +1 -8
- package/daemon/specs/agents/shared/skills/core/agent-starters/SKILL.md +132 -0
- package/daemon/{assets/plugins/openrig-core/skills → specs/agents/shared/skills/core}/agent-startup-and-context-ingestion/SKILL.md +27 -19
- package/daemon/specs/agents/shared/skills/core/attention-queue/SKILL.md +264 -0
- package/daemon/specs/agents/shared/skills/core/cross-host-rig-commands/SKILL.md +190 -0
- package/daemon/specs/agents/shared/skills/core/human-in-the-loop/SKILL.md +104 -0
- package/daemon/specs/agents/shared/skills/core/openrig-architect/SKILL.md +23 -8
- package/daemon/specs/agents/shared/skills/core/openrig-cmux/SKILL.md +0 -5
- package/daemon/specs/agents/shared/skills/core/openrig-herdr/SKILL.md +1 -6
- package/daemon/specs/agents/shared/skills/core/openrig-upgrade/SKILL.md +460 -0
- package/daemon/specs/agents/shared/skills/core/rig-bundles-and-shareable-artifacts/SKILL.md +101 -0
- package/daemon/specs/agents/shared/skills/core/rig-lifecycle/SKILL.md +22 -11
- package/daemon/specs/agents/shared/skills/core/session-source-fork/SKILL.md +160 -0
- package/daemon/specs/agents/shared/skills/core/specification-system/SKILL.md +103 -0
- package/daemon/specs/agents/shared/skills/core/topology-mutation-and-seat-management/SKILL.md +118 -0
- package/daemon/specs/agents/shared/skills/core/watchdog/SKILL.md +125 -0
- package/daemon/specs/agents/shared/skills/process/brainstorming/OPENRIG.md +3 -3
- package/daemon/specs/agents/shared/skills/process/executing-plans/OPENRIG.md +1 -1
- package/daemon/specs/agents/shared/skills/process/frontend-design/SKILL.md +6 -3
- package/daemon/specs/agents/shared/skills/process/systematic-debugging/find-polluter.sh +0 -0
- package/daemon/specs/agents/shared/skills/process/test-driven-development/SKILL.md +1 -1
- package/daemon/specs/agents/shared/skills/process/using-superpowers/OPENRIG.md +1 -1
- package/daemon/specs/agents/shared/skills/process/verification-before-completion/SKILL.md +13 -2
- package/daemon/specs/agents/shared/skills/process/writing-plans/OPENRIG.md +1 -1
- package/daemon/specs/rigs/focused/pm-team/CULTURE.md +1 -1
- package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/agent.yaml +2 -2
- package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/guidance/role.md +5 -4
- package/daemon/specs/rigs/launch/kernel/agents/operator/agent/agent.yaml +2 -2
- package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +3 -5
- package/daemon/specs/rigs/launch/kernel/agents/queue/worker/agent.yaml +2 -2
- package/daemon/specs/rigs/launch/kernel/culture/CULTURE.md +3 -4
- package/daemon/specs/rigs/preview/product-team/CULTURE.md +1 -1
- package/dist/bin-wrapper.d.ts.map +1 -1
- package/dist/bin-wrapper.js +3 -1
- package/dist/bin-wrapper.js.map +1 -1
- package/dist/build-info.js +3 -3
- package/dist/cli-error.d.ts +33 -0
- package/dist/cli-error.d.ts.map +1 -0
- package/dist/cli-error.js +94 -0
- package/dist/cli-error.js.map +1 -0
- package/dist/commands/config-init-workspace.js +1 -1
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +17 -11
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/host.d.ts.map +1 -1
- package/dist/commands/host.js +24 -10
- package/dist/commands/host.js.map +1 -1
- package/dist/commands/proof.js +1 -1
- package/dist/commands/proof.js.map +1 -1
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +16 -2
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/queue.d.ts.map +1 -1
- package/dist/commands/queue.js +103 -24
- package/dist/commands/queue.js.map +1 -1
- package/dist/commands/rig.d.ts.map +1 -1
- package/dist/commands/rig.js +122 -0
- package/dist/commands/rig.js.map +1 -1
- package/dist/commands/scope.js +2 -2
- package/dist/commands/scope.js.map +1 -1
- package/dist/commands/send.d.ts.map +1 -1
- package/dist/commands/send.js +118 -24
- package/dist/commands/send.js.map +1 -1
- 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/dist/commands/slack.d.ts +37 -0
- package/dist/commands/slack.d.ts.map +1 -0
- package/dist/commands/slack.js +274 -0
- package/dist/commands/slack.js.map +1 -0
- package/dist/commands/ui.d.ts +1 -0
- package/dist/commands/ui.d.ts.map +1 -1
- package/dist/commands/ui.js +2 -0
- package/dist/commands/ui.js.map +1 -1
- package/dist/commands/up.js +1 -1
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +3 -3
- package/dist/commands/whoami.js.map +1 -1
- package/dist/daemon-lifecycle.d.ts.map +1 -1
- package/dist/daemon-lifecycle.js +45 -14
- package/dist/daemon-lifecycle.js.map +1 -1
- package/dist/host-registry.d.ts +6 -1
- package/dist/host-registry.d.ts.map +1 -1
- package/dist/host-registry.js +15 -6
- package/dist/host-registry.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/scope/scaffold-placeholder.d.ts +38 -0
- package/dist/lib/scope/scaffold-placeholder.d.ts.map +1 -0
- package/dist/lib/scope/scaffold-placeholder.js +98 -0
- package/dist/lib/scope/scaffold-placeholder.js.map +1 -0
- package/dist/lib/scope/scope-audit.d.ts.map +1 -1
- package/dist/lib/scope/scope-audit.js +57 -20
- package/dist/lib/scope/scope-audit.js.map +1 -1
- package/dist/lib/scope-templates/backlog-deprecation.md +1 -1
- package/dist/lib/scope-templates/backlog-tech-debt.md +1 -1
- package/dist/lib/scope-templates/bug-fix.md +1 -1
- package/dist/lib/scope-templates/implementation-prd.md +1 -1
- package/dist/lib/scope-templates/mission-notes.md +7 -2
- package/dist/lib/scope-templates/mission-placeholder.md +1 -1
- package/dist/lib/scope-templates/mission-progress.md +1 -1
- package/dist/lib/scope-templates/mission-release.md +1 -1
- package/dist/lib/scope-templates/placeholder.md +1 -1
- package/dist/lib/scope-templates/proof.md +1 -1
- package/dist/lib/scope-templates/release-feature.md +1 -1
- package/dist/lib/scope-templates/research.md +1 -1
- package/dist/lib/scope-templates/slice-progress.md +1 -1
- package/dist/remote-host-ops.d.ts.map +1 -1
- package/dist/remote-host-ops.js +2 -2
- package/dist/remote-host-ops.js.map +1 -1
- package/dist/slack/config.d.ts +41 -0
- package/dist/slack/config.d.ts.map +1 -0
- package/dist/slack/config.js +60 -0
- package/dist/slack/config.js.map +1 -0
- package/dist/slack/inbound.d.ts +75 -0
- package/dist/slack/inbound.d.ts.map +1 -0
- package/dist/slack/inbound.js +133 -0
- package/dist/slack/inbound.js.map +1 -0
- package/dist/slack/message.d.ts +26 -0
- package/dist/slack/message.d.ts.map +1 -0
- package/dist/slack/message.js +60 -0
- package/dist/slack/message.js.map +1 -0
- package/dist/slack/outbound.d.ts +39 -0
- package/dist/slack/outbound.d.ts.map +1 -0
- package/dist/slack/outbound.js +52 -0
- package/dist/slack/outbound.js.map +1 -0
- package/dist/slack/queue-bridge.d.ts +56 -0
- package/dist/slack/queue-bridge.d.ts.map +1 -0
- package/dist/slack/queue-bridge.js +114 -0
- package/dist/slack/queue-bridge.js.map +1 -0
- package/dist/slack/secrets.d.ts +21 -0
- package/dist/slack/secrets.d.ts.map +1 -0
- package/dist/slack/secrets.js +73 -0
- package/dist/slack/secrets.js.map +1 -0
- package/dist/slack/slack-api.d.ts +49 -0
- package/dist/slack/slack-api.d.ts.map +1 -0
- package/dist/slack/slack-api.js +110 -0
- package/dist/slack/slack-api.js.map +1 -0
- package/dist/slack/state-store.d.ts +62 -0
- package/dist/slack/state-store.d.ts.map +1 -0
- package/dist/slack/state-store.js +132 -0
- package/dist/slack/state-store.js.map +1 -0
- package/package.json +1 -1
- package/ui/dist/assets/{index-zrFqS7gL.js → index-DkNi0RT8.js} +184 -184
- package/ui/dist/assets/index-N-SdPj-I.css +32 -0
- package/ui/dist/index.html +2 -2
- package/daemon/assets/plugins/openrig-core/skills/openrig-architect/SKILL.md +0 -361
- package/daemon/assets/plugins/openrig-core/skills/openrig-cmux/SKILL.md +0 -86
- package/daemon/assets/plugins/openrig-core/skills/openrig-herdr/SKILL.md +0 -158
- package/daemon/assets/plugins/openrig-core/skills/openrig-operator/SKILL.md +0 -222
- package/daemon/docs/reference/product-factory-vps-runbook.md +0 -132
- package/daemon/specs/agents/shared/skills/core/mission-slice-sop/SKILL.md +0 -113
- package/daemon/specs/agents/shared/skills/core/openrig-installer/SKILL.md +0 -142
- package/daemon/specs/agents/shared/skills/core/openrig-operator/SKILL.md +0 -110
- package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +0 -1245
- package/daemon/specs/agents/shared/skills/core/openrig-user-settings/SKILL.md +0 -153
- 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 -210
- 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
- package/ui/dist/assets/index-CFqxa0zW.css +0 -32
|
@@ -14,6 +14,70 @@
|
|
|
14
14
|
// event types: read-only projection over existing data + the filesystem.
|
|
15
15
|
import * as fs from "node:fs";
|
|
16
16
|
import * as path from "node:path";
|
|
17
|
+
import { parseScopeTags } from "./qitem-membership.js";
|
|
18
|
+
// --- SQL-LIKE-equivalent matching (qitem-ccf87c0d) -------------------------
|
|
19
|
+
// SQLite LIKE semantics, replicated byte-for-byte (test-pinned):
|
|
20
|
+
// - ASCII-ONLY case folding (A-Z <-> a-z; æ vs Æ do NOT fold),
|
|
21
|
+
// - `%` matches any run and `_` exactly ONE CHARACTER (code point) — both
|
|
22
|
+
// spanning newlines and astral chars (a surrogate pair is one `_`), so
|
|
23
|
+
// the translated regexes MUST compile with the `su` flags
|
|
24
|
+
// (LIKE_REGEXP_FLAGS below): dotAll for newline, `u` for code-point
|
|
25
|
+
// stepping. A [\s\S] translation would count UTF-16 code units and
|
|
26
|
+
// miss e.g. `a😀b` against `%a_b%` (guard blocker pin).
|
|
27
|
+
// - every other byte is literal (regex specials escaped).
|
|
28
|
+
/** The one flag set every translated LIKE regex compiles with. */
|
|
29
|
+
const LIKE_REGEXP_FLAGS = "su";
|
|
30
|
+
/** Lowercase ASCII A-Z only — never Unicode (SQLite LIKE's fold). */
|
|
31
|
+
function asciiFold(s) {
|
|
32
|
+
return s.replace(/[A-Z]/g, (c) => String.fromCharCode(c.charCodeAt(0) + 32));
|
|
33
|
+
}
|
|
34
|
+
/** qitem-18f3300d — SQLite LIKE stops matching at the first raw U+0000 in
|
|
35
|
+
* the haystack (guard-reproduced against the parent per-slice SQL; a NUL
|
|
36
|
+
* is production-reachable via POST /api/queue/create JSON bodies). Apply
|
|
37
|
+
* BEFORE asciiFold/prefilter/confirm so a term occurring only after a NUL
|
|
38
|
+
* never matches, exactly like the parent. */
|
|
39
|
+
function sqliteVisiblePrefix(s) {
|
|
40
|
+
const i = s.indexOf("\u0000");
|
|
41
|
+
return i === -1 ? s : s.slice(0, i);
|
|
42
|
+
}
|
|
43
|
+
/** Translate a run of LIKE-pattern characters (%/_ wildcards, everything
|
|
44
|
+
* else literal with regex specials escaped). No anchors — callers add
|
|
45
|
+
* them only where LIKE full-match semantics diverge from contains. */
|
|
46
|
+
function likePatternBodyToRegExpSource(patternBody) {
|
|
47
|
+
let out = "";
|
|
48
|
+
for (const ch of patternBody) {
|
|
49
|
+
if (ch === "%")
|
|
50
|
+
out += ".*";
|
|
51
|
+
else if (ch === "_")
|
|
52
|
+
out += ".";
|
|
53
|
+
else
|
|
54
|
+
out += ch.replace(/[.*+?^${}()|[\]\\]/, "\\$&");
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
/** qitem-18f3300d pattern-side facet — translate the FULL bound LIKE
|
|
59
|
+
* pattern for one fallback term, exactly as the parent SQL saw it:
|
|
60
|
+
* build `%<term>%` and truncate THE PATTERN at the first U+0000 (SQLite
|
|
61
|
+
* truncates patterns too — a NUL inside the term LOSES the trailing
|
|
62
|
+
* wildcard, leaving an end-anchored `%prefix`).
|
|
63
|
+
* - Untruncated pattern (the overwhelmingly common no-NUL case):
|
|
64
|
+
* `%term%` is exactly a contains-match, so the term translates
|
|
65
|
+
* UNANCHORED — a wildcard-free term compiles to a pure literal, which
|
|
66
|
+
* keeps the combined prefilter alternation on the regex engine's fast
|
|
67
|
+
* literal path (an anchored `^.*x.*$` form measured a ~80x benchmark
|
|
68
|
+
* regression: every non-matching row pays a greedy scan per branch).
|
|
69
|
+
* - Truncated pattern: LIKE full-match semantics now matter (the lost
|
|
70
|
+
* trailing `%` end-anchors the remainder), so translate the truncated
|
|
71
|
+
* pattern verbatim and anchor `^...$`.
|
|
72
|
+
* Compile with LIKE_REGEXP_FLAGS. */
|
|
73
|
+
function likeBoundPatternToRegExpSource(term) {
|
|
74
|
+
const bound = `%${term}%`;
|
|
75
|
+
const pattern = sqliteVisiblePrefix(bound);
|
|
76
|
+
if (pattern === bound) {
|
|
77
|
+
return likePatternBodyToRegExpSource(asciiFold(term));
|
|
78
|
+
}
|
|
79
|
+
return "^" + likePatternBodyToRegExpSource(asciiFold(pattern)) + "$";
|
|
80
|
+
}
|
|
17
81
|
const FRONTMATTER_DELIM = "---";
|
|
18
82
|
const DEFAULT_CACHE_TTL_MS = 60_000;
|
|
19
83
|
const STATUS_TO_BUCKET = {
|
|
@@ -22,6 +86,12 @@ const STATUS_TO_BUCKET = {
|
|
|
22
86
|
ratified: "active",
|
|
23
87
|
"draft-pending-orch-ratification": "draft",
|
|
24
88
|
draft: "draft",
|
|
89
|
+
// VM-005 (release-0.4.7): the scaffold-template frontmatter status TOKEN —
|
|
90
|
+
// a fresh `rig scope` slice is honestly a draft, not active (it previously
|
|
91
|
+
// fell through to mapStatus's terminal default). Distinct grammar from the
|
|
92
|
+
// scaffold-placeholder twin modules, which classify bracket-wrapped body
|
|
93
|
+
// TEXT — a cousin of, not a home for, this frontmatter token literal.
|
|
94
|
+
placeholder: "draft",
|
|
25
95
|
done: "done",
|
|
26
96
|
shipped: "done",
|
|
27
97
|
promoted: "done",
|
|
@@ -42,6 +112,12 @@ export class SliceIndexer {
|
|
|
42
112
|
cacheTtlMs;
|
|
43
113
|
listingCache = null;
|
|
44
114
|
detailCache = new Map();
|
|
115
|
+
// qitem-ccf87c0d — batch membership index (see MembershipIndex doc).
|
|
116
|
+
membershipIndex = null;
|
|
117
|
+
// qitem-ccf87c0d corrective — depth of open withMembershipBatch scopes.
|
|
118
|
+
batchDepth = 0;
|
|
119
|
+
// VM-005: authored mission-status sidecar cache (same TTL as the listing).
|
|
120
|
+
missionStatusCache = null;
|
|
45
121
|
constructor(opts) {
|
|
46
122
|
this.slicesRoot = opts.slicesRoot;
|
|
47
123
|
this.additionalSliceRoots = opts.additionalSliceRoots ?? [];
|
|
@@ -53,10 +129,114 @@ export class SliceIndexer {
|
|
|
53
129
|
isReady() {
|
|
54
130
|
return this.sliceRoots().some((root) => this.isDirectory(root));
|
|
55
131
|
}
|
|
132
|
+
/** qitem-ccf87c0d corrective — the explicit COMPOSITE-OPERATION scope: a
|
|
133
|
+
* caller performing list()-plus-per-slice-get() as ONE user-visible
|
|
134
|
+
* operation (the slices route's boundToWorkflow lens, ReviewGatherer.
|
|
135
|
+
* composeMission) wraps it here so every inner list/get shares ONE
|
|
136
|
+
* membership batch instead of building one per uncached get (the 2+2N
|
|
137
|
+
* regression). Contract, pinned by test:
|
|
138
|
+
* - the OUTERMOST open never reuses a prior operation's batch (drops
|
|
139
|
+
* any existing one); the index is LAZY, so the first membership
|
|
140
|
+
* access inside the scope builds from then-current queue state —
|
|
141
|
+
* request-boundary freshness, no snapshot claim;
|
|
142
|
+
* - nested/reentrant scopes share the outermost batch;
|
|
143
|
+
* - the outermost exit ALWAYS clears (finally — exception-safe), so
|
|
144
|
+
* separate operations never share a generation;
|
|
145
|
+
* - standalone list()/get() outside any scope keep their own
|
|
146
|
+
* one-operation batch semantics unchanged (their clears are
|
|
147
|
+
* conditional on depth === 0).
|
|
148
|
+
* Synchronous by design — matches the synchronous list/get call graph. */
|
|
149
|
+
withMembershipBatch(fn) {
|
|
150
|
+
if (this.batchDepth === 0)
|
|
151
|
+
this.membershipIndex = null;
|
|
152
|
+
this.batchDepth++;
|
|
153
|
+
try {
|
|
154
|
+
return fn();
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
this.batchDepth--;
|
|
158
|
+
if (this.batchDepth === 0)
|
|
159
|
+
this.membershipIndex = null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
56
162
|
/** Drops both caches. Used by tests + by a future explicit-refresh route. */
|
|
57
163
|
invalidate() {
|
|
58
164
|
this.listingCache = null;
|
|
59
165
|
this.detailCache.clear();
|
|
166
|
+
this.missionStatusCache = null;
|
|
167
|
+
this.membershipIndex = null;
|
|
168
|
+
}
|
|
169
|
+
/** VM-005 B1 (the narrow C-vii exception; arch ruling b8d91aee…) — the
|
|
170
|
+
* READ-AFTER-WRITE seam: POST /:missionId/complete writes the mission
|
|
171
|
+
* README status, and the sidecar's 60s TTL would otherwise keep serving
|
|
172
|
+
* the pre-write word to /api/slices while /api/missions/:id reads the
|
|
173
|
+
* new word from disk. This drops the WHOLE missionStatusCache blob and
|
|
174
|
+
* nothing else (listing/detail caches untouched — drop-the-blob, never
|
|
175
|
+
* full-flush: zero coherence gain and a 60s registry churn were the
|
|
176
|
+
* ruling's reasons to reject the alternatives). The sole write path
|
|
177
|
+
* calls it post-success; the next read rebuilds from disk (README =
|
|
178
|
+
* SSOT). Out-of-band file writes remain the TTL regime by design. */
|
|
179
|
+
invalidateMissionStatusCache() {
|
|
180
|
+
this.missionStatusCache = null;
|
|
181
|
+
}
|
|
182
|
+
/** VM-005 (release-0.4.7) — the authored mission-status sidecar for the
|
|
183
|
+
* slices list payload: one mission-README frontmatter read per indexed
|
|
184
|
+
* mission, inside the same 60s cache discipline as the listing. Keys are
|
|
185
|
+
* missions with at least one INDEXED slice (zero-slice missions have no
|
|
186
|
+
* indexed slices and never appear here — the tree's discovery walk owns
|
|
187
|
+
* that population). Read semantics are LOCKSTEP with
|
|
188
|
+
* routes/missions.ts readMissionStatus (README.md only, raw string, no
|
|
189
|
+
* enum validation, non-empty-or-null) — pinned by test. */
|
|
190
|
+
missionAuthoredStatuses() {
|
|
191
|
+
if (!this.isReady())
|
|
192
|
+
return {};
|
|
193
|
+
const now = Date.now();
|
|
194
|
+
if (this.missionStatusCache && this.missionStatusCache.expiresAt > now) {
|
|
195
|
+
return this.missionStatusCache.statuses;
|
|
196
|
+
}
|
|
197
|
+
const indexedMissionIds = new Set();
|
|
198
|
+
for (const entry of this.list()) {
|
|
199
|
+
if (entry.missionId)
|
|
200
|
+
indexedMissionIds.add(entry.missionId);
|
|
201
|
+
}
|
|
202
|
+
const statuses = {};
|
|
203
|
+
for (const root of this.sliceRoots()) {
|
|
204
|
+
let entries;
|
|
205
|
+
try {
|
|
206
|
+
entries = fs.readdirSync(root, { withFileTypes: true });
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
for (const entry of entries) {
|
|
212
|
+
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
213
|
+
continue;
|
|
214
|
+
if (!indexedMissionIds.has(entry.name))
|
|
215
|
+
continue;
|
|
216
|
+
if (entry.name in statuses)
|
|
217
|
+
continue; // first root wins, matching the slice walk
|
|
218
|
+
statuses[entry.name] = {
|
|
219
|
+
authoredStatus: this.readMissionAuthoredStatus(path.join(root, entry.name)),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
this.missionStatusCache = { statuses, expiresAt: now + this.cacheTtlMs };
|
|
224
|
+
return statuses;
|
|
225
|
+
}
|
|
226
|
+
/** Lockstep twin of routes/missions.ts readMissionStatus (see the sidecar
|
|
227
|
+
* doc above; the lockstep test pins both reads agree on the same bytes). */
|
|
228
|
+
readMissionAuthoredStatus(missionPath) {
|
|
229
|
+
const readmePath = path.join(missionPath, "README.md");
|
|
230
|
+
let raw;
|
|
231
|
+
try {
|
|
232
|
+
raw = fs.readFileSync(readmePath, "utf8");
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
const fm = parseFrontmatter(raw);
|
|
238
|
+
const value = fm["status"];
|
|
239
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
60
240
|
}
|
|
61
241
|
list() {
|
|
62
242
|
if (!this.isReady())
|
|
@@ -66,7 +246,19 @@ export class SliceIndexer {
|
|
|
66
246
|
return this.listingCache.entries;
|
|
67
247
|
}
|
|
68
248
|
const locations = this.readSliceLocations();
|
|
69
|
-
|
|
249
|
+
// ONE batch membership index serves this whole rebuild (the <=4 LIKE-
|
|
250
|
+
// execution load contract), then drops so later uncached operations
|
|
251
|
+
// read current queue state (qitem-18f3300d operation scoping) — unless
|
|
252
|
+
// an enclosing withMembershipBatch scope owns the batch lifetime.
|
|
253
|
+
let entries;
|
|
254
|
+
try {
|
|
255
|
+
// list() answers every location: served = ALL (null).
|
|
256
|
+
entries = locations.map((location) => this.toListEntry(location, null));
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
if (this.batchDepth === 0)
|
|
260
|
+
this.membershipIndex = null;
|
|
261
|
+
}
|
|
70
262
|
this.listingCache = { entries, expiresAt: now + this.cacheTtlMs };
|
|
71
263
|
return entries;
|
|
72
264
|
}
|
|
@@ -81,7 +273,20 @@ export class SliceIndexer {
|
|
|
81
273
|
const location = this.findSliceLocation(name);
|
|
82
274
|
if (!location)
|
|
83
275
|
return null;
|
|
84
|
-
|
|
276
|
+
// Uncached get(): its own operation-scoped batch, dropped afterward so
|
|
277
|
+
// the next uncached operation sees current queue state (qitem-18f3300d)
|
|
278
|
+
// — unless an enclosing withMembershipBatch scope owns the batch lifetime.
|
|
279
|
+
let record;
|
|
280
|
+
try {
|
|
281
|
+
// A standalone uncached get() answers exactly ONE slice, so it serves
|
|
282
|
+
// {name}; inside an open withMembershipBatch scope the operation is
|
|
283
|
+
// composite and serves ALL (null).
|
|
284
|
+
record = this.buildRecord(location, this.batchDepth > 0 ? null : new Set([name]));
|
|
285
|
+
}
|
|
286
|
+
finally {
|
|
287
|
+
if (this.batchDepth === 0)
|
|
288
|
+
this.membershipIndex = null;
|
|
289
|
+
}
|
|
85
290
|
this.detailCache.set(name, { record, expiresAt: now + this.cacheTtlMs });
|
|
86
291
|
return record;
|
|
87
292
|
}
|
|
@@ -160,12 +365,12 @@ export class SliceIndexer {
|
|
|
160
365
|
}
|
|
161
366
|
return out;
|
|
162
367
|
}
|
|
163
|
-
toListEntry(location) {
|
|
368
|
+
toListEntry(location, served) {
|
|
164
369
|
const { name, missionId, slicePath } = location;
|
|
165
370
|
const frontmatter = this.readPrimaryFrontmatter(slicePath);
|
|
166
371
|
const status = this.mapStatus(frontmatter["status"]);
|
|
167
372
|
const railItem = this.extractRailItem(frontmatter, missionId);
|
|
168
|
-
const qitemIds = this.matchQitems(name,
|
|
373
|
+
const qitemIds = this.matchQitems(name, served);
|
|
169
374
|
const proofPacket = this.findProofPacket(name);
|
|
170
375
|
const lastActivityAt = this.computeLastActivity(slicePath, qitemIds, proofPacket);
|
|
171
376
|
return {
|
|
@@ -188,12 +393,12 @@ export class SliceIndexer {
|
|
|
188
393
|
slicePath,
|
|
189
394
|
};
|
|
190
395
|
}
|
|
191
|
-
buildRecord(location) {
|
|
396
|
+
buildRecord(location, served) {
|
|
192
397
|
const { name, missionId, slicePath } = location;
|
|
193
398
|
const frontmatter = this.readPrimaryFrontmatter(slicePath);
|
|
194
399
|
const status = this.mapStatus(frontmatter["status"]);
|
|
195
400
|
const railItem = this.extractRailItem(frontmatter, missionId);
|
|
196
|
-
const qitemIds = this.matchQitems(name,
|
|
401
|
+
const qitemIds = this.matchQitems(name, served);
|
|
197
402
|
const proofPacket = this.findProofPacket(name);
|
|
198
403
|
const lastActivityAt = this.computeLastActivity(slicePath, qitemIds, proofPacket);
|
|
199
404
|
const commitRefs = this.extractCommitRefs(frontmatter);
|
|
@@ -267,6 +472,9 @@ export class SliceIndexer {
|
|
|
267
472
|
return fallback;
|
|
268
473
|
}
|
|
269
474
|
extractRailItem(frontmatter, missionId) {
|
|
475
|
+
return this.extractExplicitRailItem(frontmatter) ?? missionId;
|
|
476
|
+
}
|
|
477
|
+
extractExplicitRailItem(frontmatter) {
|
|
270
478
|
const raw = frontmatter["rail-item"];
|
|
271
479
|
if (typeof raw === "string") {
|
|
272
480
|
// Strip array brackets if YAML parser dropped them as a string ("[PL-008]").
|
|
@@ -284,7 +492,7 @@ export class SliceIndexer {
|
|
|
284
492
|
}
|
|
285
493
|
if (Array.isArray(related) && related.length > 0 && typeof related[0] === "string")
|
|
286
494
|
return related[0];
|
|
287
|
-
return
|
|
495
|
+
return null;
|
|
288
496
|
}
|
|
289
497
|
extractCommitRefs(frontmatter) {
|
|
290
498
|
const refs = [];
|
|
@@ -316,7 +524,7 @@ export class SliceIndexer {
|
|
|
316
524
|
return "draft";
|
|
317
525
|
return "active";
|
|
318
526
|
}
|
|
319
|
-
matchQitems(sliceName,
|
|
527
|
+
matchQitems(sliceName, served) {
|
|
320
528
|
// V0.3.1 slice 17 founder-walk-workspace-state-correctness (walk item 3): the previous implementation unioned substring matches on
|
|
321
529
|
// [sliceName, railItem, missionId]. The missionId term over-matched
|
|
322
530
|
// — every qitem tagged `mission:<id>` appeared under EVERY slice in
|
|
@@ -326,49 +534,49 @@ export class SliceIndexer {
|
|
|
326
534
|
// Substring fallback (including the missionId term) is preserved for
|
|
327
535
|
// slices whose qitem corpus pre-dates the typed-tag convention so
|
|
328
536
|
// legacy mission-aware workspaces don't regress.
|
|
537
|
+
// qitem-ccf87c0d — both tiers now answer from the per-generation batch
|
|
538
|
+
// membership index (TWO scans per generation instead of O(slices) scans;
|
|
539
|
+
// see ensureMembershipIndex). TWO-TIER DOCTRINE unchanged: the SIGNAL
|
|
540
|
+
// tier answers from canonical typed membership ONLY; this DISPLAY tier
|
|
541
|
+
// carries the gated legacy substring fallback. Never promote a
|
|
542
|
+
// display-tier match into a signal. (P3)
|
|
329
543
|
const ids = new Set();
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
for (const r of rows)
|
|
338
|
-
ids.add(r.qitem_id);
|
|
339
|
-
typedTagMatchCount = rows.length;
|
|
544
|
+
{
|
|
545
|
+
let index = this.ensureMembershipIndex(served);
|
|
546
|
+
if (!index.knownSlices.has(sliceName)) {
|
|
547
|
+
// Folder created mid-generation: rebuild so the fresh slice resolves
|
|
548
|
+
// membership immediately (parity with the old per-slice queries).
|
|
549
|
+
this.membershipIndex = null;
|
|
550
|
+
index = this.ensureMembershipIndex(served);
|
|
340
551
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
552
|
+
// 1. Typed-tag matches (VM-004 authoritative): confirmed rows for this
|
|
553
|
+
// slice, in ts_created DESC/qitem_id DESC scan order, capped at 500
|
|
554
|
+
// confirmed per slice by the builder.
|
|
555
|
+
const typed = index.typedBySlice.get(sliceName);
|
|
556
|
+
if (typed && typed.length > 0) {
|
|
557
|
+
for (const id of typed)
|
|
558
|
+
ids.add(id);
|
|
344
559
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
try {
|
|
357
|
-
const rows = this.db.prepare(`SELECT qitem_id FROM queue_items WHERE body LIKE ? OR tags LIKE ? LIMIT 500`).all(`%${term}%`, `%${term}%`);
|
|
358
|
-
for (const r of rows)
|
|
359
|
-
ids.add(r.qitem_id);
|
|
360
|
-
}
|
|
361
|
-
catch {
|
|
362
|
-
const rows = this.db.prepare(`SELECT qitem_id FROM queue_items WHERE body LIKE ? LIMIT 500`).all(`%${term}%`);
|
|
363
|
-
for (const r of rows)
|
|
364
|
-
ids.add(r.qitem_id);
|
|
560
|
+
else {
|
|
561
|
+
// 2. Substring fallback — executes ONLY when zero CONFIRMED typed
|
|
562
|
+
// rows exist (the deliberate VM-004 gating). The builder records the
|
|
563
|
+
// exact per-slice eligible terms after it knows whether this mission
|
|
564
|
+
// has adopted typed membership. Term-first assembly preserves the
|
|
565
|
+
// original stable ordering/caps for every eligible term.
|
|
566
|
+
for (const term of index.fallbackTermsBySlice.get(sliceName) ?? []) {
|
|
567
|
+
const bucket = index.fallbackByTerm.get(term);
|
|
568
|
+
if (bucket)
|
|
569
|
+
for (const id of bucket)
|
|
570
|
+
ids.add(id);
|
|
365
571
|
}
|
|
366
572
|
}
|
|
367
573
|
}
|
|
368
|
-
catch
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
574
|
+
// qitem-18110994 (item 2) — the broad catch that used to wrap this block
|
|
575
|
+
// is REMOVED. It existed for "queue_items table absent", which the schema
|
|
576
|
+
// probe in ensureMembershipIndex now answers structurally. Left in place
|
|
577
|
+
// it would re-swallow a REFUSED build and cache the refusal as an empty
|
|
578
|
+
// detail, defeating the propagation contract: a genuine scan fault must
|
|
579
|
+
// reach the caller, not masquerade as a slice with no membership.
|
|
372
580
|
// V0.3.1 slice 17 walk item 10 — forward-fix #1. Sort qitemIds DESC
|
|
373
581
|
// by ts_created so the slice-detail Queue tab renders newest first
|
|
374
582
|
// (HG-5). The ScopePages.ScopeQueueRollup frontend sort still runs
|
|
@@ -402,6 +610,175 @@ export class SliceIndexer {
|
|
|
402
610
|
}
|
|
403
611
|
return idsArr;
|
|
404
612
|
}
|
|
613
|
+
/** qitem-ccf87c0d — build (or reuse) the per-generation membership index.
|
|
614
|
+
* TWO queue_items scans per generation, replacing O(slices) per-slice
|
|
615
|
+
* scans.
|
|
616
|
+
*
|
|
617
|
+
* SCHEMA IS INSPECTED UP FRONT (qitem-18110994), never inferred from a
|
|
618
|
+
* swallowed error:
|
|
619
|
+
* - queue_items absent -> a structurally EMPTY index that is still
|
|
620
|
+
* PUBLISHED with its location metadata (knownSlices/terms), so get/list
|
|
621
|
+
* keep their semantics and no rebuild loop occurs;
|
|
622
|
+
* - tags column absent -> the typed scan is SKIPPED and Scan 2 uses the
|
|
623
|
+
* body-only query shape;
|
|
624
|
+
* - any PRAGMA / typed / fallback EXECUTION failure PROPAGATES to the
|
|
625
|
+
* caller and NOTHING is published (buckets accumulate locally and are
|
|
626
|
+
* published only on full success), so an interrupted build can never be
|
|
627
|
+
* cached as a plausible-but-incomplete answer.
|
|
628
|
+
*
|
|
629
|
+
* Scan 1 (typed): `tags LIKE '%slice:%'` prefilter, ORDER BY ts_created
|
|
630
|
+
* DESC, qitem_id DESC (P2 determinism preserved), parseScopeTags as the
|
|
631
|
+
* authoritative row-level confirm; a row credits EVERY slice it tags;
|
|
632
|
+
* cap after 500 CONFIRMED per slice (never a pre-confirmation LIMIT —
|
|
633
|
+
* the B2/VM-004 rule). Global: every location, regardless of `served`.
|
|
634
|
+
* Scan 2 (fallback): one streamed pass over (body, tags) evaluated
|
|
635
|
+
* against the term universe of the SERVED zero-typed locations — all of
|
|
636
|
+
* them for list() and any open withMembershipBatch scope, exactly one
|
|
637
|
+
* for a standalone uncached get(). A combined regex is a PREFILTER
|
|
638
|
+
* only; every term is then confirmed per row so overlapping terms all
|
|
639
|
+
* credit (no consuming-alternation loss). Terms use SQL-LIKE-equivalent
|
|
640
|
+
* matching (asciiFold + %/_ translation); bucket order is row (rowid)
|
|
641
|
+
* order — the same order the un-ORDERed per-term `LIMIT 500` queries
|
|
642
|
+
* returned; cap 500 per term.
|
|
643
|
+
*
|
|
644
|
+
* `served` (qitem-18110994 item 1) is the EXPLICIT scope of the current
|
|
645
|
+
* public operation — the slice names actually being answered, or null for
|
|
646
|
+
* "all known locations" — threaded through the call chain (get/list ->
|
|
647
|
+
* buildRecord/toListEntry -> matchQitems -> here), never ambient state. It
|
|
648
|
+
* narrows FRONTMATTER READS ONLY: locations, knownSlices, the typed scan
|
|
649
|
+
* and the all-location typedMissions verdict are established FIRST, so the
|
|
650
|
+
* cross-slice modern/legacy rule stays byte-identical (R5 differential). */
|
|
651
|
+
ensureMembershipIndex(served) {
|
|
652
|
+
// qitem-18f3300d — OPERATION-scoped, never TTL-scoped: the index lives
|
|
653
|
+
// only for the duration of one public cold list() or one uncached
|
|
654
|
+
// get() (the public entry points clear it), so separate uncached
|
|
655
|
+
// operations always see current queue state — parent-equivalent
|
|
656
|
+
// freshness — while one cold list still shares one batch.
|
|
657
|
+
if (this.membershipIndex) {
|
|
658
|
+
return this.membershipIndex;
|
|
659
|
+
}
|
|
660
|
+
const typedBySlice = new Map();
|
|
661
|
+
const fallbackTermsBySlice = new Map();
|
|
662
|
+
const fallbackByTerm = new Map();
|
|
663
|
+
const knownSlices = new Set();
|
|
664
|
+
// qitem-18110994 (items 2+4) — SCHEMA TRUTH UP FRONT. The queue_items
|
|
665
|
+
// shape is INSPECTED, never inferred from a swallowed scan error: a
|
|
666
|
+
// failing scan used to be recorded as "tags column missing", silently
|
|
667
|
+
// degrading membership under a false structural label. PRAGMA answers
|
|
668
|
+
// the structural question; every EXECUTION failure below then propagates.
|
|
669
|
+
const columns = this.db.prepare(`PRAGMA table_info(queue_items)`).all();
|
|
670
|
+
// Zero columns is the ONE structural degradation: the table does not
|
|
671
|
+
// exist (a harness without the migration). Membership is structurally
|
|
672
|
+
// empty — but the index is still PUBLISHED with its location metadata so
|
|
673
|
+
// get/list keep today's semantics and no rebuild loop occurs.
|
|
674
|
+
const tableAbsent = columns.length === 0;
|
|
675
|
+
const tagsColumnPresent = columns.some((c) => c.name === "tags");
|
|
676
|
+
// GLOBAL facts first — locations and knownSlices are cheap (a directory
|
|
677
|
+
// walk, no file reads) and must cover EVERY location regardless of scope:
|
|
678
|
+
// the typed scan and the mission-level verdict below depend on them.
|
|
679
|
+
const locations = this.readSliceLocations();
|
|
680
|
+
for (const location of locations)
|
|
681
|
+
knownSlices.add(location.name);
|
|
682
|
+
// Scan 1 — typed membership. Runs ONLY when the schema probe found the
|
|
683
|
+
// tags column; its absence is structural and skips the scan (no catch
|
|
684
|
+
// needed to discover it). An EXECUTION failure here propagates: it is a
|
|
685
|
+
// real fault, not a shape fact, and must not be laundered into a
|
|
686
|
+
// "tags column missing" degrade nor allow a later fallback scan.
|
|
687
|
+
if (!tableAbsent && tagsColumnPresent) {
|
|
688
|
+
const stmt = this.db.prepare(`SELECT qitem_id, tags FROM queue_items WHERE tags LIKE '%slice:%' ORDER BY ts_created DESC, qitem_id DESC`);
|
|
689
|
+
for (const r of stmt.iterate()) {
|
|
690
|
+
for (const tagged of parseScopeTags(r.tags).slices) {
|
|
691
|
+
const bucket = typedBySlice.get(tagged);
|
|
692
|
+
if (!bucket)
|
|
693
|
+
typedBySlice.set(tagged, [r.qitem_id]);
|
|
694
|
+
else if (bucket.length < 500)
|
|
695
|
+
bucket.push(r.qitem_id);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
// Scan 2 — fallback buckets for the zero-typed slices' eligible term
|
|
700
|
+
// universe. A typed sibling marks a mission modern: its zero-typed slices
|
|
701
|
+
// retain their own name and any explicitly authored rail, but omit both
|
|
702
|
+
// missionId and a rail value merely defaulted from missionId. Legacy
|
|
703
|
+
// missions with no typed slice preserve the complete old term order.
|
|
704
|
+
const typedMissions = new Set();
|
|
705
|
+
for (const location of locations) {
|
|
706
|
+
if (location.missionId && (typedBySlice.get(location.name)?.length ?? 0) > 0) {
|
|
707
|
+
typedMissions.add(location.missionId);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
// qitem-18110994 (item 1) — frontmatter is read HERE and only here, and
|
|
711
|
+
// only for locations that can actually consult fallback terms: those the
|
|
712
|
+
// current operation SERVES and that have no confirmed typed membership.
|
|
713
|
+
// A served slice with typed rows returns from typedBySlice and never
|
|
714
|
+
// touches these terms, so it needs no membership frontmatter at all.
|
|
715
|
+
// Everything the eligibility rule depends on (locations, typedBySlice,
|
|
716
|
+
// typedMissions over ALL locations) is already fixed above, so narrowing
|
|
717
|
+
// these reads cannot move the modern/legacy verdict.
|
|
718
|
+
//
|
|
719
|
+
// The authored/default rail distinction is drawn HERE, where the terms are
|
|
720
|
+
// built: it matters only for modern missions, because a default-derived
|
|
721
|
+
// rail IS the mission id and must not reintroduce the mission-wide
|
|
722
|
+
// fallback that typed sibling membership disables.
|
|
723
|
+
const fallbackTerms = new Set();
|
|
724
|
+
for (const location of locations) {
|
|
725
|
+
const slice = location.name;
|
|
726
|
+
if (served !== null && !served.has(slice))
|
|
727
|
+
continue;
|
|
728
|
+
const typed = typedBySlice.get(slice);
|
|
729
|
+
if (typed && typed.length > 0)
|
|
730
|
+
continue;
|
|
731
|
+
const frontmatter = this.readPrimaryFrontmatter(location.slicePath);
|
|
732
|
+
const railItem = this.extractRailItem(frontmatter, location.missionId);
|
|
733
|
+
const explicitRailItem = this.extractExplicitRailItem(frontmatter);
|
|
734
|
+
const modernMission = location.missionId !== null && typedMissions.has(location.missionId);
|
|
735
|
+
const terms = Array.from(new Set([
|
|
736
|
+
slice,
|
|
737
|
+
modernMission ? explicitRailItem : railItem,
|
|
738
|
+
modernMission ? null : location.missionId,
|
|
739
|
+
].filter((v) => !!v)));
|
|
740
|
+
fallbackTermsBySlice.set(slice, terms);
|
|
741
|
+
for (const term of terms)
|
|
742
|
+
fallbackTerms.add(term);
|
|
743
|
+
}
|
|
744
|
+
if (!tableAbsent && fallbackTerms.size > 0) {
|
|
745
|
+
const termList = Array.from(fallbackTerms);
|
|
746
|
+
const matchers = termList.map((term) => ({
|
|
747
|
+
term,
|
|
748
|
+
re: new RegExp(likeBoundPatternToRegExpSource(term), LIKE_REGEXP_FLAGS),
|
|
749
|
+
}));
|
|
750
|
+
const prefilter = new RegExp(matchers.map((m) => `(?:${m.re.source})`).join("|"), LIKE_REGEXP_FLAGS);
|
|
751
|
+
// qitem-18110994 (item 2) — buckets accumulate LOCALLY and are published
|
|
752
|
+
// to the index only after the scan completes. Previously they were
|
|
753
|
+
// pre-seeded on the published map and a broad catch let a partially
|
|
754
|
+
// filled result be cached as authoritative: an interrupted build served
|
|
755
|
+
// a plausible-but-incomplete membership. An execution failure now
|
|
756
|
+
// propagates and NOTHING is published.
|
|
757
|
+
const localBuckets = new Map();
|
|
758
|
+
for (const term of termList)
|
|
759
|
+
localBuckets.set(term, []);
|
|
760
|
+
const scan = tagsColumnPresent
|
|
761
|
+
? this.db.prepare(`SELECT qitem_id, body, tags FROM queue_items`)
|
|
762
|
+
: this.db.prepare(`SELECT qitem_id, body FROM queue_items`);
|
|
763
|
+
for (const r of scan.iterate()) {
|
|
764
|
+
const hayBody = asciiFold(sqliteVisiblePrefix(r.body));
|
|
765
|
+
const hayTags = r.tags != null ? asciiFold(sqliteVisiblePrefix(r.tags)) : null;
|
|
766
|
+
if (!prefilter.test(hayBody) && !(hayTags !== null && prefilter.test(hayTags)))
|
|
767
|
+
continue;
|
|
768
|
+
for (const m of matchers) {
|
|
769
|
+
if (m.re.test(hayBody) || (hayTags !== null && m.re.test(hayTags))) {
|
|
770
|
+
const bucket = localBuckets.get(m.term);
|
|
771
|
+
if (bucket.length < 500)
|
|
772
|
+
bucket.push(r.qitem_id);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
for (const [term, ids] of localBuckets)
|
|
777
|
+
fallbackByTerm.set(term, ids);
|
|
778
|
+
}
|
|
779
|
+
this.membershipIndex = { typedBySlice, fallbackTermsBySlice, fallbackByTerm, knownSlices };
|
|
780
|
+
return this.membershipIndex;
|
|
781
|
+
}
|
|
405
782
|
findProofPacket(sliceName) {
|
|
406
783
|
if (!this.dogfoodEvidenceRoot)
|
|
407
784
|
return null;
|