owlrunkit 0.19.2 → 0.20.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.
@@ -0,0 +1,906 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+
4
+ import {
5
+ decodeUtf8Strict,
6
+ readFileBytesBounded,
7
+ } from "../../packages/attest/src/formal.mjs";
8
+ import { parseJsonStrict } from "./quick-canonical.mjs";
9
+ import {
10
+ normalizeTeamProjectDefinitionV1,
11
+ readTeamProjectStatusV3,
12
+ teamProjectDefinitionBindingV1,
13
+ } from "./team-project.mjs";
14
+
15
+ const AUTHORITY_BOUNDARY = Object.freeze({
16
+ agentDispatch: false,
17
+ git: false,
18
+ release: false,
19
+ deployment: false,
20
+ production: false,
21
+ business: false,
22
+ automation: false,
23
+ money: false,
24
+ });
25
+
26
+ const ACCEPTANCE_LEVELS = new Set(["L0", "L1", "L2", "L3"]);
27
+ const SECOND_ORDER_RISKS = new Set(["low", "medium", "high"]);
28
+ const JUDGMENT_LEVELS = new Set(["low", "medium", "high"]);
29
+ const CONTEXT_DEPTHS = new Set(["local", "cross-module", "product-wide"]);
30
+ const SURFACE_WIDTHS = new Set(["narrow", "multi-module", "product-wide"]);
31
+ const DETERMINISM_LEVELS = new Set(["deterministic", "mixed", "exploratory"]);
32
+ const AUTHORITY_SPANS = new Set(["source-only", "integration", "runtime", "production"]);
33
+ const WORKTREE_MODES = new Set(["new_clean_worktree", "existing_dirty_candidate"]);
34
+ const ACCEPTANCE_VERDICTS = new Set(["ACCEPT", "REWORK", "BLOCKED"]);
35
+ const INDEPENDENCE_STATUSES = new Set([
36
+ "independent",
37
+ "same_family_not_independent",
38
+ "control_tower",
39
+ ]);
40
+ const TRANSFER_LIFECYCLES = new Set([
41
+ "candidate_active",
42
+ "transfer_requested",
43
+ "packet_generated",
44
+ "new_owner_validation",
45
+ "handoff_ack",
46
+ "old_writer_release",
47
+ ]);
48
+ const TRANSFER_VERIFICATION_STATUSES = new Set([
49
+ "source_candidate_unverified",
50
+ "source_candidate_verified",
51
+ "accepted",
52
+ "rework_required",
53
+ ]);
54
+ const PACKET_KINDS = new Map([
55
+ ["OwlCodaRunKitTeamTaskPacketV2", "task"],
56
+ ["OwlCodaRunKitTeamAcceptancePacketV2", "acceptance"],
57
+ ["OwlCodaRunKitCandidateTransferPacketV1", "transfer"],
58
+ ]);
59
+
60
+ function isRecord(value) {
61
+ return value !== null && typeof value === "object" && !Array.isArray(value);
62
+ }
63
+
64
+ function exactKeys(value, keys) {
65
+ return isRecord(value)
66
+ && Object.keys(value).sort().join("\0") === [...keys].sort().join("\0");
67
+ }
68
+
69
+ function nonEmptyString(value) {
70
+ return typeof value === "string" && value.length > 0;
71
+ }
72
+
73
+ function nullableString(value) {
74
+ return value === null || nonEmptyString(value);
75
+ }
76
+
77
+ function id(value) {
78
+ return nonEmptyString(value) && /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u.test(value);
79
+ }
80
+
81
+ function sha256Ref(value) {
82
+ return typeof value === "string" && /^sha256:[a-f0-9]{64}$/u.test(value);
83
+ }
84
+
85
+ function artifactSha256Ref(value) {
86
+ return typeof value === "string" && /^artifact:sha256:[a-f0-9]{64}$/u.test(value);
87
+ }
88
+
89
+ function gitRef(value) {
90
+ return typeof value === "string" && /^git:[a-f0-9]{40}(?:[a-f0-9]{24})?$/u.test(value);
91
+ }
92
+
93
+ function projectTruthHash(value) {
94
+ return typeof value === "string" && /^[a-f0-9]{64}$/u.test(value);
95
+ }
96
+
97
+ function absolutePath(value) {
98
+ return nonEmptyString(value)
99
+ && (path.isAbsolute(value) || path.win32.isAbsolute(value));
100
+ }
101
+
102
+ function stringArray(value, { allowEmpty = true } = {}) {
103
+ return Array.isArray(value)
104
+ && (allowEmpty || value.length > 0)
105
+ && value.every(nonEmptyString)
106
+ && new Set(value).size === value.length;
107
+ }
108
+
109
+ function nonnegativeInteger(value) {
110
+ return Number.isSafeInteger(value) && value >= 0;
111
+ }
112
+
113
+ function nullableIsoUtc(value) {
114
+ return value === null || (
115
+ typeof value === "string"
116
+ && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/u.test(value)
117
+ && !Number.isNaN(Date.parse(value))
118
+ );
119
+ }
120
+
121
+ function sameStringSet(left, right) {
122
+ return stringArray(left)
123
+ && stringArray(right)
124
+ && left.length === right.length
125
+ && [...left].sort().every((value, index) => value === [...right].sort()[index]);
126
+ }
127
+
128
+ function validAuthorityBoundary(value) {
129
+ return exactKeys(value, Object.keys(AUTHORITY_BOUNDARY))
130
+ && Object.entries(AUTHORITY_BOUNDARY).every(([key, expected]) => value[key] === expected);
131
+ }
132
+
133
+ function commonPacketContractValid(packet, expectedKeys) {
134
+ return exactKeys(packet, expectedKeys)
135
+ && validAuthorityBoundary(packet.authorityBoundary)
136
+ && packet.authorizationGranted === false;
137
+ }
138
+
139
+ function projectBindingValid(value) {
140
+ return exactKeys(value, ["projectId", "projectTruthHash"])
141
+ && id(value.projectId)
142
+ && projectTruthHash(value.projectTruthHash);
143
+ }
144
+
145
+ function actorValid(value) {
146
+ return exactKeys(value, ["executingAgent", "modelFamily", "modelVersion", "role"])
147
+ && id(value.executingAgent)
148
+ && nonEmptyString(value.modelFamily)
149
+ && nonEmptyString(value.modelVersion)
150
+ && nonEmptyString(value.role);
151
+ }
152
+
153
+ function modelIdentityValid(value) {
154
+ return exactKeys(value, ["agent", "modelFamily", "modelVersion"])
155
+ && id(value.agent)
156
+ && nonEmptyString(value.modelFamily)
157
+ && nonEmptyString(value.modelVersion);
158
+ }
159
+
160
+ function taskPacketContractValid(packet) {
161
+ return commonPacketContractValid(packet, [
162
+ "schemaVersion",
163
+ "packetId",
164
+ "projectBinding",
165
+ "gateId",
166
+ "observableSuccess",
167
+ "workItem",
168
+ "actor",
169
+ "risk",
170
+ "acceptance",
171
+ "entry",
172
+ "scope",
173
+ "evidence",
174
+ "verificationCadence",
175
+ "handoff",
176
+ "escalationBudget",
177
+ "stop",
178
+ "authorityBoundary",
179
+ "authorizationGranted",
180
+ ])
181
+ && packet.schemaVersion === "OwlCodaRunKitTeamTaskPacketV2"
182
+ && id(packet.packetId)
183
+ && projectBindingValid(packet.projectBinding)
184
+ && id(packet.gateId)
185
+ && nonEmptyString(packet.observableSuccess)
186
+ && exactKeys(packet.workItem, ["workItemId", "title", "dependencies", "ownedPaths"])
187
+ && id(packet.workItem.workItemId)
188
+ && nonEmptyString(packet.workItem.title)
189
+ && stringArray(packet.workItem.dependencies)
190
+ && stringArray(packet.workItem.ownedPaths, { allowEmpty: false })
191
+ && actorValid(packet.actor)
192
+ && exactKeys(packet.risk, [
193
+ "productJudgment",
194
+ "semanticAmbiguity",
195
+ "contextDepth",
196
+ "surfaceWidth",
197
+ "determinism",
198
+ "secondOrderRisk",
199
+ "authoritySpan",
200
+ ])
201
+ && JUDGMENT_LEVELS.has(packet.risk.productJudgment)
202
+ && JUDGMENT_LEVELS.has(packet.risk.semanticAmbiguity)
203
+ && CONTEXT_DEPTHS.has(packet.risk.contextDepth)
204
+ && SURFACE_WIDTHS.has(packet.risk.surfaceWidth)
205
+ && DETERMINISM_LEVELS.has(packet.risk.determinism)
206
+ && SECOND_ORDER_RISKS.has(packet.risk.secondOrderRisk)
207
+ && AUTHORITY_SPANS.has(packet.risk.authoritySpan)
208
+ && exactKeys(packet.acceptance, [
209
+ "requiredLevel",
210
+ "implementationModelFamily",
211
+ "implementationModelVersion",
212
+ "verificationModelFamily",
213
+ "verificationModelVersion",
214
+ "sameFamilyAllowed",
215
+ "freshAdversarialFamilies",
216
+ ])
217
+ && ACCEPTANCE_LEVELS.has(packet.acceptance.requiredLevel)
218
+ && nonEmptyString(packet.acceptance.implementationModelFamily)
219
+ && nonEmptyString(packet.acceptance.implementationModelVersion)
220
+ && nonEmptyString(packet.acceptance.verificationModelFamily)
221
+ && nonEmptyString(packet.acceptance.verificationModelVersion)
222
+ && typeof packet.acceptance.sameFamilyAllowed === "boolean"
223
+ && stringArray(packet.acceptance.freshAdversarialFamilies)
224
+ && exactKeys(packet.entry, [
225
+ "worktreeMode",
226
+ "worktree",
227
+ "branch",
228
+ "baseSha",
229
+ "candidateIdentity",
230
+ "dirtyStateManifest",
231
+ "soleWriter",
232
+ "upstreamAcceptedPackets",
233
+ ])
234
+ && WORKTREE_MODES.has(packet.entry.worktreeMode)
235
+ && absolutePath(packet.entry.worktree)
236
+ && nonEmptyString(packet.entry.branch)
237
+ && gitRef(packet.entry.baseSha)
238
+ && sha256Ref(packet.entry.candidateIdentity)
239
+ && sha256Ref(packet.entry.dirtyStateManifest)
240
+ && id(packet.entry.soleWriter)
241
+ && stringArray(packet.entry.upstreamAcceptedPackets)
242
+ && exactKeys(packet.scope, [
243
+ "allowedChangedPaths",
244
+ "prohibitedPathsAndActions",
245
+ "protectedArtifactsAndAuthority",
246
+ ])
247
+ && stringArray(packet.scope.allowedChangedPaths, { allowEmpty: false })
248
+ && stringArray(packet.scope.prohibitedPathsAndActions)
249
+ && stringArray(packet.scope.protectedArtifactsAndAuthority)
250
+ && exactKeys(packet.evidence, [
251
+ "positiveEvidence",
252
+ "negativeAndSecondOrderTests",
253
+ "deliveryPacketFields",
254
+ ])
255
+ && stringArray(packet.evidence.positiveEvidence)
256
+ && stringArray(packet.evidence.negativeAndSecondOrderTests)
257
+ && stringArray(packet.evidence.deliveryPacketFields)
258
+ && exactKeys(packet.verificationCadence, [
259
+ "microBatchId",
260
+ "closureHypothesis",
261
+ "includedChanges",
262
+ "implementationSmoke",
263
+ "frozenCandidateFocusedGate",
264
+ "candidateCloseoutChecks",
265
+ "independentAdversarialDelta",
266
+ "deferredTransitionGates",
267
+ "trustedReceipts",
268
+ "receiptInvalidationTriggers",
269
+ ])
270
+ && id(packet.verificationCadence.microBatchId)
271
+ && nonEmptyString(packet.verificationCadence.closureHypothesis)
272
+ && stringArray(packet.verificationCadence.includedChanges)
273
+ && stringArray(packet.verificationCadence.implementationSmoke)
274
+ && stringArray(packet.verificationCadence.frozenCandidateFocusedGate)
275
+ && stringArray(packet.verificationCadence.candidateCloseoutChecks)
276
+ && stringArray(packet.verificationCadence.independentAdversarialDelta)
277
+ && stringArray(packet.verificationCadence.deferredTransitionGates)
278
+ && stringArray(packet.verificationCadence.trustedReceipts)
279
+ && stringArray(packet.verificationCadence.receiptInvalidationTriggers)
280
+ && exactKeys(packet.handoff, ["required", "nextOwner"])
281
+ && typeof packet.handoff.required === "boolean"
282
+ && nullableString(packet.handoff.nextOwner)
283
+ && (!packet.handoff.required || id(packet.handoff.nextOwner))
284
+ && exactKeys(packet.escalationBudget, [
285
+ "implementationAttempts",
286
+ "narrowRework",
287
+ "harnessFailure",
288
+ "controllerIntervention",
289
+ "semanticEscape",
290
+ ])
291
+ && nonnegativeInteger(packet.escalationBudget.implementationAttempts)
292
+ && packet.escalationBudget.implementationAttempts > 0
293
+ && nonnegativeInteger(packet.escalationBudget.narrowRework)
294
+ && nonnegativeInteger(packet.escalationBudget.harnessFailure)
295
+ && nonnegativeInteger(packet.escalationBudget.controllerIntervention)
296
+ && packet.escalationBudget.semanticEscape === 0
297
+ && exactKeys(packet.stop, ["exactStopPoint", "nextGateProhibited"])
298
+ && nonEmptyString(packet.stop.exactStopPoint)
299
+ && nullableString(packet.stop.nextGateProhibited);
300
+ }
301
+
302
+ function findingValid(value) {
303
+ return exactKeys(value, ["severity", "code", "message", "evidenceRefs"])
304
+ && new Set(["critical", "important", "minor", "note"]).has(value.severity)
305
+ && id(value.code)
306
+ && nonEmptyString(value.message)
307
+ && stringArray(value.evidenceRefs);
308
+ }
309
+
310
+ function acceptancePacketContractValid(packet) {
311
+ return commonPacketContractValid(packet, [
312
+ "schemaVersion",
313
+ "packetId",
314
+ "projectBinding",
315
+ "gateId",
316
+ "workItemId",
317
+ "candidateId",
318
+ "taskPacketSha256",
319
+ "implementation",
320
+ "verification",
321
+ "secondOrderRisk",
322
+ "independenceStatus",
323
+ "acceptanceLevel",
324
+ "candidateIdentityBefore",
325
+ "candidateIdentityAfter",
326
+ "freshAdversarialFamilies",
327
+ "coverageLedger",
328
+ "protectedArtifactReadback",
329
+ "productionWriteCount",
330
+ "findings",
331
+ "verdict",
332
+ "allowedNextGate",
333
+ "remainingAcceptanceLevels",
334
+ "authorityBoundary",
335
+ "authorizationGranted",
336
+ ])
337
+ && packet.schemaVersion === "OwlCodaRunKitTeamAcceptancePacketV2"
338
+ && id(packet.packetId)
339
+ && projectBindingValid(packet.projectBinding)
340
+ && id(packet.gateId)
341
+ && id(packet.workItemId)
342
+ && id(packet.candidateId)
343
+ && sha256Ref(packet.taskPacketSha256)
344
+ && modelIdentityValid(packet.implementation)
345
+ && modelIdentityValid(packet.verification)
346
+ && SECOND_ORDER_RISKS.has(packet.secondOrderRisk)
347
+ && INDEPENDENCE_STATUSES.has(packet.independenceStatus)
348
+ && ACCEPTANCE_LEVELS.has(packet.acceptanceLevel)
349
+ && sha256Ref(packet.candidateIdentityBefore)
350
+ && sha256Ref(packet.candidateIdentityAfter)
351
+ && stringArray(packet.freshAdversarialFamilies)
352
+ && exactKeys(packet.coverageLedger, [
353
+ "evidenceReused",
354
+ "checksRunFresh",
355
+ "coveredChecksNotRepeated",
356
+ "receiptInvalidations",
357
+ "deferredTransitionGates",
358
+ ])
359
+ && stringArray(packet.coverageLedger.evidenceReused)
360
+ && stringArray(packet.coverageLedger.checksRunFresh)
361
+ && stringArray(packet.coverageLedger.coveredChecksNotRepeated)
362
+ && stringArray(packet.coverageLedger.receiptInvalidations)
363
+ && stringArray(packet.coverageLedger.deferredTransitionGates)
364
+ && stringArray(packet.protectedArtifactReadback)
365
+ && nonnegativeInteger(packet.productionWriteCount)
366
+ && Array.isArray(packet.findings)
367
+ && packet.findings.every(findingValid)
368
+ && ACCEPTANCE_VERDICTS.has(packet.verdict)
369
+ && nullableString(packet.allowedNextGate)
370
+ && stringArray(packet.remainingAcceptanceLevels)
371
+ && packet.remainingAcceptanceLevels.every(level => ACCEPTANCE_LEVELS.has(level));
372
+ }
373
+
374
+ function handoffAckValid(value) {
375
+ return exactKeys(value, ["status", "agent", "occurredAt", "evidenceRefs"])
376
+ && new Set(["pending", "accepted", "rejected"]).has(value.status)
377
+ && (value.agent === null || id(value.agent))
378
+ && nullableIsoUtc(value.occurredAt)
379
+ && stringArray(value.evidenceRefs)
380
+ && (value.status === "pending"
381
+ ? value.agent === null && value.occurredAt === null && value.evidenceRefs.length === 0
382
+ : value.agent !== null && value.occurredAt !== null);
383
+ }
384
+
385
+ function transferPacketContractValid(packet) {
386
+ return commonPacketContractValid(packet, [
387
+ "schemaVersion",
388
+ "packetId",
389
+ "projectBinding",
390
+ "gateId",
391
+ "workItemId",
392
+ "candidateId",
393
+ "candidateSha256",
394
+ "baseSha",
395
+ "head",
396
+ "branch",
397
+ "worktree",
398
+ "dirtyManifestSha256",
399
+ "patchBundleRef",
400
+ "snapshotRef",
401
+ "reconstructionRefs",
402
+ "protectedArtifacts",
403
+ "previousOwner",
404
+ "nextOwner",
405
+ "lifecycle",
406
+ "handoffAck",
407
+ "verificationStatus",
408
+ "authorityBoundary",
409
+ "authorizationGranted",
410
+ ])
411
+ && packet.schemaVersion === "OwlCodaRunKitCandidateTransferPacketV1"
412
+ && id(packet.packetId)
413
+ && projectBindingValid(packet.projectBinding)
414
+ && id(packet.gateId)
415
+ && id(packet.workItemId)
416
+ && id(packet.candidateId)
417
+ && sha256Ref(packet.candidateSha256)
418
+ && gitRef(packet.baseSha)
419
+ && gitRef(packet.head)
420
+ && nonEmptyString(packet.branch)
421
+ && absolutePath(packet.worktree)
422
+ && sha256Ref(packet.dirtyManifestSha256)
423
+ && (packet.patchBundleRef === null || artifactSha256Ref(packet.patchBundleRef))
424
+ && artifactSha256Ref(packet.snapshotRef)
425
+ && stringArray(packet.reconstructionRefs, { allowEmpty: false })
426
+ && stringArray(packet.protectedArtifacts)
427
+ && id(packet.previousOwner)
428
+ && id(packet.nextOwner)
429
+ && packet.previousOwner !== packet.nextOwner
430
+ && TRANSFER_LIFECYCLES.has(packet.lifecycle)
431
+ && handoffAckValid(packet.handoffAck)
432
+ && TRANSFER_VERIFICATION_STATUSES.has(packet.verificationStatus);
433
+ }
434
+
435
+ function pathPrefix(value) {
436
+ return value.endsWith("/**") ? value.slice(0, -3) : null;
437
+ }
438
+
439
+ function pathCovers(owner, candidate) {
440
+ if (owner === candidate) return true;
441
+ const prefix = pathPrefix(owner);
442
+ if (prefix === null) return false;
443
+ const candidatePrefix = pathPrefix(candidate) ?? candidate;
444
+ return candidatePrefix === prefix || candidatePrefix.startsWith(`${prefix}/`);
445
+ }
446
+
447
+ function conflictsBetween(left, right) {
448
+ const conflicts = [];
449
+ for (const leftPath of left.ownedPaths) {
450
+ for (const rightPath of right.ownedPaths) {
451
+ if (pathCovers(leftPath, rightPath) || pathCovers(rightPath, leftPath)) {
452
+ conflicts.push({
453
+ leftWorkItemId: left.workItemId,
454
+ leftPath,
455
+ rightWorkItemId: right.workItemId,
456
+ rightPath,
457
+ });
458
+ }
459
+ }
460
+ }
461
+ return conflicts;
462
+ }
463
+
464
+ function projectDefinitionPath(root) {
465
+ return path.join(path.resolve(root), ".owlcoda/runkit/project/definition.json");
466
+ }
467
+
468
+ function currentProjectStatus(workspaceRoot) {
469
+ if (!existsSync(projectDefinitionPath(workspaceRoot))) return null;
470
+ return readTeamProjectStatusV3({ workspaceRoot });
471
+ }
472
+
473
+ function readProjectDefinition(workspaceRoot) {
474
+ const { bytes } = readFileBytesBounded(projectDefinitionPath(workspaceRoot));
475
+ return normalizeTeamProjectDefinitionV1(parseJsonStrict(decodeUtf8Strict(bytes)));
476
+ }
477
+
478
+ function laneProjection(project) {
479
+ if (project === null) return [];
480
+ const ready = new Set(project.readyQueue);
481
+ return project.workItems
482
+ .filter(workItem => workItem.status !== "completed")
483
+ .map(workItem => {
484
+ const actionable = ready.has(workItem.workItemId)
485
+ || new Set([
486
+ "active",
487
+ "waiting_decision",
488
+ "verifying",
489
+ "ready_to_integrate",
490
+ "failed",
491
+ ]).has(workItem.status);
492
+ const coordinationFacts = [
493
+ ...(workItem.pendingHandoff ? ["pending_handoff"] : []),
494
+ ...(workItem.rework ? ["rework_active"] : []),
495
+ ...(workItem.latestSourceDelivery ? ["source_delivery_present"] : []),
496
+ ...(workItem.status === "verifying" ? ["independent_verification"] : []),
497
+ ];
498
+ return {
499
+ workItemId: workItem.workItemId,
500
+ title: workItem.title,
501
+ status: workItem.status,
502
+ agentId: workItem.agentId,
503
+ dependencies: [...workItem.dependencies],
504
+ unresolvedDependencies: [...workItem.unresolvedDependencies],
505
+ ownedPaths: [...workItem.ownedPaths],
506
+ actionable,
507
+ parallelEligible: false,
508
+ coordinationFacts,
509
+ };
510
+ });
511
+ }
512
+
513
+ function deriveProjection(project) {
514
+ const lanes = laneProjection(project);
515
+ const actionable = lanes.filter(lane => lane.actionable);
516
+ const pathConflicts = [];
517
+ for (let left = 0; left < actionable.length; left += 1) {
518
+ for (let right = left + 1; right < actionable.length; right += 1) {
519
+ pathConflicts.push(...conflictsBetween(actionable[left], actionable[right]));
520
+ }
521
+ }
522
+ const conflicted = new Set(pathConflicts.flatMap(conflict => [
523
+ conflict.leftWorkItemId,
524
+ conflict.rightWorkItemId,
525
+ ]));
526
+ for (const lane of lanes) {
527
+ lane.parallelEligible = actionable.length > 1
528
+ && lane.actionable
529
+ && !conflicted.has(lane.workItemId);
530
+ }
531
+ const acceptanceGaps = lanes
532
+ .filter(lane => lane.status === "verifying")
533
+ .map(lane => ({
534
+ workItemId: lane.workItemId,
535
+ code: "verification_model_family_unbound",
536
+ message: "Project Driver requires a different verifier Agent; model-family independence remains packet-bound.",
537
+ }));
538
+ const ownerTransitions = lanes
539
+ .filter(lane => lane.coordinationFacts.length > 0)
540
+ .map(lane => ({
541
+ workItemId: lane.workItemId,
542
+ facts: [...lane.coordinationFacts],
543
+ }));
544
+ return { lanes, actionable, pathConflicts, acceptanceGaps, ownerTransitions };
545
+ }
546
+
547
+ function uniqueSorted(values) {
548
+ return [...new Set(values)].sort();
549
+ }
550
+
551
+ function shellQuote(value) {
552
+ return `'${String(value).replaceAll("'", `'"'"'`)}'`;
553
+ }
554
+
555
+ function recommendationFromProject(project, workspaceRoot) {
556
+ const projection = deriveProjection(project);
557
+ const activeOwners = uniqueSorted(projection.actionable
558
+ .map(lane => lane.agentId)
559
+ .filter(value => value !== null));
560
+ const reasonCodes = [];
561
+ if (project === null) {
562
+ reasonCodes.push("project_driver_not_initialized");
563
+ } else if (projection.actionable.length === 0) {
564
+ reasonCodes.push("no_actionable_work_items");
565
+ } else if (projection.actionable.length === 1) {
566
+ reasonCodes.push("single_actionable_work_item");
567
+ }
568
+ if (projection.pathConflicts.length > 0) {
569
+ reasonCodes.push("owned_path_conflict_requires_coordination");
570
+ } else if (projection.actionable.length > 1) {
571
+ reasonCodes.push("multiple_independent_actionable_work_items");
572
+ }
573
+ if (activeOwners.length > 1) reasonCodes.push("multiple_active_owners");
574
+ if (projection.acceptanceGaps.length > 0) reasonCodes.push("independent_acceptance_lane");
575
+ if (projection.ownerTransitions.length > 0) reasonCodes.push("candidate_owner_transition");
576
+
577
+ const teamRecommended = projection.actionable.length > 1
578
+ || projection.pathConflicts.length > 0
579
+ || activeOwners.length > 1
580
+ || projection.acceptanceGaps.length > 0
581
+ || projection.ownerTransitions.length > 0;
582
+ const hasUnassignedActionable = projection.actionable.some(
583
+ lane => lane.agentId === null,
584
+ );
585
+ const nextCommand = projection.pathConflicts.length > 0
586
+ ? "npx --no-install owlrunkit project work-item revise-scope --help"
587
+ : teamRecommended && hasUnassignedActionable
588
+ ? "npx --no-install owlrunkit project assign --help"
589
+ : teamRecommended && projection.ownerTransitions.length > 0
590
+ ? "npx --no-install owlrunkit project takeover --help"
591
+ : teamRecommended
592
+ ? "npx --no-install owlrunkit team packet validate --help"
593
+ : project === null
594
+ ? null
595
+ : `npx --no-install owlrunkit project status --workspace ${shellQuote(workspaceRoot)}`;
596
+
597
+ return {
598
+ schemaVersion: "OwlCodaRunKitTeamRecommendationV1",
599
+ status: "team_delivery_recommended",
600
+ project: project === null
601
+ ? { present: false, projectId: null, projectTruthHash: null, overall: null }
602
+ : {
603
+ present: true,
604
+ projectId: project.projectId,
605
+ projectTruthHash: project.projectTruthHash,
606
+ overall: project.overall,
607
+ },
608
+ recommendedMode: teamRecommended ? "team" : "off",
609
+ continuity: project === null ? "none" : "project_driver",
610
+ coordination: teamRecommended ? "project_driver_team" : "none",
611
+ assurance: {
612
+ changed: false,
613
+ selection: "unchanged",
614
+ reason: "team_delivery_does_not_select_assurance",
615
+ },
616
+ reasonCodes: uniqueSorted(reasonCodes),
617
+ rejectedLighterModes: teamRecommended
618
+ ? [{ mode: "off", reasonCodes: uniqueSorted(reasonCodes) }]
619
+ : [],
620
+ lanes: projection.lanes,
621
+ pathConflicts: projection.pathConflicts,
622
+ acceptanceGaps: projection.acceptanceGaps,
623
+ ownerTransitions: projection.ownerTransitions,
624
+ estimatedOverhead: {
625
+ additionalOperatorSteps: teamRecommended ? 1 : 0,
626
+ potentialPortablePackets: teamRecommended ? projection.actionable.length : 0,
627
+ },
628
+ nextCommand,
629
+ dispatch: {
630
+ mode: "none",
631
+ permitted: false,
632
+ nextCommand: null,
633
+ },
634
+ authorityBoundary: { ...AUTHORITY_BOUNDARY },
635
+ authorizationGranted: false,
636
+ exitCode: 0,
637
+ };
638
+ }
639
+
640
+ export function recommendTeamDeliveryV1({ workspaceRoot } = {}) {
641
+ if (!nonEmptyString(workspaceRoot)) throw new Error("workspaceRoot is required.");
642
+ return recommendationFromProject(currentProjectStatus(workspaceRoot), workspaceRoot);
643
+ }
644
+
645
+ export function readTeamDeliveryStatusV1({ workspaceRoot } = {}) {
646
+ if (!nonEmptyString(workspaceRoot)) throw new Error("workspaceRoot is required.");
647
+ const project = currentProjectStatus(workspaceRoot);
648
+ const recommendation = recommendationFromProject(project, workspaceRoot);
649
+ return {
650
+ schemaVersion: "OwlCodaRunKitTeamDeliveryStatusV1",
651
+ status: "team_delivery_status",
652
+ graphSource: "project_driver",
653
+ persistedTeamGraph: false,
654
+ projectId: project?.projectId ?? null,
655
+ projectTruthHash: project?.projectTruthHash ?? null,
656
+ projectOverall: project?.overall ?? "not_initialized",
657
+ recommendation: {
658
+ recommendedMode: recommendation.recommendedMode,
659
+ coordination: recommendation.coordination,
660
+ reasonCodes: recommendation.reasonCodes,
661
+ },
662
+ lanes: recommendation.lanes,
663
+ pathConflicts: recommendation.pathConflicts,
664
+ acceptanceGaps: recommendation.acceptanceGaps,
665
+ ownerTransitions: recommendation.ownerTransitions,
666
+ nextAction: recommendation.nextCommand,
667
+ dispatch: { ...recommendation.dispatch },
668
+ authorityBoundary: { ...AUTHORITY_BOUNDARY },
669
+ authorizationGranted: false,
670
+ exitCode: 0,
671
+ };
672
+ }
673
+
674
+ function bindPacketToProject(packet, project, definition, issueCodes) {
675
+ if (!projectBindingValid(packet.projectBinding)) return;
676
+ if (project === null) {
677
+ issueCodes.push("packet_project_not_initialized");
678
+ return;
679
+ }
680
+ if (packet.projectBinding.projectId !== project.projectId) {
681
+ issueCodes.push("packet_project_id_mismatch");
682
+ }
683
+ if (packet.projectBinding.projectTruthHash !== project.projectTruthHash) {
684
+ issueCodes.push("packet_project_truth_mismatch");
685
+ }
686
+ const gate = id(packet.gateId)
687
+ ? definition.integrationGates.find(row => row.id === packet.gateId) ?? null
688
+ : null;
689
+ if (id(packet.gateId) && gate === null) {
690
+ issueCodes.push("packet_gate_unknown");
691
+ }
692
+ const workItemId = packet.schemaVersion === "OwlCodaRunKitTeamTaskPacketV2"
693
+ ? packet.workItem?.workItemId
694
+ : packet.workItemId;
695
+ const current = project.workItems.find(workItem => workItem.workItemId === workItemId);
696
+ if (!current) {
697
+ issueCodes.push("packet_work_item_unknown");
698
+ return;
699
+ }
700
+ if (gate !== null && !gate.requiredWorkItemIds.includes(workItemId)) {
701
+ issueCodes.push("packet_gate_work_item_mismatch");
702
+ }
703
+ if (packet.schemaVersion === "OwlCodaRunKitTeamTaskPacketV2") {
704
+ if (packet.workItem.title !== current.title
705
+ || !sameStringSet(packet.workItem.dependencies, current.dependencies)) {
706
+ issueCodes.push("packet_work_item_truth_mismatch");
707
+ }
708
+ if (!sameStringSet(packet.workItem.ownedPaths, current.ownedPaths)
709
+ || !sameStringSet(packet.scope.allowedChangedPaths, current.ownedPaths)) {
710
+ issueCodes.push("packet_owned_paths_mismatch");
711
+ }
712
+ }
713
+ }
714
+
715
+ export function validateTeamPacketV1({ workspaceRoot, packet } = {}) {
716
+ if (!nonEmptyString(workspaceRoot)) throw new Error("workspaceRoot is required.");
717
+ const kind = PACKET_KINDS.get(packet?.schemaVersion) ?? "unknown";
718
+ const contractValid = kind === "task"
719
+ ? taskPacketContractValid(packet)
720
+ : kind === "acceptance"
721
+ ? acceptancePacketContractValid(packet)
722
+ : kind === "transfer"
723
+ ? transferPacketContractValid(packet)
724
+ : false;
725
+ const issueCodes = [];
726
+ if (!contractValid) issueCodes.push("packet_contract_invalid");
727
+ if (contractValid) {
728
+ if (!existsSync(projectDefinitionPath(workspaceRoot))) {
729
+ bindPacketToProject(packet, null, null, issueCodes);
730
+ } else {
731
+ const definitionBefore = readProjectDefinition(workspaceRoot);
732
+ const projectBefore = currentProjectStatus(workspaceRoot);
733
+ const projectAfter = currentProjectStatus(workspaceRoot);
734
+ const definitionAfter = readProjectDefinition(workspaceRoot);
735
+ if (teamProjectDefinitionBindingV1(definitionBefore).projectDefinitionSha256
736
+ !== teamProjectDefinitionBindingV1(definitionAfter).projectDefinitionSha256
737
+ || projectBefore.projectTruthHash !== projectAfter.projectTruthHash) {
738
+ issueCodes.push("packet_project_truth_changed_during_validation");
739
+ } else {
740
+ bindPacketToProject(packet, projectAfter, definitionAfter, issueCodes);
741
+ }
742
+ }
743
+ if (kind === "task"
744
+ && new Set(["medium", "high"]).has(packet.risk.secondOrderRisk)
745
+ && packet.acceptance.sameFamilyAllowed) {
746
+ issueCodes.push("same_family_acceptance_forbidden_for_risk");
747
+ }
748
+ if (kind === "task") {
749
+ if (packet.actor.executingAgent !== packet.entry.soleWriter) {
750
+ issueCodes.push("task_sole_writer_mismatch");
751
+ }
752
+ if (packet.actor.modelFamily !== packet.acceptance.implementationModelFamily
753
+ || packet.actor.modelVersion !== packet.acceptance.implementationModelVersion) {
754
+ issueCodes.push("task_implementation_identity_mismatch");
755
+ }
756
+ if (new Set(["medium", "high"]).has(packet.risk.secondOrderRisk)
757
+ && packet.actor.modelFamily === packet.acceptance.verificationModelFamily) {
758
+ issueCodes.push("planned_acceptance_same_model_family");
759
+ }
760
+ }
761
+ if (kind === "acceptance") {
762
+ const requiresIndependence = new Set(["medium", "high"]).has(packet.secondOrderRisk);
763
+ if (requiresIndependence
764
+ && packet.independenceStatus === "independent"
765
+ && packet.implementation.modelFamily === packet.verification.modelFamily) {
766
+ issueCodes.push("independent_acceptance_same_model_family");
767
+ }
768
+ if (requiresIndependence
769
+ && packet.independenceStatus === "independent"
770
+ && packet.implementation.agent === packet.verification.agent) {
771
+ issueCodes.push("independent_acceptance_same_agent");
772
+ }
773
+ if (packet.independenceStatus === "independent"
774
+ && packet.implementation.modelFamily === packet.verification.modelFamily) {
775
+ issueCodes.push("independence_status_inconsistent");
776
+ }
777
+ if (packet.independenceStatus === "same_family_not_independent"
778
+ && packet.implementation.modelFamily !== packet.verification.modelFamily) {
779
+ issueCodes.push("independence_status_inconsistent");
780
+ }
781
+ if (requiresIndependence
782
+ && packet.verdict === "ACCEPT"
783
+ && (
784
+ packet.implementation.modelFamily === packet.verification.modelFamily
785
+ || packet.implementation.agent === packet.verification.agent
786
+ )) {
787
+ issueCodes.push("accepted_packet_requires_independent_verifier");
788
+ }
789
+ if (packet.verdict === "ACCEPT"
790
+ && packet.candidateIdentityBefore !== packet.candidateIdentityAfter) {
791
+ issueCodes.push("accepted_candidate_identity_drift");
792
+ }
793
+ if (packet.verdict === "ACCEPT"
794
+ && packet.acceptanceLevel !== "L0"
795
+ && (
796
+ packet.freshAdversarialFamilies.length === 0
797
+ || packet.coverageLedger.checksRunFresh.length === 0
798
+ )) {
799
+ issueCodes.push("accepted_packet_requires_fresh_adversarial_evidence");
800
+ }
801
+ }
802
+ if (kind === "transfer") {
803
+ if (packet.handoffAck.status === "accepted"
804
+ && (
805
+ packet.handoffAck.agent !== packet.nextOwner
806
+ || packet.handoffAck.evidenceRefs.length === 0
807
+ )) {
808
+ issueCodes.push("accepted_handoff_ack_invalid");
809
+ }
810
+ if (packet.lifecycle === "old_writer_release"
811
+ && (
812
+ packet.handoffAck.status !== "accepted"
813
+ || packet.handoffAck.agent !== packet.nextOwner
814
+ || packet.handoffAck.evidenceRefs.length === 0
815
+ )) {
816
+ issueCodes.push("old_writer_release_requires_accepted_handoff_ack");
817
+ }
818
+ if (packet.lifecycle === "handoff_ack"
819
+ && (
820
+ packet.handoffAck.status !== "accepted"
821
+ || packet.handoffAck.agent !== packet.nextOwner
822
+ || packet.handoffAck.evidenceRefs.length === 0
823
+ )) {
824
+ issueCodes.push("handoff_ack_lifecycle_requires_accepted_ack");
825
+ }
826
+ }
827
+ }
828
+ const uniqueIssues = uniqueSorted(issueCodes);
829
+ return {
830
+ schemaVersion: "OwlCodaRunKitTeamPacketValidationV1",
831
+ status: uniqueIssues.length === 0 ? "team_packet_valid" : "team_packet_invalid",
832
+ packetKind: kind,
833
+ packetSchemaVersion: packet?.schemaVersion ?? null,
834
+ issueCodes: uniqueIssues,
835
+ authorityBoundary: { ...AUTHORITY_BOUNDARY },
836
+ authorizationGranted: false,
837
+ exitCode: uniqueIssues.length === 0 ? 0 : 2,
838
+ };
839
+ }
840
+
841
+ export function validateTeamPacketFileV1({ workspaceRoot, packetPath } = {}) {
842
+ if (!nonEmptyString(packetPath)) throw new Error("packetPath is required.");
843
+ try {
844
+ const { bytes } = readFileBytesBounded(packetPath);
845
+ const packet = parseJsonStrict(decodeUtf8Strict(bytes));
846
+ return validateTeamPacketV1({ workspaceRoot, packet });
847
+ } catch (error) {
848
+ const duplicate = error?.code === "receipt_duplicate_key"
849
+ || error?.code === "DUPLICATE_OBJECT_KEY";
850
+ return {
851
+ schemaVersion: "OwlCodaRunKitTeamPacketValidationV1",
852
+ status: "team_packet_invalid",
853
+ packetKind: "unknown",
854
+ packetSchemaVersion: null,
855
+ issueCodes: [duplicate ? "packet_duplicate_object_key" : "packet_unreadable"],
856
+ authorityBoundary: { ...AUTHORITY_BOUNDARY },
857
+ authorizationGranted: false,
858
+ exitCode: 2,
859
+ };
860
+ }
861
+ }
862
+
863
+ export function formatTeamDeliveryRecommendationHumanV1(result) {
864
+ return [
865
+ `Recommended Team mode: ${result.recommendedMode}`,
866
+ `Continuity: ${result.continuity}`,
867
+ `Coordination: ${result.coordination}`,
868
+ `Why: ${result.reasonCodes.join(", ") || "none"}`,
869
+ `Lanes: ${result.lanes.length}`,
870
+ `Path conflicts: ${result.pathConflicts.length}`,
871
+ `Acceptance gaps: ${result.acceptanceGaps.length}`,
872
+ `Next: ${result.nextCommand ?? "none"}`,
873
+ "Agent dispatch: not permitted.",
874
+ "Authority: no Git, release, deployment, production, business, automation, or money authorization granted.",
875
+ "",
876
+ ].join("\n");
877
+ }
878
+
879
+ export function formatTeamDeliveryStatusHumanV1(result) {
880
+ return [
881
+ `Team Delivery: ${result.recommendation.recommendedMode}`,
882
+ `Project: ${result.projectId ?? "not initialized"}`,
883
+ `Project state: ${result.projectOverall}`,
884
+ `Graph source: ${result.graphSource}`,
885
+ `Persisted team graph: ${result.persistedTeamGraph ? "yes" : "no"}`,
886
+ `Lanes: ${result.lanes.length}`,
887
+ `Path conflicts: ${result.pathConflicts.length}`,
888
+ `Acceptance gaps: ${result.acceptanceGaps.length}`,
889
+ `Next: ${result.nextAction ?? "none"}`,
890
+ "Agent dispatch: not permitted.",
891
+ "Authority: not granted.",
892
+ "",
893
+ ].join("\n");
894
+ }
895
+
896
+ export function formatTeamPacketValidationHumanV1(result) {
897
+ return [
898
+ `Team packet: ${result.status}`,
899
+ `Kind: ${result.packetKind}`,
900
+ `Schema: ${result.packetSchemaVersion ?? "unknown"}`,
901
+ `Issues: ${result.issueCodes.join(", ") || "none"}`,
902
+ "Agent dispatch: not permitted.",
903
+ "Authority: not granted.",
904
+ "",
905
+ ].join("\n");
906
+ }