mancode 0.5.4 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  assertActivationRollbackManifestTransition,
9
9
  assertClaimTransition,
10
10
  assertConfigPolicyConsistency,
11
+ assertExecutableImplementationScope,
11
12
  assertHandoffTransition,
12
13
  assertKnownKeys,
13
14
  assertOperationJournalTransition,
@@ -17,6 +18,7 @@ import {
17
18
  assertRecord,
18
19
  assertRepairUsesOriginalAuthorization,
19
20
  assertRequirementsLedgerTransition,
21
+ assertRequirementsScopeConsistent,
20
22
  assertReviewLedgerAgainstContext,
21
23
  assertReviewLedgerTransition,
22
24
  assertSafeSharedRelativePath,
@@ -49,6 +51,7 @@ import {
49
51
  formatTaskRef,
50
52
  gitRefWorkflowRepairJournalPath,
51
53
  handoffDirectory,
54
+ implementationScopeIsExecutable,
52
55
  isUlid,
53
56
  listGitRefWorkflowRepairJournalSummaries,
54
57
  listUnfinishedGitRefWorkflowRepairs,
@@ -111,7 +114,7 @@ import {
111
114
  workflowMetadataDigest,
112
115
  writeOperationReservation,
113
116
  writeProjectFacts
114
- } from "./chunk-VHZI2WKD.js";
117
+ } from "./chunk-M5CWWECP.js";
115
118
  import {
116
119
  DEFAULT_MANCODE_END_MARKER,
117
120
  DEFAULT_MANCODE_START_MARKER,
@@ -136,10 +139,12 @@ import {
136
139
  stageV3AdapterUpgradeFiles,
137
140
  v3AdapterTargetPath,
138
141
  v3AdapterVersionsFromStatuses
139
- } from "./chunk-PQDAFZYS.js";
142
+ } from "./chunk-AWOIP2LC.js";
140
143
 
141
144
  // src/cli.ts
142
- import { Option, program } from "commander";
145
+ import { realpathSync } from "fs";
146
+ import { fileURLToPath } from "url";
147
+ import { Command, Option } from "commander";
143
148
 
144
149
  // src/installers/adapter-upgrade.ts
145
150
  import {
@@ -1154,6 +1159,11 @@ var OPERATION_DEFINITIONS = {
1154
1159
  expectedRevisionPrefixes: ["claim:"],
1155
1160
  requiredLockPrefixes: ["claim:"]
1156
1161
  }),
1162
+ write(
1163
+ "mark-review-verification-stale",
1164
+ ["review:", "verification:", "task:"],
1165
+ ["task:"]
1166
+ ),
1157
1167
  write("update-metadata-scope", ["task:"], ["task:"]),
1158
1168
  write("activate-successor-claims", ["task:"], ["task:"], {
1159
1169
  expectedRevisionPrefixes: ["claim:"],
@@ -5694,11 +5704,13 @@ function parseRequirementsLedger2(raw, options = {}) {
5694
5704
  "requirements need at least one required acceptance criterion"
5695
5705
  );
5696
5706
  }
5707
+ const confirmedScope = normalizeStrings(value.confirmedScope);
5708
+ const excludedScope = normalizeStrings(value.excludedScope);
5697
5709
  return {
5698
5710
  version: 1,
5699
5711
  goal: value.goal.trim(),
5700
- confirmedScope: normalizeStrings(value.confirmedScope),
5701
- excludedScope: normalizeStrings(value.excludedScope),
5712
+ confirmedScope,
5713
+ excludedScope,
5702
5714
  technicalDecisions: normalizeStrings(value.technicalDecisions),
5703
5715
  defaults: normalizeStrings(value.defaults),
5704
5716
  blockingUnknowns: normalizeStrings(value.blockingUnknowns),
@@ -5706,6 +5718,12 @@ function parseRequirementsLedger2(raw, options = {}) {
5706
5718
  acceptanceCriteria
5707
5719
  };
5708
5720
  }
5721
+ function assertRequirementsScopeConsistent2(ledger) {
5722
+ const confirmed = new Set(ledger.confirmedScope);
5723
+ if (ledger.excludedScope.some((item) => confirmed.has(item))) {
5724
+ throw new Error("requirements scope cannot be both confirmed and excluded");
5725
+ }
5726
+ }
5709
5727
  function requirementsAreReady2(ledger) {
5710
5728
  return ledger.blockingUnknowns.length === 0;
5711
5729
  }
@@ -6535,6 +6553,20 @@ async function validateParentTask(projectRoot, mode, parentTaskId, requireStepSi
6535
6553
  }
6536
6554
  }
6537
6555
  async function validateWorkflowMeta(projectRoot, updated, existing, options) {
6556
+ validateImmutableWorkflowFields(updated, existing);
6557
+ validateWorkflowShapeAndSkipPolicy(updated);
6558
+ validateWorkflowLifecycle(updated, existing);
6559
+ validateWorkflowOutcome(updated);
6560
+ validateWorkflowPolicyVersions(updated);
6561
+ validateWorkflowPolicyState(updated);
6562
+ validatePlanDecisionTransition(updated, existing);
6563
+ await validatePlanningArtifactGate(projectRoot, updated);
6564
+ await validateVerificationGate(projectRoot, updated, existing, options);
6565
+ validatePlanVersionTransition(updated, existing);
6566
+ await validateWorkflowFamilyState(projectRoot, updated);
6567
+ await validateWorkflowCompletionGates(projectRoot, updated);
6568
+ }
6569
+ function validateImmutableWorkflowFields(updated, existing) {
6538
6570
  if (updated.mode !== existing.mode) {
6539
6571
  throw new Error("workflow mode cannot be changed");
6540
6572
  }
@@ -6558,6 +6590,8 @@ async function validateWorkflowMeta(projectRoot, updated, existing, options) {
6558
6590
  if (updated.verificationPolicyVersion !== existing.verificationPolicyVersion) {
6559
6591
  throw new Error("workflow verification policy version cannot be changed");
6560
6592
  }
6593
+ }
6594
+ function validateWorkflowShapeAndSkipPolicy(updated) {
6561
6595
  if (!Number.isInteger(updated.currentStep) || updated.currentStep < 1 || updated.currentStep > maxWorkflowStep(updated.mode)) {
6562
6596
  throw new Error(`invalid workflow step: ${updated.currentStep}`);
6563
6597
  }
@@ -6574,6 +6608,8 @@ async function validateWorkflowMeta(projectRoot, updated, existing, options) {
6574
6608
  "workflow policy v2 only allows skipping clarification or review"
6575
6609
  );
6576
6610
  }
6611
+ }
6612
+ function validateWorkflowLifecycle(updated, existing) {
6577
6613
  if (!canTransition(existing.status, updated.status)) {
6578
6614
  throw new Error(
6579
6615
  `invalid workflow status transition: ${existing.status} -> ${updated.status}`
@@ -6600,6 +6636,8 @@ async function validateWorkflowMeta(projectRoot, updated, existing, options) {
6600
6636
  } else if (updated.blockingReason !== void 0) {
6601
6637
  throw new Error("only blocked workflows can have a blocking reason");
6602
6638
  }
6639
+ }
6640
+ function validateWorkflowOutcome(updated) {
6603
6641
  if (updated.mode !== "mamba" && updated.outcome !== void 0) {
6604
6642
  throw new Error("only manba workflows can have an outcome");
6605
6643
  }
@@ -6612,6 +6650,8 @@ async function validateWorkflowMeta(projectRoot, updated, existing, options) {
6612
6650
  if (updated.mode === "mamba" && updated.status === "completed" && !updated.outcome) {
6613
6651
  throw new Error("completed manba workflows require an outcome");
6614
6652
  }
6653
+ }
6654
+ function validateWorkflowPolicyVersions(updated) {
6615
6655
  if (updated.mode === "mamba" && updated.planVersion !== void 0) {
6616
6656
  throw new Error("manba workflows cannot have a plan version");
6617
6657
  }
@@ -6635,6 +6675,8 @@ async function validateWorkflowMeta(projectRoot, updated, existing, options) {
6635
6675
  "manba workflows cannot have a verification policy version"
6636
6676
  );
6637
6677
  }
6678
+ }
6679
+ function validateWorkflowPolicyState(updated) {
6638
6680
  if (updated.verificationStatus !== void 0 && !isVerificationStatus(updated.verificationStatus)) {
6639
6681
  throw new Error("invalid workflow verification status");
6640
6682
  }
@@ -6659,12 +6701,16 @@ async function validateWorkflowMeta(projectRoot, updated, existing, options) {
6659
6701
  if (updated.mode === "mamba" && updated.planDecision !== void 0) {
6660
6702
  throw new Error("manba workflows cannot have a plan decision");
6661
6703
  }
6704
+ }
6705
+ function validatePlanDecisionTransition(updated, existing) {
6662
6706
  if (updated.planDecision !== existing.planDecision && existing.planDecision !== void 0) {
6663
6707
  throw new Error("workflow plan decision cannot be changed");
6664
6708
  }
6665
6709
  if (updated.planDecision !== existing.planDecision && existing.currentStep !== 4) {
6666
6710
  throw new Error("workflow plan decision can only be set at step 4");
6667
6711
  }
6712
+ }
6713
+ async function validatePlanningArtifactGate(projectRoot, updated) {
6668
6714
  if (updated.planningPolicyVersion === 1 || updated.planningPolicyVersion === 2) {
6669
6715
  if (updated.currentStep >= 3) {
6670
6716
  if (updated.requirementsStatus !== "ready") {
@@ -6701,6 +6747,8 @@ async function validateWorkflowMeta(projectRoot, updated, existing, options) {
6701
6747
  throw new Error("governed execution must be confirmed before step 5");
6702
6748
  }
6703
6749
  }
6750
+ }
6751
+ async function validateVerificationGate(projectRoot, updated, existing, options) {
6704
6752
  if (updated.verificationPolicyVersion === 1 && updated.currentStep >= 7 && updated.planDecision !== "solo_handoff" && !options.allowIncompleteVerification && !await verificationCanAdvance(
6705
6753
  projectRoot,
6706
6754
  updated.taskId,
@@ -6715,6 +6763,8 @@ async function validateWorkflowMeta(projectRoot, updated, existing, options) {
6715
6763
  "verification-blocked workflows must resume through verify"
6716
6764
  );
6717
6765
  }
6766
+ }
6767
+ function validatePlanVersionTransition(updated, existing) {
6718
6768
  if (updated.planVersion !== void 0 && (!Number.isInteger(updated.planVersion) || updated.planVersion < 1)) {
6719
6769
  throw new Error("workflow plan version must be a positive integer");
6720
6770
  }
@@ -6724,10 +6774,14 @@ async function validateWorkflowMeta(projectRoot, updated, existing, options) {
6724
6774
  if (updated.planVersion !== existing.planVersion && updated.currentStep !== 4) {
6725
6775
  throw new Error("workflow plan version can only change at step 4");
6726
6776
  }
6777
+ }
6778
+ async function validateWorkflowFamilyState(projectRoot, updated) {
6727
6779
  await validateParentTask(projectRoot, updated.mode, updated.parentTaskId);
6728
6780
  if ((isTerminalWorkflowStatus(updated.status) || updated.status === "planned") && (await listActiveMambaChildren(projectRoot, updated.taskId)).length > 0) {
6729
6781
  throw new Error("cannot finish workflow with an active manba child");
6730
6782
  }
6783
+ }
6784
+ async function validateWorkflowCompletionGates(projectRoot, updated) {
6731
6785
  if (updated.status === "completed" && updated.reviewPolicyVersion === 1 && updated.planDecision !== "solo_handoff" && !reviewWasExplicitlySkipped(updated) && !await reviewCanComplete(projectRoot, updated.taskId)) {
6732
6786
  throw new Error("workflow review is incomplete or still has open blockers");
6733
6787
  }
@@ -9622,7 +9676,7 @@ async function activateLegacyMigration(input) {
9622
9676
  if (session === null || session.status !== "active") {
9623
9677
  throw new Error("MANCODE_SESSION_NOT_FOUND");
9624
9678
  }
9625
- const store = new (await import("./store-EEWJJANB.js")).V3ContextStore(root);
9679
+ const store = new (await import("./store-Z53OE53A.js")).V3ContextStore(root);
9626
9680
  const project = await store.readProjectSnapshot();
9627
9681
  const stage = await readMigrationStage(root, input.stageId);
9628
9682
  if (stage.state !== "staged" || stage.revision !== input.expectedStageRevision) {
@@ -9885,7 +9939,7 @@ async function activateLegacyMigration(input) {
9885
9939
  for (const action of payload.actions.filter(
9886
9940
  (action2) => action2.kind === "v3_adapter_file"
9887
9941
  )) {
9888
- const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-NEN5F32W.js");
9942
+ const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-TCEFETAG.js");
9889
9943
  await applyV3AdapterFilePlan2(root, action);
9890
9944
  }
9891
9945
  journal = await completeActivationStep(
@@ -13741,7 +13795,7 @@ async function upgradeV3Adapters(input) {
13741
13795
  if (unfinished.length > 0) {
13742
13796
  throw new Error("MANCODE_ADAPTER_UPGRADE_OPERATION_PENDING");
13743
13797
  }
13744
- const actualVersions = await import("./v3-adapter-NEN5F32W.js").then(
13798
+ const actualVersions = await import("./v3-adapter-TCEFETAG.js").then(
13745
13799
  ({ inspectV3AdapterVersions: inspectV3AdapterVersions2 }) => inspectV3AdapterVersions2(
13746
13800
  root,
13747
13801
  managedAdapterNames(project.manifest.managedAdapters)
@@ -14332,7 +14386,7 @@ import path26 from "path";
14332
14386
  var SCOUT_AGENT = {
14333
14387
  name: "scout",
14334
14388
  description: "Investigates the codebase for mancode /man workflows. Finds similar implementations, reusable modules, files to change, and risks. Does not write code.",
14335
- tools: ["Read", "Grep", "Glob", "Bash"],
14389
+ tools: ["Read", "Grep", "Glob"],
14336
14390
  body: `\u4F60\u662F mancode \u6559\u7EC3\u7EC4\u7684 Scout\uFF08\u7403\u63A2\uFF09\u3002
14337
14391
 
14338
14392
  \u4F60\u7684\u804C\u8D23\uFF1A\u8C03\u7814\u4EE3\u7801\u5E93\uFF0C\u4E3A Head Coach \u51C6\u5907\u6218\u672F\u4FE1\u606F\u3002
@@ -14343,6 +14397,8 @@ var SCOUT_AGENT = {
14343
14397
  - \u53EA\u5217\u5BF9\u5B9E\u65BD\u6709\u7528\u7684\u4FE1\u606F
14344
14398
  - \u627E\u5230\u98CE\u9669\u70B9\u8981\u6807\u6CE8\uFF08\u26A0\uFE0F\uFF09
14345
14399
  - \u4E0D\u786E\u5B9A\u7684\u8981\u660E\u8BF4\uFF0C\u4E0D\u731C
14400
+ - \u4E3B\u52A8\u6838\u9A8C\u7528\u6237\u524D\u63D0\uFF0C\u5E76\u4ECE\u7AEF\u5230\u7AEF\u7528\u6237\u76EE\u6807\u3001\u5E38\u89C1\u9886\u57DF\u5931\u8D25\u8DEF\u5F84\u548C\u8FB9\u754C\u6761\u4EF6\u5BFB\u627E\u4F1A\u6539\u53D8\u65B9\u6848\u7684\u76F2\u70B9\uFF1B\u6700\u591A\u4FDD\u7559 3 \u4E2A\u6700\u9AD8\u5F71\u54CD\u9879\u3002\u4ED3\u5E93\u4E8B\u5B9E\u5FC5\u987B\u6709\u8BC1\u636E\uFF1B\u65E0\u6CD5\u5728\u4ED3\u5E93\u6838\u9A8C\u7684\u884C\u4E1A\u5224\u65AD\u5FC5\u987B\u6807\u4E3A domain_hypothesis\uFF0C\u53EA\u80FD\u5F62\u6210\u805A\u7126\u95EE\u9898\uFF0C\u4E0D\u80FD\u5199\u6210\u4E8B\u5B9E
14401
+ - \u53D1\u73B0\u53EA\u63D0\u4F9B\u8BC1\u636E\u548C\u5EFA\u8BAE\u6743\uFF0C\u4E0D\u4EA7\u751F\u4FEE\u6539\u6743\uFF1B\u4E0D\u628A\u5EFA\u8BAE\u5199\u6210\u5DF2\u786E\u8BA4\u8303\u56F4\u6216\u6280\u672F\u51B3\u7B56
14346
14402
  - \u5B58\u5728 \`.mancode/shared/context/glossary.json\` \u65F6\uFF0C\u62A5\u544A\u4F18\u5148\u4F7F\u7528\u5176\u4E2D\u672F\u8BED\uFF1B\u53D1\u73B0\u65B0\u7684\u9AD8\u9891\u9886\u57DF\u8BCD\u53EF\u5728\u62A5\u544A\u4E2D\u5217\u4E3A\u5EFA\u8BAE\u8BCD\u6761\uFF08\u4EC5\u5EFA\u8BAE\uFF0C\u4E0D\u5199\u5165\u672F\u8BED\u8868\uFF09
14347
14403
  - \u5F15\u7528\u6587\u4EF6\u7528 \`path:line\` \u683C\u5F0F\uFF0C\u8BA9 Head Coach \u4E00\u79D2\u8DF3\u8FC7\u53BB
14348
14404
 
@@ -14408,6 +14464,16 @@ var SCOUT_AGENT = {
14408
14464
  - Transport/platform: <\u5F71\u54CD\u6216 no change>
14409
14465
  - Migration/rollback: <\u9700\u8981\u7684\u8BC1\u636E\u6216 no change>
14410
14466
 
14467
+ ## Decision-impact Findings
14468
+ - Finding ID: F-1\uFF08\u540E\u7EED\u4F9D\u6B21 F-2\u3001F-3\uFF1B\u6700\u591A\u4E09\u9879\uFF09
14469
+ - Type: premise | scope | technical | risk | acceptance
14470
+ - Status: repository_fact | domain_hypothesis
14471
+ - Finding: <\u4E0E\u7528\u6237\u524D\u63D0\u51B2\u7A81\u7684\u4E8B\u5B9E\u3001\u5173\u952E\u76F2\u70B9\u6216\u53EF\u884C\u7684\u8303\u56F4\u5EFA\u8BAE\uFF1B\u6CA1\u6709\u5219\u5199 none>
14472
+ - Evidence/Basis: \`<repository test/file:line/caller-provided output\uFF0C\u6216\u660E\u786E\u6807\u6CE8\u7684\u9886\u57DF\u63A8\u7406\u4F9D\u636E>\`
14473
+ - Class: blocking | recommendable | defaultable
14474
+ - Impact: <\u4F1A\u6539\u53D8\u7684\u76EE\u6807\u3001\u8303\u56F4\u3001\u884C\u4E3A\u3001\u9A8C\u6536\u3001\u67B6\u6784\u3001\u6570\u636E\u3001\u517C\u5BB9\u6027\u3001\u5B89\u5168\u6216 owner>
14475
+ - Recommendation: <\u4E00\u4E2A\u6700\u5C0F\u3001\u76F4\u63A5\u7684\u5EFA\u8BAE\uFF1B\u4E0D\u66FF\u7528\u6237\u786E\u8BA4>
14476
+
14411
14477
  ## \u76F8\u4F3C\u5B9E\u73B0
14412
14478
  - \`<detected-source-root>/<relevant-file>:<line>\` \u2014 \u7B80\u8FF0\u53EF\u590D\u7528\u7684\u903B\u8F91
14413
14479
 
@@ -14443,8 +14509,8 @@ trigger: <\u88AB\u65B0\u8BC1\u636E\u63A8\u7FFB\u6216\u8D85\u51FA\u5F53\u524D req
14443
14509
 
14444
14510
  - \u7528 Grep / Glob \u627E\u4EE3\u7801\uFF0C\u4E0D\u8981 cat \u6574\u4E2A\u6587\u4EF6
14445
14511
  - \u7528 Read \u770B file:line \u9644\u8FD1\u7684\u4E0A\u4E0B\u6587
14446
- - \u7528 Bash \u8DD1 \`git log --oneline -5\` \u4E86\u89E3\u6700\u8FD1\u6539\u52A8
14447
- - **\u4E0D\u8981** Edit / Write \u2014 \u90A3\u662F Head Coach \u7684\u6D3B
14512
+ - \u53EA\u5F15\u7528\u5F53\u524D\u53EA\u8BFB\u5DE5\u5177\u80FD\u591F\u6838\u9A8C\u7684\u8BC1\u636E\uFF1B\u9700\u8981\u8FD0\u884C\u547D\u4EE4\u65F6\uFF0C\u628A\u547D\u4EE4\u5217\u4E3A\u4EA4\u7ED9\u8C03\u7528\u65B9\u7684\u9A8C\u8BC1\u5EFA\u8BAE\uFF0C\u4E0D\u81EA\u884C\u6267\u884C
14513
+ - **\u4E0D\u8981** Edit / Write / Bash \u2014 \u90A3\u662F\u6267\u884C\u9636\u6BB5\u7684\u6D3B
14448
14514
 
14449
14515
  \u6536\u5230\u4EFB\u52A1\u540E\u7ACB\u5373\u5F00\u59CB\u8C03\u7814\u3002\u62A5\u544A\u5B8C\u6574\u5373\u53EF\uFF0C\u4E0D\u9700\u8981\u7B49\u7528\u6237\u786E\u8BA4\u3002`
14450
14516
  };
@@ -14468,7 +14534,11 @@ var PLAN_COACH_AGENT = {
14468
14534
 
14469
14535
  ## \u8F93\u5165\u5C31\u7EEA\u68C0\u67E5
14470
14536
 
14471
- \u5148\u8BFB\u53D6 \`requirements.json\`\uFF0C\u4EE5\u5176\u4E2D\u7684 confirmedScope\u3001excludedScope\u3001technicalDecisions\u3001defaults\u3001blockingUnknowns\u3001coverage \u548C acceptanceCriteria \u4E3A\u6743\u5A01\u8F93\u5165\uFF1B\`requirements.md\` \u53EA\u7528\u4E8E\u9605\u8BFB\u3002\u9010\u9879\u68C0\u67E5 platform\u3001core_scope\u3001technical_stack\u3001data_and_persistence\u3001performance\u3001compatibility\u3001security \u7684\u72B6\u6001\u548C\u7406\u7531\u662F\u5426\u4E0E\u4E8B\u5B9E\u4E00\u81F4\u3002\u68C0\u67E5\u9700\u6C42\u662F\u5426\u8986\u76D6\u4EFB\u52A1\u5B9E\u9645\u9002\u7528\u7684\u7528\u6237\u76EE\u6807\u3001\u6838\u5FC3\u6D41\u7A0B\u3001\u9996\u671F\u8303\u56F4\u3001\u6392\u9664\u9879\u3001\u6280\u672F\u4E0E\u8FD0\u884C\u7EA6\u675F\u3001\u6570\u636E/\u72B6\u6001/\u96C6\u6210\u3001\u5173\u952E\u6027\u80FD/\u517C\u5BB9\u6027/\u5B89\u5168\u8981\u6C42\u548C\u9A8C\u6536\u6807\u51C6\u3002blockingUnknowns \u975E\u7A7A\u3001coverage \u7528\u65E0\u6839\u636E\u7684 not_applicable \u63A9\u76D6\u51B3\u7B56\u3001\u6838\u5FC3\u884C\u4E3A\u7F3A\u5C11\u9A8C\u6536 ID\uFF0C\u6216\u6587\u6863\u4E0E\u7ED3\u6784\u5316\u8F93\u5165\u77DB\u76FE\u65F6\u5FC5\u987B\u8FD4\u56DE NEEDS_CLARIFICATION\u3002
14537
+ \u5148\u8BFB\u53D6 \`requirements.json\`\u3002V3 \u4EE5 \`functionalScope.inScope\`\u3001\`functionalScope.outOfScope\`\u3001\`technicalDecisions\`\u3001\`defaults\`\u3001\`blockingUnknowns\`\u3001\`coverage\` \u548C \`acceptanceCriteria\` \u4E3A\u6743\u5A01\u8F93\u5165\uFF1Blegacy \u8F93\u5165\u4E2D\u7684\u8BED\u4E49\u5BF9\u5E94\u5B57\u6BB5\u662F \`confirmedScope\` \u4E0E \`excludedScope\`\uFF1B\`requirements.md\` \u53EA\u7528\u4E8E\u9605\u8BFB\u3002\u9010\u9879\u68C0\u67E5 platform\u3001core_scope\u3001technical_stack\u3001data_and_persistence\u3001performance\u3001compatibility\u3001security \u7684\u72B6\u6001\u548C\u7406\u7531\u662F\u5426\u4E0E\u4E8B\u5B9E\u4E00\u81F4\u3002\u68C0\u67E5\u9700\u6C42\u662F\u5426\u8986\u76D6\u4EFB\u52A1\u5B9E\u9645\u9002\u7528\u7684\u7528\u6237\u76EE\u6807\u3001\u6838\u5FC3\u6D41\u7A0B\u3001\u9996\u671F\u8303\u56F4\u3001\u6392\u9664\u9879\u3001\u6280\u672F\u4E0E\u8FD0\u884C\u7EA6\u675F\u3001\u6570\u636E/\u72B6\u6001/\u96C6\u6210\u3001\u5173\u952E\u6027\u80FD/\u517C\u5BB9\u6027/\u5B89\u5168\u8981\u6C42\u548C\u9A8C\u6536\u6807\u51C6\u3002blockingUnknowns \u975E\u7A7A\u3001coverage \u7528\u65E0\u6839\u636E\u7684 not_applicable \u63A9\u76D6\u51B3\u7B56\u3001\u6838\u5FC3\u884C\u4E3A\u7F3A\u5C11\u9A8C\u6536 ID\uFF0C\u6216\u6587\u6863\u4E0E\u7ED3\u6784\u5316\u8F93\u5165\u77DB\u76FE\u65F6\u5FC5\u987B\u8FD4\u56DE NEEDS_CLARIFICATION\u3002
14538
+
14539
+ \u9010\u9879\u6838\u5BF9 Scout \u7684 F-1\u2026F-3 \u662F\u5426\u5DF2\u6709\u6309\u7C7B\u578B\u5904\u7F6E\uFF1A\`repository_fact\` \u53EF\u4EE5\u7EA0\u6B63\u9519\u8BEF\u524D\u63D0\uFF1B\`domain_hypothesis\` \u5FC5\u987B\u5148\u8F6C\u6210\u805A\u7126\u95EE\u9898\uFF0C\u4E0D\u80FD\u5F53\u6210\u5DF2\u786E\u8BA4\u4E8B\u5B9E\u3002blocking \u5199\u5165 \`blockingUnknowns\`\uFF1B\u7528\u6237\u63A5\u53D7\u7684\u8303\u56F4\u6216\u884C\u4E3A finding \u5199\u5165 \`confirmedScope\`\uFF08V3 \u4E3A \`functionalScope.inScope\`\uFF09\u5E76\u8865\u4E0A\u5339\u914D\u7684\u9A8C\u6536 \`acceptanceCriteria\`\uFF1B\u7528\u6237\u63A5\u53D7\u7684\u6280\u672F\u9009\u62E9\u5199\u5165 \`technicalDecisions\`\uFF1B\u4F4E\u5F71\u54CD\u3001\u53EF\u9006\u7684\u5B9E\u73B0\u7EC6\u8282\u624D\u5199\u5165 \`defaults\`\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u6392\u9664\u7684\u884C\u4E3A\u5199\u5165 \`excludedScope\`\uFF08V3 \u4E3A \`functionalScope.outOfScope\`\uFF09\u3002\u672A\u63A5\u53D7\u7684\u5EFA\u8BAE\u4ECD\u7136\u6CA1\u6709\u6267\u884C\u6743\uFF0C\u4F46\u4E0D\u5F97\u81EA\u52A8\u585E\u5165 excludedScope\uFF0C\u66F4\u4E0D\u80FD\u590D\u5236\u8FDB\u6240\u6709\u5B57\u6BB5\u3002\u9519\u8BEF\u524D\u63D0\u6216\u98CE\u9669\u82E5\u4F1A\u6539\u53D8\u8BA1\u5212\uFF0C\u5FC5\u987B\u5148\u4F5C\u4E3A blocking \u6F84\u6E05\uFF0C\u518D\u6309\u6700\u7EC8\u8BED\u4E49\u843D\u5165\u4E0A\u8FF0\u552F\u4E00\u5408\u9002\u4F4D\u7F6E\u3002\u53D1\u73B0\u53EA\u4EA7\u751F\u5EFA\u8BAE\u6743\uFF0Cconfirmed requirements \u624D\u4EA7\u751F\u884C\u4E3A\u6388\u6743\u3002
14540
+
14541
+ \u8BA1\u5212\u8FD8\u5FC5\u987B\u8BFB\u53D6\u6216\u63D0\u51FA\u4E00\u4EFD\u7528\u6237\u53EF\u89C1\u7684 \`implementationScope\`\uFF08repo-relative \`include\`\u3001\`exclude\`\u3001\`modules\`\uFF09\uFF0C\u4F5C\u4E3A\u6587\u4EF6\u6539\u52A8\u4E0A\u9650\u3002\u5B83\u4E0D\u80FD\u7531 Scout \u5EFA\u8BAE\u81EA\u52A8\u751F\u6210\u6388\u6743\uFF0C\u4E5F\u4E0D\u80FD\u7528\u6A21\u5757\u6807\u7B7E\u4EE3\u66FF\u975E\u7A7A include\uFF1B\u5B83\u4E0E\u884C\u4E3A\u9700\u6C42\u5171\u540C\u7EA6\u675F\u6267\u884C\u3002
14472
14542
 
14473
14543
  \u540C\u65F6\u6267\u884C\u65B9\u6848\u5B8C\u6574\u6027\u68C0\u67E5\uFF1A
14474
14544
 
@@ -14476,6 +14546,7 @@ var PLAN_COACH_AGENT = {
14476
14546
  2. \u6BCF\u4E2A\u65B9\u6848\u5FC5\u987B\u8BF4\u660E\u590D\u6742\u5EA6\u7531\u8C01\u627F\u62C5\u4EE5\u53CA\u53EF\u89C2\u5BDF\u6210\u672C\uFF0C\u627F\u62C5\u8005\u53EF\u4EE5\u662F\u5B9E\u73B0\u4EE3\u7801\u3001\u8FC1\u79FB\u3001\u8FD0\u884C\u7EF4\u62A4\u3001\u7528\u6237\u64CD\u4F5C\u3001\u517C\u5BB9\u5C42\u6216\u6D4B\u8BD5\uFF1B\u4E0D\u80FD\u53EA\u5199\u201C\u66F4\u7B80\u5355\u201D\u3002
14477
14547
  3. \u5FC5\u987B\u7ED9\u51FA\u552F\u4E00 recommendation\uFF0C\u5E76\u8BF4\u660E\u62D2\u7EDD\u5176\u4ED6\u65B9\u5411\u7684\u4E3B\u8981\u7406\u7531\uFF1B\u4E0D\u80FD\u628A\u591A\u4E2A\u672A\u51B3\u65B9\u5411\u539F\u6837\u4EA4\u7ED9\u7528\u6237\u3002
14478
14548
  4. \u7B80\u5355\u4EFB\u52A1\u6CA1\u6709\u771F\u5B9E\u66FF\u4EE3\u65B9\u6848\u65F6\u53EA\u5217\u4E00\u4E2A\u660E\u663E\u53EF\u884C\u65B9\u5411\uFF0C\u5E76\u89E3\u91CA\u4E3A\u4EC0\u4E48\u4E0D\u5B58\u5728\u771F\u5B9E\u66FF\u4EE3\uFF1B\u4E0D\u5F97\u5236\u9020\u4F2A\u9009\u9879\u3002\u8FD9\u4E2A\u5355\u4E00\u65B9\u5411\u4ECD\u5FC5\u987B\u6210\u4E3A recommendation \u5E76\u6709 stop conditions\u3002
14549
+ 5. \u6BCF\u4E2A\u5B9E\u65BD\u6B65\u9AA4\u5FC5\u987B\u6620\u5C04\u5230\u5DF2\u786E\u8BA4\u8303\u56F4\u6216\u9A8C\u6536 ID\u3002\u4F18\u5148\u590D\u7528\u73B0\u6709\u5B9E\u73B0\u548C\u4F9D\u8D56\uFF0C\u9009\u62E9\u80FD\u6EE1\u8DB3\u9A8C\u6536\u7684\u6700\u5C0F\u76F4\u63A5\u65B9\u6848\uFF1B\u4E0D\u4E3A\u5355\u6B21\u7528\u9014\u589E\u52A0\u62BD\u8C61\u3001\u53EF\u914D\u7F6E\u6027\u3001\u76F8\u90BB\u6E05\u7406\u6216\u63A8\u6D4B\u6027\u9632\u5FA1\u3002
14479
14550
 
14480
14551
  Scout \u82E5\u7ED9\u51FA\u4E24\u4E2A\u540C\u7B49\u5019\u9009 semantic owner\u3001\u65E0\u6CD5\u786E\u5B9A authority/writer\uFF0C\u6216 evidence \u4E0E confirmed requirements \u51B2\u7A81\uFF0C\u4E0D\u80FD\u81EA\u884C\u9009\u4E00\u4E2A\u7EE7\u7EED\u3002
14481
14552
 
@@ -14509,6 +14580,10 @@ stop_conditions: <conditions that invalidate this plan>
14509
14580
  ## \u6A21\u5757\u7D22\u5F15
14510
14581
  ## \u6280\u672F\u4E0E\u4EA4\u4ED8\u7EA6\u675F\uFF08\u4EC5\u65B0\u9879\u76EE\u6216\u6280\u672F\u9009\u62E9\u672A\u5B9A\u65F6\uFF09
14511
14582
  - \u5DF2\u786E\u8BA4\u65B9\u6848\u3001\u9009\u62E9\u7406\u7531\u548C\u53D6\u820D\uFF1B\u5C1A\u672A\u786E\u8BA4\u4F1A\u6539\u53D8\u67B6\u6784\u7684\u6280\u672F\u9009\u62E9\u65F6\u8FD4\u56DE NEEDS_CLARIFICATION\uFF1B\u5DF2\u6709\u9879\u76EE\u5199\u201C\u6CBF\u7528\u68C0\u6D4B\u5230\u7684\u9879\u76EE\u7EA6\u5B9A\u201D
14583
+ ## \u6267\u884C\u8FB9\u754C\uFF08implementationScope\uFF09
14584
+ - include\uFF1A<\u5141\u8BB8\u4FEE\u6539\u7684 repo-relative \u8DEF\u5F84/glob>
14585
+ - exclude\uFF1A<\u5373\u4F7F\u5339\u914D include \u4E5F\u4E0D\u5F97\u4FEE\u6539\u7684\u8DEF\u5F84/glob>
14586
+ - modules\uFF1A<\u8BED\u4E49\u5F52\u5C5E\u6807\u7B7E\uFF1B\u4E0D\u5355\u72EC\u6388\u6743\u6587\u4EF6\u5199\u5165>
14512
14587
  ## \u6A21\u5757\uFF1A<\u540D\u79F0>
14513
14588
  ### \u6539\u52A8\u6587\u4EF6 / \u65B0\u5EFA\u6587\u4EF6
14514
14589
  ### \u590D\u7528\u8D44\u6E90\uFF08\u5F15\u7528 scout-report.md \u884C\u53F7\uFF09
@@ -14764,6 +14839,7 @@ var FILM_ANALYST_OFFENSE_AGENT = {
14764
14839
  - \u6700\u540E\u7ED9\u8BC4\u5206\uFF081-10\uFF09+ \u901A\u8FC7 / \u4E0D\u901A\u8FC7
14765
14840
  - \u53EA\u5BA1\u67E5\u672C\u6B21 diff\u3001\u7528\u6237\u9700\u6C42\u548C\u76F4\u63A5\u53D7\u5F71\u54CD\u8DEF\u5F84\uFF1B\u6700\u591A 3 \u4E2A\u65B0\u95EE\u9898
14766
14841
  - \u6BCF\u4E2A\u95EE\u9898\u5FC5\u987B\u5305\u542B\u6539\u52A8\u884C\u3001\u53EF\u6838\u67E5\u8BC1\u636E\u548C\u7528\u6237\u5F71\u54CD\u3002\u6CA1\u6709\u8BC1\u636E\u7684 checklist \u9879\u4E0D\u8F93\u51FA
14842
+ - \u5148\u505A\u6388\u6743\u4E00\u81F4\u6027\u5BA1\u67E5\uFF1AV3 \u5BF9\u7167 requirements \u7684 \`functionalScope.inScope\` / \`functionalScope.outOfScope\`\u3001\`technicalDecisions\`\u3001\`defaults\` \u548C \`acceptanceCriteria\`\uFF1Blegacy \u5BF9\u7167\u8BED\u4E49\u7B49\u4EF7\u7684 \`confirmedScope\` / \`excludedScope\`\u3002\u540C\u65F6\u8BFB\u53D6 Context Pack \u7684 \`activeTask.implementationScope\`\uFF0C\u9010\u4E2A\u68C0\u67E5\u5B9E\u9645\u6539\u52A8\u8DEF\u5F84\u662F\u5426\u843D\u5728 include \u4E14\u4E0D\u5339\u914D exclude\uFF1Bmodules \u53EA\u662F\u5F52\u5C5E\u6807\u7B7E\uFF0C\u4E0D\u5355\u72EC\u6388\u6743\u6587\u4EF6\u5199\u5165\u3002\u4EFB\u4F55\u672A\u7ECF\u6388\u6743\u3001\u89E6\u78B0\u884C\u4E3A\u6392\u9664\u9879\u3001\u8D85\u51FA\u6587\u4EF6\u8FB9\u754C\u6216\u65E0\u6CD5\u8FFD\u6EAF\u5230\u9A8C\u6536\u7684\u6539\u52A8\u4E00\u5F8B\u8BB0\u4E3A \u{1F534} scope blocker
14767
14843
 
14768
14844
  ## \u4F60\u4E0D\u5199\u4EE3\u7801
14769
14845
 
@@ -14773,6 +14849,7 @@ var FILM_ANALYST_OFFENSE_AGENT = {
14773
14849
 
14774
14850
  | \u7EF4\u5EA6 | \u68C0\u67E5\u4EC0\u4E48 |
14775
14851
  |---|---|
14852
+ | **\u6388\u6743\u4E00\u81F4\u6027** | \u6BCF\u4E00\u5904\u6539\u52A8\u80FD\u5426\u540C\u65F6\u8FFD\u6EAF\u5230\u5DF2\u786E\u8BA4\u884C\u4E3A/\u9A8C\u6536 ID\uFF0C\u5E76\u4F4D\u4E8E implementationScope \u6587\u4EF6\u8FB9\u754C\u5185\uFF1B\u662F\u5426\u5B9E\u73B0\u4E86\u88AB\u62D2\u7EDD\u3001\u5EF6\u671F\u6216\u672A\u8BA8\u8BBA\u7684\u5EFA\u8BAE |
14776
14853
  | **\u53EF\u8BFB\u6027** | \u547D\u540D\u6E05\u6670\u3001\u7ED3\u6784\u5408\u7406\u3001\u6CE8\u91CA\u6070\u5F53\uFF08\u53EA\u5728 WHY \u975E\u663E\u7136\u65F6\uFF09 |
14777
14854
  | **\u53EF\u7EF4\u62A4\u6027** | \u6A21\u5757\u8FB9\u754C\u3001\u8026\u5408\u5EA6\u3001\u6269\u5C55\u6027 |
14778
14855
  | **\u98CE\u683C\u4E00\u81F4\u6027** | \u662F\u5426\u5339\u914D\u9879\u76EE\u5DF2\u6709\u98CE\u683C\uFF08\u5373\u4F7F\u4F60\u4E0D\u8BA4\u540C\uFF09 |
@@ -15321,11 +15398,11 @@ trigger: <\u5177\u4F53\u4E8B\u5B9E>
15321
15398
  // src/templates/skills/principles.ts
15322
15399
  var CORE_CODING_PRINCIPLES = `## \u94C1\u5F8B\uFF08\u6C38\u4E0D\u8FDD\u53CD\uFF09
15323
15400
 
15324
- 1. **\u4E0D\u505A\u65E0\u5173\u4FEE\u6539** \u2014 \u53EA\u6539 plan \u8303\u56F4\u5185\u7684
15325
- 2. **\u5148\u9A8C\u8BC1\u518D\u58F0\u79F0\u5B8C\u6210** \u2014 build/lint/test \u5FC5\u987B\u5B9E\u9645\u8DD1
15401
+ 1. **\u4E0D\u505A\u65E0\u5173\u4FEE\u6539** \u2014 \u53EA\u6539\u7528\u6237\u5DF2\u786E\u8BA4\u7684 plan \u4E0E implementationScope\uFF1B\u6BCF\u4E00\u5904\u6539\u52A8\u90FD\u80FD\u8FFD\u6EAF\u5230\u8303\u56F4\u6216\u9A8C\u6536
15402
+ 2. **\u5148\u9A8C\u8BC1\u518D\u58F0\u79F0\u5B8C\u6210** \u2014 \u5F00\u5DE5\u524D\u5199\u660E\u5B9E\u8D28\u5047\u8BBE\u548C\u53EF\u9A8C\u8BC1\u6210\u529F\u6807\u51C6\uFF1Bbuild/lint/test \u5FC5\u987B\u5B9E\u9645\u8DD1
15326
15403
  3. **\u5931\u8D25\u4E24\u6B21\u5FC5\u987B\u505C\u4E0B** \u2014 \u4E0D\u76F2\u8BD5
15327
15404
  4. **\u4E0D\u53EF\u9006\u64CD\u4F5C\u5148\u95EE** \u2014 \u5220\u9664\u3001force push\u3001worktree \u5408\u5E76
15328
- 5. **\u53EA\u89E3\u51B3\u88AB\u95EE\u5230\u7684\u95EE\u9898** \u2014 \u4E0D\u52A0\u63A8\u6D4B\u6027\u529F\u80FD`;
15405
+ 5. **\u53EA\u89E3\u51B3\u88AB\u95EE\u5230\u7684\u95EE\u9898** \u2014 \u4F18\u5148\u590D\u7528\u73B0\u6709\u5B9E\u73B0\uFF0C\u9009\u62E9\u6EE1\u8DB3\u9A8C\u6536\u7684\u6700\u5C0F\u76F4\u63A5\u6539\u52A8\uFF1B\u4E0D\u52A0\u63A8\u6D4B\u6027\u529F\u80FD\u3001\u4E00\u6B21\u6027\u62BD\u8C61\u3001\u65E0\u5173\u6E05\u7406\u6216\u591A\u4F59\u914D\u7F6E`;
15329
15406
 
15330
15407
  // src/templates/skills/man.ts
15331
15408
  var MAN_SKILL = {
@@ -15345,7 +15422,7 @@ var MAN_SKILL = {
15345
15422
 
15346
15423
  ### Step 1: Scout \u8C03\u7814
15347
15424
 
15348
- \u5148\u8BFB \`.mancode/shared/context/glossary.json\`\uFF08\u82E5\u5B58\u5728\uFF09\uFF0C\u8C03\u7814\u3001\u62A5\u544A\u4E0E\u540E\u7EED\u6C9F\u901A\u4F18\u5148\u4F7F\u7528\u5176\u4E2D\u5DF2\u786E\u8BA4\u672F\u8BED\u3002\u8C03\u7528 \`scout\`\uFF0C\u5199 \`scout-report.md\`\u3002\u62A5\u544A\u5FC5\u987B\u5305\u542B\u201C**\u4E0D\u786E\u5B9A\u7684\u5730\u65B9**\u201D\uFF0C\u5E76\u6309\u53EF\u9A8C\u8BC1\u4E8B\u5B9E\u8865\u5145 Current Behavior Evidence\u3001Candidate Semantic Owner\u3001Source of Truth\u3001Historical / Compatibility Impact\uFF1B\u5B57\u6BB5\u4E0D\u76F8\u5173\u6216\u65E0\u6CD5\u9A8C\u8BC1\u65F6\u53EF\u4EE5\u7701\u7565\uFF0C\u4E0D\u80FD\u7F16\u9020\u3002Current Behavior Evidence \u81F3\u5C11\u6709\u4E00\u4E2A\u53EF\u590D\u73B0\u89C2\u5BDF\u548C\u4ED3\u5E93\u8DEF\u5F84\u3001\u6D4B\u8BD5\u6216\u547D\u4EE4\u8BC1\u636E\uFF1Bowner \u5199\u7F6E\u4FE1\u5EA6\u4E0E\u51B2\u7A81\uFF1Bsource of truth \u533A\u5206 authority \u548C derived copy\uFF1B\u517C\u5BB9\u5F71\u54CD\u8986\u76D6\u65E7 workflow\u3001legacy fixture\u3001transport\u3001\u8FC1\u79FB\u548C rollback\u3002\u8FD0\u884C \`mancode workflow update <taskId> --step 2\`\u3002
15425
+ \u5148\u8BFB \`.mancode/shared/context/glossary.json\`\uFF08\u82E5\u5B58\u5728\uFF09\uFF0C\u8C03\u7814\u3001\u62A5\u544A\u4E0E\u540E\u7EED\u6C9F\u901A\u4F18\u5148\u4F7F\u7528\u5176\u4E2D\u5DF2\u786E\u8BA4\u672F\u8BED\u3002\u8C03\u7528\u53EA\u8BFB \`scout\`\uFF0C\u5199 \`scout-report.md\`\u3002\u62A5\u544A\u5FC5\u987B\u5305\u542B\u201C**\u4E0D\u786E\u5B9A\u7684\u5730\u65B9**\u201D\u548C\u6700\u591A 3 \u4E2A\u4F1A\u6539\u53D8\u51B3\u7B56\u7684 Decision-impact Findings\uFF1B\u4F7F\u7528\u7A33\u5B9A ID F-1\u2026F-3\uFF0C\u6807\u6CE8 Type\uFF1Apremise / scope / technical / risk / acceptance\uFF0C\u5E76\u533A\u5206 repository_fact \u4E0E domain_hypothesis\u3002\u524D\u8005\u5FC5\u987B\u6709\u4ED3\u5E93\u8BC1\u636E\uFF1B\u540E\u8005\u53EA\u6839\u636E\u7AEF\u5230\u7AEF\u76EE\u6807\u548C\u5E38\u89C1\u9886\u57DF\u5931\u8D25/\u8FB9\u754C\u8DEF\u5F84\u63D0\u51FA\u805A\u7126\u95EE\u9898\uFF0C\u4E0D\u80FD\u5199\u6210\u4E8B\u5B9E\u3002\u6309\u53EF\u9A8C\u8BC1\u4E8B\u5B9E\u8865\u5145 Current Behavior Evidence\u3001Candidate Semantic Owner\u3001Source of Truth\u3001Historical / Compatibility Impact\uFF1B\u5B57\u6BB5\u4E0D\u76F8\u5173\u6216\u65E0\u6CD5\u9A8C\u8BC1\u65F6\u53EF\u4EE5\u7701\u7565\uFF0C\u4E0D\u80FD\u7F16\u9020\u3002Current Behavior Evidence \u81F3\u5C11\u6709\u4E00\u4E2A\u53EF\u590D\u73B0\u89C2\u5BDF\u548C\u4ED3\u5E93\u8DEF\u5F84\u3001\u6D4B\u8BD5\u6216\u8C03\u7528\u65B9\u63D0\u4F9B\u7684\u547D\u4EE4\u8BC1\u636E\uFF1Bowner \u5199\u7F6E\u4FE1\u5EA6\u4E0E\u51B2\u7A81\uFF1Bsource of truth \u533A\u5206 authority \u548C derived copy\uFF1B\u517C\u5BB9\u5F71\u54CD\u8986\u76D6\u65E7 workflow\u3001legacy fixture\u3001transport\u3001\u8FC1\u79FB\u548C rollback\u3002\u4E3B\u52A8\u6838\u9A8C\u7528\u6237\u524D\u63D0\u5E76\u6307\u51FA\u5173\u952E\u76F2\u70B9\uFF0C\u4F46\u53D1\u73B0\u53EA\u4EA7\u751F\u5EFA\u8BAE\u6743\uFF0C\u4E0D\u4EA7\u751F\u6267\u884C\u6743\u3002\u8FD0\u884C \`mancode workflow update <taskId> --step 2\`\u3002
15349
15426
 
15350
15427
  ### Step 2: \u9700\u6C42\u6F84\u6E05
15351
15428
 
@@ -15356,6 +15433,8 @@ var MAN_SKILL = {
15356
15433
  - **recommendable**\uFF1A\u6709\u5408\u9002\u65B9\u6848\u65F6\u76F4\u63A5\u7ED9 2\u20133 \u4E2A\u65B9\u6848\u3001\u4F18\u7F3A\u70B9\u548C\u660E\u786E\u63A8\u8350\uFF0C\u8BA9\u7528\u6237\u63A5\u53D7\u6216\u8C03\u6574\uFF1B\u4E0D\u8981\u53EA\u628A\u9009\u62E9\u9898\u629B\u7ED9\u7528\u6237\u3002
15357
15434
  - **defaultable**\uFF1A\u547D\u540D\u3001\u5FAE\u5C0F\u6837\u5F0F\u7B49\u4F4E\u5F71\u54CD\u7EC6\u8282\uFF0C\u53EF\u91C7\u7528\u9ED8\u8BA4\u503C\uFF0C\u4F46\u5199\u660E\u9ED8\u8BA4\u503C\u548C\u7406\u7531\u3002
15358
15435
 
15436
+ \u4E3A\u6BCF\u4E2A F-1\u2026F-3 \u660E\u786E\u4E14\u6309\u7C7B\u578B\u5904\u7F6E\uFF1Ablocking \u5199\u5165 \`blockingUnknowns\`\uFF1B\u7528\u6237\u63A5\u53D7\u7684\u8303\u56F4\u6216\u884C\u4E3A\u5199\u5165 \`confirmedScope\` \u5E76\u8865\u4E0A\u76F8\u5E94 \`acceptanceCriteria\`\uFF1B\u7528\u6237\u63A5\u53D7\u7684\u6280\u672F\u9009\u62E9\u5199\u5165 \`technicalDecisions\`\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u6392\u9664\u7684\u884C\u4E3A\u5199\u5165 \`excludedScope\`\uFF1B\`defaults\` \u53EA\u80FD\u63CF\u8FF0\u5DF2\u786E\u8BA4\u8303\u56F4\u5185\u4F4E\u5F71\u54CD\u3001\u53EF\u9006\u4E14\u7B26\u5408\u4ED3\u5E93\u7EA6\u5B9A\u7684\u5B9E\u73B0\u7EC6\u8282\uFF0C\u4E0D\u80FD\u6269\u5927\u8303\u56F4\u3002\u672A\u63A5\u53D7\u7684\u5EFA\u8BAE\u4ECD\u65E0\u6267\u884C\u6743\uFF0C\u4F46\u4E0D\u5F97\u81EA\u52A8\u585E\u5165 \`excludedScope\`\uFF0C\u4E5F\u4E0D\u5F97\u590D\u5236\u8FDB\u6240\u6709\u5B57\u6BB5\u3002
15437
+
15359
15438
  \u6309\u4EFB\u52A1\u5B9E\u9645\u9002\u7528\u8303\u56F4\u68C0\u67E5\uFF1A\u7528\u6237\u76EE\u6807\u4E0E\u5E73\u53F0\u3001\u6838\u5FC3\u6D41\u7A0B\u3001\u9996\u671F\u8303\u56F4\u3001\u6392\u9664\u9879\u3001\u6280\u672F\u4E0E\u8FD0\u884C\u7EA6\u675F\u3001\u6570\u636E/\u72B6\u6001/\u96C6\u6210\u3001\u6027\u80FD/\u517C\u5BB9\u6027/\u5B89\u5168\u3001\u53EF\u9A8C\u8BC1\u5B8C\u6210\u6807\u51C6\u3002\u8FDE\u7EED\u6F84\u6E05\u6CA1\u6709\u51CF\u5C11 blocking \u9879\u65F6\uFF0C\u4E0D\u6563\u95EE\uFF1B\u8BA9\u7528\u6237\u9009\u62E9\u7F29\u5C0F\u9996\u671F\u8303\u56F4\u3001\u63A5\u53D7\u5217\u660E\u7684\u63A8\u8350\u9ED8\u8BA4\u503C\u6216\u6682\u505C\u3002
15360
15439
 
15361
15440
  \u628A\u7ED3\u8BBA\u5199\u5165\u7ED3\u6784\u5316\u9700\u6C42\u8F93\u5165\uFF0C\u81F3\u5C11\u5305\u542B \`goal\`\u3001\u975E\u7A7A \`confirmedScope\`\u3001\`excludedScope\`\u3001\`technicalDecisions\`\u3001\`defaults\`\u3001\`blockingUnknowns\`\u3001\`coverage\` \u548C \`acceptanceCriteria\`\u3002coverage \u5FC5\u987B\u9010\u9879\u8BF4\u660E platform\u3001core_scope\u3001technical_stack\u3001data_and_persistence\u3001performance\u3001compatibility\u3001security \u662F \`confirmed\`\u3001\`defaulted\` \u6216\u5E26\u7406\u7531\u7684 \`not_applicable\`\uFF0C\u4E0D\u80FD\u7528\u7A7A\u6570\u7EC4\u5047\u88C5\u5DF2\u7ECF\u8003\u8651\u3002\u6BCF\u4E2A\u6838\u5FC3\u7528\u6237\u884C\u4E3A\u5FC5\u987B\u6709\u7A33\u5B9A\u9A8C\u6536 ID\uFF08\`AC-1\` \u7B49\uFF09\u3001\u63CF\u8FF0\u3001\`required\` \u548C\u9A8C\u8BC1\u65B9\u5F0F \`automated\` / \`manual\` / \`hybrid\`\uFF1B\u81F3\u5C11\u4E00\u4E2A\u9A8C\u6536\u9879\u5FC5\u9700\u3002\u8FD0\u884C \`mancode workflow requirements <taskId> finalize --file <requirements-input.json>\`\uFF0C\u7531 CLI \u6821\u9A8C\u5E76\u751F\u6210\u6743\u5A01 \`requirements.json\` \u4E0E \`requirements.md\`\uFF0C\u4E0D\u8981\u624B\u5DE5\u5236\u9020\u4E24\u4EFD\u53EF\u80FD\u51B2\u7A81\u7684\u7ED3\u8BBA\u3002\u65E0\u987B\u63D0\u95EE\u65F6\u53EF\u628A \`clarification\` \u8BB0\u5165\u7D2F\u8BA1 skippedSteps\uFF0C\u4F46\u4E0D\u80FD\u8DF3\u8FC7\u9700\u6C42\u6458\u8981\u4E0E\u5C31\u7EEA\u5224\u65AD\u3002\u4ECD\u6709 blocking \u9879\u65F6\u505C\u5728 Step 2\uFF1B\u53EA\u6709 CLI \u8FD4\u56DE ready \u624D\u8FD0\u884C \`mancode workflow update <taskId> --step 3\`\u3002
@@ -15366,7 +15445,7 @@ var MAN_SKILL = {
15366
15445
 
15367
15446
  Plan Coach \u5FC5\u987B\u8BC1\u660E\u6240\u6709\u9009\u9879\u89E3\u51B3\u540C\u4E00\u4E2A goal\u3001\u9A8C\u6536\u8FB9\u754C\u548C scope\uFF1B\u9010\u9879\u5199\u660E complexity bearer \u53CA\u53EF\u89C2\u5BDF\u6210\u672C\uFF1B\u7ED9\u51FA\u4E14\u53EA\u7ED9\u51FA\u4E00\u4E2A recommendation\u3001\u62D2\u7EDD\u5176\u4ED6\u65B9\u5411\u7684\u4E3B\u8981\u7406\u7531\u548C stop conditions\u3002\u7B80\u5355\u4EFB\u52A1\u6CA1\u6709\u771F\u5B9E\u66FF\u4EE3\u65F6\u53EA\u5217\u4E00\u4E2A\u65B9\u5411\u5E76\u8BF4\u660E\u539F\u56E0\uFF0C\u4E0D\u5236\u9020\u4F2A\u9009\u9879\u3002\u4E24\u4E2A\u540C\u7B49 owner \u5019\u9009\u6216 authority writer \u672A\u51B3\u65F6\u8FD4\u56DE \`NEEDS_CLARIFICATION\`\u3002
15368
15447
 
15369
- \u8BA1\u5212\u5FC5\u987B\u542B\u9700\u6C42\u6458\u8981\u3001\u4EFB\u52A1\u5206\u7EA7\u3001\u6280\u672F\u9009\u62E9\u53CA\u7406\u7531\u3001\u6A21\u5757\u7D22\u5F15\u3001\u590D\u7528\u8D44\u6E90\u4E0E scout \u884C\u53F7\u3001\u6838\u5FC3\u884C\u4E3A\u3001\u6700\u5C0F\u7B56\u7565\u3001\u4E0D\u505A\u4EC0\u4E48\u3001\u6B65\u9AA4\u3001\u98CE\u9669/\u56DE\u9000\u3001\u5B8C\u6210\u5B9A\u4E49\u3001\u771F\u5B9E\u9A8C\u8BC1\u4E0E smoke test\u3001\u9884\u4F30\u548C\u975E\u963B\u585E\u9ED8\u8BA4\u503C\u3002\u5165\u53E3/\u6D41\u7A0B\u8DE8\u5E73\u53F0\u4E0D\u4E00\u81F4\u3001owner/source of truth \u4E0D\u6E05\u3001\u72B6\u6001\u6216 contract \u8BED\u4E49\u53D8\u5316\u3001\u8DE8 workflow/child/team/transport\uFF0C\u6216\u8FC1\u79FB/\u517C\u5BB9\u5F71\u54CD\u8D85\u8FC7\u4E00\u4E2A\u7248\u672C\u65F6\uFF0C\u5728 \`plan.md\` \u5185\u52A0\u5165\u53EF\u9009 Domain Matrix\uFF0C\u5217\u51FA Domain\u3001\u5F53\u524D\u884C\u4E3A/\u8BC1\u636E\u3001\u5019\u9009 owner\u3001source of truth\u3001contract/state \u5F71\u54CD\u3001compatibility/history\u3001validation \u548C rollback/stop\uFF1B\u5B83\u4E0D\u662F\u65B0\u7684 authority\u3002\u9996\u6B21\u8BA1\u5212\u5199\u5165\u6210\u529F\u540E\u8FD0\u884C \`mancode workflow update <taskId> --step 4\`\uFF1B\u91CD\u5199\u8BA1\u5212\u65F6\u4FDD\u6301 Step 4\uFF0C\u8FD0\u884C \`--plan-version <\u5F53\u524D\u7248\u672C+1>\`\uFF0C\u4E0D\u5F97\u76F4\u63A5\u7F16\u8F91 planVersion\u3002
15448
+ \u8BA1\u5212\u5FC5\u987B\u542B\u9700\u6C42\u6458\u8981\u3001\u4EFB\u52A1\u5206\u7EA7\u3001\u6280\u672F\u9009\u62E9\u53CA\u7406\u7531\u3001\u6A21\u5757\u7D22\u5F15\u3001\u590D\u7528\u8D44\u6E90\u4E0E scout \u884C\u53F7\u3001\u6838\u5FC3\u884C\u4E3A\u3001\u6700\u5C0F\u7B56\u7565\u3001\u4E0D\u505A\u4EC0\u4E48\u3001\u6B65\u9AA4\u3001\u98CE\u9669/\u56DE\u9000\u3001\u5B8C\u6210\u5B9A\u4E49\u3001\u771F\u5B9E\u9A8C\u8BC1\u4E0E smoke test\u3001\u9884\u4F30\u548C\u975E\u963B\u585E\u9ED8\u8BA4\u503C\uFF0C\u8FD8\u8981\u6709\u7528\u6237\u53EF\u89C1\u7684 \`implementationScope\`\uFF1Arepo-relative \`include\`\u3001\`exclude\`\u3001\`modules\`\u3002include \u662F\u6587\u4EF6\u5199\u5165\u4E0A\u9650\u4E14\u5FC5\u987B\u975E\u7A7A\uFF0Cexclude \u4F18\u5148\uFF0Cmodules \u53EA\u63CF\u8FF0\u5F52\u5C5E\u3001\u4E0D\u5355\u72EC\u6388\u6743\u3002\u6BCF\u4E2A\u5B9E\u65BD\u6B65\u9AA4\u5FC5\u987B\u6620\u5C04\u5230\u5DF2\u786E\u8BA4\u8303\u56F4\u6216\u9A8C\u6536 ID\uFF1B\u4F18\u5148\u590D\u7528\u5DF2\u6709\u4EE3\u7801\u548C\u4F9D\u8D56\uFF0C\u9009\u62E9\u80FD\u6EE1\u8DB3\u9A8C\u6536\u7684\u6700\u5C0F\u3001\u76F4\u63A5\u3001\u53EF\u9A8C\u8BC1\u65B9\u6848\uFF0C\u4E0D\u4E3A\u5355\u6B21\u7528\u9014\u65B0\u589E\u62BD\u8C61\u3001\u53EF\u914D\u7F6E\u6027\u6216\u63A8\u6D4B\u6027\u9632\u5FA1\u3002\u5165\u53E3/\u6D41\u7A0B\u8DE8\u5E73\u53F0\u4E0D\u4E00\u81F4\u3001owner/source of truth \u4E0D\u6E05\u3001\u72B6\u6001\u6216 contract \u8BED\u4E49\u53D8\u5316\u3001\u8DE8 workflow/child/team/transport\uFF0C\u6216\u8FC1\u79FB/\u517C\u5BB9\u5F71\u54CD\u8D85\u8FC7\u4E00\u4E2A\u7248\u672C\u65F6\uFF0C\u5728 \`plan.md\` \u5185\u52A0\u5165\u53EF\u9009 Domain Matrix\uFF0C\u5217\u51FA Domain\u3001\u5F53\u524D\u884C\u4E3A/\u8BC1\u636E\u3001\u5019\u9009 owner\u3001source of truth\u3001contract/state \u5F71\u54CD\u3001compatibility/history\u3001validation \u548C rollback/stop\uFF1B\u5B83\u4E0D\u662F\u65B0\u7684 authority\u3002\u9996\u6B21\u8BA1\u5212\u4E0E\u8FB9\u754C\u901A\u8FC7 CLI \u4E00\u8D77\u5199\u5165\u540E\u8FD0\u884C \`mancode workflow update <taskId> --step 4\`\uFF1B\u517C\u5BB9\u65E7\u5165\u53E3\u91CD\u5199\u8BA1\u5212\u65F6\u4FDD\u6301 Step 4\uFF0C\u4F7F\u7528 \`--plan-version <\u5F53\u524D\u7248\u672C+1>\`\uFF0C\u5E76\u8BA9\u65E7\u5BA1\u67E5/\u9A8C\u8BC1\u5931\u6548\uFF0C\u4E0D\u5F97\u76F4\u63A5\u7F16\u8F91 planVersion\u3002
15370
15449
 
15371
15450
  ### Step 4: \u8BA1\u5212\u5173\u5361
15372
15451
 
@@ -15388,7 +15467,9 @@ Plan Coach \u5FC5\u987B\u8BC1\u660E\u6240\u6709\u9009\u9879\u89E3\u51B3\u540C\u4
15388
15467
 
15389
15468
  ### Step 5: \u5B9E\u65BD
15390
15469
 
15391
- \u8C03\u7528 \`head-coach\` \u6309\u786E\u8BA4\u8BA1\u5212\u5B9E\u65BD\u3002\u591A\u6587\u4EF6\u3001\u65B0\u6A21\u5757\u6216\u9AD8\u98CE\u9669\u4EFB\u52A1\u53EF\u5EFA\u8BAE worktree\uFF0C\u5FC5\u987B\u5148\u83B7\u7528\u6237\u540C\u610F\u3002\u5B9E\u65BD\u5B8C\u6210\u540E\u901A\u8FC7 CLI \u66F4\u65B0\u81F3 Step 6\u3002
15470
+ \u8C03\u7528 \`head-coach\` \u6309\u786E\u8BA4\u8BA1\u5212\u5B9E\u65BD\u3002\u5148\u660E\u786E\u4ECD\u5B58\u5728\u7684\u5B9E\u8D28\u5047\u8BBE\u548C\u53EF\u9A8C\u8BC1\u6210\u529F\u6807\u51C6\uFF1B\u6BCF\u4E00\u5904\u6539\u52A8\u90FD\u5FC5\u987B\u8FFD\u6EAF\u5230\u5DF2\u786E\u8BA4\u8303\u56F4\u3001\u6280\u672F\u51B3\u7B56\u6216\u9A8C\u6536 ID\u3002\u53EA\u6539\u4E3A\u6EE1\u8DB3\u8BA1\u5212\u6240\u5FC5\u9700\u7684\u6587\u4EF6\uFF0C\u4E0D\u987A\u624B\u91CD\u6784\u3001\u683C\u5F0F\u5316\u3001\u6E05\u7406\u76F8\u90BB\u4EE3\u7801\u6216\u589E\u52A0\u672A\u8BF7\u6C42\u529F\u80FD\u3002\u591A\u6587\u4EF6\u3001\u65B0\u6A21\u5757\u6216\u9AD8\u98CE\u9669\u4EFB\u52A1\u53EF\u5EFA\u8BAE worktree\uFF0C\u5FC5\u987B\u5148\u83B7\u7528\u6237\u540C\u610F\u3002\u5B9E\u65BD\u5B8C\u6210\u540E\u901A\u8FC7 CLI \u66F4\u65B0\u81F3 Step 6\u3002
15471
+
15472
+ \u82E5\u5347\u7EA7\u524D\u5DF2\u7ECF\u8FDB\u5165\u6267\u884C\u9636\u6BB5\u7684\u672C\u5730 Man \u4EFB\u52A1\u7F3A\u5C11\u53EF\u6267\u884C \`implementationScope\`\uFF0C\u5B8C\u6210\u95E8\u4ECD\u4F1A\u62D2\u7EDD\u3002\u5148\u5411\u7528\u6237\u5C55\u793A\u5B8C\u6574\u8FB9\u754C\u5E76\u7B49\u5F85\u660E\u786E\u786E\u8BA4\uFF0C\u518D\u4F7F\u7528\u5185\u5BB9\u5B8C\u5168\u4E0D\u53D8\u7684\u5F53\u524D plan \u548C \`--scope-file\` \u91CD\u65B0\u6267\u884C plan revise\u3002\u8FD9\u4E2A\u517C\u5BB9\u8865\u7ED1\u53EA\u5141\u8BB8\u9012\u589E plan authority \u5E76\u4F7F\u65E7 review/verification \u5931\u6548\uFF1B\u4E0D\u5F97\u4FEE\u6539 plan\u3001\u884C\u4E3A\u3001\u9A8C\u6536\u6216\u5DF2\u7ECF\u53EF\u6267\u884C\u7684\u8FB9\u754C\u3002
15392
15473
 
15393
15474
  ### Step 6: \u81EA\u6D4B\u3001\u8BCA\u65AD\u4E0E\u56DE\u5F52
15394
15475
 
@@ -15400,7 +15481,7 @@ Plan Coach \u5FC5\u987B\u8BC1\u660E\u6240\u6709\u9009\u9879\u89E3\u51B3\u540C\u4
15400
15481
 
15401
15482
  ### Step 7: Film #1 \u4EE3\u7801\u8D28\u91CF\u5BA1\u67E5\u4E0E\u4FEE\u590D
15402
15483
 
15403
- \u672A\u8DF3\u8FC7 review \u65F6\u8C03\u7528 \`film-analyst-offense\`\uFF0C\u53EA\u5BA1\u67E5\u672C\u6B21 diff \u7684\u884C\u4E3A\u6B63\u786E\u6027\u3001\u590D\u7528\u3001\u590D\u6742\u5EA6\u548C\u6D4B\u8BD5\uFF0C\u5199 \`film-report-1.md\`\u3002\u6BCF\u6761 finding \u5FC5\u987B\u5F15\u7528\u6539\u52A8\u884C\u3001\u7ED9\u51FA\u8BC1\u636E\u548C\u7528\u6237\u5F71\u54CD\uFF1B\u6700\u591A 3 \u4E2A\u65B0 finding\u3002\u7528\u7A33\u5B9A ID\uFF08\u5982 Q1\uFF09\u6807\u8BB0 \u{1F534} blocker\uFF0C\u5E76\u8FD0\u884C \`mancode workflow review <taskId> complete --review-domain quality --report film-report-1.md --blockers Q1,Q2\`\uFF1B\u6CA1\u6709 blocker \u65F6\u4F20\u7A7A\u5B57\u7B26\u4E32\u3002\u6B64\u65F6\u4E0D\u4FEE\u590D\uFF0C\u5148\u5B8C\u6210\u6240\u9700\u5BA1\u67E5\u9886\u57DF\uFF0C\u518D\u66F4\u65B0\u81F3 Step 8\u3002
15484
+ \u672A\u8DF3\u8FC7 review \u65F6\u8C03\u7528 \`film-analyst-offense\`\uFF0C\u5148\u628A\u5B9E\u9645 diff \u5BF9\u7167 \`confirmedScope\`\u3001\`excludedScope\`\u3001\`technicalDecisions\`\u3001\`acceptanceCriteria\` \u548C \`implementationScope\` \u505A\u6388\u6743\u4E00\u81F4\u6027\u5BA1\u67E5\uFF0C\u518D\u68C0\u67E5\u884C\u4E3A\u6B63\u786E\u6027\u3001\u590D\u7528\u3001\u590D\u6742\u5EA6\u548C\u6D4B\u8BD5\uFF0C\u5199 \`film-report-1.md\`\u3002\u5B9E\u73B0\u88AB\u62D2\u7EDD\u3001\u5EF6\u671F\u3001\u672A\u8BA8\u8BBA\u3001\u65E0\u6CD5\u8FFD\u6EAF\u5230\u5DF2\u786E\u8BA4\u884C\u4E3A\uFF0C\u6216\u6539\u52A8\u8DEF\u5F84\u843D\u5728 include \u5916 / \u5339\u914D exclude \u7684\u5185\u5BB9\u4E00\u5F8B\u4F5C\u4E3A \u{1F534} scope blocker\u3002\u6BCF\u6761 finding \u5FC5\u987B\u5F15\u7528\u6539\u52A8\u884C\u3001\u7ED9\u51FA\u8BC1\u636E\u548C\u7528\u6237\u5F71\u54CD\uFF1B\u6700\u591A 3 \u4E2A\u65B0 finding\u3002\u7528\u7A33\u5B9A ID\uFF08\u5982 Q1\uFF09\u6807\u8BB0 \u{1F534} blocker\uFF0C\u5E76\u8FD0\u884C \`mancode workflow review <taskId> complete --review-domain quality --report film-report-1.md --blockers Q1,Q2\`\uFF1B\u6CA1\u6709 blocker \u65F6\u4F20\u7A7A\u5B57\u7B26\u4E32\u3002\u6B64\u65F6\u4E0D\u4FEE\u590D\uFF0C\u5148\u5B8C\u6210\u6240\u9700\u5BA1\u67E5\u9886\u57DF\uFF0C\u518D\u66F4\u65B0\u81F3 Step 8\u3002
15404
15485
 
15405
15486
  ### Step 8: Film #2 \u5B89\u5168\u4E0E\u8FB9\u754C\u5BA1\u67E5
15406
15487
 
@@ -15734,16 +15815,18 @@ var MANTEAM_SKILL = {
15734
15815
 
15735
15816
  \u6309 \`/man\` \u7684 9 \u6B65\u6D41\u7A0B\u6267\u884C\uFF08\u542B\u6F84\u6E05\u3001\u8BA1\u5212\u5173\u5361\u548C\u589E\u5F3A\u6536\u5C3E\uFF09\uFF0C\u4F46\u6BCF\u4E00\u6B65\u589E\u52A0\u56E2\u961F\u7EA6\u675F\uFF1A
15736
15817
 
15737
- 1. Scout Report\uFF1A\u5FC5\u987B\u5217\u51FA\u5171\u4EAB\u6587\u4EF6\u3001\u8FD1\u671F\u76F8\u5173\u63D0\u4EA4\u3001\u6F5C\u5728\u51B2\u7A81\u6587\u4EF6\uFF0C\u5E76\u6309\u4E8B\u5B9E\u8865\u5145 Current Behavior Evidence\u3001Candidate Semantic Owner\u3001Source of Truth\u3001Historical / Compatibility Impact\uFF1Bauthority \u4E0E Markdown/adapter \u7B49 derived copy \u5FC5\u987B\u533A\u5206\u3002
15738
- 2. \u6F84\u6E05\uFF1A\u6CBF\u7528 /man \u7684\u9700\u6C42\u5C31\u7EEA\u95E8\u69DB\uFF0C\u4E0D\u8BBE\u56FA\u5B9A\u8F6E\u6570\u6216\u6BCF\u6279\u95EE\u9898\u6570\u91CF\uFF1B\u95EE\u51FA\u6240\u6709\u4F1A\u6539\u53D8\u51B3\u7B56\u4E14\u65E0\u6CD5\u4ECE\u9879\u76EE\u4E8B\u5B9E\u67E5\u6E05\u7684\u7591\u95EE\uFF0C\u4E0D\u91CD\u590D\u5DF2\u786E\u8BA4\u5185\u5BB9\u3002\u6709\u5408\u9002\u65B9\u6848\u65F6\u76F4\u63A5\u7ED9\u51FA\u9009\u9879\u3001\u4F18\u7F3A\u70B9\u548C\u660E\u786E\u63A8\u8350\u3002\u901A\u8FC7 \`workflow requirements ... finalize\` \u56FA\u5316\u4E03\u4E2A coverage \u7EF4\u5EA6\u3001\u7ED3\u6784\u5316\u9700\u6C42\u548C\u5E26\u9A8C\u8BC1\u65B9\u5F0F\u7684\u9A8C\u6536 ID\uFF0C\u53EA\u6709 CLI \u5224\u5B9A ready \u624D\u8FDB\u5165\u8BA1\u5212\u3002
15739
- 3. Game Plan\uFF1APlan Coach \u5148\u505A\u8F93\u5165\u5C31\u7EEA\u68C0\u67E5\uFF1B\u6240\u6709\u9009\u9879\u5FC5\u987B\u89E3\u51B3\u540C\u4E00\u76EE\u6807\u548C\u9A8C\u6536\u8FB9\u754C\uFF0C\u5199\u660E complexity bearer\uFF0C\u53EA\u4FDD\u7559\u4E00\u4E2A recommendation \u548C stop conditions\uFF1B\u7B80\u5355\u4EFB\u52A1\u53EF\u4EE5\u53EA\u6709\u4E00\u4E2A\u771F\u5B9E\u65B9\u5411\u3002\u8BA1\u5212\u91CC\u5FC5\u987B\u5305\u542B\u53D8\u66F4\u8FB9\u754C\u3001\u6280\u672F\u9009\u62E9\u7406\u7531\u3001\u517C\u5BB9\u6027\u98CE\u9669\u3001\u56DE\u6EDA\u65B9\u5F0F\uFF1B\u9AD8\u98CE\u9669\u6216\u8DE8 team/transport/owner/authority \u7684\u4EFB\u52A1\u5728 plan.md \u5185\u52A0\u5165\u975E\u6743\u5A01 Domain Matrix\u3002\u7981\u6B62\u63D0\u524D\u4FEE\u6539\u4E1A\u52A1\u6587\u4EF6\u6216\u56E2\u961F memory\u3002
15818
+ 1. Scout Report\uFF1A\u5FC5\u987B\u5217\u51FA\u5171\u4EAB\u6587\u4EF6\u3001\u8FD1\u671F\u76F8\u5173\u63D0\u4EA4\u3001\u6F5C\u5728\u51B2\u7A81\u6587\u4EF6\uFF0C\u5E76\u6309\u4E8B\u5B9E\u8865\u5145 Current Behavior Evidence\u3001Candidate Semantic Owner\u3001Source of Truth\u3001Historical / Compatibility Impact\uFF1Bauthority \u4E0E Markdown/adapter \u7B49 derived copy \u5FC5\u987B\u533A\u5206\u3002\u6700\u591A\u4FDD\u7559\u4E09\u4E2A\u4F1A\u6539\u53D8\u51B3\u7B56\u7684 finding\uFF0C\u4F7F\u7528\u7A33\u5B9A ID F-1\u2026F-3 \u548C Type\uFF1Apremise / scope / technical / risk / acceptance\u3002
15819
+ 2. \u6F84\u6E05\uFF1A\u6CBF\u7528 /man \u7684\u9700\u6C42\u5C31\u7EEA\u95E8\u69DB\uFF0C\u4E0D\u8BBE\u56FA\u5B9A\u8F6E\u6570\u6216\u6BCF\u6279\u95EE\u9898\u6570\u91CF\uFF1B\u95EE\u51FA\u6240\u6709\u4F1A\u6539\u53D8\u51B3\u7B56\u4E14\u65E0\u6CD5\u4ECE\u9879\u76EE\u4E8B\u5B9E\u67E5\u6E05\u7684\u7591\u95EE\uFF0C\u4E0D\u91CD\u590D\u5DF2\u786E\u8BA4\u5185\u5BB9\u3002\u6709\u5408\u9002\u65B9\u6848\u65F6\u76F4\u63A5\u7ED9\u51FA\u9009\u9879\u3001\u4F18\u7F3A\u70B9\u548C\u660E\u786E\u63A8\u8350\u3002\u53D1\u73B0\u53EA\u4EA7\u751F\u5EFA\u8BAE\u6743\uFF0C\u4E0D\u4EA7\u751F\u6267\u884C\u6743\uFF1A\u63A5\u53D7\u7684\u8303\u56F4\u6216\u884C\u4E3A\u8FDB\u5165 confirmedScope \u548C\u5339\u914D\u7684 acceptanceCriteria\uFF1B\u63A5\u53D7\u7684\u6280\u672F\u9009\u62E9\u8FDB\u5165 technicalDecisions\uFF1B\u53EA\u6709\u660E\u786E\u6392\u9664\u7684\u884C\u4E3A\u8FDB\u5165 excludedScope\uFF1B\u672A\u63A5\u53D7\u7684\u5EFA\u8BAE\u4ECD\u65E0\u6267\u884C\u6743\uFF0C\u4F46\u4E0D\u5F97\u81EA\u52A8\u585E\u5165 excludedScope\uFF1B\u4F4E\u5F71\u54CD\u53EF\u9006\u9ED8\u8BA4\u503C\u8FDB\u5165 defaults \u4E14\u4E0D\u5F97\u6269\u5F20\u8303\u56F4\u3002\u901A\u8FC7 \`workflow requirements ... finalize\` \u56FA\u5316\u4E03\u4E2A coverage \u7EF4\u5EA6\u3001\u7ED3\u6784\u5316\u9700\u6C42\u548C\u5E26\u9A8C\u8BC1\u65B9\u5F0F\u7684\u9A8C\u6536 ID\uFF0C\u53EA\u6709 CLI \u5224\u5B9A ready \u624D\u8FDB\u5165\u8BA1\u5212\u3002
15820
+ 3. Game Plan\uFF1APlan Coach \u5148\u505A\u8F93\u5165\u5C31\u7EEA\u68C0\u67E5\uFF1B\u6240\u6709\u9009\u9879\u5FC5\u987B\u89E3\u51B3\u540C\u4E00\u76EE\u6807\u548C\u9A8C\u6536\u8FB9\u754C\uFF0C\u5199\u660E complexity bearer\uFF0C\u53EA\u4FDD\u7559\u4E00\u4E2A recommendation \u548C stop conditions\uFF1B\u7B80\u5355\u4EFB\u52A1\u53EF\u4EE5\u53EA\u6709\u4E00\u4E2A\u771F\u5B9E\u65B9\u5411\u3002\u8BA1\u5212\u91CC\u5FC5\u987B\u5305\u542B\u7528\u6237\u53EF\u89C1\u7684 \`implementationScope\`\uFF08repo-relative include/exclude/modules\uFF09\u3001\u6280\u672F\u9009\u62E9\u7406\u7531\u3001\u517C\u5BB9\u6027\u98CE\u9669\u3001\u56DE\u6EDA\u65B9\u5F0F\uFF1Binclude \u662F\u6587\u4EF6\u5199\u5165\u4E0A\u9650\uFF0Cmodules \u4E0D\u5355\u72EC\u6388\u6743\u3002\u9AD8\u98CE\u9669\u6216\u8DE8 team/transport/owner/authority \u7684\u4EFB\u52A1\u5728 plan.md \u5185\u52A0\u5165\u975E\u6743\u5A01 Domain Matrix\u3002\u7981\u6B62\u63D0\u524D\u4FEE\u6539\u4E1A\u52A1\u6587\u4EF6\u6216\u56E2\u961F memory\u3002
15740
15821
  4. \u8BA1\u5212\u5173\u5361\uFF1A\u7528\u6237\u53EF\u53EA\u4FDD\u7559\u8BA1\u5212\u3001\u7EE7\u7EED\u5B8C\u6574\u56E2\u961F\u6267\u884C\u3001\u660E\u786E\u4EA4\u7ED9 solo \u8F7B\u91CF\u6267\u884C\u6216\u91CD\u5199\u8BA1\u5212\uFF1BActive Plans \u6309 taskId \u66F4\u65B0\u3002\u56E2\u961F\u5171\u4EAB\u6587\u4EF6\u6216\u4EA4\u63A5\u98CE\u9669\u5B58\u5728\u65F6\u63A8\u8350\u5B8C\u6574\u56E2\u961F\u6267\u884C\u3002
15741
15822
  5. \u5B9E\u65BD\uFF1A\u6539\u52A8\u524D\u518D\u6B21\u68C0\u67E5 \`git status --short\`\uFF0C\u907F\u514D\u8E29\u7528\u6237\u6216\u961F\u53CB\u6539\u52A8\u3002
15742
15823
  6. Self-test\uFF1A\u5728 Step 6 \u521D\u59CB\u5316 verification ledger\uFF0C\u628A\u6BCF\u4E2A required \u9A8C\u6536 ID \u7684\u81EA\u52A8\u3001\u4EBA\u5DE5\u6216 hybrid \u7ED3\u679C\u548C\u8BC1\u636E\u901A\u8FC7 CLI \u8BB0\u5F55\uFF1B\u81EA\u52A8\u7ED3\u679C\u5305\u542B\u547D\u4EE4\u4E0E\u9000\u51FA\u7801\uFF0C\u672A\u5168\u90E8\u901A\u8FC7\u4E0D\u5F97\u8FDB\u5165 review\u3002\u4F18\u5148\u8DD1\u9879\u76EE\u5DF2\u6709\u9A8C\u8BC1\u547D\u4EE4\uFF1B\u5931\u8D25\u4E24\u6B21\u505C\u4E0B\u8BCA\u65AD\u6839\u56E0\u3002\u9700\u8981\u4EBA\u5DE5\u9A8C\u8BC1\u65F6\u6807\u8BB0 require-manual \u5E76\u7B49\u5F85\u7528\u6237\u660E\u786E\u786E\u8BA4\uFF0C\u4E0D\u5F97\u81EA\u52A8\u6062\u590D\u3002remediation \u540E\u5728 Step 9 \u91CD\u65B0\u767B\u8BB0\u5168\u90E8\u9A8C\u6536\u3002
15743
- 7. Review scope + Film #1\uFF1A\u57FA\u4E8E\u5B9E\u9645 diff \u5199 \`review-scope.md\`\uFF0C\u7528 \`workflow review ... init\` \u9009\u62E9 targeted \u6216 full\uFF1B\u91CD\u70B9\u5BA1\u67E5\u884C\u4E3A\u3001\u53EF\u7EF4\u62A4\u6027\u3001\u56E2\u961F\u98CE\u683C\u4E0E\u6D4B\u8BD5\uFF0Cfinding \u5FC5\u987B\u6709\u8BC1\u636E\u548C\u7A33\u5B9A ID\u3002
15824
+ 7. Review scope + Film #1\uFF1A\u57FA\u4E8E\u5B9E\u9645 diff \u5199 \`review-scope.md\`\uFF0C\u7528 \`workflow review ... init\` \u9009\u62E9 targeted \u6216 full\uFF1B\u5148\u68C0\u67E5\u6BCF\u4E00\u5904\u6539\u52A8\u662F\u5426\u80FD\u8FFD\u6EAF\u5230\u5DF2\u786E\u8BA4\u8303\u56F4\u4E14\u540C\u65F6\u4F4D\u4E8E \`implementationScope\` include \u5185\u3001\u4E0D\u5339\u914D exclude\uFF0C\u672A\u7ECF\u6388\u6743\u7684\u6539\u52A8\u4F5C\u4E3A blocker\uFF0C\u518D\u5BA1\u67E5\u884C\u4E3A\u3001\u53EF\u7EF4\u62A4\u6027\u3001\u56E2\u961F\u98CE\u683C\u4E0E\u6D4B\u8BD5\uFF1Bfinding \u5FC5\u987B\u6709\u8BC1\u636E\u548C\u7A33\u5B9A ID\u3002
15744
15825
  8. Film #2\uFF1A\u4EC5 full \u6267\u884C\uFF0C\u5148\u8BFB Film #1 \u62A5\u544A\u5E76\u53BB\u91CD\uFF0C\u53EA\u5BA1\u67E5\u8FB9\u754C\u3001\u5B89\u5168\u3001\u6027\u80FD\u3001\u5E76\u53D1\u548C\u517C\u5BB9\u6027\u3002targeted \u7684\u7B2C\u4E8C\u5BA1\u662F\u4E0D\u9002\u7528\uFF0C\u4E0D\u80FD\u8BB0\u4E3A skipped\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8981\u6C42\u624D\u53EF\u8DF3\u8FC7\u5168\u90E8 review\uFF0C\u5E76\u5199\u5165 \`review\` \u548C\u6B8B\u4F59\u98CE\u9669\u3002
15745
15826
  9. Post-game\uFF1A\u6C47\u603B blocker\uFF0C\u53EA\u505A\u4E00\u8F6E\u4FEE\u590D\u5E76\u7528 \`workflow review ... remediate\` \u8BB0\u5F55\uFF1B\u590D\u9A8C\u540E\u5199 summary \u4E0E hand-off\u3002\u9A8C\u8BC1\u5931\u8D25\u3001\u5BA1\u67E5\u4E0D\u5B8C\u6574\u6216\u4ECD\u6709 blocker \u65F6\u6807\u8BB0 blocked\uFF0C\u4E0D\u5F97\u6807 completed\u3002
15746
15827
 
15828
+ \u5B9E\u65BD\u671F\u95F4\u82E5\u53EA\u9700\u8C03\u6574\u6587\u4EF6\u8FB9\u754C\u3001\u4E0D\u6539\u53D8\u5DF2\u786E\u8BA4\u884C\u4E3A\u6216\u9A8C\u6536\uFF0C\u5148\u5411\u7528\u6237\u5C55\u793A\u5B8C\u6574\u65B0\u8FB9\u754C\u5E76\u53D6\u5F97\u660E\u786E\u540C\u610F\uFF0C\u518D\u901A\u8FC7\u4E13\u7528 \`workflow scope change\` mutation \u66F4\u65B0\uFF1B\u5B83\u5FC5\u987B\u9012\u589E plan authority\u3001\u4F7F\u65E7 review/verification \u5931\u6548\u5E76\u91CD\u7B7E\u517C\u5BB9 claim\u3002\u884C\u4E3A\u6216\u9A8C\u6536\u53D8\u5316\u4ECD\u8D70 reframe\uFF0C\u4E0D\u80FD\u7528 scope change \u7ED5\u8FC7\u9700\u6C42\u786E\u8BA4\u3002
15829
+
15747
15830
  \u5B9E\u65BD\u4E2D\u65B0\u8BC1\u636E\u82E5\u63A8\u7FFB\u5DF2\u786E\u8BA4\u7684\u76EE\u6807\u3001owner\u3001source of truth \u6216\u9A8C\u6536\uFF0C\u5165\u53E3/\u6D41\u7A0B\u4F1A\u4EA7\u751F\u4E0D\u540C\u8BED\u4E49\uFF0Cstatus/contract/policy/transition \u542B\u4E49\u8981\u53D8\uFF0C\u53D1\u73B0 stale adapter\u3001writer \u4E0D\u517C\u5BB9\u3001\u672A\u5B8C\u6210 operation\u3001active child/open handoff/active solo assignment\uFF0C\u6216\u53D8\u5316\u8D85\u51FA requirements/plan scope\uFF0C\u7ACB\u5373\u505C\u6B62\uFF0C\u53EA\u8FD4\u56DE \`NEEDS_REALIGNMENT\` \u548C \`MANCODE_REFRAME_REQUIRED\`\u3002\u8FD9\u662F\u53EA\u8BFB\u8BCA\u65AD\uFF1A\u4E0D\u5F97\u8C03\u7528\u901A\u7528 workflow update \u5199 blocker\uFF0C\u4E0D\u6539 metadata/step/policy/requirements/plan/claims/handoff\uFF0C\u4E0D\u5F52\u6863\u6216\u91CA\u653E authority\u3002
15748
15831
 
15749
15832
  \u5982\u679C\u7528\u6237\u5728\u786E\u8BA4\u9636\u6BB5\u9009\u62E9"\u9000\u51FA"\u6216\u653E\u5F03\u56E2\u961F workflow\uFF1A\u7528 \`mancode workflow update <taskId> --status abandoned\` \u66F4\u65B0\u5E76\u6E05\u7406 Active Plans\uFF1B\u82E5\u6709\u6D3B\u8DC3 manba \u5B50\u4EFB\u52A1\uFF0C\u5148\u53D6\u5F97\u786E\u8BA4\u5E76\u9010\u4E2A abandoned\u3002\u6210\u529F\u540E\u518D\u7528 Edit \u66F4\u65B0 state \u56DE solo\u3002\u4E0D\u8981\u76F4\u63A5\u6539 metadata\uFF0C\u4E5F\u4E0D\u8981\u628A abandoned workflow \u7559\u5728 active state\u3002
@@ -16707,13 +16790,13 @@ var MODE_META = {
16707
16790
  "After each completed phase, advance through the CLI to the next numbered step;",
16708
16791
  "never advance state merely because a report was requested or an agent was called.",
16709
16792
  "",
16710
- "Step 1 \u2014 Scout: inspect the profile, existing implementation, dependencies, risks, and unknowns; write `scout-report.md`. When relevant and verifiable, include Current Behavior Evidence, Candidate Semantic Owner with confidence/conflict, Source of Truth split into authority/readers/writer/derived copies, and Historical / Compatibility Impact for existing workflows, legacy fixtures, transport, migration, and rollback. Never invent fields to fill the template.",
16711
- "Step 2 \u2014 Clarify by readiness, not a fixed round or question count. Ask every decision-changing question that cannot be resolved from project facts; use as many batches as needed without repeating confirmed answers. Classify unknowns as blocking, recommendable, or defaultable. When a good approach exists, present 2\u20133 options and make a clear recommendation. Create structured input with non-empty scope, exclusions, technical decisions, defaults, blocking unknowns, stable acceptance IDs, and explicit confirmed/defaulted/not-applicable coverage for platform, core scope, stack, data, performance, compatibility, and security. Run `mancode workflow requirements <taskId> finalize --file <input.json>`; only advance to Step 3 when the CLI returns ready.",
16712
- "Step 3 \u2014 Plan Coach first returns READY_FOR_PLAN or NEEDS_CLARIFICATION. Never hide blocking gaps inside assumptions. Every option must solve the same goal, acceptance boundary, and scope; name its complexity bearer and observable cost; return exactly one recommendation with rejection reasons and stop conditions. A simple task may have one real direction and must not manufacture alternatives. When ready, write `plan.md` with confirmed scope, technical choices and reasons, reuse, exclusions, behavior, risks/rollback, completion criteria, defaults, and real validation. For cross-platform entry differences, unclear owner/source of truth, contract/state changes, cross-workflow/team/transport work, or multi-version compatibility, add an optional Domain Matrix inside plan.md; it is not authority. First plan is v1; revisions use `--plan-version <current+1>`.",
16793
+ "Step 1 \u2014 Scout: run a bounded, read-only decision-impact discovery; test the user premise against repository evidence, inspect the end-to-end user goal and common domain failure/edge paths, and retain at most three material findings with stable IDs F-1 through F-3 and type premise, scope, technical, risk, or acceptance. Mark each repository_fact or domain_hypothesis; an unverified domain hypothesis becomes a focused question, never a fact. Discovery produces evidence and recommendations, never execution authority. Write `scout-report.md` with the profile, implementation, dependencies, risks, unknowns, and\u2014when verifiable\u2014Current Behavior Evidence, Candidate Semantic Owner with confidence/conflict, Source of Truth split into authority/readers/writer/derived copies, and Historical / Compatibility Impact for existing workflows, legacy fixtures, transport, migration, and rollback. Never invent fields to fill the template.",
16794
+ "Step 2 \u2014 Clarify by readiness, not a fixed round or question count. Ask every decision-changing question that cannot be resolved from project facts; use as many batches as needed without repeating confirmed answers. Classify unknowns as blocking, recommendable, or defaultable. When a good approach exists, present 2\u20133 options and make a clear recommendation. Give every F-ID one type-directed disposition: blocking findings stay in blockingUnknowns; accepted scope or behavior enters confirmedScope plus matching acceptanceCriteria; accepted technical choices enter technicalDecisions; only explicitly excluded behavior enters excludedScope; low-impact reversible details may enter defaults. An unaccepted proposal remains unauthorized and is not copied into every field. Create structured input with non-empty scope, exclusions, technical decisions, defaults, blocking unknowns, stable acceptance IDs, and explicit confirmed/defaulted/not-applicable coverage for platform, core scope, stack, data, performance, compatibility, and security. Run `mancode workflow requirements <taskId> finalize --file <input.json>`; only advance to Step 3 when the CLI returns ready.",
16795
+ "Step 3 \u2014 Plan Coach first returns READY_FOR_PLAN or NEEDS_CLARIFICATION. Never hide blocking gaps inside assumptions. Every option must solve the same goal, acceptance boundary, and scope; name its complexity bearer and observable cost; return exactly one recommendation with rejection reasons and stop conditions. A simple task may have one real direction and must not manufacture alternatives. When ready, write `plan.md` with confirmed scope, technical choices and reasons, reuse, exclusions, behavior, risks/rollback, completion criteria, defaults, and real validation. Add a user-visible implementation scope with non-empty repo-relative include, exclude, and module labels; include is the file-write upper bound, exclude wins, and modules do not authorize files. For cross-platform entry differences, unclear owner/source of truth, contract/state changes, cross-workflow/team/transport work, or multi-version compatibility, add an optional Domain Matrix inside plan.md; it is not authority. First plan is v1; revisions use `--plan-version <current+1>`.",
16713
16796
  "Step 4 \u2014 Plan gate: recommend based on risk and let the user choose (1) hand the confirmed plan to lightweight solo via `mancode workflow handoff <taskId> --to solo`, (2) continue full governed execution via `mancode workflow decide <taskId> --plan-decision governed_execution` before Step 5, (3) keep the plan only via `mancode workflow decide <taskId> --plan-decision plan_only`, or (4) revise. Do not implement before this choice. Before either execution path, echo the plan version, delivery, stack, inclusions, exclusions, validation, and residual assumptions.",
16714
- "Step 5 \u2014 Implement the confirmed minimum change.",
16797
+ "Step 5 \u2014 State material assumptions and verifiable success criteria, then implement the smallest direct change inside both the confirmed plan and implementation scope. Reuse existing code and dependencies; do not add speculative features, one-off abstractions, configurability, adjacent cleanup, or unrelated defenses. A newly discovered out-of-scope need authorizes only NEEDS_REALIGNMENT until the user approves reframe. If an upgraded already-running local man task has no executable scope, show the complete boundary and wait for explicit approval, then rerun plan revise with the exact unchanged current plan plus --scope-file; this compatibility bind stales old evidence and cannot change behavior or an already executable boundary.",
16715
16798
  "Step 6 \u2014 Run `workflow verify <taskId> init`, execute detected build/lint/typecheck/test and smoke checks, and record every required acceptance ID with reproducible evidence; automated passed/failed records include the command and exit code. Use require-manual when a foreground browser, device, or human judgment is necessary; stop for explicit user confirmation before confirm-manual. The CLI blocks Step 7 and review until all checks pass. Then write `review-scope.md` and initialize targeted or full review. An explicit user review skip uses `workflow review <taskId> skip --reason <reason>` at Step 6, never generic skipped metadata.",
16716
- "Step 7 \u2014 Run one quality review limited to the changed diff and direct impact. Findings require changed-line evidence and user impact, with at most three new findings. Record stable blocker IDs through `workflow review ... complete`; do not fix yet.",
16799
+ "Step 7 \u2014 Run one quality review limited to the changed diff and direct impact. Compare every changed path and behavior with confirmed requirements, acceptance IDs, and implementation scope; any unauthorized behavior, path outside include, or path matching exclude is a blocker. Findings require changed-line evidence and user impact, with at most three new findings. Record stable blocker IDs through `workflow review ... complete`; do not fix yet.",
16717
16800
  "Step 8 \u2014 Only full review runs the security/boundary reviewer. It must read Film #1, mark the same root cause duplicate, and stay within security, permissions, recovery, resources, and boundaries. A targeted review treats the second domain as not applicable; it is never recorded as a skipped step.",
16718
16801
  "Step 9 \u2014 If open blockers exist, fix them in one remediation round and record resolved IDs through `workflow review ... remediate`; remediation invalidates all earlier acceptance evidence, so re-run and re-record every required check at Step 9 without re-running completed reviewers. Write `summary.md` and set completed only when verification and required review domains are complete and blockers are zero.",
16719
16802
  "",
@@ -16733,6 +16816,10 @@ var MODE_META = {
16733
16816
  "and currentWorkflowMode to manteam. First collect branch, dirty-worktree, contributor,",
16734
16817
  "shared-module, and handoff risks in `team-context.md`.",
16735
16818
  "",
16819
+ "Run the same bounded Scout discovery as /man with stable F-IDs and typed findings. Discovery produces evidence and recommendations, never execution authority.",
16820
+ "Use the same type-directed disposition as /man, bind the confirmed plan to a user-visible implementation scope, and treat that scope as the file-write upper bound for claims, implementation, and review.",
16821
+ "After explicit user approval, a file-boundary-only adjustment may use `workflow scope change`; it versions plan authority, stales prior evidence, and reissues compatible claims. A behavior or acceptance change still requires reframe.",
16822
+ "",
16736
16823
  "Then execute every /man Step 1 through Step 9, including clarification,",
16737
16824
  "plan gate, validation, bounded risk-based review, conditional completion, planVersion,",
16738
16825
  "Active Plans, and linked manba child behavior. Add compatibility, rollback,",
@@ -23051,7 +23138,7 @@ async function planContextCompaction(input) {
23051
23138
  ...gitRefWorkflowRepairPlan.protectedTaskRefs
23052
23139
  ]);
23053
23140
  const taskRefs = input.taskRef === void 0 ? await listTaskRefs(root) : [parseTaskRefValue(input.taskRef)];
23054
- const [checkpointPlan, sessions, overlays, cache] = await Promise.all([
23141
+ const [checkpointPlan, sessions, cache] = await Promise.all([
23055
23142
  planCheckpointCompaction(
23056
23143
  store,
23057
23144
  coordinationStore,
@@ -23064,13 +23151,6 @@ async function planContextCompaction(input) {
23064
23151
  now,
23065
23152
  protectedSessionIds
23066
23153
  ),
23067
- planLocalOverlayRetention(
23068
- root,
23069
- store,
23070
- taskRefs,
23071
- project.policy.retention.localRawArtifactDays,
23072
- now
23073
- ),
23074
23154
  planLocalCacheRetention(root, project.policy.retention.localCacheDays, now)
23075
23155
  ]);
23076
23156
  return {
@@ -23081,7 +23161,6 @@ async function planContextCompaction(input) {
23081
23161
  ...operationPlan.candidates,
23082
23162
  ...gitRefWorkflowRepairPlan.candidates,
23083
23163
  ...checkpointPlan.candidates,
23084
- ...overlays,
23085
23164
  ...cache
23086
23165
  ].sort(
23087
23166
  (left, right) => Buffer.from(left.target, "utf8").compare(
@@ -23091,37 +23170,6 @@ async function planContextCompaction(input) {
23091
23170
  skippedReferencedCheckpoints: checkpointPlan.skippedReferencedCheckpoints
23092
23171
  };
23093
23172
  }
23094
- async function planLocalOverlayRetention(root, store, taskRefs, localRawArtifactDays, now) {
23095
- const threshold = now.getTime() - localRawArtifactDays * 864e5;
23096
- const candidates = [];
23097
- for (const taskRef of taskRefs) {
23098
- if (taskRef.namespace !== "shared") continue;
23099
- const task = await store.readTaskSnapshot(taskRef);
23100
- if (!isTerminalTaskStatus(task.metadata.status)) continue;
23101
- const directory = path41.join(
23102
- root,
23103
- ".mancode",
23104
- "local",
23105
- "overlays",
23106
- taskRef.taskId,
23107
- "artifacts"
23108
- );
23109
- for (const entry of await readDirectoryOrEmpty(directory)) {
23110
- const target = path41.join(directory, entry);
23111
- const metadata = await regularFileMetadataOrNull(target);
23112
- if (metadata === null || metadata.mtimeMs >= threshold) continue;
23113
- candidates.push({
23114
- kind: "local_overlay_artifact",
23115
- target,
23116
- reason: `terminal task raw artifact exceeds ${localRawArtifactDays} day retention`,
23117
- // The artifact is local-only even though it is grouped by shared task.
23118
- taskRef: null,
23119
- relatedTargets: []
23120
- });
23121
- }
23122
- }
23123
- return candidates;
23124
- }
23125
23173
  async function planLocalCacheRetention(root, localCacheDays, now) {
23126
23174
  const threshold = now.getTime() - localCacheDays * 864e5;
23127
23175
  const directory = path41.join(root, ".mancode", "local", "cache");
@@ -23306,9 +23354,6 @@ function taskRefKeyFromEntityKey(entityKey) {
23306
23354
  );
23307
23355
  return match === null ? null : `${match[1]}:${match[2]}`;
23308
23356
  }
23309
- function isTerminalTaskStatus(status2) {
23310
- return status2 === "completed" || status2 === "abandoned" || status2 === "superseded";
23311
- }
23312
23357
  async function listTaskRefs(root) {
23313
23358
  const refs = [];
23314
23359
  for (const namespace of ["local", "shared"]) {
@@ -28012,7 +28057,6 @@ async function writeGreenfieldLayout(stagingRoot, manifest, config, policy, proj
28012
28057
  recursive: true
28013
28058
  }),
28014
28059
  mkdir35(path53.join(stagingRoot, "local", "workflows"), { recursive: true }),
28015
- mkdir35(path53.join(stagingRoot, "local", "overlays"), { recursive: true }),
28016
28060
  mkdir35(path53.join(stagingRoot, "local", "quarantine"), { recursive: true }),
28017
28061
  mkdir35(path53.join(stagingRoot, "local", "publish"), { recursive: true }),
28018
28062
  mkdir35(path53.join(stagingRoot, "local", "cache"), { recursive: true }),
@@ -41491,6 +41535,30 @@ function version() {
41491
41535
  console.log(platform);
41492
41536
  }
41493
41537
 
41538
+ // src/commands/workflow-subcommands.ts
41539
+ var WORKFLOW_SUBCOMMANDS = [
41540
+ "create",
41541
+ "list",
41542
+ "show",
41543
+ "update",
41544
+ "requirements",
41545
+ "plan",
41546
+ "review",
41547
+ "verify",
41548
+ "complete",
41549
+ "scope",
41550
+ "reframe",
41551
+ "archive",
41552
+ "checkpoint",
41553
+ "child",
41554
+ "promote",
41555
+ "handoff"
41556
+ ];
41557
+ var WORKFLOW_SUBCOMMAND_SET = new Set(
41558
+ WORKFLOW_SUBCOMMANDS
41559
+ );
41560
+ var CONTINUITY_COMPATIBILITY_SUBCOMMANDS = /* @__PURE__ */ new Set(["clean"]);
41561
+
41494
41562
  // src/commands/workflow.ts
41495
41563
  import { access as access6, readFile as readFile48, rm as rm23, writeFile as writeFile50 } from "fs/promises";
41496
41564
  import path69 from "path";
@@ -41821,175 +41889,289 @@ function assertPositiveRevision6(value, label) {
41821
41889
  }
41822
41890
  }
41823
41891
 
41824
- // src/context/plan-revision.ts
41825
- async function reviseV3Plan(input) {
41892
+ // src/context/scope-change.ts
41893
+ import { createHash as createHash11 } from "crypto";
41894
+ async function changeV3WorkflowScope(input) {
41826
41895
  const taskRef = parseTaskRefValue(input.taskRef);
41827
- const plan = requirePlan(input.plan);
41828
- const planDecision = parsePlanDecision(input.planDecision);
41829
- if (taskRef.namespace === "shared") {
41830
- assertSharedTextSafe(plan, "plan");
41896
+ if (taskRef.namespace !== "shared") {
41897
+ throw new Error("MANCODE_SCOPE_CHANGE_REQUIRES_SHARED_TASK");
41831
41898
  }
41832
- const context = await openV3TaskOperation({
41899
+ const scope = normalizeImplementationScope(input.scope);
41900
+ const now = input.now ?? /* @__PURE__ */ new Date();
41901
+ const timestamp4 = now.toISOString();
41902
+ const checkpointId = input.checkpointId ?? createUlid(now.getTime());
41903
+ const operationId = input.operationId ?? createUlid(now.getTime());
41904
+ assertUlid(checkpointId, "scope change checkpointId");
41905
+ assertUlid(operationId, "scope change operationId");
41906
+ const opened = await openScopeChangeContext({
41833
41907
  projectRoot: input.projectRoot,
41834
41908
  taskRef,
41835
41909
  sessionId: input.sessionId,
41836
41910
  expectedTaskRevision: input.expectedTaskRevision,
41837
- operationId: input.operationId,
41838
- extraEntityLocks: taskRef.namespace === "shared" ? [taskHeadEntityKey(taskRef)] : [],
41839
- now: input.now
41911
+ scope,
41912
+ checkpointId,
41913
+ successorClaimIds: input.successorClaimIds,
41914
+ operationId,
41915
+ now
41840
41916
  });
41917
+ const { context, activeClaims: activeClaims2, successorClaimIds, successorPredecessors } = opened;
41841
41918
  let journal = null;
41842
41919
  try {
41843
- assertPlanRevisionEligible(
41920
+ assertScopeChangeEligible(context, scope);
41921
+ assertClaimsFreshForScopeChange(context, activeClaims2);
41922
+ const pendingMetadata = markScopeChangeOperationPending(
41844
41923
  context.task.metadata,
41845
- context.task.requirements
41924
+ context.operationId,
41925
+ timestamp4
41846
41926
  );
41847
- if (context.task.metadata.workflowMode === "manteam" && planDecision === "governed_execution") {
41848
- assertManteamPlanContent(plan);
41849
- }
41850
- if (context.task.plan?.content === plan && planDecision === null) {
41851
- throw new Error("MANCODE_PLAN_CONTENT_UNCHANGED");
41852
- }
41853
- const planChanged = context.task.plan?.content !== plan;
41854
- const timestamp4 = context.now.toISOString();
41855
- const planDigest = planChanged ? digestCanonicalJson({
41856
- artifactRef: { taskRef, kind: "plan" },
41857
- content: plan
41858
- }) : context.task.plan?.digest;
41859
- if (planDigest === void 0) {
41860
- throw new Error("MANCODE_PLAN_FILE_REQUIRED");
41861
- }
41862
- const review = planChanged ? markTaskReviewStale(context.task.review, context.operationId, timestamp4) : context.task.review;
41863
- const verification = planChanged ? markTaskVerificationStale(
41927
+ const review = markTaskReviewStale(
41928
+ context.task.review,
41929
+ context.operationId,
41930
+ timestamp4
41931
+ );
41932
+ const verification = markTaskVerificationStale(
41864
41933
  context.task.verification,
41865
41934
  context.operationId,
41866
41935
  timestamp4
41867
- ) : context.task.verification;
41868
- const metadata = updateMetadata(
41869
- context.task.metadata,
41870
- context.task.requirements,
41871
- review,
41872
- verification,
41873
- planChanged,
41874
- planDecision,
41936
+ );
41937
+ const branch = await readCheckoutBranch(context.projectRoot) ?? "HEAD";
41938
+ const checkpoint = buildScopeChangedCheckpoint(
41939
+ context,
41940
+ pendingMetadata,
41941
+ checkpointId,
41942
+ input.checkpointSummary,
41943
+ input.checkpointNextAction,
41944
+ branch,
41945
+ pendingMetadata.governance.planVersion + 1,
41946
+ review.contentDigest,
41947
+ verification.contentDigest,
41948
+ timestamp4
41949
+ );
41950
+ const metadata = completeScopeChangeMetadata(
41951
+ pendingMetadata,
41952
+ scope,
41953
+ checkpoint,
41954
+ review.contentDigest,
41955
+ verification.contentDigest,
41875
41956
  context.operationId,
41876
41957
  timestamp4
41877
41958
  );
41959
+ const pendingSuccessorClaims = buildPendingSuccessorClaims2(
41960
+ successorPredecessors,
41961
+ successorClaimIds,
41962
+ metadata,
41963
+ branch,
41964
+ requireCodeHead3(context),
41965
+ context.operationId,
41966
+ timestamp4,
41967
+ capabilitiesFromProjectConfig(context.project.config)
41968
+ );
41969
+ const successorByPredecessor = new Map(
41970
+ successorPredecessors.map((claim, index) => {
41971
+ const successorClaimId = successorClaimIds[index];
41972
+ if (successorClaimId === void 0) {
41973
+ throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
41974
+ }
41975
+ return [claim.claimId, successorClaimId];
41976
+ })
41977
+ );
41978
+ const terminatedClaims = activeClaims2.map(
41979
+ (claim) => terminateClaimForScopeChange(
41980
+ claim,
41981
+ successorByPredecessor.get(claim.claimId) ?? null,
41982
+ context.operationId,
41983
+ timestamp4
41984
+ )
41985
+ );
41986
+ const activeSuccessorClaims = pendingSuccessorClaims.map(
41987
+ (claim) => activateSuccessorClaim3(claim, context.operationId, timestamp4)
41988
+ );
41878
41989
  const aggregate = buildTaskAggregateManifest({
41879
41990
  metadata,
41880
41991
  requirements: context.task.requirements,
41881
41992
  review,
41882
41993
  verification,
41883
- planDigest,
41884
- latestCheckpoint: context.task.latestCheckpoint
41994
+ planDigest: context.task.plan?.digest ?? null,
41995
+ latestCheckpoint: checkpoint
41885
41996
  });
41886
41997
  const taskHeadFence = nextTaskHeadFence(context, aggregate, timestamp4);
41887
- if (planDecision === "plan_only") {
41888
- await enqueueSessionPointerProjection(context.projectRoot, {
41889
- operationId: context.operationId,
41890
- action: "clear",
41891
- sessionId: context.session.sessionId,
41892
- expectedPreviousTaskRef: context.session.activeTaskRef,
41893
- taskRef,
41894
- workflowMode: metadata.workflowMode,
41895
- taskRevision: metadata.revision,
41896
- now: context.now
41897
- });
41998
+ if (taskHeadFence === null) {
41999
+ throw new Error("MANCODE_TASK_HEAD_FENCE_MISSING");
41898
42000
  }
41899
42001
  journal = await createTaskOperationJournal(context, {
41900
- type: "plan_revision",
41901
- action: taskRef.namespace === "shared" ? "shared_metadata_plan_mutation" : "local_workflow_mutation",
41902
- expectedRevisions: taskMutationExpectedRevisions(context, [
41903
- "plan",
41904
- "review",
41905
- "verification"
41906
- ]),
42002
+ type: "scope_change_reclaim",
42003
+ action: "task_complete_scope_change_child_merge",
42004
+ expectedRevisions: scopeChangeExpectedRevisions(
42005
+ context,
42006
+ checkpointId,
42007
+ activeClaims2,
42008
+ successorClaimIds
42009
+ ),
42010
+ conditions: { completionGateSatisfied: true },
41907
42011
  recovery: {
41908
42012
  actions: [
41909
- ...planChanged ? [
41910
- createTaskAuthorityFileRecoveryAction({
41911
- stepId: "write-plan",
41912
- taskRef,
41913
- fileName: "plan.md",
41914
- beforeContent: context.task.plan?.content ?? null,
41915
- targetContent: plan
41916
- })
41917
- ] : [],
41918
42013
  createTaskAuthorityFileRecoveryAction({
41919
- stepId: "update-metadata",
42014
+ stepId: "mark-task-operation-pending",
41920
42015
  taskRef,
41921
42016
  fileName: "metadata.json",
41922
42017
  beforeContent: serializeTaskAuthority(context.task.metadata),
41923
- targetContent: serializeTaskAuthority(metadata)
42018
+ targetContent: serializeTaskAuthority(pendingMetadata)
41924
42019
  }),
41925
- ...planChanged ? [
41926
- createTaskAuthorityFileRecoveryAction({
41927
- stepId: "mark-review-verification-stale",
41928
- taskRef,
41929
- fileName: "review-ledger.json",
41930
- beforeContent: serializeTaskAuthority(context.task.review),
41931
- targetContent: serializeTaskAuthority(review)
41932
- }),
41933
- createTaskAuthorityFileRecoveryAction({
41934
- stepId: "mark-review-verification-stale",
41935
- taskRef,
41936
- fileName: "verification-ledger.json",
41937
- beforeContent: serializeTaskAuthority(
41938
- context.task.verification
41939
- ),
41940
- targetContent: serializeTaskAuthority(verification)
41941
- })
41942
- ] : [],
41943
- ...taskHeadFence === null ? [] : [
41944
- createTaskHeadFenceRecoveryAction({
41945
- stepId: "update-task-head-fence",
41946
- before: context.coordination.taskHeadFence,
41947
- fence: taskHeadFence
42020
+ createCheckpointRecoveryAction({
42021
+ stepId: "write-scope-changed-checkpoint",
42022
+ before: null,
42023
+ checkpoint
42024
+ }),
42025
+ ...pendingSuccessorClaims.map(
42026
+ (claim) => createClaimRecoveryAction({
42027
+ stepId: "create-pending-successor-claims",
42028
+ before: null,
42029
+ claim
41948
42030
  })
41949
- ]
42031
+ ),
42032
+ ...terminatedClaims.map((claim, index) => {
42033
+ const before = activeClaims2[index];
42034
+ if (before === void 0) {
42035
+ throw new Error("MANCODE_CLAIM_SET_CHANGED");
42036
+ }
42037
+ return createClaimRecoveryAction({
42038
+ stepId: "terminate-old-claims",
42039
+ before,
42040
+ claim
42041
+ });
42042
+ }),
42043
+ createTaskAuthorityFileRecoveryAction({
42044
+ stepId: "mark-review-verification-stale",
42045
+ taskRef,
42046
+ fileName: "review-ledger.json",
42047
+ beforeContent: serializeTaskAuthority(context.task.review),
42048
+ targetContent: serializeTaskAuthority(review)
42049
+ }),
42050
+ createTaskAuthorityFileRecoveryAction({
42051
+ stepId: "mark-review-verification-stale",
42052
+ taskRef,
42053
+ fileName: "verification-ledger.json",
42054
+ beforeContent: serializeTaskAuthority(context.task.verification),
42055
+ targetContent: serializeTaskAuthority(verification)
42056
+ }),
42057
+ createTaskAuthorityFileRecoveryAction({
42058
+ stepId: "update-metadata-scope",
42059
+ taskRef,
42060
+ fileName: "metadata.json",
42061
+ beforeContent: serializeTaskAuthority(pendingMetadata),
42062
+ targetContent: serializeTaskAuthority(metadata)
42063
+ }),
42064
+ ...activeSuccessorClaims.map((claim, index) => {
42065
+ const before = pendingSuccessorClaims[index];
42066
+ if (before === void 0) {
42067
+ throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
42068
+ }
42069
+ return createClaimRecoveryAction({
42070
+ stepId: "activate-successor-claims",
42071
+ before,
42072
+ claim
42073
+ });
42074
+ }),
42075
+ createTaskHeadFenceRecoveryAction({
42076
+ stepId: "update-task-head-fence",
42077
+ before: context.coordination.taskHeadFence,
42078
+ fence: taskHeadFence
42079
+ })
41950
42080
  ],
41951
42081
  noOpStepIds: [
41952
- ...planChanged ? [] : ["write-plan", "mark-review-verification-stale"],
41953
- ...taskHeadFence === null ? ["update-task-head-fence"] : []
42082
+ ...pendingSuccessorClaims.length === 0 ? ["create-pending-successor-claims"] : [],
42083
+ ...terminatedClaims.length === 0 ? ["terminate-old-claims"] : [],
42084
+ ...activeSuccessorClaims.length === 0 ? ["activate-successor-claims"] : []
41954
42085
  ]
41955
42086
  }
41956
42087
  });
41957
42088
  journal = await advanceTaskOperation(context, journal, "validate", true);
41958
- journal = await advanceTaskOperation(context, journal, "write-plan", false);
41959
- if (planChanged) {
41960
- await writeTaskAuthorityFile(context, "plan.md", plan);
41961
- }
41962
42089
  journal = await advanceTaskOperation(
41963
42090
  context,
41964
42091
  journal,
41965
- "update-metadata",
42092
+ "mark-task-operation-pending",
41966
42093
  false
41967
42094
  );
42095
+ await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
41968
42096
  await writeTaskAuthorityFile(
41969
42097
  context,
41970
42098
  "metadata.json",
41971
- `${JSON.stringify(metadata, null, 2)}
42099
+ `${JSON.stringify(pendingMetadata, null, 2)}
41972
42100
  `
41973
42101
  );
42102
+ journal = await advanceTaskOperation(
42103
+ context,
42104
+ journal,
42105
+ "write-scope-changed-checkpoint",
42106
+ false
42107
+ );
42108
+ await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
42109
+ await writeTaskCheckpoint(context, checkpoint);
42110
+ journal = await advanceTaskOperation(
42111
+ context,
42112
+ journal,
42113
+ "create-pending-successor-claims",
42114
+ false
42115
+ );
42116
+ await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
42117
+ for (const claim of pendingSuccessorClaims) {
42118
+ await createClaim(context.homeStore, claim);
42119
+ }
42120
+ journal = await advanceTaskOperation(
42121
+ context,
42122
+ journal,
42123
+ "terminate-old-claims",
42124
+ false
42125
+ );
42126
+ await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
42127
+ for (const [index, claim] of terminatedClaims.entries()) {
42128
+ const previous = activeClaims2[index];
42129
+ if (previous === void 0) {
42130
+ throw new Error("MANCODE_CLAIM_SET_CHANGED");
42131
+ }
42132
+ await updateClaim(context.homeStore, claim, previous.revision);
42133
+ }
41974
42134
  journal = await advanceTaskOperation(
41975
42135
  context,
41976
42136
  journal,
41977
42137
  "mark-review-verification-stale",
41978
42138
  false
41979
42139
  );
41980
- if (planChanged) {
41981
- await writeTaskAuthorityFile(
41982
- context,
41983
- "review-ledger.json",
41984
- `${JSON.stringify(review, null, 2)}
42140
+ await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
42141
+ await writeTaskAuthorityFile(
42142
+ context,
42143
+ "review-ledger.json",
42144
+ `${JSON.stringify(review, null, 2)}
41985
42145
  `
41986
- );
41987
- await writeTaskAuthorityFile(
41988
- context,
41989
- "verification-ledger.json",
41990
- `${JSON.stringify(verification, null, 2)}
42146
+ );
42147
+ await writeTaskAuthorityFile(
42148
+ context,
42149
+ "verification-ledger.json",
42150
+ `${JSON.stringify(verification, null, 2)}
41991
42151
  `
41992
- );
42152
+ );
42153
+ journal = await advanceTaskOperation(
42154
+ context,
42155
+ journal,
42156
+ "update-metadata-scope",
42157
+ false
42158
+ );
42159
+ await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
42160
+ await writeTaskAuthorityFile(
42161
+ context,
42162
+ "metadata.json",
42163
+ `${JSON.stringify(metadata, null, 2)}
42164
+ `
42165
+ );
42166
+ journal = await advanceTaskOperation(
42167
+ context,
42168
+ journal,
42169
+ "activate-successor-claims",
42170
+ false
42171
+ );
42172
+ await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
42173
+ for (const claim of activeSuccessorClaims) {
42174
+ await updateClaim(context.homeStore, claim, 1);
41993
42175
  }
41994
42176
  journal = await advanceTaskOperation(
41995
42177
  context,
@@ -41997,26 +42179,14 @@ async function reviseV3Plan(input) {
41997
42179
  "update-task-head-fence",
41998
42180
  false
41999
42181
  );
42000
- if (taskHeadFence !== null) {
42001
- await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
42002
- await replaceTaskHeadFence(context.homeStore, taskHeadFence);
42003
- }
42182
+ await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
42183
+ await replaceTaskHeadFence(context.homeStore, taskHeadFence);
42004
42184
  const operation = await commitTaskOperation(context, journal);
42005
- if (planDecision === "plan_only") {
42006
- try {
42007
- await reconcileProjectionIntents(
42008
- context.projectRoot,
42009
- context.operationId,
42010
- context.now
42011
- );
42012
- } catch {
42013
- }
42014
- }
42015
42185
  return {
42016
42186
  metadata,
42017
- review,
42018
- verification,
42019
- planDigest,
42187
+ checkpoint,
42188
+ terminatedClaims,
42189
+ successorClaims: activeSuccessorClaims,
42020
42190
  aggregate,
42021
42191
  taskHeadFence,
42022
42192
  operation
@@ -42033,65 +42203,665 @@ async function reviseV3Plan(input) {
42033
42203
  await context.release();
42034
42204
  }
42035
42205
  }
42036
- function requirePlan(value) {
42037
- if (typeof value !== "string" || !value.trim() || value.includes("\0")) {
42038
- throw new Error("MANCODE_PLAN_CONTENT_REQUIRED");
42206
+ async function openScopeChangeContext(input) {
42207
+ for (let attempt = 0; attempt < 3; attempt += 1) {
42208
+ const runtime = await readProjectRuntimeContext(input.projectRoot);
42209
+ const store = new V3ContextStore(input.projectRoot);
42210
+ const homeStore = resolveTaskEntityHomeStore(
42211
+ runtime.entityHomeStoreContext,
42212
+ input.taskRef
42213
+ );
42214
+ const preflight = await store.readCoordinationSnapshot(
42215
+ input.taskRef,
42216
+ homeStore
42217
+ );
42218
+ const preflightClaims = activeClaims(preflight.claims);
42219
+ const preflightSuccessors = claimsWithinScope(preflightClaims, input.scope);
42220
+ const preflightSuccessorIds = resolveSuccessorClaimIds2(
42221
+ preflightSuccessors,
42222
+ input.successorClaimIds,
42223
+ input.operationId,
42224
+ input.now.toISOString()
42225
+ );
42226
+ const context = await openV3TaskOperation({
42227
+ projectRoot: input.projectRoot,
42228
+ taskRef: input.taskRef,
42229
+ sessionId: input.sessionId,
42230
+ expectedTaskRevision: input.expectedTaskRevision,
42231
+ operationId: input.operationId,
42232
+ extraEntityLocks: [
42233
+ `checkpoint:${input.checkpointId}`,
42234
+ taskHeadEntityKey(input.taskRef),
42235
+ ...preflightClaims.map((claim) => `claim:${claim.claimId}`),
42236
+ ...preflightSuccessorIds.map((claimId) => `claim:${claimId}`)
42237
+ ],
42238
+ now: input.now
42239
+ });
42240
+ const lockedClaims = activeClaims(context.coordination.claims);
42241
+ if (sameClaimIdSet(preflightClaims, lockedClaims)) {
42242
+ const successors = claimsWithinScope(lockedClaims, input.scope);
42243
+ const successorIds = resolveSuccessorClaimIds2(
42244
+ successors,
42245
+ input.successorClaimIds,
42246
+ input.operationId,
42247
+ input.now.toISOString()
42248
+ );
42249
+ return {
42250
+ context,
42251
+ activeClaims: lockedClaims,
42252
+ successorPredecessors: successors,
42253
+ successorClaimIds: successorIds
42254
+ };
42255
+ }
42256
+ await context.release();
42039
42257
  }
42040
- return value;
42258
+ throw new Error("MANCODE_CLAIM_SET_CHANGED");
42041
42259
  }
42042
- function parsePlanDecision(value) {
42043
- if (value === void 0) return null;
42044
- if (value !== "plan_only" && value !== "governed_execution") {
42045
- throw new Error("MANCODE_PLAN_DECISION_INVALID");
42260
+ function assertScopeChangeEligible(context, scope) {
42261
+ const metadata = context.task.metadata;
42262
+ if (context.project.config.transport.mode !== "local") {
42263
+ throw new Error("MANCODE_GIT_REF_TRANSPORT_NOT_IMPLEMENTED");
42046
42264
  }
42047
- return value;
42048
- }
42049
- function assertPlanRevisionEligible(metadata, requirements) {
42050
- if (metadata.workflowMode !== "man" && metadata.workflowMode !== "manteam") {
42051
- throw new Error("MANCODE_PLAN_WORKFLOW_MODE_INVALID");
42265
+ if (metadata.workflowMode !== "manteam") {
42266
+ throw new Error("MANCODE_SCOPE_CHANGE_WORKFLOW_MODE_INVALID");
42052
42267
  }
42053
42268
  if (metadata.status !== "in_progress") {
42054
- throw new Error("MANCODE_PLAN_WORKFLOW_NOT_ACTIVE");
42269
+ throw new Error("MANCODE_SCOPE_CHANGE_WORKFLOW_NOT_ACTIVE");
42055
42270
  }
42056
- if (metadata.currentStep < 2 || metadata.currentStep > 4) {
42057
- throw new Error("MANCODE_PLAN_STEP_INVALID");
42271
+ if (metadata.ownerActorId !== context.session.actorId) {
42272
+ throw new Error("MANCODE_TASK_OWNER_REQUIRED");
42058
42273
  }
42059
- if (metadata.governance.planDecision !== null || metadata.governance.requirementsStatus !== "ready" || metadata.governance.requirementsDigest !== requirements.contentDigest || requirements.status !== "confirmed" || !requirementsAreReady(requirements)) {
42060
- throw new Error("MANCODE_PLAN_REQUIREMENTS_OR_DECISION_INVALID");
42274
+ if (metadata.parent !== null) {
42275
+ throw new Error("MANCODE_PARENT_SCOPE_INHERITANCE_REQUIRED");
42276
+ }
42277
+ if (metadata.implementationScope.digest === scope.digest) {
42278
+ throw new Error("MANCODE_SCOPE_CHANGE_NOOP");
42061
42279
  }
42062
42280
  }
42063
- function updateMetadata(previous, requirements, review, verification, planChanged, planDecision, operationId, updatedAt) {
42064
- const status2 = planDecision === "plan_only" ? "planned" : "in_progress";
42065
- const currentStep = planDecision === "governed_execution" ? 5 : 4;
42066
- const next = parseWorkflowMetadata({
42067
- ...previous,
42068
- status: status2,
42069
- currentStep,
42070
- revision: previous.revision + 1,
42071
- transitionState: "stable",
42072
- lastOperationId: operationId,
42073
- governance: {
42074
- ...previous.governance,
42075
- requirementsStatus: "ready",
42076
- requirementsDigest: requirements.contentDigest,
42077
- planVersion: previous.governance.planVersion + (planChanged ? 1 : 0),
42078
- planDecision,
42079
- reviewStatus: planChanged ? "stale" : previous.governance.reviewStatus,
42080
- reviewLedgerDigest: review.contentDigest,
42081
- verificationStatus: planChanged ? "stale" : previous.governance.verificationStatus,
42082
- verificationLedgerDigest: verification.contentDigest
42083
- },
42084
- updatedAt
42085
- });
42086
- assertWorkflowMetadataTransition(previous, next, "ordinary");
42087
- return next;
42088
- }
42089
-
42090
- // src/context/reframe.ts
42091
- async function reframeV3Workflow(input) {
42092
- const taskRef = parseTaskRefValue(input.taskRef);
42093
- assertUlid(input.checkpointId, "reframe checkpointId");
42094
- const now = input.now ?? /* @__PURE__ */ new Date();
42281
+ function assertClaimsFreshForScopeChange(context, claims) {
42282
+ const codeHead = requireCodeHead3(context);
42283
+ for (const claim of claims) {
42284
+ if (claim.authority.mode !== "local") {
42285
+ throw new Error("MANCODE_OPERATION_REPAIR_REQUIRED");
42286
+ }
42287
+ const validity = deriveClaimValidity(claim, {
42288
+ taskRef: context.taskRef,
42289
+ taskRevision: context.task.metadata.revision,
42290
+ implementationScopeDigest: context.task.metadata.implementationScope.digest,
42291
+ ownershipEpoch: context.task.metadata.ownershipEpoch,
42292
+ codeRefHead: codeHead,
42293
+ now: context.now,
42294
+ transportFreshness: "fresh"
42295
+ });
42296
+ if (validity !== "fresh") {
42297
+ throw new Error("MANCODE_CLAIM_REVALIDATION_REQUIRED");
42298
+ }
42299
+ }
42300
+ }
42301
+ function normalizeImplementationScope(value) {
42302
+ assertRecord(value, "workflow scope change");
42303
+ assertKnownKeys(
42304
+ value,
42305
+ ["include", "exclude", "modules"],
42306
+ "workflow scope change"
42307
+ );
42308
+ const scope = {
42309
+ source: "explicit",
42310
+ include: normalizeScopeValues(value.include, "include", true),
42311
+ exclude: normalizeScopeValues(value.exclude, "exclude", true),
42312
+ modules: normalizeScopeValues(value.modules, "modules", false)
42313
+ };
42314
+ const included = new Set(scope.include);
42315
+ if (scope.exclude.some((item) => included.has(item))) {
42316
+ throw new Error("MANCODE_SCOPE_INCLUDE_EXCLUDE_CONFLICT");
42317
+ }
42318
+ return { ...scope, digest: digestCanonicalJson(scope) };
42319
+ }
42320
+ function normalizeScopeValues(value, label, paths) {
42321
+ if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || !item.trim())) {
42322
+ throw new Error(`MANCODE_SCOPE_${label.toUpperCase()}_INVALID`);
42323
+ }
42324
+ const values = value.map((item) => item.trim());
42325
+ const normalized = sortUtf8StringSet(values);
42326
+ if (normalized.length !== values.length) {
42327
+ throw new Error(`MANCODE_SCOPE_${label.toUpperCase()}_DUPLICATE`);
42328
+ }
42329
+ for (const item of normalized) {
42330
+ assertSharedTextSafe(item, `workflow scope ${label}`);
42331
+ if (paths) assertScopePath(item);
42332
+ }
42333
+ return normalized;
42334
+ }
42335
+ function assertScopePath(value) {
42336
+ if (value.startsWith("/") || value.startsWith("~") || /^[A-Za-z]:/.test(value) || value.includes("\\") || value.split("/").some((segment) => segment === "" || segment === "." || segment === "..")) {
42337
+ throw new Error("MANCODE_SCOPE_PATH_INVALID");
42338
+ }
42339
+ }
42340
+ function markScopeChangeOperationPending(previous, operationId, updatedAt) {
42341
+ const next = parseWorkflowMetadata({
42342
+ ...previous,
42343
+ revision: previous.revision + 1,
42344
+ transitionState: "operation_pending",
42345
+ lastOperationId: operationId,
42346
+ updatedAt
42347
+ });
42348
+ assertWorkflowMetadataTransition(previous, next, "ordinary");
42349
+ return next;
42350
+ }
42351
+ function completeScopeChangeMetadata(previous, scope, checkpoint, reviewLedgerDigest2, verificationLedgerDigest2, operationId, updatedAt) {
42352
+ const next = parseWorkflowMetadata({
42353
+ ...previous,
42354
+ revision: previous.revision + 1,
42355
+ transitionState: "stable",
42356
+ implementationScope: scope,
42357
+ governance: {
42358
+ ...previous.governance,
42359
+ planVersion: previous.governance.planVersion + 1,
42360
+ reviewStatus: "stale",
42361
+ reviewLedgerDigest: reviewLedgerDigest2,
42362
+ verificationStatus: "stale",
42363
+ verificationLedgerDigest: verificationLedgerDigest2
42364
+ },
42365
+ latestCheckpointRef: {
42366
+ taskRef: checkpoint.taskRef,
42367
+ kind: "checkpoint",
42368
+ artifactId: checkpoint.checkpointId
42369
+ },
42370
+ lastOperationId: operationId,
42371
+ updatedAt
42372
+ });
42373
+ assertWorkflowMetadataTransition(previous, next, "ordinary");
42374
+ return next;
42375
+ }
42376
+ function buildScopeChangedCheckpoint(context, pendingMetadata, checkpointId, summary, nextAction, branch, planVersion, reviewLedgerDigest2, verificationLedgerDigest2, timestamp4) {
42377
+ return parseCheckpoint({
42378
+ schemaVersion: 1,
42379
+ checkpointId,
42380
+ operationId: context.operationId,
42381
+ taskRef: context.taskRef,
42382
+ taskRevision: pendingMetadata.revision,
42383
+ ownershipEpochAtOffer: pendingMetadata.ownershipEpoch,
42384
+ kind: "scope_changed",
42385
+ git: {
42386
+ branch,
42387
+ head: requireCodeHead3(context),
42388
+ base: pendingMetadata.base?.head ?? null
42389
+ },
42390
+ summary: summary ?? "Changed the implementation scope and replaced affected coordination claims.",
42391
+ governance: {
42392
+ requirementsDigest: context.task.requirements.contentDigest,
42393
+ planVersion,
42394
+ reviewLedgerDigest: reviewLedgerDigest2,
42395
+ verificationLedgerDigest: verificationLedgerDigest2
42396
+ },
42397
+ nextAction: nextAction ?? "Re-read the updated scope and continue only with the successor claim.",
42398
+ createdBy: {
42399
+ actorId: context.session.actorId,
42400
+ client: context.session.client
42401
+ },
42402
+ createdAt: timestamp4
42403
+ });
42404
+ }
42405
+ function buildPendingSuccessorClaims2(predecessors, successorClaimIds, metadata, branch, codeHead, operationId, timestamp4, capabilities) {
42406
+ return predecessors.map((previous, index) => {
42407
+ const claimId = successorClaimIds[index];
42408
+ if (claimId === void 0) {
42409
+ throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
42410
+ }
42411
+ return parseClaim({
42412
+ ...previous,
42413
+ claimId,
42414
+ authority: { mode: "local", remoteRevision: null },
42415
+ taskRevisionAtAcquire: metadata.revision,
42416
+ lastValidatedTaskRevision: metadata.revision,
42417
+ implementationScopeDigest: metadata.implementationScope.digest,
42418
+ ownershipEpochAtAcquire: metadata.ownershipEpoch,
42419
+ state: "pending",
42420
+ revision: 1,
42421
+ codeRefAtAcquire: { branch, head: codeHead },
42422
+ lastValidatedCodeRef: { branch, head: codeHead },
42423
+ acquisitionEnforcement: capabilities.claimAcquisition,
42424
+ writeGuard: capabilities.writeGuard,
42425
+ predecessorClaimId: previous.claimId,
42426
+ successorClaimId: null,
42427
+ lastOperationId: operationId,
42428
+ createdAt: timestamp4,
42429
+ updatedAt: timestamp4
42430
+ });
42431
+ });
42432
+ }
42433
+ function terminateClaimForScopeChange(previous, successorClaimId, operationId, timestamp4) {
42434
+ const next = parseClaim({
42435
+ ...previous,
42436
+ state: successorClaimId === null ? "released" : "transferred",
42437
+ revision: previous.revision + 1,
42438
+ successorClaimId,
42439
+ lastOperationId: operationId,
42440
+ updatedAt: timestamp4
42441
+ });
42442
+ assertClaimTransition(previous, next);
42443
+ return next;
42444
+ }
42445
+ function activateSuccessorClaim3(previous, operationId, timestamp4) {
42446
+ const next = parseClaim({
42447
+ ...previous,
42448
+ state: "active",
42449
+ revision: previous.revision + 1,
42450
+ lastOperationId: operationId,
42451
+ updatedAt: timestamp4
42452
+ });
42453
+ assertClaimTransition(previous, next);
42454
+ return next;
42455
+ }
42456
+ function scopeChangeExpectedRevisions(context, checkpointId, predecessors, successorClaimIds) {
42457
+ const expected = {
42458
+ [taskEntityKey(context.taskRef)]: context.task.metadata.revision,
42459
+ [`review:${context.taskRef.taskId}`]: context.task.review.revision,
42460
+ [`verification:${context.taskRef.taskId}`]: context.task.verification.revision,
42461
+ [`checkpoint:${checkpointId}`]: 0
42462
+ };
42463
+ for (const claim of predecessors) {
42464
+ expected[`claim:${claim.claimId}`] = claim.revision;
42465
+ }
42466
+ for (const claimId of successorClaimIds) {
42467
+ expected[`claim:${claimId}`] = 0;
42468
+ }
42469
+ const fence = context.coordination.taskHeadFence;
42470
+ if (fence === null) throw new Error("MANCODE_TASK_HEAD_FENCE_MISSING");
42471
+ expected[taskHeadEntityKey(context.taskRef)] = fence.fenceRevision;
42472
+ return expected;
42473
+ }
42474
+ function activeClaims(claims) {
42475
+ return claims.filter((claim) => claim.state === "active").sort((left, right) => compareUtf815(left.claimId, right.claimId));
42476
+ }
42477
+ function claimsWithinScope(claims, scope) {
42478
+ return claims.filter(
42479
+ (claim) => evaluateClaimScopeSubset(claim.scope, {
42480
+ source: scope.source,
42481
+ include: scope.include,
42482
+ exclude: scope.exclude,
42483
+ modules: scope.modules
42484
+ }).allowed
42485
+ );
42486
+ }
42487
+ function resolveSuccessorClaimIds2(predecessors, requested, operationId, timestamp4) {
42488
+ const ids = requested ?? predecessors.map(
42489
+ (claim) => scopeSuccessorClaimId(operationId, claim.claimId, timestamp4)
42490
+ );
42491
+ if (ids.length !== predecessors.length) {
42492
+ throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
42493
+ }
42494
+ const predecessorIds = new Set(predecessors.map((claim) => claim.claimId));
42495
+ const seen = /* @__PURE__ */ new Set();
42496
+ for (const claimId of ids) {
42497
+ assertUlid(claimId, "scope successor claimId");
42498
+ if (predecessorIds.has(claimId) || seen.has(claimId)) {
42499
+ throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_INVALID");
42500
+ }
42501
+ seen.add(claimId);
42502
+ }
42503
+ return ids;
42504
+ }
42505
+ function scopeSuccessorClaimId(operationId, predecessorClaimId, timestamp4) {
42506
+ assertUlid(operationId, "scope change operationId");
42507
+ assertUlid(predecessorClaimId, "scope predecessor claimId");
42508
+ const milliseconds = Date.parse(timestamp4);
42509
+ if (Number.isNaN(milliseconds)) {
42510
+ throw new Error("MANCODE_SCOPE_TIMESTAMP_INVALID");
42511
+ }
42512
+ const entropy = createHash11("sha256").update(`scope-change:${operationId}:${predecessorClaimId}`, "utf8").digest().subarray(0, 10);
42513
+ return createUlid(milliseconds, entropy);
42514
+ }
42515
+ function requireCodeHead3(context) {
42516
+ if (context.codeHead === null) {
42517
+ throw new Error("MANCODE_TASK_HEAD_CODE_REF_UNAVAILABLE");
42518
+ }
42519
+ return context.codeHead;
42520
+ }
42521
+ function sameClaimIdSet(left, right) {
42522
+ return left.length === right.length && left.every((claim, index) => claim.claimId === right[index]?.claimId);
42523
+ }
42524
+ function compareUtf815(left, right) {
42525
+ return Buffer.from(left, "utf8").compare(Buffer.from(right, "utf8"));
42526
+ }
42527
+
42528
+ // src/context/plan-revision.ts
42529
+ async function reviseV3Plan(input) {
42530
+ const taskRef = parseTaskRefValue(input.taskRef);
42531
+ const plan = requirePlan(input.plan);
42532
+ const planDecision = parsePlanDecision(input.planDecision);
42533
+ const submittedScope = input.implementationScope === void 0 ? null : normalizeImplementationScope(input.implementationScope);
42534
+ if (taskRef.namespace === "shared") {
42535
+ assertSharedTextSafe(plan, "plan");
42536
+ }
42537
+ const context = await openV3TaskOperation({
42538
+ projectRoot: input.projectRoot,
42539
+ taskRef,
42540
+ sessionId: input.sessionId,
42541
+ expectedTaskRevision: input.expectedTaskRevision,
42542
+ operationId: input.operationId,
42543
+ extraEntityLocks: taskRef.namespace === "shared" ? [taskHeadEntityKey(taskRef)] : [],
42544
+ now: input.now
42545
+ });
42546
+ let journal = null;
42547
+ try {
42548
+ const planChanged = context.task.plan?.content !== plan;
42549
+ const executionScopeBinding = assertExecutionScopeBindingAttempt({
42550
+ metadata: context.task.metadata,
42551
+ currentPlan: context.task.plan?.content ?? null,
42552
+ submittedPlan: plan,
42553
+ submittedScope,
42554
+ planDecisionSupplied: input.planDecision !== void 0,
42555
+ sessionActorId: context.session.actorId
42556
+ });
42557
+ assertPlanRevisionEligible(
42558
+ context.task.metadata,
42559
+ context.task.requirements,
42560
+ executionScopeBinding
42561
+ );
42562
+ const implementationScope = submittedScope ?? context.task.metadata.implementationScope;
42563
+ const scopeChanged = submittedScope !== null && submittedScope.digest !== context.task.metadata.implementationScope.digest;
42564
+ if (planDecision === "governed_execution") {
42565
+ assertExecutableImplementationScope(implementationScope);
42566
+ }
42567
+ if (executionScopeBinding) {
42568
+ assertExecutableImplementationScope(implementationScope);
42569
+ }
42570
+ if (context.task.metadata.workflowMode === "manteam" && planDecision === "governed_execution") {
42571
+ assertManteamPlanContent(plan);
42572
+ }
42573
+ if (context.task.plan?.content === plan && planDecision === null && !scopeChanged) {
42574
+ throw new Error("MANCODE_PLAN_CONTENT_UNCHANGED");
42575
+ }
42576
+ const authorityChanged = planChanged || scopeChanged;
42577
+ const timestamp4 = context.now.toISOString();
42578
+ const planDigest = planChanged ? digestCanonicalJson({
42579
+ artifactRef: { taskRef, kind: "plan" },
42580
+ content: plan
42581
+ }) : context.task.plan?.digest;
42582
+ if (planDigest === void 0) {
42583
+ throw new Error("MANCODE_PLAN_FILE_REQUIRED");
42584
+ }
42585
+ const review = authorityChanged ? markTaskReviewStale(context.task.review, context.operationId, timestamp4) : context.task.review;
42586
+ const verification = authorityChanged ? markTaskVerificationStale(
42587
+ context.task.verification,
42588
+ context.operationId,
42589
+ timestamp4
42590
+ ) : context.task.verification;
42591
+ const metadata = updateMetadata(
42592
+ context.task.metadata,
42593
+ context.task.requirements,
42594
+ review,
42595
+ verification,
42596
+ implementationScope,
42597
+ authorityChanged,
42598
+ planDecision,
42599
+ executionScopeBinding,
42600
+ context.operationId,
42601
+ timestamp4
42602
+ );
42603
+ const aggregate = buildTaskAggregateManifest({
42604
+ metadata,
42605
+ requirements: context.task.requirements,
42606
+ review,
42607
+ verification,
42608
+ planDigest,
42609
+ latestCheckpoint: context.task.latestCheckpoint
42610
+ });
42611
+ const taskHeadFence = nextTaskHeadFence(context, aggregate, timestamp4);
42612
+ if (planDecision === "plan_only") {
42613
+ await enqueueSessionPointerProjection(context.projectRoot, {
42614
+ operationId: context.operationId,
42615
+ action: "clear",
42616
+ sessionId: context.session.sessionId,
42617
+ expectedPreviousTaskRef: context.session.activeTaskRef,
42618
+ taskRef,
42619
+ workflowMode: metadata.workflowMode,
42620
+ taskRevision: metadata.revision,
42621
+ now: context.now
42622
+ });
42623
+ }
42624
+ journal = await createTaskOperationJournal(context, {
42625
+ type: "plan_revision",
42626
+ action: taskRef.namespace === "shared" ? "shared_metadata_plan_mutation" : "local_workflow_mutation",
42627
+ expectedRevisions: taskMutationExpectedRevisions(context, [
42628
+ "plan",
42629
+ "review",
42630
+ "verification"
42631
+ ]),
42632
+ recovery: {
42633
+ actions: [
42634
+ ...planChanged ? [
42635
+ createTaskAuthorityFileRecoveryAction({
42636
+ stepId: "write-plan",
42637
+ taskRef,
42638
+ fileName: "plan.md",
42639
+ beforeContent: context.task.plan?.content ?? null,
42640
+ targetContent: plan
42641
+ })
42642
+ ] : [],
42643
+ createTaskAuthorityFileRecoveryAction({
42644
+ stepId: "update-metadata",
42645
+ taskRef,
42646
+ fileName: "metadata.json",
42647
+ beforeContent: serializeTaskAuthority(context.task.metadata),
42648
+ targetContent: serializeTaskAuthority(metadata)
42649
+ }),
42650
+ ...authorityChanged ? [
42651
+ createTaskAuthorityFileRecoveryAction({
42652
+ stepId: "mark-review-verification-stale",
42653
+ taskRef,
42654
+ fileName: "review-ledger.json",
42655
+ beforeContent: serializeTaskAuthority(context.task.review),
42656
+ targetContent: serializeTaskAuthority(review)
42657
+ }),
42658
+ createTaskAuthorityFileRecoveryAction({
42659
+ stepId: "mark-review-verification-stale",
42660
+ taskRef,
42661
+ fileName: "verification-ledger.json",
42662
+ beforeContent: serializeTaskAuthority(
42663
+ context.task.verification
42664
+ ),
42665
+ targetContent: serializeTaskAuthority(verification)
42666
+ })
42667
+ ] : [],
42668
+ ...taskHeadFence === null ? [] : [
42669
+ createTaskHeadFenceRecoveryAction({
42670
+ stepId: "update-task-head-fence",
42671
+ before: context.coordination.taskHeadFence,
42672
+ fence: taskHeadFence
42673
+ })
42674
+ ]
42675
+ ],
42676
+ noOpStepIds: [
42677
+ ...planChanged ? [] : ["write-plan"],
42678
+ ...authorityChanged ? [] : ["mark-review-verification-stale"],
42679
+ ...taskHeadFence === null ? ["update-task-head-fence"] : []
42680
+ ]
42681
+ }
42682
+ });
42683
+ journal = await advanceTaskOperation(context, journal, "validate", true);
42684
+ journal = await advanceTaskOperation(context, journal, "write-plan", false);
42685
+ if (planChanged) {
42686
+ await writeTaskAuthorityFile(context, "plan.md", plan);
42687
+ }
42688
+ journal = await advanceTaskOperation(
42689
+ context,
42690
+ journal,
42691
+ "update-metadata",
42692
+ false
42693
+ );
42694
+ await writeTaskAuthorityFile(
42695
+ context,
42696
+ "metadata.json",
42697
+ `${JSON.stringify(metadata, null, 2)}
42698
+ `
42699
+ );
42700
+ journal = await advanceTaskOperation(
42701
+ context,
42702
+ journal,
42703
+ "mark-review-verification-stale",
42704
+ false
42705
+ );
42706
+ if (authorityChanged) {
42707
+ await writeTaskAuthorityFile(
42708
+ context,
42709
+ "review-ledger.json",
42710
+ `${JSON.stringify(review, null, 2)}
42711
+ `
42712
+ );
42713
+ await writeTaskAuthorityFile(
42714
+ context,
42715
+ "verification-ledger.json",
42716
+ `${JSON.stringify(verification, null, 2)}
42717
+ `
42718
+ );
42719
+ }
42720
+ journal = await advanceTaskOperation(
42721
+ context,
42722
+ journal,
42723
+ "update-task-head-fence",
42724
+ false
42725
+ );
42726
+ if (taskHeadFence !== null) {
42727
+ await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
42728
+ await replaceTaskHeadFence(context.homeStore, taskHeadFence);
42729
+ }
42730
+ const operation = await commitTaskOperation(context, journal);
42731
+ if (planDecision === "plan_only") {
42732
+ try {
42733
+ await reconcileProjectionIntents(
42734
+ context.projectRoot,
42735
+ context.operationId,
42736
+ context.now
42737
+ );
42738
+ } catch {
42739
+ }
42740
+ }
42741
+ return {
42742
+ metadata,
42743
+ review,
42744
+ verification,
42745
+ planDigest,
42746
+ aggregate,
42747
+ taskHeadFence,
42748
+ operation
42749
+ };
42750
+ } catch (error) {
42751
+ if (journal !== null) {
42752
+ try {
42753
+ await handleTaskOperationFailure(context, journal);
42754
+ } catch {
42755
+ }
42756
+ }
42757
+ throw error;
42758
+ } finally {
42759
+ await context.release();
42760
+ }
42761
+ }
42762
+ function requirePlan(value) {
42763
+ if (typeof value !== "string" || !value.trim() || value.includes("\0")) {
42764
+ throw new Error("MANCODE_PLAN_CONTENT_REQUIRED");
42765
+ }
42766
+ return value;
42767
+ }
42768
+ function parsePlanDecision(value) {
42769
+ if (value === void 0) return null;
42770
+ if (value !== "plan_only" && value !== "governed_execution") {
42771
+ throw new Error("MANCODE_PLAN_DECISION_INVALID");
42772
+ }
42773
+ return value;
42774
+ }
42775
+ function assertPlanRevisionEligible(metadata, requirements, executionScopeBinding) {
42776
+ if (executionScopeBinding) {
42777
+ assertReadyPlanRequirements(metadata, requirements);
42778
+ return;
42779
+ }
42780
+ if (metadata.workflowMode !== "man" && metadata.workflowMode !== "manteam") {
42781
+ throw new Error("MANCODE_PLAN_WORKFLOW_MODE_INVALID");
42782
+ }
42783
+ if (metadata.status !== "in_progress") {
42784
+ throw new Error("MANCODE_PLAN_WORKFLOW_NOT_ACTIVE");
42785
+ }
42786
+ if (metadata.currentStep < 2 || metadata.currentStep > 4) {
42787
+ throw new Error("MANCODE_PLAN_STEP_INVALID");
42788
+ }
42789
+ if (metadata.governance.planDecision !== null) {
42790
+ throw new Error("MANCODE_PLAN_REQUIREMENTS_OR_DECISION_INVALID");
42791
+ }
42792
+ assertReadyPlanRequirements(metadata, requirements);
42793
+ }
42794
+ function assertReadyPlanRequirements(metadata, requirements) {
42795
+ if (metadata.governance.requirementsStatus !== "ready" || metadata.governance.requirementsDigest !== requirements.contentDigest || requirements.status !== "confirmed" || !requirementsAreReady(requirements)) {
42796
+ throw new Error("MANCODE_PLAN_REQUIREMENTS_OR_DECISION_INVALID");
42797
+ }
42798
+ assertRequirementsScopeConsistent(requirements);
42799
+ }
42800
+ function assertExecutionScopeBindingAttempt(input) {
42801
+ const decision = input.metadata.governance.planDecision;
42802
+ if (decision !== "governed_execution" && decision !== "solo_handoff") {
42803
+ return false;
42804
+ }
42805
+ if (input.metadata.workflowMode !== "man" || input.metadata.coordination !== "single" || input.metadata.taskRef.namespace !== "local") {
42806
+ throw new Error("MANCODE_EXECUTION_SCOPE_BINDING_LOCAL_MAN_ONLY");
42807
+ }
42808
+ const activeExecution = decision === "governed_execution" && input.metadata.status === "in_progress" && input.metadata.currentStep >= 5 || decision === "solo_handoff" && input.metadata.status === "planned" && input.metadata.currentStep === 4 && input.metadata.soloExecution?.state === "active";
42809
+ if (!activeExecution) {
42810
+ throw new Error("MANCODE_EXECUTION_SCOPE_BINDING_NOT_ACTIVE");
42811
+ }
42812
+ if (input.metadata.ownerActorId !== input.sessionActorId) {
42813
+ throw new Error("MANCODE_TASK_OWNER_REQUIRED");
42814
+ }
42815
+ if (implementationScopeIsExecutable(input.metadata.implementationScope)) {
42816
+ throw new Error("MANCODE_EXECUTION_SCOPE_ALREADY_BOUND");
42817
+ }
42818
+ if (input.submittedScope === null) {
42819
+ throw new Error("MANCODE_IMPLEMENTATION_SCOPE_REQUIRED");
42820
+ }
42821
+ if (input.currentPlan === null || input.currentPlan !== input.submittedPlan) {
42822
+ throw new Error("MANCODE_EXECUTION_SCOPE_BINDING_PLAN_CHANGED");
42823
+ }
42824
+ if (input.planDecisionSupplied) {
42825
+ throw new Error("MANCODE_EXECUTION_SCOPE_BINDING_DECISION_INVALID");
42826
+ }
42827
+ assertExecutableImplementationScope(input.submittedScope);
42828
+ return true;
42829
+ }
42830
+ function updateMetadata(previous, requirements, review, verification, implementationScope, authorityChanged, planDecision, executionScopeBinding, operationId, updatedAt) {
42831
+ const status2 = executionScopeBinding ? previous.status : planDecision === "plan_only" ? "planned" : "in_progress";
42832
+ const currentStep = executionScopeBinding ? previous.currentStep : planDecision === "governed_execution" ? 5 : 4;
42833
+ const nextPlanVersion = previous.governance.planVersion + (authorityChanged ? 1 : 0);
42834
+ const next = parseWorkflowMetadata({
42835
+ ...previous,
42836
+ status: status2,
42837
+ currentStep,
42838
+ revision: previous.revision + 1,
42839
+ transitionState: "stable",
42840
+ lastOperationId: operationId,
42841
+ implementationScope,
42842
+ governance: {
42843
+ ...previous.governance,
42844
+ requirementsStatus: "ready",
42845
+ requirementsDigest: requirements.contentDigest,
42846
+ planVersion: nextPlanVersion,
42847
+ planDecision: executionScopeBinding ? previous.governance.planDecision : planDecision,
42848
+ reviewStatus: authorityChanged ? "stale" : previous.governance.reviewStatus,
42849
+ reviewLedgerDigest: review.contentDigest,
42850
+ verificationStatus: authorityChanged ? "stale" : previous.governance.verificationStatus,
42851
+ verificationLedgerDigest: verification.contentDigest
42852
+ },
42853
+ soloExecution: executionScopeBinding && previous.soloExecution !== null ? { ...previous.soloExecution, planVersion: nextPlanVersion } : previous.soloExecution,
42854
+ updatedAt
42855
+ });
42856
+ assertWorkflowMetadataTransition(previous, next, "ordinary");
42857
+ return next;
42858
+ }
42859
+
42860
+ // src/context/reframe.ts
42861
+ async function reframeV3Workflow(input) {
42862
+ const taskRef = parseTaskRefValue(input.taskRef);
42863
+ assertUlid(input.checkpointId, "reframe checkpointId");
42864
+ const now = input.now ?? /* @__PURE__ */ new Date();
42095
42865
  const operationId = input.operationId ?? createUlid(now.getTime());
42096
42866
  assertUlid(operationId, "reframe operationId");
42097
42867
  const opened = await openReframeContext({
@@ -42658,6 +43428,9 @@ async function writeV3Requirements(input, action) {
42658
43428
  if (action === "finalize" && submitted.status !== "confirmed") {
42659
43429
  throw new Error("MANCODE_REQUIREMENTS_CONFIRMATION_REQUIRED");
42660
43430
  }
43431
+ if (action === "finalize") {
43432
+ assertRequirementsScopeConsistent(submitted);
43433
+ }
42661
43434
  if (action === "draft" && submitted.status !== "draft") {
42662
43435
  throw new Error("MANCODE_REQUIREMENTS_DRAFT_REQUIRED");
42663
43436
  }
@@ -43128,580 +43901,6 @@ function reviewAuthorization(context, next) {
43128
43901
  };
43129
43902
  }
43130
43903
 
43131
- // src/context/scope-change.ts
43132
- import { createHash as createHash11 } from "crypto";
43133
- async function changeV3WorkflowScope(input) {
43134
- const taskRef = parseTaskRefValue(input.taskRef);
43135
- if (taskRef.namespace !== "shared") {
43136
- throw new Error("MANCODE_SCOPE_CHANGE_REQUIRES_SHARED_TASK");
43137
- }
43138
- const scope = normalizeImplementationScope(input.scope);
43139
- const now = input.now ?? /* @__PURE__ */ new Date();
43140
- const timestamp4 = now.toISOString();
43141
- const checkpointId = input.checkpointId ?? createUlid(now.getTime());
43142
- const operationId = input.operationId ?? createUlid(now.getTime());
43143
- assertUlid(checkpointId, "scope change checkpointId");
43144
- assertUlid(operationId, "scope change operationId");
43145
- const opened = await openScopeChangeContext({
43146
- projectRoot: input.projectRoot,
43147
- taskRef,
43148
- sessionId: input.sessionId,
43149
- expectedTaskRevision: input.expectedTaskRevision,
43150
- scope,
43151
- checkpointId,
43152
- successorClaimIds: input.successorClaimIds,
43153
- operationId,
43154
- now
43155
- });
43156
- const { context, activeClaims: activeClaims2, successorClaimIds, successorPredecessors } = opened;
43157
- let journal = null;
43158
- try {
43159
- assertScopeChangeEligible(context, scope);
43160
- assertClaimsFreshForScopeChange(context, activeClaims2);
43161
- const pendingMetadata = markScopeChangeOperationPending(
43162
- context.task.metadata,
43163
- context.operationId,
43164
- timestamp4
43165
- );
43166
- const branch = await readCheckoutBranch(context.projectRoot) ?? "HEAD";
43167
- const checkpoint = buildScopeChangedCheckpoint(
43168
- context,
43169
- pendingMetadata,
43170
- checkpointId,
43171
- input.checkpointSummary,
43172
- input.checkpointNextAction,
43173
- branch,
43174
- timestamp4
43175
- );
43176
- const metadata = completeScopeChangeMetadata(
43177
- pendingMetadata,
43178
- scope,
43179
- checkpoint,
43180
- context.operationId,
43181
- timestamp4
43182
- );
43183
- const pendingSuccessorClaims = buildPendingSuccessorClaims2(
43184
- successorPredecessors,
43185
- successorClaimIds,
43186
- metadata,
43187
- branch,
43188
- requireCodeHead3(context),
43189
- context.operationId,
43190
- timestamp4,
43191
- capabilitiesFromProjectConfig(context.project.config)
43192
- );
43193
- const successorByPredecessor = new Map(
43194
- successorPredecessors.map((claim, index) => {
43195
- const successorClaimId = successorClaimIds[index];
43196
- if (successorClaimId === void 0) {
43197
- throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
43198
- }
43199
- return [claim.claimId, successorClaimId];
43200
- })
43201
- );
43202
- const terminatedClaims = activeClaims2.map(
43203
- (claim) => terminateClaimForScopeChange(
43204
- claim,
43205
- successorByPredecessor.get(claim.claimId) ?? null,
43206
- context.operationId,
43207
- timestamp4
43208
- )
43209
- );
43210
- const activeSuccessorClaims = pendingSuccessorClaims.map(
43211
- (claim) => activateSuccessorClaim3(claim, context.operationId, timestamp4)
43212
- );
43213
- const aggregate = buildTaskAggregateManifest({
43214
- metadata,
43215
- requirements: context.task.requirements,
43216
- review: context.task.review,
43217
- verification: context.task.verification,
43218
- planDigest: context.task.plan?.digest ?? null,
43219
- latestCheckpoint: checkpoint
43220
- });
43221
- const taskHeadFence = nextTaskHeadFence(context, aggregate, timestamp4);
43222
- if (taskHeadFence === null) {
43223
- throw new Error("MANCODE_TASK_HEAD_FENCE_MISSING");
43224
- }
43225
- journal = await createTaskOperationJournal(context, {
43226
- type: "scope_change_reclaim",
43227
- action: "task_complete_scope_change_child_merge",
43228
- expectedRevisions: scopeChangeExpectedRevisions(
43229
- context,
43230
- checkpointId,
43231
- activeClaims2,
43232
- successorClaimIds
43233
- ),
43234
- conditions: { completionGateSatisfied: true },
43235
- recovery: {
43236
- actions: [
43237
- createTaskAuthorityFileRecoveryAction({
43238
- stepId: "mark-task-operation-pending",
43239
- taskRef,
43240
- fileName: "metadata.json",
43241
- beforeContent: serializeTaskAuthority(context.task.metadata),
43242
- targetContent: serializeTaskAuthority(pendingMetadata)
43243
- }),
43244
- createCheckpointRecoveryAction({
43245
- stepId: "write-scope-changed-checkpoint",
43246
- before: null,
43247
- checkpoint
43248
- }),
43249
- ...pendingSuccessorClaims.map(
43250
- (claim) => createClaimRecoveryAction({
43251
- stepId: "create-pending-successor-claims",
43252
- before: null,
43253
- claim
43254
- })
43255
- ),
43256
- ...terminatedClaims.map((claim, index) => {
43257
- const before = activeClaims2[index];
43258
- if (before === void 0) {
43259
- throw new Error("MANCODE_CLAIM_SET_CHANGED");
43260
- }
43261
- return createClaimRecoveryAction({
43262
- stepId: "terminate-old-claims",
43263
- before,
43264
- claim
43265
- });
43266
- }),
43267
- createTaskAuthorityFileRecoveryAction({
43268
- stepId: "update-metadata-scope",
43269
- taskRef,
43270
- fileName: "metadata.json",
43271
- beforeContent: serializeTaskAuthority(pendingMetadata),
43272
- targetContent: serializeTaskAuthority(metadata)
43273
- }),
43274
- ...activeSuccessorClaims.map((claim, index) => {
43275
- const before = pendingSuccessorClaims[index];
43276
- if (before === void 0) {
43277
- throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
43278
- }
43279
- return createClaimRecoveryAction({
43280
- stepId: "activate-successor-claims",
43281
- before,
43282
- claim
43283
- });
43284
- }),
43285
- createTaskHeadFenceRecoveryAction({
43286
- stepId: "update-task-head-fence",
43287
- before: context.coordination.taskHeadFence,
43288
- fence: taskHeadFence
43289
- })
43290
- ],
43291
- noOpStepIds: [
43292
- ...pendingSuccessorClaims.length === 0 ? ["create-pending-successor-claims"] : [],
43293
- ...terminatedClaims.length === 0 ? ["terminate-old-claims"] : [],
43294
- ...activeSuccessorClaims.length === 0 ? ["activate-successor-claims"] : []
43295
- ]
43296
- }
43297
- });
43298
- journal = await advanceTaskOperation(context, journal, "validate", true);
43299
- journal = await advanceTaskOperation(
43300
- context,
43301
- journal,
43302
- "mark-task-operation-pending",
43303
- false
43304
- );
43305
- await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
43306
- await writeTaskAuthorityFile(
43307
- context,
43308
- "metadata.json",
43309
- `${JSON.stringify(pendingMetadata, null, 2)}
43310
- `
43311
- );
43312
- journal = await advanceTaskOperation(
43313
- context,
43314
- journal,
43315
- "write-scope-changed-checkpoint",
43316
- false
43317
- );
43318
- await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
43319
- await writeTaskCheckpoint(context, checkpoint);
43320
- journal = await advanceTaskOperation(
43321
- context,
43322
- journal,
43323
- "create-pending-successor-claims",
43324
- false
43325
- );
43326
- await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
43327
- for (const claim of pendingSuccessorClaims) {
43328
- await createClaim(context.homeStore, claim);
43329
- }
43330
- journal = await advanceTaskOperation(
43331
- context,
43332
- journal,
43333
- "terminate-old-claims",
43334
- false
43335
- );
43336
- await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
43337
- for (const [index, claim] of terminatedClaims.entries()) {
43338
- const previous = activeClaims2[index];
43339
- if (previous === void 0) {
43340
- throw new Error("MANCODE_CLAIM_SET_CHANGED");
43341
- }
43342
- await updateClaim(context.homeStore, claim, previous.revision);
43343
- }
43344
- journal = await advanceTaskOperation(
43345
- context,
43346
- journal,
43347
- "update-metadata-scope",
43348
- false
43349
- );
43350
- await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
43351
- await writeTaskAuthorityFile(
43352
- context,
43353
- "metadata.json",
43354
- `${JSON.stringify(metadata, null, 2)}
43355
- `
43356
- );
43357
- journal = await advanceTaskOperation(
43358
- context,
43359
- journal,
43360
- "activate-successor-claims",
43361
- false
43362
- );
43363
- await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
43364
- for (const claim of activeSuccessorClaims) {
43365
- await updateClaim(context.homeStore, claim, 1);
43366
- }
43367
- journal = await advanceTaskOperation(
43368
- context,
43369
- journal,
43370
- "update-task-head-fence",
43371
- false
43372
- );
43373
- await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
43374
- await replaceTaskHeadFence(context.homeStore, taskHeadFence);
43375
- const operation = await commitTaskOperation(context, journal);
43376
- return {
43377
- metadata,
43378
- checkpoint,
43379
- terminatedClaims,
43380
- successorClaims: activeSuccessorClaims,
43381
- aggregate,
43382
- taskHeadFence,
43383
- operation
43384
- };
43385
- } catch (error) {
43386
- if (journal !== null) {
43387
- try {
43388
- await handleTaskOperationFailure(context, journal);
43389
- } catch {
43390
- }
43391
- }
43392
- throw error;
43393
- } finally {
43394
- await context.release();
43395
- }
43396
- }
43397
- async function openScopeChangeContext(input) {
43398
- for (let attempt = 0; attempt < 3; attempt += 1) {
43399
- const runtime = await readProjectRuntimeContext(input.projectRoot);
43400
- const store = new V3ContextStore(input.projectRoot);
43401
- const homeStore = resolveTaskEntityHomeStore(
43402
- runtime.entityHomeStoreContext,
43403
- input.taskRef
43404
- );
43405
- const preflight = await store.readCoordinationSnapshot(
43406
- input.taskRef,
43407
- homeStore
43408
- );
43409
- const preflightClaims = activeClaims(preflight.claims);
43410
- const preflightSuccessors = claimsWithinScope(preflightClaims, input.scope);
43411
- const preflightSuccessorIds = resolveSuccessorClaimIds2(
43412
- preflightSuccessors,
43413
- input.successorClaimIds,
43414
- input.operationId,
43415
- input.now.toISOString()
43416
- );
43417
- const context = await openV3TaskOperation({
43418
- projectRoot: input.projectRoot,
43419
- taskRef: input.taskRef,
43420
- sessionId: input.sessionId,
43421
- expectedTaskRevision: input.expectedTaskRevision,
43422
- operationId: input.operationId,
43423
- extraEntityLocks: [
43424
- `checkpoint:${input.checkpointId}`,
43425
- taskHeadEntityKey(input.taskRef),
43426
- ...preflightClaims.map((claim) => `claim:${claim.claimId}`),
43427
- ...preflightSuccessorIds.map((claimId) => `claim:${claimId}`)
43428
- ],
43429
- now: input.now
43430
- });
43431
- const lockedClaims = activeClaims(context.coordination.claims);
43432
- if (sameClaimIdSet(preflightClaims, lockedClaims)) {
43433
- const successors = claimsWithinScope(lockedClaims, input.scope);
43434
- const successorIds = resolveSuccessorClaimIds2(
43435
- successors,
43436
- input.successorClaimIds,
43437
- input.operationId,
43438
- input.now.toISOString()
43439
- );
43440
- return {
43441
- context,
43442
- activeClaims: lockedClaims,
43443
- successorPredecessors: successors,
43444
- successorClaimIds: successorIds
43445
- };
43446
- }
43447
- await context.release();
43448
- }
43449
- throw new Error("MANCODE_CLAIM_SET_CHANGED");
43450
- }
43451
- function assertScopeChangeEligible(context, scope) {
43452
- const metadata = context.task.metadata;
43453
- if (context.project.config.transport.mode !== "local") {
43454
- throw new Error("MANCODE_GIT_REF_TRANSPORT_NOT_IMPLEMENTED");
43455
- }
43456
- if (metadata.workflowMode !== "manteam") {
43457
- throw new Error("MANCODE_SCOPE_CHANGE_WORKFLOW_MODE_INVALID");
43458
- }
43459
- if (metadata.status !== "in_progress") {
43460
- throw new Error("MANCODE_SCOPE_CHANGE_WORKFLOW_NOT_ACTIVE");
43461
- }
43462
- if (metadata.ownerActorId !== context.session.actorId) {
43463
- throw new Error("MANCODE_TASK_OWNER_REQUIRED");
43464
- }
43465
- if (metadata.parent !== null) {
43466
- throw new Error("MANCODE_PARENT_SCOPE_INHERITANCE_REQUIRED");
43467
- }
43468
- if (metadata.implementationScope.digest === scope.digest) {
43469
- throw new Error("MANCODE_SCOPE_CHANGE_NOOP");
43470
- }
43471
- }
43472
- function assertClaimsFreshForScopeChange(context, claims) {
43473
- const codeHead = requireCodeHead3(context);
43474
- for (const claim of claims) {
43475
- if (claim.authority.mode !== "local") {
43476
- throw new Error("MANCODE_OPERATION_REPAIR_REQUIRED");
43477
- }
43478
- const validity = deriveClaimValidity(claim, {
43479
- taskRef: context.taskRef,
43480
- taskRevision: context.task.metadata.revision,
43481
- implementationScopeDigest: context.task.metadata.implementationScope.digest,
43482
- ownershipEpoch: context.task.metadata.ownershipEpoch,
43483
- codeRefHead: codeHead,
43484
- now: context.now,
43485
- transportFreshness: "fresh"
43486
- });
43487
- if (validity !== "fresh") {
43488
- throw new Error("MANCODE_CLAIM_REVALIDATION_REQUIRED");
43489
- }
43490
- }
43491
- }
43492
- function normalizeImplementationScope(value) {
43493
- assertRecord(value, "workflow scope change");
43494
- assertKnownKeys(
43495
- value,
43496
- ["include", "exclude", "modules"],
43497
- "workflow scope change"
43498
- );
43499
- const scope = {
43500
- source: "explicit",
43501
- include: normalizeScopeValues(value.include, "include", true),
43502
- exclude: normalizeScopeValues(value.exclude, "exclude", true),
43503
- modules: normalizeScopeValues(value.modules, "modules", false)
43504
- };
43505
- return { ...scope, digest: digestCanonicalJson(scope) };
43506
- }
43507
- function normalizeScopeValues(value, label, paths) {
43508
- if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || !item.trim())) {
43509
- throw new Error(`MANCODE_SCOPE_${label.toUpperCase()}_INVALID`);
43510
- }
43511
- const values = value.map((item) => item.trim());
43512
- const normalized = sortUtf8StringSet(values);
43513
- if (normalized.length !== values.length) {
43514
- throw new Error(`MANCODE_SCOPE_${label.toUpperCase()}_DUPLICATE`);
43515
- }
43516
- for (const item of normalized) {
43517
- assertSharedTextSafe(item, `workflow scope ${label}`);
43518
- if (paths) assertScopePath(item);
43519
- }
43520
- return normalized;
43521
- }
43522
- function assertScopePath(value) {
43523
- if (value.startsWith("/") || value.startsWith("~") || /^[A-Za-z]:/.test(value) || value.includes("\\") || value.split("/").some((segment) => segment === "" || segment === "." || segment === "..")) {
43524
- throw new Error("MANCODE_SCOPE_PATH_INVALID");
43525
- }
43526
- }
43527
- function markScopeChangeOperationPending(previous, operationId, updatedAt) {
43528
- const next = parseWorkflowMetadata({
43529
- ...previous,
43530
- revision: previous.revision + 1,
43531
- transitionState: "operation_pending",
43532
- lastOperationId: operationId,
43533
- updatedAt
43534
- });
43535
- assertWorkflowMetadataTransition(previous, next, "ordinary");
43536
- return next;
43537
- }
43538
- function completeScopeChangeMetadata(previous, scope, checkpoint, operationId, updatedAt) {
43539
- const next = parseWorkflowMetadata({
43540
- ...previous,
43541
- revision: previous.revision + 1,
43542
- transitionState: "stable",
43543
- implementationScope: scope,
43544
- latestCheckpointRef: {
43545
- taskRef: checkpoint.taskRef,
43546
- kind: "checkpoint",
43547
- artifactId: checkpoint.checkpointId
43548
- },
43549
- lastOperationId: operationId,
43550
- updatedAt
43551
- });
43552
- assertWorkflowMetadataTransition(previous, next, "ordinary");
43553
- return next;
43554
- }
43555
- function buildScopeChangedCheckpoint(context, pendingMetadata, checkpointId, summary, nextAction, branch, timestamp4) {
43556
- return parseCheckpoint({
43557
- schemaVersion: 1,
43558
- checkpointId,
43559
- operationId: context.operationId,
43560
- taskRef: context.taskRef,
43561
- taskRevision: pendingMetadata.revision,
43562
- ownershipEpochAtOffer: pendingMetadata.ownershipEpoch,
43563
- kind: "scope_changed",
43564
- git: {
43565
- branch,
43566
- head: requireCodeHead3(context),
43567
- base: pendingMetadata.base?.head ?? null
43568
- },
43569
- summary: summary ?? "Changed the implementation scope and replaced affected coordination claims.",
43570
- governance: {
43571
- requirementsDigest: context.task.requirements.contentDigest,
43572
- planVersion: pendingMetadata.governance.planVersion,
43573
- reviewLedgerDigest: context.task.review.contentDigest,
43574
- verificationLedgerDigest: context.task.verification.contentDigest
43575
- },
43576
- nextAction: nextAction ?? "Re-read the updated scope and continue only with the successor claim.",
43577
- createdBy: {
43578
- actorId: context.session.actorId,
43579
- client: context.session.client
43580
- },
43581
- createdAt: timestamp4
43582
- });
43583
- }
43584
- function buildPendingSuccessorClaims2(predecessors, successorClaimIds, metadata, branch, codeHead, operationId, timestamp4, capabilities) {
43585
- return predecessors.map((previous, index) => {
43586
- const claimId = successorClaimIds[index];
43587
- if (claimId === void 0) {
43588
- throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
43589
- }
43590
- return parseClaim({
43591
- ...previous,
43592
- claimId,
43593
- authority: { mode: "local", remoteRevision: null },
43594
- taskRevisionAtAcquire: metadata.revision,
43595
- lastValidatedTaskRevision: metadata.revision,
43596
- implementationScopeDigest: metadata.implementationScope.digest,
43597
- ownershipEpochAtAcquire: metadata.ownershipEpoch,
43598
- state: "pending",
43599
- revision: 1,
43600
- codeRefAtAcquire: { branch, head: codeHead },
43601
- lastValidatedCodeRef: { branch, head: codeHead },
43602
- acquisitionEnforcement: capabilities.claimAcquisition,
43603
- writeGuard: capabilities.writeGuard,
43604
- predecessorClaimId: previous.claimId,
43605
- successorClaimId: null,
43606
- lastOperationId: operationId,
43607
- createdAt: timestamp4,
43608
- updatedAt: timestamp4
43609
- });
43610
- });
43611
- }
43612
- function terminateClaimForScopeChange(previous, successorClaimId, operationId, timestamp4) {
43613
- const next = parseClaim({
43614
- ...previous,
43615
- state: successorClaimId === null ? "released" : "transferred",
43616
- revision: previous.revision + 1,
43617
- successorClaimId,
43618
- lastOperationId: operationId,
43619
- updatedAt: timestamp4
43620
- });
43621
- assertClaimTransition(previous, next);
43622
- return next;
43623
- }
43624
- function activateSuccessorClaim3(previous, operationId, timestamp4) {
43625
- const next = parseClaim({
43626
- ...previous,
43627
- state: "active",
43628
- revision: previous.revision + 1,
43629
- lastOperationId: operationId,
43630
- updatedAt: timestamp4
43631
- });
43632
- assertClaimTransition(previous, next);
43633
- return next;
43634
- }
43635
- function scopeChangeExpectedRevisions(context, checkpointId, predecessors, successorClaimIds) {
43636
- const expected = {
43637
- [taskEntityKey(context.taskRef)]: context.task.metadata.revision,
43638
- [`checkpoint:${checkpointId}`]: 0
43639
- };
43640
- for (const claim of predecessors) {
43641
- expected[`claim:${claim.claimId}`] = claim.revision;
43642
- }
43643
- for (const claimId of successorClaimIds) {
43644
- expected[`claim:${claimId}`] = 0;
43645
- }
43646
- const fence = context.coordination.taskHeadFence;
43647
- if (fence === null) throw new Error("MANCODE_TASK_HEAD_FENCE_MISSING");
43648
- expected[taskHeadEntityKey(context.taskRef)] = fence.fenceRevision;
43649
- return expected;
43650
- }
43651
- function activeClaims(claims) {
43652
- return claims.filter((claim) => claim.state === "active").sort((left, right) => compareUtf815(left.claimId, right.claimId));
43653
- }
43654
- function claimsWithinScope(claims, scope) {
43655
- return claims.filter(
43656
- (claim) => evaluateClaimScopeSubset(claim.scope, {
43657
- source: scope.source,
43658
- include: scope.include,
43659
- exclude: scope.exclude,
43660
- modules: scope.modules
43661
- }).allowed
43662
- );
43663
- }
43664
- function resolveSuccessorClaimIds2(predecessors, requested, operationId, timestamp4) {
43665
- const ids = requested ?? predecessors.map(
43666
- (claim) => scopeSuccessorClaimId(operationId, claim.claimId, timestamp4)
43667
- );
43668
- if (ids.length !== predecessors.length) {
43669
- throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
43670
- }
43671
- const predecessorIds = new Set(predecessors.map((claim) => claim.claimId));
43672
- const seen = /* @__PURE__ */ new Set();
43673
- for (const claimId of ids) {
43674
- assertUlid(claimId, "scope successor claimId");
43675
- if (predecessorIds.has(claimId) || seen.has(claimId)) {
43676
- throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_INVALID");
43677
- }
43678
- seen.add(claimId);
43679
- }
43680
- return ids;
43681
- }
43682
- function scopeSuccessorClaimId(operationId, predecessorClaimId, timestamp4) {
43683
- assertUlid(operationId, "scope change operationId");
43684
- assertUlid(predecessorClaimId, "scope predecessor claimId");
43685
- const milliseconds = Date.parse(timestamp4);
43686
- if (Number.isNaN(milliseconds)) {
43687
- throw new Error("MANCODE_SCOPE_TIMESTAMP_INVALID");
43688
- }
43689
- const entropy = createHash11("sha256").update(`scope-change:${operationId}:${predecessorClaimId}`, "utf8").digest().subarray(0, 10);
43690
- return createUlid(milliseconds, entropy);
43691
- }
43692
- function requireCodeHead3(context) {
43693
- if (context.codeHead === null) {
43694
- throw new Error("MANCODE_TASK_HEAD_CODE_REF_UNAVAILABLE");
43695
- }
43696
- return context.codeHead;
43697
- }
43698
- function sameClaimIdSet(left, right) {
43699
- return left.length === right.length && left.every((claim, index) => claim.claimId === right[index]?.claimId);
43700
- }
43701
- function compareUtf815(left, right) {
43702
- return Buffer.from(left, "utf8").compare(Buffer.from(right, "utf8"));
43703
- }
43704
-
43705
43904
  // src/context/solo-handoff.ts
43706
43905
  async function startV3SoloHandoff(input) {
43707
43906
  const taskRef = assertLocalTaskRef(input.taskRef);
@@ -43949,6 +44148,8 @@ function assertSoloStartEligible(context) {
43949
44148
  if (metadata.workflowMode !== "man" || metadata.coordination !== "single" || metadata.status !== "in_progress" || metadata.currentStep !== 4 || metadata.governance.planDecision !== null || metadata.soloExecution !== null || metadata.ownerActorId !== context.session.actorId || plan === null || requirements.status !== "confirmed" || !requirementsAreReady(requirements) || metadata.governance.requirementsStatus !== "ready" || metadata.governance.requirementsDigest !== requirements.contentDigest) {
43950
44149
  throw new Error("MANCODE_SOLO_HANDOFF_NOT_ELIGIBLE");
43951
44150
  }
44151
+ assertRequirementsScopeConsistent(requirements);
44152
+ assertExecutableImplementationScope(metadata.implementationScope);
43952
44153
  }
43953
44154
  function assertSoloCompletionEligible(context) {
43954
44155
  const { metadata } = context.task;
@@ -45237,11 +45438,20 @@ function initialScope(parent, explicitScope) {
45237
45438
  };
45238
45439
  return { ...inherited, digest: digestCanonicalJson(inherited) };
45239
45440
  }
45441
+ if (explicitScope === void 0) {
45442
+ const unspecified = {
45443
+ source: "legacy_unspecified",
45444
+ include: [],
45445
+ exclude: [],
45446
+ modules: []
45447
+ };
45448
+ return { ...unspecified, digest: digestCanonicalJson(unspecified) };
45449
+ }
45240
45450
  const explicit = {
45241
45451
  source: "explicit",
45242
- include: [...explicitScope?.include ?? []],
45243
- exclude: [...explicitScope?.exclude ?? []],
45244
- modules: [...explicitScope?.modules ?? []]
45452
+ include: [...explicitScope.include ?? []],
45453
+ exclude: [...explicitScope.exclude ?? []],
45454
+ modules: [...explicitScope.modules ?? []]
45245
45455
  };
45246
45456
  return { ...explicit, digest: digestCanonicalJson(explicit) };
45247
45457
  }
@@ -45703,10 +45913,22 @@ async function changeGitRefWorkflowScope(input) {
45703
45913
  operationId,
45704
45914
  timestamp4
45705
45915
  );
45916
+ const review = markTaskReviewStale(
45917
+ opened.context.task.review,
45918
+ operationId,
45919
+ timestamp4
45920
+ );
45921
+ const verification = markTaskVerificationStale(
45922
+ opened.context.task.verification,
45923
+ operationId,
45924
+ timestamp4
45925
+ );
45706
45926
  const metadata = scopeChangedMetadata(
45707
45927
  pendingMetadata,
45708
45928
  scope,
45709
45929
  checkpointId,
45930
+ review.contentDigest,
45931
+ verification.contentDigest,
45710
45932
  operationId,
45711
45933
  timestamp4
45712
45934
  );
@@ -45717,6 +45939,9 @@ async function changeGitRefWorkflowScope(input) {
45717
45939
  summary: input.checkpointSummary,
45718
45940
  nextAction: input.checkpointNextAction,
45719
45941
  codeRef: opened.bundle.codeRef,
45942
+ planVersion: pendingMetadata.governance.planVersion + 1,
45943
+ reviewLedgerDigest: review.contentDigest,
45944
+ verificationLedgerDigest: verification.contentDigest,
45720
45945
  timestamp: timestamp4
45721
45946
  });
45722
45947
  const finalMetadata = parseWorkflowMetadata({
@@ -45730,8 +45955,8 @@ async function changeGitRefWorkflowScope(input) {
45730
45955
  const aggregate = buildTaskAggregateManifest({
45731
45956
  metadata: finalMetadata,
45732
45957
  requirements: opened.context.task.requirements,
45733
- review: opened.context.task.review,
45734
- verification: opened.context.task.verification,
45958
+ review,
45959
+ verification,
45735
45960
  planDigest: opened.context.task.plan?.digest ?? null,
45736
45961
  latestCheckpoint: checkpoint
45737
45962
  });
@@ -45754,6 +45979,8 @@ async function changeGitRefWorkflowScope(input) {
45754
45979
  task: {
45755
45980
  ...opened.context.task,
45756
45981
  metadata: finalMetadata,
45982
+ review,
45983
+ verification,
45757
45984
  latestCheckpoint: checkpoint,
45758
45985
  aggregate
45759
45986
  },
@@ -46173,12 +46400,20 @@ function assertClaimsFresh(context, bundle, claims) {
46173
46400
  }
46174
46401
  }
46175
46402
  }
46176
- function scopeChangedMetadata(previous, scope, checkpointId, operationId, updatedAt) {
46403
+ function scopeChangedMetadata(previous, scope, checkpointId, reviewLedgerDigest2, verificationLedgerDigest2, operationId, updatedAt) {
46177
46404
  const next = parseWorkflowMetadata({
46178
46405
  ...previous,
46179
46406
  revision: previous.revision + 1,
46180
46407
  transitionState: "stable",
46181
46408
  implementationScope: scope,
46409
+ governance: {
46410
+ ...previous.governance,
46411
+ planVersion: previous.governance.planVersion + 1,
46412
+ reviewStatus: "stale",
46413
+ reviewLedgerDigest: reviewLedgerDigest2,
46414
+ verificationStatus: "stale",
46415
+ verificationLedgerDigest: verificationLedgerDigest2
46416
+ },
46182
46417
  latestCheckpointRef: {
46183
46418
  taskRef: previous.taskRef,
46184
46419
  kind: "checkpoint",
@@ -46207,9 +46442,9 @@ function scopeChangedCheckpoint(input) {
46207
46442
  summary: input.summary ?? "Changed the implementation scope and replaced affected coordination claims.",
46208
46443
  governance: {
46209
46444
  requirementsDigest: input.context.task.requirements.contentDigest,
46210
- planVersion: input.metadata.governance.planVersion,
46211
- reviewLedgerDigest: input.context.task.review.contentDigest,
46212
- verificationLedgerDigest: input.context.task.verification.contentDigest
46445
+ planVersion: input.planVersion,
46446
+ reviewLedgerDigest: input.reviewLedgerDigest,
46447
+ verificationLedgerDigest: input.verificationLedgerDigest
46213
46448
  },
46214
46449
  nextAction: input.nextAction ?? "Re-read the updated scope and continue only with the successor claim.",
46215
46450
  createdBy: {
@@ -46541,60 +46776,43 @@ async function workflow(rootDir, subcommand, args = [], options = {}) {
46541
46776
  return EXIT_INVALID_ARG3;
46542
46777
  }
46543
46778
  }
46779
+ var WORKFLOW_V3_HANDLERS = {
46780
+ create: workflowCreateV3,
46781
+ list: workflowListV3,
46782
+ show: workflowShowV3,
46783
+ update: workflowUpdateV3,
46784
+ requirements: workflowRequirementsV3,
46785
+ plan: workflowPlanV3,
46786
+ review: workflowReviewV3,
46787
+ verify: workflowVerifyV3,
46788
+ complete: workflowCompleteV3,
46789
+ scope: workflowScopeChangeV3,
46790
+ reframe: workflowReframeV3,
46791
+ archive: (rootDir, args, options) => workflowArtifactShowV3(rootDir, "archive", args, options),
46792
+ checkpoint: (rootDir, args, options) => workflowArtifactShowV3(rootDir, "checkpoint", args, options),
46793
+ child: workflowChildResultMergeV3,
46794
+ promote: workflowPromoteV3,
46795
+ handoff: workflowSoloHandoffV3
46796
+ };
46797
+ var CONTINUITY_COMPATIBILITY_HANDLERS = {
46798
+ clean: (_rootDir, _args, options) => workflowCleanV3(options)
46799
+ };
46544
46800
  async function workflowV3(rootDir, subcommand, args, options) {
46545
- if (subcommand === "list") {
46546
- return workflowListV3(rootDir, args, options);
46547
- }
46548
- if (subcommand === "show") {
46549
- return workflowShowV3(rootDir, args, options);
46550
- }
46551
- if (subcommand === "clean") {
46552
- return workflowCleanV3(options);
46553
- }
46554
- if (subcommand === "create") {
46555
- return workflowCreateV3(rootDir, args, options);
46556
- }
46557
- if (subcommand === "update") {
46558
- return workflowUpdateV3(rootDir, args, options);
46559
- }
46560
- if (subcommand === "requirements") {
46561
- return workflowRequirementsV3(rootDir, args, options);
46562
- }
46563
- if (subcommand === "plan") {
46564
- return workflowPlanV3(rootDir, args, options);
46565
- }
46566
- if (subcommand === "review") {
46567
- return workflowReviewV3(rootDir, args, options);
46568
- }
46569
- if (subcommand === "verify") {
46570
- return workflowVerifyV3(rootDir, args, options);
46571
- }
46572
- if (subcommand === "complete") {
46573
- return workflowCompleteV3(rootDir, args, options);
46574
- }
46575
- if (subcommand === "scope") {
46576
- return workflowScopeChangeV3(rootDir, args, options);
46577
- }
46578
- if (subcommand === "reframe") {
46579
- return workflowReframeV3(rootDir, args, options);
46580
- }
46581
- if (subcommand === "archive" || subcommand === "checkpoint") {
46582
- return workflowArtifactShowV3(rootDir, subcommand, args, options);
46583
- }
46584
- if (subcommand === "child") {
46585
- return workflowChildResultMergeV3(rootDir, args, options);
46586
- }
46587
- if (subcommand === "promote") {
46588
- return workflowPromoteV3(rootDir, args, options);
46801
+ if (!WORKFLOW_SUBCOMMAND_SET.has(subcommand) && !CONTINUITY_COMPATIBILITY_SUBCOMMANDS.has(subcommand)) {
46802
+ return printV3Error(
46803
+ options.json,
46804
+ "MANCODE_V3_OPERATION_NOT_IMPLEMENTED",
46805
+ `Unknown workflow subcommand: ${subcommand}. Use one of: ${WORKFLOW_SUBCOMMANDS.join(", ")}.`
46806
+ );
46589
46807
  }
46590
- if (subcommand === "handoff") {
46591
- return workflowSoloHandoffV3(rootDir, args, options);
46808
+ if (WORKFLOW_SUBCOMMAND_SET.has(subcommand)) {
46809
+ return WORKFLOW_V3_HANDLERS[subcommand](
46810
+ rootDir,
46811
+ args,
46812
+ options
46813
+ );
46592
46814
  }
46593
- return printV3Error(
46594
- options.json,
46595
- "MANCODE_V3_OPERATION_NOT_IMPLEMENTED",
46596
- `workflow ${subcommand} is not yet implemented for mancode authority.`
46597
- );
46815
+ return CONTINUITY_COMPATIBILITY_HANDLERS[subcommand](rootDir, args, options);
46598
46816
  }
46599
46817
  async function workflowListV3(rootDir, args, options) {
46600
46818
  if (args.length !== 0) {
@@ -47400,7 +47618,7 @@ async function workflowPlanV3(rootDir, args, options) {
47400
47618
  return printV3Error(
47401
47619
  options.json,
47402
47620
  "MANCODE_PLAN_ARGUMENT_INVALID",
47403
- "Use: workflow plan <namespace:ULID> revise --expected-revision <n> --file <path>, or confirm --expected-revision <n> --plan-decision <plan_only|governed_execution>.",
47621
+ "Use: workflow plan <namespace:ULID> revise --expected-revision <n> --file <path> [--scope-file <path>], or confirm --expected-revision <n> --plan-decision <plan_only|governed_execution>.",
47404
47622
  EXIT_INVALID_ARG3
47405
47623
  );
47406
47624
  }
@@ -47429,6 +47647,14 @@ async function workflowPlanV3(rootDir, args, options) {
47429
47647
  EXIT_INVALID_ARG3
47430
47648
  );
47431
47649
  }
47650
+ if (action === "confirm" && options.scopeFile !== void 0) {
47651
+ return printV3Error(
47652
+ options.json,
47653
+ "MANCODE_PLAN_SCOPE_REVISE_REQUIRED",
47654
+ "Bind implementation scope with workflow plan revise before confirmation.",
47655
+ EXIT_INVALID_ARG3
47656
+ );
47657
+ }
47432
47658
  try {
47433
47659
  const project = await readV3CommandProject(rootDir);
47434
47660
  const taskRef = parseTaskRef(task);
@@ -47445,12 +47671,17 @@ async function workflowPlanV3(rootDir, args, options) {
47445
47671
  if (plan === void 0 || plan === null) {
47446
47672
  throw new Error("MANCODE_PLAN_FILE_REQUIRED");
47447
47673
  }
47674
+ const implementationScope = action === "revise" && options.scopeFile !== void 0 ? await readWorkflowJsonInputFile(
47675
+ project.projectRoot,
47676
+ options.scopeFile
47677
+ ) : void 0;
47448
47678
  const result2 = await reviseV3Plan({
47449
47679
  projectRoot: project.projectRoot,
47450
47680
  taskRef,
47451
47681
  sessionId: session.sessionId,
47452
47682
  expectedTaskRevision,
47453
47683
  plan,
47684
+ implementationScope,
47454
47685
  planDecision: parseV3PlanDecision(options.planDecision)
47455
47686
  });
47456
47687
  return printV3Result(options.json, {
@@ -47703,6 +47934,7 @@ async function workflowRequirements(rootDir, args, options) {
47703
47934
  const inputPath = path69.isAbsolute(options.file) ? options.file : path69.resolve(rootDir, options.file);
47704
47935
  const input = await readFile48(inputPath, "utf-8");
47705
47936
  const requirements = parseRequirementsLedger2(input);
47937
+ assertRequirementsScopeConsistent2(requirements);
47706
47938
  [originalJson, originalMarkdown, originalMetadata] = await Promise.all([
47707
47939
  readOptionalText2(jsonPath),
47708
47940
  readOptionalText2(markdownPath),
@@ -48811,442 +49043,528 @@ async function pathExists16(p) {
48811
49043
  }
48812
49044
 
48813
49045
  // src/cli.ts
48814
- program.name("mancode").description(
48815
- "AI coding agent harness. Modes: solo, man, manba, manteam, manps."
48816
- ).version(VERSION);
48817
- program.command("init").description("Initialize mancode in the current project").option("--force", "Reinstall even if already initialized").option("--yes", "Skip all confirmations (CI mode)").option("--team", "Force enable team mode (MVP-2)").option("--no-team", "Force disable team mode (MVP-2)").option("--style <name>", "Specify aesthetic style (MVP-2)").option("--platform <platforms>", "Adapters: comma-separated names or all").option("--empty", "Initialize a safe empty directory as a generic project").addOption(new Option("--v3").hideHelp()).option("--legacy", "Use the legacy state.json initializer").option("--lang <locale>", "Initialization language: zh-CN or en").action(async (options) => {
48818
- const code = await init(process.cwd(), {
48819
- ...options,
48820
- fromCli: true,
48821
- interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY)
48822
- });
48823
- process.exitCode = code;
48824
- });
48825
- program.command("install [platform]").description(
48826
- "Install platform adapter (claude-code, cursor, codex, copilot, zcode, kimi-code, qoder)"
48827
- ).option("--force", "Reinstall even if already installed").option("--minimal", "Minimal install (MVP-2)").option(
48828
- "--shadow",
48829
- "Stage a mancode bootstrap candidate without changing live files"
48830
- ).option("--confirm", "Confirm a journaled adapter install or repair").option("--operation-id <id>", "Operation ID returned by adapter dry-run").option("--session <id>", "mancode session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").action(async (platform, options) => {
48831
- const code = await install(
48832
- process.cwd(),
48833
- platform ?? "claude-code",
48834
- options
48835
- );
48836
- process.exitCode = code;
48837
- });
48838
- var adapterProgram = program.command("adapter").description("Inspect and explicitly upgrade managed platform adapters");
48839
- adapterProgram.command("status").description("Inspect managed adapter content on disk").option("--platform <platform>", "Inspect one platform adapter").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48840
- process.exitCode = await adapterStatus(process.cwd(), options);
48841
- });
48842
- adapterProgram.command("upgrade").description("Preview or repair managed adapter content").option("--all", "Upgrade all platform adapters").option("--platform <platform>", "Upgrade one platform adapter").option("--dry-run", "Stage and report changes without writing live targets").option("--confirm", "Confirm the journaled adapter upgrade").option("--operation-id <id>", "Operation ID returned by adapter dry-run").option("--session <id>", "mancode session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48843
- process.exitCode = await adapterUpgrade(process.cwd(), options);
48844
- });
48845
- program.command("status").description("Show current mancode project status").option("--json", "Output as JSON (for scripts)").option("--brief", "Output compact mancode Continuity runtime status").action(async (options) => {
48846
- const code = await status(process.cwd(), options);
48847
- process.exitCode = code;
48848
- });
48849
- var projectProgram = program.command("project").description("Manage project-level mancode policy and compatibility");
48850
- projectProgram.command("upgrade").description("Upgrade project governance policy explicitly").requiredOption("--policy <version>", "Target planning policy version (2)").option("--dry-run", "Preview the upgrade without writing").option("--operation-id <id>", "Operation ID returned by project dry-run").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48851
- process.exitCode = await projectUpgrade(process.cwd(), options);
48852
- });
48853
- program.command("list-platforms").description("List available and installed mancode platform adapters").action(async () => {
48854
- const code = await listPlatforms(process.cwd());
48855
- process.exitCode = code;
48856
- });
48857
- program.command("uninstall [platform]").description("Remove platform adapter or all mancode artifacts").option("--force", "Skip confirmation message").option("--all", "Remove everything including .mancode/ directory").action(async (platform, options) => {
48858
- const code = await uninstall(process.cwd(), platform, options);
48859
- process.exitCode = code;
48860
- });
48861
- program.command("workflow <subcommand> [args...]").description("Manage mancode workflows").option("--dry-run", "Preview clean without deleting").option("--older-than <duration>", "Clean workflows older than (e.g. 30d)").option("--step <n>", "Update workflow current step").option("--status <status>", "Update workflow status").option(
48862
- "--parent-task <taskId>",
48863
- "Parent /man or /manteam workflow for manba"
48864
- ).option("--parent <namespace:id>", "Parent TaskRef for a manba child").option(
48865
- "--participant <actorId>",
48866
- "Invite a joined team participant",
48867
- collectOption,
48868
- []
48869
- ).option("--visibility <visibility>", "Task visibility: local or shared").option("--coordination <coordination>", "Task coordination: single or team").option("--session <id>", "mancode session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--expected-revision <n>", "Expected task revision for mutations").option("--checkpoint-id <id>", "Checkpoint ID for a requirements reframe").option("--child-revision <n>", "Expected child task revision for merge").option("--summary <text>", "Privacy-screened child result summary").option("--next-action <text>", "Next parent action after a child merge").option("--sync", "Publish shared mutations through git-ref transport").option(
48870
- "--confirm-shared",
48871
- "Confirm that task metadata may enter shared mancode authority"
48872
- ).option("--blocking-reason <reason>", "Explain why a workflow is blocked").option("--outcome <outcome>", "Set manba outcome when completing a task").option("--plan-version <n>", "Set the next man/manteam plan revision").option(
48873
- "--requirements-status <status>",
48874
- "Planning readiness: ready or needs_clarification"
48875
- ).option(
48876
- "--plan-decision <decision>",
48877
- "Plan gate choice: plan_only or governed_execution"
48878
- ).option("--to <mode>", "Workflow handoff target (solo)").option("--complete", "Complete an active solo handoff").option(
48879
- "--skipped <steps>",
48880
- "Policy v2: clarification only; use workflow review skip for review"
48881
- ).option("--review-depth <depth>", "Review depth: targeted or full").option("--review-domain <domain>", "Review domain: quality or security").option(
48882
- "--report <path>",
48883
- "Relative Markdown report path for a review domain"
48884
- ).option("--blockers <ids>", "Comma-separated blocker ids found by a review").option(
48885
- "--resolved <ids>",
48886
- "Comma-separated blocker ids resolved in remediation"
48887
- ).option(
48888
- "--file <path>",
48889
- "Semantic requirements JSON, plan Markdown, or ledger input file"
48890
- ).option("--acceptance <id>", "Acceptance criterion id (for example AC-1)").option("--method <method>", "Verification method: automated or manual").option("--result <result>", "Verification result").option("--evidence <text>", "Verification evidence or user confirmation").option("--command <command>", "Command used for automated verification").option("--exit-code <code>", "Exit code from automated verification").option("--evidence-file <path>", "Existing verification report or artifact").option("--reason <reason>", "Reason for an explicit review skip").option("--json", "Output as JSON (for scripts)").action(async (subcommand, args, options) => {
48891
- const code = await workflow(process.cwd(), subcommand, args ?? [], {
48892
- ...options,
48893
- participants: options.participant.length === 0 ? void 0 : options.participant
48894
- });
48895
- process.exitCode = code;
48896
- });
48897
- var contextProgram = program.command("context").description("Resolve mancode task context and manage explicit sessions");
48898
- contextProgram.command("show").description("Resolve one mancode Context Pack").option("--task <namespace:id>", "Explicit TaskRef").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--level <level>", "bootstrap, task, or full").option(
48899
- "--purpose <purpose>",
48900
- "orient, plan, implement, review, verify, or handoff"
48901
- ).option("--json", "Output as JSON (for scripts)").action(async (options) => {
48902
- process.exitCode = await contextShow(process.cwd(), options);
48903
- });
48904
- var contextSessionProgram = contextProgram.command("session").description("Manage mancode session identities");
48905
- contextSessionProgram.command("new").description("Create an explicit bootstrap session").requiredOption("--client <name>", "Client identity").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48906
- process.exitCode = await contextSessionNew(process.cwd(), options);
48907
- });
48908
- contextSessionProgram.command("show").description("Show one explicit session without changing it").requiredOption("--session <id>", "Session ID").option("--client <name>", "Expected client identity").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48909
- process.exitCode = await contextSessionShow(process.cwd(), options);
48910
- });
48911
- contextSessionProgram.command("spike").description("Record real-host session evidence without persisting host keys").requiredOption(
48912
- "--platform <platform>",
48913
- "claude-code, codex, cursor, copilot, zcode, kimi-code, or qoder"
48914
- ).requiredOption("--session-mode <mode>", "Evidence path: host or explicit").requiredOption(
48915
- "--host-session-source <source>",
48916
- "hook_stdin, environment, api, or none for explicit sessions"
48917
- ).requiredOption(
48918
- "--command-propagation <status>",
48919
- "Real host child-command result: proven, not_proven, not_tested, or not_applicable"
48920
- ).requiredOption(
48921
- "--subagent-inheritance <status>",
48922
- "Real host child-agent result: proven, not_proven, not_tested, or not_applicable"
48923
- ).option(
48924
- "--subagent-inheritance-reason <reason>",
48925
- "Required when child-agent inheritance is not applicable"
48926
- ).option(
48927
- "--hook-approval <status>",
48928
- "approved, unapproved, unknown, or not_applicable"
48929
- ).requiredOption(
48930
- "--host-version <version>",
48931
- "Installed host version used for the spike"
48932
- ).requiredOption(
48933
- "--release-candidate <id>",
48934
- "Immutable mancode release candidate or source commit identifier"
48935
- ).option("--json", "Output as JSON (for scripts)").action(async (options) => {
48936
- process.exitCode = await contextSessionSpike(process.cwd(), options);
48937
- });
48938
- contextProgram.command("resume <namespace:id>").description("Validate and bind the current session to a mancode TaskRef").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish shared mutations through git-ref transport").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
48939
- process.exitCode = await contextResume(process.cwd(), task, options);
48940
- });
48941
- contextProgram.command("close").description("Close one explicit session without affecting other sessions").requiredOption("--session <id>", "Session ID").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48942
- process.exitCode = await contextClose(process.cwd(), options);
48943
- });
48944
- contextProgram.command("doctor").description("Inspect unfinished mancode operations or repair one explicitly").option(
48945
- "--repair <operationId>",
48946
- "Repair this operation with its original session"
48947
- ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48948
- process.exitCode = await contextDoctor(process.cwd(), options);
48949
- });
48950
- contextProgram.command("diagnostics [action]").description("Show or configure local aggregate diagnostics").option("--json", "Output as JSON (for scripts)").action(async (action, options) => {
48951
- process.exitCode = await contextDiagnostics(process.cwd(), action, options);
48952
- });
48953
- contextProgram.command("compact").description("List and remove eligible mancode runtime retention candidates").option("--task <namespace:id>", "Compact checkpoints for one completed task").option("--dry-run", "Show the deletion list without changing files").option("--apply-shared", "Permit deletion for shared completed tasks").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48954
- process.exitCode = await contextCompact(process.cwd(), options);
48955
- });
48956
- contextProgram.command("beta", { hidden: true }).description("Evaluate internal release-evidence gates").requiredOption(
48957
- "--release-candidate <id>",
48958
- "Release candidate that must match every platform evidence record"
48959
- ).option("--json", "Output as JSON (for scripts)").action(async (options) => {
48960
- process.exitCode = await contextBeta(process.cwd(), options);
48961
- });
48962
- contextProgram.command("publish <local:id>").description("Create a privacy-screened shared man successor").requiredOption("--expected-revision <n>", "Current local task revision").requiredOption(
48963
- "--confirm-shared",
48964
- "Confirm that the screened task authority may enter shared storage"
48965
- ).option("--dry-run", "Validate the publish preflight without writing").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
48966
- process.exitCode = await contextPublish(process.cwd(), task, options);
48967
- });
48968
- contextProgram.command("reconcile-task-head <shared:id>").description(
48969
- "Adopt a Git-sourced shared aggregate through an explicit fence CAS"
48970
- ).requiredOption(
48971
- "--expected-fence-revision <n>",
48972
- "Current shared task-head fence revision"
48973
- ).requiredOption(
48974
- "--from-git",
48975
- "Confirm the checked-out aggregate came from Git"
48976
- ).option("--dry-run", "Validate adoption without changing the task-head fence").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
48977
- process.exitCode = await contextReconcileTaskHead(
48978
- process.cwd(),
48979
- task,
48980
- options
48981
- );
48982
- });
48983
- contextProgram.command("glossary <action>").description("Manage the user-confirmed shared project glossary").option("--term <term>", "Glossary term (add, update, remove)").option("--definition <text>", "Term definition (add, update)").option(
48984
- "--alias <alias>",
48985
- "Term alias; repeat for multiple aliases (add, update)",
48986
- (value, previous) => [...previous, value],
48987
- []
48988
- ).option("--task <namespace:id>", "Source shared TaskRef (add, update)").option(
48989
- "--expected-revision <n>",
48990
- "Current glossary revision (0 for an empty glossary)"
48991
- ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (action, options) => {
48992
- process.exitCode = await contextGlossary(process.cwd(), action, options);
48993
- });
48994
- var contextWorktreeProgram = contextProgram.command("worktree").description("Register and inspect the current mancode checkout binding");
48995
- contextWorktreeProgram.command("register").description(
48996
- "Register this linked worktree before using mancode coordination"
48997
- ).option("--json", "Output as JSON (for scripts)").action(async (options) => {
48998
- process.exitCode = await contextWorktreeRegister(process.cwd(), options);
48999
- });
49000
- var operationProgram = program.command("operation").description("Inspect and recover durable mancode operations");
49001
- operationProgram.command("show <operationId>").description("Show one operation journal and its recovery disposition").option("--json", "Output as JSON (for scripts)").action(async (operationId, options) => {
49002
- process.exitCode = await operationShow(process.cwd(), operationId, options);
49003
- });
49004
- operationProgram.command("repair <operationId>").description("Repair an operation using its original actor and session").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (operationId, options) => {
49005
- process.exitCode = await operationRepair(
49006
- process.cwd(),
49007
- operationId,
49008
- options
49009
- );
49010
- });
49011
- operationProgram.command("abort <operationId>").description(
49012
- "Abort only an operation proven to have no visible business write"
49013
- ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (operationId, options) => {
49014
- process.exitCode = await operationAbort(
49015
- process.cwd(),
49016
- operationId,
49017
- options
49018
- );
49019
- });
49020
- var teamProgram = program.command("team").description("Manage mancode local identity and local-team membership");
49021
- teamProgram.command("status").description("Show mancode team policy, transport, and local identity state").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49022
- process.exitCode = await teamStatus(process.cwd(), options);
49023
- });
49024
- teamProgram.command("policy <mode>").description("Set the mancode team recommendation policy with a revision CAS").requiredOption("--expected-revision <n>", "Current team policy revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (policy, options) => {
49025
- process.exitCode = await teamPolicy(process.cwd(), {
49026
- ...options,
49027
- policy
49046
+ function createCliProgram() {
49047
+ const program = new Command();
49048
+ program.name("mancode").description(
49049
+ "AI coding agent harness. Modes: solo, man, manba, manteam, manps."
49050
+ ).version(VERSION);
49051
+ program.command("init").description("Initialize mancode in the current project").option("--force", "Reinstall even if already initialized").option("--yes", "Skip all confirmations (CI mode)").option("--team", "Force enable team mode").option("--no-team", "Force disable team mode").option(
49052
+ "--style <name>",
49053
+ "Legacy aesthetic style (only supported with mancode init --legacy)"
49054
+ ).option("--platform <platforms>", "Adapters: comma-separated names or all").option("--empty", "Initialize a safe empty directory as a generic project").addOption(new Option("--v3").hideHelp()).option("--legacy", "Use the legacy state.json initializer").option("--lang <locale>", "Initialization language: zh-CN or en").action(async (options) => {
49055
+ const code = await init(process.cwd(), {
49056
+ ...options,
49057
+ fromCli: true,
49058
+ interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY)
49059
+ });
49060
+ process.exitCode = code;
49061
+ });
49062
+ program.command("install [platform]").description(
49063
+ "Install platform adapter (claude-code, cursor, codex, copilot, zcode, kimi-code, qoder)"
49064
+ ).option("--force", "Reinstall even if already installed").option(
49065
+ "--minimal",
49066
+ "Retained for legacy compatibility; Continuity bootstrap is already minimal"
49067
+ ).option(
49068
+ "--shadow",
49069
+ "Stage a mancode bootstrap candidate without changing live files"
49070
+ ).option("--confirm", "Confirm a journaled adapter install or repair").option("--operation-id <id>", "Operation ID returned by adapter dry-run").option(
49071
+ "--session <id>",
49072
+ "mancode session ID (otherwise MANCODE_SESSION_ID)"
49073
+ ).option("--client <name>", "Client identity (default: mancode-cli)").action(async (platform, options) => {
49074
+ const code = await install(
49075
+ process.cwd(),
49076
+ platform ?? "claude-code",
49077
+ options
49078
+ );
49079
+ process.exitCode = code;
49080
+ });
49081
+ const adapterProgram = program.command("adapter").description("Inspect and explicitly upgrade managed platform adapters");
49082
+ adapterProgram.command("status").description("Inspect managed adapter content on disk").option("--platform <platform>", "Inspect one platform adapter").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49083
+ process.exitCode = await adapterStatus(process.cwd(), options);
49084
+ });
49085
+ adapterProgram.command("upgrade").description("Preview or repair managed adapter content").option("--all", "Upgrade all platform adapters").option("--platform <platform>", "Upgrade one platform adapter").option(
49086
+ "--dry-run",
49087
+ "Stage and report changes without writing live targets"
49088
+ ).option("--confirm", "Confirm the journaled adapter upgrade").option("--operation-id <id>", "Operation ID returned by adapter dry-run").option(
49089
+ "--session <id>",
49090
+ "mancode session ID (otherwise MANCODE_SESSION_ID)"
49091
+ ).option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49092
+ process.exitCode = await adapterUpgrade(process.cwd(), options);
49093
+ });
49094
+ program.command("status").description("Show current mancode project status").option("--json", "Output as JSON (for scripts)").option("--brief", "Output compact mancode Continuity runtime status").action(async (options) => {
49095
+ const code = await status(process.cwd(), options);
49096
+ process.exitCode = code;
49097
+ });
49098
+ const projectProgram = program.command("project").description("Manage project-level mancode policy and compatibility");
49099
+ projectProgram.command("upgrade").description("Upgrade project governance policy explicitly").requiredOption("--policy <version>", "Target planning policy version (2)").option("--dry-run", "Preview the upgrade without writing").option("--operation-id <id>", "Operation ID returned by project dry-run").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49100
+ process.exitCode = await projectUpgrade(process.cwd(), options);
49101
+ });
49102
+ program.command("list-platforms").description("List available and installed mancode platform adapters").action(async () => {
49103
+ const code = await listPlatforms(process.cwd());
49104
+ process.exitCode = code;
49105
+ });
49106
+ program.command("uninstall [platform]").description("Remove platform adapter or all mancode artifacts").option("--force", "Skip confirmation message").option("--all", "Remove everything including .mancode/ directory").action(async (platform, options) => {
49107
+ const code = await uninstall(process.cwd(), platform, options);
49108
+ process.exitCode = code;
49109
+ });
49110
+ program.command("workflow <subcommand> [args...]").description("Manage mancode workflows").addHelpText(
49111
+ "after",
49112
+ `
49113
+ Public Continuity subcommands:
49114
+ ${WORKFLOW_SUBCOMMANDS.join(", ")}
49115
+ `
49116
+ ).option("--dry-run", "Preview clean without deleting").option("--older-than <duration>", "Clean workflows older than (e.g. 30d)").option("--step <n>", "Update workflow current step").option("--status <status>", "Update workflow status").option(
49117
+ "--parent-task <taskId>",
49118
+ "Parent /man or /manteam workflow for manba"
49119
+ ).option("--parent <namespace:id>", "Parent TaskRef for a manba child").option(
49120
+ "--participant <actorId>",
49121
+ "Invite a joined team participant",
49122
+ collectOption,
49123
+ []
49124
+ ).option("--visibility <visibility>", "Task visibility: local or shared").option(
49125
+ "--coordination <coordination>",
49126
+ "Task coordination: single or team"
49127
+ ).option(
49128
+ "--session <id>",
49129
+ "mancode session ID (otherwise MANCODE_SESSION_ID)"
49130
+ ).option("--client <name>", "Client identity (default: mancode-cli)").option("--expected-revision <n>", "Expected task revision for mutations").option("--checkpoint-id <id>", "Checkpoint ID for a requirements reframe").option("--child-revision <n>", "Expected child task revision for merge").option("--summary <text>", "Privacy-screened child result summary").option("--next-action <text>", "Next parent action after a child merge").option("--sync", "Publish shared mutations through git-ref transport").option(
49131
+ "--confirm-shared",
49132
+ "Confirm that task metadata may enter shared mancode authority"
49133
+ ).option("--blocking-reason <reason>", "Explain why a workflow is blocked").option("--outcome <outcome>", "Set manba outcome when completing a task").option("--plan-version <n>", "Set the next man/manteam plan revision").option(
49134
+ "--requirements-status <status>",
49135
+ "Planning readiness: ready or needs_clarification"
49136
+ ).option(
49137
+ "--plan-decision <decision>",
49138
+ "Plan gate choice: plan_only or governed_execution"
49139
+ ).option("--to <mode>", "Workflow handoff target (solo)").option("--complete", "Complete an active solo handoff").option(
49140
+ "--skipped <steps>",
49141
+ "Policy v2: clarification only; use workflow review skip for review"
49142
+ ).option("--review-depth <depth>", "Review depth: targeted or full").option("--review-domain <domain>", "Review domain: quality or security").option(
49143
+ "--report <path>",
49144
+ "Relative Markdown report path for a review domain"
49145
+ ).option("--blockers <ids>", "Comma-separated blocker ids found by a review").option(
49146
+ "--resolved <ids>",
49147
+ "Comma-separated blocker ids resolved in remediation"
49148
+ ).option(
49149
+ "--file <path>",
49150
+ "Semantic requirements JSON, plan Markdown, or ledger input file"
49151
+ ).option(
49152
+ "--scope-file <path>",
49153
+ "Plan implementation scope JSON {include,exclude,modules}"
49154
+ ).option("--acceptance <id>", "Acceptance criterion id (for example AC-1)").option("--method <method>", "Verification method: automated or manual").option("--result <result>", "Verification result").option("--evidence <text>", "Verification evidence or user confirmation").option("--command <command>", "Command used for automated verification").option("--exit-code <code>", "Exit code from automated verification").option(
49155
+ "--evidence-file <path>",
49156
+ "Existing verification report or artifact"
49157
+ ).option("--reason <reason>", "Reason for an explicit review skip").option("--json", "Output as JSON (for scripts)").action(async (subcommand, args, options) => {
49158
+ const code = await workflow(process.cwd(), subcommand, args ?? [], {
49159
+ ...options,
49160
+ participants: options.participant.length === 0 ? void 0 : options.participant
49161
+ });
49162
+ process.exitCode = code;
49163
+ });
49164
+ const contextProgram = program.command("context").description("Resolve mancode task context and manage explicit sessions");
49165
+ contextProgram.command("show").description("Resolve one mancode Context Pack").option("--task <namespace:id>", "Explicit TaskRef").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--level <level>", "bootstrap, task, or full").option(
49166
+ "--purpose <purpose>",
49167
+ "orient, plan, implement, review, verify, or handoff"
49168
+ ).option("--json", "Output as JSON (for scripts)").action(async (options) => {
49169
+ process.exitCode = await contextShow(process.cwd(), options);
49170
+ });
49171
+ const contextSessionProgram = contextProgram.command("session").description("Manage mancode session identities");
49172
+ contextSessionProgram.command("new").description("Create an explicit bootstrap session").requiredOption("--client <name>", "Client identity").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49173
+ process.exitCode = await contextSessionNew(process.cwd(), options);
49174
+ });
49175
+ contextSessionProgram.command("show").description("Show one explicit session without changing it").requiredOption("--session <id>", "Session ID").option("--client <name>", "Expected client identity").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49176
+ process.exitCode = await contextSessionShow(process.cwd(), options);
49177
+ });
49178
+ contextSessionProgram.command("spike").description(
49179
+ "Record real-host session evidence without persisting host keys"
49180
+ ).requiredOption(
49181
+ "--platform <platform>",
49182
+ "claude-code, codex, cursor, copilot, zcode, kimi-code, or qoder"
49183
+ ).requiredOption("--session-mode <mode>", "Evidence path: host or explicit").requiredOption(
49184
+ "--host-session-source <source>",
49185
+ "hook_stdin, environment, api, or none for explicit sessions"
49186
+ ).requiredOption(
49187
+ "--command-propagation <status>",
49188
+ "Real host child-command result: proven, not_proven, not_tested, or not_applicable"
49189
+ ).requiredOption(
49190
+ "--subagent-inheritance <status>",
49191
+ "Real host child-agent result: proven, not_proven, not_tested, or not_applicable"
49192
+ ).option(
49193
+ "--subagent-inheritance-reason <reason>",
49194
+ "Required when child-agent inheritance is not applicable"
49195
+ ).option(
49196
+ "--hook-approval <status>",
49197
+ "approved, unapproved, unknown, or not_applicable"
49198
+ ).requiredOption(
49199
+ "--host-version <version>",
49200
+ "Installed host version used for the spike"
49201
+ ).requiredOption(
49202
+ "--release-candidate <id>",
49203
+ "Immutable mancode release candidate or source commit identifier"
49204
+ ).option("--json", "Output as JSON (for scripts)").action(async (options) => {
49205
+ process.exitCode = await contextSessionSpike(process.cwd(), options);
49206
+ });
49207
+ contextProgram.command("resume <namespace:id>").description("Validate and bind the current session to a mancode TaskRef").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish shared mutations through git-ref transport").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49208
+ process.exitCode = await contextResume(process.cwd(), task, options);
49209
+ });
49210
+ contextProgram.command("close").description("Close one explicit session without affecting other sessions").requiredOption("--session <id>", "Session ID").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49211
+ process.exitCode = await contextClose(process.cwd(), options);
49212
+ });
49213
+ contextProgram.command("doctor").description(
49214
+ "Inspect unfinished mancode operations or repair one explicitly"
49215
+ ).option(
49216
+ "--repair <operationId>",
49217
+ "Repair this operation with its original session"
49218
+ ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49219
+ process.exitCode = await contextDoctor(process.cwd(), options);
49220
+ });
49221
+ contextProgram.command("diagnostics [action]").description("Show or configure local aggregate diagnostics").option("--json", "Output as JSON (for scripts)").action(async (action, options) => {
49222
+ process.exitCode = await contextDiagnostics(
49223
+ process.cwd(),
49224
+ action,
49225
+ options
49226
+ );
49227
+ });
49228
+ contextProgram.command("compact").description(
49229
+ "List and remove eligible mancode runtime retention candidates"
49230
+ ).option(
49231
+ "--task <namespace:id>",
49232
+ "Compact checkpoints for one completed task"
49233
+ ).option("--dry-run", "Show the deletion list without changing files").option("--apply-shared", "Permit deletion for shared completed tasks").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49234
+ process.exitCode = await contextCompact(process.cwd(), options);
49235
+ });
49236
+ contextProgram.command("beta", { hidden: true }).description("Evaluate internal release-evidence gates").requiredOption(
49237
+ "--release-candidate <id>",
49238
+ "Release candidate that must match every platform evidence record"
49239
+ ).option("--json", "Output as JSON (for scripts)").action(async (options) => {
49240
+ process.exitCode = await contextBeta(process.cwd(), options);
49241
+ });
49242
+ contextProgram.command("publish <local:id>").description("Create a privacy-screened shared man successor").requiredOption("--expected-revision <n>", "Current local task revision").requiredOption(
49243
+ "--confirm-shared",
49244
+ "Confirm that the screened task authority may enter shared storage"
49245
+ ).option("--dry-run", "Validate the publish preflight without writing").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49246
+ process.exitCode = await contextPublish(process.cwd(), task, options);
49247
+ });
49248
+ contextProgram.command("reconcile-task-head <shared:id>").description(
49249
+ "Adopt a Git-sourced shared aggregate through an explicit fence CAS"
49250
+ ).requiredOption(
49251
+ "--expected-fence-revision <n>",
49252
+ "Current shared task-head fence revision"
49253
+ ).requiredOption(
49254
+ "--from-git",
49255
+ "Confirm the checked-out aggregate came from Git"
49256
+ ).option(
49257
+ "--dry-run",
49258
+ "Validate adoption without changing the task-head fence"
49259
+ ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49260
+ process.exitCode = await contextReconcileTaskHead(
49261
+ process.cwd(),
49262
+ task,
49263
+ options
49264
+ );
49265
+ });
49266
+ contextProgram.command("glossary <action>").description("Manage the user-confirmed shared project glossary").option("--term <term>", "Glossary term (add, update, remove)").option("--definition <text>", "Term definition (add, update)").option(
49267
+ "--alias <alias>",
49268
+ "Term alias; repeat for multiple aliases (add, update)",
49269
+ (value, previous) => [...previous, value],
49270
+ []
49271
+ ).option("--task <namespace:id>", "Source shared TaskRef (add, update)").option(
49272
+ "--expected-revision <n>",
49273
+ "Current glossary revision (0 for an empty glossary)"
49274
+ ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (action, options) => {
49275
+ process.exitCode = await contextGlossary(process.cwd(), action, options);
49276
+ });
49277
+ const contextWorktreeProgram = contextProgram.command("worktree").description("Register and inspect the current mancode checkout binding");
49278
+ contextWorktreeProgram.command("register").description(
49279
+ "Register this linked worktree before using mancode coordination"
49280
+ ).option("--json", "Output as JSON (for scripts)").action(async (options) => {
49281
+ process.exitCode = await contextWorktreeRegister(process.cwd(), options);
49282
+ });
49283
+ const operationProgram = program.command("operation").description("Inspect and recover durable mancode operations");
49284
+ operationProgram.command("show <operationId>").description("Show one operation journal and its recovery disposition").option("--json", "Output as JSON (for scripts)").action(async (operationId, options) => {
49285
+ process.exitCode = await operationShow(
49286
+ process.cwd(),
49287
+ operationId,
49288
+ options
49289
+ );
49028
49290
  });
49029
- });
49030
- teamProgram.command("conflicts").description(
49031
- "Inspect local claim conflicts and handoffs without mutating coordination"
49032
- ).option("--task <namespace:id>", "Narrow the report to one shared TaskRef").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49033
- process.exitCode = await teamConflicts(process.cwd(), options);
49034
- });
49035
- var teamTransportProgram = teamProgram.command("transport").description("Inspect and migrate the coordination authority");
49036
- teamTransportProgram.command("status").description("Show active coordination transport and freshness").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49037
- process.exitCode = await teamTransportStatus(process.cwd(), options);
49038
- });
49039
- teamTransportProgram.command("set <mode>").description(
49040
- "Switch an empty coordination authority; otherwise use transport migrate"
49041
- ).requiredOption(
49042
- "--expected-config-revision <n>",
49043
- "Current project config revision"
49044
- ).option(
49045
- "--remote <name>",
49046
- "Git remote for a git-ref target (default: origin)"
49047
- ).option("--dry-run", "Validate the empty-authority switch without writing").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (mode, options) => {
49048
- process.exitCode = await teamTransportSet(process.cwd(), {
49049
- ...options,
49050
- mode
49291
+ operationProgram.command("repair <operationId>").description("Repair an operation using its original actor and session").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (operationId, options) => {
49292
+ process.exitCode = await operationRepair(
49293
+ process.cwd(),
49294
+ operationId,
49295
+ options
49296
+ );
49051
49297
  });
49052
- });
49053
- teamTransportProgram.command("migrate").description("Journal a single-authority local/git-ref transport switch").requiredOption("--to <mode>", "Target authority: local or git-ref").requiredOption(
49054
- "--expected-config-revision <n>",
49055
- "Current project config revision"
49056
- ).option(
49057
- "--remote <name>",
49058
- "Git remote for a git-ref target (default: origin)"
49059
- ).option("--dry-run", "Validate and preview without writing authority state").option("--confirm", "Explicitly confirm the authority migration").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49060
- process.exitCode = await teamTransportMigrate(process.cwd(), options);
49061
- });
49062
- teamTransportProgram.command("recover <operationId>").description("Repair forward or safely abort a transport migration").requiredOption("--to <mode>", "Original target authority: local or git-ref").option("--remote <name>", "Original Git remote for a git-ref target").option("--abort", "Abort only before the target authority is established").option("--session <id>", "Original migration session ID").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (operationId, options) => {
49063
- process.exitCode = await teamTransportRecover(
49064
- process.cwd(),
49065
- operationId,
49066
- options
49067
- );
49068
- });
49069
- var teamSyncProgram = teamProgram.command("sync").description("Explicitly synchronize the git-ref coordination authority");
49070
- teamSyncProgram.command("pull").description("Fetch, validate, and cache refs/mancode/team").option("--task <namespace:id>", "Narrow output to one shared TaskRef").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49071
- process.exitCode = await teamSyncPull(process.cwd(), options);
49072
- });
49073
- teamSyncProgram.command("push <namespace:id>").description("Publish one task bundle through a fresh ownership fence CAS").requiredOption(
49074
- "--expected-task-revision <n>",
49075
- "Current shared task revision"
49076
- ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49077
- process.exitCode = await teamSyncPush(process.cwd(), {
49078
- ...options,
49079
- task
49298
+ operationProgram.command("abort <operationId>").description(
49299
+ "Abort only an operation proven to have no visible business write"
49300
+ ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (operationId, options) => {
49301
+ process.exitCode = await operationAbort(
49302
+ process.cwd(),
49303
+ operationId,
49304
+ options
49305
+ );
49080
49306
  });
49081
- });
49082
- var teamIdentityProgram = teamProgram.command("identity").description("Manage the machine-local actor identity");
49083
- teamIdentityProgram.command("create").description("Create one local actor identity").requiredOption("--name <displayName>", "Display name").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49084
- process.exitCode = await teamIdentityCreate(process.cwd(), options);
49085
- });
49086
- teamIdentityProgram.command("show").description("Show local identity and whether it is joined").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49087
- process.exitCode = await teamIdentityShow(process.cwd(), options);
49088
- });
49089
- var teamDecisionProgram = teamProgram.command("decision").description("Publish explicitly confirmed, privacy-safe shared decisions");
49090
- teamDecisionProgram.command("publish").description("Publish one immutable confirmed decision").requiredOption("--title <text>", "Short decision title").requiredOption("--statement <text>", "Confirmed decision statement").option("--task <namespace:id>", "Optional shared TaskRef that produced it").requiredOption("--confirm", "Confirm this decision may enter shared memory").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49091
- process.exitCode = await teamDecisionPublish(process.cwd(), options);
49092
- });
49093
- teamProgram.command("join").description(
49094
- "Publish the approved shared actor profile after explicit confirmation"
49095
- ).requiredOption("--name <displayName>", "Must match the local actor identity").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Request explicit remote sync when transport supports it").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49096
- process.exitCode = await teamJoin(process.cwd(), options);
49097
- });
49098
- teamProgram.command("checkpoint <namespace:id>").description("Create a journaled immutable checkpoint for a shared task").requiredOption(
49099
- "--expected-task-revision <n>",
49100
- "Current shared task revision"
49101
- ).requiredOption("--kind <kind>", "Checkpoint kind").requiredOption("--summary <text>", "Privacy-safe checkpoint summary").option("--next-action <text>", "Next action for the receiving workflow").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49102
- process.exitCode = await teamCheckpoint(process.cwd(), {
49103
- ...options,
49104
- task
49307
+ const teamProgram = program.command("team").description("Manage mancode local identity and local-team membership");
49308
+ teamProgram.command("status").description(
49309
+ "Show mancode team policy, transport, and local identity state"
49310
+ ).option("--json", "Output as JSON (for scripts)").action(async (options) => {
49311
+ process.exitCode = await teamStatus(process.cwd(), options);
49105
49312
  });
49106
- });
49107
- teamProgram.command("claim <namespace:id>").description("Acquire a scoped claim for a shared task").requiredOption(
49108
- "--expected-task-revision <n>",
49109
- "Current shared task revision"
49110
- ).option("--path <glob>", "Repository-relative path glob", collectOption, []).option("--module <name>", "Implementation module", collectOption, []).option("--api <name>", "Public API boundary", collectOption, []).option("--schema <name>", "Shared schema boundary", collectOption, []).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49111
- process.exitCode = await teamClaim(process.cwd(), {
49112
- ...options,
49113
- task,
49114
- paths: options.path,
49115
- modules: options.module,
49116
- apis: options.api,
49117
- schemas: options.schema
49313
+ teamProgram.command("policy <mode>").description(
49314
+ "Set the mancode team recommendation policy with a revision CAS"
49315
+ ).requiredOption("--expected-revision <n>", "Current team policy revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (policy, options) => {
49316
+ process.exitCode = await teamPolicy(process.cwd(), {
49317
+ ...options,
49318
+ policy
49319
+ });
49320
+ });
49321
+ teamProgram.command("conflicts").description(
49322
+ "Inspect local claim conflicts and handoffs without mutating coordination"
49323
+ ).option("--task <namespace:id>", "Narrow the report to one shared TaskRef").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49324
+ process.exitCode = await teamConflicts(process.cwd(), options);
49325
+ });
49326
+ const teamTransportProgram = teamProgram.command("transport").description("Inspect and migrate the coordination authority");
49327
+ teamTransportProgram.command("status").description("Show active coordination transport and freshness").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49328
+ process.exitCode = await teamTransportStatus(process.cwd(), options);
49329
+ });
49330
+ teamTransportProgram.command("set <mode>").description(
49331
+ "Switch an empty coordination authority; otherwise use transport migrate"
49332
+ ).requiredOption(
49333
+ "--expected-config-revision <n>",
49334
+ "Current project config revision"
49335
+ ).option(
49336
+ "--remote <name>",
49337
+ "Git remote for a git-ref target (default: origin)"
49338
+ ).option("--dry-run", "Validate the empty-authority switch without writing").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (mode, options) => {
49339
+ process.exitCode = await teamTransportSet(process.cwd(), {
49340
+ ...options,
49341
+ mode
49342
+ });
49118
49343
  });
49119
- });
49120
- teamProgram.command("renew <claimId>").description("Renew one fresh claim lease").requiredOption("--expected-revision <n>", "Current claim revision").option("--ttl <duration>", "Lease duration: ms, s, m, h, or d").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (claimId, options) => {
49121
- process.exitCode = await teamClaimRenew(process.cwd(), {
49122
- ...options,
49123
- claimId
49344
+ teamTransportProgram.command("migrate").description("Journal a single-authority local/git-ref transport switch").requiredOption("--to <mode>", "Target authority: local or git-ref").requiredOption(
49345
+ "--expected-config-revision <n>",
49346
+ "Current project config revision"
49347
+ ).option(
49348
+ "--remote <name>",
49349
+ "Git remote for a git-ref target (default: origin)"
49350
+ ).option("--dry-run", "Validate and preview without writing authority state").option("--confirm", "Explicitly confirm the authority migration").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49351
+ process.exitCode = await teamTransportMigrate(process.cwd(), options);
49352
+ });
49353
+ teamTransportProgram.command("recover <operationId>").description("Repair forward or safely abort a transport migration").requiredOption(
49354
+ "--to <mode>",
49355
+ "Original target authority: local or git-ref"
49356
+ ).option("--remote <name>", "Original Git remote for a git-ref target").option("--abort", "Abort only before the target authority is established").option("--session <id>", "Original migration session ID").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (operationId, options) => {
49357
+ process.exitCode = await teamTransportRecover(
49358
+ process.cwd(),
49359
+ operationId,
49360
+ options
49361
+ );
49124
49362
  });
49125
- });
49126
- teamProgram.command("release <claimId>").description("Release one claim").requiredOption("--expected-revision <n>", "Current claim revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (claimId, options) => {
49127
- process.exitCode = await teamClaimRelease(process.cwd(), {
49128
- ...options,
49129
- claimId
49363
+ const teamSyncProgram = teamProgram.command("sync").description("Explicitly synchronize the git-ref coordination authority");
49364
+ teamSyncProgram.command("pull").description("Fetch, validate, and cache refs/mancode/team").option("--task <namespace:id>", "Narrow output to one shared TaskRef").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49365
+ process.exitCode = await teamSyncPull(process.cwd(), options);
49130
49366
  });
49131
- });
49132
- teamProgram.command("transfer <claimId>").description("Transfer a claim through a new successor identity").requiredOption("--to <actorId>", "Receiving joined participant actor ID").requiredOption("--expected-revision <n>", "Current claim revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (claimId, options) => {
49133
- process.exitCode = await teamClaimTransfer(process.cwd(), {
49134
- ...options,
49135
- claimId
49367
+ teamSyncProgram.command("push <namespace:id>").description("Publish one task bundle through a fresh ownership fence CAS").requiredOption(
49368
+ "--expected-task-revision <n>",
49369
+ "Current shared task revision"
49370
+ ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49371
+ process.exitCode = await teamSyncPush(process.cwd(), {
49372
+ ...options,
49373
+ task
49374
+ });
49375
+ });
49376
+ const teamIdentityProgram = teamProgram.command("identity").description("Manage the machine-local actor identity");
49377
+ teamIdentityProgram.command("create").description("Create one local actor identity").requiredOption("--name <displayName>", "Display name").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49378
+ process.exitCode = await teamIdentityCreate(process.cwd(), options);
49379
+ });
49380
+ teamIdentityProgram.command("show").description("Show local identity and whether it is joined").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49381
+ process.exitCode = await teamIdentityShow(process.cwd(), options);
49382
+ });
49383
+ const teamDecisionProgram = teamProgram.command("decision").description("Publish explicitly confirmed, privacy-safe shared decisions");
49384
+ teamDecisionProgram.command("publish").description("Publish one immutable confirmed decision").requiredOption("--title <text>", "Short decision title").requiredOption("--statement <text>", "Confirmed decision statement").option("--task <namespace:id>", "Optional shared TaskRef that produced it").requiredOption(
49385
+ "--confirm",
49386
+ "Confirm this decision may enter shared memory"
49387
+ ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49388
+ process.exitCode = await teamDecisionPublish(process.cwd(), options);
49389
+ });
49390
+ teamProgram.command("join").description(
49391
+ "Publish the approved shared actor profile after explicit confirmation"
49392
+ ).requiredOption(
49393
+ "--name <displayName>",
49394
+ "Must match the local actor identity"
49395
+ ).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Request explicit remote sync when transport supports it").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49396
+ process.exitCode = await teamJoin(process.cwd(), options);
49397
+ });
49398
+ teamProgram.command("checkpoint <namespace:id>").description("Create a journaled immutable checkpoint for a shared task").requiredOption(
49399
+ "--expected-task-revision <n>",
49400
+ "Current shared task revision"
49401
+ ).requiredOption("--kind <kind>", "Checkpoint kind").requiredOption("--summary <text>", "Privacy-safe checkpoint summary").option("--next-action <text>", "Next action for the receiving workflow").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49402
+ process.exitCode = await teamCheckpoint(process.cwd(), {
49403
+ ...options,
49404
+ task
49405
+ });
49136
49406
  });
49137
- });
49138
- teamProgram.command("reclaim <claimId>").description("Explicitly mark an expired claim terminal").requiredOption("--expected-revision <n>", "Current claim revision").requiredOption("--reason <text>", "Privacy-safe expiry reclaim reason").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (claimId, options) => {
49139
- process.exitCode = await teamClaimReclaim(process.cwd(), {
49140
- ...options,
49141
- claimId
49407
+ teamProgram.command("claim <namespace:id>").description("Acquire a scoped claim for a shared task").requiredOption(
49408
+ "--expected-task-revision <n>",
49409
+ "Current shared task revision"
49410
+ ).option("--path <glob>", "Repository-relative path glob", collectOption, []).option("--module <name>", "Implementation module", collectOption, []).option("--api <name>", "Public API boundary", collectOption, []).option("--schema <name>", "Shared schema boundary", collectOption, []).option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49411
+ process.exitCode = await teamClaim(process.cwd(), {
49412
+ ...options,
49413
+ task,
49414
+ paths: options.path,
49415
+ modules: options.module,
49416
+ apis: options.api,
49417
+ schemas: options.schema
49418
+ });
49142
49419
  });
49143
- });
49144
- teamProgram.command("revalidate <claimId>").description("Refresh one claim after task or code snapshot drift").requiredOption("--expected-revision <n>", "Current claim revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (claimId, options) => {
49145
- process.exitCode = await teamClaimRevalidate(process.cwd(), {
49146
- ...options,
49147
- claimId
49420
+ teamProgram.command("renew <claimId>").description("Renew one fresh claim lease").requiredOption("--expected-revision <n>", "Current claim revision").option("--ttl <duration>", "Lease duration: ms, s, m, h, or d").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (claimId, options) => {
49421
+ process.exitCode = await teamClaimRenew(process.cwd(), {
49422
+ ...options,
49423
+ claimId
49424
+ });
49148
49425
  });
49149
- });
49150
- var teamHandoffProgram = teamProgram.command("handoff").description("Create and transition journaled ownership handoffs");
49151
- teamHandoffProgram.command("draft <namespace:id>").description("Create a checkpoint-backed named handoff draft").requiredOption(
49152
- "--expected-task-revision <n>",
49153
- "Current shared task revision"
49154
- ).requiredOption("--to <actorId>", "Receiving joined participant actor ID").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49155
- process.exitCode = await teamHandoffDraft(process.cwd(), {
49156
- ...options,
49157
- task
49426
+ teamProgram.command("release <claimId>").description("Release one claim").requiredOption("--expected-revision <n>", "Current claim revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (claimId, options) => {
49427
+ process.exitCode = await teamClaimRelease(process.cwd(), {
49428
+ ...options,
49429
+ claimId
49430
+ });
49158
49431
  });
49159
- });
49160
- teamHandoffProgram.command("offer <handoffId>").description("Offer a handoff draft to its receiving actor").requiredOption("--expected-revision <n>", "Current handoff revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (handoffId, options) => {
49161
- process.exitCode = await teamHandoffOffer(process.cwd(), {
49162
- ...options,
49163
- handoffId
49432
+ teamProgram.command("transfer <claimId>").description("Transfer a claim through a new successor identity").requiredOption("--to <actorId>", "Receiving joined participant actor ID").requiredOption("--expected-revision <n>", "Current claim revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (claimId, options) => {
49433
+ process.exitCode = await teamClaimTransfer(process.cwd(), {
49434
+ ...options,
49435
+ claimId
49436
+ });
49164
49437
  });
49165
- });
49166
- teamHandoffProgram.command("accept <handoffId>").description("Accept an offered handoff and transfer ownership atomically").requiredOption("--expected-revision <n>", "Current handoff revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (handoffId, options) => {
49167
- process.exitCode = await teamHandoffAccept(process.cwd(), {
49168
- ...options,
49169
- handoffId
49438
+ teamProgram.command("reclaim <claimId>").description("Explicitly mark an expired claim terminal").requiredOption("--expected-revision <n>", "Current claim revision").requiredOption("--reason <text>", "Privacy-safe expiry reclaim reason").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (claimId, options) => {
49439
+ process.exitCode = await teamClaimReclaim(process.cwd(), {
49440
+ ...options,
49441
+ claimId
49442
+ });
49170
49443
  });
49171
- });
49172
- teamHandoffProgram.command("reject <handoffId>").description("Reject an offered handoff with a durable reason").requiredOption("--expected-revision <n>", "Current handoff revision").requiredOption("--reason <text>", "Reason for rejecting the handoff").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (handoffId, options) => {
49173
- process.exitCode = await teamHandoffReject(process.cwd(), {
49174
- ...options,
49175
- handoffId
49444
+ teamProgram.command("revalidate <claimId>").description("Refresh one claim after task or code snapshot drift").requiredOption("--expected-revision <n>", "Current claim revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (claimId, options) => {
49445
+ process.exitCode = await teamClaimRevalidate(process.cwd(), {
49446
+ ...options,
49447
+ claimId
49448
+ });
49176
49449
  });
49177
- });
49178
- teamHandoffProgram.command("cancel <handoffId>").description("Cancel a draft or offered handoff").requiredOption("--expected-revision <n>", "Current handoff revision").option("--reason <text>", "Optional cancellation reason").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (handoffId, options) => {
49179
- process.exitCode = await teamHandoffCancel(process.cwd(), {
49180
- ...options,
49181
- handoffId
49450
+ const teamHandoffProgram = teamProgram.command("handoff").description("Create and transition journaled ownership handoffs");
49451
+ teamHandoffProgram.command("draft <namespace:id>").description("Create a checkpoint-backed named handoff draft").requiredOption(
49452
+ "--expected-task-revision <n>",
49453
+ "Current shared task revision"
49454
+ ).requiredOption("--to <actorId>", "Receiving joined participant actor ID").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (task, options) => {
49455
+ process.exitCode = await teamHandoffDraft(process.cwd(), {
49456
+ ...options,
49457
+ task
49458
+ });
49182
49459
  });
49183
- });
49184
- var migrateProgram = program.command("migrate").description("Inspect and migrate legacy context into mancode staging");
49185
- var migrateContextProgram = migrateProgram.command("context").description("Manage the isolated legacy-to-mancode context migration stage").option("--dry-run", "Inspect legacy authority without writing files").option("--stage", "Create or refresh an isolated local migration stage").option("--status", "Show local migration stages").option("--activate", "Attempt the journaled mancode activation").option(
49186
- "--rollback <operationId>",
49187
- "Roll back an untouched mancode activation"
49188
- ).option("--stage-id <id>", "Migration stage ID (required if more than one)").option(
49189
- "--expected-stage-revision <n>",
49190
- "Expected stage revision for activation"
49191
- ).option("--session <id>", "Active session required for activation").option("--confirm", "Explicitly confirm the mancode cutover").option("--confirm-shared", "Confirm promotion of staged shared authority").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49192
- const code = await migrateContext(process.cwd(), options);
49193
- process.exitCode = code;
49194
- });
49195
- migrateContextProgram.command("resolve <legacyTaskId>").description("Resolve missing owner or implementation scope in one stage").requiredOption(
49196
- "--expected-stage-revision <n>",
49197
- "Expected local migration stage revision"
49198
- ).option("--stage-id <id>", "Migration stage ID (required if more than one)").option("--owner <actorId>", "Explicit owner actor ID").option(
49199
- "--scope-file <path>",
49200
- "JSON implementation scope {include,exclude,modules}"
49201
- ).option("--json", "Output as JSON (for scripts)").action(async (legacyTaskId, options) => {
49202
- const code = await migrateContextResolve(
49203
- process.cwd(),
49204
- legacyTaskId,
49205
- options
49206
- );
49207
- process.exitCode = code;
49208
- });
49209
- program.command("manps [area]").description("Run deterministic preseason health scan").option("--json", "Output as JSON (for scripts)").option("--remediate", "Review scan issues with y/n/skip prompts").action(async (area, options) => {
49210
- const code = await manps(process.cwd(), area ?? "all", options);
49211
- process.exitCode = code;
49212
- });
49213
- var designProgram = program.command("design").description("Inspect and configure project UI design policy");
49214
- designProgram.command("status").description("Show the configured and effective project design policy").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49215
- process.exitCode = await designStatus(process.cwd(), options);
49216
- });
49217
- designProgram.command("context").description("Emit bounded UI design context for coding agents").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49218
- process.exitCode = await designContext(process.cwd(), options);
49219
- });
49220
- designProgram.command("configure").description("CAS-update the optional project design policy").requiredOption(
49221
- "--expected-revision <n>",
49222
- "Current policy revision; use 0 when absent"
49223
- ).option("--preset <preset>", "preserve, refine, or experimental").option("--icons <policy>", "existing-first or lucide").option(
49224
- "--emoji <policy>",
49225
- "forbid-as-interface-icon; legacy allow is normalized"
49226
- ).option("--motion <policy>", "minimal or purposeful").option("--browser-validation <mode>", "off, when-available, or required").option("--confirm-experimental", "Explicitly allow the experimental preset").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49227
- process.exitCode = await designConfigure(process.cwd(), options);
49228
- });
49229
- designProgram.command("disable").description("Disable the project design policy without deleting it").requiredOption("--expected-revision <n>", "Current policy revision").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49230
- process.exitCode = await designDisable(process.cwd(), options);
49231
- });
49232
- program.command("refresh-style").description("Refresh project profile and rescan applicable design tokens").option("--root <path>", "Repository-relative UI project root").action(async (options) => {
49233
- const code = await refreshStyle(process.cwd(), options);
49234
- process.exitCode = code;
49235
- });
49236
- program.command("refresh-project").description(
49237
- "Refresh detected project facts after adding Git or project files"
49238
- ).action(async () => {
49239
- const code = await refreshProject(process.cwd());
49240
- process.exitCode = code;
49241
- });
49242
- program.command("version").description("Show version, node version, and platform").action(() => {
49243
- version();
49244
- });
49245
- program.parse();
49460
+ teamHandoffProgram.command("offer <handoffId>").description("Offer a handoff draft to its receiving actor").requiredOption("--expected-revision <n>", "Current handoff revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (handoffId, options) => {
49461
+ process.exitCode = await teamHandoffOffer(process.cwd(), {
49462
+ ...options,
49463
+ handoffId
49464
+ });
49465
+ });
49466
+ teamHandoffProgram.command("accept <handoffId>").description("Accept an offered handoff and transfer ownership atomically").requiredOption("--expected-revision <n>", "Current handoff revision").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (handoffId, options) => {
49467
+ process.exitCode = await teamHandoffAccept(process.cwd(), {
49468
+ ...options,
49469
+ handoffId
49470
+ });
49471
+ });
49472
+ teamHandoffProgram.command("reject <handoffId>").description("Reject an offered handoff with a durable reason").requiredOption("--expected-revision <n>", "Current handoff revision").requiredOption("--reason <text>", "Reason for rejecting the handoff").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (handoffId, options) => {
49473
+ process.exitCode = await teamHandoffReject(process.cwd(), {
49474
+ ...options,
49475
+ handoffId
49476
+ });
49477
+ });
49478
+ teamHandoffProgram.command("cancel <handoffId>").description("Cancel a draft or offered handoff").requiredOption("--expected-revision <n>", "Current handoff revision").option("--reason <text>", "Optional cancellation reason").option("--session <id>", "Session ID (otherwise MANCODE_SESSION_ID)").option("--client <name>", "Client identity (default: mancode-cli)").option("--sync", "Publish through the active git-ref authority").option("--json", "Output as JSON (for scripts)").action(async (handoffId, options) => {
49479
+ process.exitCode = await teamHandoffCancel(process.cwd(), {
49480
+ ...options,
49481
+ handoffId
49482
+ });
49483
+ });
49484
+ const migrateProgram = program.command("migrate").description("Inspect and migrate legacy context into mancode staging");
49485
+ const migrateContextProgram = migrateProgram.command("context").description(
49486
+ "Manage the isolated legacy-to-mancode context migration stage"
49487
+ ).option("--dry-run", "Inspect legacy authority without writing files").option("--stage", "Create or refresh an isolated local migration stage").option("--status", "Show local migration stages").option("--activate", "Attempt the journaled mancode activation").option(
49488
+ "--rollback <operationId>",
49489
+ "Roll back an untouched mancode activation"
49490
+ ).option("--stage-id <id>", "Migration stage ID (required if more than one)").option(
49491
+ "--expected-stage-revision <n>",
49492
+ "Expected stage revision for activation"
49493
+ ).option("--session <id>", "Active session required for activation").option("--confirm", "Explicitly confirm the mancode cutover").option("--confirm-shared", "Confirm promotion of staged shared authority").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49494
+ const code = await migrateContext(process.cwd(), options);
49495
+ process.exitCode = code;
49496
+ });
49497
+ migrateContextProgram.command("resolve <legacyTaskId>").description("Resolve missing owner or implementation scope in one stage").requiredOption(
49498
+ "--expected-stage-revision <n>",
49499
+ "Expected local migration stage revision"
49500
+ ).option("--stage-id <id>", "Migration stage ID (required if more than one)").option("--owner <actorId>", "Explicit owner actor ID").option(
49501
+ "--scope-file <path>",
49502
+ "JSON implementation scope {include,exclude,modules}"
49503
+ ).option("--json", "Output as JSON (for scripts)").action(async (legacyTaskId, options) => {
49504
+ const code = await migrateContextResolve(
49505
+ process.cwd(),
49506
+ legacyTaskId,
49507
+ options
49508
+ );
49509
+ process.exitCode = code;
49510
+ });
49511
+ program.command("manps [area]").description("Run deterministic preseason health scan").option("--json", "Output as JSON (for scripts)").option("--remediate", "Review scan issues with y/n/skip prompts").action(async (area, options) => {
49512
+ const code = await manps(process.cwd(), area ?? "all", options);
49513
+ process.exitCode = code;
49514
+ });
49515
+ const designProgram = program.command("design").description("Inspect and configure project UI design policy");
49516
+ designProgram.command("status").description("Show the configured and effective project design policy").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49517
+ process.exitCode = await designStatus(process.cwd(), options);
49518
+ });
49519
+ designProgram.command("context").description("Emit bounded UI design context for coding agents").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49520
+ process.exitCode = await designContext(process.cwd(), options);
49521
+ });
49522
+ designProgram.command("configure").description("CAS-update the optional project design policy").requiredOption(
49523
+ "--expected-revision <n>",
49524
+ "Current policy revision; use 0 when absent"
49525
+ ).option("--preset <preset>", "preserve, refine, or experimental").option("--icons <policy>", "existing-first or lucide").option(
49526
+ "--emoji <policy>",
49527
+ "forbid-as-interface-icon; legacy allow is normalized"
49528
+ ).option("--motion <policy>", "minimal or purposeful").option("--browser-validation <mode>", "off, when-available, or required").option(
49529
+ "--confirm-experimental",
49530
+ "Explicitly allow the experimental preset"
49531
+ ).option("--json", "Output as JSON (for scripts)").action(async (options) => {
49532
+ process.exitCode = await designConfigure(process.cwd(), options);
49533
+ });
49534
+ designProgram.command("disable").description("Disable the project design policy without deleting it").requiredOption("--expected-revision <n>", "Current policy revision").option("--json", "Output as JSON (for scripts)").action(async (options) => {
49535
+ process.exitCode = await designDisable(process.cwd(), options);
49536
+ });
49537
+ program.command("refresh-style").description("Refresh project profile and rescan applicable design tokens").option("--root <path>", "Repository-relative UI project root").action(async (options) => {
49538
+ const code = await refreshStyle(process.cwd(), options);
49539
+ process.exitCode = code;
49540
+ });
49541
+ program.command("refresh-project").description(
49542
+ "Refresh detected project facts after adding Git or project files"
49543
+ ).action(async () => {
49544
+ const code = await refreshProject(process.cwd());
49545
+ process.exitCode = code;
49546
+ });
49547
+ program.command("version").description("Show version, node version, and platform").action(() => {
49548
+ version();
49549
+ });
49550
+ return program;
49551
+ }
49552
+ if (isDirectExecution()) {
49553
+ createCliProgram().parse();
49554
+ }
49555
+ function isDirectExecution() {
49556
+ const entrypoint = process.argv[1];
49557
+ if (entrypoint === void 0) return false;
49558
+ try {
49559
+ return realpathSync(entrypoint) === realpathSync(fileURLToPath(import.meta.url));
49560
+ } catch {
49561
+ return false;
49562
+ }
49563
+ }
49246
49564
  function collectOption(value, previous) {
49247
49565
  return [...previous, value];
49248
49566
  }
49249
49567
  export {
49250
- program as cliProgram
49568
+ createCliProgram
49251
49569
  };
49252
49570
  //# sourceMappingURL=cli.js.map