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