zob-harness 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/.pi/capabilities/zob-public-runtime-capabilities.json +20 -1
  2. package/.pi/extensions/zob-harness/index.ts +226 -1
  3. package/.pi/extensions/zob-harness/src/core/artifact-roots.ts +55 -0
  4. package/.pi/extensions/zob-harness/src/core/constants.ts +6 -5
  5. package/.pi/extensions/zob-harness/src/domains/autonomy/autonomous-runtime/report-writers.ts +42 -41
  6. package/.pi/extensions/zob-harness/src/domains/coms/coms-v2/transcript-capture.ts +2 -1
  7. package/.pi/extensions/zob-harness/src/domains/coms/mission-control.ts +10 -7
  8. package/.pi/extensions/zob-harness/src/domains/environment/AGENTS.md +62 -0
  9. package/.pi/extensions/zob-harness/src/domains/environment/auto-resolve.ts +408 -0
  10. package/.pi/extensions/zob-harness/src/domains/environment/environment-contract.ts +104 -0
  11. package/.pi/extensions/zob-harness/src/domains/environment/launch-gate.ts +158 -0
  12. package/.pi/extensions/zob-harness/src/domains/environment/primitives.ts +134 -0
  13. package/.pi/extensions/zob-harness/src/domains/environment/types.ts +90 -0
  14. package/.pi/extensions/zob-harness/src/domains/factory/run.ts +2 -1
  15. package/.pi/extensions/zob-harness/src/domains/plan/plan-todos.ts +2 -1
  16. package/.pi/extensions/zob-harness/src/domains/project-dna/project-dna.ts +2 -2
  17. package/.pi/extensions/zob-harness/src/domains/worklist/AGENTS.md +73 -0
  18. package/.pi/extensions/zob-harness/src/domains/worklist/dag.ts +495 -0
  19. package/.pi/extensions/zob-harness/src/domains/worklist/delivery.ts +451 -0
  20. package/.pi/extensions/zob-harness/src/domains/worklist/evidence-contract.ts +188 -0
  21. package/.pi/extensions/zob-harness/src/domains/worklist/reducer-contract.ts +193 -0
  22. package/.pi/extensions/zob-harness/src/domains/worklist/store.ts +534 -0
  23. package/.pi/extensions/zob-harness/src/domains/worklist/types.ts +203 -0
  24. package/.pi/extensions/zob-harness/src/domains/worklist/watchdog.ts +477 -0
  25. package/.pi/extensions/zob-harness/src/runtime/commands/misc.ts +50 -1
  26. package/.pi/extensions/zob-harness/src/runtime/commands/plans.ts +12 -5
  27. package/.pi/extensions/zob-harness/src/runtime/delegation-feed.ts +6 -2
  28. package/.pi/extensions/zob-harness/src/runtime/delegation-monitor.ts +29 -1
  29. package/.pi/extensions/zob-harness/src/runtime/delegation-overlay.ts +5 -3
  30. package/.pi/extensions/zob-harness/src/runtime/events.ts +41 -0
  31. package/.pi/extensions/zob-harness/src/runtime/plan-capture.ts +34 -12
  32. package/.pi/extensions/zob-harness/src/runtime/plan-launch.ts +79 -9
  33. package/.pi/extensions/zob-harness/src/runtime/schemas.ts +40 -0
  34. package/.pi/extensions/zob-harness/src/runtime/state.ts +3 -0
  35. package/.pi/extensions/zob-harness/src/runtime/stop-restore.ts +144 -0
  36. package/.pi/extensions/zob-harness/src/runtime/tools-delegation/helpers.ts +23 -3
  37. package/.pi/extensions/zob-harness/src/runtime/tools-delegation/register.ts +34 -11
  38. package/.pi/extensions/zob-harness/src/runtime/tools-plan.ts +9 -7
  39. package/.pi/extensions/zob-harness/src/runtime/tools-worklist.ts +365 -0
  40. package/.pi/extensions/zob-harness/src/runtime/zobHarness.ts +3 -0
  41. package/.pi/extensions/zob-harness/src/types.ts +1 -0
  42. package/.pi/skills/zob-tool-router/SKILL.md +1 -0
  43. package/.pi/skills/zob-worklist/SKILL.md +52 -0
  44. package/AGENTS.md +1 -0
  45. package/README.md +2 -2
  46. package/SOURCE_INDEX.md +3 -3
  47. package/package.json +27 -25
  48. package/scripts/agentic-spec-team/validate-bdd.mjs +1 -1
  49. package/scripts/agentic-spec-team/validate-final-report.mjs +1 -1
  50. package/scripts/agentic-spec-team/validate-manifest.mjs +1 -1
  51. package/scripts/agentic-spec-team/validate-question-loop.mjs +1 -1
  52. package/scripts/agentic-spec-team/validate-source-register.mjs +1 -1
  53. package/scripts/agentic-spec-team/validate-traceability.mjs +1 -1
  54. package/scripts/agentic-spec-team/validate-workgraph.mjs +1 -1
  55. package/scripts/harness-intake/lib/cli-io.mjs +3 -3
  56. package/scripts/harness-intake/lib/constants.mjs +2 -1
  57. package/scripts/harness-intake/lib.mjs +1 -1
  58. package/scripts/package-surface/validate-script-refs.mjs +87 -0
  59. package/scripts/project-dna/emit/emit-golden-cases.mjs +1 -1
  60. package/scripts/project-dna/emit/emit-ontology.mjs +1 -1
  61. package/scripts/project-dna/sample/generate-sample.mjs +2 -2
  62. package/scripts/project-dna/scan/scan.mjs +1 -1
  63. package/scripts/project-dna/workflow/plan-workflow.mjs +3 -3
  64. package/scripts/project-dna/workflow/validate-workflow.mjs +2 -2
  65. package/scripts/spec-run.mjs +10 -3
  66. package/scripts/worklist/static-smoke.mjs +30 -0
@@ -338,7 +338,7 @@
338
338
  ".pi/extensions/zob-harness/src/AGENTS.md",
339
339
  "AGENTS.md"
340
340
  ],
341
- "noShipNotes": "Launches a saved plan TODO sidecar into runtime goal/TODO metadata; does not edit source files and must not recreate TODOs from prose. Blocks on active-goal/relaunch conflicts unless explicitly gated."
341
+ "noShipNotes": "Launches a saved plan TODO sidecar into runtime goal/TODO metadata; does not edit source files and must not recreate TODOs from prose. Safely auto-attaches to a non-complete active goal by default, remains idempotent for the same launched goal, and blocks true relaunch conflicts unless explicitly gated."
342
342
  },
343
343
  {
344
344
  "name": "create_goal",
@@ -972,6 +972,25 @@
972
972
  ],
973
973
  "noShipNotes": "Lists metadata-only merge queue; no raw diffs or source writes."
974
974
  },
975
+ {
976
+ "name": "zob_worklist",
977
+ "family": "worklist",
978
+ "modes": [
979
+ "plan",
980
+ "implement",
981
+ "factory",
982
+ "orchestrator"
983
+ ],
984
+ "skillRefs": [
985
+ ".pi/skills/zob-worklist/SKILL.md",
986
+ ".pi/skills/zob-coms-safety/SKILL.md"
987
+ ],
988
+ "docRefs": [
989
+ ".pi/extensions/zob-harness/src/domains/worklist/AGENTS.md",
990
+ ".pi/extensions/zob-harness/src/AGENTS.md"
991
+ ],
992
+ "noShipNotes": "Append-only metadata-only/body-free/network-disabled worklist blackboard; claim/satisfy by content hash (lease-gated, idempotent); observe is true only when no directive is open; never stores raw bodies or dispatches live transport."
993
+ },
975
994
  {
976
995
  "name": "zob_coms_readiness",
977
996
  "family": "mission-control",
@@ -46,12 +46,14 @@ export type { ZobModeIntent, ZobModeIntentConfidence, ZobModeIntentRisk, ZobMode
46
46
  export { capturePlanArtifact, extractPlanTitle, listCapturedPlanEntries, shouldCapturePlanResponse, updateCapturedPlanEntry } from "./src/runtime/plan-capture.js";
47
47
  export type { PlanCaptureInput, PlanCaptureResult, PlanIndexEntry } from "./src/runtime/plan-capture.js";
48
48
  export { launchCapturedPlan, previewCapturedPlanLaunch, resolveCapturedPlanForLaunch } from "./src/runtime/plan-launch.js";
49
- export type { PlanLaunchInput, PlanLaunchResult, PlanLaunchSelector } from "./src/runtime/plan-launch.js";
49
+ export type { PlanActiveGoalStrategy, PlanLaunchInput, PlanLaunchResult, PlanLaunchSelector } from "./src/runtime/plan-launch.js";
50
50
  export { PLAN_TODOS_BLOCK_END, PLAN_TODOS_BLOCK_START, PLAN_TODOS_CANONICAL_SCHEMA, PLAN_TODOS_DISPLAY_CARD_END, PLAN_TODOS_DISPLAY_CARD_START, PLAN_TODOS_INPUT_SCHEMA, PLAN_TODOS_SIDECAR_SCHEMA, buildPlanTodoSidecar, canonicalManifestHash, compileMarkdownPlanTodoManifest, extractAndNormalizePlanTodoManifest, extractPlanTodosJson, formatPlanTodoManifestDisplayCard, formatPlanTodoManifestTree, normalizePlanTodoManifest, planTodoSidecarRelativePath, readPlanTodoSidecar, redactPlanTodosBlockForDisplay, validatePlanTodoSidecar, writePlanTodoSidecar } from "./src/domains/plan/plan-todos.js";
51
51
  export type { PlanLaunchStatus, PlanTodoCanonicalItem, PlanTodoCanonicalManifest, PlanTodoDisplayCardOptions, PlanTodoDisplayRedactionResult, PlanTodoManifestQuality, PlanTodoManifestResult, PlanTodoManifestSource, PlanTodoSidecar } from "./src/domains/plan/plan-todos.js";
52
52
  export { ZOB_COMPACTION_CONTINUITY_CONTRACT, ZOB_TOOL_ROUTING_CONTRACT } from "./src/core/constants.js";
53
53
  export { ZOB_COMPACTION_DETAILS_SCHEMA, ZOB_COMPACTION_ENTRY_TYPE, ZOB_COMPACTION_HARD_CAP_TOKENS, ZOB_COMPACTION_LEDGER_SCHEMA, ZOB_COMPACTION_SUMMARY_SCHEMA, ZOB_COMPACTION_TARGET_TOKENS, buildDeterministicZobCompactionResult, buildDeterministicZobCompactionSummary, buildZobCompactionDetails, buildZobCompactionInstructions, buildZobCompactionLedgerEntry, buildZobCompactionStateCapsule, withZobCompactionDetails, zobCompactionBodyFreeViolations } from "./src/runtime/compaction-policy.js";
54
54
  export type { ZobCompactionDetails, ZobCompactionFileRefsInput, ZobCompactionInstructionInput, ZobCompactionLedgerEntry, ZobCompactionStateCapsule } from "./src/runtime/compaction-policy.js";
55
+ export { assistantMessageHasVisibleOutput, createStopRestoreCandidate, findStopRestoreUserEntryId, markStopRestoreAssistantMessage, markStopRestoreRestored, markStopRestoreToolVisible, shouldRestoreStopPrompt } from "./src/runtime/stop-restore.js";
56
+ export type { StopRestoreCandidate, StopRestoreCandidateInput, StopRestoreDecision, StopRestoreDecisionInput, StopRestoreRewindResult } from "./src/runtime/stop-restore.js";
55
57
  export { isAdaptiveZmodeAlias, renderAdaptiveZmodeTemplate, resolveAdaptiveZmodeEntrypoint, validateAdaptiveZmodeEntrypoint } from "./src/runtime/adaptive-zmode.js";
56
58
  export type { AdaptiveZmodeAlias, AdaptiveZmodeEntrypoint } from "./src/runtime/adaptive-zmode.js";
57
59
  export {
@@ -127,6 +129,229 @@ export { createWorkerPoolOwnerDecision, createWorkerPoolOwnerRequest, createWork
127
129
  export type { WorkerPoolAssignmentInput, WorkerPoolAssignmentRecord, WorkerPoolCommunicationPolicyInput, WorkerPoolCommunicationPolicyMode, WorkerPoolCommunicationPolicyRecord, WorkerPoolConflictRecord, WorkerPoolDecision, WorkerPoolOwnerDecisionInput, WorkerPoolOwnerDecisionRecord, WorkerPoolOwnerRequestInput, WorkerPoolOwnerRequestRecord, WorkerPoolPlanInput, WorkerPoolPlanRecord, WorkerPoolStatusInput } from "./src/domains/governance/worker-pool.js";
128
130
  export { decideMergeCandidate, isMergeCandidateRecord, isMergeDecisionRecord, listMergeQueue, mergeQueueBodyFreeViolations, submitMergeCandidate } from "./src/domains/governance/merge-queue.js";
129
131
  export type { MergeCandidateInput, MergeCandidatePriority, MergeCandidateRecord, MergeCandidateRisk, MergeDecision, MergeDecisionInput, MergeDecisionRecord, MergeQueueListInput } from "./src/domains/governance/merge-queue.js";
132
+ export {
133
+ GENERIC_WORKLIST_REDUCER_ID,
134
+ buildDirective,
135
+ evaluateEvidenceForDirective,
136
+ genericWorklistReducer,
137
+ listWorklistReducerIds,
138
+ registerWorklistReducer,
139
+ resolveWorklistReducer,
140
+ } from "./src/domains/worklist/reducer-contract.js";
141
+ export type { BuildDirectiveInput, WorklistReducer } from "./src/domains/worklist/reducer-contract.js";
142
+ // WS-EH1: the typed evidence pillar (canonical-evidence-model PART II). The
143
+ // EvidenceContract + registry + shapes + body-free validator. Backward compatible
144
+ // (WorklistDeps.evidence is now EvidenceInput with optional gates/deps).
145
+ export {
146
+ emptyEvidenceInput,
147
+ evidenceBodyFreeViolations,
148
+ gateVerdictIsValid,
149
+ listEvidenceContractIds,
150
+ normalizeEvidenceInput,
151
+ registerEvidenceContract,
152
+ resolveEvidenceContract,
153
+ } from "./src/domains/worklist/evidence-contract.js";
154
+ export type {
155
+ DepEntry,
156
+ EvidenceContract,
157
+ EvidenceInput,
158
+ EvidenceKind,
159
+ EvidenceVerdict,
160
+ GateEntry,
161
+ TaskView,
162
+ } from "./src/domains/worklist/evidence-contract.js";
163
+ export {
164
+ FORBIDDEN_PLAINTEXT_KEYS,
165
+ WORKLIST_DIRECTIVE_SCHEMA,
166
+ WORKLIST_EVENT_SCHEMA,
167
+ WORKLIST_LEASE_SCHEMA,
168
+ WORKLIST_PROJECTION_SCHEMA,
169
+ directiveHash,
170
+ } from "./src/domains/worklist/types.js";
171
+ export type {
172
+ Directive,
173
+ ProjectedDirective,
174
+ WorklistDeps,
175
+ WorklistEvent,
176
+ WorklistEventInput,
177
+ WorklistLease,
178
+ WorklistLeaseStatus,
179
+ WorklistProjection,
180
+ WorklistValidation,
181
+ } from "./src/domains/worklist/types.js";
182
+ export {
183
+ appendWorklistEvent,
184
+ claimWorklistDirective,
185
+ isWorklistEvent,
186
+ isWorklistLease,
187
+ listWorklistDirectives,
188
+ listWorklistEvents,
189
+ listWorklistLeases,
190
+ openWorklistStore,
191
+ projectWorklist,
192
+ recoverStaleWorklistLeases,
193
+ satisfyWorklistDirective,
194
+ validateWorklist,
195
+ worklistBodyFreeViolations,
196
+ } from "./src/domains/worklist/store.js";
197
+ export type { WorklistClaimOptions, WorklistStore, WorklistStoreOptions } from "./src/domains/worklist/store.js";
198
+ export {
199
+ DEFAULT_RESEND_INTERVAL_MS,
200
+ DIRECTIVE_DELIVERY_REASON_DIRECTIVE_SATISFIED,
201
+ DIRECTIVE_DELIVERY_REASON_IN_FLIGHT,
202
+ DIRECTIVE_DELIVERY_REASON_NEW,
203
+ DIRECTIVE_DELIVERY_REASON_NO_HASH,
204
+ DIRECTIVE_DELIVERY_REASON_REDELIVER,
205
+ DIRECTIVE_DELIVERY_REASON_SEEN_ACTED,
206
+ DIRECTIVE_READY_NOTIFICATION_SCHEMA,
207
+ WORKLIST_DIRECTIVE_DELIVERY_ACTED_SCHEMA,
208
+ WORKLIST_DIRECTIVE_DELIVERY_LEDGER_SCHEMA,
209
+ deliverDirectiveNotification,
210
+ deliverDirectives,
211
+ listDeliveries,
212
+ loadDirectiveDeliveryLedger,
213
+ markDirectiveActed,
214
+ markDirectiveDeliveredActed,
215
+ planDirectiveDelivery,
216
+ reconcileDirectiveLedger,
217
+ recordDirectiveDelivery,
218
+ } from "./src/domains/worklist/delivery.js";
219
+ export type {
220
+ DeliverDirectiveNotificationOptions,
221
+ DirectiveDeliveryLedger,
222
+ DirectiveDeliveryPlan,
223
+ DirectiveDeliveryRecord,
224
+ DirectiveDeliveryResult,
225
+ DirectiveReadyNotification,
226
+ } from "./src/domains/worklist/delivery.js";
227
+ export {
228
+ DECISION_TIMEOUT_DEFAULT_MS,
229
+ ESCALATE_TO_HUMAN_DEFAULT_MS,
230
+ ESCALATE_TO_LLM_DEFAULT_MS,
231
+ ESCALATION_LEVEL_ACT_NOW,
232
+ ESCALATION_LEVEL_AUTO,
233
+ ESCALATION_LEVEL_HUMAN_BLOCK,
234
+ ESCALATION_LEVEL_NUDGE_LLM,
235
+ ESCALATION_LEVEL_WAIT,
236
+ WATCHDOG_ESCALATION_SCHEMA,
237
+ WATCHDOG_EVALUATION_SCHEMA,
238
+ WATCHDOG_TICK_RESULT_SCHEMA,
239
+ computeWatchdogEscalation,
240
+ evaluateWorklistWatchdog,
241
+ listWatchdogEscalations,
242
+ runWorklistWatchdogTick,
243
+ } from "./src/domains/worklist/watchdog.js";
244
+ export type {
245
+ WatchdogBudgets,
246
+ WatchdogEscalation,
247
+ WatchdogEscalationEntry,
248
+ WatchdogEscalationEvent,
249
+ WatchdogEvaluation,
250
+ WatchdogTickDeps,
251
+ WatchdogTickResult,
252
+ } from "./src/domains/worklist/watchdog.js";
253
+ export {
254
+ DAG_STATUSES,
255
+ WORKLIST_DAG_SCHEMA,
256
+ WORKLIST_DAG_STATE_SCHEMA,
257
+ buildDag,
258
+ buildDagOrThrow,
259
+ butterflySeedNext,
260
+ computeDownstreamImpact,
261
+ dagBodyFreeViolations,
262
+ dagFingerprint,
263
+ dependencySatisfied,
264
+ detectCycle,
265
+ isCrossScopeRef,
266
+ nodeDepsSatisfied,
267
+ parseCrossScopeRef,
268
+ readyNodes,
269
+ readDagState,
270
+ resolveCrossScopeDependency,
271
+ writeDagState,
272
+ } from "./src/domains/worklist/dag.js";
273
+ export type {
274
+ CrossScopeResolver,
275
+ DagBuildResult,
276
+ DagGraph,
277
+ DagNode,
278
+ DagNodeInput,
279
+ DagNodeStatus,
280
+ DagState,
281
+ DownstreamImpact,
282
+ } from "./src/domains/worklist/dag.js";
283
+ export { registerWorklistTools } from "./src/runtime/tools-worklist.js";
284
+ // WS-PH1 (environment-precondition PART II keystone): the typed EnvironmentContract
285
+ // pillar (the 4th pillar alongside computeWorklist/EvidenceContract). The contract
286
+ // shape + registry + PURE primitives (no node:fs/node:child_process); the body +
287
+ // snapshotEnvironment IO are project-registered (WS-PH4). Metadata-only / body-free
288
+ // / network-disabled: Precondition/PreconditionVerdict/EnvironmentSnapshot carry
289
+ // paths, counts, channel names, command strings only; FORBIDDEN_PLAINTEXT_KEYS
290
+ // applies (reused from the worklist domain).
291
+ export {
292
+ commandPresent,
293
+ dirEmpty,
294
+ pathWritable,
295
+ toolchainInstalled,
296
+ } from "./src/domains/environment/primitives.js";
297
+ export type {
298
+ CommandPresentResult,
299
+ DirEmptyResult,
300
+ PathWritableResult,
301
+ ToolchainInstalledResult,
302
+ } from "./src/domains/environment/primitives.js";
303
+ export {
304
+ environmentBodyFreeViolations,
305
+ listEnvironmentContractIds,
306
+ registerEnvironmentContract,
307
+ resolveEnvironmentContract,
308
+ } from "./src/domains/environment/environment-contract.js";
309
+ export type {
310
+ EnvironmentContract,
311
+ PreconditionScope,
312
+ } from "./src/domains/environment/environment-contract.js";
313
+ export type {
314
+ CheckPhase,
315
+ EnvironmentSnapshot,
316
+ Precondition,
317
+ PreconditionKind,
318
+ PreconditionVerdict,
319
+ } from "./src/domains/environment/types.js";
320
+ // WS-PH2 (environment-precondition PART II): the launch-time gate primitive.
321
+ // runLaunchGate snapshots once, evaluates all check_phase:"launch" preconditions,
322
+ // returns { ok, verdicts, fix_packet, shouldStart } with shouldStart === ok BY
323
+ // CONSTRUCTION (fail-closed, no opt-out). Pure over (contract, snapshot); never
324
+ // starts anything itself (mechanism in harness, action in app). Idempotent +
325
+ // re-runnable (re-snapshots on re-call). Metadata-only / body-free / network-
326
+ // disabled. No node:fs/node:child_process (the purity grep returns nothing).
327
+ export { runLaunchGate } from "./src/domains/environment/launch-gate.js";
328
+ export type {
329
+ FixPacketEntry,
330
+ LaunchGateOptions,
331
+ LaunchGateResult,
332
+ } from "./src/domains/environment/launch-gate.js";
333
+ // WS-PH3 (environment-precondition PART II — SAFETY-CRITICAL slice): the auto-resolve
334
+ // framework. applyAutoResolve applies ONLY allowlisted + REVERSIBLE strategies;
335
+ // REFUSES reversible:false ALWAYS (structurally unresolvable); SKIPS requires_network
336
+ // unless options.network===true; dispatches via PROJECT-REGISTERED
337
+ // ResolutionStrategyFn (the harness NEVER hardcodes a shell command); REFUSES
338
+ // missing-strategy + no-allowlist-match (fail-safe); DRY-RUN-FIRST (after_state:null,
339
+ // io.exec guarded). Incapable-by-construction of irreversible ops: the allowlist
340
+ // filter rejects reversible:false BEFORE dispatch. node:fs is used ONLY for the
341
+ // audit-log writer (appendFileSync); no node:child_process / direct spawn.
342
+ // Metadata-only / body-free / network-disabled (environmentBodyFreeViolations per entry).
343
+ export { AUTO_RESOLVE_AUDIT_SCHEMA, applyAutoResolve, registerResolutionStrategy } from "./src/domains/environment/auto-resolve.js";
344
+ export type {
345
+ AutoResolveAllowlist,
346
+ AutoResolveAuditEntry,
347
+ AutoResolveEntry,
348
+ AutoResolveIO,
349
+ AutoResolveOptions,
350
+ AutoResolveOutcome,
351
+ AutoResolveResult,
352
+ AutoResolveVerdict,
353
+ ResolutionStrategyFn,
354
+ } from "./src/domains/environment/auto-resolve.js";
130
355
  export { DEFAULT_PROMOTION_GATES, advancePromotionCandidate, appendPromotionLedger, createPromotionCandidate, promotionCandidateDir, promotionCandidateRef, promotionReportsDir, summarizePromotionCandidates, transitionAllowed, validatePromotionCandidate, writePromotionCandidate } from "./src/domains/promotion/candidate.js";
131
356
  export { addPromotionComsMessageRef, buildPromotionComsMessageRef, buildPromotionComsThread, validatePromotionComsMessageRef, validatePromotionComsReadiness, validatePromotionComsThread, writePromotionComsThread } from "./src/domains/promotion/coms.js";
132
357
  export { applyDocumentationPromotionInQuarantine, prepareDocumentationPromotion, validateDocumentationPromotion, validateDocumentationPromotionCandidate } from "./src/domains/promotion/documentation.js";
@@ -0,0 +1,55 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ export const PRIMARY_PLANS_ROOT = ".pi/plans";
5
+ export const LEGACY_PLANS_ROOT = "plans";
6
+ export const PRIMARY_REPORTS_ROOT = ".pi/reports";
7
+ export const LEGACY_REPORTS_ROOT = "reports";
8
+
9
+ export type ArtifactRootKind = "plans" | "reports";
10
+
11
+ function normalizeSegments(segments: string[]): string[] {
12
+ return segments.flatMap((segment) => segment.split("/")).filter(Boolean);
13
+ }
14
+
15
+ export function artifactRootRef(kind: ArtifactRootKind, legacy = false): string {
16
+ if (kind === "plans") return legacy ? LEGACY_PLANS_ROOT : PRIMARY_PLANS_ROOT;
17
+ return legacy ? LEGACY_REPORTS_ROOT : PRIMARY_REPORTS_ROOT;
18
+ }
19
+
20
+ export function artifactRootPath(repoRoot: string, kind: ArtifactRootKind, legacy = false): string {
21
+ return join(repoRoot, ...artifactRootRef(kind, legacy).split("/"));
22
+ }
23
+
24
+ export function artifactRef(kind: ArtifactRootKind, ...segments: string[]): string {
25
+ return [artifactRootRef(kind), ...normalizeSegments(segments)].join("/");
26
+ }
27
+
28
+ export function legacyArtifactRef(kind: ArtifactRootKind, ...segments: string[]): string {
29
+ return [artifactRootRef(kind, true), ...normalizeSegments(segments)].join("/");
30
+ }
31
+
32
+ export function artifactPath(repoRoot: string, kind: ArtifactRootKind, ...segments: string[]): string {
33
+ return join(artifactRootPath(repoRoot, kind), ...normalizeSegments(segments));
34
+ }
35
+
36
+ export function legacyArtifactPath(repoRoot: string, kind: ArtifactRootKind, ...segments: string[]): string {
37
+ return join(artifactRootPath(repoRoot, kind, true), ...normalizeSegments(segments));
38
+ }
39
+
40
+ export function isArtifactRef(value: string, kind: ArtifactRootKind, options: { legacy?: boolean } = {}): boolean {
41
+ const normalized = value.replace(/^\.\//, "");
42
+ const primary = artifactRootRef(kind);
43
+ const legacy = artifactRootRef(kind, true);
44
+ return normalized === primary || normalized.startsWith(`${primary}/`) || options.legacy === true && (normalized === legacy || normalized.startsWith(`${legacy}/`));
45
+ }
46
+
47
+ export function existingArtifactRoots(repoRoot: string, kind: ArtifactRootKind, ...segments: string[]): string[] {
48
+ const primary = artifactPath(repoRoot, kind, ...segments);
49
+ const legacy = legacyArtifactPath(repoRoot, kind, ...segments);
50
+ return [primary, legacy].filter((path, index, paths) => paths.indexOf(path) === index && existsSync(path));
51
+ }
52
+
53
+ export function firstExistingArtifactPath(repoRoot: string, kind: ArtifactRootKind, ...segments: string[]): string {
54
+ return existingArtifactRoots(repoRoot, kind, ...segments)[0] ?? artifactPath(repoRoot, kind, ...segments);
55
+ }
@@ -18,7 +18,7 @@ export { DEFAULT_RULES };
18
18
  export const ZOB_TOOL_ROUTING_CONTRACT = [
19
19
  "ZOB TOOL ROUTING CONTRACT",
20
20
  "- For non-trivial or tool-ambiguous work, run a lightweight routing loop before acting.",
21
- "- Classify applicable families: goal/TODO, delegation, orchestration, compute, context/ProjectDNA, factory, coms/goal-room, workspace/merge, autonomous-runtime, oracle.",
21
+ "- Classify applicable families: goal/TODO, delegation, orchestration, compute, context/ProjectDNA, factory, coms/goal-room, worklist/liveness, workspace/merge, autonomous-runtime, oracle.",
22
22
  "- Load .pi/skills/zob-tool-router/SKILL.md when routing is uncertain or work spans multiple families; then load the domain skill(s) named by the registry.",
23
23
  "- Use the smallest sufficient tool set: use, delegate, or explicitly skip applicable families with a reason.",
24
24
  "- Do not bypass mode/tool safety, approval, sandbox, budget, evidence, or oracle gates.",
@@ -51,6 +51,7 @@ export const ZOB_GOAL_ROOM_TOOLS = ["zob_goal_room_send", "zob_goal_room_list"]
51
51
  export const ZOB_GOVERNED_REQUEST_TOOLS = ["zob_governed_request_extract"] as const;
52
52
  export const ZOB_WORKSPACE_CLAIM_TOOLS = ["zob_workspace_claim", "zob_workspace_release", "zob_workspace_claims_list"] as const;
53
53
  export const ZOB_WORKER_POOL_TOOLS = ["zob_worker_pool_plan", "zob_worker_pool_status", "zob_worker_pool_owner_request", "zob_worker_pool_owner_decision"] as const;
54
+ export const ZOB_WORKLIST_TOOLS = ["zob_worklist"] as const;
54
55
  export const ZOB_MERGE_QUEUE_TOOLS = ["zob_merge_candidate_submit", "zob_merge_queue_decide", "zob_merge_queue_list"] as const;
55
56
  export const ZOB_ZCOMMIT_TOOLS = ["zob_zcommit_run"] as const;
56
57
  export const ZOB_ZAGENT_TOOLS = ["zob_zteam_hot_add", "zob_zteam_remove"] as const;
@@ -70,11 +71,11 @@ export const ZOB_AUTONOMOUS_FACTORY_TOOLS = ["zob_autonomous_dry_run", "zob_auto
70
71
 
71
72
  export const MODE_TOOLS: Record<ModeName, string[]> = {
72
73
  explore: ["read", "grep", "find", "ls", "bash", "delegate_agent", "delegate_task", "zob_coms_list", "zob_coms_get", "zob_coms_await", "zpeer_ask", "zob_goal_room_list", "zob_workspace_claims_list", "zob_worker_pool_status", "zob_merge_queue_list", ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_AUTONOMOUS_READ_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_PROJECT_DNA_READ_TOOLS],
73
- plan: ["read", "grep", "find", "ls", "delegate_agent", "delegate_task", "orchestrate_run", "chain_run", ...ZOB_PLAN_LAUNCH_TOOLS, ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_ZAGENT_TOOLS, ...ZOB_COMS_TOOLS, ...ZOB_GOAL_ROOM_TOOLS, ...ZOB_GOVERNED_REQUEST_TOOLS, ...ZOB_WORKSPACE_CLAIM_TOOLS, ...ZOB_WORKER_POOL_TOOLS, ...ZOB_MERGE_QUEUE_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_MISSION_CONTROL_PROPOSAL_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_CONTEXT_PROPOSAL_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_COMPUTE_REPORT_TOOLS, ...ZOB_PROJECT_DNA_READ_TOOLS, ...ZOB_PROJECT_DNA_PROPOSAL_TOOLS],
74
- implement: ["read", "bash", "edit", "write", "grep", "find", "ls", "delegate_agent", "delegate_task", ...ZOB_PLAN_LAUNCH_TOOLS, ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_ZAGENT_TOOLS, ...ZOB_COMS_TOOLS, ...ZOB_GOAL_ROOM_TOOLS, ...ZOB_GOVERNED_REQUEST_TOOLS, ...ZOB_WORKSPACE_CLAIM_TOOLS, ...ZOB_WORKER_POOL_TOOLS, ...ZOB_MERGE_QUEUE_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_MISSION_CONTROL_PROPOSAL_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_CONTEXT_PROPOSAL_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_COMPUTE_REPORT_TOOLS, ...ZOB_PROJECT_DNA_READ_TOOLS, ...ZOB_PROJECT_DNA_PROPOSAL_TOOLS],
74
+ plan: ["read", "grep", "find", "ls", "delegate_agent", "delegate_task", "orchestrate_run", "chain_run", ...ZOB_PLAN_LAUNCH_TOOLS, ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_ZAGENT_TOOLS, ...ZOB_COMS_TOOLS, ...ZOB_GOAL_ROOM_TOOLS, ...ZOB_GOVERNED_REQUEST_TOOLS, ...ZOB_WORKSPACE_CLAIM_TOOLS, ...ZOB_WORKER_POOL_TOOLS, ...ZOB_MERGE_QUEUE_TOOLS, ...ZOB_WORKLIST_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_MISSION_CONTROL_PROPOSAL_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_CONTEXT_PROPOSAL_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_COMPUTE_REPORT_TOOLS, ...ZOB_PROJECT_DNA_READ_TOOLS, ...ZOB_PROJECT_DNA_PROPOSAL_TOOLS],
75
+ implement: ["read", "bash", "edit", "write", "grep", "find", "ls", "delegate_agent", "delegate_task", ...ZOB_PLAN_LAUNCH_TOOLS, ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_ZAGENT_TOOLS, ...ZOB_COMS_TOOLS, ...ZOB_GOAL_ROOM_TOOLS, ...ZOB_GOVERNED_REQUEST_TOOLS, ...ZOB_WORKSPACE_CLAIM_TOOLS, ...ZOB_WORKER_POOL_TOOLS, ...ZOB_MERGE_QUEUE_TOOLS, ...ZOB_WORKLIST_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_MISSION_CONTROL_PROPOSAL_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_CONTEXT_PROPOSAL_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_COMPUTE_REPORT_TOOLS, ...ZOB_PROJECT_DNA_READ_TOOLS, ...ZOB_PROJECT_DNA_PROPOSAL_TOOLS],
75
76
  oracle: ["read", "grep", "find", "ls", "bash", "delegate_agent", "delegate_task", "zob_coms_list", "zob_coms_get", "zob_coms_await", "zpeer_ask", "zob_goal_room_list", "zob_workspace_claims_list", "zob_worker_pool_status", "zob_merge_queue_list", ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_AUTONOMOUS_READ_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_PROJECT_DNA_READ_TOOLS],
76
- orchestrator: ["read", "grep", "find", "ls", "delegate_agent", "delegate_task", "orchestrate_run", "chain_run", ...ZOB_PLAN_LAUNCH_TOOLS, ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_ZAGENT_TOOLS, ...ZOB_COMS_TOOLS, ...ZOB_GOAL_ROOM_TOOLS, ...ZOB_GOVERNED_REQUEST_TOOLS, ...ZOB_WORKSPACE_CLAIM_TOOLS, ...ZOB_WORKER_POOL_TOOLS, ...ZOB_MERGE_QUEUE_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_MISSION_CONTROL_PROPOSAL_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_CONTEXT_PROPOSAL_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_COMPUTE_REPORT_TOOLS],
77
- factory: ["read", "bash", "edit", "write", "grep", "find", "ls", "delegate_agent", "delegate_task", "orchestrate_run", "factory_run", "factory_quarantine_review", "factory_quarantine_activate", "factory_quarantine_verify_activation", "chain_run", ...ZOB_PLAN_LAUNCH_TOOLS, ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_ZAGENT_TOOLS, ...ZOB_AUTONOMOUS_READ_TOOLS, ...ZOB_AUTONOMOUS_FACTORY_TOOLS, ...ZOB_COMS_TOOLS, ...ZOB_GOAL_ROOM_TOOLS, ...ZOB_GOVERNED_REQUEST_TOOLS, ...ZOB_WORKSPACE_CLAIM_TOOLS, ...ZOB_WORKER_POOL_TOOLS, ...ZOB_MERGE_QUEUE_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_MISSION_CONTROL_PROPOSAL_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_CONTEXT_PROPOSAL_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_COMPUTE_REPORT_TOOLS, ...ZOB_PROJECT_DNA_READ_TOOLS, ...ZOB_PROJECT_DNA_PROPOSAL_TOOLS],
77
+ orchestrator: ["read", "grep", "find", "ls", "delegate_agent", "delegate_task", "orchestrate_run", "chain_run", ...ZOB_PLAN_LAUNCH_TOOLS, ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_ZAGENT_TOOLS, ...ZOB_COMS_TOOLS, ...ZOB_GOAL_ROOM_TOOLS, ...ZOB_GOVERNED_REQUEST_TOOLS, ...ZOB_WORKSPACE_CLAIM_TOOLS, ...ZOB_WORKER_POOL_TOOLS, ...ZOB_MERGE_QUEUE_TOOLS, ...ZOB_WORKLIST_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_MISSION_CONTROL_PROPOSAL_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_CONTEXT_PROPOSAL_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_COMPUTE_REPORT_TOOLS],
78
+ factory: ["read", "bash", "edit", "write", "grep", "find", "ls", "delegate_agent", "delegate_task", "orchestrate_run", "factory_run", "factory_quarantine_review", "factory_quarantine_activate", "factory_quarantine_verify_activation", "chain_run", ...ZOB_PLAN_LAUNCH_TOOLS, ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_ZAGENT_TOOLS, ...ZOB_AUTONOMOUS_READ_TOOLS, ...ZOB_AUTONOMOUS_FACTORY_TOOLS, ...ZOB_COMS_TOOLS, ...ZOB_GOAL_ROOM_TOOLS, ...ZOB_GOVERNED_REQUEST_TOOLS, ...ZOB_WORKSPACE_CLAIM_TOOLS, ...ZOB_WORKER_POOL_TOOLS, ...ZOB_MERGE_QUEUE_TOOLS, ...ZOB_WORKLIST_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_MISSION_CONTROL_PROPOSAL_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_CONTEXT_PROPOSAL_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_COMPUTE_REPORT_TOOLS, ...ZOB_PROJECT_DNA_READ_TOOLS, ...ZOB_PROJECT_DNA_PROPOSAL_TOOLS],
78
79
  // Vanilla is handled specially by applyMode: all currently available Pi tools are enabled.
79
80
  vanilla: [],
80
81
  };
@@ -1,5 +1,6 @@
1
1
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { artifactPath, artifactRef, firstExistingArtifactPath } from "../../../core/artifact-roots.js";
3
4
  import { runFactoryRun } from "../../factory/run.js";
4
5
  import { sha256 } from "../../../core/utils/hashing.js";
5
6
  import { safeFileStem } from "../../../core/utils/paths.js";
@@ -12,7 +13,7 @@ export function writeAutonomousRuntimeDryRunReport(repoRoot: string, input: Auto
12
13
  const report = buildAutonomousRuntimeDryRun(repoRoot, input);
13
14
  const runId = String(report.runId);
14
15
  const safeRunId = safeFileStem(runId);
15
- const runDir = join(repoRoot, "reports", "autonomous-runs", safeRunId);
16
+ const runDir = artifactPath(repoRoot, "reports", "autonomous-runs", safeRunId);
16
17
  mkdirSync(runDir, { recursive: true });
17
18
  const specGatePath = join(runDir, "spec-gate.json");
18
19
  const contextScopePath = join(runDir, "context-scope.json");
@@ -44,25 +45,25 @@ export function writeAutonomousRuntimeDryRunReport(repoRoot: string, input: Auto
44
45
  if (report.status === "dry_run_plan_ready") writeFileSync(join(runDir, "DRY_RUN_READY.sentinel"), "dry-run-ready\n");
45
46
  return {
46
47
  ...report,
47
- specGatePath: `reports/autonomous-runs/${safeRunId}/spec-gate.json`,
48
- contextScopePath: `reports/autonomous-runs/${safeRunId}/context-scope.json`,
49
- contextLookupPath: `reports/autonomous-runs/${safeRunId}/context-lookup.json`,
50
- contextPackPath: `reports/autonomous-runs/${safeRunId}/context-pack.json`,
51
- runtimeGatesPath: `reports/autonomous-runs/${safeRunId}/runtime-gates.json`,
52
- modelRoutingPlanPath: `reports/autonomous-runs/${safeRunId}/model-routing-plan.json`,
53
- runGraphPath: `reports/autonomous-runs/${safeRunId}/run-graph.json`,
54
- factorySelectionPath: `reports/autonomous-runs/${safeRunId}/factory-selection.json`,
55
- proofPlanPath: `reports/autonomous-runs/${safeRunId}/proof-plan.json`,
56
- reportPath: `reports/autonomous-runs/${safeRunId}/dry-run-report.json`,
57
- validationPath: `reports/autonomous-runs/${safeRunId}/validation.json`,
58
- finalReportPath: `reports/autonomous-runs/${safeRunId}/final-report.md`,
59
- sentinelPath: report.status === "dry_run_plan_ready" ? `reports/autonomous-runs/${safeRunId}/DRY_RUN_READY.sentinel` : undefined,
48
+ specGatePath: artifactRef("reports", "autonomous-runs", safeRunId, "spec-gate.json"),
49
+ contextScopePath: artifactRef("reports", "autonomous-runs", safeRunId, "context-scope.json"),
50
+ contextLookupPath: artifactRef("reports", "autonomous-runs", safeRunId, "context-lookup.json"),
51
+ contextPackPath: artifactRef("reports", "autonomous-runs", safeRunId, "context-pack.json"),
52
+ runtimeGatesPath: artifactRef("reports", "autonomous-runs", safeRunId, "runtime-gates.json"),
53
+ modelRoutingPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "model-routing-plan.json"),
54
+ runGraphPath: artifactRef("reports", "autonomous-runs", safeRunId, "run-graph.json"),
55
+ factorySelectionPath: artifactRef("reports", "autonomous-runs", safeRunId, "factory-selection.json"),
56
+ proofPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "proof-plan.json"),
57
+ reportPath: artifactRef("reports", "autonomous-runs", safeRunId, "dry-run-report.json"),
58
+ validationPath: artifactRef("reports", "autonomous-runs", safeRunId, "validation.json"),
59
+ finalReportPath: artifactRef("reports", "autonomous-runs", safeRunId, "final-report.md"),
60
+ sentinelPath: report.status === "dry_run_plan_ready" ? artifactRef("reports", "autonomous-runs", safeRunId, "DRY_RUN_READY.sentinel") : undefined,
60
61
  };
61
62
  }
62
63
  export function writeAutonomousReadOnlySmokeRunReport(repoRoot: string, input: AutonomousReadOnlySmokeRunInput): Record<string, unknown> {
63
64
  const runId = safeFileStem(input.runId ?? `autonomous-readonly-smoke-${sha256(input.userNeed || "missing-spec").slice(0, 12)}`);
64
65
  const safeRunId = safeFileStem(runId);
65
- const runDir = join(repoRoot, "reports", "autonomous-runs", safeRunId);
66
+ const runDir = artifactPath(repoRoot, "reports", "autonomous-runs", safeRunId);
66
67
  const smokeAutonomySentinelPath = join(runDir, "SMOKE_AUTONOMY_PASSED.sentinel");
67
68
  if (existsSync(smokeAutonomySentinelPath)) throw new Error(`Autonomous smoke run already passed; choose a fresh run_id to avoid stale sentinel reuse: ${runId}`);
68
69
  const dryRun = writeAutonomousRuntimeDryRunReport(repoRoot, {
@@ -75,7 +76,7 @@ export function writeAutonomousReadOnlySmokeRunReport(repoRoot: string, input: A
75
76
  const selectedFactory = typeof factorySelection.selectedFactory === "string" ? factorySelection.selectedFactory : undefined;
76
77
  const manifestPath = selectedFactory ? `.pi/factories/${selectedFactory}/smoke-manifest.json` : undefined;
77
78
  const factoryRunId = safeFileStem(input.factoryRunId ?? `autonomous-smoke-${safeRunId}`);
78
- const factoryRunAlreadyExists = existsSync(join(repoRoot, "reports", "factory-runs", factoryRunId));
79
+ const factoryRunAlreadyExists = existsSync(firstExistingArtifactPath(repoRoot, "reports", "factory-runs", factoryRunId));
79
80
  const blockers = [
80
81
  ...(dryRun.status === "dry_run_plan_ready" ? [] : ["dry_run_not_ready"]),
81
82
  ...(isRecord(dryRun.validation) && Array.isArray(dryRun.validation.blockers) ? dryRun.validation.blockers.filter((blocker): blocker is string => typeof blocker === "string") : []),
@@ -99,7 +100,7 @@ export function writeAutonomousReadOnlySmokeRunReport(repoRoot: string, input: A
99
100
  budget: { strictRequested: true, strictEnabled: false, maxRuns: 1, estimatedRuns: 1, maxParallelChildren: 1, estimatedParallelChildren: 1 },
100
101
  model_routing: { enabled: false, risk: input.risk ?? "medium", contextTokens: input.maxContextTokens },
101
102
  }) : undefined;
102
- const factoryRunDir = join(repoRoot, "reports", "factory-runs", factoryRunId);
103
+ const factoryRunDir = firstExistingArtifactPath(repoRoot, "reports", "factory-runs", factoryRunId);
103
104
  const factoryValidationPath = join(factoryRunDir, "validation.json");
104
105
  const factoryValidationRead = readJsonArtifact(factoryValidationPath);
105
106
  const factoryValidation = isRecord(factoryValidationRead.parsed) ? factoryValidationRead.parsed : {};
@@ -164,12 +165,12 @@ export function writeAutonomousReadOnlySmokeRunReport(repoRoot: string, input: A
164
165
  checks: oracleChecks,
165
166
  failedChecks: oracleChecks.filter((check) => check.passed !== true).map((check) => check.name),
166
167
  evidenceRefs: [
167
- `reports/autonomous-runs/${safeRunId}/spec-gate.json`,
168
- `reports/autonomous-runs/${safeRunId}/context-pack.json`,
169
- `reports/autonomous-runs/${safeRunId}/runtime-gates.json`,
170
- `reports/autonomous-runs/${safeRunId}/model-routing-plan.json`,
171
- `reports/autonomous-runs/${safeRunId}/factory-selection.json`,
172
- `reports/autonomous-runs/${safeRunId}/factory-run-ref.json`,
168
+ artifactRef("reports", "autonomous-runs", safeRunId, "spec-gate.json"),
169
+ artifactRef("reports", "autonomous-runs", safeRunId, "context-pack.json"),
170
+ artifactRef("reports", "autonomous-runs", safeRunId, "runtime-gates.json"),
171
+ artifactRef("reports", "autonomous-runs", safeRunId, "model-routing-plan.json"),
172
+ artifactRef("reports", "autonomous-runs", safeRunId, "factory-selection.json"),
173
+ artifactRef("reports", "autonomous-runs", safeRunId, "factory-run-ref.json"),
173
174
  relativeFactoryRunPath(factoryRunId, "validation.json"),
174
175
  relativeFactoryRunPath(factoryRunId, "SMOKE_PASSED.sentinel"),
175
176
  relativeFactoryRunPath(factoryRunId, "DONE.sentinel"),
@@ -303,23 +304,23 @@ export function writeAutonomousReadOnlySmokeRunReport(repoRoot: string, input: A
303
304
  finalNoShipOracle,
304
305
  completionGate,
305
306
  validation,
306
- factoryRunRefPath: `reports/autonomous-runs/${safeRunId}/factory-run-ref.json`,
307
- oracleReviewPath: `reports/autonomous-runs/${safeRunId}/oracle-review.json`,
308
- promotionPlanPath: `reports/autonomous-runs/${safeRunId}/promotion-plan.json`,
309
- promotionProofPlanPath: `reports/autonomous-runs/${safeRunId}/promotion-proof-plan.json`,
310
- schedulerPlanPath: `reports/autonomous-runs/${safeRunId}/scheduler-plan.json`,
311
- schedulerProofPlanPath: `reports/autonomous-runs/${safeRunId}/scheduler-proof-plan.json`,
312
- missionControlPlanPath: `reports/autonomous-runs/${safeRunId}/mission-control-plan.json`,
313
- missionControlProofPlanPath: `reports/autonomous-runs/${safeRunId}/mission-control-proof-plan.json`,
314
- sandboxApplyPlanPath: `reports/autonomous-runs/${safeRunId}/sandbox-apply-plan.json`,
315
- strictBudgetProofPlanPath: `reports/autonomous-runs/${safeRunId}/strict-budget-proof-plan.json`,
316
- modelRoutingProofPlanPath: `reports/autonomous-runs/${safeRunId}/model-routing-proof-plan.json`,
317
- currentSourceFingerprintPath: `reports/autonomous-runs/${safeRunId}/current-source-fingerprint.json`,
318
- finalE2EProofPlanPath: `reports/autonomous-runs/${safeRunId}/final-e2e-proof-plan.json`,
319
- finalNoShipOraclePath: `reports/autonomous-runs/${safeRunId}/final-no-ship-oracle.json`,
320
- completionGatePath: `reports/autonomous-runs/${safeRunId}/completion-gate.json`,
321
- validationPath: `reports/autonomous-runs/${safeRunId}/validation.json`,
322
- finalReportPath: `reports/autonomous-runs/${safeRunId}/final-report.md`,
323
- smokeSentinelPath: structuralOraclePassed ? `reports/autonomous-runs/${safeRunId}/SMOKE_AUTONOMY_PASSED.sentinel` : undefined,
307
+ factoryRunRefPath: artifactRef("reports", "autonomous-runs", safeRunId, "factory-run-ref.json"),
308
+ oracleReviewPath: artifactRef("reports", "autonomous-runs", safeRunId, "oracle-review.json"),
309
+ promotionPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "promotion-plan.json"),
310
+ promotionProofPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "promotion-proof-plan.json"),
311
+ schedulerPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "scheduler-plan.json"),
312
+ schedulerProofPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "scheduler-proof-plan.json"),
313
+ missionControlPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "mission-control-plan.json"),
314
+ missionControlProofPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "mission-control-proof-plan.json"),
315
+ sandboxApplyPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "sandbox-apply-plan.json"),
316
+ strictBudgetProofPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "strict-budget-proof-plan.json"),
317
+ modelRoutingProofPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "model-routing-proof-plan.json"),
318
+ currentSourceFingerprintPath: artifactRef("reports", "autonomous-runs", safeRunId, "current-source-fingerprint.json"),
319
+ finalE2EProofPlanPath: artifactRef("reports", "autonomous-runs", safeRunId, "final-e2e-proof-plan.json"),
320
+ finalNoShipOraclePath: artifactRef("reports", "autonomous-runs", safeRunId, "final-no-ship-oracle.json"),
321
+ completionGatePath: artifactRef("reports", "autonomous-runs", safeRunId, "completion-gate.json"),
322
+ validationPath: artifactRef("reports", "autonomous-runs", safeRunId, "validation.json"),
323
+ finalReportPath: artifactRef("reports", "autonomous-runs", safeRunId, "final-report.md"),
324
+ smokeSentinelPath: structuralOraclePassed ? artifactRef("reports", "autonomous-runs", safeRunId, "SMOKE_AUTONOMY_PASSED.sentinel") : undefined,
324
325
  };
325
326
  }
@@ -2,6 +2,7 @@ import { mkdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
 
4
4
  import type { ZobComsTranscriptCapturePolicy } from "./types.js";
5
+ import { PRIMARY_REPORTS_ROOT } from "../../../core/artifact-roots.js";
5
6
  import { sha256 } from "../../../core/utils/hashing.js";
6
7
  import { safeFileStem } from "../../../core/utils/paths.js";
7
8
 
@@ -32,7 +33,7 @@ export interface ZobComsRedactedCaptureRef {
32
33
  bodyStored: false;
33
34
  }
34
35
 
35
- const DEFAULT_ARTIFACT_ROOT = "reports/coms-captures";
36
+ const DEFAULT_ARTIFACT_ROOT = `${PRIMARY_REPORTS_ROOT}/coms-captures`;
36
37
  const DEFAULT_REDACTION_PROFILE = "zob-default-v1";
37
38
  const SECRET_PATTERNS: Array<{ name: string; pattern: RegExp }> = [
38
39
  { name: "private_key", pattern: /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/g },
@@ -1,6 +1,7 @@
1
1
  import { appendFileSync, existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
 
4
+ import { artifactRef, firstExistingArtifactPath } from "../../core/artifact-roots.js";
4
5
  import { buildZobLivePresenceSummary, redactZobLivePeerForMissionControl } from "./coms-v2/presence.js";
5
6
  import { readZobComsV2Policy } from "./coms-v2/policy.js";
6
7
  import { zpeerMembershipsForPeer } from "./coms-v2/zpeer.js";
@@ -121,11 +122,13 @@ function summarizeRunDir(repoRoot: string, baseRelative: string, runId: string):
121
122
  }
122
123
 
123
124
  function summarizeLatestRuns(repoRoot: string, baseRelative: string, limit: number): Array<Record<string, unknown>> {
124
- return sortedEntriesByMtime(join(repoRoot, baseRelative)).slice(0, limit).map((runId) => summarizeRunDir(repoRoot, baseRelative, runId));
125
+ const primaryRelative = baseRelative.startsWith("reports/") ? baseRelative.replace(/^reports\//, ".pi/reports/") : baseRelative;
126
+ const roots = [primaryRelative, baseRelative].filter((value, index, values) => values.indexOf(value) === index);
127
+ return roots.flatMap((rootRelative) => sortedEntriesByMtime(join(repoRoot, rootRelative)).slice(0, limit).map((runId) => summarizeRunDir(repoRoot, rootRelative, runId))).slice(0, limit);
125
128
  }
126
129
 
127
130
  function summarizeAdaptiveWorkflowArtifacts(repoRoot: string, limit: number): Array<Record<string, unknown>> {
128
- const root = join(repoRoot, "reports", "orchestrations");
131
+ const root = firstExistingArtifactPath(repoRoot, "reports", "orchestrations");
129
132
  if (!existsSync(root)) return [];
130
133
  return sortedEntriesByMtime(root).slice(0, Math.max(limit, 20)).flatMap((runId) => {
131
134
  const runDir = join(root, runId);
@@ -152,14 +155,14 @@ function summarizeAdaptiveWorkflowArtifacts(repoRoot: string, limit: number): Ar
152
155
  docWritebackPolicy: documentationPolicy?.writebackPolicy,
153
156
  valid: validation?.valid,
154
157
  errors: Array.isArray(validation?.errors) ? validation.errors : [],
155
- artifact: `reports/orchestrations/${runId}/adaptive-workflow-validation.json`,
158
+ artifact: artifactRef("reports", "orchestrations", runId, "adaptive-workflow-validation.json"),
156
159
  bodyStored: false,
157
160
  }];
158
161
  }).slice(0, limit);
159
162
  }
160
163
 
161
164
  function summarizeComputeProfileArtifacts(repoRoot: string, limit: number): Array<Record<string, unknown>> {
162
- const root = join(repoRoot, "reports", "project-dna-scans");
165
+ const root = firstExistingArtifactPath(repoRoot, "reports", "project-dna-scans");
163
166
  if (!existsSync(root)) return [];
164
167
  return readdirSync(root)
165
168
  .map((runId) => ({ runId, summaryPath: join(root, runId, "compute-mission-control-summary.json") }))
@@ -180,7 +183,7 @@ function summarizeComputeProfileArtifacts(repoRoot: string, limit: number): Arra
180
183
  parentOwnedDispatch: isRecord(summary.workflow) ? summary.workflow.parentOwnedDispatch : undefined,
181
184
  childDirectDispatch: isRecord(summary.workflow) ? summary.workflow.childDirectDispatch : undefined,
182
185
  fullHudWidgetWiringImplemented: summary.fullHudWidgetWiringImplemented,
183
- artifact: `reports/project-dna-scans/${runId}/compute-mission-control-summary.json`,
186
+ artifact: artifactRef("reports", "project-dna-scans", runId, "compute-mission-control-summary.json"),
184
187
  bodyStored: summary.bodyStored,
185
188
  }];
186
189
  });
@@ -484,8 +487,8 @@ export function buildMissionControlSnapshot(repoRoot: string, definition: TeamDe
484
487
  const queueDashboard = sanitizeMissionControlMetadata(buildQueueDashboardSummary(repoRoot));
485
488
  const today = new Date().toISOString().slice(0, 10);
486
489
  const telemetryDaily = sanitizeMissionControlMetadata(readJsonObjectIfPresent(join(repoRoot, ".pi", "logs", "summaries", `${today}.json`))) as Record<string, unknown> | undefined;
487
- const autonomyAudit = readJsonObjectIfPresent(join(repoRoot, "reports", "autonomy-readiness-audit-smoke.json"));
488
- const factoryRegistryAudit = readJsonObjectIfPresent(join(repoRoot, "reports", "factory-registry-readiness-audit-smoke.json"));
490
+ const autonomyAudit = readJsonObjectIfPresent(firstExistingArtifactPath(repoRoot, "reports", "autonomy-readiness-audit-smoke.json"));
491
+ const factoryRegistryAudit = readJsonObjectIfPresent(firstExistingArtifactPath(repoRoot, "reports", "factory-registry-readiness-audit-smoke.json"));
489
492
  const computeProfiles = summarizeComputeProfileArtifacts(repoRoot, limit);
490
493
  const adaptiveWorkflows = summarizeAdaptiveWorkflowArtifacts(repoRoot, limit);
491
494
  const promotionCandidates = summarizePromotionCandidates(repoRoot, limit);