@mstar-harness/dsh 3.9.3 → 3.10.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 (44) hide show
  1. package/dist/gates/dispatch.d.ts +9 -3
  2. package/dist/index.js +734 -351
  3. package/harness-commands/iteration-drive.md +16 -2
  4. package/harness-skills/mstar-artifacts/SKILL.md +10 -6
  5. package/harness-skills/mstar-artifacts/references/plan-files-and-reports.md +1 -1
  6. package/harness-skills/mstar-artifacts/references/plan-quality-bar.md +10 -0
  7. package/harness-skills/mstar-artifacts/references/plan-workflow-lifecycle-contract.md +115 -0
  8. package/harness-skills/mstar-artifacts/references/status-and-residuals.md +85 -12
  9. package/harness-skills/mstar-artifacts/templates/plan.main.md +6 -1
  10. package/harness-skills/mstar-branch-worktree/SKILL.md +5 -4
  11. package/harness-skills/mstar-compound/SKILL.md +4 -4
  12. package/harness-skills/mstar-conventions/SKILL.md +1 -0
  13. package/harness-skills/mstar-conventions/references/effort-estimation.md +2 -0
  14. package/harness-skills/mstar-dispatch-gates/SKILL.md +11 -2
  15. package/harness-skills/mstar-harness-core/SKILL.md +2 -2
  16. package/harness-skills/mstar-host/SKILL.md +9 -2
  17. package/harness-skills/mstar-host/references/_shared/plan-mode-bridge-core.md +2 -0
  18. package/harness-skills/mstar-host/references/codex.md +1 -1
  19. package/harness-skills/mstar-host/references/dsh.md +14 -4
  20. package/harness-skills/mstar-host/references/omp.md +62 -2
  21. package/harness-skills/mstar-iteration/SKILL.md +13 -1
  22. package/harness-skills/mstar-iteration/references/command-shared-invariants.md +6 -0
  23. package/harness-skills/mstar-iteration/references/phase-1-prepare.md +2 -0
  24. package/harness-skills/mstar-iteration/references/phase-2-worktree-lease.md +121 -15
  25. package/harness-skills/mstar-iteration/references/phase-3-iteration-close.md +3 -3
  26. package/harness-skills/mstar-iteration/references/phase-4-5-pr-delivery.md +3 -2
  27. package/harness-skills/mstar-iteration/references/phase-6-post-merge-close.md +5 -2
  28. package/harness-skills/mstar-iteration/references/plan-scoped-pm.md +181 -0
  29. package/harness-skills/mstar-phase-gates/SKILL.md +7 -5
  30. package/harness-skills/mstar-project-governance/SKILL.md +3 -3
  31. package/harness-skills/mstar-review-qc/SKILL.md +4 -4
  32. package/harness-skills/mstar-review-qc/references/review-responsibility-boundaries.md +1 -1
  33. package/harness-skills/mstar-roles/references/_shared/leaf-executor-core.md +1 -0
  34. package/harness-skills/mstar-roles/references/project-manager/dispatch-and-assignment.md +12 -2
  35. package/harness-skills/mstar-roles/references/project-manager/plan-management.md +15 -0
  36. package/harness-skills/mstar-roles/references/project-manager/qa-trigger-matrix.md +3 -3
  37. package/harness-skills/mstar-roles/references/project-manager/qc-and-residuals.md +7 -5
  38. package/harness-skills/mstar-roles/references/project-manager.md +12 -4
  39. package/harness-skills/mstar-sdd/SKILL.md +8 -3
  40. package/harness-skills/mstar-sdd/references/file-handoffs.md +1 -0
  41. package/harness-skills/mstar-sdd/references/implementer-continuation-prompt.md +4 -1
  42. package/harness-skills/mstar-sdd/references/implementer-prompt.md +4 -0
  43. package/harness-skills/pm/SKILL.md +2 -0
  44. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -75,7 +75,7 @@ var require_lib = __commonJS(function(exports, module) {
75
75
  is: () => is,
76
76
  isNonNullable: () => isNonNullable,
77
77
  isNullable: () => isNullable,
78
- isPlainObject: () => isPlainObject6,
78
+ isPlainObject: () => isPlainObject4,
79
79
  makeArray: () => makeArray,
80
80
  mapValues: () => mapValues,
81
81
  noop: () => noop,
@@ -98,7 +98,7 @@ var require_lib = __commonJS(function(exports, module) {
98
98
  function isNonNullable(value) {
99
99
  return !isNullable(value);
100
100
  }
101
- function isPlainObject6(data) {
101
+ function isPlainObject4(data) {
102
102
  return data && typeof data === "object" && !Array.isArray(data);
103
103
  }
104
104
  function filterKeys(object, filter) {
@@ -679,7 +679,7 @@ var require_lib2 = __commonJS(function(exports, module) {
679
679
  Schema.extend = /* @__PURE__ */ __name(function extend(type, resolve22) {
680
680
  resolvers[type] = resolve22;
681
681
  }, "extend");
682
- Schema.resolve = /* @__PURE__ */ __name(function resolve4(data, schema, options = {}, strict = false) {
682
+ Schema.resolve = /* @__PURE__ */ __name(function resolve5(data, schema, options = {}, strict = false) {
683
683
  if (!schema)
684
684
  return [data];
685
685
  if (options.ignore?.(data, schema))
@@ -1122,8 +1122,8 @@ var require_lib2 = __commonJS(function(exports, module) {
1122
1122
  });
1123
1123
 
1124
1124
  // src/index.ts
1125
- import { existsSync as existsSync24, readFileSync as readFileSync19, readdirSync as readdirSync14 } from "node:fs";
1126
- import { join as join28 } from "node:path";
1125
+ import { existsSync as existsSync24, readFileSync as readFileSync19, readdirSync as readdirSync15 } from "node:fs";
1126
+ import { join as join29 } from "node:path";
1127
1127
  import { fileURLToPath as fileURLToPath3 } from "node:url";
1128
1128
  import {
1129
1129
  apply as applySkillLocal,
@@ -1138,28 +1138,30 @@ import { basename, dirname, join, resolve } from "node:path";
1138
1138
  import { fileURLToPath } from "node:url";
1139
1139
  import { readFileSync as readFileSync2, statSync } from "node:fs";
1140
1140
  import { dirname as dirname2, isAbsolute, join as join2, relative, resolve as resolve2 } from "node:path";
1141
- import { existsSync as existsSync7, mkdirSync as mkdirSync5, readdirSync as readdirSync5, readFileSync as readFileSync7, realpathSync as realpathSync2, statSync as statSync3, writeFileSync as writeFileSync3 } from "node:fs";
1141
+ import { existsSync as existsSync8, mkdirSync as mkdirSync5, readdirSync as readdirSync6, readFileSync as readFileSync8, realpathSync as realpathSync3, statSync as statSync3, writeFileSync as writeFileSync3 } from "node:fs";
1142
1142
  import { execFileSync } from "node:child_process";
1143
- import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute5, join as join9, relative as relative2, resolve as resolve7 } from "node:path";
1144
- import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "node:fs";
1145
- import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as readdirSync2, realpathSync } from "node:fs";
1146
- import { dirname as dirname4, join as join6, resolve as resolve5, sep } from "node:path";
1143
+ import { basename as basename5, dirname as dirname6, isAbsolute as isAbsolute6, join as join10, relative as relative2, resolve as resolve9 } from "node:path";
1144
+ import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync6 } from "node:fs";
1145
+ import { existsSync as existsSync5, readFileSync as readFileSync5, readdirSync as readdirSync3, realpathSync as realpathSync2 } from "node:fs";
1146
+ import { dirname as dirname5, join as join7, resolve as resolve7, sep as sep2 } from "node:path";
1147
1147
  import { dirname as dirname3, isAbsolute as isAbsolute2, join as join3, resolve as resolve3 } from "node:path";
1148
1148
  import { AsyncLocalStorage } from "node:async_hooks";
1149
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3 } from "node:fs";
1150
- import { isAbsolute as isAbsolute4, join as join5 } from "node:path";
1149
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
1150
+ import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute3, join as join4, resolve as resolve4 } from "node:path";
1151
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, readdirSync as readdirSync2, rmdirSync as rmdirSync2 } from "node:fs";
1152
+ import { isAbsolute as isAbsolute5, join as join6, resolve as resolve6 } from "node:path";
1151
1153
  import { execFileSync as execFileSync2 } from "node:child_process";
1152
- import { existsSync as existsSync8, realpathSync as realpathSync3 } from "node:fs";
1153
- import { isAbsolute as isAbsolute6, join as join10, resolve as resolve8 } from "node:path";
1154
- import { existsSync as existsSync9 } from "node:fs";
1155
- import { join as join11, dirname as dirname7 } from "node:path";
1154
+ import { existsSync as existsSync9, realpathSync as realpathSync4 } from "node:fs";
1155
+ import { isAbsolute as isAbsolute7, join as join11, resolve as resolve10 } from "node:path";
1156
+ import { existsSync as existsSync10 } from "node:fs";
1157
+ import { join as join12, dirname as dirname8 } from "node:path";
1156
1158
  import { execFileSync as execFileSync3, spawn } from "node:child_process";
1157
- import { mkdirSync as mkdirSync6, readdirSync as readdirSync6, readFileSync as readFileSync8, realpathSync as realpathSync4, statSync as statSync4, writeFileSync as writeFileSync4 } from "node:fs";
1158
- import { basename as basename5, dirname as dirname8, isAbsolute as isAbsolute7, join as join12, relative as relative3, resolve as resolve9 } from "node:path";
1159
- import { existsSync as existsSync12, readdirSync as readdirSync9, readFileSync as readFileSync11 } from "node:fs";
1160
- import { basename as basename8, isAbsolute as isAbsolute9, join as join16, relative as relative6, resolve as resolve13, sep as sep4 } from "node:path";
1161
- import { existsSync as existsSync13 } from "node:fs";
1162
- import { join as join17 } from "node:path";
1159
+ import { mkdirSync as mkdirSync6, readdirSync as readdirSync7, readFileSync as readFileSync9, realpathSync as realpathSync5, statSync as statSync4, writeFileSync as writeFileSync4 } from "node:fs";
1160
+ import { basename as basename7, dirname as dirname9, isAbsolute as isAbsolute8, join as join13, relative as relative3, resolve as resolve11 } from "node:path";
1161
+ import { existsSync as existsSync13, readdirSync as readdirSync10, readFileSync as readFileSync12 } from "node:fs";
1162
+ import { basename as basename11, isAbsolute as isAbsolute10, join as join17, relative as relative6, resolve as resolve15, sep as sep5 } from "node:path";
1163
+ import { existsSync as existsSync14 } from "node:fs";
1164
+ import { join as join18 } from "node:path";
1163
1165
  var SEVERITY_ORDER = ["critical", "high", "medium", "low", "nit"];
1164
1166
  function applyEnforcement(gate, opts) {
1165
1167
  return { ...gate, hardBlocked: opts.hard && gate.violations.length > 0 };
@@ -1395,6 +1397,302 @@ function verifyPlanExecutionLease(row, planId) {
1395
1397
  return { ok: violations.length === 0, violations, lease };
1396
1398
  }
1397
1399
  var heldLockDirs = new AsyncLocalStorage;
1400
+ function isPlainObject2(value) {
1401
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1402
+ }
1403
+ function isNonEmptyString(value) {
1404
+ return typeof value === "string" && value.trim() !== "";
1405
+ }
1406
+ var writeAuthorizations = new AsyncLocalStorage2;
1407
+ var HANDOFF_STATES = [
1408
+ "submitted",
1409
+ "accepted",
1410
+ "returned",
1411
+ "integrating",
1412
+ "merged",
1413
+ "completed"
1414
+ ];
1415
+ var PLAN_PROGRESS_STATUSES = ["InProgress", "InReview", "Blocked"];
1416
+ var SHA256_HEX = /^[0-9a-f]{64}$/;
1417
+ var GIT_SHA = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/;
1418
+ function invalid(code, message) {
1419
+ return { ok: false, severity: "high", code, message };
1420
+ }
1421
+ function validateBinding(value, what) {
1422
+ if (!isPlainObject2(value))
1423
+ return [invalid("coordination.row.binding-shape", `${what} must be an object`)];
1424
+ const violations = [];
1425
+ const extra = Object.keys(value).filter((key) => !["session_id", "session_file", "bound_at"].includes(key));
1426
+ if (extra.length > 0) {
1427
+ violations.push(invalid("coordination.row.binding-field", `${what} has unexpected key(s): ${extra.join(", ")}`));
1428
+ }
1429
+ if (!isNonEmptyString(value.session_id)) {
1430
+ violations.push(invalid("coordination.row.binding-field", `${what}.session_id must be a non-empty string`));
1431
+ }
1432
+ if (!isNonEmptyString(value.session_file) || !isAbsolute3(String(value.session_file))) {
1433
+ violations.push(invalid("coordination.row.binding-field", `${what}.session_file must be an absolute path`));
1434
+ }
1435
+ if (!isNonEmptyString(value.bound_at)) {
1436
+ violations.push(invalid("coordination.row.binding-field", `${what}.bound_at must be a timestamp`));
1437
+ }
1438
+ return violations;
1439
+ }
1440
+ function validateEvidenceRef(value, what) {
1441
+ if (!isPlainObject2(value))
1442
+ return [invalid("coordination.row.evidence-shape", `${what} must be a hash-pinned reference`)];
1443
+ const violations = [];
1444
+ const extra = Object.keys(value).filter((key) => !["path", "sha256"].includes(key));
1445
+ if (extra.length > 0) {
1446
+ violations.push(invalid("coordination.row.evidence-field", `${what} has unexpected key(s): ${extra.join(", ")}`));
1447
+ }
1448
+ if (!isNonEmptyString(value.path) || !isAbsolute3(String(value.path))) {
1449
+ violations.push(invalid("coordination.row.evidence-field", `${what}.path must be an absolute path`));
1450
+ }
1451
+ if (!isNonEmptyString(value.sha256) || !SHA256_HEX.test(String(value.sha256))) {
1452
+ violations.push(invalid("coordination.row.evidence-field", `${what}.sha256 must be 64 lowercase hex`));
1453
+ }
1454
+ return violations;
1455
+ }
1456
+ function validatePlanProgress(value, what = "coordination.progress") {
1457
+ if (!isPlainObject2(value))
1458
+ return [invalid("coordination.row.progress-shape", `${what} must be an object`)];
1459
+ const violations = [];
1460
+ const extra = Object.keys(value).filter((key) => !["status", "summary", "evidence_paths", "track_branches"].includes(key));
1461
+ if (extra.length > 0) {
1462
+ violations.push(invalid("coordination.row.progress-field", `${what} has unexpected key(s): ${extra.join(", ")}`));
1463
+ }
1464
+ if (!PLAN_PROGRESS_STATUSES.includes(value.status)) {
1465
+ violations.push(invalid("coordination.row.progress-field", `${what}.status must be one of ${PLAN_PROGRESS_STATUSES.join(", ")}`));
1466
+ }
1467
+ if (!isNonEmptyString(value.summary)) {
1468
+ violations.push(invalid("coordination.row.progress-field", `${what}.summary must be a non-empty string`));
1469
+ }
1470
+ if (!Array.isArray(value.evidence_paths) || !value.evidence_paths.every(isNonEmptyString)) {
1471
+ violations.push(invalid("coordination.row.progress-field", `${what}.evidence_paths must be an array of paths`));
1472
+ }
1473
+ if (value.track_branches !== undefined) {
1474
+ if (!Array.isArray(value.track_branches) || !value.track_branches.every(isNonEmptyString)) {
1475
+ violations.push(invalid("coordination.row.progress-field", `${what}.track_branches must be an array of branch names`));
1476
+ }
1477
+ }
1478
+ return violations;
1479
+ }
1480
+ function validatePlanHandoff(value, what = "coordination.handoff") {
1481
+ if (!isPlainObject2(value))
1482
+ return [invalid("coordination.row.handoff-shape", `${what} must be an object`)];
1483
+ const allowed = [
1484
+ "id",
1485
+ "attempt",
1486
+ "state",
1487
+ "submitted_by",
1488
+ "submitted_at",
1489
+ "source_branch",
1490
+ "source_sha",
1491
+ "worktree_path",
1492
+ "review_base",
1493
+ "review_head",
1494
+ "qc",
1495
+ "qa",
1496
+ "accepted_by",
1497
+ "accepted_at",
1498
+ "returned_at",
1499
+ "return_reason",
1500
+ "integration",
1501
+ "completed_at"
1502
+ ];
1503
+ const violations = [];
1504
+ const extra = Object.keys(value).filter((key) => !allowed.includes(key));
1505
+ if (extra.length > 0) {
1506
+ violations.push(invalid("coordination.row.handoff-field", `${what} has unexpected key(s): ${extra.join(", ")}`));
1507
+ }
1508
+ const required = [
1509
+ "id",
1510
+ "attempt",
1511
+ "state",
1512
+ "submitted_by",
1513
+ "submitted_at",
1514
+ "source_branch",
1515
+ "source_sha",
1516
+ "worktree_path",
1517
+ "review_base",
1518
+ "review_head"
1519
+ ];
1520
+ for (const key of required) {
1521
+ if (value[key] === undefined) {
1522
+ violations.push(invalid("coordination.row.handoff-field", `${what}.${key} is required`));
1523
+ }
1524
+ }
1525
+ if (!Number.isInteger(value.attempt) || value.attempt < 1) {
1526
+ violations.push(invalid("coordination.row.handoff-field", `${what}.attempt must be a positive integer`));
1527
+ }
1528
+ if (!HANDOFF_STATES.includes(value.state)) {
1529
+ violations.push(invalid("coordination.row.handoff-field", `${what}.state must be one of ${HANDOFF_STATES.join(", ")}`));
1530
+ }
1531
+ if (value.id !== undefined && !isNonEmptyString(value.id)) {
1532
+ violations.push(invalid("coordination.row.handoff-field", `${what}.id must be a non-empty string`));
1533
+ }
1534
+ for (const key of ["source_sha", "review_base", "review_head"]) {
1535
+ if (value[key] !== undefined && !GIT_SHA.test(String(value[key]))) {
1536
+ violations.push(invalid("coordination.row.handoff-field", `${what}.${key} must be a 40-hex git object id`));
1537
+ }
1538
+ }
1539
+ for (const key of ["submitted_at", "accepted_at", "returned_at", "completed_at"]) {
1540
+ if (value[key] !== undefined && !isNonEmptyString(value[key])) {
1541
+ violations.push(invalid("coordination.row.handoff-field", `${what}.${key} must be a timestamp`));
1542
+ }
1543
+ }
1544
+ if (value.worktree_path !== undefined && (!isNonEmptyString(value.worktree_path) || !isAbsolute3(String(value.worktree_path)))) {
1545
+ violations.push(invalid("coordination.row.handoff-field", `${what}.worktree_path must be an absolute path`));
1546
+ }
1547
+ if (value.qc !== undefined) {
1548
+ if (!isPlainObject2(value.qc)) {
1549
+ violations.push(invalid("coordination.row.handoff-shape", `${what}.qc must be an object`));
1550
+ } else {
1551
+ const qc = value.qc;
1552
+ const qcExtra = Object.keys(qc).filter((key) => !["decision", "reports", "consolidated"].includes(key));
1553
+ if (qcExtra.length > 0) {
1554
+ violations.push(invalid("coordination.row.handoff-field", `${what}.qc has unexpected key(s): ${qcExtra.join(", ")}`));
1555
+ }
1556
+ if (!isNonEmptyString(qc.decision)) {
1557
+ violations.push(invalid("coordination.row.handoff-field", `${what}.qc.decision must be a non-empty string`));
1558
+ }
1559
+ if (!Array.isArray(qc.reports) || qc.reports.length === 0) {
1560
+ violations.push(invalid("coordination.row.handoff-field", `${what}.qc.reports must be a non-empty array`));
1561
+ } else {
1562
+ qc.reports.forEach((ref, index) => {
1563
+ violations.push(...validateEvidenceRef(ref, `${what}.qc.reports[${index}]`));
1564
+ });
1565
+ }
1566
+ violations.push(...validateEvidenceRef(qc.consolidated, `${what}.qc.consolidated`));
1567
+ }
1568
+ }
1569
+ if (value.qa !== undefined) {
1570
+ if (!isPlainObject2(value.qa)) {
1571
+ violations.push(invalid("coordination.row.handoff-shape", `${what}.qa must be an object`));
1572
+ } else {
1573
+ const qa = value.qa;
1574
+ const qaExtra = Object.keys(qa).filter((key) => !["gate", "decision", "report"].includes(key));
1575
+ if (qaExtra.length > 0) {
1576
+ violations.push(invalid("coordination.row.handoff-field", `${what}.qa has unexpected key(s): ${qaExtra.join(", ")}`));
1577
+ }
1578
+ if (!isNonEmptyString(qa.gate)) {
1579
+ violations.push(invalid("coordination.row.handoff-field", `${what}.qa.gate must be a non-empty string`));
1580
+ }
1581
+ if (!isNonEmptyString(qa.decision)) {
1582
+ violations.push(invalid("coordination.row.handoff-field", `${what}.qa.decision must be a non-empty string`));
1583
+ }
1584
+ violations.push(...validateEvidenceRef(qa.report, `${what}.qa.report`));
1585
+ }
1586
+ }
1587
+ if (value.integration !== undefined) {
1588
+ if (!isPlainObject2(value.integration)) {
1589
+ violations.push(invalid("coordination.row.handoff-shape", `${what}.integration must be an object`));
1590
+ } else {
1591
+ const integration = value.integration;
1592
+ const integrationAllowed = [
1593
+ "target_branch",
1594
+ "worktree_path",
1595
+ "base_sha",
1596
+ "started_at",
1597
+ "result_sha",
1598
+ "verified_at"
1599
+ ];
1600
+ const integrationExtra = Object.keys(integration).filter((key) => !integrationAllowed.includes(key));
1601
+ if (integrationExtra.length > 0) {
1602
+ violations.push(invalid("coordination.row.handoff-field", `${what}.integration has unexpected key(s): ${integrationExtra.join(", ")}`));
1603
+ }
1604
+ for (const key of ["target_branch", "worktree_path", "base_sha", "started_at"]) {
1605
+ if (!isNonEmptyString(integration[key])) {
1606
+ violations.push(invalid("coordination.row.handoff-field", `${what}.integration.${key} is required`));
1607
+ }
1608
+ }
1609
+ for (const key of ["base_sha", "result_sha"]) {
1610
+ if (integration[key] !== undefined && !GIT_SHA.test(String(integration[key]))) {
1611
+ violations.push(invalid("coordination.row.handoff-field", `${what}.integration.${key} must be a 40-hex git object id`));
1612
+ }
1613
+ }
1614
+ if (integration.result_sha !== undefined && integration.verified_at === undefined) {
1615
+ violations.push(invalid("coordination.row.handoff-field", `${what}.integration.result_sha requires verified_at`));
1616
+ }
1617
+ }
1618
+ }
1619
+ if ((value.state === "integrating" || value.state === "merged" || value.state === "completed") && value.integration === undefined) {
1620
+ violations.push(invalid("coordination.row.handoff-field", `${what}.state ${String(value.state)} requires integration`));
1621
+ }
1622
+ return violations;
1623
+ }
1624
+ function validatePreparedCoordination(value, what = "coordination.prepared") {
1625
+ if (!isPlainObject2(value))
1626
+ return [invalid("coordination.row.prepared-shape", `${what} must be an object`)];
1627
+ const allowed = [
1628
+ "assignment_path",
1629
+ "assignment_sha256",
1630
+ "plan_sha256",
1631
+ "qa_gate",
1632
+ "findings_cleanup",
1633
+ "prepared_by",
1634
+ "prepared_at"
1635
+ ];
1636
+ const violations = [];
1637
+ const extra = Object.keys(value).filter((key) => !allowed.includes(key));
1638
+ if (extra.length > 0) {
1639
+ violations.push(invalid("coordination.row.prepared-field", `${what} has unexpected key(s): ${extra.join(", ")}`));
1640
+ }
1641
+ for (const key of allowed) {
1642
+ if (!isNonEmptyString(value[key])) {
1643
+ violations.push(invalid("coordination.row.prepared-field", `${what}.${key} is required`));
1644
+ }
1645
+ }
1646
+ if (value.assignment_path !== undefined && !isAbsolute3(String(value.assignment_path))) {
1647
+ violations.push(invalid("coordination.row.prepared-field", `${what}.assignment_path must be absolute`));
1648
+ }
1649
+ for (const key of ["assignment_sha256", "plan_sha256"]) {
1650
+ if (value[key] !== undefined && !SHA256_HEX.test(String(value[key]))) {
1651
+ violations.push(invalid("coordination.row.prepared-field", `${what}.${key} must be 64 lowercase hex`));
1652
+ }
1653
+ }
1654
+ return violations;
1655
+ }
1656
+ function validateRowCoordination(value, what = "coordination") {
1657
+ if (!isPlainObject2(value))
1658
+ return [invalid("coordination.row.shape", `${what} must be an object`)];
1659
+ const allowed = ["revision", "prepared", "session", "progress", "handoff"];
1660
+ const violations = [];
1661
+ const extra = Object.keys(value).filter((key) => !allowed.includes(key));
1662
+ if (extra.length > 0) {
1663
+ violations.push(invalid("coordination.row.field", `${what} has unexpected key(s): ${extra.join(", ")}`));
1664
+ }
1665
+ if (!Number.isInteger(value.revision) || value.revision < 0) {
1666
+ violations.push(invalid("coordination.row.revision", `${what}.revision must be a non-negative integer`));
1667
+ }
1668
+ if (value.prepared !== undefined)
1669
+ violations.push(...validatePreparedCoordination(value.prepared, `${what}.prepared`));
1670
+ if (value.session !== undefined)
1671
+ violations.push(...validateBinding(value.session, `${what}.session`));
1672
+ if (value.progress !== undefined)
1673
+ violations.push(...validatePlanProgress(value.progress, `${what}.progress`));
1674
+ if (value.handoff !== undefined)
1675
+ violations.push(...validatePlanHandoff(value.handoff, `${what}.handoff`));
1676
+ if (value.handoff !== undefined && value.session === undefined) {
1677
+ violations.push(invalid("coordination.row.handoff-field", `${what}.handoff requires a bound plan session`));
1678
+ }
1679
+ return violations;
1680
+ }
1681
+ function validateSnapshotCoordination(value, what = "coordination") {
1682
+ if (!isPlainObject2(value))
1683
+ return [invalid("coordination.snapshot.shape", `${what} must be an object`)];
1684
+ const violations = [];
1685
+ const extra = Object.keys(value).filter((key) => key !== "coordinator");
1686
+ if (extra.length > 0) {
1687
+ violations.push(invalid("coordination.snapshot.field", `${what} has unexpected key(s): ${extra.join(", ")}`));
1688
+ }
1689
+ if (value.coordinator === undefined) {
1690
+ violations.push(invalid("coordination.snapshot.field", `${what}.coordinator is required`));
1691
+ } else {
1692
+ violations.push(...validateBinding(value.coordinator, `${what}.coordinator`));
1693
+ }
1694
+ return violations;
1695
+ }
1398
1696
  var BRANCH_FORMS_HINT = '"Working branch: <existing>" | "Working branch: create <new> from <base>" | "Branch policy: direct on <branch> — <reason>"';
1399
1697
  var REQUIRED_FIELDS = [
1400
1698
  { key: "executeAs", label: "Execute as", code: "execute-as" },
@@ -1404,6 +1702,7 @@ var REQUIRED_FIELDS = [
1404
1702
  var REVIEW_SEAT_ROLES = ["qc-specialist", "qc-specialist-2", "qc-specialist-3", "code-reviewer", "qa-engineer"];
1405
1703
  var BUDGET_LABELS = ["Budget (review / QC seats)", "Budget"];
1406
1704
  var RETURN_SHAPE_LABELS = ["Return shape (review / QC seats)", "Return shape"];
1705
+ var TASK_BUDGET_LABELS = ["Task budget (implement / ops rounds)", "Task budget"];
1407
1706
  function violation2(severity, code, message, fix) {
1408
1707
  return { ok: false, severity, code, message, fix };
1409
1708
  }
@@ -1431,6 +1730,8 @@ function parseAssignmentFields(assignmentText) {
1431
1730
  fields.budget = value;
1432
1731
  else if (RETURN_SHAPE_LABELS.includes(label))
1433
1732
  fields.returnShape = value;
1733
+ else if (TASK_BUDGET_LABELS.includes(label))
1734
+ fields.taskBudget = value;
1434
1735
  }
1435
1736
  return fields;
1436
1737
  }
@@ -1545,6 +1846,12 @@ function validateAssignmentFields(assignmentText, opts = {}) {
1545
1846
  violations.push(violation2("high", field.code, `${subject} must declare a round ${field.label} — ${missing}`, field.fix));
1546
1847
  }
1547
1848
  }
1849
+ if (!reviewSeat && !auditRound) {
1850
+ const missing = describeAbsence(fields.taskBudget);
1851
+ if (missing !== undefined) {
1852
+ violations.push(violation2("high", "assignment.field.task-budget-missing", `implement/ops round "${role}" must declare a Task budget — ${missing}`, `add "**Task budget (implement / ops rounds)**: <one implementer round closing the task's declared Files list and verification gates> — capacity contract spec § A1/A2"`));
1853
+ }
1854
+ }
1548
1855
  if (writable) {
1549
1856
  const workingPresent = fields.workingBranch !== undefined && fields.workingBranch !== "";
1550
1857
  const policyPresent = fields.branchPolicy !== undefined && fields.branchPolicy !== "";
@@ -1665,9 +1972,8 @@ var WORKFLOW_SNAPSHOT_FILE = "snapshot.json";
1665
1972
  var WORKFLOW_LIFECYCLE_STATUSES = ["running", "paused", "completed", "failed", "stopped"];
1666
1973
  var WORKFLOW_TERMINAL_STATUSES = ["completed", "failed", "stopped"];
1667
1974
  var WORKFLOW_LIFECYCLE_TYPES = ["plan", "iteration"];
1668
- function isPlainObject2(value) {
1669
- return typeof value === "object" && value !== null && !Array.isArray(value);
1670
- }
1975
+ var WORKFLOW_DELIVERY_KINDS = ["development", "verification/report-only"];
1976
+ var WORKFLOW_COMPOUND_OUTCOMES = ["created", "updated", "skipped"];
1671
1977
  function violation3(severity, code, message, fix) {
1672
1978
  return { ok: false, severity, code, message, fix };
1673
1979
  }
@@ -1679,10 +1985,65 @@ function validateNonEmptyString2(violations, value, field, missingCode, invalidC
1679
1985
  }
1680
1986
  }
1681
1987
  function validateWorktreePathValue(violations, value, field) {
1682
- if (typeof value !== "string" || value.trim() === "" || !isAbsolute4(value)) {
1988
+ if (typeof value !== "string" || value.trim() === "" || !isAbsolute5(value)) {
1683
1989
  violations.push(violation3("high", "workflow.snapshot.invalid-integration-worktree-path", `${field} must be a non-empty absolute path — got ${JSON.stringify(value)}`, "record the absolute integration checkout path (integration_worktree_path)"));
1684
1990
  }
1685
1991
  }
1992
+ function deliveryEvidenceViolations(value, what) {
1993
+ const violations = [];
1994
+ const invalid2 = (message) => {
1995
+ violations.push(violation3("medium", "workflow.snapshot.invalid-delivery-evidence", `${what}: ${message}`));
1996
+ };
1997
+ if (!isPlainObject2(value)) {
1998
+ invalid2("must be an object");
1999
+ return violations;
2000
+ }
2001
+ const members = ["compound", "pr", "merge", "completion"];
2002
+ const unknownMembers = Object.keys(value).filter((key) => !members.includes(key));
2003
+ if (unknownMembers.length > 0)
2004
+ invalid2(`unknown member(s) ${unknownMembers.join(", ")} — expected ${members.join(" | ")}`);
2005
+ const compound = value.compound;
2006
+ if (compound !== undefined) {
2007
+ if (!isPlainObject2(compound))
2008
+ invalid2("compound must be an object");
2009
+ else {
2010
+ const unknown = Object.keys(compound).filter((key) => key !== "outcome" && key !== "reason");
2011
+ if (unknown.length > 0)
2012
+ invalid2(`compound has unknown key(s) ${unknown.join(", ")}`);
2013
+ if (typeof compound.outcome !== "string" || !WORKFLOW_COMPOUND_OUTCOMES.includes(compound.outcome)) {
2014
+ invalid2(`compound.outcome must be one of ${WORKFLOW_COMPOUND_OUTCOMES.join(" | ")} — got ${JSON.stringify(compound.outcome)}`);
2015
+ } else if (compound.outcome === "skipped" && (typeof compound.reason !== "string" || compound.reason.trim() === "")) {
2016
+ invalid2("compound reason is required when the disposition outcome is 'skipped' (contract §4c)");
2017
+ } else if (compound.reason !== undefined && (typeof compound.reason !== "string" || compound.reason.trim() === "")) {
2018
+ invalid2("compound.reason must be a non-empty string when given");
2019
+ }
2020
+ }
2021
+ }
2022
+ const stringMembers = {
2023
+ pr: ["repo", "head", "target"],
2024
+ merge: ["provider", "evidence"],
2025
+ completion: ["policy", "evidence"]
2026
+ };
2027
+ for (const member of ["pr", "merge", "completion"]) {
2028
+ const block = value[member];
2029
+ if (block === undefined)
2030
+ continue;
2031
+ if (!isPlainObject2(block)) {
2032
+ invalid2(`${member} must be an object`);
2033
+ continue;
2034
+ }
2035
+ const fields = stringMembers[member];
2036
+ const unknown = Object.keys(block).filter((key) => !fields.includes(key));
2037
+ if (unknown.length > 0)
2038
+ invalid2(`${member} has unknown key(s) ${unknown.join(", ")}`);
2039
+ for (const field of fields) {
2040
+ if (typeof block[field] !== "string" || block[field].trim() === "") {
2041
+ invalid2(`${member}.${field} must be a non-empty string`);
2042
+ }
2043
+ }
2044
+ }
2045
+ return violations;
2046
+ }
1686
2047
  function validateWorkflowSnapshot(doc) {
1687
2048
  const violations = [];
1688
2049
  if (!isPlainObject2(doc)) {
@@ -1728,8 +2089,14 @@ function validateWorkflowSnapshot(doc) {
1728
2089
  if (isPlainObject2(row) && row.execution_lease !== undefined) {
1729
2090
  violations.push(...validateExecutionLease(row.execution_lease).violations);
1730
2091
  }
2092
+ if (isPlainObject2(row) && row.coordination !== undefined) {
2093
+ violations.push(...validateRowCoordination(row.coordination, `plans[${String(row.id)}].coordination`));
2094
+ }
1731
2095
  }
1732
2096
  }
2097
+ if (doc.coordination !== undefined) {
2098
+ violations.push(...validateSnapshotCoordination(doc.coordination));
2099
+ }
1733
2100
  if (doc.execution_policy !== undefined) {
1734
2101
  if (!isPlainObject2(doc.execution_policy)) {
1735
2102
  violations.push(violation3("medium", "workflow.snapshot.invalid-execution-policy", "execution_policy must be an object"));
@@ -1742,7 +2109,7 @@ function validateWorkflowSnapshot(doc) {
1742
2109
  if (!isPlainObject2(doc.branch)) {
1743
2110
  violations.push(violation3("medium", "workflow.snapshot.invalid-branch", "branch must be an object"));
1744
2111
  } else {
1745
- for (const key of ["base", "integration", "target"]) {
2112
+ for (const key of ["base", "source", "integration", "target"]) {
1746
2113
  if (doc.branch[key] !== undefined && (typeof doc.branch[key] !== "string" || doc.branch[key].trim() === "")) {
1747
2114
  violations.push(violation3("medium", "workflow.snapshot.invalid-branch", `branch.${key} must be a non-empty string`));
1748
2115
  }
@@ -1768,6 +2135,20 @@ function validateWorkflowSnapshot(doc) {
1768
2135
  if (doc.compass_ref !== undefined) {
1769
2136
  validateNonEmptyString2(violations, doc.compass_ref, "compass_ref", "workflow.snapshot.missing-compass-ref", "workflow.snapshot.invalid-compass-ref");
1770
2137
  }
2138
+ if (doc.delivery_kind !== undefined) {
2139
+ if (typeof doc.delivery_kind !== "string" || !WORKFLOW_DELIVERY_KINDS.includes(doc.delivery_kind)) {
2140
+ violations.push(violation3("medium", "workflow.snapshot.invalid-delivery-kind", `delivery_kind must be one of ${WORKFLOW_DELIVERY_KINDS.join(" | ")} — got ${JSON.stringify(doc.delivery_kind)}`));
2141
+ }
2142
+ }
2143
+ if (doc.project !== undefined) {
2144
+ validateNonEmptyString2(violations, doc.project, "project", "workflow.snapshot.missing-project", "workflow.snapshot.invalid-project");
2145
+ }
2146
+ if (doc.completion_policy !== undefined) {
2147
+ validateNonEmptyString2(violations, doc.completion_policy, "completion_policy", "workflow.snapshot.missing-completion-policy", "workflow.snapshot.invalid-completion-policy");
2148
+ }
2149
+ if (doc.delivery !== undefined) {
2150
+ violations.push(...deliveryEvidenceViolations(doc.delivery, "delivery"));
2151
+ }
1771
2152
  const terminal = typeof doc.status === "string" && WORKFLOW_TERMINAL_STATUSES.includes(doc.status);
1772
2153
  if (terminal) {
1773
2154
  if (doc.ended_at === undefined) {
@@ -1796,13 +2177,13 @@ class WorkflowSnapshotValidationError extends Error {
1796
2177
  }
1797
2178
  }
1798
2179
  function readWorkflowSnapshot(dir) {
1799
- const snapshotPath = join5(dir, WORKFLOW_SNAPSHOT_FILE);
1800
- if (!existsSync3(snapshotPath)) {
2180
+ const snapshotPath = join6(dir, WORKFLOW_SNAPSHOT_FILE);
2181
+ if (!existsSync4(snapshotPath)) {
1801
2182
  throw new Error(`workflow snapshot not found: ${snapshotPath}`);
1802
2183
  }
1803
2184
  let doc;
1804
2185
  try {
1805
- doc = JSON.parse(readFileSync3(snapshotPath, "utf8"));
2186
+ doc = JSON.parse(readFileSync4(snapshotPath, "utf8"));
1806
2187
  } catch (error) {
1807
2188
  throw new Error(`Invalid JSON in ${snapshotPath}: ${error.message}`);
1808
2189
  }
@@ -1833,9 +2214,6 @@ var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
1833
2214
  var PLAN_STATUSES = ["Todo", "InProgress", "InReview", "Blocked", "Done"];
1834
2215
  var RESIDUAL_DECISIONS = ["defer", "accept", "risk-accepted"];
1835
2216
  var RESIDUAL_LIFECYCLES = ["open", "resolved", "waived", "superseded", "duplicate"];
1836
- function isPlainObject3(value) {
1837
- return typeof value === "object" && value !== null && !Array.isArray(value);
1838
- }
1839
2217
  function violation4(severity, code, message, fix) {
1840
2218
  return { ok: false, severity, code, message, fix };
1841
2219
  }
@@ -1860,7 +2238,7 @@ function validateNonEmptyString3(violations, value, field, missingCode, invalidC
1860
2238
  }
1861
2239
  function validatePlanRow(row) {
1862
2240
  const violations = [];
1863
- if (!isPlainObject3(row)) {
2241
+ if (!isPlainObject2(row)) {
1864
2242
  return { ok: false, violations: [violation4("high", "status.plan-row.invalid", "plan row must be an object")] };
1865
2243
  }
1866
2244
  const { id, plan_id: planId, title, file, status, metadata, execution_lease } = row;
@@ -1884,10 +2262,10 @@ function validatePlanRow(row) {
1884
2262
  } else if (typeof status !== "string" || !PLAN_STATUSES.includes(status)) {
1885
2263
  violations.push(violation4("medium", "status.plan-row.invalid-status", `status must be one of ${PLAN_STATUSES.join(" | ")} — got ${JSON.stringify(status)}`));
1886
2264
  }
1887
- if (metadata !== undefined && !isPlainObject3(metadata)) {
2265
+ if (metadata !== undefined && !isPlainObject2(metadata)) {
1888
2266
  violations.push(violation4("medium", "status.plan-row.invalid-metadata", "metadata must be an object"));
1889
2267
  }
1890
- if (execution_lease !== undefined && !isPlainObject3(execution_lease)) {
2268
+ if (execution_lease !== undefined && !isPlainObject2(execution_lease)) {
1891
2269
  violations.push(violation4("medium", "status.plan-row.invalid-execution-lease", "execution_lease must be an object"));
1892
2270
  }
1893
2271
  if (status === "Done" && execution_lease !== undefined) {
@@ -1897,7 +2275,7 @@ function validatePlanRow(row) {
1897
2275
  }
1898
2276
  function validateResidual(entry) {
1899
2277
  const violations = [];
1900
- if (!isPlainObject3(entry)) {
2278
+ if (!isPlainObject2(entry)) {
1901
2279
  return { ok: false, violations: [violation4("high", "status.residual.invalid", "residual entry must be an object")] };
1902
2280
  }
1903
2281
  const { id, title, severity, source, scope, decision, owner, target, tracking, detail_doc, lifecycle, closed_at } = entry;
@@ -1957,7 +2335,7 @@ function isHarnessRelativePath(dir) {
1957
2335
  }
1958
2336
  function validateWorkflowEntry(entry) {
1959
2337
  const violations = [];
1960
- if (!isPlainObject3(entry)) {
2338
+ if (!isPlainObject2(entry)) {
1961
2339
  return {
1962
2340
  ok: false,
1963
2341
  violations: [violation4("high", "status.workflow.invalid", "workflow entry must be an object")]
@@ -1985,7 +2363,7 @@ function validateStatusV2(docOrPath, opts = {}) {
1985
2363
  if (typeof docOrPath === "string") {
1986
2364
  try {
1987
2365
  doc = readJson(docOrPath);
1988
- harnessDir = dirname4(resolve5(docOrPath));
2366
+ harnessDir = dirname5(resolve7(docOrPath));
1989
2367
  } catch (error) {
1990
2368
  return {
1991
2369
  ok: false,
@@ -1995,7 +2373,7 @@ function validateStatusV2(docOrPath, opts = {}) {
1995
2373
  } else {
1996
2374
  doc = docOrPath;
1997
2375
  }
1998
- if (!isPlainObject3(doc)) {
2376
+ if (!isPlainObject2(doc)) {
1999
2377
  return { ok: false, violations: [violation4("high", "status.invalid-doc", "status document must be an object")] };
2000
2378
  }
2001
2379
  if (doc.version !== 2) {
@@ -2036,7 +2414,7 @@ function validateStatusV2(docOrPath, opts = {}) {
2036
2414
  const seen = new Set;
2037
2415
  for (const entry of doc.workflows) {
2038
2416
  violations.push(...validateWorkflowEntry(entry).violations);
2039
- if (isPlainObject3(entry) && typeof entry.id === "string") {
2417
+ if (isPlainObject2(entry) && typeof entry.id === "string") {
2040
2418
  if (seen.has(entry.id)) {
2041
2419
  violations.push(violation4("medium", "status.workflow.duplicate-id", `duplicate workflow id in workflows[]: ${JSON.stringify(entry.id)}`));
2042
2420
  }
@@ -2047,22 +2425,22 @@ function validateStatusV2(docOrPath, opts = {}) {
2047
2425
  if (harnessDir !== undefined && Array.isArray(doc.workflows)) {
2048
2426
  let realHarnessDir = null;
2049
2427
  try {
2050
- realHarnessDir = realpathSync(harnessDir);
2428
+ realHarnessDir = realpathSync2(harnessDir);
2051
2429
  } catch {}
2052
2430
  for (const entry of doc.workflows) {
2053
- if (!isPlainObject3(entry) || typeof entry.dir !== "string")
2431
+ if (!isPlainObject2(entry) || typeof entry.dir !== "string")
2054
2432
  continue;
2055
- const relSnapshot = join6(entry.dir, WORKFLOW_SNAPSHOT_FILE);
2056
- const snapshotPath = join6(harnessDir, relSnapshot);
2433
+ const relSnapshot = join7(entry.dir, WORKFLOW_SNAPSHOT_FILE);
2434
+ const snapshotPath = join7(harnessDir, relSnapshot);
2057
2435
  const label = typeof entry.id === "string" ? entry.id : relSnapshot;
2058
2436
  let physical;
2059
2437
  try {
2060
- physical = realpathSync(snapshotPath);
2438
+ physical = realpathSync2(snapshotPath);
2061
2439
  } catch {
2062
2440
  violations.push(violation4("high", "status.workflow.snapshot-missing", `workflows[] lists ${JSON.stringify(label)} but its snapshot does not exist at ${JSON.stringify(relSnapshot)} — the root holds active lifecycles only; unregister the id when its snapshot is removed`));
2063
2441
  continue;
2064
2442
  }
2065
- if (realHarnessDir !== null && physical !== realHarnessDir && !physical.startsWith(`${realHarnessDir}${sep}`)) {
2443
+ if (realHarnessDir !== null && physical !== realHarnessDir && !physical.startsWith(`${realHarnessDir}${sep2}`)) {
2066
2444
  violations.push(violation4("high", "status.workflow.snapshot-outside-harness", `workflows[] lists ${JSON.stringify(label)} but its snapshot resolves outside the harness dir (${JSON.stringify(physical)}) — symlinked snapshot paths are rejected; the snapshot must physically live under ${JSON.stringify(harnessDir)}`));
2067
2445
  continue;
2068
2446
  }
@@ -2089,23 +2467,23 @@ function validateStatusV2(docOrPath, opts = {}) {
2089
2467
  var validateStatus = validateStatusV2;
2090
2468
  function resolveCompassEnforcement(harnessDir) {
2091
2469
  const iterationsDir = resolveIterationDir(harnessDir);
2092
- if (!existsSync4(iterationsDir))
2470
+ if (!existsSync5(iterationsDir))
2093
2471
  return { hard: false, source: "none" };
2094
2472
  let entries;
2095
2473
  try {
2096
- entries = readdirSync2(iterationsDir, { withFileTypes: true });
2474
+ entries = readdirSync3(iterationsDir, { withFileTypes: true });
2097
2475
  } catch {
2098
2476
  return { hard: false, source: "none" };
2099
2477
  }
2100
2478
  for (const entry of entries) {
2101
2479
  if (!entry.isDirectory())
2102
2480
  continue;
2103
- const compassPath = join6(iterationsDir, entry.name, "delivery-compass.md");
2104
- if (!existsSync4(compassPath))
2481
+ const compassPath = join7(iterationsDir, entry.name, "delivery-compass.md");
2482
+ if (!existsSync5(compassPath))
2105
2483
  continue;
2106
2484
  let content;
2107
2485
  try {
2108
- content = readFileSync4(compassPath, "utf8");
2486
+ content = readFileSync5(compassPath, "utf8");
2109
2487
  } catch {
2110
2488
  continue;
2111
2489
  }
@@ -2120,8 +2498,8 @@ function resolveCompassEnforcement(harnessDir) {
2120
2498
  return { hard: false, source: "none" };
2121
2499
  }
2122
2500
  function resolveMstarcEnforcement(harnessDir) {
2123
- const dir = resolve5(harnessDir);
2124
- const rc = loadMstarc(dir, dirname4(dir));
2501
+ const dir = resolve7(harnessDir);
2502
+ const rc = loadMstarc(dir, dirname5(dir));
2125
2503
  const value = rc?.config.enforcement;
2126
2504
  if (value === "hard")
2127
2505
  return { hard: true, source: "mstarc" };
@@ -2212,11 +2590,11 @@ function validateCompassShape(doc) {
2212
2590
  function violation5(severity, code, message, fix) {
2213
2591
  return { ok: false, severity, code, message, fix };
2214
2592
  }
2215
- function isPlainObject4(value) {
2593
+ function isPlainObject3(value) {
2216
2594
  return typeof value === "object" && value !== null && !Array.isArray(value);
2217
2595
  }
2218
2596
  function validateCompassFrontmatter(doc) {
2219
- if (!isPlainObject4(doc)) {
2597
+ if (!isPlainObject3(doc)) {
2220
2598
  return {
2221
2599
  ok: false,
2222
2600
  violations: [
@@ -2253,7 +2631,7 @@ function findPlanRow(snapshotDoc, planId) {
2253
2631
  if (!Array.isArray(snapshotDoc.plans))
2254
2632
  return null;
2255
2633
  for (const row of snapshotDoc.plans) {
2256
- if (!isPlainObject4(row))
2634
+ if (!isPlainObject3(row))
2257
2635
  continue;
2258
2636
  const rowId = typeof row.id === "string" ? row.id : typeof row.plan_id === "string" ? row.plan_id : null;
2259
2637
  if (rowId === planId)
@@ -2349,7 +2727,7 @@ function evaluatePhaseGate(snapshotDoc, compassDoc, opts = {}) {
2349
2727
  };
2350
2728
  }
2351
2729
  function parseCompassFrontmatter(filePath) {
2352
- return parseCompassFrontmatterText(readFileSync5(filePath, "utf8"), filePath);
2730
+ return parseCompassFrontmatterText(readFileSync6(filePath, "utf8"), filePath);
2353
2731
  }
2354
2732
  function parseCompassFrontmatterText(content, filePath) {
2355
2733
  const lines = content.split(/\r?\n/);
@@ -2416,9 +2794,6 @@ var PROJECT_ROADMAP_FILE = "roadmap.md";
2416
2794
  var PROJECT_REGISTER_FILE = "residuals.json";
2417
2795
  var _DEFAULT_PROJECT = "_default";
2418
2796
  var DATE_RE3 = /^\d{4}-\d{2}-\d{2}$/;
2419
- function isPlainObject5(value) {
2420
- return typeof value === "object" && value !== null && !Array.isArray(value);
2421
- }
2422
2797
  function violation6(severity, code, message, fix) {
2423
2798
  return { ok: false, severity, code, message, fix };
2424
2799
  }
@@ -2431,7 +2806,7 @@ function validateNonEmptyString4(violations, value, field, missingCode, invalidC
2431
2806
  }
2432
2807
  function validateProjectRegister(doc) {
2433
2808
  const violations = [];
2434
- if (!isPlainObject5(doc)) {
2809
+ if (!isPlainObject2(doc)) {
2435
2810
  return {
2436
2811
  ok: false,
2437
2812
  violations: [violation6("high", "project.register.invalid", "project register must be an object")]
@@ -2439,7 +2814,7 @@ function validateProjectRegister(doc) {
2439
2814
  }
2440
2815
  if (doc.entries === undefined) {
2441
2816
  violations.push(violation6("high", "project.register.missing-entries", "missing required field: entries"));
2442
- } else if (!isPlainObject5(doc.entries)) {
2817
+ } else if (!isPlainObject2(doc.entries)) {
2443
2818
  violations.push(violation6("high", "project.register.invalid-entries", "entries must be an object keyed by plan id"));
2444
2819
  } else {
2445
2820
  for (const [key, entries] of Object.entries(doc.entries)) {
@@ -2452,7 +2827,7 @@ function validateProjectRegister(doc) {
2452
2827
  }
2453
2828
  for (const entry of entries) {
2454
2829
  violations.push(...validateResidual(entry).violations);
2455
- if (!isPlainObject5(entry))
2830
+ if (!isPlainObject2(entry))
2456
2831
  continue;
2457
2832
  validateNonEmptyString4(violations, entry.source_plan, "source_plan", "project.register.missing-source-plan", "project.register.invalid-source-plan");
2458
2833
  if (entry.registered_at === undefined) {
@@ -2474,7 +2849,7 @@ function validateProjectRegister(doc) {
2474
2849
  function findingsCleanupGate(register, planId, opts) {
2475
2850
  const mode = opts?.mode ?? "allow-residual";
2476
2851
  const violations = [];
2477
- const entries = isPlainObject5(register.entries) ? register.entries[planId] : undefined;
2852
+ const entries = isPlainObject2(register.entries) ? register.entries[planId] : undefined;
2478
2853
  if (entries === undefined) {
2479
2854
  return { ok: true, violations };
2480
2855
  }
@@ -2511,25 +2886,25 @@ function findingsCleanupGate(register, planId, opts) {
2511
2886
  return { ok: violations.length === 0, violations };
2512
2887
  }
2513
2888
  function resolveHarnessDir(startDir = process.cwd(), opts = {}) {
2514
- const start = resolve7(startDir);
2889
+ const start = resolve9(startDir);
2515
2890
  const explicit = opts.harnessDir ?? process.env.MSTAR_HARNESS_DIR;
2516
2891
  if (explicit)
2517
- return resolve7(start, explicit);
2518
- const boundary = resolve7(start, opts.workspaceRoot ?? defaultWorkspaceRoot(start));
2892
+ return resolve9(start, explicit);
2893
+ const boundary = resolve9(start, opts.workspaceRoot ?? defaultWorkspaceRoot(start));
2519
2894
  const rc = loadMstarc(start, boundary);
2520
2895
  if (rc !== null && rc.config.harnessDir)
2521
- return resolve7(rc.dir, rc.config.harnessDir);
2896
+ return resolve9(rc.dir, rc.config.harnessDir);
2522
2897
  let dir = start;
2523
2898
  for (;; ) {
2524
2899
  if (!isAtOrBelow2(dir, boundary))
2525
2900
  return null;
2526
- for (const candidate of [join9(dir, ".mstar"), join9(dir, ".agents"), join9(dir, ".plans"), join9(dir, "plans")]) {
2901
+ for (const candidate of [join10(dir, ".mstar"), join10(dir, ".agents"), join10(dir, ".plans"), join10(dir, "plans")]) {
2527
2902
  if (isDirectory(candidate))
2528
2903
  return candidate;
2529
2904
  }
2530
2905
  if (dir === boundary)
2531
2906
  return null;
2532
- const parent = dirname5(dir);
2907
+ const parent = dirname6(dir);
2533
2908
  if (parent === dir)
2534
2909
  return null;
2535
2910
  dir = parent;
@@ -2547,21 +2922,21 @@ function defaultWorkspaceRoot(startDir) {
2547
2922
  let boundary = startDir;
2548
2923
  for (const segment of cdup.split(/[\\/]/)) {
2549
2924
  if (segment && segment !== ".")
2550
- boundary = dirname5(boundary);
2925
+ boundary = dirname6(boundary);
2551
2926
  }
2552
- return resolve7(boundary);
2927
+ return resolve9(boundary);
2553
2928
  } catch {}
2554
2929
  return startDir;
2555
2930
  }
2556
2931
  function isAtOrBelow2(dir, root) {
2557
2932
  const rel = relative2(root, dir);
2558
- return rel === "" || !rel.startsWith("..") && !isAbsolute5(rel);
2933
+ return rel === "" || !rel.startsWith("..") && !isAbsolute6(rel);
2559
2934
  }
2560
2935
  function mstarcDirOverride(harnessDir, key) {
2561
- const dir = resolve7(harnessDir);
2562
- const rc = loadMstarc(dir, dirname5(dir));
2936
+ const dir = resolve9(harnessDir);
2937
+ const rc = loadMstarc(dir, dirname6(dir));
2563
2938
  const declared = rc?.config[key];
2564
- return declared ? resolve7(rc.dir, declared) : null;
2939
+ return declared ? resolve9(rc.dir, declared) : null;
2565
2940
  }
2566
2941
  function assertSafePathComponent(value, what) {
2567
2942
  if (value === "" || value === "." || value === ".." || !/^[A-Za-z0-9._-]+$/.test(value)) {
@@ -2569,44 +2944,44 @@ function assertSafePathComponent(value, what) {
2569
2944
  }
2570
2945
  }
2571
2946
  function canonicalizeNearestExisting(path) {
2572
- const abs = resolve7(path);
2947
+ const abs = resolve9(path);
2573
2948
  let dir = abs;
2574
2949
  const tail = [];
2575
2950
  for (;; ) {
2576
- if (existsSync7(dir)) {
2951
+ if (existsSync8(dir)) {
2577
2952
  try {
2578
- return join9(realpathSync2(dir), ...tail);
2953
+ return join10(realpathSync3(dir), ...tail);
2579
2954
  } catch {
2580
2955
  return abs;
2581
2956
  }
2582
2957
  }
2583
- const parent = dirname5(dir);
2958
+ const parent = dirname6(dir);
2584
2959
  if (parent === dir)
2585
2960
  return abs;
2586
- tail.unshift(basename3(dir));
2961
+ tail.unshift(basename5(dir));
2587
2962
  dir = parent;
2588
2963
  }
2589
2964
  }
2590
2965
  function resolveSddDir(harnessDir, planId) {
2591
2966
  assertSafePathComponent(planId, "planId");
2592
- const base = resolve7(harnessDir);
2967
+ const base = resolve9(harnessDir);
2593
2968
  const declared = mstarcDirOverride(base, "sddDir");
2594
- const sddBase = declared !== null ? declared : join9(base, "sdd");
2595
- return join9(sddBase, planId);
2969
+ const sddBase = declared !== null ? declared : join10(base, "sdd");
2970
+ return join10(sddBase, planId);
2596
2971
  }
2597
2972
  function resolveIterationDir(harnessDir) {
2598
2973
  const declared = mstarcDirOverride(harnessDir, "iterationDir");
2599
2974
  if (declared !== null)
2600
2975
  return declared;
2601
- return join9(resolve7(harnessDir), "iterations");
2976
+ return join10(resolve9(harnessDir), "iterations");
2602
2977
  }
2603
2978
  function resolveHarnessSubdir(startDir, opts, key, fallback) {
2604
2979
  const harness = resolveHarnessDir(startDir, opts);
2605
2980
  if (harness === null) {
2606
- throw new Error(`harness dir not found from ${resolve7(startDir)} — cannot resolve the ${fallback} dir (run \`mstar harness scaffold\`, pass opts.harnessDir, or set MSTAR_HARNESS_DIR)`);
2981
+ throw new Error(`harness dir not found from ${resolve9(startDir)} — cannot resolve the ${fallback} dir (run \`mstar harness scaffold\`, pass opts.harnessDir, or set MSTAR_HARNESS_DIR)`);
2607
2982
  }
2608
2983
  const declared = mstarcDirOverride(harness, key);
2609
- return declared !== null ? declared : join9(resolve7(harness), fallback);
2984
+ return declared !== null ? declared : join10(resolve9(harness), fallback);
2610
2985
  }
2611
2986
  function resolveWorkflowDir(startDir = process.cwd(), opts = {}) {
2612
2987
  return resolveHarnessSubdir(startDir, opts, "workflowDir", "workflows");
@@ -2686,7 +3061,7 @@ function parseMainWorktree(out) {
2686
3061
  if (branch === null)
2687
3062
  return null;
2688
3063
  try {
2689
- return { root: realpathSync3(rawPath), branch };
3064
+ return { root: realpathSync4(rawPath), branch };
2690
3065
  } catch {
2691
3066
  return null;
2692
3067
  }
@@ -2754,8 +3129,8 @@ function probeCheckout(worktreePath, opts) {
2754
3129
  const raw = stdout.trim();
2755
3130
  if (raw === "")
2756
3131
  return { error: `no git dir reported at "${worktreePath}"` };
2757
- const abs = isAbsolute6(raw) ? raw : join10(worktreePath, raw);
2758
- return { gitDir: realpathSync3(abs) };
3132
+ const abs = isAbsolute7(raw) ? raw : join11(worktreePath, raw);
3133
+ return { gitDir: realpathSync4(abs) };
2759
3134
  } catch (err) {
2760
3135
  const e = err;
2761
3136
  if (e.killed === true || e.signal !== undefined) {
@@ -2776,7 +3151,7 @@ function probeCheckoutRoot(path, opts = {}) {
2776
3151
  const raw = stdout.trim();
2777
3152
  if (raw === "")
2778
3153
  return null;
2779
- return realpathSync3(raw);
3154
+ return realpathSync4(raw);
2780
3155
  } catch {
2781
3156
  return null;
2782
3157
  }
@@ -2785,7 +3160,7 @@ function l1PreDispatchCheck(input, opts = {}) {
2785
3160
  const violations = [];
2786
3161
  const checkoutCache = new Map;
2787
3162
  const checkout = (path) => {
2788
- const key = resolve8(path);
3163
+ const key = resolve10(path);
2789
3164
  if (!checkoutCache.has(key))
2790
3165
  checkoutCache.set(key, probeCheckout(path, opts));
2791
3166
  return checkoutCache.get(key);
@@ -2824,7 +3199,7 @@ function l1PreDispatchCheck(input, opts = {}) {
2824
3199
  violations.push(violation8("high", "worktree.l1.lease-branch-missing", `execution_lease.working_branch is empty for plan "${planId}"`, "record the lease working_branch before dispatch"));
2825
3200
  }
2826
3201
  if (integrationRequired && integrationWorktreePath.trim() !== "" && integrationBranch.trim() !== "") {
2827
- if (!existsSync8(integrationWorktreePath)) {
3202
+ if (!existsSync9(integrationWorktreePath)) {
2828
3203
  violations.push(violation8("high", "worktree.l1.integration-missing", `integration worktree "${integrationWorktreePath}" does not exist for plan "${planId}" — the integration checkout must exist before dispatch`, `create it before dispatch: git worktree add ${shellQuote(integrationWorktreePath)} ${shellQuote(integrationBranch)}`));
2829
3204
  } else {
2830
3205
  const probe = probeBranch(integrationWorktreePath, opts);
@@ -2836,10 +3211,10 @@ function l1PreDispatchCheck(input, opts = {}) {
2836
3211
  }
2837
3212
  }
2838
3213
  const identityViolation = (aPath, bPath, code, describe, fix) => {
2839
- if (resolve8(aPath) === resolve8(bPath)) {
3214
+ if (resolve10(aPath) === resolve10(bPath)) {
2840
3215
  return violation8("critical", code, `${describe} — the same checkout (normalized path equality) is not isolation`, fix);
2841
3216
  }
2842
- if (!existsSync8(aPath) || !existsSync8(bPath))
3217
+ if (!existsSync9(aPath) || !existsSync9(bPath))
2843
3218
  return null;
2844
3219
  const a = checkout(aPath);
2845
3220
  const b = checkout(bPath);
@@ -2869,7 +3244,7 @@ function l1PreDispatchCheck(input, opts = {}) {
2869
3244
  if (v !== null)
2870
3245
  violations.push(v);
2871
3246
  }
2872
- if (leaseWorktreePath.trim() !== "" && !existsSync8(leaseWorktreePath)) {
3247
+ if (leaseWorktreePath.trim() !== "" && !existsSync9(leaseWorktreePath)) {
2873
3248
  violations.push(violation8("high", "worktree.l1.feature-missing", `feature worktree directory "${leaseWorktreePath}" does not exist for plan "${planId}"`, `create it before dispatch: git worktree add ${shellQuote(leaseWorktreePath)} <working-branch>`));
2874
3249
  } else if (leaseWorktreePath.trim() !== "" && leaseWorkingBranch.trim() !== "") {
2875
3250
  const probe = probeBranch(leaseWorktreePath, opts);
@@ -2893,17 +3268,17 @@ function l2PreDispatchCheck(input, opts = {}) {
2893
3268
  violations.push(violation8("high", "worktree.l2.track-invalid", `track ${index + 1} is missing worktreePath and/or workingBranch`, "fill both fields for every track"));
2894
3269
  return;
2895
3270
  }
2896
- if (!isAbsolute6(track.worktreePath)) {
3271
+ if (!isAbsolute7(track.worktreePath)) {
2897
3272
  violations.push(violation8("high", "worktree.l2.track-path-relative", `track ${index + 1} worktreePath "${track.worktreePath}" is not an absolute path — L2 tracks MUST use absolute worktree checkout paths (consistent with the lease validator's absolute worktree_path enforcement)`, `use an absolute path for track ${index + 1} (e.g. /Users/<you>/worktrees/<branch>)`));
2898
3273
  return;
2899
3274
  }
2900
- const normalized = resolve8(track.worktreePath);
3275
+ const normalized = resolve10(track.worktreePath);
2901
3276
  if (seenPaths.has(normalized)) {
2902
3277
  violations.push(violation8("high", "worktree.l2.track-path-collision", `duplicate worktreePath "${track.worktreePath}" across parallel tracks — L2 parallel-writable isolation requires a distinct absolute Worktree path per track (N parallel invokes ≠ isolation)`, "give every parallel track its own git worktree checkout"));
2903
3278
  return;
2904
3279
  }
2905
3280
  seenPaths.add(normalized);
2906
- if (!existsSync8(track.worktreePath)) {
3281
+ if (!existsSync9(track.worktreePath)) {
2907
3282
  violations.push(violation8("high", "worktree.l2.track-missing", `track worktree directory "${track.worktreePath}" does not exist`, `create it before dispatch: git worktree add ${track.worktreePath} ${track.workingBranch}`));
2908
3283
  return;
2909
3284
  }
@@ -2929,33 +3304,33 @@ function assertBranchAlignment(worktreePath, expectedBranch, opts = {}) {
2929
3304
  function shellQuote(value) {
2930
3305
  return "'" + value.replaceAll("'", `'"'"'`) + "'";
2931
3306
  }
2932
- function isPlainObject8(value) {
3307
+ function isPlainObject6(value) {
2933
3308
  return typeof value === "object" && value !== null && !Array.isArray(value);
2934
3309
  }
2935
3310
  function collectActiveLifecycleBranches(snapshots) {
2936
3311
  const owned = new Set;
2937
3312
  for (const doc of snapshots) {
2938
3313
  const branch = doc.branch;
2939
- if (isPlainObject8(branch) && typeof branch.integration === "string" && branch.integration.trim() !== "") {
3314
+ if (isPlainObject6(branch) && typeof branch.integration === "string" && branch.integration.trim() !== "") {
2940
3315
  owned.add(branch.integration);
2941
3316
  }
2942
3317
  if (!Array.isArray(doc.plans))
2943
3318
  continue;
2944
3319
  for (const row of doc.plans) {
2945
- if (!isPlainObject8(row))
3320
+ if (!isPlainObject6(row))
2946
3321
  continue;
2947
3322
  const lease = row.execution_lease;
2948
- if (isPlainObject8(lease) && typeof lease.working_branch === "string" && lease.working_branch.trim() !== "") {
3323
+ if (isPlainObject6(lease) && typeof lease.working_branch === "string" && lease.working_branch.trim() !== "") {
2949
3324
  owned.add(lease.working_branch);
2950
3325
  }
2951
3326
  const meta = row.metadata;
2952
- if (isPlainObject8(meta) && Array.isArray(meta.track_branches)) {
3327
+ if (isPlainObject6(meta) && Array.isArray(meta.track_branches)) {
2953
3328
  for (const branch2 of meta.track_branches) {
2954
3329
  if (typeof branch2 === "string" && branch2.trim() !== "")
2955
3330
  owned.add(branch2);
2956
3331
  }
2957
3332
  }
2958
- if (isPlainObject8(meta) && typeof meta.working_branch === "string" && meta.working_branch.trim() !== "") {
3333
+ if (isPlainObject6(meta) && typeof meta.working_branch === "string" && meta.working_branch.trim() !== "") {
2959
3334
  owned.add(meta.working_branch);
2960
3335
  }
2961
3336
  }
@@ -2963,8 +3338,8 @@ function collectActiveLifecycleBranches(snapshots) {
2963
3338
  return [...owned];
2964
3339
  }
2965
3340
  function scanActiveLifecycleBranches(harnessDir, governingWorkflowId) {
2966
- const registerPath = join11(harnessDir, "status.json");
2967
- if (!existsSync9(registerPath))
3341
+ const registerPath = join12(harnessDir, "status.json");
3342
+ if (!existsSync10(registerPath))
2968
3343
  return { kind: "ok", branches: [], notes: [] };
2969
3344
  let register;
2970
3345
  try {
@@ -2972,7 +3347,7 @@ function scanActiveLifecycleBranches(harnessDir, governingWorkflowId) {
2972
3347
  } catch (error) {
2973
3348
  return { kind: "refusal", code: "worktree.l1.lifecycle-register-unreadable", detail: `${registerPath}: ${error.message}` };
2974
3349
  }
2975
- if (!isPlainObject8(register) || register.version !== 2 || !Array.isArray(register.workflows)) {
3350
+ if (!isPlainObject6(register) || register.version !== 2 || !Array.isArray(register.workflows)) {
2976
3351
  return {
2977
3352
  kind: "refusal",
2978
3353
  code: "worktree.l1.lifecycle-register-unreadable",
@@ -3003,10 +3378,10 @@ function scanActiveLifecycleBranches(harnessDir, governingWorkflowId) {
3003
3378
  }
3004
3379
  if (id === governingWorkflowId)
3005
3380
  continue;
3006
- const snapshotPath = join11(workflowsDir, id, WORKFLOW_SNAPSHOT_FILE);
3381
+ const snapshotPath = join12(workflowsDir, id, WORKFLOW_SNAPSHOT_FILE);
3007
3382
  let snapshot;
3008
3383
  try {
3009
- const read = readWorkflowSnapshot(dirname7(snapshotPath));
3384
+ const read = readWorkflowSnapshot(dirname8(snapshotPath));
3010
3385
  snapshot = read.snapshot;
3011
3386
  notes.push(...read.diagnostics);
3012
3387
  } catch (error) {
@@ -3059,14 +3434,14 @@ function gitOut(cwd, args) {
3059
3434
  }
3060
3435
  }
3061
3436
  function probeHarnessWithStatus(root) {
3062
- if (isFile2(join12(root, ".mstar", "status.json")))
3063
- return join12(root, ".mstar");
3064
- if (isFile2(join12(root, ".agents", "status.json")))
3065
- return join12(root, ".agents");
3066
- if (hasWorkflowSnapshot(join12(root, ".mstar")))
3067
- return join12(root, ".mstar");
3068
- if (hasWorkflowSnapshot(join12(root, ".agents")))
3069
- return join12(root, ".agents");
3437
+ if (isFile2(join13(root, ".mstar", "status.json")))
3438
+ return join13(root, ".mstar");
3439
+ if (isFile2(join13(root, ".agents", "status.json")))
3440
+ return join13(root, ".agents");
3441
+ if (hasWorkflowSnapshot(join13(root, ".mstar")))
3442
+ return join13(root, ".mstar");
3443
+ if (hasWorkflowSnapshot(join13(root, ".agents")))
3444
+ return join13(root, ".agents");
3070
3445
  return null;
3071
3446
  }
3072
3447
  function hasWorkflowSnapshot(harnessDir) {
@@ -3074,13 +3449,13 @@ function hasWorkflowSnapshot(harnessDir) {
3074
3449
  try {
3075
3450
  workflowsDir = resolveWorkflowDir(harnessDir, { harnessDir });
3076
3451
  } catch {
3077
- workflowsDir = join12(harnessDir, "workflows");
3452
+ workflowsDir = join13(harnessDir, "workflows");
3078
3453
  }
3079
3454
  if (!isDirectory2(workflowsDir))
3080
3455
  return false;
3081
3456
  try {
3082
- for (const entry of readdirSync6(workflowsDir, { withFileTypes: true })) {
3083
- if (entry.isDirectory() && isFile2(join12(workflowsDir, entry.name, "snapshot.json")))
3457
+ for (const entry of readdirSync7(workflowsDir, { withFileTypes: true })) {
3458
+ if (entry.isDirectory() && isFile2(join13(workflowsDir, entry.name, "snapshot.json")))
3084
3459
  return true;
3085
3460
  }
3086
3461
  } catch {
@@ -3089,16 +3464,16 @@ function hasWorkflowSnapshot(harnessDir) {
3089
3464
  return false;
3090
3465
  }
3091
3466
  function checkoutRootNearestExisting(dir, boundary) {
3092
- const stop = resolve9(boundary);
3093
- const startInside = isInside(resolve9(dir), stop);
3094
- let current = resolve9(dir);
3467
+ const stop = resolve11(boundary);
3468
+ const startInside = isInside(resolve11(dir), stop);
3469
+ let current = resolve11(dir);
3095
3470
  for (;; ) {
3096
3471
  const probed = probeCheckoutRoot(current);
3097
3472
  if (probed !== null)
3098
3473
  return probed;
3099
3474
  if (startInside && current === stop)
3100
3475
  return null;
3101
- const parent = dirname8(current);
3476
+ const parent = dirname9(current);
3102
3477
  if (parent === current)
3103
3478
  return null;
3104
3479
  if (startInside && !isInside(parent, stop))
@@ -3118,7 +3493,7 @@ function sddWorkspace(planId, opts = {}) {
3118
3493
  if (!isDirectory2(controlRoot)) {
3119
3494
  throw new SddScriptError(`mstar sdd workspace: CONTROL_ROOT / MSTAR_CONTROL_ROOT is not a directory: ${controlRoot}`, 1);
3120
3495
  }
3121
- const supplied = realpathSync4(controlRoot);
3496
+ const supplied = realpathSync5(controlRoot);
3122
3497
  const main = readMainWorktree(supplied);
3123
3498
  if (main !== null) {
3124
3499
  if (main.root !== supplied) {
@@ -3127,7 +3502,7 @@ function sddWorkspace(planId, opts = {}) {
3127
3502
  ` + ` Re-run with MSTAR_CONTROL_ROOT=${main.root}`, 1);
3128
3503
  }
3129
3504
  root = main.root;
3130
- } else if (isFile2(join12(supplied, ".git")) || gitOut(supplied, ["rev-parse", "--is-inside-work-tree"]) === "true") {
3505
+ } else if (isFile2(join13(supplied, ".git")) || gitOut(supplied, ["rev-parse", "--is-inside-work-tree"]) === "true") {
3131
3506
  throw new SddScriptError(`mstar sdd workspace: cannot verify the main worktree for CONTROL_ROOT "${supplied}" (git worktree discovery failed).
3132
3507
  Refusing to resolve or create any SDD tree without a verified main worktree.`, 1);
3133
3508
  } else {
@@ -3145,22 +3520,22 @@ function sddWorkspace(planId, opts = {}) {
3145
3520
  const harnessOverride = opts.harnessDir ?? (process.env.MSTAR_HARNESS_DIR || undefined);
3146
3521
  let harnessDir;
3147
3522
  if (harnessOverride) {
3148
- harnessDir = resolve9(root, harnessOverride);
3523
+ harnessDir = resolve11(root, harnessOverride);
3149
3524
  } else {
3150
3525
  const rc = findMstarc(root, root);
3151
- const rcHarnessDir = rc !== null ? parseMstarc(readFileSync8(rc, "utf8")).harnessDir : undefined;
3526
+ const rcHarnessDir = rc !== null ? parseMstarc(readFileSync9(rc, "utf8")).harnessDir : undefined;
3152
3527
  if (rcHarnessDir) {
3153
- harnessDir = resolve9(rc !== null ? dirname8(rc) : root, rcHarnessDir);
3528
+ harnessDir = resolve11(rc !== null ? dirname9(rc) : root, rcHarnessDir);
3154
3529
  } else {
3155
3530
  const probed = probeHarnessWithStatus(root);
3156
3531
  if (probed) {
3157
3532
  harnessDir = probed;
3158
- } else if (isDirectory2(join12(root, ".mstar"))) {
3159
- harnessDir = join12(root, ".mstar");
3160
- } else if (isDirectory2(join12(root, ".agents"))) {
3161
- harnessDir = join12(root, ".agents");
3533
+ } else if (isDirectory2(join13(root, ".mstar"))) {
3534
+ harnessDir = join13(root, ".mstar");
3535
+ } else if (isDirectory2(join13(root, ".agents"))) {
3536
+ harnessDir = join13(root, ".agents");
3162
3537
  } else {
3163
- harnessDir = join12(root, ".mstar");
3538
+ harnessDir = join13(root, ".mstar");
3164
3539
  }
3165
3540
  }
3166
3541
  }
@@ -3171,9 +3546,9 @@ function sddWorkspace(planId, opts = {}) {
3171
3546
  }
3172
3547
  const sddDir = resolveSddDir(harnessDir, planId);
3173
3548
  mkdirSync6(sddDir, { recursive: true });
3174
- writeFileSync4(join12(sddDir, ".gitignore"), `*
3549
+ writeFileSync4(join13(sddDir, ".gitignore"), `*
3175
3550
  `);
3176
- return realpathSync4(sddDir);
3551
+ return realpathSync5(sddDir);
3177
3552
  }
3178
3553
  function taskBrief(planFile, taskN, outFile, opts = {}) {
3179
3554
  if (!planFile || !Number.isInteger(taskN) || taskN < 1) {
@@ -3182,7 +3557,7 @@ function taskBrief(planFile, taskN, outFile, opts = {}) {
3182
3557
  const bound = opts.context;
3183
3558
  const observedCwd = opts.cwd ?? process.cwd();
3184
3559
  if (bound) {
3185
- const inputPlan = canonicalizeNearestExisting(resolve9(observedCwd, planFile));
3560
+ const inputPlan = canonicalizeNearestExisting(resolve11(observedCwd, planFile));
3186
3561
  if (inputPlan !== canonicalizeNearestExisting(bound.planFile)) {
3187
3562
  throwGateFail([
3188
3563
  contextViolation("high", "sdd.context.plan-file-mismatch", `plan file "${planFile}" does not match the bound context plan file "${bound.planFile}" — ` + "bound mode extracts only the resolved context's plan; refused before any read or write")
@@ -3191,16 +3566,16 @@ function taskBrief(planFile, taskN, outFile, opts = {}) {
3191
3566
  }
3192
3567
  let content;
3193
3568
  try {
3194
- content = readFileSync8(planFile, "utf8");
3569
+ content = readFileSync9(planFile, "utf8");
3195
3570
  } catch {
3196
3571
  throw new SddScriptError(`no such plan file: ${planFile}`, 2);
3197
3572
  }
3198
3573
  let out;
3199
3574
  let mkdirAfterGate = null;
3200
3575
  if (outFile) {
3201
- out = bound ? resolve9(observedCwd, outFile) : outFile;
3576
+ out = bound ? resolve11(observedCwd, outFile) : outFile;
3202
3577
  } else if (bound) {
3203
- out = join12(bound.sddDir, `task-${taskN}-brief.md`);
3578
+ out = join13(bound.sddDir, `task-${taskN}-brief.md`);
3204
3579
  mkdirAfterGate = bound.sddDir;
3205
3580
  } else {
3206
3581
  const sddDir = opts.sddDir ?? process.env.SDD_DIR;
@@ -3208,7 +3583,7 @@ function taskBrief(planFile, taskN, outFile, opts = {}) {
3208
3583
  throw new SddScriptError("mstar sdd task-brief: set SDD_DIR or pass OUTFILE (run mstar sdd workspace PLAN_ID first)", 2);
3209
3584
  }
3210
3585
  mkdirSync6(sddDir, { recursive: true });
3211
- out = join12(sddDir, `task-${taskN}-brief.md`);
3586
+ out = join13(sddDir, `task-${taskN}-brief.md`);
3212
3587
  }
3213
3588
  if (bound) {
3214
3589
  const gate2 = checkSddAction(bound, { kind: "artifact", cwd: observedCwd, target: out });
@@ -3241,15 +3616,15 @@ function taskBrief(planFile, taskN, outFile, opts = {}) {
3241
3616
  if (printed.length === 0) {
3242
3617
  throw new SddScriptError(`task ${taskN} not found in ${planFile} (no heading matching Task ${taskN})`, 3);
3243
3618
  }
3244
- return bound ? resolve9(observedCwd, out) : out;
3619
+ return bound ? resolve11(observedCwd, out) : out;
3245
3620
  }
3246
3621
  function isInside(child, ancestor) {
3247
3622
  const rel = relative3(ancestor, child);
3248
- return rel === "" || !rel.startsWith("..") && !isAbsolute7(rel);
3623
+ return rel === "" || !rel.startsWith("..") && !isAbsolute8(rel);
3249
3624
  }
3250
3625
  function canonicalDir(path) {
3251
3626
  try {
3252
- return statSync4(path).isDirectory() ? realpathSync4(path) : null;
3627
+ return statSync4(path).isDirectory() ? realpathSync5(path) : null;
3253
3628
  } catch {
3254
3629
  return null;
3255
3630
  }
@@ -3279,11 +3654,11 @@ function checkSddAction(context, action) {
3279
3654
  const featureReal = canonicalDir(context.featureCwd);
3280
3655
  const canonicalSddDir = canonicalizeNearestExisting(context.sddDir);
3281
3656
  const canonicalPlanFile = canonicalizeNearestExisting(context.planFile);
3282
- const cwdResolved = resolve9(action.cwd);
3657
+ const cwdResolved = resolve11(action.cwd);
3283
3658
  const checkTarget = (baseDir, target, kind) => {
3284
3659
  if (featureReal === null)
3285
3660
  return;
3286
- const targetAbs = resolve9(baseDir, target);
3661
+ const targetAbs = resolve11(baseDir, target);
3287
3662
  const canonical = canonicalizeNearestExisting(targetAbs);
3288
3663
  if (!isInside(canonical, featureReal)) {
3289
3664
  const declaredPrefix = targetAbs === featureReal || targetAbs.startsWith(`${featureReal}/`);
@@ -3311,10 +3686,10 @@ function checkSddAction(context, action) {
3311
3686
  add("sdd.context.target-missing", "artifact checks require the destination target");
3312
3687
  return { ok: false, violations };
3313
3688
  }
3314
- const targetAbs = resolve9(cwdResolved, action.target);
3689
+ const targetAbs = resolve11(cwdResolved, action.target);
3315
3690
  const canonical = canonicalizeNearestExisting(targetAbs);
3316
3691
  if (!isInside(canonical, canonicalSddDir) && canonical !== canonicalPlanFile) {
3317
- const rawSddDir = resolve9(context.sddDir);
3692
+ const rawSddDir = resolve11(context.sddDir);
3318
3693
  const declaredPrefix = targetAbs === rawSddDir || targetAbs.startsWith(`${rawSddDir}/`) || targetAbs === canonicalSddDir || targetAbs.startsWith(`${canonicalSddDir}/`) || targetAbs === canonicalPlanFile;
3319
3694
  if (declaredPrefix) {
3320
3695
  add("sdd.context.artifact-symlink-escape", `artifact target "${targetAbs}" canonicalizes to "${canonical}", outside the plan's control sddDir — symlink escape refused before write`);
@@ -4047,7 +4422,7 @@ function referenceExists(repoRoot, docText) {
4047
4422
  if (ref === "" || seen.has(ref))
4048
4423
  continue;
4049
4424
  seen.add(ref);
4050
- if (SCHEME_RE.test(ref) || ref.startsWith("{") || ref.startsWith("#") || ref.includes("*") || ref.includes("?") || ref.startsWith("~") || isAbsolute9(ref)) {
4425
+ if (SCHEME_RE.test(ref) || ref.startsWith("{") || ref.startsWith("#") || ref.includes("*") || ref.includes("?") || ref.startsWith("~") || isAbsolute10(ref)) {
4051
4426
  continue;
4052
4427
  }
4053
4428
  if (ref.includes("/") || REF_EXT_RE.test(ref)) {
@@ -4066,7 +4441,7 @@ function referenceExists(repoRoot, docText) {
4066
4441
  const dir = stack.pop();
4067
4442
  let entries;
4068
4443
  try {
4069
- entries = readdirSync9(dir, { withFileTypes: true });
4444
+ entries = readdirSync10(dir, { withFileTypes: true });
4070
4445
  } catch {
4071
4446
  continue;
4072
4447
  }
@@ -4075,7 +4450,7 @@ function referenceExists(repoRoot, docText) {
4075
4450
  break;
4076
4451
  if (entry.isDirectory()) {
4077
4452
  if (!WALK_SKIP_DIRS.has(entry.name))
4078
- stack.push(join16(dir, entry.name));
4453
+ stack.push(join17(dir, entry.name));
4079
4454
  } else if (!entry.isSymbolicLink()) {
4080
4455
  const base = entry.name.replace(/\.(?:ts|tsx|js|jsx|mjs|cjs)$/, "");
4081
4456
  if (moduleNames.has(base))
@@ -4087,7 +4462,7 @@ function referenceExists(repoRoot, docText) {
4087
4462
  for (const { ref, isSymbol, module } of refs) {
4088
4463
  if (!isSymbol || module === undefined) {
4089
4464
  const candidate = ref.replace(LINE_SUFFIX_RE, "").replace(ANCHOR_RE, "");
4090
- if (existsSync12(resolve13(repoRoot, candidate))) {
4465
+ if (existsSync13(resolve15(repoRoot, candidate))) {
4091
4466
  checked++;
4092
4467
  } else {
4093
4468
  violations.push(violation11("medium", "compound.reference.missing-file", `referenced path \`${ref}\` does not exist under ${repoRoot} (compound-refresh Phase 2: referenced code still exists?)`, "update the doc to reference an existing path, or delete the stale reference"));
@@ -4107,18 +4482,18 @@ function collectKnowledgeDocs(dir) {
4107
4482
  const current = stack.pop();
4108
4483
  let entries;
4109
4484
  try {
4110
- entries = readdirSync9(current, { withFileTypes: true });
4485
+ entries = readdirSync10(current, { withFileTypes: true });
4111
4486
  } catch {
4112
4487
  continue;
4113
4488
  }
4114
4489
  for (const entry of entries) {
4115
4490
  if (entry.isSymbolicLink())
4116
4491
  continue;
4117
- const full = join16(current, entry.name);
4492
+ const full = join17(current, entry.name);
4118
4493
  if (entry.isDirectory()) {
4119
4494
  stack.push(full);
4120
4495
  } else if (entry.name.endsWith(".md") && entry.name !== "README.md" && entry.name !== "index.md") {
4121
- docs.push(relative6(dir, full).split(sep4).join("/"));
4496
+ docs.push(relative6(dir, full).split(sep5).join("/"));
4122
4497
  }
4123
4498
  }
4124
4499
  }
@@ -4134,14 +4509,14 @@ function normalizeIndexRef(cell) {
4134
4509
  }
4135
4510
  function assertIndexRows(knowledgeDir) {
4136
4511
  const violations = [];
4137
- const readmePath = join16(knowledgeDir, "README.md");
4138
- if (!existsSync12(readmePath)) {
4512
+ const readmePath = join17(knowledgeDir, "README.md");
4513
+ if (!existsSync13(readmePath)) {
4139
4514
  violations.push(violation11("medium", "compound.index.missing-readme", `missing ${readmePath} — the knowledge index is required (mstar-compound Phase 6: every doc gets a README.md row)`, "create knowledge/README.md with a Document / Source Plan / Description / Status table"));
4140
4515
  return { ok: false, violations };
4141
4516
  }
4142
4517
  const docs = collectKnowledgeDocs(knowledgeDir);
4143
4518
  const rows = new Set;
4144
- for (const line of readFileSync11(readmePath, "utf8").split(/\r?\n/)) {
4519
+ for (const line of readFileSync12(readmePath, "utf8").split(/\r?\n/)) {
4145
4520
  if (!line.trim().startsWith("|"))
4146
4521
  continue;
4147
4522
  const cells = line.split("|").map((c) => c.trim());
@@ -4159,16 +4534,16 @@ function assertIndexRows(knowledgeDir) {
4159
4534
  return { ok: violations.length === 0, violations };
4160
4535
  }
4161
4536
  function isFileLikeRoot(root) {
4162
- return /^[^.]*\.[A-Za-z0-9]{1,10}$/.test(basename8(root));
4537
+ return /^[^.]*\.[A-Za-z0-9]{1,10}$/.test(basename11(root));
4163
4538
  }
4164
4539
  function scopeGuard(path, allowedRoots) {
4165
- const resolved = resolve13(path);
4540
+ const resolved = resolve15(path);
4166
4541
  for (const root of allowedRoots) {
4167
- const r = resolve13(root);
4542
+ const r = resolve15(root);
4168
4543
  if (isFileLikeRoot(r)) {
4169
4544
  if (resolved === r)
4170
4545
  return { ok: true, violations: [] };
4171
- } else if (resolved === r || resolved.startsWith(r + sep4)) {
4546
+ } else if (resolved === r || resolved.startsWith(r + sep5)) {
4172
4547
  return { ok: true, violations: [] };
4173
4548
  }
4174
4549
  }
@@ -4324,8 +4699,8 @@ function validateRoleMapping(rolesDir, options = {}) {
4324
4699
  const violations = [];
4325
4700
  const referenceById = new Map(mapping.map((m) => [m.agentId, m.reference]));
4326
4701
  for (const { agentId, reference } of mapping) {
4327
- if (!existsSync13(join17(rolesDir, reference))) {
4328
- violations.push(violation13("medium", "roles.mapping.reference.missing", `role "${agentId}" maps to ${reference} which does not exist under ${rolesDir} (mstar-roles § Role Reference Mapping)`, `create ${join17(rolesDir, reference)} or fix the mapping row`));
4702
+ if (!existsSync14(join18(rolesDir, reference))) {
4703
+ violations.push(violation13("medium", "roles.mapping.reference.missing", `role "${agentId}" maps to ${reference} which does not exist under ${rolesDir} (mstar-roles § Role Reference Mapping)`, `create ${join18(rolesDir, reference)} or fix the mapping row`));
4329
4704
  }
4330
4705
  }
4331
4706
  for (const { family, memberIds } of families) {
@@ -4584,7 +4959,7 @@ class DshMstar extends Service {
4584
4959
  // src/gates/_shared.ts
4585
4960
  var import_schemastery = __toESM(require_lib2(), 1);
4586
4961
  import { existsSync as existsSync2 } from "node:fs";
4587
- import { resolve as resolve4 } from "node:path";
4962
+ import { resolve as resolve5 } from "node:path";
4588
4963
  import { fileURLToPath as fileURLToPath2 } from "node:url";
4589
4964
  var STATUS_FILE = "status.json";
4590
4965
  var PERSONA_INTERPOLATION_HAZARD = /\{\{[\s\S]*\}\}/;
@@ -4683,14 +5058,14 @@ class HarnessResolver {
4683
5058
  explicit;
4684
5059
  cache = new Map;
4685
5060
  constructor(explicit) {
4686
- this.explicit = explicit !== undefined && explicit.trim() !== "" ? resolve4(process.cwd(), explicit) : null;
5061
+ this.explicit = explicit !== undefined && explicit.trim() !== "" ? resolve5(process.cwd(), explicit) : null;
4687
5062
  }
4688
5063
  forWorkspace(cwd) {
4689
5064
  if (this.explicit !== null)
4690
5065
  return this.explicit;
4691
5066
  if (cwd === undefined || cwd.trim() === "")
4692
5067
  return null;
4693
- const abs = resolve4(cwd);
5068
+ const abs = resolve5(cwd);
4694
5069
  const hit = this.cache.get(abs);
4695
5070
  if (hit !== undefined)
4696
5071
  return hit;
@@ -4761,21 +5136,21 @@ function skillLocalConfig(config) {
4761
5136
  }
4762
5137
 
4763
5138
  // src/gates/catalog.ts
4764
- import { existsSync as existsSync16, readFileSync as readFileSync12, readdirSync as readdirSync4, realpathSync as realpathSync7 } from "node:fs";
4765
- import { basename as basename4, isAbsolute as isAbsolute8, join as join18, relative as relative7, sep as sep3 } from "node:path";
5139
+ import { existsSync as existsSync15, readFileSync as readFileSync10, readdirSync as readdirSync5, realpathSync as realpathSync6 } from "node:fs";
5140
+ import { basename as basename6, isAbsolute as isAbsolute9, join as join19, relative as relative7, sep as sep3 } from "node:path";
4766
5141
  import { createUserMessage } from "@deepseek-ai/dsh-llm";
4767
5142
 
4768
5143
  // src/gates/agent-flow.ts
4769
- import { appendFileSync, closeSync, existsSync as existsSync14, mkdirSync as mkdirSync2, openSync, readFileSync as readFileSync6, readSync, renameSync as renameSync2, rmdirSync, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "node:fs";
4770
- import { join as join13 } from "node:path";
5144
+ import { appendFileSync, closeSync, existsSync as existsSync11, mkdirSync as mkdirSync2, openSync, readFileSync as readFileSync3, readSync, renameSync as renameSync2, rmdirSync, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "node:fs";
5145
+ import { join as join14 } from "node:path";
4771
5146
 
4772
5147
  // src/gates/dispatch.ts
4773
- import { existsSync as existsSync10 } from "node:fs";
4774
- import { basename as basename2, join as join7, resolve as resolve6 } from "node:path";
5148
+ import { existsSync as existsSync7 } from "node:fs";
5149
+ import { basename as basename3, join as join8, resolve as resolve8 } from "node:path";
4775
5150
 
4776
5151
  // src/gates/workflow-selection.ts
4777
- import { existsSync as existsSync6, readdirSync, realpathSync as realpathSync5, statSync as statSync2 } from "node:fs";
4778
- import { dirname as dirname6, isAbsolute as isAbsolute3, join as join4, normalize, relative as relative4, sep as sep2 } from "node:path";
5152
+ import { existsSync as existsSync3, readdirSync, realpathSync, statSync as statSync2 } from "node:fs";
5153
+ import { dirname as dirname7, isAbsolute as isAbsolute4, join as join5, normalize, relative as relative4, sep } from "node:path";
4779
5154
  var TERMINAL_STATUS_CACHE_MAX = 64;
4780
5155
  var terminalStatusCache = new Map;
4781
5156
  function terminalStatusOf(snapshotPath) {
@@ -4811,7 +5186,7 @@ function terminalStatusOf(snapshotPath) {
4811
5186
  }
4812
5187
  function stripTrailingSeparators(path) {
4813
5188
  let out = path;
4814
- while (out.length > 1 && out.endsWith(sep2))
5189
+ while (out.length > 1 && out.endsWith(sep))
4815
5190
  out = out.slice(0, -1);
4816
5191
  return out;
4817
5192
  }
@@ -4821,13 +5196,13 @@ function lexical(path) {
4821
5196
  function canonicalPath(path) {
4822
5197
  const fallback = lexical(path);
4823
5198
  try {
4824
- return { kind: "ok", path: lexical(realpathSync5(path)) };
5199
+ return { kind: "ok", path: lexical(realpathSync(path)) };
4825
5200
  } catch (error) {
4826
5201
  return error.code === "ENOENT" ? { kind: "missing", path: fallback } : { kind: "error" };
4827
5202
  }
4828
5203
  }
4829
5204
  function within(root, cwd) {
4830
- if (root === "" || cwd === "" || !isAbsolute3(root) || !isAbsolute3(cwd))
5205
+ if (root === "" || cwd === "" || !isAbsolute4(root) || !isAbsolute4(cwd))
4831
5206
  return false;
4832
5207
  const rootCanonical = canonicalPath(root);
4833
5208
  if (rootCanonical.kind === "error")
@@ -4841,7 +5216,7 @@ function within(root, cwd) {
4841
5216
  if (rootPath === cwdPath)
4842
5217
  return true;
4843
5218
  const rel = relative4(rootPath, cwdPath);
4844
- return rel !== "" && !isAbsolute3(rel) && rel !== ".." && !rel.startsWith(`..${sep2}`);
5219
+ return rel !== "" && !isAbsolute4(rel) && rel !== ".." && !rel.startsWith(`..${sep}`);
4845
5220
  }
4846
5221
  function validLeases(snapshot) {
4847
5222
  if (!Array.isArray(snapshot.plans))
@@ -4856,8 +5231,8 @@ function validLeases(snapshot) {
4856
5231
  return leases;
4857
5232
  }
4858
5233
  function readSnapshot(harnessDir, entry) {
4859
- const snapshotPath = join4(harnessDir, entry.dir, WORKFLOW_SNAPSHOT_FILE);
4860
- if (!existsSync6(snapshotPath))
5234
+ const snapshotPath = join5(harnessDir, entry.dir, WORKFLOW_SNAPSHOT_FILE);
5235
+ if (!existsSync3(snapshotPath))
4861
5236
  return;
4862
5237
  try {
4863
5238
  const snapshot = asRecord(readJson(snapshotPath));
@@ -4913,8 +5288,8 @@ function automaticBinding(harnessDir, entries, hint) {
4913
5288
  return byCwd === undefined ? undefined : { kind: "active", workflowId: byCwd.id, dir: byCwd.dir };
4914
5289
  }
4915
5290
  function resolveActiveWorkflow(harnessDir, hint) {
4916
- const statusPath = join4(harnessDir, STATUS_FILE);
4917
- if (!existsSync6(statusPath)) {
5291
+ const statusPath = join5(harnessDir, STATUS_FILE);
5292
+ if (!existsSync3(statusPath)) {
4918
5293
  return {
4919
5294
  kind: "error",
4920
5295
  code: "status.missing",
@@ -5004,7 +5379,7 @@ function resolveReadWorkflow(harnessDir, hint) {
5004
5379
  if (active.kind === "error" && active.code !== "workflow.selection.no-active")
5005
5380
  return active;
5006
5381
  const workflowsDir = resolveWorkflowDir(harnessDir, { harnessDir });
5007
- if (!existsSync6(workflowsDir)) {
5382
+ if (!existsSync3(workflowsDir)) {
5008
5383
  return {
5009
5384
  kind: "error",
5010
5385
  code: "workflow.selection.no-snapshot",
@@ -5025,8 +5400,8 @@ function resolveReadWorkflow(harnessDir, hint) {
5025
5400
  for (const entry of entries) {
5026
5401
  if (!entry.isDirectory())
5027
5402
  continue;
5028
- const snapshotPath = join4(workflowsDir, entry.name, WORKFLOW_SNAPSHOT_FILE);
5029
- if (!existsSync6(snapshotPath)) {
5403
+ const snapshotPath = join5(workflowsDir, entry.name, WORKFLOW_SNAPSHOT_FILE);
5404
+ if (!existsSync3(snapshotPath)) {
5030
5405
  terminalStatusCache.delete(snapshotPath);
5031
5406
  continue;
5032
5407
  }
@@ -5034,11 +5409,11 @@ function resolveReadWorkflow(harnessDir, hint) {
5034
5409
  if (verdict === undefined || !verdict.terminal)
5035
5410
  continue;
5036
5411
  if (best === undefined || verdict.mtimeMs > best.mtimeMs) {
5037
- best = { workflowId: entry.name, dir: join4(relative4(harnessDir, workflowsDir), entry.name), mtimeMs: verdict.mtimeMs };
5412
+ best = { workflowId: entry.name, dir: join5(relative4(harnessDir, workflowsDir), entry.name), mtimeMs: verdict.mtimeMs };
5038
5413
  }
5039
5414
  }
5040
5415
  for (const cachedPath of terminalStatusCache.keys()) {
5041
- if (!existsSync6(join4(dirname6(cachedPath), WORKFLOW_SNAPSHOT_FILE))) {
5416
+ if (!existsSync3(join5(dirname7(cachedPath), WORKFLOW_SNAPSHOT_FILE))) {
5042
5417
  terminalStatusCache.delete(cachedPath);
5043
5418
  }
5044
5419
  }
@@ -5207,12 +5582,12 @@ function isNaValue(value) {
5207
5582
  function planIdOf(headerRegion) {
5208
5583
  const planPath = assignmentHeaderValue(headerRegion, "Plan Path");
5209
5584
  if (!isNaValue(planPath)) {
5210
- const id = basename2(firstToken(planPath) ?? "");
5585
+ const id = basename3(firstToken(planPath) ?? "");
5211
5586
  return id.endsWith(".md") ? id.slice(0, -3) : id;
5212
5587
  }
5213
5588
  const sddDir = assignmentHeaderValue(headerRegion, "SDD dir");
5214
5589
  if (!isNaValue(sddDir)) {
5215
- const id = basename2(firstToken(sddDir) ?? "");
5590
+ const id = basename3(firstToken(sddDir) ?? "");
5216
5591
  return id === "" ? undefined : id;
5217
5592
  }
5218
5593
  const planId = assignmentHeaderValue(headerRegion, "plan_id");
@@ -5237,12 +5612,12 @@ function leaseGateViolations(harnessDir, exec, writable, prompt, hint) {
5237
5612
  if (!sdd)
5238
5613
  return [];
5239
5614
  if (selection.kind === "error" && selection.code === "status.unreadable") {
5240
- return [leaseViolation("lease.dispatch.unreadable", `cannot read ${join7(harnessDir, STATUS_FILE)}: the plan's execution_lease state is unverifiable; STOP before writable dispatch`, "restore a valid status.json (the status gate refuses invalid writes)")];
5615
+ return [leaseViolation("lease.dispatch.unreadable", `cannot read ${join8(harnessDir, STATUS_FILE)}: the plan's execution_lease state is unverifiable; STOP before writable dispatch`, "restore a valid status.json (the status gate refuses invalid writes)")];
5241
5616
  }
5242
- return [leaseViolation("lease.dispatch.unverifiable", `${join7(harnessDir, STATUS_FILE)}: ${selection.kind === "error" ? selection.message : "no active workflow"} — the plan's execution_lease state is unverifiable; STOP before writable dispatch`, "create a valid v2 status.json registering an active workflow (first implement dispatch requires a plan row + lease)")];
5617
+ return [leaseViolation("lease.dispatch.unverifiable", `${join8(harnessDir, STATUS_FILE)}: ${selection.kind === "error" ? selection.message : "no active workflow"} — the plan's execution_lease state is unverifiable; STOP before writable dispatch`, "create a valid v2 status.json registering an active workflow (first implement dispatch requires a plan row + lease)")];
5243
5618
  }
5244
- const snapshotPath = join7(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
5245
- if (!existsSync10(snapshotPath)) {
5619
+ const snapshotPath = join8(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
5620
+ if (!existsSync7(snapshotPath)) {
5246
5621
  if (!sdd)
5247
5622
  return [];
5248
5623
  return [leaseViolation("lease.dispatch.unverifiable", `${snapshotPath} is missing — the plan's execution_lease state is unverifiable; STOP before writable dispatch`, "create a valid workflow snapshot registering the plan row (first implement dispatch requires a plan row)")];
@@ -5275,7 +5650,7 @@ function leaseGateViolations(harnessDir, exec, writable, prompt, hint) {
5275
5650
  const wt = worktree === undefined ? undefined : firstToken(worktree);
5276
5651
  if (isNaValue(wt)) {
5277
5652
  violations.push(leaseViolation("lease.dispatch.worktree-mismatch", "Assignment declares no Worktree path — cannot confirm this dispatch matches execution_lease.worktree_path", "add the absolute Worktree path to the Assignment (must equal the lease worktree_path)"));
5278
- } else if (resolve6(wt) !== resolve6(String(lease.worktree_path ?? ""))) {
5653
+ } else if (resolve8(wt) !== resolve8(String(lease.worktree_path ?? ""))) {
5279
5654
  violations.push(leaseViolation("lease.dispatch.worktree-mismatch", `Assignment Worktree path "${wt}" differs from execution_lease.worktree_path "${String(lease.worktree_path)}"`, "align the Assignment with the lease worktree path (or update the lease)"));
5280
5655
  }
5281
5656
  const forms = parseAssignmentBranchForms(header);
@@ -5316,7 +5691,7 @@ function worktreeL2Violations(header) {
5316
5691
  return violations;
5317
5692
  }
5318
5693
  function activeSnapshotRows(harnessDir, hint) {
5319
- if (!existsSync10(join7(harnessDir, STATUS_FILE)))
5694
+ if (!existsSync7(join8(harnessDir, STATUS_FILE)))
5320
5695
  return { rows: null, snapshot: null, workflowId: null, unreadable: false };
5321
5696
  const selection = resolveActiveWorkflow(harnessDir, hint);
5322
5697
  if (selection.kind !== "active") {
@@ -5327,8 +5702,8 @@ function activeSnapshotRows(harnessDir, hint) {
5327
5702
  unreadable: selection.kind === "error" && selection.code !== "workflow.selection.no-active"
5328
5703
  };
5329
5704
  }
5330
- const snapshotDir = join7(harnessDir, selection.dir);
5331
- if (!existsSync10(join7(snapshotDir, WORKFLOW_SNAPSHOT_FILE))) {
5705
+ const snapshotDir = join8(harnessDir, selection.dir);
5706
+ if (!existsSync7(join8(snapshotDir, WORKFLOW_SNAPSHOT_FILE))) {
5332
5707
  return { rows: null, snapshot: null, workflowId: selection.workflowId, unreadable: true };
5333
5708
  }
5334
5709
  let snapshot;
@@ -5432,7 +5807,7 @@ function gateWorkflow(ctx, harnessDir, config, adapter, exec, hintReadOf) {
5432
5807
  }
5433
5808
  const pb = writableFanOutUncovered(harnessDir, hintReadOf().hint);
5434
5809
  if (pb.unreadable) {
5435
- const statusLabel = harnessDir === null ? STATUS_FILE : join7(harnessDir, STATUS_FILE);
5810
+ const statusLabel = harnessDir === null ? STATUS_FILE : join8(harnessDir, STATUS_FILE);
5436
5811
  ctx.logger(DISPATCH_LOGGER).warn(`workflow gate (${toolName}) (fail-open): cannot read ${statusLabel} — P-b lease attribution degraded; call allowed`);
5437
5812
  }
5438
5813
  const verdict = workflowPolicy(config, adapter.workflowAskCache, {
@@ -5544,10 +5919,16 @@ function assignmentTextFromFields(fields) {
5544
5919
  lines.push(`**Delegation**: ${fields.delegation}`);
5545
5920
  if (fields.taskCategory !== undefined)
5546
5921
  lines.push(`**Task category**: ${fields.taskCategory}`);
5922
+ if (fields.taskBudget !== undefined)
5923
+ lines.push(`**Task budget (implement / ops rounds)**: ${fields.taskBudget}`);
5547
5924
  if (fields.workingBranch !== undefined)
5548
5925
  lines.push(`**Working branch**: ${fields.workingBranch}`);
5549
5926
  if (fields.branchPolicy !== undefined)
5550
5927
  lines.push(`**Branch policy**: ${fields.branchPolicy}`);
5928
+ if (fields.budget !== undefined)
5929
+ lines.push(`**Budget (review / QC seats)**: ${fields.budget}`);
5930
+ if (fields.returnShape !== undefined)
5931
+ lines.push(`**Return shape (review / QC seats)**: ${fields.returnShape}`);
5551
5932
  return lines.join(`
5552
5933
  `);
5553
5934
  }
@@ -5637,7 +6018,7 @@ function callPairingKey(exec) {
5637
6018
  function resolveAgentFlowWriteTarget(harnessDir, hint) {
5638
6019
  const selection = resolveActiveWorkflow(harnessDir, hint);
5639
6020
  if (selection.kind === "active")
5640
- return { dir: join13(harnessDir, selection.dir), selection };
6021
+ return { dir: join14(harnessDir, selection.dir), selection };
5641
6022
  const message = selection.kind === "error" ? selection.message : "no active lifecycle (unexpected terminal selection — the active-set resolver has no history view)";
5642
6023
  if (!noActiveWarned) {
5643
6024
  noActiveWarned = true;
@@ -5657,7 +6038,7 @@ function sleepSync(ms) {
5657
6038
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
5658
6039
  }
5659
6040
  function withWorkflowDirLock(workflowDir, fn, opts = {}) {
5660
- const lockDir = join13(workflowDir, WORKFLOW_LEDGER_LOCKDIR);
6041
+ const lockDir = join14(workflowDir, WORKFLOW_LEDGER_LOCKDIR);
5661
6042
  if (heldWorkflowLocks.has(lockDir)) {
5662
6043
  throw new Error(`${lockDir} is already held by this process — withWorkflowDirLock is not reentrant; a nested acquisition on the same workflow dir is a bug`);
5663
6044
  }
@@ -5683,7 +6064,7 @@ function withWorkflowDirLock(workflowDir, fn, opts = {}) {
5683
6064
  heldWorkflowLocks.add(lockDir);
5684
6065
  try {
5685
6066
  try {
5686
- writeFileSync2(join13(lockDir, WORKFLOW_LOCKER_HOLDER_PID), String(process.pid), "utf8");
6067
+ writeFileSync2(join14(lockDir, WORKFLOW_LOCKER_HOLDER_PID), String(process.pid), "utf8");
5687
6068
  } catch {}
5688
6069
  return fn();
5689
6070
  } finally {
@@ -5692,7 +6073,7 @@ function withWorkflowDirLock(workflowDir, fn, opts = {}) {
5692
6073
  const current = statSync5(lockDir);
5693
6074
  if (acquired !== null && current.dev === acquired.dev && current.ino === acquired.ino) {
5694
6075
  try {
5695
- unlinkSync2(join13(lockDir, WORKFLOW_LOCKER_HOLDER_PID));
6076
+ unlinkSync2(join14(lockDir, WORKFLOW_LOCKER_HOLDER_PID));
5696
6077
  } catch {}
5697
6078
  rmdirSync(lockDir);
5698
6079
  }
@@ -5700,13 +6081,13 @@ function withWorkflowDirLock(workflowDir, fn, opts = {}) {
5700
6081
  }
5701
6082
  }
5702
6083
  function appendEvent(workflowDir, event) {
5703
- const file = join13(workflowDir, AGENT_FLOW_FILE);
6084
+ const file = join14(workflowDir, AGENT_FLOW_FILE);
5704
6085
  withWorkflowDirLock(workflowDir, () => {
5705
6086
  appendFileSync(file, `${JSON.stringify(event)}
5706
6087
  `);
5707
6088
  if (statSync5(file).size <= AGENT_FLOW_SIZE_GATE_BYTES)
5708
6089
  return;
5709
- const content = readFileSync6(file, "utf8");
6090
+ const content = readFileSync3(file, "utf8");
5710
6091
  const lines = content.replace(/\n$/, "").split(`
5711
6092
  `);
5712
6093
  if (lines.length > AGENT_FLOW_MAX_EVENTS) {
@@ -6110,7 +6491,7 @@ function summaryOf(events) {
6110
6491
  function ledgerContent(file, n) {
6111
6492
  const size = statSync5(file).size;
6112
6493
  if (size <= AGENT_FLOW_TAIL_READ_THRESHOLD_BYTES) {
6113
- return readFileSync6(file, "utf8");
6494
+ return readFileSync3(file, "utf8");
6114
6495
  }
6115
6496
  let windowBytes = AGENT_FLOW_TAIL_READ_THRESHOLD_BYTES;
6116
6497
  const fd = openSync(file, "r");
@@ -6142,8 +6523,8 @@ function ledgerContent(file, n) {
6142
6523
  }
6143
6524
  }
6144
6525
  function readAgentFlow(workflowDir, limit) {
6145
- const file = join13(workflowDir, AGENT_FLOW_FILE);
6146
- if (!existsSync14(file)) {
6526
+ const file = join14(workflowDir, AGENT_FLOW_FILE);
6527
+ if (!existsSync11(file)) {
6147
6528
  return { events: [], summary: [] };
6148
6529
  }
6149
6530
  const n = limit === undefined ? AGENT_FLOW_DEFAULT_LIMIT : Math.max(0, Math.floor(limit));
@@ -6308,8 +6689,8 @@ function reserveCatalogCandidate(pairing, ref, exec) {
6308
6689
  map.set(label, { ref, fromSeq: seq });
6309
6690
  ref.catalog = { session, label };
6310
6691
  }
6311
- function matchCatalogEvent(session, label, join8, envelope) {
6312
- const result = join8.result;
6692
+ function matchCatalogEvent(session, label, join9, envelope) {
6693
+ const result = join9.result;
6313
6694
  if (result === undefined)
6314
6695
  return;
6315
6696
  const rec = asRecord(envelope);
@@ -6323,7 +6704,7 @@ function matchCatalogEvent(session, label, join8, envelope) {
6323
6704
  const seq = rec.seq;
6324
6705
  if (typeof seq !== "number" || !Number.isInteger(seq))
6325
6706
  return;
6326
- if (seq < join8.fromSeq || seq >= session.seq || seq >= WORKFLOW_LEDGER_MAX_SEQ)
6707
+ if (seq < join9.fromSeq || seq >= session.seq || seq >= WORKFLOW_LEDGER_MAX_SEQ)
6327
6708
  return;
6328
6709
  const childCreatedAt = data.childCreatedAt;
6329
6710
  if (typeof childCreatedAt !== "number" || !Number.isInteger(childCreatedAt) || childCreatedAt < 0)
@@ -6339,9 +6720,9 @@ function matchCatalogEvent(session, label, join8, envelope) {
6339
6720
  return;
6340
6721
  return childId;
6341
6722
  }
6342
- function consumeCatalogCandidate(map, label, join8, childId) {
6723
+ function consumeCatalogCandidate(map, label, join9, childId) {
6343
6724
  map.set(label, null);
6344
- const ref = join8.ref;
6725
+ const ref = join9.ref;
6345
6726
  ref.childId = childId;
6346
6727
  delete ref.catalog;
6347
6728
  recordSubagentLink({ ref, childId, label });
@@ -6352,16 +6733,16 @@ function advanceCatalogCandidate(pairing, ref, result) {
6352
6733
  if (catalog === undefined)
6353
6734
  return;
6354
6735
  const map = pairing.catalogBySession.get(catalog.session);
6355
- const join8 = map?.get(catalog.label);
6356
- if (map === undefined || join8 === undefined || join8 === null || join8.ref !== ref)
6736
+ const join9 = map?.get(catalog.label);
6737
+ if (map === undefined || join9 === undefined || join9 === null || join9.ref !== ref)
6357
6738
  return;
6358
- join8.result = result;
6739
+ join9.result = result;
6359
6740
  const end = catalog.session.seq;
6360
6741
  let skippedReads = 0;
6361
6742
  let firstSkippedSeq;
6362
6743
  let firstSkippedError;
6363
6744
  try {
6364
- for (let seq = join8.fromSeq;seq < end; seq += 1) {
6745
+ for (let seq = join9.fromSeq;seq < end; seq += 1) {
6365
6746
  let envelope;
6366
6747
  try {
6367
6748
  envelope = catalog.session.eventAt(seq);
@@ -6373,10 +6754,10 @@ function advanceCatalogCandidate(pairing, ref, result) {
6373
6754
  }
6374
6755
  continue;
6375
6756
  }
6376
- const childId = matchCatalogEvent(catalog.session, catalog.label, join8, envelope);
6757
+ const childId = matchCatalogEvent(catalog.session, catalog.label, join9, envelope);
6377
6758
  if (childId === undefined)
6378
6759
  continue;
6379
- consumeCatalogCandidate(map, catalog.label, join8, childId);
6760
+ consumeCatalogCandidate(map, catalog.label, join9, childId);
6380
6761
  return;
6381
6762
  }
6382
6763
  } finally {
@@ -6451,13 +6832,13 @@ function registerSubagentCatalogListener(ctx, pairing) {
6451
6832
  const map = pairing.catalogBySession.get(session);
6452
6833
  if (map === undefined)
6453
6834
  return;
6454
- for (const [label, join8] of map) {
6455
- if (join8 === null || join8.result === undefined)
6835
+ for (const [label, join9] of map) {
6836
+ if (join9 === null || join9.result === undefined)
6456
6837
  continue;
6457
- const childId = matchCatalogEvent(session, label, join8, envelope);
6838
+ const childId = matchCatalogEvent(session, label, join9, envelope);
6458
6839
  if (childId === undefined)
6459
6840
  continue;
6460
- consumeCatalogCandidate(map, label, join8, childId);
6841
+ consumeCatalogCandidate(map, label, join9, childId);
6461
6842
  }
6462
6843
  } catch (error) {
6463
6844
  log("warn", `subagent catalog observation failed (contained — the session append proceeds): ${errorMessage(error)}`);
@@ -6466,8 +6847,8 @@ function registerSubagentCatalogListener(ctx, pairing) {
6466
6847
  }
6467
6848
 
6468
6849
  // src/engine-status-store.ts
6469
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync9, renameSync as renameSync3, rmSync, statSync as statSync7, writeFileSync as writeFileSync5 } from "node:fs";
6470
- import { dirname as dirname9, join as join15 } from "node:path";
6850
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync7, renameSync as renameSync3, rmSync, statSync as statSync7, writeFileSync as writeFileSync5 } from "node:fs";
6851
+ import { dirname as dirname10, join as join16 } from "node:path";
6471
6852
  var ENGINE_STATUS_SNAPSHOT_VERSION = 1;
6472
6853
  var ENGINE_STATUS_SNAPSHOT_ENTRY_VERSION = 1;
6473
6854
  var ENGINE_STATUS_SNAPSHOT_MAX_PER_SESSION = 50;
@@ -6476,19 +6857,19 @@ var ENGINE_STATUS_SNAPSHOT_MAX_BYTES = 16 * 1024 * 1024;
6476
6857
  var ENGINE_STATUS_SNAPSHOT_LOCK_TIMEOUT_MS = 250;
6477
6858
  var ENGINE_STATUS_SNAPSHOT_RELATIVE_PATH = "snapshots/engine-status.json";
6478
6859
  function engineStatusSnapshotPath(harnessDir) {
6479
- return join15(harnessDir, ENGINE_STATUS_SNAPSHOT_RELATIVE_PATH);
6860
+ return join16(harnessDir, ENGINE_STATUS_SNAPSHOT_RELATIVE_PATH);
6480
6861
  }
6481
6862
  function engineStatusUnavailable(reason) {
6482
6863
  return { kind: "unavailable", reason };
6483
6864
  }
6484
- function isPlainObject6(value) {
6865
+ function isPlainObject4(value) {
6485
6866
  return typeof value === "object" && value !== null && !Array.isArray(value);
6486
6867
  }
6487
6868
  function nonEmptyString(value) {
6488
6869
  return typeof value === "string" && value !== "" ? value : undefined;
6489
6870
  }
6490
6871
  function asEntry(value) {
6491
- if (!isPlainObject6(value))
6872
+ if (!isPlainObject4(value))
6492
6873
  return;
6493
6874
  if (value.rv !== ENGINE_STATUS_SNAPSHOT_ENTRY_VERSION)
6494
6875
  return;
@@ -6498,12 +6879,12 @@ function asEntry(value) {
6498
6879
  return;
6499
6880
  if (typeof value.turn !== "number" || !Number.isFinite(value.turn))
6500
6881
  return;
6501
- if (!isPlainObject6(value.payload))
6882
+ if (!isPlainObject4(value.payload))
6502
6883
  return;
6503
6884
  return { rv: value.rv, cwd, at, turn: value.turn, payload: value.payload };
6504
6885
  }
6505
6886
  function asBinding(value) {
6506
- if (!isPlainObject6(value))
6887
+ if (!isPlainObject4(value))
6507
6888
  return;
6508
6889
  const cwd = nonEmptyString(value.cwd);
6509
6890
  if (cwd === undefined)
@@ -6534,7 +6915,7 @@ function readEngineStatusSnapshot(harnessDir, sessionId) {
6534
6915
  return engineStatusUnavailable("no-session-entry");
6535
6916
  let raw;
6536
6917
  try {
6537
- raw = readFileSync9(engineStatusSnapshotPath(harnessDir), "utf8");
6918
+ raw = readFileSync7(engineStatusSnapshotPath(harnessDir), "utf8");
6538
6919
  } catch (error) {
6539
6920
  const code = error.code;
6540
6921
  return engineStatusUnavailable(code === "ENOENT" ? "absent" : "unreadable");
@@ -6545,11 +6926,11 @@ function readEngineStatusSnapshot(harnessDir, sessionId) {
6545
6926
  } catch {
6546
6927
  return engineStatusUnavailable("invalid-json");
6547
6928
  }
6548
- if (!isPlainObject6(doc) || doc.sv !== ENGINE_STATUS_SNAPSHOT_VERSION) {
6929
+ if (!isPlainObject4(doc) || doc.sv !== ENGINE_STATUS_SNAPSHOT_VERSION) {
6549
6930
  return engineStatusUnavailable("envelope-schema");
6550
6931
  }
6551
6932
  const entries = doc.entries;
6552
- if (!isPlainObject6(entries))
6933
+ if (!isPlainObject4(entries))
6553
6934
  return engineStatusUnavailable("envelope-schema");
6554
6935
  if (!Object.hasOwn(entries, sessionId))
6555
6936
  return engineStatusUnavailable("no-session-entry");
@@ -6574,7 +6955,7 @@ function serializeEnvelope(entries, bindings) {
6574
6955
  function loadForWrite(harnessDir) {
6575
6956
  let raw;
6576
6957
  try {
6577
- raw = readFileSync9(engineStatusSnapshotPath(harnessDir), "utf8");
6958
+ raw = readFileSync7(engineStatusSnapshotPath(harnessDir), "utf8");
6578
6959
  } catch (error) {
6579
6960
  if (error.code === "ENOENT") {
6580
6961
  return {
@@ -6590,7 +6971,7 @@ function loadForWrite(harnessDir) {
6590
6971
  } catch {
6591
6972
  return { kind: "refused", reason: "store-invalid-json" };
6592
6973
  }
6593
- if (!isPlainObject6(parsed) || parsed.sv !== ENGINE_STATUS_SNAPSHOT_VERSION || !isPlainObject6(parsed.entries)) {
6974
+ if (!isPlainObject4(parsed) || parsed.sv !== ENGINE_STATUS_SNAPSHOT_VERSION || !isPlainObject4(parsed.entries)) {
6594
6975
  return { kind: "refused", reason: "store-envelope-schema" };
6595
6976
  }
6596
6977
  const entries = sessionMap();
@@ -6609,7 +6990,7 @@ function loadForWrite(harnessDir) {
6609
6990
  }
6610
6991
  const bindings = bindingMap();
6611
6992
  if (parsed.bindings !== undefined) {
6612
- if (!isPlainObject6(parsed.bindings))
6993
+ if (!isPlainObject4(parsed.bindings))
6613
6994
  return { kind: "refused", reason: "store-bindings-schema" };
6614
6995
  for (const [key, value] of Object.entries(parsed.bindings)) {
6615
6996
  const binding = asBinding(value);
@@ -6664,12 +7045,12 @@ function writeEngineStatusSnapshot(harnessDir, input) {
6664
7045
  return { kind: "degraded", reason: "no-session-cwd" };
6665
7046
  if (!Number.isFinite(input.turn))
6666
7047
  return { kind: "degraded", reason: "invalid-turn" };
6667
- if (!isPlainObject6(input.payload))
7048
+ if (!isPlainObject4(input.payload))
6668
7049
  return { kind: "degraded", reason: "payload-not-object" };
6669
7050
  const at = (input.now ?? new Date).toISOString();
6670
7051
  if (!Number.isFinite(Date.parse(at)))
6671
7052
  return { kind: "degraded", reason: "invalid-timestamp" };
6672
- const dir = dirname9(engineStatusSnapshotPath(harnessDir));
7053
+ const dir = dirname10(engineStatusSnapshotPath(harnessDir));
6673
7054
  const file = engineStatusSnapshotPath(harnessDir);
6674
7055
  const tmp = `${file}.${process.pid}.${Math.random().toString(36).slice(2, 10)}.tmp`;
6675
7056
  try {
@@ -6732,7 +7113,7 @@ var bindingStoreMemos = new Map;
6732
7113
  function parseBindingStore(file) {
6733
7114
  let raw;
6734
7115
  try {
6735
- raw = readFileSync9(file, "utf8");
7116
+ raw = readFileSync7(file, "utf8");
6736
7117
  } catch {
6737
7118
  return { kind: "unavailable", reason: "store-unreadable" };
6738
7119
  }
@@ -6742,13 +7123,13 @@ function parseBindingStore(file) {
6742
7123
  } catch {
6743
7124
  return { kind: "unavailable", reason: "store-invalid-json" };
6744
7125
  }
6745
- if (!isPlainObject6(parsed) || parsed.sv !== ENGINE_STATUS_SNAPSHOT_VERSION || !isPlainObject6(parsed.entries)) {
7126
+ if (!isPlainObject4(parsed) || parsed.sv !== ENGINE_STATUS_SNAPSHOT_VERSION || !isPlainObject4(parsed.entries)) {
6746
7127
  return { kind: "unavailable", reason: "store-envelope-schema" };
6747
7128
  }
6748
7129
  const bindings = parsed.bindings;
6749
7130
  if (bindings === undefined)
6750
7131
  return { kind: "ok", bindings: undefined };
6751
- if (!isPlainObject6(bindings))
7132
+ if (!isPlainObject4(bindings))
6752
7133
  return { kind: "unavailable", reason: "store-bindings-schema" };
6753
7134
  return { kind: "ok", bindings };
6754
7135
  }
@@ -6806,7 +7187,7 @@ function updateWorkflowSessionBinding(harnessDir, sessionId, cwd, update) {
6806
7187
  return { kind: "degraded", reason: "invalid-selected-workflow-id" };
6807
7188
  }
6808
7189
  const file = engineStatusSnapshotPath(harnessDir);
6809
- const dir = dirname9(file);
7190
+ const dir = dirname10(file);
6810
7191
  const tmp = `${file}.${process.pid}.${Math.random().toString(36).slice(2, 10)}.tmp`;
6811
7192
  try {
6812
7193
  mkdirSync4(dir, { recursive: true });
@@ -6858,7 +7239,7 @@ function residualSeverityIndex(severity) {
6858
7239
  function pluginVersion() {
6859
7240
  for (const rel of ["../package.json", "../../package.json"]) {
6860
7241
  try {
6861
- const pkg = JSON.parse(readFileSync12(new URL(rel, import.meta.url), "utf8"));
7242
+ const pkg = JSON.parse(readFileSync10(new URL(rel, import.meta.url), "utf8"));
6862
7243
  if (typeof pkg.version === "string" && pkg.version !== "")
6863
7244
  return pkg.version;
6864
7245
  } catch {}
@@ -7024,8 +7405,8 @@ function hhmm(ts) {
7024
7405
  return `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
7025
7406
  }
7026
7407
  function harnessStateSource(harnessDir, selection) {
7027
- const statusPath = join18(harnessDir, STATUS_FILE);
7028
- if (!existsSync16(statusPath))
7408
+ const statusPath = join19(harnessDir, STATUS_FILE);
7409
+ if (!existsSync15(statusPath))
7029
7410
  return null;
7030
7411
  try {
7031
7412
  const rollup = residualRollup(harnessDir);
@@ -7034,9 +7415,9 @@ function harnessStateSource(harnessDir, selection) {
7034
7415
  if (selection.kind === "error") {
7035
7416
  return selectionErrorState(selection, rollup, harnessDir);
7036
7417
  }
7037
- const snapshotPath = join18(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
7418
+ const snapshotPath = join19(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
7038
7419
  let snapshot;
7039
- if (!existsSync16(snapshotPath)) {
7420
+ if (!existsSync15(snapshotPath)) {
7040
7421
  return selectionErrorState({
7041
7422
  kind: "error",
7042
7423
  code: "workflow.selection.snapshot-unreadable",
@@ -7044,7 +7425,7 @@ function harnessStateSource(harnessDir, selection) {
7044
7425
  }, rollup, harnessDir);
7045
7426
  }
7046
7427
  try {
7047
- snapshot = readWorkflowSnapshot(join18(harnessDir, selection.dir)).snapshot;
7428
+ snapshot = readWorkflowSnapshot(join19(harnessDir, selection.dir)).snapshot;
7048
7429
  } catch {
7049
7430
  return selectionErrorState({
7050
7431
  kind: "error",
@@ -7100,7 +7481,7 @@ function harnessStateSource(harnessDir, selection) {
7100
7481
  leases,
7101
7482
  knowledge: knowledgeDigest(harnessDir),
7102
7483
  direction: compass !== undefined ? compassDirection(compass.compassPath) : null,
7103
- agentFlow: readAgentFlow(join18(harnessDir, selection.dir), 50)
7484
+ agentFlow: readAgentFlow(join19(harnessDir, selection.dir), 50)
7104
7485
  };
7105
7486
  } catch {
7106
7487
  return null;
@@ -7130,21 +7511,21 @@ function selectionErrorState(selection, rollup, harnessDir) {
7130
7511
  function projectRollupSource(harnessDir, residuals) {
7131
7512
  const milestones = [];
7132
7513
  const projectsDir = resolveProjectDir(harnessDir, { harnessDir });
7133
- if (existsSync16(projectsDir)) {
7514
+ if (existsSync15(projectsDir)) {
7134
7515
  let entries;
7135
7516
  try {
7136
- entries = readdirSync4(projectsDir, { withFileTypes: true });
7517
+ entries = readdirSync5(projectsDir, { withFileTypes: true });
7137
7518
  } catch {
7138
7519
  entries = [];
7139
7520
  }
7140
7521
  for (const entry of entries) {
7141
7522
  if (!entry.isDirectory())
7142
7523
  continue;
7143
- const roadmapPath = join18(projectsDir, entry.name, PROJECT_ROADMAP_FILE);
7144
- if (!existsSync16(roadmapPath))
7524
+ const roadmapPath = join19(projectsDir, entry.name, PROJECT_ROADMAP_FILE);
7525
+ if (!existsSync15(roadmapPath))
7145
7526
  continue;
7146
7527
  try {
7147
- const doc = parseCompassFrontmatterText(readFileSync12(roadmapPath, "utf8"), roadmapPath);
7528
+ const doc = parseCompassFrontmatterText(readFileSync10(roadmapPath, "utf8"), roadmapPath);
7148
7529
  if (Array.isArray(doc.milestones)) {
7149
7530
  for (const milestone of doc.milestones) {
7150
7531
  if (typeof milestone === "string" && milestone.trim() !== "")
@@ -7206,11 +7587,11 @@ function residualRollup(harnessDir) {
7206
7587
  }
7207
7588
  function projectRegisters(harnessDir) {
7208
7589
  const projectsDir = resolveProjectDir(harnessDir, { harnessDir });
7209
- if (!existsSync16(projectsDir))
7590
+ if (!existsSync15(projectsDir))
7210
7591
  return [];
7211
7592
  let entries;
7212
7593
  try {
7213
- entries = readdirSync4(projectsDir, { withFileTypes: true });
7594
+ entries = readdirSync5(projectsDir, { withFileTypes: true });
7214
7595
  } catch {
7215
7596
  return [];
7216
7597
  }
@@ -7218,8 +7599,8 @@ function projectRegisters(harnessDir) {
7218
7599
  for (const entry of entries) {
7219
7600
  if (!entry.isDirectory())
7220
7601
  continue;
7221
- const registerPath = join18(projectsDir, entry.name, PROJECT_REGISTER_FILE);
7222
- if (!existsSync16(registerPath))
7602
+ const registerPath = join19(projectsDir, entry.name, PROJECT_REGISTER_FILE);
7603
+ if (!existsSync15(registerPath))
7223
7604
  continue;
7224
7605
  try {
7225
7606
  registers.push({ projectId: entry.name, doc: readJson(registerPath) });
@@ -7230,13 +7611,13 @@ function projectRegisters(harnessDir) {
7230
7611
  return registers;
7231
7612
  }
7232
7613
  function knowledgeDigest(harnessDir) {
7233
- const indexPath = join18(harnessDir, "knowledge", "README.md");
7234
- if (!existsSync16(indexPath))
7614
+ const indexPath = join19(harnessDir, "knowledge", "README.md");
7615
+ if (!existsSync15(indexPath))
7235
7616
  return null;
7236
7617
  try {
7237
7618
  const categories = new Set;
7238
7619
  let docCount = 0;
7239
- for (const line of readFileSync12(indexPath, "utf8").split(/\r?\n/)) {
7620
+ for (const line of readFileSync10(indexPath, "utf8").split(/\r?\n/)) {
7240
7621
  const row = line.trim().match(/^\|(.+)\|$/);
7241
7622
  if (row === null)
7242
7623
  continue;
@@ -7259,7 +7640,7 @@ function knowledgeDigest(harnessDir) {
7259
7640
  }
7260
7641
  function compassDirection(compassPath) {
7261
7642
  try {
7262
- const content = readFileSync12(compassPath, "utf8");
7643
+ const content = readFileSync10(compassPath, "utf8");
7263
7644
  const section = content.match(/^## Direction lock[^\n]*\n+([\s\S]*?)(?=\n## |$)/m);
7264
7645
  if (section === null)
7265
7646
  return null;
@@ -7276,20 +7657,20 @@ function compassDirection(compassPath) {
7276
7657
  }
7277
7658
  function selectedCompass(harnessDir, workflowId, snapshot) {
7278
7659
  const ref = snapshot.compass_ref;
7279
- if (typeof ref !== "string" || ref.trim() === "" || isAbsolute8(ref))
7660
+ if (typeof ref !== "string" || ref.trim() === "" || isAbsolute9(ref))
7280
7661
  return;
7281
- const compassPath = join18(harnessDir, ref);
7662
+ const compassPath = join19(harnessDir, ref);
7282
7663
  if (!pathInside(harnessDir, compassPath))
7283
7664
  return;
7284
- if (basename4(compassPath) !== "delivery-compass.md")
7665
+ if (basename6(compassPath) !== "delivery-compass.md")
7285
7666
  return;
7286
- if (!existsSync16(compassPath))
7667
+ if (!existsSync15(compassPath))
7287
7668
  return;
7288
7669
  let resolvedHarness;
7289
7670
  let resolvedCompass;
7290
7671
  try {
7291
- resolvedHarness = realpathSync7(harnessDir);
7292
- resolvedCompass = realpathSync7(compassPath);
7672
+ resolvedHarness = realpathSync6(harnessDir);
7673
+ resolvedCompass = realpathSync6(compassPath);
7293
7674
  } catch {
7294
7675
  return;
7295
7676
  }
@@ -7309,15 +7690,15 @@ function selectedCompass(harnessDir, workflowId, snapshot) {
7309
7690
  }
7310
7691
  function pathInside(root, candidate) {
7311
7692
  const rel = relative7(root, candidate);
7312
- return rel !== "" && rel !== ".." && !rel.startsWith(`..${sep3}`) && !isAbsolute8(rel);
7693
+ return rel !== "" && rel !== ".." && !rel.startsWith(`..${sep3}`) && !isAbsolute9(rel);
7313
7694
  }
7314
7695
  function iterationGateSource(harnessDir, selection) {
7315
7696
  if (harnessDir === null || selection === undefined || selection.kind === "error")
7316
7697
  return;
7317
- const statusPath = join18(harnessDir, STATUS_FILE);
7318
- if (!existsSync16(statusPath))
7698
+ const statusPath = join19(harnessDir, STATUS_FILE);
7699
+ if (!existsSync15(statusPath))
7319
7700
  return;
7320
- const snapshotPath = join18(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
7701
+ const snapshotPath = join19(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
7321
7702
  try {
7322
7703
  const snapshotDoc = readJson(snapshotPath);
7323
7704
  const compass = selectedCompass(harnessDir, selection.workflowId, snapshotDoc);
@@ -7407,7 +7788,7 @@ function persistEngineStatusSnapshot(ctx, harnessDir, cwd, turn, catalogPayload,
7407
7788
  }
7408
7789
 
7409
7790
  // src/engine-status-endpoint.ts
7410
- import { isAbsolute as isAbsolute10 } from "node:path";
7791
+ import { isAbsolute as isAbsolute11 } from "node:path";
7411
7792
 
7412
7793
  // ../../node_modules/.bun/@deepseek-ai+dsh-typert-protocol@0.1.5-rc.2+1e4e7adc57ac8890/node_modules/@deepseek-ai/dsh-typert-protocol/lib/index.js
7413
7794
  import { Service as Service2 } from "@deepseek-ai/cordis";
@@ -7463,7 +7844,7 @@ function liveSeqOf(value) {
7463
7844
  function isRefusedPath(cwd) {
7464
7845
  if (cwd.includes("\x00"))
7465
7846
  return true;
7466
- if (!isAbsolute10(cwd))
7847
+ if (!isAbsolute11(cwd))
7467
7848
  return true;
7468
7849
  return cwd.split(/[\\/]+/).includes("..");
7469
7850
  }
@@ -7699,12 +8080,12 @@ function installEngineStatusEndpoint(ctx, options) {
7699
8080
  }
7700
8081
 
7701
8082
  // src/gates/status.ts
7702
- import { existsSync as existsSync17, readdirSync as readdirSync7 } from "node:fs";
7703
- import { basename as basename6, join as join20, relative as relative9, resolve as resolve10 } from "node:path";
8083
+ import { existsSync as existsSync17, readdirSync as readdirSync8 } from "node:fs";
8084
+ import { basename as basename8, join as join21, relative as relative9, resolve as resolve12 } from "node:path";
7704
8085
  var LOGGER_NAME = "mstar/status-gate";
7705
8086
  function harnessDocKindOfTarget(harnessDir, targetPath) {
7706
- const resolved = resolve10(targetPath);
7707
- const name = basename6(resolved);
8087
+ const resolved = resolve12(targetPath);
8088
+ const name = basename8(resolved);
7708
8089
  if (name !== STATUS_FILE && name !== WORKFLOW_SNAPSHOT_FILE && name !== PROJECT_REGISTER_FILE)
7709
8090
  return null;
7710
8091
  const rel = relative9(harnessDir, resolved);
@@ -7716,8 +8097,8 @@ function harnessDocKindOfTarget(harnessDir, targetPath) {
7716
8097
  workflowDir = resolveWorkflowDir(harnessDir, { harnessDir });
7717
8098
  projectDir = resolveProjectDir(harnessDir, { harnessDir });
7718
8099
  } catch {
7719
- workflowDir = join20(harnessDir, "workflows");
7720
- projectDir = join20(harnessDir, "projects");
8100
+ workflowDir = join21(harnessDir, "workflows");
8101
+ projectDir = join21(harnessDir, "projects");
7721
8102
  }
7722
8103
  if (name === WORKFLOW_SNAPSHOT_FILE && /^[^/]+\/snapshot\.json$/.test(relative9(workflowDir, resolved)))
7723
8104
  return "snapshot";
@@ -7773,7 +8154,7 @@ function projectRegisterDocs(harnessDir) {
7773
8154
  const projectsDir = resolveProjectDir(harnessDir, { harnessDir });
7774
8155
  let entries;
7775
8156
  try {
7776
- entries = readdirSync7(projectsDir, { withFileTypes: true });
8157
+ entries = readdirSync8(projectsDir, { withFileTypes: true });
7777
8158
  } catch {
7778
8159
  return [];
7779
8160
  }
@@ -7781,7 +8162,7 @@ function projectRegisterDocs(harnessDir) {
7781
8162
  for (const entry of entries) {
7782
8163
  if (!entry.isDirectory())
7783
8164
  continue;
7784
- const registerPath = join20(projectsDir, entry.name, PROJECT_REGISTER_FILE);
8165
+ const registerPath = join21(projectsDir, entry.name, PROJECT_REGISTER_FILE);
7785
8166
  if (!existsSync17(registerPath))
7786
8167
  continue;
7787
8168
  try {
@@ -7855,8 +8236,8 @@ async function editIntentListener(ctx, resolver, config, adapter, target, actor,
7855
8236
  }
7856
8237
 
7857
8238
  // src/gates/skill-lint.ts
7858
- import { existsSync as existsSync18, readFileSync as readFileSync14 } from "node:fs";
7859
- import { basename as basename7, dirname as dirname11, resolve as resolve12, sep as sep5 } from "node:path";
8239
+ import { existsSync as existsSync18, readFileSync as readFileSync13 } from "node:fs";
8240
+ import { basename as basename9, dirname as dirname12, resolve as resolve14, sep as sep6 } from "node:path";
7860
8241
  var SKILL_LINT_LOGGER = "mstar/skill-lint";
7861
8242
 
7862
8243
  class SkillLintVetoError extends Error {
@@ -7897,7 +8278,7 @@ function lintSkillDoc(doc, options = {}) {
7897
8278
  return violations.length === 0 ? { ok: true, violations } : { ok: false, violations };
7898
8279
  }
7899
8280
  function lintSkillWrite(doc, options) {
7900
- const skillId = basename7(dirname11(resolve12(options.target)));
8281
+ const skillId = basename9(dirname12(resolve14(options.target)));
7901
8282
  const result = lintSkillDoc(doc, { skillId });
7902
8283
  if (options.hard && !result.ok) {
7903
8284
  throw new SkillLintVetoError(options.target, result.violations);
@@ -7910,13 +8291,13 @@ function skillRootsOf(config) {
7910
8291
  return roots.map((root) => root.trim()).filter((root) => root !== "");
7911
8292
  }
7912
8293
  function isSkillTarget(roots, target) {
7913
- if (basename7(target.displayPath) !== "SKILL.md")
8294
+ if (basename9(target.displayPath) !== "SKILL.md")
7914
8295
  return false;
7915
- const resolvedPath = resolve12(target.displayPath);
7916
- return roots.some((root) => resolvedPath.startsWith(resolve12(root) + sep5));
8296
+ const resolvedPath = resolve14(target.displayPath);
8297
+ return roots.some((root) => resolvedPath.startsWith(resolve14(root) + sep6));
7917
8298
  }
7918
8299
  function skillNameOf(target) {
7919
- return basename7(dirname11(target.displayPath));
8300
+ return basename9(dirname12(target.displayPath));
7920
8301
  }
7921
8302
  function skillCanonicalForm(target) {
7922
8303
  return resolveSkillRoot("dsh", { skill: skillNameOf(target), rel: "SKILL.md" });
@@ -7928,12 +8309,12 @@ function gateSkillIntent(ctx, harnessDir, config, target) {
7928
8309
  return;
7929
8310
  if (!isSkillTarget(roots, target))
7930
8311
  return;
7931
- const skillPath = resolve12(target.displayPath);
8312
+ const skillPath = resolve14(target.displayPath);
7932
8313
  if (!existsSync18(skillPath))
7933
8314
  return;
7934
8315
  let doc;
7935
8316
  try {
7936
- doc = readFileSync14(skillPath, "utf8");
8317
+ doc = readFileSync13(skillPath, "utf8");
7937
8318
  } catch (error) {
7938
8319
  ctx.logger(SKILL_LINT_LOGGER).error(`skill lint degraded to allow (cannot read ${skillPath}): ${error.message}`);
7939
8320
  ctx.emit("mstar/skill-lint", {
@@ -7946,7 +8327,7 @@ function gateSkillIntent(ctx, harnessDir, config, target) {
7946
8327
  });
7947
8328
  return;
7948
8329
  }
7949
- const result = lintSkillDoc(doc, { skillId: basename7(dirname11(skillPath)) });
8330
+ const result = lintSkillDoc(doc, { skillId: basename9(dirname12(skillPath)) });
7950
8331
  if (result.ok)
7951
8332
  return;
7952
8333
  const hard = resolveSeamHard(harnessDir, config);
@@ -7980,15 +8361,17 @@ async function skillWriteIntentListener(ctx, resolver, config, target, actor, ne
7980
8361
  }
7981
8362
 
7982
8363
  // src/gates/seams.ts
7983
- import { existsSync as existsSync19, readFileSync as readFileSync15, readdirSync as readdirSync10 } from "node:fs";
7984
- import { basename as basename9, dirname as dirname12, join as join21, resolve as resolve14, sep as sep7 } from "node:path";
8364
+ import { existsSync as existsSync19, readFileSync as readFileSync15, readdirSync as readdirSync11 } from "node:fs";
8365
+ import { basename as basename10, dirname as dirname13, join as join22, resolve as resolve16, sep as sep8 } from "node:path";
7985
8366
 
7986
8367
  // ../engine/dist/audit.js
7987
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
8368
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
8369
+ import { AsyncLocalStorage as AsyncLocalStorage22 } from "node:async_hooks";
7988
8370
  var DATE_PART2 = String.raw`\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])`;
7989
8371
  var RFC3339_Z_RE2 = new RegExp(String.raw`^${DATE_PART2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$`);
7990
8372
  var DATE_ONLY_RE2 = new RegExp(String.raw`^${DATE_PART2}$`);
7991
- var heldLockDirs2 = new AsyncLocalStorage2;
8373
+ var heldLockDirs2 = new AsyncLocalStorage3;
8374
+ var writeAuthorizations2 = new AsyncLocalStorage22;
7992
8375
  var MSTARC_HARNESS_DIR_KEY2 = "harness_dir";
7993
8376
  var MSTARC_PLAN_DIR_KEY2 = "plan_dir";
7994
8377
  var MSTARC_SDD_DIR_KEY2 = "sdd_dir";
@@ -8180,7 +8563,7 @@ var SEAM_LOGGERS = {
8180
8563
  roles: "mstar/roles-lint"
8181
8564
  };
8182
8565
  function isIndexFile(path) {
8183
- const base = basename9(path);
8566
+ const base = basename10(path);
8184
8567
  return base === "README.md" || base === "index.md";
8185
8568
  }
8186
8569
  function isMarkdownDoc(path) {
@@ -8189,7 +8572,7 @@ function isMarkdownDoc(path) {
8189
8572
  function isAuditPlanTarget(path) {
8190
8573
  if (!isMarkdownDoc(path))
8191
8574
  return false;
8192
- const segments = resolve14(path).split(sep7);
8575
+ const segments = resolve16(path).split(sep8);
8193
8576
  for (let i = 0;i < segments.length; i++) {
8194
8577
  if (segments[i] !== "plans")
8195
8578
  continue;
@@ -8200,7 +8583,7 @@ function isAuditPlanTarget(path) {
8200
8583
  return false;
8201
8584
  }
8202
8585
  function isRolesTarget(path) {
8203
- const segments = resolve14(path).split(sep7);
8586
+ const segments = resolve16(path).split(sep8);
8204
8587
  const idx = segments.indexOf("mstar-roles");
8205
8588
  if (idx === -1)
8206
8589
  return false;
@@ -8210,17 +8593,17 @@ function isRolesTarget(path) {
8210
8593
  return rest[0] === "SKILL.md" || rest[0] === "references" && rest[rest.length - 1].endsWith(".md");
8211
8594
  }
8212
8595
  function rolesDirOf(path) {
8213
- const segments = resolve14(path).split(sep7);
8596
+ const segments = resolve16(path).split(sep8);
8214
8597
  const idx = segments.indexOf("mstar-roles");
8215
8598
  if (idx === -1)
8216
- return dirname12(path);
8217
- return idx === 0 ? sep7 : join21(sep7, ...segments.slice(1, idx + 1));
8599
+ return dirname13(path);
8600
+ return idx === 0 ? sep8 : join22(sep8, ...segments.slice(1, idx + 1));
8218
8601
  }
8219
8602
  function isSeamTarget(seam, harnessDir, target) {
8220
- const path = resolve14(target.displayPath);
8603
+ const path = resolve16(target.displayPath);
8221
8604
  switch (seam) {
8222
8605
  case "design-md": {
8223
- const base = basename9(path);
8606
+ const base = basename10(path);
8224
8607
  return base === "DESIGN.md" || base === "DESIGN.dark.md";
8225
8608
  }
8226
8609
  case "audit":
@@ -8228,7 +8611,7 @@ function isSeamTarget(seam, harnessDir, target) {
8228
8611
  case "compound": {
8229
8612
  if (harnessDir === null)
8230
8613
  return false;
8231
- return path.startsWith(resolve14(join21(harnessDir, "knowledge")) + sep7) && isMarkdownDoc(path);
8614
+ return path.startsWith(resolve16(join22(harnessDir, "knowledge")) + sep8) && isMarkdownDoc(path);
8232
8615
  }
8233
8616
  case "roles":
8234
8617
  return isRolesTarget(path);
@@ -8245,8 +8628,8 @@ function auditSecretsViolations(findings, file) {
8245
8628
  }
8246
8629
  function validateDesignDoc(doc, path) {
8247
8630
  const violations = [...validateDesignTokenFrontmatter(doc).violations];
8248
- const isDark = basename9(path) === "DESIGN.dark.md";
8249
- const sibling = join21(dirname12(path), isDark ? "DESIGN.md" : "DESIGN.dark.md");
8631
+ const isDark = basename10(path) === "DESIGN.dark.md";
8632
+ const sibling = join22(dirname13(path), isDark ? "DESIGN.md" : "DESIGN.dark.md");
8250
8633
  if (existsSync19(sibling)) {
8251
8634
  const light = isDark ? readFileSync15(sibling, "utf8") : doc;
8252
8635
  const dark = isDark ? doc : readFileSync15(sibling, "utf8");
@@ -8263,17 +8646,17 @@ function validateAuditDoc(doc, path) {
8263
8646
  function validateCompoundDoc(doc, _path, harnessDir) {
8264
8647
  const violations = [...validateSchemaYaml(doc).violations];
8265
8648
  if (harnessDir !== null) {
8266
- violations.push(...referenceExists(dirname12(harnessDir), doc).violations);
8649
+ violations.push(...referenceExists(dirname13(harnessDir), doc).violations);
8267
8650
  }
8268
8651
  return violations.length === 0 ? { ok: true, violations } : { ok: false, violations };
8269
8652
  }
8270
- function validateRolesState(rolesDir, skillsRoot = dirname12(rolesDir)) {
8653
+ function validateRolesState(rolesDir, skillsRoot = dirname13(rolesDir)) {
8271
8654
  const violations = [...validateRoleMapping(rolesDir).violations];
8272
8655
  const skillTexts = {};
8273
- for (const entry of readdirSync10(skillsRoot, { withFileTypes: true })) {
8656
+ for (const entry of readdirSync11(skillsRoot, { withFileTypes: true })) {
8274
8657
  if (!entry.isDirectory() || !entry.name.startsWith("mstar-"))
8275
8658
  continue;
8276
- const skillFile = join21(skillsRoot, entry.name, "SKILL.md");
8659
+ const skillFile = join22(skillsRoot, entry.name, "SKILL.md");
8277
8660
  if (!existsSync19(skillFile))
8278
8661
  continue;
8279
8662
  try {
@@ -8307,7 +8690,7 @@ function gateSeamIntent(ctx, harnessDir, config, seam, target) {
8307
8690
  try {
8308
8691
  if (!isSeamTarget(seam, harnessDir, target))
8309
8692
  return;
8310
- const path = resolve14(target.displayPath);
8693
+ const path = resolve16(target.displayPath);
8311
8694
  if (!existsSync19(path))
8312
8695
  return;
8313
8696
  let doc;
@@ -8324,12 +8707,12 @@ function gateSeamIntent(ctx, harnessDir, config, seam, target) {
8324
8707
  const hard = resolveSeamHard(harnessDir, config);
8325
8708
  const verdict = applyEnforcement(result, { hard });
8326
8709
  if (verdict.hardBlocked) {
8327
- logger.error(`${basename9(path)} write to ${target.displayPath} ALLOWED as repair (Enforcement: hard; the current on-disk document is already invalid — the intent carries no incoming content, so the vetoable signal is only the pre-write state):
8710
+ logger.error(`${basename10(path)} write to ${target.displayPath} ALLOWED as repair (Enforcement: hard; the current on-disk document is already invalid — the intent carries no incoming content, so the vetoable signal is only the pre-write state):
8328
8711
  ${verdict.violations.map(formatViolation).join(`
8329
8712
  `)}`);
8330
8713
  emitSeamAdvisory(ctx, seam, target.displayPath, verdict, hard, { repair: true });
8331
8714
  } else {
8332
- logger.warn(`${basename9(path)} write to ${target.displayPath} (advisory):
8715
+ logger.warn(`${basename10(path)} write to ${target.displayPath} (advisory):
8333
8716
  ${verdict.violations.map(formatViolation).join(`
8334
8717
  `)}`);
8335
8718
  emitSeamAdvisory(ctx, seam, target.displayPath, verdict, hard);
@@ -8379,7 +8762,7 @@ function lintRolesWrite(doc, options) {
8379
8762
 
8380
8763
  // src/gates/tools.ts
8381
8764
  import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
8382
- import { join as join22, resolve as resolve16 } from "node:path";
8765
+ import { join as join23, resolve as resolve18 } from "node:path";
8383
8766
  import { defineTool } from "@deepseek-ai/dsh-tools";
8384
8767
  var ITERATION_VIOLATION_SCHEMA = {
8385
8768
  type: "object",
@@ -8599,8 +8982,8 @@ function registerSeamTools(ctx, resolver) {
8599
8982
  presentCall: (args) => ({ card: "generic", title: "Validate DESIGN.md", kind: "other", rawInput: args.dir }),
8600
8983
  isConcurrencySafe: () => false,
8601
8984
  async execute(args) {
8602
- const abs = resolve16(args.dir);
8603
- const lightPath = join22(abs, "DESIGN.md");
8985
+ const abs = resolve18(args.dir);
8986
+ const lightPath = join23(abs, "DESIGN.md");
8604
8987
  if (!existsSync20(lightPath))
8605
8988
  throw new Error(`design file not found: ${lightPath}`);
8606
8989
  const light = readFileSync16(lightPath, "utf8");
@@ -8653,7 +9036,7 @@ function registerSeamTools(ctx, resolver) {
8653
9036
  presentCall: (args) => ({ card: "generic", title: "Validate audit plan", kind: "other", rawInput: args.plan_path }),
8654
9037
  isConcurrencySafe: () => false,
8655
9038
  async execute(args) {
8656
- const abs = resolve16(args.plan_path);
9039
+ const abs = resolve18(args.plan_path);
8657
9040
  if (!existsSync20(abs))
8658
9041
  throw new Error(`plan file not found: ${abs}`);
8659
9042
  const text = readFileSync16(abs, "utf8");
@@ -8693,17 +9076,17 @@ function registerSeamTools(ctx, resolver) {
8693
9076
  presentCall: (args) => ({ card: "generic", title: "Validate knowledge doc", kind: "other", rawInput: args.doc_path }),
8694
9077
  isConcurrencySafe: () => false,
8695
9078
  async execute(args, exec) {
8696
- const abs = resolve16(args.doc_path);
9079
+ const abs = resolve18(args.doc_path);
8697
9080
  if (!existsSync20(abs))
8698
9081
  throw new Error(`knowledge doc not found: ${abs}`);
8699
9082
  const text = readFileSync16(abs, "utf8");
8700
9083
  const base = validateCompoundDoc(text, abs, args.repo_root !== undefined ? null : resolver.forAgent(exec.agent));
8701
9084
  const violations = [...base.violations];
8702
9085
  if (args.repo_root !== undefined) {
8703
- violations.push(...referenceExists(resolve16(args.repo_root), text).violations);
9086
+ violations.push(...referenceExists(resolve18(args.repo_root), text).violations);
8704
9087
  }
8705
9088
  if (args.knowledge_dir !== undefined) {
8706
- const knowledgeDir = resolve16(args.knowledge_dir);
9089
+ const knowledgeDir = resolve18(args.knowledge_dir);
8707
9090
  violations.push(...assertIndexRows(knowledgeDir).violations);
8708
9091
  violations.push(...scopeGuard(abs, [knowledgeDir]).violations);
8709
9092
  }
@@ -8738,10 +9121,10 @@ function registerSeamTools(ctx, resolver) {
8738
9121
  presentCall: (args) => ({ card: "generic", title: "Validate roles mapping", kind: "other", rawInput: args.roles_dir }),
8739
9122
  isConcurrencySafe: () => false,
8740
9123
  async execute(args) {
8741
- const rolesDir = resolve16(args.roles_dir);
8742
- if (!existsSync20(join22(rolesDir, "SKILL.md")))
9124
+ const rolesDir = resolve18(args.roles_dir);
9125
+ if (!existsSync20(join23(rolesDir, "SKILL.md")))
8743
9126
  throw new Error(`roles dir not found: ${rolesDir}`);
8744
- const result = validateRolesState(rolesDir, args.skills_root !== undefined ? resolve16(args.skills_root) : undefined);
9127
+ const result = validateRolesState(rolesDir, args.skills_root !== undefined ? resolve18(args.skills_root) : undefined);
8745
9128
  return { ok: result.ok, violations: result.violations.map(iterationViolationView) };
8746
9129
  }
8747
9130
  }));
@@ -8750,7 +9133,7 @@ function registerSeamTools(ctx, resolver) {
8750
9133
 
8751
9134
  // src/gates/adapter.ts
8752
9135
  import { existsSync as existsSync21 } from "node:fs";
8753
- import { join as join23 } from "node:path";
9136
+ import { join as join24 } from "node:path";
8754
9137
  import { Service as Service3 } from "@deepseek-ai/cordis";
8755
9138
  var HOST_LOGGER = "mstar/host-adapter";
8756
9139
  function mergeLeasesMatch(left, right) {
@@ -8865,7 +9248,7 @@ class DshHostAdapter extends Service3 {
8865
9248
  if (harnessDir !== null) {
8866
9249
  const selection = resolveActiveWorkflow(harnessDir);
8867
9250
  if (selection.kind === "active") {
8868
- const snapshotPath = join23(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
9251
+ const snapshotPath = join24(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
8869
9252
  try {
8870
9253
  const snapshot = readJson(snapshotPath);
8871
9254
  const stored = snapshot?.integration_merge_lease;
@@ -8891,8 +9274,8 @@ class DshHostAdapter extends Service3 {
8891
9274
  }
8892
9275
 
8893
9276
  // src/gates/agent-personas.ts
8894
- import { readFileSync as readFileSync17, readdirSync as readdirSync12, statSync as statSync8 } from "node:fs";
8895
- import { join as join24, resolve as resolve17, sep as sep8 } from "node:path";
9277
+ import { readFileSync as readFileSync17, readdirSync as readdirSync13, statSync as statSync8 } from "node:fs";
9278
+ import { join as join25, resolve as resolve19, sep as sep9 } from "node:path";
8896
9279
  var ROLE_ID_PATTERN = /^[a-z0-9-]{1,32}$/;
8897
9280
  var defaultCache = new Map;
8898
9281
  function personaFor(roleId, lookup, warn) {
@@ -8909,7 +9292,7 @@ function personaFor(roleId, lookup, warn) {
8909
9292
  function subagentRoleIds(agentsDir) {
8910
9293
  let names;
8911
9294
  try {
8912
- names = readdirSync12(agentsDir);
9295
+ names = readdirSync13(agentsDir);
8913
9296
  } catch {
8914
9297
  return [];
8915
9298
  }
@@ -8920,7 +9303,7 @@ function subagentRoleIds(agentsDir) {
8920
9303
  const roleId = name.slice(0, -3);
8921
9304
  let content;
8922
9305
  try {
8923
- content = readFileSync17(join24(agentsDir, name), "utf8");
9306
+ content = readFileSync17(join25(agentsDir, name), "utf8");
8924
9307
  } catch {
8925
9308
  continue;
8926
9309
  }
@@ -8933,9 +9316,9 @@ function subagentRoleIds(agentsDir) {
8933
9316
  function defaultFromMirror(agentsDir, roleId, warn) {
8934
9317
  if (!ROLE_ID_PATTERN.test(roleId))
8935
9318
  return;
8936
- const root = resolve17(agentsDir);
8937
- const file = resolve17(agentsDir, `${roleId}.md`);
8938
- if (!file.startsWith(root + sep8))
9319
+ const root = resolve19(agentsDir);
9320
+ const file = resolve19(agentsDir, `${roleId}.md`);
9321
+ if (!file.startsWith(root + sep9))
8939
9322
  return;
8940
9323
  let stat;
8941
9324
  try {
@@ -9182,7 +9565,7 @@ function log2(level, message) {
9182
9565
 
9183
9566
  // src/gates/workflow-ledger.ts
9184
9567
  import { readFileSync as readFileSync18, renameSync as renameSync4, writeFileSync as writeFileSync7 } from "node:fs";
9185
- import { join as join25 } from "node:path";
9568
+ import { join as join26 } from "node:path";
9186
9569
  var WORKFLOW_LEDGER_LOGGER = "mstar/workflow-ledger";
9187
9570
  var TOOL_WORKFLOW_RUN_START = "tool-workflow/run-start";
9188
9571
  var TOOL_WORKFLOW_AGENT_START = "tool-workflow/agent-start";
@@ -9242,7 +9625,7 @@ function loadWatermark(workflowDir, fresh = false) {
9242
9625
  return cached;
9243
9626
  const watermark = new Map;
9244
9627
  try {
9245
- const raw = readFileSync18(join25(workflowDir, WORKFLOW_LEDGER_WATERMARK_FILE), "utf8");
9628
+ const raw = readFileSync18(join26(workflowDir, WORKFLOW_LEDGER_WATERMARK_FILE), "utf8");
9246
9629
  const record = asRecord(JSON.parse(raw));
9247
9630
  const cursors = asRecord(record?.cursors);
9248
9631
  if (cursors !== undefined) {
@@ -9265,7 +9648,7 @@ function loadWatermark(workflowDir, fresh = false) {
9265
9648
  }
9266
9649
  function saveWatermark(workflowDir, watermark) {
9267
9650
  try {
9268
- const file = join25(workflowDir, WORKFLOW_LEDGER_WATERMARK_FILE);
9651
+ const file = join26(workflowDir, WORKFLOW_LEDGER_WATERMARK_FILE);
9269
9652
  const tmp = `${file}.tmp`;
9270
9653
  writeFileSync7(tmp, JSON.stringify({ v: 1, cursors: Object.fromEntries(watermark) }));
9271
9654
  renameSync4(tmp, file);
@@ -9584,8 +9967,8 @@ function registerWorkflowLedger(ctx, resolver, workflowAskCache) {
9584
9967
  }
9585
9968
 
9586
9969
  // src/gates/goal-bridge.ts
9587
- import { existsSync as existsSync22, readdirSync as readdirSync13 } from "node:fs";
9588
- import { join as join26 } from "node:path";
9970
+ import { existsSync as existsSync22, readdirSync as readdirSync14 } from "node:fs";
9971
+ import { join as join27 } from "node:path";
9589
9972
  var GOAL_BRIDGE_LOGGER = "mstar/goal-bridge";
9590
9973
  var GOAL_CHANGE_EVENT_TYPE = "goal/change";
9591
9974
  var GOAL_CHANGE_VERSION = 1;
@@ -9607,15 +9990,15 @@ function errorMessage4(error) {
9607
9990
  function projectRegisterPointer(harnessDir) {
9608
9991
  const projectsDir = resolveProjectDir(harnessDir, { harnessDir });
9609
9992
  try {
9610
- for (const entry of readdirSync13(projectsDir, { withFileTypes: true })) {
9993
+ for (const entry of readdirSync14(projectsDir, { withFileTypes: true })) {
9611
9994
  if (!entry.isDirectory())
9612
9995
  continue;
9613
- const registerPath = join26(projectsDir, entry.name, PROJECT_REGISTER_FILE);
9996
+ const registerPath = join27(projectsDir, entry.name, PROJECT_REGISTER_FILE);
9614
9997
  if (existsSync22(registerPath))
9615
9998
  return registerPath;
9616
9999
  }
9617
10000
  } catch {}
9618
- return join26(projectsDir, _DEFAULT_PROJECT, PROJECT_REGISTER_FILE);
10001
+ return join27(projectsDir, _DEFAULT_PROJECT, PROJECT_REGISTER_FILE);
9619
10002
  }
9620
10003
  function blockedAdvisoryOf(envelope) {
9621
10004
  const record = asRecord(envelope);
@@ -9667,7 +10050,7 @@ function registerGoalBridge(ctx, resolver) {
9667
10050
 
9668
10051
  // src/gates/plan-mode-bridge.ts
9669
10052
  import { existsSync as existsSync23 } from "node:fs";
9670
- import { isAbsolute as isAbsolute11, join as join27, relative as relative10, sep as sep9 } from "node:path";
10053
+ import { isAbsolute as isAbsolute12, join as join28, relative as relative10, sep as sep10 } from "node:path";
9671
10054
 
9672
10055
  // src/gates/steering.ts
9673
10056
  function isRootLikeAgent(agent) {
@@ -9711,7 +10094,7 @@ function errorMessage5(error) {
9711
10094
  return error instanceof Error ? error.message : String(error);
9712
10095
  }
9713
10096
  function selectedLifecycle(harnessDir, hint) {
9714
- if (!existsSync23(join27(harnessDir, STATUS_FILE)))
10097
+ if (!existsSync23(join28(harnessDir, STATUS_FILE)))
9715
10098
  return { kind: "none" };
9716
10099
  const selection = resolveReadWorkflow(harnessDir, hint);
9717
10100
  if (selection.kind === "error") {
@@ -9719,7 +10102,7 @@ function selectedLifecycle(harnessDir, hint) {
9719
10102
  }
9720
10103
  let doc;
9721
10104
  try {
9722
- doc = readJson(join27(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE));
10105
+ doc = readJson(join28(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE));
9723
10106
  } catch {
9724
10107
  return { kind: "none" };
9725
10108
  }
@@ -9729,11 +10112,11 @@ function selectedLifecycle(harnessDir, hint) {
9729
10112
  }
9730
10113
  function selectedCompassSteers(harnessDir, lifecycle) {
9731
10114
  const ref = lifecycle.doc.compass_ref;
9732
- if (typeof ref !== "string" || ref.trim() === "" || isAbsolute11(ref))
10115
+ if (typeof ref !== "string" || ref.trim() === "" || isAbsolute12(ref))
9733
10116
  return false;
9734
- const compassPath = join27(harnessDir, ref);
10117
+ const compassPath = join28(harnessDir, ref);
9735
10118
  const inside = relative10(harnessDir, compassPath);
9736
- if (inside === "" || inside === ".." || inside.startsWith(`..${sep9}`) || isAbsolute11(inside))
10119
+ if (inside === "" || inside === ".." || inside.startsWith(`..${sep10}`) || isAbsolute12(inside))
9737
10120
  return false;
9738
10121
  if (!existsSync23(compassPath))
9739
10122
  return false;
@@ -10301,10 +10684,10 @@ function registerMstarCommands(ctx) {
10301
10684
  if (dir === undefined)
10302
10685
  return;
10303
10686
  ctx.inject(["commands"], (commandsCtx) => {
10304
- for (const file of readdirSync14(dir).sort()) {
10687
+ for (const file of readdirSync15(dir).sort()) {
10305
10688
  if (!file.endsWith(".md"))
10306
10689
  continue;
10307
- const parsed = parseCommandMarkdown(readFileSync19(join28(dir, file), "utf8"));
10690
+ const parsed = parseCommandMarkdown(readFileSync19(join29(dir, file), "utf8"));
10308
10691
  if (parsed === undefined)
10309
10692
  continue;
10310
10693
  commandsCtx.commands.register({