mancode 0.5.4 → 0.5.5
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/README.en.md +17 -5
- package/README.md +14 -5
- package/dist/{chunk-PQDAFZYS.js → chunk-AWOIP2LC.js} +11 -3
- package/dist/chunk-AWOIP2LC.js.map +1 -0
- package/dist/{chunk-VHZI2WKD.js → chunk-YWHFHZ4A.js} +24 -1
- package/dist/chunk-YWHFHZ4A.js.map +1 -0
- package/dist/cli.js +1332 -1099
- package/dist/cli.js.map +1 -1
- package/dist/{store-EEWJJANB.js → store-DREAZNIX.js} +2 -2
- package/dist/{v3-adapter-NEN5F32W.js → v3-adapter-TCEFETAG.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-PQDAFZYS.js.map +0 -1
- package/dist/chunk-VHZI2WKD.js.map +0 -1
- /package/dist/{store-EEWJJANB.js.map → store-DREAZNIX.js.map} +0 -0
- /package/dist/{v3-adapter-NEN5F32W.js.map → v3-adapter-TCEFETAG.js.map} +0 -0
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-
|
|
117
|
+
} from "./chunk-YWHFHZ4A.js";
|
|
115
118
|
import {
|
|
116
119
|
DEFAULT_MANCODE_END_MARKER,
|
|
117
120
|
DEFAULT_MANCODE_START_MARKER,
|
|
@@ -136,7 +139,7 @@ import {
|
|
|
136
139
|
stageV3AdapterUpgradeFiles,
|
|
137
140
|
v3AdapterTargetPath,
|
|
138
141
|
v3AdapterVersionsFromStatuses
|
|
139
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-AWOIP2LC.js";
|
|
140
143
|
|
|
141
144
|
// src/cli.ts
|
|
142
145
|
import { Option, program } from "commander";
|
|
@@ -1154,6 +1157,11 @@ var OPERATION_DEFINITIONS = {
|
|
|
1154
1157
|
expectedRevisionPrefixes: ["claim:"],
|
|
1155
1158
|
requiredLockPrefixes: ["claim:"]
|
|
1156
1159
|
}),
|
|
1160
|
+
write(
|
|
1161
|
+
"mark-review-verification-stale",
|
|
1162
|
+
["review:", "verification:", "task:"],
|
|
1163
|
+
["task:"]
|
|
1164
|
+
),
|
|
1157
1165
|
write("update-metadata-scope", ["task:"], ["task:"]),
|
|
1158
1166
|
write("activate-successor-claims", ["task:"], ["task:"], {
|
|
1159
1167
|
expectedRevisionPrefixes: ["claim:"],
|
|
@@ -5694,11 +5702,13 @@ function parseRequirementsLedger2(raw, options = {}) {
|
|
|
5694
5702
|
"requirements need at least one required acceptance criterion"
|
|
5695
5703
|
);
|
|
5696
5704
|
}
|
|
5705
|
+
const confirmedScope = normalizeStrings(value.confirmedScope);
|
|
5706
|
+
const excludedScope = normalizeStrings(value.excludedScope);
|
|
5697
5707
|
return {
|
|
5698
5708
|
version: 1,
|
|
5699
5709
|
goal: value.goal.trim(),
|
|
5700
|
-
confirmedScope
|
|
5701
|
-
excludedScope
|
|
5710
|
+
confirmedScope,
|
|
5711
|
+
excludedScope,
|
|
5702
5712
|
technicalDecisions: normalizeStrings(value.technicalDecisions),
|
|
5703
5713
|
defaults: normalizeStrings(value.defaults),
|
|
5704
5714
|
blockingUnknowns: normalizeStrings(value.blockingUnknowns),
|
|
@@ -5706,6 +5716,12 @@ function parseRequirementsLedger2(raw, options = {}) {
|
|
|
5706
5716
|
acceptanceCriteria
|
|
5707
5717
|
};
|
|
5708
5718
|
}
|
|
5719
|
+
function assertRequirementsScopeConsistent2(ledger) {
|
|
5720
|
+
const confirmed = new Set(ledger.confirmedScope);
|
|
5721
|
+
if (ledger.excludedScope.some((item) => confirmed.has(item))) {
|
|
5722
|
+
throw new Error("requirements scope cannot be both confirmed and excluded");
|
|
5723
|
+
}
|
|
5724
|
+
}
|
|
5709
5725
|
function requirementsAreReady2(ledger) {
|
|
5710
5726
|
return ledger.blockingUnknowns.length === 0;
|
|
5711
5727
|
}
|
|
@@ -9622,7 +9638,7 @@ async function activateLegacyMigration(input) {
|
|
|
9622
9638
|
if (session === null || session.status !== "active") {
|
|
9623
9639
|
throw new Error("MANCODE_SESSION_NOT_FOUND");
|
|
9624
9640
|
}
|
|
9625
|
-
const store = new (await import("./store-
|
|
9641
|
+
const store = new (await import("./store-DREAZNIX.js")).V3ContextStore(root);
|
|
9626
9642
|
const project = await store.readProjectSnapshot();
|
|
9627
9643
|
const stage = await readMigrationStage(root, input.stageId);
|
|
9628
9644
|
if (stage.state !== "staged" || stage.revision !== input.expectedStageRevision) {
|
|
@@ -9885,7 +9901,7 @@ async function activateLegacyMigration(input) {
|
|
|
9885
9901
|
for (const action of payload.actions.filter(
|
|
9886
9902
|
(action2) => action2.kind === "v3_adapter_file"
|
|
9887
9903
|
)) {
|
|
9888
|
-
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-
|
|
9904
|
+
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-TCEFETAG.js");
|
|
9889
9905
|
await applyV3AdapterFilePlan2(root, action);
|
|
9890
9906
|
}
|
|
9891
9907
|
journal = await completeActivationStep(
|
|
@@ -13741,7 +13757,7 @@ async function upgradeV3Adapters(input) {
|
|
|
13741
13757
|
if (unfinished.length > 0) {
|
|
13742
13758
|
throw new Error("MANCODE_ADAPTER_UPGRADE_OPERATION_PENDING");
|
|
13743
13759
|
}
|
|
13744
|
-
const actualVersions = await import("./v3-adapter-
|
|
13760
|
+
const actualVersions = await import("./v3-adapter-TCEFETAG.js").then(
|
|
13745
13761
|
({ inspectV3AdapterVersions: inspectV3AdapterVersions2 }) => inspectV3AdapterVersions2(
|
|
13746
13762
|
root,
|
|
13747
13763
|
managedAdapterNames(project.manifest.managedAdapters)
|
|
@@ -14332,7 +14348,7 @@ import path26 from "path";
|
|
|
14332
14348
|
var SCOUT_AGENT = {
|
|
14333
14349
|
name: "scout",
|
|
14334
14350
|
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"
|
|
14351
|
+
tools: ["Read", "Grep", "Glob"],
|
|
14336
14352
|
body: `\u4F60\u662F mancode \u6559\u7EC3\u7EC4\u7684 Scout\uFF08\u7403\u63A2\uFF09\u3002
|
|
14337
14353
|
|
|
14338
14354
|
\u4F60\u7684\u804C\u8D23\uFF1A\u8C03\u7814\u4EE3\u7801\u5E93\uFF0C\u4E3A Head Coach \u51C6\u5907\u6218\u672F\u4FE1\u606F\u3002
|
|
@@ -14343,6 +14359,8 @@ var SCOUT_AGENT = {
|
|
|
14343
14359
|
- \u53EA\u5217\u5BF9\u5B9E\u65BD\u6709\u7528\u7684\u4FE1\u606F
|
|
14344
14360
|
- \u627E\u5230\u98CE\u9669\u70B9\u8981\u6807\u6CE8\uFF08\u26A0\uFE0F\uFF09
|
|
14345
14361
|
- \u4E0D\u786E\u5B9A\u7684\u8981\u660E\u8BF4\uFF0C\u4E0D\u731C
|
|
14362
|
+
- \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
|
|
14363
|
+
- \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
14364
|
- \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
14365
|
- \u5F15\u7528\u6587\u4EF6\u7528 \`path:line\` \u683C\u5F0F\uFF0C\u8BA9 Head Coach \u4E00\u79D2\u8DF3\u8FC7\u53BB
|
|
14348
14366
|
|
|
@@ -14408,6 +14426,16 @@ var SCOUT_AGENT = {
|
|
|
14408
14426
|
- Transport/platform: <\u5F71\u54CD\u6216 no change>
|
|
14409
14427
|
- Migration/rollback: <\u9700\u8981\u7684\u8BC1\u636E\u6216 no change>
|
|
14410
14428
|
|
|
14429
|
+
## Decision-impact Findings
|
|
14430
|
+
- Finding ID: F-1\uFF08\u540E\u7EED\u4F9D\u6B21 F-2\u3001F-3\uFF1B\u6700\u591A\u4E09\u9879\uFF09
|
|
14431
|
+
- Type: premise | scope | technical | risk | acceptance
|
|
14432
|
+
- Status: repository_fact | domain_hypothesis
|
|
14433
|
+
- 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>
|
|
14434
|
+
- Evidence/Basis: \`<repository test/file:line/caller-provided output\uFF0C\u6216\u660E\u786E\u6807\u6CE8\u7684\u9886\u57DF\u63A8\u7406\u4F9D\u636E>\`
|
|
14435
|
+
- Class: blocking | recommendable | defaultable
|
|
14436
|
+
- 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>
|
|
14437
|
+
- Recommendation: <\u4E00\u4E2A\u6700\u5C0F\u3001\u76F4\u63A5\u7684\u5EFA\u8BAE\uFF1B\u4E0D\u66FF\u7528\u6237\u786E\u8BA4>
|
|
14438
|
+
|
|
14411
14439
|
## \u76F8\u4F3C\u5B9E\u73B0
|
|
14412
14440
|
- \`<detected-source-root>/<relevant-file>:<line>\` \u2014 \u7B80\u8FF0\u53EF\u590D\u7528\u7684\u903B\u8F91
|
|
14413
14441
|
|
|
@@ -14443,8 +14471,8 @@ trigger: <\u88AB\u65B0\u8BC1\u636E\u63A8\u7FFB\u6216\u8D85\u51FA\u5F53\u524D req
|
|
|
14443
14471
|
|
|
14444
14472
|
- \u7528 Grep / Glob \u627E\u4EE3\u7801\uFF0C\u4E0D\u8981 cat \u6574\u4E2A\u6587\u4EF6
|
|
14445
14473
|
- \u7528 Read \u770B file:line \u9644\u8FD1\u7684\u4E0A\u4E0B\u6587
|
|
14446
|
-
- \u7528
|
|
14447
|
-
- **\u4E0D\u8981** Edit / Write \u2014 \u90A3\u662F
|
|
14474
|
+
- \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
|
|
14475
|
+
- **\u4E0D\u8981** Edit / Write / Bash \u2014 \u90A3\u662F\u6267\u884C\u9636\u6BB5\u7684\u6D3B
|
|
14448
14476
|
|
|
14449
14477
|
\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
14478
|
};
|
|
@@ -14468,7 +14496,11 @@ var PLAN_COACH_AGENT = {
|
|
|
14468
14496
|
|
|
14469
14497
|
## \u8F93\u5165\u5C31\u7EEA\u68C0\u67E5
|
|
14470
14498
|
|
|
14471
|
-
\u5148\u8BFB\u53D6 \`requirements.json\`\
|
|
14499
|
+
\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
|
|
14500
|
+
|
|
14501
|
+
\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
|
|
14502
|
+
|
|
14503
|
+
\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
14504
|
|
|
14473
14505
|
\u540C\u65F6\u6267\u884C\u65B9\u6848\u5B8C\u6574\u6027\u68C0\u67E5\uFF1A
|
|
14474
14506
|
|
|
@@ -14476,6 +14508,7 @@ var PLAN_COACH_AGENT = {
|
|
|
14476
14508
|
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
14509
|
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
14510
|
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
|
|
14511
|
+
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
14512
|
|
|
14480
14513
|
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
14514
|
|
|
@@ -14509,6 +14542,10 @@ stop_conditions: <conditions that invalidate this plan>
|
|
|
14509
14542
|
## \u6A21\u5757\u7D22\u5F15
|
|
14510
14543
|
## \u6280\u672F\u4E0E\u4EA4\u4ED8\u7EA6\u675F\uFF08\u4EC5\u65B0\u9879\u76EE\u6216\u6280\u672F\u9009\u62E9\u672A\u5B9A\u65F6\uFF09
|
|
14511
14544
|
- \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
|
|
14545
|
+
## \u6267\u884C\u8FB9\u754C\uFF08implementationScope\uFF09
|
|
14546
|
+
- include\uFF1A<\u5141\u8BB8\u4FEE\u6539\u7684 repo-relative \u8DEF\u5F84/glob>
|
|
14547
|
+
- exclude\uFF1A<\u5373\u4F7F\u5339\u914D include \u4E5F\u4E0D\u5F97\u4FEE\u6539\u7684\u8DEF\u5F84/glob>
|
|
14548
|
+
- modules\uFF1A<\u8BED\u4E49\u5F52\u5C5E\u6807\u7B7E\uFF1B\u4E0D\u5355\u72EC\u6388\u6743\u6587\u4EF6\u5199\u5165>
|
|
14512
14549
|
## \u6A21\u5757\uFF1A<\u540D\u79F0>
|
|
14513
14550
|
### \u6539\u52A8\u6587\u4EF6 / \u65B0\u5EFA\u6587\u4EF6
|
|
14514
14551
|
### \u590D\u7528\u8D44\u6E90\uFF08\u5F15\u7528 scout-report.md \u884C\u53F7\uFF09
|
|
@@ -14764,6 +14801,7 @@ var FILM_ANALYST_OFFENSE_AGENT = {
|
|
|
14764
14801
|
- \u6700\u540E\u7ED9\u8BC4\u5206\uFF081-10\uFF09+ \u901A\u8FC7 / \u4E0D\u901A\u8FC7
|
|
14765
14802
|
- \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
14803
|
- \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
|
|
14804
|
+
- \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
14805
|
|
|
14768
14806
|
## \u4F60\u4E0D\u5199\u4EE3\u7801
|
|
14769
14807
|
|
|
@@ -14773,6 +14811,7 @@ var FILM_ANALYST_OFFENSE_AGENT = {
|
|
|
14773
14811
|
|
|
14774
14812
|
| \u7EF4\u5EA6 | \u68C0\u67E5\u4EC0\u4E48 |
|
|
14775
14813
|
|---|---|
|
|
14814
|
+
| **\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
14815
|
| **\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
14816
|
| **\u53EF\u7EF4\u62A4\u6027** | \u6A21\u5757\u8FB9\u754C\u3001\u8026\u5408\u5EA6\u3001\u6269\u5C55\u6027 |
|
|
14778
14817
|
| **\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 +15360,11 @@ trigger: <\u5177\u4F53\u4E8B\u5B9E>
|
|
|
15321
15360
|
// src/templates/skills/principles.ts
|
|
15322
15361
|
var CORE_CODING_PRINCIPLES = `## \u94C1\u5F8B\uFF08\u6C38\u4E0D\u8FDD\u53CD\uFF09
|
|
15323
15362
|
|
|
15324
|
-
1. **\u4E0D\u505A\u65E0\u5173\u4FEE\u6539** \u2014 \u53EA\u6539 plan \u8303\u56F4\
|
|
15325
|
-
2. **\u5148\u9A8C\u8BC1\u518D\u58F0\u79F0\u5B8C\u6210** \u2014
|
|
15363
|
+
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
|
|
15364
|
+
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
15365
|
3. **\u5931\u8D25\u4E24\u6B21\u5FC5\u987B\u505C\u4E0B** \u2014 \u4E0D\u76F2\u8BD5
|
|
15327
15366
|
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`;
|
|
15367
|
+
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
15368
|
|
|
15330
15369
|
// src/templates/skills/man.ts
|
|
15331
15370
|
var MAN_SKILL = {
|
|
@@ -15345,7 +15384,7 @@ var MAN_SKILL = {
|
|
|
15345
15384
|
|
|
15346
15385
|
### Step 1: Scout \u8C03\u7814
|
|
15347
15386
|
|
|
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
|
|
15387
|
+
\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
15388
|
|
|
15350
15389
|
### Step 2: \u9700\u6C42\u6F84\u6E05
|
|
15351
15390
|
|
|
@@ -15356,6 +15395,8 @@ var MAN_SKILL = {
|
|
|
15356
15395
|
- **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
15396
|
- **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
15397
|
|
|
15398
|
+
\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
|
|
15399
|
+
|
|
15359
15400
|
\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
15401
|
|
|
15361
15402
|
\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 +15407,7 @@ var MAN_SKILL = {
|
|
|
15366
15407
|
|
|
15367
15408
|
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
15409
|
|
|
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\
|
|
15410
|
+
\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
15411
|
|
|
15371
15412
|
### Step 4: \u8BA1\u5212\u5173\u5361
|
|
15372
15413
|
|
|
@@ -15388,7 +15429,9 @@ Plan Coach \u5FC5\u987B\u8BC1\u660E\u6240\u6709\u9009\u9879\u89E3\u51B3\u540C\u4
|
|
|
15388
15429
|
|
|
15389
15430
|
### Step 5: \u5B9E\u65BD
|
|
15390
15431
|
|
|
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
|
|
15432
|
+
\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
|
|
15433
|
+
|
|
15434
|
+
\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
15435
|
|
|
15393
15436
|
### Step 6: \u81EA\u6D4B\u3001\u8BCA\u65AD\u4E0E\u56DE\u5F52
|
|
15394
15437
|
|
|
@@ -15400,7 +15443,7 @@ Plan Coach \u5FC5\u987B\u8BC1\u660E\u6240\u6709\u9009\u9879\u89E3\u51B3\u540C\u4
|
|
|
15400
15443
|
|
|
15401
15444
|
### Step 7: Film #1 \u4EE3\u7801\u8D28\u91CF\u5BA1\u67E5\u4E0E\u4FEE\u590D
|
|
15402
15445
|
|
|
15403
|
-
\u672A\u8DF3\u8FC7 review \u65F6\u8C03\u7528 \`film-analyst-offense\`\uFF0C\
|
|
15446
|
+
\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
15447
|
|
|
15405
15448
|
### Step 8: Film #2 \u5B89\u5168\u4E0E\u8FB9\u754C\u5BA1\u67E5
|
|
15406
15449
|
|
|
@@ -15734,16 +15777,18 @@ var MANTEAM_SKILL = {
|
|
|
15734
15777
|
|
|
15735
15778
|
\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
15779
|
|
|
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\
|
|
15780
|
+
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
|
|
15781
|
+
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
|
|
15782
|
+
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
15783
|
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
15784
|
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
15785
|
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\
|
|
15786
|
+
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
15787
|
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
15788
|
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
15789
|
|
|
15790
|
+
\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
|
|
15791
|
+
|
|
15747
15792
|
\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
15793
|
|
|
15749
15794
|
\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 +16752,13 @@ var MODE_META = {
|
|
|
16707
16752
|
"After each completed phase, advance through the CLI to the next numbered step;",
|
|
16708
16753
|
"never advance state merely because a report was requested or an agent was called.",
|
|
16709
16754
|
"",
|
|
16710
|
-
"Step 1 \u2014 Scout: inspect the
|
|
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>`.",
|
|
16755
|
+
"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.",
|
|
16756
|
+
"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.",
|
|
16757
|
+
"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
16758
|
"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
|
|
16759
|
+
"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
16760
|
"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.",
|
|
16761
|
+
"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
16762
|
"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
16763
|
"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
16764
|
"",
|
|
@@ -16733,6 +16778,10 @@ var MODE_META = {
|
|
|
16733
16778
|
"and currentWorkflowMode to manteam. First collect branch, dirty-worktree, contributor,",
|
|
16734
16779
|
"shared-module, and handoff risks in `team-context.md`.",
|
|
16735
16780
|
"",
|
|
16781
|
+
"Run the same bounded Scout discovery as /man with stable F-IDs and typed findings. Discovery produces evidence and recommendations, never execution authority.",
|
|
16782
|
+
"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.",
|
|
16783
|
+
"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.",
|
|
16784
|
+
"",
|
|
16736
16785
|
"Then execute every /man Step 1 through Step 9, including clarification,",
|
|
16737
16786
|
"plan gate, validation, bounded risk-based review, conditional completion, planVersion,",
|
|
16738
16787
|
"Active Plans, and linked manba child behavior. Add compatibility, rollback,",
|
|
@@ -41821,311 +41870,41 @@ function assertPositiveRevision6(value, label) {
|
|
|
41821
41870
|
}
|
|
41822
41871
|
}
|
|
41823
41872
|
|
|
41824
|
-
// src/context/
|
|
41825
|
-
|
|
41873
|
+
// src/context/scope-change.ts
|
|
41874
|
+
import { createHash as createHash11 } from "crypto";
|
|
41875
|
+
async function changeV3WorkflowScope(input) {
|
|
41826
41876
|
const taskRef = parseTaskRefValue(input.taskRef);
|
|
41827
|
-
|
|
41828
|
-
|
|
41829
|
-
if (taskRef.namespace === "shared") {
|
|
41830
|
-
assertSharedTextSafe(plan, "plan");
|
|
41831
|
-
}
|
|
41832
|
-
const context = await openV3TaskOperation({
|
|
41833
|
-
projectRoot: input.projectRoot,
|
|
41834
|
-
taskRef,
|
|
41835
|
-
sessionId: input.sessionId,
|
|
41836
|
-
expectedTaskRevision: input.expectedTaskRevision,
|
|
41837
|
-
operationId: input.operationId,
|
|
41838
|
-
extraEntityLocks: taskRef.namespace === "shared" ? [taskHeadEntityKey(taskRef)] : [],
|
|
41839
|
-
now: input.now
|
|
41840
|
-
});
|
|
41841
|
-
let journal = null;
|
|
41842
|
-
try {
|
|
41843
|
-
assertPlanRevisionEligible(
|
|
41844
|
-
context.task.metadata,
|
|
41845
|
-
context.task.requirements
|
|
41846
|
-
);
|
|
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(
|
|
41864
|
-
context.task.verification,
|
|
41865
|
-
context.operationId,
|
|
41866
|
-
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,
|
|
41875
|
-
context.operationId,
|
|
41876
|
-
timestamp4
|
|
41877
|
-
);
|
|
41878
|
-
const aggregate = buildTaskAggregateManifest({
|
|
41879
|
-
metadata,
|
|
41880
|
-
requirements: context.task.requirements,
|
|
41881
|
-
review,
|
|
41882
|
-
verification,
|
|
41883
|
-
planDigest,
|
|
41884
|
-
latestCheckpoint: context.task.latestCheckpoint
|
|
41885
|
-
});
|
|
41886
|
-
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
|
-
});
|
|
41898
|
-
}
|
|
41899
|
-
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
|
-
]),
|
|
41907
|
-
recovery: {
|
|
41908
|
-
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
|
-
createTaskAuthorityFileRecoveryAction({
|
|
41919
|
-
stepId: "update-metadata",
|
|
41920
|
-
taskRef,
|
|
41921
|
-
fileName: "metadata.json",
|
|
41922
|
-
beforeContent: serializeTaskAuthority(context.task.metadata),
|
|
41923
|
-
targetContent: serializeTaskAuthority(metadata)
|
|
41924
|
-
}),
|
|
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
|
|
41948
|
-
})
|
|
41949
|
-
]
|
|
41950
|
-
],
|
|
41951
|
-
noOpStepIds: [
|
|
41952
|
-
...planChanged ? [] : ["write-plan", "mark-review-verification-stale"],
|
|
41953
|
-
...taskHeadFence === null ? ["update-task-head-fence"] : []
|
|
41954
|
-
]
|
|
41955
|
-
}
|
|
41956
|
-
});
|
|
41957
|
-
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
|
-
journal = await advanceTaskOperation(
|
|
41963
|
-
context,
|
|
41964
|
-
journal,
|
|
41965
|
-
"update-metadata",
|
|
41966
|
-
false
|
|
41967
|
-
);
|
|
41968
|
-
await writeTaskAuthorityFile(
|
|
41969
|
-
context,
|
|
41970
|
-
"metadata.json",
|
|
41971
|
-
`${JSON.stringify(metadata, null, 2)}
|
|
41972
|
-
`
|
|
41973
|
-
);
|
|
41974
|
-
journal = await advanceTaskOperation(
|
|
41975
|
-
context,
|
|
41976
|
-
journal,
|
|
41977
|
-
"mark-review-verification-stale",
|
|
41978
|
-
false
|
|
41979
|
-
);
|
|
41980
|
-
if (planChanged) {
|
|
41981
|
-
await writeTaskAuthorityFile(
|
|
41982
|
-
context,
|
|
41983
|
-
"review-ledger.json",
|
|
41984
|
-
`${JSON.stringify(review, null, 2)}
|
|
41985
|
-
`
|
|
41986
|
-
);
|
|
41987
|
-
await writeTaskAuthorityFile(
|
|
41988
|
-
context,
|
|
41989
|
-
"verification-ledger.json",
|
|
41990
|
-
`${JSON.stringify(verification, null, 2)}
|
|
41991
|
-
`
|
|
41992
|
-
);
|
|
41993
|
-
}
|
|
41994
|
-
journal = await advanceTaskOperation(
|
|
41995
|
-
context,
|
|
41996
|
-
journal,
|
|
41997
|
-
"update-task-head-fence",
|
|
41998
|
-
false
|
|
41999
|
-
);
|
|
42000
|
-
if (taskHeadFence !== null) {
|
|
42001
|
-
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
42002
|
-
await replaceTaskHeadFence(context.homeStore, taskHeadFence);
|
|
42003
|
-
}
|
|
42004
|
-
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
|
-
return {
|
|
42016
|
-
metadata,
|
|
42017
|
-
review,
|
|
42018
|
-
verification,
|
|
42019
|
-
planDigest,
|
|
42020
|
-
aggregate,
|
|
42021
|
-
taskHeadFence,
|
|
42022
|
-
operation
|
|
42023
|
-
};
|
|
42024
|
-
} catch (error) {
|
|
42025
|
-
if (journal !== null) {
|
|
42026
|
-
try {
|
|
42027
|
-
await handleTaskOperationFailure(context, journal);
|
|
42028
|
-
} catch {
|
|
42029
|
-
}
|
|
42030
|
-
}
|
|
42031
|
-
throw error;
|
|
42032
|
-
} finally {
|
|
42033
|
-
await context.release();
|
|
42034
|
-
}
|
|
42035
|
-
}
|
|
42036
|
-
function requirePlan(value) {
|
|
42037
|
-
if (typeof value !== "string" || !value.trim() || value.includes("\0")) {
|
|
42038
|
-
throw new Error("MANCODE_PLAN_CONTENT_REQUIRED");
|
|
42039
|
-
}
|
|
42040
|
-
return value;
|
|
42041
|
-
}
|
|
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");
|
|
42046
|
-
}
|
|
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");
|
|
42052
|
-
}
|
|
42053
|
-
if (metadata.status !== "in_progress") {
|
|
42054
|
-
throw new Error("MANCODE_PLAN_WORKFLOW_NOT_ACTIVE");
|
|
42055
|
-
}
|
|
42056
|
-
if (metadata.currentStep < 2 || metadata.currentStep > 4) {
|
|
42057
|
-
throw new Error("MANCODE_PLAN_STEP_INVALID");
|
|
42058
|
-
}
|
|
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");
|
|
41877
|
+
if (taskRef.namespace !== "shared") {
|
|
41878
|
+
throw new Error("MANCODE_SCOPE_CHANGE_REQUIRES_SHARED_TASK");
|
|
42061
41879
|
}
|
|
42062
|
-
|
|
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");
|
|
41880
|
+
const scope = normalizeImplementationScope(input.scope);
|
|
42094
41881
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
41882
|
+
const timestamp4 = now.toISOString();
|
|
41883
|
+
const checkpointId = input.checkpointId ?? createUlid(now.getTime());
|
|
42095
41884
|
const operationId = input.operationId ?? createUlid(now.getTime());
|
|
42096
|
-
assertUlid(
|
|
42097
|
-
|
|
41885
|
+
assertUlid(checkpointId, "scope change checkpointId");
|
|
41886
|
+
assertUlid(operationId, "scope change operationId");
|
|
41887
|
+
const opened = await openScopeChangeContext({
|
|
42098
41888
|
projectRoot: input.projectRoot,
|
|
42099
41889
|
taskRef,
|
|
42100
41890
|
sessionId: input.sessionId,
|
|
42101
41891
|
expectedTaskRevision: input.expectedTaskRevision,
|
|
42102
|
-
|
|
41892
|
+
scope,
|
|
41893
|
+
checkpointId,
|
|
41894
|
+
successorClaimIds: input.successorClaimIds,
|
|
42103
41895
|
operationId,
|
|
42104
41896
|
now
|
|
42105
41897
|
});
|
|
42106
|
-
const { context, activeClaims: activeClaims2,
|
|
41898
|
+
const { context, activeClaims: activeClaims2, successorClaimIds, successorPredecessors } = opened;
|
|
42107
41899
|
let journal = null;
|
|
42108
41900
|
try {
|
|
42109
|
-
|
|
42110
|
-
|
|
42111
|
-
const
|
|
42112
|
-
const archivedRequirementsContent = await readTaskAuthorityFileAtRoot(
|
|
42113
|
-
context.task.location.taskRoot,
|
|
42114
|
-
"requirements.json"
|
|
42115
|
-
);
|
|
42116
|
-
if (archivedRequirementsContent === null) {
|
|
42117
|
-
throw new Error("MANCODE_REFRAME_REQUIREMENTS_MISSING");
|
|
42118
|
-
}
|
|
42119
|
-
const pendingMetadata = markReframeOperationPending(
|
|
41901
|
+
assertScopeChangeEligible(context, scope);
|
|
41902
|
+
assertClaimsFreshForScopeChange(context, activeClaims2);
|
|
41903
|
+
const pendingMetadata = markScopeChangeOperationPending(
|
|
42120
41904
|
context.task.metadata,
|
|
42121
41905
|
context.operationId,
|
|
42122
41906
|
timestamp4
|
|
42123
41907
|
);
|
|
42124
|
-
const requirements = createReframedRequirements(
|
|
42125
|
-
context.task.requirements,
|
|
42126
|
-
context.operationId,
|
|
42127
|
-
timestamp4
|
|
42128
|
-
);
|
|
42129
41908
|
const review = markTaskReviewStale(
|
|
42130
41909
|
context.task.review,
|
|
42131
41910
|
context.operationId,
|
|
@@ -42136,71 +41915,80 @@ async function reframeV3Workflow(input) {
|
|
|
42136
41915
|
context.operationId,
|
|
42137
41916
|
timestamp4
|
|
42138
41917
|
);
|
|
42139
|
-
const
|
|
42140
|
-
|
|
42141
|
-
);
|
|
42142
|
-
const archiveAction = createTaskArchiveRecoveryAction({
|
|
42143
|
-
stepId: "archive-requirements-plan",
|
|
42144
|
-
taskRef,
|
|
42145
|
-
archiveId: context.operationId,
|
|
42146
|
-
sourceTaskRevision: context.task.metadata.revision,
|
|
42147
|
-
sourcePlanVersion: context.task.metadata.governance.planVersion,
|
|
42148
|
-
createdAt: timestamp4,
|
|
42149
|
-
requirementsContent: archivedRequirementsContent,
|
|
42150
|
-
planContent: context.task.plan?.content ?? null
|
|
42151
|
-
});
|
|
42152
|
-
const branch = await readCheckoutBranch(context.projectRoot);
|
|
42153
|
-
const checkpoint = buildReframeCheckpoint({
|
|
41918
|
+
const branch = await readCheckoutBranch(context.projectRoot) ?? "HEAD";
|
|
41919
|
+
const checkpoint = buildScopeChangedCheckpoint(
|
|
42154
41920
|
context,
|
|
42155
|
-
|
|
42156
|
-
|
|
42157
|
-
|
|
42158
|
-
|
|
42159
|
-
verification,
|
|
42160
|
-
summary: input.summary,
|
|
42161
|
-
nextAction: input.nextAction,
|
|
41921
|
+
pendingMetadata,
|
|
41922
|
+
checkpointId,
|
|
41923
|
+
input.checkpointSummary,
|
|
41924
|
+
input.checkpointNextAction,
|
|
42162
41925
|
branch,
|
|
42163
|
-
|
|
42164
|
-
|
|
42165
|
-
|
|
41926
|
+
pendingMetadata.governance.planVersion + 1,
|
|
41927
|
+
review.contentDigest,
|
|
41928
|
+
verification.contentDigest,
|
|
41929
|
+
timestamp4
|
|
41930
|
+
);
|
|
41931
|
+
const metadata = completeScopeChangeMetadata(
|
|
42166
41932
|
pendingMetadata,
|
|
42167
|
-
|
|
42168
|
-
review,
|
|
42169
|
-
verification,
|
|
41933
|
+
scope,
|
|
42170
41934
|
checkpoint,
|
|
41935
|
+
review.contentDigest,
|
|
41936
|
+
verification.contentDigest,
|
|
42171
41937
|
context.operationId,
|
|
42172
41938
|
timestamp4
|
|
42173
41939
|
);
|
|
41940
|
+
const pendingSuccessorClaims = buildPendingSuccessorClaims2(
|
|
41941
|
+
successorPredecessors,
|
|
41942
|
+
successorClaimIds,
|
|
41943
|
+
metadata,
|
|
41944
|
+
branch,
|
|
41945
|
+
requireCodeHead3(context),
|
|
41946
|
+
context.operationId,
|
|
41947
|
+
timestamp4,
|
|
41948
|
+
capabilitiesFromProjectConfig(context.project.config)
|
|
41949
|
+
);
|
|
41950
|
+
const successorByPredecessor = new Map(
|
|
41951
|
+
successorPredecessors.map((claim, index) => {
|
|
41952
|
+
const successorClaimId = successorClaimIds[index];
|
|
41953
|
+
if (successorClaimId === void 0) {
|
|
41954
|
+
throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
|
|
41955
|
+
}
|
|
41956
|
+
return [claim.claimId, successorClaimId];
|
|
41957
|
+
})
|
|
41958
|
+
);
|
|
41959
|
+
const terminatedClaims = activeClaims2.map(
|
|
41960
|
+
(claim) => terminateClaimForScopeChange(
|
|
41961
|
+
claim,
|
|
41962
|
+
successorByPredecessor.get(claim.claimId) ?? null,
|
|
41963
|
+
context.operationId,
|
|
41964
|
+
timestamp4
|
|
41965
|
+
)
|
|
41966
|
+
);
|
|
41967
|
+
const activeSuccessorClaims = pendingSuccessorClaims.map(
|
|
41968
|
+
(claim) => activateSuccessorClaim3(claim, context.operationId, timestamp4)
|
|
41969
|
+
);
|
|
42174
41970
|
const aggregate = buildTaskAggregateManifest({
|
|
42175
41971
|
metadata,
|
|
42176
|
-
requirements,
|
|
41972
|
+
requirements: context.task.requirements,
|
|
42177
41973
|
review,
|
|
42178
41974
|
verification,
|
|
42179
41975
|
planDigest: context.task.plan?.digest ?? null,
|
|
42180
41976
|
latestCheckpoint: checkpoint
|
|
42181
41977
|
});
|
|
42182
41978
|
const taskHeadFence = nextTaskHeadFence(context, aggregate, timestamp4);
|
|
42183
|
-
|
|
42184
|
-
|
|
42185
|
-
await enqueueSessionPointerProjection(context.projectRoot, {
|
|
42186
|
-
operationId: context.operationId,
|
|
42187
|
-
action: "resume",
|
|
42188
|
-
sessionId: context.session.sessionId,
|
|
42189
|
-
expectedPreviousTaskRef: context.session.activeTaskRef,
|
|
42190
|
-
taskRef,
|
|
42191
|
-
workflowMode: metadata.workflowMode,
|
|
42192
|
-
taskRevision: metadata.revision,
|
|
42193
|
-
now: context.now
|
|
42194
|
-
});
|
|
41979
|
+
if (taskHeadFence === null) {
|
|
41980
|
+
throw new Error("MANCODE_TASK_HEAD_FENCE_MISSING");
|
|
42195
41981
|
}
|
|
42196
41982
|
journal = await createTaskOperationJournal(context, {
|
|
42197
|
-
type: "
|
|
42198
|
-
action:
|
|
42199
|
-
expectedRevisions:
|
|
41983
|
+
type: "scope_change_reclaim",
|
|
41984
|
+
action: "task_complete_scope_change_child_merge",
|
|
41985
|
+
expectedRevisions: scopeChangeExpectedRevisions(
|
|
42200
41986
|
context,
|
|
42201
|
-
|
|
42202
|
-
activeClaims2
|
|
41987
|
+
checkpointId,
|
|
41988
|
+
activeClaims2,
|
|
41989
|
+
successorClaimIds
|
|
42203
41990
|
),
|
|
41991
|
+
conditions: { completionGateSatisfied: true },
|
|
42204
41992
|
recovery: {
|
|
42205
41993
|
actions: [
|
|
42206
41994
|
createTaskAuthorityFileRecoveryAction({
|
|
@@ -42210,20 +41998,28 @@ async function reframeV3Workflow(input) {
|
|
|
42210
41998
|
beforeContent: serializeTaskAuthority(context.task.metadata),
|
|
42211
41999
|
targetContent: serializeTaskAuthority(pendingMetadata)
|
|
42212
42000
|
}),
|
|
42213
|
-
|
|
42214
|
-
|
|
42215
|
-
|
|
42216
|
-
|
|
42217
|
-
|
|
42001
|
+
createCheckpointRecoveryAction({
|
|
42002
|
+
stepId: "write-scope-changed-checkpoint",
|
|
42003
|
+
before: null,
|
|
42004
|
+
checkpoint
|
|
42005
|
+
}),
|
|
42006
|
+
...pendingSuccessorClaims.map(
|
|
42007
|
+
(claim) => createClaimRecoveryAction({
|
|
42008
|
+
stepId: "create-pending-successor-claims",
|
|
42009
|
+
before: null,
|
|
42218
42010
|
claim
|
|
42219
42011
|
})
|
|
42220
42012
|
),
|
|
42221
|
-
|
|
42222
|
-
|
|
42223
|
-
|
|
42224
|
-
|
|
42225
|
-
|
|
42226
|
-
|
|
42013
|
+
...terminatedClaims.map((claim, index) => {
|
|
42014
|
+
const before = activeClaims2[index];
|
|
42015
|
+
if (before === void 0) {
|
|
42016
|
+
throw new Error("MANCODE_CLAIM_SET_CHANGED");
|
|
42017
|
+
}
|
|
42018
|
+
return createClaimRecoveryAction({
|
|
42019
|
+
stepId: "terminate-old-claims",
|
|
42020
|
+
before,
|
|
42021
|
+
claim
|
|
42022
|
+
});
|
|
42227
42023
|
}),
|
|
42228
42024
|
createTaskAuthorityFileRecoveryAction({
|
|
42229
42025
|
stepId: "mark-review-verification-stale",
|
|
@@ -42239,29 +42035,34 @@ async function reframeV3Workflow(input) {
|
|
|
42239
42035
|
beforeContent: serializeTaskAuthority(context.task.verification),
|
|
42240
42036
|
targetContent: serializeTaskAuthority(verification)
|
|
42241
42037
|
}),
|
|
42242
|
-
createCheckpointRecoveryAction({
|
|
42243
|
-
stepId: "write-reframe-checkpoint",
|
|
42244
|
-
before: null,
|
|
42245
|
-
checkpoint
|
|
42246
|
-
}),
|
|
42247
42038
|
createTaskAuthorityFileRecoveryAction({
|
|
42248
|
-
stepId: "
|
|
42039
|
+
stepId: "update-metadata-scope",
|
|
42249
42040
|
taskRef,
|
|
42250
42041
|
fileName: "metadata.json",
|
|
42251
42042
|
beforeContent: serializeTaskAuthority(pendingMetadata),
|
|
42252
42043
|
targetContent: serializeTaskAuthority(metadata)
|
|
42253
42044
|
}),
|
|
42254
|
-
...
|
|
42255
|
-
|
|
42256
|
-
|
|
42257
|
-
|
|
42258
|
-
|
|
42259
|
-
|
|
42260
|
-
|
|
42045
|
+
...activeSuccessorClaims.map((claim, index) => {
|
|
42046
|
+
const before = pendingSuccessorClaims[index];
|
|
42047
|
+
if (before === void 0) {
|
|
42048
|
+
throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
|
|
42049
|
+
}
|
|
42050
|
+
return createClaimRecoveryAction({
|
|
42051
|
+
stepId: "activate-successor-claims",
|
|
42052
|
+
before,
|
|
42053
|
+
claim
|
|
42054
|
+
});
|
|
42055
|
+
}),
|
|
42056
|
+
createTaskHeadFenceRecoveryAction({
|
|
42057
|
+
stepId: "update-task-head-fence",
|
|
42058
|
+
before: context.coordination.taskHeadFence,
|
|
42059
|
+
fence: taskHeadFence
|
|
42060
|
+
})
|
|
42261
42061
|
],
|
|
42262
42062
|
noOpStepIds: [
|
|
42263
|
-
...
|
|
42264
|
-
...
|
|
42063
|
+
...pendingSuccessorClaims.length === 0 ? ["create-pending-successor-claims"] : [],
|
|
42064
|
+
...terminatedClaims.length === 0 ? ["terminate-old-claims"] : [],
|
|
42065
|
+
...activeSuccessorClaims.length === 0 ? ["activate-successor-claims"] : []
|
|
42265
42066
|
]
|
|
42266
42067
|
}
|
|
42267
42068
|
});
|
|
@@ -42272,65 +42073,1015 @@ async function reframeV3Workflow(input) {
|
|
|
42272
42073
|
"mark-task-operation-pending",
|
|
42273
42074
|
false
|
|
42274
42075
|
);
|
|
42275
|
-
await
|
|
42076
|
+
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
42276
42077
|
await writeTaskAuthorityFile(
|
|
42277
42078
|
context,
|
|
42278
42079
|
"metadata.json",
|
|
42279
|
-
|
|
42080
|
+
`${JSON.stringify(pendingMetadata, null, 2)}
|
|
42081
|
+
`
|
|
42280
42082
|
);
|
|
42281
42083
|
journal = await advanceTaskOperation(
|
|
42282
42084
|
context,
|
|
42283
42085
|
journal,
|
|
42284
|
-
"
|
|
42086
|
+
"write-scope-changed-checkpoint",
|
|
42285
42087
|
false
|
|
42286
42088
|
);
|
|
42287
|
-
await
|
|
42288
|
-
await
|
|
42089
|
+
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
42090
|
+
await writeTaskCheckpoint(context, checkpoint);
|
|
42289
42091
|
journal = await advanceTaskOperation(
|
|
42290
42092
|
context,
|
|
42291
42093
|
journal,
|
|
42292
|
-
"
|
|
42094
|
+
"create-pending-successor-claims",
|
|
42293
42095
|
false
|
|
42294
42096
|
);
|
|
42295
|
-
await
|
|
42296
|
-
for (const
|
|
42297
|
-
|
|
42298
|
-
if (previous === void 0) throw new Error("MANCODE_CLAIM_SET_CHANGED");
|
|
42299
|
-
await updateClaim(context.homeStore, claim, previous.revision);
|
|
42097
|
+
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
42098
|
+
for (const claim of pendingSuccessorClaims) {
|
|
42099
|
+
await createClaim(context.homeStore, claim);
|
|
42300
42100
|
}
|
|
42301
42101
|
journal = await advanceTaskOperation(
|
|
42302
42102
|
context,
|
|
42303
42103
|
journal,
|
|
42304
|
-
"
|
|
42104
|
+
"terminate-old-claims",
|
|
42305
42105
|
false
|
|
42306
42106
|
);
|
|
42307
|
-
await
|
|
42308
|
-
|
|
42309
|
-
|
|
42310
|
-
|
|
42311
|
-
|
|
42312
|
-
|
|
42107
|
+
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
42108
|
+
for (const [index, claim] of terminatedClaims.entries()) {
|
|
42109
|
+
const previous = activeClaims2[index];
|
|
42110
|
+
if (previous === void 0) {
|
|
42111
|
+
throw new Error("MANCODE_CLAIM_SET_CHANGED");
|
|
42112
|
+
}
|
|
42113
|
+
await updateClaim(context.homeStore, claim, previous.revision);
|
|
42114
|
+
}
|
|
42313
42115
|
journal = await advanceTaskOperation(
|
|
42314
42116
|
context,
|
|
42315
42117
|
journal,
|
|
42316
42118
|
"mark-review-verification-stale",
|
|
42317
42119
|
false
|
|
42318
42120
|
);
|
|
42319
|
-
await
|
|
42121
|
+
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
42320
42122
|
await writeTaskAuthorityFile(
|
|
42321
42123
|
context,
|
|
42322
42124
|
"review-ledger.json",
|
|
42323
|
-
|
|
42125
|
+
`${JSON.stringify(review, null, 2)}
|
|
42126
|
+
`
|
|
42324
42127
|
);
|
|
42325
42128
|
await writeTaskAuthorityFile(
|
|
42326
42129
|
context,
|
|
42327
42130
|
"verification-ledger.json",
|
|
42328
|
-
|
|
42131
|
+
`${JSON.stringify(verification, null, 2)}
|
|
42132
|
+
`
|
|
42329
42133
|
);
|
|
42330
42134
|
journal = await advanceTaskOperation(
|
|
42331
42135
|
context,
|
|
42332
42136
|
journal,
|
|
42333
|
-
"
|
|
42137
|
+
"update-metadata-scope",
|
|
42138
|
+
false
|
|
42139
|
+
);
|
|
42140
|
+
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
42141
|
+
await writeTaskAuthorityFile(
|
|
42142
|
+
context,
|
|
42143
|
+
"metadata.json",
|
|
42144
|
+
`${JSON.stringify(metadata, null, 2)}
|
|
42145
|
+
`
|
|
42146
|
+
);
|
|
42147
|
+
journal = await advanceTaskOperation(
|
|
42148
|
+
context,
|
|
42149
|
+
journal,
|
|
42150
|
+
"activate-successor-claims",
|
|
42151
|
+
false
|
|
42152
|
+
);
|
|
42153
|
+
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
42154
|
+
for (const claim of activeSuccessorClaims) {
|
|
42155
|
+
await updateClaim(context.homeStore, claim, 1);
|
|
42156
|
+
}
|
|
42157
|
+
journal = await advanceTaskOperation(
|
|
42158
|
+
context,
|
|
42159
|
+
journal,
|
|
42160
|
+
"update-task-head-fence",
|
|
42161
|
+
false
|
|
42162
|
+
);
|
|
42163
|
+
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
42164
|
+
await replaceTaskHeadFence(context.homeStore, taskHeadFence);
|
|
42165
|
+
const operation = await commitTaskOperation(context, journal);
|
|
42166
|
+
return {
|
|
42167
|
+
metadata,
|
|
42168
|
+
checkpoint,
|
|
42169
|
+
terminatedClaims,
|
|
42170
|
+
successorClaims: activeSuccessorClaims,
|
|
42171
|
+
aggregate,
|
|
42172
|
+
taskHeadFence,
|
|
42173
|
+
operation
|
|
42174
|
+
};
|
|
42175
|
+
} catch (error) {
|
|
42176
|
+
if (journal !== null) {
|
|
42177
|
+
try {
|
|
42178
|
+
await handleTaskOperationFailure(context, journal);
|
|
42179
|
+
} catch {
|
|
42180
|
+
}
|
|
42181
|
+
}
|
|
42182
|
+
throw error;
|
|
42183
|
+
} finally {
|
|
42184
|
+
await context.release();
|
|
42185
|
+
}
|
|
42186
|
+
}
|
|
42187
|
+
async function openScopeChangeContext(input) {
|
|
42188
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
42189
|
+
const runtime = await readProjectRuntimeContext(input.projectRoot);
|
|
42190
|
+
const store = new V3ContextStore(input.projectRoot);
|
|
42191
|
+
const homeStore = resolveTaskEntityHomeStore(
|
|
42192
|
+
runtime.entityHomeStoreContext,
|
|
42193
|
+
input.taskRef
|
|
42194
|
+
);
|
|
42195
|
+
const preflight = await store.readCoordinationSnapshot(
|
|
42196
|
+
input.taskRef,
|
|
42197
|
+
homeStore
|
|
42198
|
+
);
|
|
42199
|
+
const preflightClaims = activeClaims(preflight.claims);
|
|
42200
|
+
const preflightSuccessors = claimsWithinScope(preflightClaims, input.scope);
|
|
42201
|
+
const preflightSuccessorIds = resolveSuccessorClaimIds2(
|
|
42202
|
+
preflightSuccessors,
|
|
42203
|
+
input.successorClaimIds,
|
|
42204
|
+
input.operationId,
|
|
42205
|
+
input.now.toISOString()
|
|
42206
|
+
);
|
|
42207
|
+
const context = await openV3TaskOperation({
|
|
42208
|
+
projectRoot: input.projectRoot,
|
|
42209
|
+
taskRef: input.taskRef,
|
|
42210
|
+
sessionId: input.sessionId,
|
|
42211
|
+
expectedTaskRevision: input.expectedTaskRevision,
|
|
42212
|
+
operationId: input.operationId,
|
|
42213
|
+
extraEntityLocks: [
|
|
42214
|
+
`checkpoint:${input.checkpointId}`,
|
|
42215
|
+
taskHeadEntityKey(input.taskRef),
|
|
42216
|
+
...preflightClaims.map((claim) => `claim:${claim.claimId}`),
|
|
42217
|
+
...preflightSuccessorIds.map((claimId) => `claim:${claimId}`)
|
|
42218
|
+
],
|
|
42219
|
+
now: input.now
|
|
42220
|
+
});
|
|
42221
|
+
const lockedClaims = activeClaims(context.coordination.claims);
|
|
42222
|
+
if (sameClaimIdSet(preflightClaims, lockedClaims)) {
|
|
42223
|
+
const successors = claimsWithinScope(lockedClaims, input.scope);
|
|
42224
|
+
const successorIds = resolveSuccessorClaimIds2(
|
|
42225
|
+
successors,
|
|
42226
|
+
input.successorClaimIds,
|
|
42227
|
+
input.operationId,
|
|
42228
|
+
input.now.toISOString()
|
|
42229
|
+
);
|
|
42230
|
+
return {
|
|
42231
|
+
context,
|
|
42232
|
+
activeClaims: lockedClaims,
|
|
42233
|
+
successorPredecessors: successors,
|
|
42234
|
+
successorClaimIds: successorIds
|
|
42235
|
+
};
|
|
42236
|
+
}
|
|
42237
|
+
await context.release();
|
|
42238
|
+
}
|
|
42239
|
+
throw new Error("MANCODE_CLAIM_SET_CHANGED");
|
|
42240
|
+
}
|
|
42241
|
+
function assertScopeChangeEligible(context, scope) {
|
|
42242
|
+
const metadata = context.task.metadata;
|
|
42243
|
+
if (context.project.config.transport.mode !== "local") {
|
|
42244
|
+
throw new Error("MANCODE_GIT_REF_TRANSPORT_NOT_IMPLEMENTED");
|
|
42245
|
+
}
|
|
42246
|
+
if (metadata.workflowMode !== "manteam") {
|
|
42247
|
+
throw new Error("MANCODE_SCOPE_CHANGE_WORKFLOW_MODE_INVALID");
|
|
42248
|
+
}
|
|
42249
|
+
if (metadata.status !== "in_progress") {
|
|
42250
|
+
throw new Error("MANCODE_SCOPE_CHANGE_WORKFLOW_NOT_ACTIVE");
|
|
42251
|
+
}
|
|
42252
|
+
if (metadata.ownerActorId !== context.session.actorId) {
|
|
42253
|
+
throw new Error("MANCODE_TASK_OWNER_REQUIRED");
|
|
42254
|
+
}
|
|
42255
|
+
if (metadata.parent !== null) {
|
|
42256
|
+
throw new Error("MANCODE_PARENT_SCOPE_INHERITANCE_REQUIRED");
|
|
42257
|
+
}
|
|
42258
|
+
if (metadata.implementationScope.digest === scope.digest) {
|
|
42259
|
+
throw new Error("MANCODE_SCOPE_CHANGE_NOOP");
|
|
42260
|
+
}
|
|
42261
|
+
}
|
|
42262
|
+
function assertClaimsFreshForScopeChange(context, claims) {
|
|
42263
|
+
const codeHead = requireCodeHead3(context);
|
|
42264
|
+
for (const claim of claims) {
|
|
42265
|
+
if (claim.authority.mode !== "local") {
|
|
42266
|
+
throw new Error("MANCODE_OPERATION_REPAIR_REQUIRED");
|
|
42267
|
+
}
|
|
42268
|
+
const validity = deriveClaimValidity(claim, {
|
|
42269
|
+
taskRef: context.taskRef,
|
|
42270
|
+
taskRevision: context.task.metadata.revision,
|
|
42271
|
+
implementationScopeDigest: context.task.metadata.implementationScope.digest,
|
|
42272
|
+
ownershipEpoch: context.task.metadata.ownershipEpoch,
|
|
42273
|
+
codeRefHead: codeHead,
|
|
42274
|
+
now: context.now,
|
|
42275
|
+
transportFreshness: "fresh"
|
|
42276
|
+
});
|
|
42277
|
+
if (validity !== "fresh") {
|
|
42278
|
+
throw new Error("MANCODE_CLAIM_REVALIDATION_REQUIRED");
|
|
42279
|
+
}
|
|
42280
|
+
}
|
|
42281
|
+
}
|
|
42282
|
+
function normalizeImplementationScope(value) {
|
|
42283
|
+
assertRecord(value, "workflow scope change");
|
|
42284
|
+
assertKnownKeys(
|
|
42285
|
+
value,
|
|
42286
|
+
["include", "exclude", "modules"],
|
|
42287
|
+
"workflow scope change"
|
|
42288
|
+
);
|
|
42289
|
+
const scope = {
|
|
42290
|
+
source: "explicit",
|
|
42291
|
+
include: normalizeScopeValues(value.include, "include", true),
|
|
42292
|
+
exclude: normalizeScopeValues(value.exclude, "exclude", true),
|
|
42293
|
+
modules: normalizeScopeValues(value.modules, "modules", false)
|
|
42294
|
+
};
|
|
42295
|
+
const included = new Set(scope.include);
|
|
42296
|
+
if (scope.exclude.some((item) => included.has(item))) {
|
|
42297
|
+
throw new Error("MANCODE_SCOPE_INCLUDE_EXCLUDE_CONFLICT");
|
|
42298
|
+
}
|
|
42299
|
+
return { ...scope, digest: digestCanonicalJson(scope) };
|
|
42300
|
+
}
|
|
42301
|
+
function normalizeScopeValues(value, label, paths) {
|
|
42302
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || !item.trim())) {
|
|
42303
|
+
throw new Error(`MANCODE_SCOPE_${label.toUpperCase()}_INVALID`);
|
|
42304
|
+
}
|
|
42305
|
+
const values = value.map((item) => item.trim());
|
|
42306
|
+
const normalized = sortUtf8StringSet(values);
|
|
42307
|
+
if (normalized.length !== values.length) {
|
|
42308
|
+
throw new Error(`MANCODE_SCOPE_${label.toUpperCase()}_DUPLICATE`);
|
|
42309
|
+
}
|
|
42310
|
+
for (const item of normalized) {
|
|
42311
|
+
assertSharedTextSafe(item, `workflow scope ${label}`);
|
|
42312
|
+
if (paths) assertScopePath(item);
|
|
42313
|
+
}
|
|
42314
|
+
return normalized;
|
|
42315
|
+
}
|
|
42316
|
+
function assertScopePath(value) {
|
|
42317
|
+
if (value.startsWith("/") || value.startsWith("~") || /^[A-Za-z]:/.test(value) || value.includes("\\") || value.split("/").some((segment) => segment === "" || segment === "." || segment === "..")) {
|
|
42318
|
+
throw new Error("MANCODE_SCOPE_PATH_INVALID");
|
|
42319
|
+
}
|
|
42320
|
+
}
|
|
42321
|
+
function markScopeChangeOperationPending(previous, operationId, updatedAt) {
|
|
42322
|
+
const next = parseWorkflowMetadata({
|
|
42323
|
+
...previous,
|
|
42324
|
+
revision: previous.revision + 1,
|
|
42325
|
+
transitionState: "operation_pending",
|
|
42326
|
+
lastOperationId: operationId,
|
|
42327
|
+
updatedAt
|
|
42328
|
+
});
|
|
42329
|
+
assertWorkflowMetadataTransition(previous, next, "ordinary");
|
|
42330
|
+
return next;
|
|
42331
|
+
}
|
|
42332
|
+
function completeScopeChangeMetadata(previous, scope, checkpoint, reviewLedgerDigest2, verificationLedgerDigest2, operationId, updatedAt) {
|
|
42333
|
+
const next = parseWorkflowMetadata({
|
|
42334
|
+
...previous,
|
|
42335
|
+
revision: previous.revision + 1,
|
|
42336
|
+
transitionState: "stable",
|
|
42337
|
+
implementationScope: scope,
|
|
42338
|
+
governance: {
|
|
42339
|
+
...previous.governance,
|
|
42340
|
+
planVersion: previous.governance.planVersion + 1,
|
|
42341
|
+
reviewStatus: "stale",
|
|
42342
|
+
reviewLedgerDigest: reviewLedgerDigest2,
|
|
42343
|
+
verificationStatus: "stale",
|
|
42344
|
+
verificationLedgerDigest: verificationLedgerDigest2
|
|
42345
|
+
},
|
|
42346
|
+
latestCheckpointRef: {
|
|
42347
|
+
taskRef: checkpoint.taskRef,
|
|
42348
|
+
kind: "checkpoint",
|
|
42349
|
+
artifactId: checkpoint.checkpointId
|
|
42350
|
+
},
|
|
42351
|
+
lastOperationId: operationId,
|
|
42352
|
+
updatedAt
|
|
42353
|
+
});
|
|
42354
|
+
assertWorkflowMetadataTransition(previous, next, "ordinary");
|
|
42355
|
+
return next;
|
|
42356
|
+
}
|
|
42357
|
+
function buildScopeChangedCheckpoint(context, pendingMetadata, checkpointId, summary, nextAction, branch, planVersion, reviewLedgerDigest2, verificationLedgerDigest2, timestamp4) {
|
|
42358
|
+
return parseCheckpoint({
|
|
42359
|
+
schemaVersion: 1,
|
|
42360
|
+
checkpointId,
|
|
42361
|
+
operationId: context.operationId,
|
|
42362
|
+
taskRef: context.taskRef,
|
|
42363
|
+
taskRevision: pendingMetadata.revision,
|
|
42364
|
+
ownershipEpochAtOffer: pendingMetadata.ownershipEpoch,
|
|
42365
|
+
kind: "scope_changed",
|
|
42366
|
+
git: {
|
|
42367
|
+
branch,
|
|
42368
|
+
head: requireCodeHead3(context),
|
|
42369
|
+
base: pendingMetadata.base?.head ?? null
|
|
42370
|
+
},
|
|
42371
|
+
summary: summary ?? "Changed the implementation scope and replaced affected coordination claims.",
|
|
42372
|
+
governance: {
|
|
42373
|
+
requirementsDigest: context.task.requirements.contentDigest,
|
|
42374
|
+
planVersion,
|
|
42375
|
+
reviewLedgerDigest: reviewLedgerDigest2,
|
|
42376
|
+
verificationLedgerDigest: verificationLedgerDigest2
|
|
42377
|
+
},
|
|
42378
|
+
nextAction: nextAction ?? "Re-read the updated scope and continue only with the successor claim.",
|
|
42379
|
+
createdBy: {
|
|
42380
|
+
actorId: context.session.actorId,
|
|
42381
|
+
client: context.session.client
|
|
42382
|
+
},
|
|
42383
|
+
createdAt: timestamp4
|
|
42384
|
+
});
|
|
42385
|
+
}
|
|
42386
|
+
function buildPendingSuccessorClaims2(predecessors, successorClaimIds, metadata, branch, codeHead, operationId, timestamp4, capabilities) {
|
|
42387
|
+
return predecessors.map((previous, index) => {
|
|
42388
|
+
const claimId = successorClaimIds[index];
|
|
42389
|
+
if (claimId === void 0) {
|
|
42390
|
+
throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
|
|
42391
|
+
}
|
|
42392
|
+
return parseClaim({
|
|
42393
|
+
...previous,
|
|
42394
|
+
claimId,
|
|
42395
|
+
authority: { mode: "local", remoteRevision: null },
|
|
42396
|
+
taskRevisionAtAcquire: metadata.revision,
|
|
42397
|
+
lastValidatedTaskRevision: metadata.revision,
|
|
42398
|
+
implementationScopeDigest: metadata.implementationScope.digest,
|
|
42399
|
+
ownershipEpochAtAcquire: metadata.ownershipEpoch,
|
|
42400
|
+
state: "pending",
|
|
42401
|
+
revision: 1,
|
|
42402
|
+
codeRefAtAcquire: { branch, head: codeHead },
|
|
42403
|
+
lastValidatedCodeRef: { branch, head: codeHead },
|
|
42404
|
+
acquisitionEnforcement: capabilities.claimAcquisition,
|
|
42405
|
+
writeGuard: capabilities.writeGuard,
|
|
42406
|
+
predecessorClaimId: previous.claimId,
|
|
42407
|
+
successorClaimId: null,
|
|
42408
|
+
lastOperationId: operationId,
|
|
42409
|
+
createdAt: timestamp4,
|
|
42410
|
+
updatedAt: timestamp4
|
|
42411
|
+
});
|
|
42412
|
+
});
|
|
42413
|
+
}
|
|
42414
|
+
function terminateClaimForScopeChange(previous, successorClaimId, operationId, timestamp4) {
|
|
42415
|
+
const next = parseClaim({
|
|
42416
|
+
...previous,
|
|
42417
|
+
state: successorClaimId === null ? "released" : "transferred",
|
|
42418
|
+
revision: previous.revision + 1,
|
|
42419
|
+
successorClaimId,
|
|
42420
|
+
lastOperationId: operationId,
|
|
42421
|
+
updatedAt: timestamp4
|
|
42422
|
+
});
|
|
42423
|
+
assertClaimTransition(previous, next);
|
|
42424
|
+
return next;
|
|
42425
|
+
}
|
|
42426
|
+
function activateSuccessorClaim3(previous, operationId, timestamp4) {
|
|
42427
|
+
const next = parseClaim({
|
|
42428
|
+
...previous,
|
|
42429
|
+
state: "active",
|
|
42430
|
+
revision: previous.revision + 1,
|
|
42431
|
+
lastOperationId: operationId,
|
|
42432
|
+
updatedAt: timestamp4
|
|
42433
|
+
});
|
|
42434
|
+
assertClaimTransition(previous, next);
|
|
42435
|
+
return next;
|
|
42436
|
+
}
|
|
42437
|
+
function scopeChangeExpectedRevisions(context, checkpointId, predecessors, successorClaimIds) {
|
|
42438
|
+
const expected = {
|
|
42439
|
+
[taskEntityKey(context.taskRef)]: context.task.metadata.revision,
|
|
42440
|
+
[`review:${context.taskRef.taskId}`]: context.task.review.revision,
|
|
42441
|
+
[`verification:${context.taskRef.taskId}`]: context.task.verification.revision,
|
|
42442
|
+
[`checkpoint:${checkpointId}`]: 0
|
|
42443
|
+
};
|
|
42444
|
+
for (const claim of predecessors) {
|
|
42445
|
+
expected[`claim:${claim.claimId}`] = claim.revision;
|
|
42446
|
+
}
|
|
42447
|
+
for (const claimId of successorClaimIds) {
|
|
42448
|
+
expected[`claim:${claimId}`] = 0;
|
|
42449
|
+
}
|
|
42450
|
+
const fence = context.coordination.taskHeadFence;
|
|
42451
|
+
if (fence === null) throw new Error("MANCODE_TASK_HEAD_FENCE_MISSING");
|
|
42452
|
+
expected[taskHeadEntityKey(context.taskRef)] = fence.fenceRevision;
|
|
42453
|
+
return expected;
|
|
42454
|
+
}
|
|
42455
|
+
function activeClaims(claims) {
|
|
42456
|
+
return claims.filter((claim) => claim.state === "active").sort((left, right) => compareUtf815(left.claimId, right.claimId));
|
|
42457
|
+
}
|
|
42458
|
+
function claimsWithinScope(claims, scope) {
|
|
42459
|
+
return claims.filter(
|
|
42460
|
+
(claim) => evaluateClaimScopeSubset(claim.scope, {
|
|
42461
|
+
source: scope.source,
|
|
42462
|
+
include: scope.include,
|
|
42463
|
+
exclude: scope.exclude,
|
|
42464
|
+
modules: scope.modules
|
|
42465
|
+
}).allowed
|
|
42466
|
+
);
|
|
42467
|
+
}
|
|
42468
|
+
function resolveSuccessorClaimIds2(predecessors, requested, operationId, timestamp4) {
|
|
42469
|
+
const ids = requested ?? predecessors.map(
|
|
42470
|
+
(claim) => scopeSuccessorClaimId(operationId, claim.claimId, timestamp4)
|
|
42471
|
+
);
|
|
42472
|
+
if (ids.length !== predecessors.length) {
|
|
42473
|
+
throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_COUNT_INVALID");
|
|
42474
|
+
}
|
|
42475
|
+
const predecessorIds = new Set(predecessors.map((claim) => claim.claimId));
|
|
42476
|
+
const seen = /* @__PURE__ */ new Set();
|
|
42477
|
+
for (const claimId of ids) {
|
|
42478
|
+
assertUlid(claimId, "scope successor claimId");
|
|
42479
|
+
if (predecessorIds.has(claimId) || seen.has(claimId)) {
|
|
42480
|
+
throw new Error("MANCODE_SCOPE_SUCCESSOR_CLAIM_INVALID");
|
|
42481
|
+
}
|
|
42482
|
+
seen.add(claimId);
|
|
42483
|
+
}
|
|
42484
|
+
return ids;
|
|
42485
|
+
}
|
|
42486
|
+
function scopeSuccessorClaimId(operationId, predecessorClaimId, timestamp4) {
|
|
42487
|
+
assertUlid(operationId, "scope change operationId");
|
|
42488
|
+
assertUlid(predecessorClaimId, "scope predecessor claimId");
|
|
42489
|
+
const milliseconds = Date.parse(timestamp4);
|
|
42490
|
+
if (Number.isNaN(milliseconds)) {
|
|
42491
|
+
throw new Error("MANCODE_SCOPE_TIMESTAMP_INVALID");
|
|
42492
|
+
}
|
|
42493
|
+
const entropy = createHash11("sha256").update(`scope-change:${operationId}:${predecessorClaimId}`, "utf8").digest().subarray(0, 10);
|
|
42494
|
+
return createUlid(milliseconds, entropy);
|
|
42495
|
+
}
|
|
42496
|
+
function requireCodeHead3(context) {
|
|
42497
|
+
if (context.codeHead === null) {
|
|
42498
|
+
throw new Error("MANCODE_TASK_HEAD_CODE_REF_UNAVAILABLE");
|
|
42499
|
+
}
|
|
42500
|
+
return context.codeHead;
|
|
42501
|
+
}
|
|
42502
|
+
function sameClaimIdSet(left, right) {
|
|
42503
|
+
return left.length === right.length && left.every((claim, index) => claim.claimId === right[index]?.claimId);
|
|
42504
|
+
}
|
|
42505
|
+
function compareUtf815(left, right) {
|
|
42506
|
+
return Buffer.from(left, "utf8").compare(Buffer.from(right, "utf8"));
|
|
42507
|
+
}
|
|
42508
|
+
|
|
42509
|
+
// src/context/plan-revision.ts
|
|
42510
|
+
async function reviseV3Plan(input) {
|
|
42511
|
+
const taskRef = parseTaskRefValue(input.taskRef);
|
|
42512
|
+
const plan = requirePlan(input.plan);
|
|
42513
|
+
const planDecision = parsePlanDecision(input.planDecision);
|
|
42514
|
+
const submittedScope = input.implementationScope === void 0 ? null : normalizeImplementationScope(input.implementationScope);
|
|
42515
|
+
if (taskRef.namespace === "shared") {
|
|
42516
|
+
assertSharedTextSafe(plan, "plan");
|
|
42517
|
+
}
|
|
42518
|
+
const context = await openV3TaskOperation({
|
|
42519
|
+
projectRoot: input.projectRoot,
|
|
42520
|
+
taskRef,
|
|
42521
|
+
sessionId: input.sessionId,
|
|
42522
|
+
expectedTaskRevision: input.expectedTaskRevision,
|
|
42523
|
+
operationId: input.operationId,
|
|
42524
|
+
extraEntityLocks: taskRef.namespace === "shared" ? [taskHeadEntityKey(taskRef)] : [],
|
|
42525
|
+
now: input.now
|
|
42526
|
+
});
|
|
42527
|
+
let journal = null;
|
|
42528
|
+
try {
|
|
42529
|
+
const planChanged = context.task.plan?.content !== plan;
|
|
42530
|
+
const executionScopeBinding = assertExecutionScopeBindingAttempt({
|
|
42531
|
+
metadata: context.task.metadata,
|
|
42532
|
+
currentPlan: context.task.plan?.content ?? null,
|
|
42533
|
+
submittedPlan: plan,
|
|
42534
|
+
submittedScope,
|
|
42535
|
+
planDecisionSupplied: input.planDecision !== void 0,
|
|
42536
|
+
sessionActorId: context.session.actorId
|
|
42537
|
+
});
|
|
42538
|
+
assertPlanRevisionEligible(
|
|
42539
|
+
context.task.metadata,
|
|
42540
|
+
context.task.requirements,
|
|
42541
|
+
executionScopeBinding
|
|
42542
|
+
);
|
|
42543
|
+
const implementationScope = submittedScope ?? context.task.metadata.implementationScope;
|
|
42544
|
+
const scopeChanged = submittedScope !== null && submittedScope.digest !== context.task.metadata.implementationScope.digest;
|
|
42545
|
+
if (planDecision === "governed_execution") {
|
|
42546
|
+
assertExecutableImplementationScope(implementationScope);
|
|
42547
|
+
}
|
|
42548
|
+
if (executionScopeBinding) {
|
|
42549
|
+
assertExecutableImplementationScope(implementationScope);
|
|
42550
|
+
}
|
|
42551
|
+
if (context.task.metadata.workflowMode === "manteam" && planDecision === "governed_execution") {
|
|
42552
|
+
assertManteamPlanContent(plan);
|
|
42553
|
+
}
|
|
42554
|
+
if (context.task.plan?.content === plan && planDecision === null && !scopeChanged) {
|
|
42555
|
+
throw new Error("MANCODE_PLAN_CONTENT_UNCHANGED");
|
|
42556
|
+
}
|
|
42557
|
+
const authorityChanged = planChanged || scopeChanged;
|
|
42558
|
+
const timestamp4 = context.now.toISOString();
|
|
42559
|
+
const planDigest = planChanged ? digestCanonicalJson({
|
|
42560
|
+
artifactRef: { taskRef, kind: "plan" },
|
|
42561
|
+
content: plan
|
|
42562
|
+
}) : context.task.plan?.digest;
|
|
42563
|
+
if (planDigest === void 0) {
|
|
42564
|
+
throw new Error("MANCODE_PLAN_FILE_REQUIRED");
|
|
42565
|
+
}
|
|
42566
|
+
const review = authorityChanged ? markTaskReviewStale(context.task.review, context.operationId, timestamp4) : context.task.review;
|
|
42567
|
+
const verification = authorityChanged ? markTaskVerificationStale(
|
|
42568
|
+
context.task.verification,
|
|
42569
|
+
context.operationId,
|
|
42570
|
+
timestamp4
|
|
42571
|
+
) : context.task.verification;
|
|
42572
|
+
const metadata = updateMetadata(
|
|
42573
|
+
context.task.metadata,
|
|
42574
|
+
context.task.requirements,
|
|
42575
|
+
review,
|
|
42576
|
+
verification,
|
|
42577
|
+
implementationScope,
|
|
42578
|
+
authorityChanged,
|
|
42579
|
+
planDecision,
|
|
42580
|
+
executionScopeBinding,
|
|
42581
|
+
context.operationId,
|
|
42582
|
+
timestamp4
|
|
42583
|
+
);
|
|
42584
|
+
const aggregate = buildTaskAggregateManifest({
|
|
42585
|
+
metadata,
|
|
42586
|
+
requirements: context.task.requirements,
|
|
42587
|
+
review,
|
|
42588
|
+
verification,
|
|
42589
|
+
planDigest,
|
|
42590
|
+
latestCheckpoint: context.task.latestCheckpoint
|
|
42591
|
+
});
|
|
42592
|
+
const taskHeadFence = nextTaskHeadFence(context, aggregate, timestamp4);
|
|
42593
|
+
if (planDecision === "plan_only") {
|
|
42594
|
+
await enqueueSessionPointerProjection(context.projectRoot, {
|
|
42595
|
+
operationId: context.operationId,
|
|
42596
|
+
action: "clear",
|
|
42597
|
+
sessionId: context.session.sessionId,
|
|
42598
|
+
expectedPreviousTaskRef: context.session.activeTaskRef,
|
|
42599
|
+
taskRef,
|
|
42600
|
+
workflowMode: metadata.workflowMode,
|
|
42601
|
+
taskRevision: metadata.revision,
|
|
42602
|
+
now: context.now
|
|
42603
|
+
});
|
|
42604
|
+
}
|
|
42605
|
+
journal = await createTaskOperationJournal(context, {
|
|
42606
|
+
type: "plan_revision",
|
|
42607
|
+
action: taskRef.namespace === "shared" ? "shared_metadata_plan_mutation" : "local_workflow_mutation",
|
|
42608
|
+
expectedRevisions: taskMutationExpectedRevisions(context, [
|
|
42609
|
+
"plan",
|
|
42610
|
+
"review",
|
|
42611
|
+
"verification"
|
|
42612
|
+
]),
|
|
42613
|
+
recovery: {
|
|
42614
|
+
actions: [
|
|
42615
|
+
...planChanged ? [
|
|
42616
|
+
createTaskAuthorityFileRecoveryAction({
|
|
42617
|
+
stepId: "write-plan",
|
|
42618
|
+
taskRef,
|
|
42619
|
+
fileName: "plan.md",
|
|
42620
|
+
beforeContent: context.task.plan?.content ?? null,
|
|
42621
|
+
targetContent: plan
|
|
42622
|
+
})
|
|
42623
|
+
] : [],
|
|
42624
|
+
createTaskAuthorityFileRecoveryAction({
|
|
42625
|
+
stepId: "update-metadata",
|
|
42626
|
+
taskRef,
|
|
42627
|
+
fileName: "metadata.json",
|
|
42628
|
+
beforeContent: serializeTaskAuthority(context.task.metadata),
|
|
42629
|
+
targetContent: serializeTaskAuthority(metadata)
|
|
42630
|
+
}),
|
|
42631
|
+
...authorityChanged ? [
|
|
42632
|
+
createTaskAuthorityFileRecoveryAction({
|
|
42633
|
+
stepId: "mark-review-verification-stale",
|
|
42634
|
+
taskRef,
|
|
42635
|
+
fileName: "review-ledger.json",
|
|
42636
|
+
beforeContent: serializeTaskAuthority(context.task.review),
|
|
42637
|
+
targetContent: serializeTaskAuthority(review)
|
|
42638
|
+
}),
|
|
42639
|
+
createTaskAuthorityFileRecoveryAction({
|
|
42640
|
+
stepId: "mark-review-verification-stale",
|
|
42641
|
+
taskRef,
|
|
42642
|
+
fileName: "verification-ledger.json",
|
|
42643
|
+
beforeContent: serializeTaskAuthority(
|
|
42644
|
+
context.task.verification
|
|
42645
|
+
),
|
|
42646
|
+
targetContent: serializeTaskAuthority(verification)
|
|
42647
|
+
})
|
|
42648
|
+
] : [],
|
|
42649
|
+
...taskHeadFence === null ? [] : [
|
|
42650
|
+
createTaskHeadFenceRecoveryAction({
|
|
42651
|
+
stepId: "update-task-head-fence",
|
|
42652
|
+
before: context.coordination.taskHeadFence,
|
|
42653
|
+
fence: taskHeadFence
|
|
42654
|
+
})
|
|
42655
|
+
]
|
|
42656
|
+
],
|
|
42657
|
+
noOpStepIds: [
|
|
42658
|
+
...planChanged ? [] : ["write-plan"],
|
|
42659
|
+
...authorityChanged ? [] : ["mark-review-verification-stale"],
|
|
42660
|
+
...taskHeadFence === null ? ["update-task-head-fence"] : []
|
|
42661
|
+
]
|
|
42662
|
+
}
|
|
42663
|
+
});
|
|
42664
|
+
journal = await advanceTaskOperation(context, journal, "validate", true);
|
|
42665
|
+
journal = await advanceTaskOperation(context, journal, "write-plan", false);
|
|
42666
|
+
if (planChanged) {
|
|
42667
|
+
await writeTaskAuthorityFile(context, "plan.md", plan);
|
|
42668
|
+
}
|
|
42669
|
+
journal = await advanceTaskOperation(
|
|
42670
|
+
context,
|
|
42671
|
+
journal,
|
|
42672
|
+
"update-metadata",
|
|
42673
|
+
false
|
|
42674
|
+
);
|
|
42675
|
+
await writeTaskAuthorityFile(
|
|
42676
|
+
context,
|
|
42677
|
+
"metadata.json",
|
|
42678
|
+
`${JSON.stringify(metadata, null, 2)}
|
|
42679
|
+
`
|
|
42680
|
+
);
|
|
42681
|
+
journal = await advanceTaskOperation(
|
|
42682
|
+
context,
|
|
42683
|
+
journal,
|
|
42684
|
+
"mark-review-verification-stale",
|
|
42685
|
+
false
|
|
42686
|
+
);
|
|
42687
|
+
if (authorityChanged) {
|
|
42688
|
+
await writeTaskAuthorityFile(
|
|
42689
|
+
context,
|
|
42690
|
+
"review-ledger.json",
|
|
42691
|
+
`${JSON.stringify(review, null, 2)}
|
|
42692
|
+
`
|
|
42693
|
+
);
|
|
42694
|
+
await writeTaskAuthorityFile(
|
|
42695
|
+
context,
|
|
42696
|
+
"verification-ledger.json",
|
|
42697
|
+
`${JSON.stringify(verification, null, 2)}
|
|
42698
|
+
`
|
|
42699
|
+
);
|
|
42700
|
+
}
|
|
42701
|
+
journal = await advanceTaskOperation(
|
|
42702
|
+
context,
|
|
42703
|
+
journal,
|
|
42704
|
+
"update-task-head-fence",
|
|
42705
|
+
false
|
|
42706
|
+
);
|
|
42707
|
+
if (taskHeadFence !== null) {
|
|
42708
|
+
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
42709
|
+
await replaceTaskHeadFence(context.homeStore, taskHeadFence);
|
|
42710
|
+
}
|
|
42711
|
+
const operation = await commitTaskOperation(context, journal);
|
|
42712
|
+
if (planDecision === "plan_only") {
|
|
42713
|
+
try {
|
|
42714
|
+
await reconcileProjectionIntents(
|
|
42715
|
+
context.projectRoot,
|
|
42716
|
+
context.operationId,
|
|
42717
|
+
context.now
|
|
42718
|
+
);
|
|
42719
|
+
} catch {
|
|
42720
|
+
}
|
|
42721
|
+
}
|
|
42722
|
+
return {
|
|
42723
|
+
metadata,
|
|
42724
|
+
review,
|
|
42725
|
+
verification,
|
|
42726
|
+
planDigest,
|
|
42727
|
+
aggregate,
|
|
42728
|
+
taskHeadFence,
|
|
42729
|
+
operation
|
|
42730
|
+
};
|
|
42731
|
+
} catch (error) {
|
|
42732
|
+
if (journal !== null) {
|
|
42733
|
+
try {
|
|
42734
|
+
await handleTaskOperationFailure(context, journal);
|
|
42735
|
+
} catch {
|
|
42736
|
+
}
|
|
42737
|
+
}
|
|
42738
|
+
throw error;
|
|
42739
|
+
} finally {
|
|
42740
|
+
await context.release();
|
|
42741
|
+
}
|
|
42742
|
+
}
|
|
42743
|
+
function requirePlan(value) {
|
|
42744
|
+
if (typeof value !== "string" || !value.trim() || value.includes("\0")) {
|
|
42745
|
+
throw new Error("MANCODE_PLAN_CONTENT_REQUIRED");
|
|
42746
|
+
}
|
|
42747
|
+
return value;
|
|
42748
|
+
}
|
|
42749
|
+
function parsePlanDecision(value) {
|
|
42750
|
+
if (value === void 0) return null;
|
|
42751
|
+
if (value !== "plan_only" && value !== "governed_execution") {
|
|
42752
|
+
throw new Error("MANCODE_PLAN_DECISION_INVALID");
|
|
42753
|
+
}
|
|
42754
|
+
return value;
|
|
42755
|
+
}
|
|
42756
|
+
function assertPlanRevisionEligible(metadata, requirements, executionScopeBinding) {
|
|
42757
|
+
if (executionScopeBinding) {
|
|
42758
|
+
assertReadyPlanRequirements(metadata, requirements);
|
|
42759
|
+
return;
|
|
42760
|
+
}
|
|
42761
|
+
if (metadata.workflowMode !== "man" && metadata.workflowMode !== "manteam") {
|
|
42762
|
+
throw new Error("MANCODE_PLAN_WORKFLOW_MODE_INVALID");
|
|
42763
|
+
}
|
|
42764
|
+
if (metadata.status !== "in_progress") {
|
|
42765
|
+
throw new Error("MANCODE_PLAN_WORKFLOW_NOT_ACTIVE");
|
|
42766
|
+
}
|
|
42767
|
+
if (metadata.currentStep < 2 || metadata.currentStep > 4) {
|
|
42768
|
+
throw new Error("MANCODE_PLAN_STEP_INVALID");
|
|
42769
|
+
}
|
|
42770
|
+
if (metadata.governance.planDecision !== null) {
|
|
42771
|
+
throw new Error("MANCODE_PLAN_REQUIREMENTS_OR_DECISION_INVALID");
|
|
42772
|
+
}
|
|
42773
|
+
assertReadyPlanRequirements(metadata, requirements);
|
|
42774
|
+
}
|
|
42775
|
+
function assertReadyPlanRequirements(metadata, requirements) {
|
|
42776
|
+
if (metadata.governance.requirementsStatus !== "ready" || metadata.governance.requirementsDigest !== requirements.contentDigest || requirements.status !== "confirmed" || !requirementsAreReady(requirements)) {
|
|
42777
|
+
throw new Error("MANCODE_PLAN_REQUIREMENTS_OR_DECISION_INVALID");
|
|
42778
|
+
}
|
|
42779
|
+
assertRequirementsScopeConsistent(requirements);
|
|
42780
|
+
}
|
|
42781
|
+
function assertExecutionScopeBindingAttempt(input) {
|
|
42782
|
+
const decision = input.metadata.governance.planDecision;
|
|
42783
|
+
if (decision !== "governed_execution" && decision !== "solo_handoff") {
|
|
42784
|
+
return false;
|
|
42785
|
+
}
|
|
42786
|
+
if (input.metadata.workflowMode !== "man" || input.metadata.coordination !== "single" || input.metadata.taskRef.namespace !== "local") {
|
|
42787
|
+
throw new Error("MANCODE_EXECUTION_SCOPE_BINDING_LOCAL_MAN_ONLY");
|
|
42788
|
+
}
|
|
42789
|
+
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";
|
|
42790
|
+
if (!activeExecution) {
|
|
42791
|
+
throw new Error("MANCODE_EXECUTION_SCOPE_BINDING_NOT_ACTIVE");
|
|
42792
|
+
}
|
|
42793
|
+
if (input.metadata.ownerActorId !== input.sessionActorId) {
|
|
42794
|
+
throw new Error("MANCODE_TASK_OWNER_REQUIRED");
|
|
42795
|
+
}
|
|
42796
|
+
if (implementationScopeIsExecutable(input.metadata.implementationScope)) {
|
|
42797
|
+
throw new Error("MANCODE_EXECUTION_SCOPE_ALREADY_BOUND");
|
|
42798
|
+
}
|
|
42799
|
+
if (input.submittedScope === null) {
|
|
42800
|
+
throw new Error("MANCODE_IMPLEMENTATION_SCOPE_REQUIRED");
|
|
42801
|
+
}
|
|
42802
|
+
if (input.currentPlan === null || input.currentPlan !== input.submittedPlan) {
|
|
42803
|
+
throw new Error("MANCODE_EXECUTION_SCOPE_BINDING_PLAN_CHANGED");
|
|
42804
|
+
}
|
|
42805
|
+
if (input.planDecisionSupplied) {
|
|
42806
|
+
throw new Error("MANCODE_EXECUTION_SCOPE_BINDING_DECISION_INVALID");
|
|
42807
|
+
}
|
|
42808
|
+
assertExecutableImplementationScope(input.submittedScope);
|
|
42809
|
+
return true;
|
|
42810
|
+
}
|
|
42811
|
+
function updateMetadata(previous, requirements, review, verification, implementationScope, authorityChanged, planDecision, executionScopeBinding, operationId, updatedAt) {
|
|
42812
|
+
const status2 = executionScopeBinding ? previous.status : planDecision === "plan_only" ? "planned" : "in_progress";
|
|
42813
|
+
const currentStep = executionScopeBinding ? previous.currentStep : planDecision === "governed_execution" ? 5 : 4;
|
|
42814
|
+
const nextPlanVersion = previous.governance.planVersion + (authorityChanged ? 1 : 0);
|
|
42815
|
+
const next = parseWorkflowMetadata({
|
|
42816
|
+
...previous,
|
|
42817
|
+
status: status2,
|
|
42818
|
+
currentStep,
|
|
42819
|
+
revision: previous.revision + 1,
|
|
42820
|
+
transitionState: "stable",
|
|
42821
|
+
lastOperationId: operationId,
|
|
42822
|
+
implementationScope,
|
|
42823
|
+
governance: {
|
|
42824
|
+
...previous.governance,
|
|
42825
|
+
requirementsStatus: "ready",
|
|
42826
|
+
requirementsDigest: requirements.contentDigest,
|
|
42827
|
+
planVersion: nextPlanVersion,
|
|
42828
|
+
planDecision: executionScopeBinding ? previous.governance.planDecision : planDecision,
|
|
42829
|
+
reviewStatus: authorityChanged ? "stale" : previous.governance.reviewStatus,
|
|
42830
|
+
reviewLedgerDigest: review.contentDigest,
|
|
42831
|
+
verificationStatus: authorityChanged ? "stale" : previous.governance.verificationStatus,
|
|
42832
|
+
verificationLedgerDigest: verification.contentDigest
|
|
42833
|
+
},
|
|
42834
|
+
soloExecution: executionScopeBinding && previous.soloExecution !== null ? { ...previous.soloExecution, planVersion: nextPlanVersion } : previous.soloExecution,
|
|
42835
|
+
updatedAt
|
|
42836
|
+
});
|
|
42837
|
+
assertWorkflowMetadataTransition(previous, next, "ordinary");
|
|
42838
|
+
return next;
|
|
42839
|
+
}
|
|
42840
|
+
|
|
42841
|
+
// src/context/reframe.ts
|
|
42842
|
+
async function reframeV3Workflow(input) {
|
|
42843
|
+
const taskRef = parseTaskRefValue(input.taskRef);
|
|
42844
|
+
assertUlid(input.checkpointId, "reframe checkpointId");
|
|
42845
|
+
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
42846
|
+
const operationId = input.operationId ?? createUlid(now.getTime());
|
|
42847
|
+
assertUlid(operationId, "reframe operationId");
|
|
42848
|
+
const opened = await openReframeContext({
|
|
42849
|
+
projectRoot: input.projectRoot,
|
|
42850
|
+
taskRef,
|
|
42851
|
+
sessionId: input.sessionId,
|
|
42852
|
+
expectedTaskRevision: input.expectedTaskRevision,
|
|
42853
|
+
checkpointId: input.checkpointId,
|
|
42854
|
+
operationId,
|
|
42855
|
+
now
|
|
42856
|
+
});
|
|
42857
|
+
const { context, activeClaims: activeClaims2, openHandoffs, activeChildren } = opened;
|
|
42858
|
+
let journal = null;
|
|
42859
|
+
try {
|
|
42860
|
+
assertReframeEligible(context, activeClaims2, openHandoffs, activeChildren);
|
|
42861
|
+
assertReframeClaimsFresh(context, activeClaims2);
|
|
42862
|
+
const timestamp4 = context.now.toISOString();
|
|
42863
|
+
const archivedRequirementsContent = await readTaskAuthorityFileAtRoot(
|
|
42864
|
+
context.task.location.taskRoot,
|
|
42865
|
+
"requirements.json"
|
|
42866
|
+
);
|
|
42867
|
+
if (archivedRequirementsContent === null) {
|
|
42868
|
+
throw new Error("MANCODE_REFRAME_REQUIREMENTS_MISSING");
|
|
42869
|
+
}
|
|
42870
|
+
const pendingMetadata = markReframeOperationPending(
|
|
42871
|
+
context.task.metadata,
|
|
42872
|
+
context.operationId,
|
|
42873
|
+
timestamp4
|
|
42874
|
+
);
|
|
42875
|
+
const requirements = createReframedRequirements(
|
|
42876
|
+
context.task.requirements,
|
|
42877
|
+
context.operationId,
|
|
42878
|
+
timestamp4
|
|
42879
|
+
);
|
|
42880
|
+
const review = markTaskReviewStale(
|
|
42881
|
+
context.task.review,
|
|
42882
|
+
context.operationId,
|
|
42883
|
+
timestamp4
|
|
42884
|
+
);
|
|
42885
|
+
const verification = markTaskVerificationStale(
|
|
42886
|
+
context.task.verification,
|
|
42887
|
+
context.operationId,
|
|
42888
|
+
timestamp4
|
|
42889
|
+
);
|
|
42890
|
+
const releasedClaims = activeClaims2.map(
|
|
42891
|
+
(claim) => releaseClaimForReframe(claim, context.operationId, timestamp4)
|
|
42892
|
+
);
|
|
42893
|
+
const archiveAction = createTaskArchiveRecoveryAction({
|
|
42894
|
+
stepId: "archive-requirements-plan",
|
|
42895
|
+
taskRef,
|
|
42896
|
+
archiveId: context.operationId,
|
|
42897
|
+
sourceTaskRevision: context.task.metadata.revision,
|
|
42898
|
+
sourcePlanVersion: context.task.metadata.governance.planVersion,
|
|
42899
|
+
createdAt: timestamp4,
|
|
42900
|
+
requirementsContent: archivedRequirementsContent,
|
|
42901
|
+
planContent: context.task.plan?.content ?? null
|
|
42902
|
+
});
|
|
42903
|
+
const branch = await readCheckoutBranch(context.projectRoot);
|
|
42904
|
+
const checkpoint = buildReframeCheckpoint({
|
|
42905
|
+
context,
|
|
42906
|
+
checkpointId: input.checkpointId,
|
|
42907
|
+
taskRevision: pendingMetadata.revision + 1,
|
|
42908
|
+
requirements,
|
|
42909
|
+
review,
|
|
42910
|
+
verification,
|
|
42911
|
+
summary: input.summary,
|
|
42912
|
+
nextAction: input.nextAction,
|
|
42913
|
+
branch,
|
|
42914
|
+
timestamp: timestamp4
|
|
42915
|
+
});
|
|
42916
|
+
const metadata = completeReframeMetadata(
|
|
42917
|
+
pendingMetadata,
|
|
42918
|
+
requirements,
|
|
42919
|
+
review,
|
|
42920
|
+
verification,
|
|
42921
|
+
checkpoint,
|
|
42922
|
+
context.operationId,
|
|
42923
|
+
timestamp4
|
|
42924
|
+
);
|
|
42925
|
+
const aggregate = buildTaskAggregateManifest({
|
|
42926
|
+
metadata,
|
|
42927
|
+
requirements,
|
|
42928
|
+
review,
|
|
42929
|
+
verification,
|
|
42930
|
+
planDigest: context.task.plan?.digest ?? null,
|
|
42931
|
+
latestCheckpoint: checkpoint
|
|
42932
|
+
});
|
|
42933
|
+
const taskHeadFence = nextTaskHeadFence(context, aggregate, timestamp4);
|
|
42934
|
+
const refreshesSessionPointer = context.session.activeTaskRef !== null && sameTaskRef(context.session.activeTaskRef, taskRef);
|
|
42935
|
+
if (refreshesSessionPointer) {
|
|
42936
|
+
await enqueueSessionPointerProjection(context.projectRoot, {
|
|
42937
|
+
operationId: context.operationId,
|
|
42938
|
+
action: "resume",
|
|
42939
|
+
sessionId: context.session.sessionId,
|
|
42940
|
+
expectedPreviousTaskRef: context.session.activeTaskRef,
|
|
42941
|
+
taskRef,
|
|
42942
|
+
workflowMode: metadata.workflowMode,
|
|
42943
|
+
taskRevision: metadata.revision,
|
|
42944
|
+
now: context.now
|
|
42945
|
+
});
|
|
42946
|
+
}
|
|
42947
|
+
journal = await createTaskOperationJournal(context, {
|
|
42948
|
+
type: "reframe",
|
|
42949
|
+
action: taskRef.namespace === "shared" ? "shared_metadata_plan_mutation" : "local_workflow_mutation",
|
|
42950
|
+
expectedRevisions: reframeExpectedRevisions(
|
|
42951
|
+
context,
|
|
42952
|
+
input.checkpointId,
|
|
42953
|
+
activeClaims2
|
|
42954
|
+
),
|
|
42955
|
+
recovery: {
|
|
42956
|
+
actions: [
|
|
42957
|
+
createTaskAuthorityFileRecoveryAction({
|
|
42958
|
+
stepId: "mark-task-operation-pending",
|
|
42959
|
+
taskRef,
|
|
42960
|
+
fileName: "metadata.json",
|
|
42961
|
+
beforeContent: serializeTaskAuthority(context.task.metadata),
|
|
42962
|
+
targetContent: serializeTaskAuthority(pendingMetadata)
|
|
42963
|
+
}),
|
|
42964
|
+
archiveAction,
|
|
42965
|
+
...releasedClaims.map(
|
|
42966
|
+
(claim, index) => createClaimRecoveryAction({
|
|
42967
|
+
stepId: "release-active-claims",
|
|
42968
|
+
before: activeClaims2[index] ?? null,
|
|
42969
|
+
claim
|
|
42970
|
+
})
|
|
42971
|
+
),
|
|
42972
|
+
createTaskAuthorityFileRecoveryAction({
|
|
42973
|
+
stepId: "write-requirements-draft",
|
|
42974
|
+
taskRef,
|
|
42975
|
+
fileName: "requirements.json",
|
|
42976
|
+
beforeContent: serializeTaskAuthority(context.task.requirements),
|
|
42977
|
+
targetContent: serializeTaskAuthority(requirements)
|
|
42978
|
+
}),
|
|
42979
|
+
createTaskAuthorityFileRecoveryAction({
|
|
42980
|
+
stepId: "mark-review-verification-stale",
|
|
42981
|
+
taskRef,
|
|
42982
|
+
fileName: "review-ledger.json",
|
|
42983
|
+
beforeContent: serializeTaskAuthority(context.task.review),
|
|
42984
|
+
targetContent: serializeTaskAuthority(review)
|
|
42985
|
+
}),
|
|
42986
|
+
createTaskAuthorityFileRecoveryAction({
|
|
42987
|
+
stepId: "mark-review-verification-stale",
|
|
42988
|
+
taskRef,
|
|
42989
|
+
fileName: "verification-ledger.json",
|
|
42990
|
+
beforeContent: serializeTaskAuthority(context.task.verification),
|
|
42991
|
+
targetContent: serializeTaskAuthority(verification)
|
|
42992
|
+
}),
|
|
42993
|
+
createCheckpointRecoveryAction({
|
|
42994
|
+
stepId: "write-reframe-checkpoint",
|
|
42995
|
+
before: null,
|
|
42996
|
+
checkpoint
|
|
42997
|
+
}),
|
|
42998
|
+
createTaskAuthorityFileRecoveryAction({
|
|
42999
|
+
stepId: "commit-reframed-metadata",
|
|
43000
|
+
taskRef,
|
|
43001
|
+
fileName: "metadata.json",
|
|
43002
|
+
beforeContent: serializeTaskAuthority(pendingMetadata),
|
|
43003
|
+
targetContent: serializeTaskAuthority(metadata)
|
|
43004
|
+
}),
|
|
43005
|
+
...taskHeadFence === null ? [] : [
|
|
43006
|
+
createTaskHeadFenceRecoveryAction({
|
|
43007
|
+
stepId: "update-task-head-fence",
|
|
43008
|
+
before: context.coordination.taskHeadFence,
|
|
43009
|
+
fence: taskHeadFence
|
|
43010
|
+
})
|
|
43011
|
+
]
|
|
43012
|
+
],
|
|
43013
|
+
noOpStepIds: [
|
|
43014
|
+
...releasedClaims.length === 0 ? ["release-active-claims"] : [],
|
|
43015
|
+
...taskHeadFence === null ? ["update-task-head-fence"] : []
|
|
43016
|
+
]
|
|
43017
|
+
}
|
|
43018
|
+
});
|
|
43019
|
+
journal = await advanceTaskOperation(context, journal, "validate", true);
|
|
43020
|
+
journal = await advanceTaskOperation(
|
|
43021
|
+
context,
|
|
43022
|
+
journal,
|
|
43023
|
+
"mark-task-operation-pending",
|
|
43024
|
+
false
|
|
43025
|
+
);
|
|
43026
|
+
await assertReframeCodeHeadUnchanged(context);
|
|
43027
|
+
await writeTaskAuthorityFile(
|
|
43028
|
+
context,
|
|
43029
|
+
"metadata.json",
|
|
43030
|
+
serializeTaskAuthority(pendingMetadata)
|
|
43031
|
+
);
|
|
43032
|
+
journal = await advanceTaskOperation(
|
|
43033
|
+
context,
|
|
43034
|
+
journal,
|
|
43035
|
+
"archive-requirements-plan",
|
|
43036
|
+
false
|
|
43037
|
+
);
|
|
43038
|
+
await assertReframeCodeHeadUnchanged(context);
|
|
43039
|
+
await writeTaskArchive(context, archiveAction);
|
|
43040
|
+
journal = await advanceTaskOperation(
|
|
43041
|
+
context,
|
|
43042
|
+
journal,
|
|
43043
|
+
"release-active-claims",
|
|
43044
|
+
false
|
|
43045
|
+
);
|
|
43046
|
+
await assertReframeCodeHeadUnchanged(context);
|
|
43047
|
+
for (const [index, claim] of releasedClaims.entries()) {
|
|
43048
|
+
const previous = activeClaims2[index];
|
|
43049
|
+
if (previous === void 0) throw new Error("MANCODE_CLAIM_SET_CHANGED");
|
|
43050
|
+
await updateClaim(context.homeStore, claim, previous.revision);
|
|
43051
|
+
}
|
|
43052
|
+
journal = await advanceTaskOperation(
|
|
43053
|
+
context,
|
|
43054
|
+
journal,
|
|
43055
|
+
"write-requirements-draft",
|
|
43056
|
+
false
|
|
43057
|
+
);
|
|
43058
|
+
await assertReframeCodeHeadUnchanged(context);
|
|
43059
|
+
await writeTaskAuthorityFile(
|
|
43060
|
+
context,
|
|
43061
|
+
"requirements.json",
|
|
43062
|
+
serializeTaskAuthority(requirements)
|
|
43063
|
+
);
|
|
43064
|
+
journal = await advanceTaskOperation(
|
|
43065
|
+
context,
|
|
43066
|
+
journal,
|
|
43067
|
+
"mark-review-verification-stale",
|
|
43068
|
+
false
|
|
43069
|
+
);
|
|
43070
|
+
await assertReframeCodeHeadUnchanged(context);
|
|
43071
|
+
await writeTaskAuthorityFile(
|
|
43072
|
+
context,
|
|
43073
|
+
"review-ledger.json",
|
|
43074
|
+
serializeTaskAuthority(review)
|
|
43075
|
+
);
|
|
43076
|
+
await writeTaskAuthorityFile(
|
|
43077
|
+
context,
|
|
43078
|
+
"verification-ledger.json",
|
|
43079
|
+
serializeTaskAuthority(verification)
|
|
43080
|
+
);
|
|
43081
|
+
journal = await advanceTaskOperation(
|
|
43082
|
+
context,
|
|
43083
|
+
journal,
|
|
43084
|
+
"write-reframe-checkpoint",
|
|
42334
43085
|
false
|
|
42335
43086
|
);
|
|
42336
43087
|
await assertReframeCodeHeadUnchanged(context);
|
|
@@ -42658,6 +43409,9 @@ async function writeV3Requirements(input, action) {
|
|
|
42658
43409
|
if (action === "finalize" && submitted.status !== "confirmed") {
|
|
42659
43410
|
throw new Error("MANCODE_REQUIREMENTS_CONFIRMATION_REQUIRED");
|
|
42660
43411
|
}
|
|
43412
|
+
if (action === "finalize") {
|
|
43413
|
+
assertRequirementsScopeConsistent(submitted);
|
|
43414
|
+
}
|
|
42661
43415
|
if (action === "draft" && submitted.status !== "draft") {
|
|
42662
43416
|
throw new Error("MANCODE_REQUIREMENTS_DRAFT_REQUIRED");
|
|
42663
43417
|
}
|
|
@@ -42930,454 +43684,95 @@ async function applyV3ReviewLedger(input) {
|
|
|
42930
43684
|
journal = await createTaskOperationJournal(context, {
|
|
42931
43685
|
type: "review_remediation",
|
|
42932
43686
|
action: authorization.action,
|
|
42933
|
-
evidence: authorization.evidence,
|
|
42934
|
-
conditions: authorization.conditions,
|
|
42935
|
-
expectedRevisions: taskMutationExpectedRevisions(context, [
|
|
42936
|
-
"review",
|
|
42937
|
-
"verification"
|
|
42938
|
-
]),
|
|
42939
|
-
recovery: {
|
|
42940
|
-
actions: [
|
|
42941
|
-
createTaskAuthorityFileRecoveryAction({
|
|
42942
|
-
stepId: "write-review-ledger",
|
|
42943
|
-
taskRef,
|
|
42944
|
-
fileName: "review-ledger.json",
|
|
42945
|
-
beforeContent: serializeTaskAuthority(context.task.review),
|
|
42946
|
-
targetContent: serializeTaskAuthority(review)
|
|
42947
|
-
}),
|
|
42948
|
-
createTaskAuthorityFileRecoveryAction({
|
|
42949
|
-
stepId: "mark-verification-stale",
|
|
42950
|
-
taskRef,
|
|
42951
|
-
fileName: "verification-ledger.json",
|
|
42952
|
-
beforeContent: serializeTaskAuthority(context.task.verification),
|
|
42953
|
-
targetContent: serializeTaskAuthority(verification)
|
|
42954
|
-
}),
|
|
42955
|
-
createTaskAuthorityFileRecoveryAction({
|
|
42956
|
-
stepId: "update-metadata",
|
|
42957
|
-
taskRef,
|
|
42958
|
-
fileName: "metadata.json",
|
|
42959
|
-
beforeContent: serializeTaskAuthority(context.task.metadata),
|
|
42960
|
-
targetContent: serializeTaskAuthority(metadata)
|
|
42961
|
-
}),
|
|
42962
|
-
...taskHeadFence === null ? [] : [
|
|
42963
|
-
createTaskHeadFenceRecoveryAction({
|
|
42964
|
-
stepId: "update-task-head-fence",
|
|
42965
|
-
before: context.coordination.taskHeadFence,
|
|
42966
|
-
fence: taskHeadFence
|
|
42967
|
-
})
|
|
42968
|
-
]
|
|
42969
|
-
],
|
|
42970
|
-
noOpStepIds: taskHeadFence === null ? ["update-task-head-fence"] : []
|
|
42971
|
-
}
|
|
42972
|
-
});
|
|
42973
|
-
journal = await advanceTaskOperation(context, journal, "validate", true);
|
|
42974
|
-
journal = await advanceTaskOperation(
|
|
42975
|
-
context,
|
|
42976
|
-
journal,
|
|
42977
|
-
"write-review-ledger",
|
|
42978
|
-
false
|
|
42979
|
-
);
|
|
42980
|
-
await writeTaskAuthorityFile(
|
|
42981
|
-
context,
|
|
42982
|
-
"review-ledger.json",
|
|
42983
|
-
serializeTaskAuthority(review)
|
|
42984
|
-
);
|
|
42985
|
-
journal = await advanceTaskOperation(
|
|
42986
|
-
context,
|
|
42987
|
-
journal,
|
|
42988
|
-
"mark-verification-stale",
|
|
42989
|
-
false
|
|
42990
|
-
);
|
|
42991
|
-
await writeTaskAuthorityFile(
|
|
42992
|
-
context,
|
|
42993
|
-
"verification-ledger.json",
|
|
42994
|
-
serializeTaskAuthority(verification)
|
|
42995
|
-
);
|
|
42996
|
-
journal = await advanceTaskOperation(
|
|
42997
|
-
context,
|
|
42998
|
-
journal,
|
|
42999
|
-
"update-metadata",
|
|
43000
|
-
false
|
|
43001
|
-
);
|
|
43002
|
-
await writeTaskAuthorityFile(
|
|
43003
|
-
context,
|
|
43004
|
-
"metadata.json",
|
|
43005
|
-
serializeTaskAuthority(metadata)
|
|
43006
|
-
);
|
|
43007
|
-
journal = await advanceTaskOperation(
|
|
43008
|
-
context,
|
|
43009
|
-
journal,
|
|
43010
|
-
"update-task-head-fence",
|
|
43011
|
-
false
|
|
43012
|
-
);
|
|
43013
|
-
if (taskHeadFence !== null) {
|
|
43014
|
-
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
43015
|
-
await replaceTaskHeadFence(context.homeStore, taskHeadFence);
|
|
43016
|
-
}
|
|
43017
|
-
const operation = await commitTaskOperation(context, journal);
|
|
43018
|
-
return {
|
|
43019
|
-
metadata,
|
|
43020
|
-
review,
|
|
43021
|
-
verification,
|
|
43022
|
-
aggregate,
|
|
43023
|
-
taskHeadFence,
|
|
43024
|
-
operation
|
|
43025
|
-
};
|
|
43026
|
-
} catch (error) {
|
|
43027
|
-
if (journal !== null) {
|
|
43028
|
-
try {
|
|
43029
|
-
await handleTaskOperationFailure(context, journal);
|
|
43030
|
-
} catch {
|
|
43031
|
-
}
|
|
43032
|
-
}
|
|
43033
|
-
throw error;
|
|
43034
|
-
} finally {
|
|
43035
|
-
await context.release();
|
|
43036
|
-
}
|
|
43037
|
-
}
|
|
43038
|
-
function assertReviewEligible(metadata, hasPlan) {
|
|
43039
|
-
if (metadata.workflowMode !== "man" && metadata.workflowMode !== "manteam") {
|
|
43040
|
-
throw new Error("MANCODE_REVIEW_WORKFLOW_MODE_INVALID");
|
|
43041
|
-
}
|
|
43042
|
-
if (metadata.status !== "in_progress" && metadata.status !== "blocked") {
|
|
43043
|
-
throw new Error("MANCODE_REVIEW_WORKFLOW_NOT_ACTIVE");
|
|
43044
|
-
}
|
|
43045
|
-
if (metadata.currentStep < 5 || metadata.governance.planDecision !== "governed_execution" || !hasPlan) {
|
|
43046
|
-
throw new Error("MANCODE_REVIEW_PLAN_GATE_REQUIRED");
|
|
43047
|
-
}
|
|
43048
|
-
}
|
|
43049
|
-
function createCurrentReview(previous, submitted, metadata, operationId, updatedAt) {
|
|
43050
|
-
if (submitted.requirementsDigest !== metadata.governance.requirementsDigest || submitted.planVersion !== metadata.governance.planVersion) {
|
|
43051
|
-
throw new Error("MANCODE_REVIEW_CONTEXT_STALE");
|
|
43052
|
-
}
|
|
43053
|
-
const draft = {
|
|
43054
|
-
...submitted,
|
|
43055
|
-
taskRef: previous.taskRef,
|
|
43056
|
-
revision: previous.revision + 1,
|
|
43057
|
-
contentDigest: "",
|
|
43058
|
-
lastOperationId: operationId,
|
|
43059
|
-
updatedAt
|
|
43060
|
-
};
|
|
43061
|
-
const next = parseReviewLedger({
|
|
43062
|
-
...draft,
|
|
43063
|
-
contentDigest: reviewLedgerDigest(draft)
|
|
43064
|
-
});
|
|
43065
|
-
assertReviewLedgerTransition(previous, next);
|
|
43066
|
-
assertReviewLedgerAgainstContext(next, {
|
|
43067
|
-
requirementsDigest: metadata.governance.requirementsDigest,
|
|
43068
|
-
planVersion: metadata.governance.planVersion
|
|
43069
|
-
});
|
|
43070
|
-
return next;
|
|
43071
|
-
}
|
|
43072
|
-
function updateMetadata3(previous, review, verification, operationId, updatedAt) {
|
|
43073
|
-
const next = parseWorkflowMetadata({
|
|
43074
|
-
...previous,
|
|
43075
|
-
revision: previous.revision + 1,
|
|
43076
|
-
transitionState: "stable",
|
|
43077
|
-
lastOperationId: operationId,
|
|
43078
|
-
governance: {
|
|
43079
|
-
...previous.governance,
|
|
43080
|
-
reviewStatus: review.status,
|
|
43081
|
-
reviewLedgerDigest: review.contentDigest,
|
|
43082
|
-
verificationStatus: verification.status,
|
|
43083
|
-
verificationLedgerDigest: verification.contentDigest
|
|
43084
|
-
},
|
|
43085
|
-
updatedAt
|
|
43086
|
-
});
|
|
43087
|
-
assertWorkflowMetadataTransition(previous, next, "ordinary");
|
|
43088
|
-
return next;
|
|
43089
|
-
}
|
|
43090
|
-
function reviewAuthorization(context, next) {
|
|
43091
|
-
if (context.taskRef.namespace === "local") {
|
|
43092
|
-
return { action: "local_workflow_mutation" };
|
|
43093
|
-
}
|
|
43094
|
-
if (next.skip !== null) {
|
|
43095
|
-
return {
|
|
43096
|
-
action: "review_skip_or_waiver",
|
|
43097
|
-
conditions: { reviewAction: "skip", reason: next.skip.reason }
|
|
43098
|
-
};
|
|
43099
|
-
}
|
|
43100
|
-
const waivers = next.blockers.filter(
|
|
43101
|
-
(blocker) => blocker.status === "waived"
|
|
43102
|
-
);
|
|
43103
|
-
if (waivers.length > 0) {
|
|
43104
|
-
for (const blocker of waivers) {
|
|
43105
|
-
if (blocker.severity === "p0" || blocker.severity === "legacy_unknown" || blocker.waiver === null) {
|
|
43106
|
-
throw new Error("MANCODE_WAIVER_FORBIDDEN");
|
|
43107
|
-
}
|
|
43108
|
-
}
|
|
43109
|
-
const first = waivers[0];
|
|
43110
|
-
if (first?.waiver === null || first === void 0) {
|
|
43111
|
-
throw new Error("MANCODE_WAIVER_FORBIDDEN");
|
|
43112
|
-
}
|
|
43113
|
-
return {
|
|
43114
|
-
action: "review_skip_or_waiver",
|
|
43115
|
-
conditions: {
|
|
43116
|
-
reviewAction: "waiver",
|
|
43117
|
-
reviewSeverity: first.severity,
|
|
43118
|
-
reason: first.waiver.reason
|
|
43119
|
-
}
|
|
43120
|
-
};
|
|
43121
|
-
}
|
|
43122
|
-
return {
|
|
43123
|
-
action: "shared_ledger_evidence",
|
|
43124
|
-
evidence: {
|
|
43125
|
-
assignedToActor: context.task.metadata.ownerActorId === context.session.actorId,
|
|
43126
|
-
restrictsWriteToAssignedItem: true
|
|
43127
|
-
}
|
|
43128
|
-
};
|
|
43129
|
-
}
|
|
43130
|
-
|
|
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 },
|
|
43687
|
+
evidence: authorization.evidence,
|
|
43688
|
+
conditions: authorization.conditions,
|
|
43689
|
+
expectedRevisions: taskMutationExpectedRevisions(context, [
|
|
43690
|
+
"review",
|
|
43691
|
+
"verification"
|
|
43692
|
+
]),
|
|
43235
43693
|
recovery: {
|
|
43236
43694
|
actions: [
|
|
43237
43695
|
createTaskAuthorityFileRecoveryAction({
|
|
43238
|
-
stepId: "
|
|
43696
|
+
stepId: "write-review-ledger",
|
|
43239
43697
|
taskRef,
|
|
43240
|
-
fileName: "
|
|
43241
|
-
beforeContent: serializeTaskAuthority(context.task.
|
|
43242
|
-
targetContent: serializeTaskAuthority(
|
|
43243
|
-
}),
|
|
43244
|
-
createCheckpointRecoveryAction({
|
|
43245
|
-
stepId: "write-scope-changed-checkpoint",
|
|
43246
|
-
before: null,
|
|
43247
|
-
checkpoint
|
|
43698
|
+
fileName: "review-ledger.json",
|
|
43699
|
+
beforeContent: serializeTaskAuthority(context.task.review),
|
|
43700
|
+
targetContent: serializeTaskAuthority(review)
|
|
43248
43701
|
}),
|
|
43249
|
-
|
|
43250
|
-
|
|
43251
|
-
|
|
43252
|
-
|
|
43253
|
-
|
|
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
|
-
});
|
|
43702
|
+
createTaskAuthorityFileRecoveryAction({
|
|
43703
|
+
stepId: "mark-verification-stale",
|
|
43704
|
+
taskRef,
|
|
43705
|
+
fileName: "verification-ledger.json",
|
|
43706
|
+
beforeContent: serializeTaskAuthority(context.task.verification),
|
|
43707
|
+
targetContent: serializeTaskAuthority(verification)
|
|
43266
43708
|
}),
|
|
43267
43709
|
createTaskAuthorityFileRecoveryAction({
|
|
43268
|
-
stepId: "update-metadata
|
|
43710
|
+
stepId: "update-metadata",
|
|
43269
43711
|
taskRef,
|
|
43270
43712
|
fileName: "metadata.json",
|
|
43271
|
-
beforeContent: serializeTaskAuthority(
|
|
43713
|
+
beforeContent: serializeTaskAuthority(context.task.metadata),
|
|
43272
43714
|
targetContent: serializeTaskAuthority(metadata)
|
|
43273
43715
|
}),
|
|
43274
|
-
...
|
|
43275
|
-
|
|
43276
|
-
|
|
43277
|
-
|
|
43278
|
-
|
|
43279
|
-
|
|
43280
|
-
|
|
43281
|
-
before,
|
|
43282
|
-
claim
|
|
43283
|
-
});
|
|
43284
|
-
}),
|
|
43285
|
-
createTaskHeadFenceRecoveryAction({
|
|
43286
|
-
stepId: "update-task-head-fence",
|
|
43287
|
-
before: context.coordination.taskHeadFence,
|
|
43288
|
-
fence: taskHeadFence
|
|
43289
|
-
})
|
|
43716
|
+
...taskHeadFence === null ? [] : [
|
|
43717
|
+
createTaskHeadFenceRecoveryAction({
|
|
43718
|
+
stepId: "update-task-head-fence",
|
|
43719
|
+
before: context.coordination.taskHeadFence,
|
|
43720
|
+
fence: taskHeadFence
|
|
43721
|
+
})
|
|
43722
|
+
]
|
|
43290
43723
|
],
|
|
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
|
-
]
|
|
43724
|
+
noOpStepIds: taskHeadFence === null ? ["update-task-head-fence"] : []
|
|
43296
43725
|
}
|
|
43297
43726
|
});
|
|
43298
43727
|
journal = await advanceTaskOperation(context, journal, "validate", true);
|
|
43299
43728
|
journal = await advanceTaskOperation(
|
|
43300
43729
|
context,
|
|
43301
43730
|
journal,
|
|
43302
|
-
"
|
|
43731
|
+
"write-review-ledger",
|
|
43303
43732
|
false
|
|
43304
43733
|
);
|
|
43305
|
-
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
43306
43734
|
await writeTaskAuthorityFile(
|
|
43307
43735
|
context,
|
|
43308
|
-
"
|
|
43309
|
-
|
|
43310
|
-
`
|
|
43311
|
-
);
|
|
43312
|
-
journal = await advanceTaskOperation(
|
|
43313
|
-
context,
|
|
43314
|
-
journal,
|
|
43315
|
-
"write-scope-changed-checkpoint",
|
|
43316
|
-
false
|
|
43736
|
+
"review-ledger.json",
|
|
43737
|
+
serializeTaskAuthority(review)
|
|
43317
43738
|
);
|
|
43318
|
-
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
43319
|
-
await writeTaskCheckpoint(context, checkpoint);
|
|
43320
43739
|
journal = await advanceTaskOperation(
|
|
43321
43740
|
context,
|
|
43322
43741
|
journal,
|
|
43323
|
-
"
|
|
43742
|
+
"mark-verification-stale",
|
|
43324
43743
|
false
|
|
43325
43744
|
);
|
|
43326
|
-
await
|
|
43327
|
-
for (const claim of pendingSuccessorClaims) {
|
|
43328
|
-
await createClaim(context.homeStore, claim);
|
|
43329
|
-
}
|
|
43330
|
-
journal = await advanceTaskOperation(
|
|
43745
|
+
await writeTaskAuthorityFile(
|
|
43331
43746
|
context,
|
|
43332
|
-
|
|
43333
|
-
|
|
43334
|
-
false
|
|
43747
|
+
"verification-ledger.json",
|
|
43748
|
+
serializeTaskAuthority(verification)
|
|
43335
43749
|
);
|
|
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
43750
|
journal = await advanceTaskOperation(
|
|
43345
43751
|
context,
|
|
43346
43752
|
journal,
|
|
43347
|
-
"update-metadata
|
|
43753
|
+
"update-metadata",
|
|
43348
43754
|
false
|
|
43349
43755
|
);
|
|
43350
|
-
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
43351
43756
|
await writeTaskAuthorityFile(
|
|
43352
43757
|
context,
|
|
43353
43758
|
"metadata.json",
|
|
43354
|
-
|
|
43355
|
-
`
|
|
43356
|
-
);
|
|
43357
|
-
journal = await advanceTaskOperation(
|
|
43358
|
-
context,
|
|
43359
|
-
journal,
|
|
43360
|
-
"activate-successor-claims",
|
|
43361
|
-
false
|
|
43759
|
+
serializeTaskAuthority(metadata)
|
|
43362
43760
|
);
|
|
43363
|
-
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
43364
|
-
for (const claim of activeSuccessorClaims) {
|
|
43365
|
-
await updateClaim(context.homeStore, claim, 1);
|
|
43366
|
-
}
|
|
43367
43761
|
journal = await advanceTaskOperation(
|
|
43368
43762
|
context,
|
|
43369
43763
|
journal,
|
|
43370
43764
|
"update-task-head-fence",
|
|
43371
43765
|
false
|
|
43372
43766
|
);
|
|
43373
|
-
|
|
43374
|
-
|
|
43767
|
+
if (taskHeadFence !== null) {
|
|
43768
|
+
await assertTaskCodeHeadUnchanged(context.projectRoot, context.codeHead);
|
|
43769
|
+
await replaceTaskHeadFence(context.homeStore, taskHeadFence);
|
|
43770
|
+
}
|
|
43375
43771
|
const operation = await commitTaskOperation(context, journal);
|
|
43376
43772
|
return {
|
|
43377
43773
|
metadata,
|
|
43378
|
-
|
|
43379
|
-
|
|
43380
|
-
successorClaims: activeSuccessorClaims,
|
|
43774
|
+
review,
|
|
43775
|
+
verification,
|
|
43381
43776
|
aggregate,
|
|
43382
43777
|
taskHeadFence,
|
|
43383
43778
|
operation
|
|
@@ -43394,312 +43789,97 @@ async function changeV3WorkflowScope(input) {
|
|
|
43394
43789
|
await context.release();
|
|
43395
43790
|
}
|
|
43396
43791
|
}
|
|
43397
|
-
|
|
43398
|
-
|
|
43399
|
-
|
|
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`);
|
|
43792
|
+
function assertReviewEligible(metadata, hasPlan) {
|
|
43793
|
+
if (metadata.workflowMode !== "man" && metadata.workflowMode !== "manteam") {
|
|
43794
|
+
throw new Error("MANCODE_REVIEW_WORKFLOW_MODE_INVALID");
|
|
43510
43795
|
}
|
|
43511
|
-
|
|
43512
|
-
|
|
43513
|
-
if (normalized.length !== values.length) {
|
|
43514
|
-
throw new Error(`MANCODE_SCOPE_${label.toUpperCase()}_DUPLICATE`);
|
|
43796
|
+
if (metadata.status !== "in_progress" && metadata.status !== "blocked") {
|
|
43797
|
+
throw new Error("MANCODE_REVIEW_WORKFLOW_NOT_ACTIVE");
|
|
43515
43798
|
}
|
|
43516
|
-
|
|
43517
|
-
|
|
43518
|
-
if (paths) assertScopePath(item);
|
|
43799
|
+
if (metadata.currentStep < 5 || metadata.governance.planDecision !== "governed_execution" || !hasPlan) {
|
|
43800
|
+
throw new Error("MANCODE_REVIEW_PLAN_GATE_REQUIRED");
|
|
43519
43801
|
}
|
|
43520
|
-
return normalized;
|
|
43521
43802
|
}
|
|
43522
|
-
function
|
|
43523
|
-
if (
|
|
43524
|
-
throw new Error("
|
|
43803
|
+
function createCurrentReview(previous, submitted, metadata, operationId, updatedAt) {
|
|
43804
|
+
if (submitted.requirementsDigest !== metadata.governance.requirementsDigest || submitted.planVersion !== metadata.governance.planVersion) {
|
|
43805
|
+
throw new Error("MANCODE_REVIEW_CONTEXT_STALE");
|
|
43525
43806
|
}
|
|
43526
|
-
|
|
43527
|
-
|
|
43528
|
-
|
|
43529
|
-
...previous,
|
|
43807
|
+
const draft = {
|
|
43808
|
+
...submitted,
|
|
43809
|
+
taskRef: previous.taskRef,
|
|
43530
43810
|
revision: previous.revision + 1,
|
|
43531
|
-
|
|
43811
|
+
contentDigest: "",
|
|
43532
43812
|
lastOperationId: operationId,
|
|
43533
43813
|
updatedAt
|
|
43814
|
+
};
|
|
43815
|
+
const next = parseReviewLedger({
|
|
43816
|
+
...draft,
|
|
43817
|
+
contentDigest: reviewLedgerDigest(draft)
|
|
43818
|
+
});
|
|
43819
|
+
assertReviewLedgerTransition(previous, next);
|
|
43820
|
+
assertReviewLedgerAgainstContext(next, {
|
|
43821
|
+
requirementsDigest: metadata.governance.requirementsDigest,
|
|
43822
|
+
planVersion: metadata.governance.planVersion
|
|
43534
43823
|
});
|
|
43535
|
-
assertWorkflowMetadataTransition(previous, next, "ordinary");
|
|
43536
43824
|
return next;
|
|
43537
43825
|
}
|
|
43538
|
-
function
|
|
43826
|
+
function updateMetadata3(previous, review, verification, operationId, updatedAt) {
|
|
43539
43827
|
const next = parseWorkflowMetadata({
|
|
43540
43828
|
...previous,
|
|
43541
43829
|
revision: previous.revision + 1,
|
|
43542
43830
|
transitionState: "stable",
|
|
43543
|
-
implementationScope: scope,
|
|
43544
|
-
latestCheckpointRef: {
|
|
43545
|
-
taskRef: checkpoint.taskRef,
|
|
43546
|
-
kind: "checkpoint",
|
|
43547
|
-
artifactId: checkpoint.checkpointId
|
|
43548
|
-
},
|
|
43549
43831
|
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
43832
|
governance: {
|
|
43571
|
-
|
|
43572
|
-
|
|
43573
|
-
reviewLedgerDigest:
|
|
43574
|
-
|
|
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
|
|
43833
|
+
...previous.governance,
|
|
43834
|
+
reviewStatus: review.status,
|
|
43835
|
+
reviewLedgerDigest: review.contentDigest,
|
|
43836
|
+
verificationStatus: verification.status,
|
|
43837
|
+
verificationLedgerDigest: verification.contentDigest
|
|
43580
43838
|
},
|
|
43581
|
-
|
|
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
|
|
43839
|
+
updatedAt
|
|
43631
43840
|
});
|
|
43632
|
-
|
|
43841
|
+
assertWorkflowMetadataTransition(previous, next, "ordinary");
|
|
43633
43842
|
return next;
|
|
43634
43843
|
}
|
|
43635
|
-
function
|
|
43636
|
-
|
|
43637
|
-
|
|
43638
|
-
[`checkpoint:${checkpointId}`]: 0
|
|
43639
|
-
};
|
|
43640
|
-
for (const claim of predecessors) {
|
|
43641
|
-
expected[`claim:${claim.claimId}`] = claim.revision;
|
|
43844
|
+
function reviewAuthorization(context, next) {
|
|
43845
|
+
if (context.taskRef.namespace === "local") {
|
|
43846
|
+
return { action: "local_workflow_mutation" };
|
|
43642
43847
|
}
|
|
43643
|
-
|
|
43644
|
-
|
|
43848
|
+
if (next.skip !== null) {
|
|
43849
|
+
return {
|
|
43850
|
+
action: "review_skip_or_waiver",
|
|
43851
|
+
conditions: { reviewAction: "skip", reason: next.skip.reason }
|
|
43852
|
+
};
|
|
43645
43853
|
}
|
|
43646
|
-
const
|
|
43647
|
-
|
|
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)
|
|
43854
|
+
const waivers = next.blockers.filter(
|
|
43855
|
+
(blocker) => blocker.status === "waived"
|
|
43667
43856
|
);
|
|
43668
|
-
if (
|
|
43669
|
-
|
|
43670
|
-
|
|
43671
|
-
|
|
43672
|
-
|
|
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");
|
|
43857
|
+
if (waivers.length > 0) {
|
|
43858
|
+
for (const blocker of waivers) {
|
|
43859
|
+
if (blocker.severity === "p0" || blocker.severity === "legacy_unknown" || blocker.waiver === null) {
|
|
43860
|
+
throw new Error("MANCODE_WAIVER_FORBIDDEN");
|
|
43861
|
+
}
|
|
43677
43862
|
}
|
|
43678
|
-
|
|
43679
|
-
|
|
43680
|
-
|
|
43681
|
-
}
|
|
43682
|
-
|
|
43683
|
-
|
|
43684
|
-
|
|
43685
|
-
|
|
43686
|
-
|
|
43687
|
-
|
|
43688
|
-
|
|
43689
|
-
|
|
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");
|
|
43863
|
+
const first = waivers[0];
|
|
43864
|
+
if (first?.waiver === null || first === void 0) {
|
|
43865
|
+
throw new Error("MANCODE_WAIVER_FORBIDDEN");
|
|
43866
|
+
}
|
|
43867
|
+
return {
|
|
43868
|
+
action: "review_skip_or_waiver",
|
|
43869
|
+
conditions: {
|
|
43870
|
+
reviewAction: "waiver",
|
|
43871
|
+
reviewSeverity: first.severity,
|
|
43872
|
+
reason: first.waiver.reason
|
|
43873
|
+
}
|
|
43874
|
+
};
|
|
43695
43875
|
}
|
|
43696
|
-
return
|
|
43697
|
-
|
|
43698
|
-
|
|
43699
|
-
|
|
43700
|
-
|
|
43701
|
-
|
|
43702
|
-
|
|
43876
|
+
return {
|
|
43877
|
+
action: "shared_ledger_evidence",
|
|
43878
|
+
evidence: {
|
|
43879
|
+
assignedToActor: context.task.metadata.ownerActorId === context.session.actorId,
|
|
43880
|
+
restrictsWriteToAssignedItem: true
|
|
43881
|
+
}
|
|
43882
|
+
};
|
|
43703
43883
|
}
|
|
43704
43884
|
|
|
43705
43885
|
// src/context/solo-handoff.ts
|
|
@@ -43949,6 +44129,8 @@ function assertSoloStartEligible(context) {
|
|
|
43949
44129
|
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
44130
|
throw new Error("MANCODE_SOLO_HANDOFF_NOT_ELIGIBLE");
|
|
43951
44131
|
}
|
|
44132
|
+
assertRequirementsScopeConsistent(requirements);
|
|
44133
|
+
assertExecutableImplementationScope(metadata.implementationScope);
|
|
43952
44134
|
}
|
|
43953
44135
|
function assertSoloCompletionEligible(context) {
|
|
43954
44136
|
const { metadata } = context.task;
|
|
@@ -45237,11 +45419,20 @@ function initialScope(parent, explicitScope) {
|
|
|
45237
45419
|
};
|
|
45238
45420
|
return { ...inherited, digest: digestCanonicalJson(inherited) };
|
|
45239
45421
|
}
|
|
45422
|
+
if (explicitScope === void 0) {
|
|
45423
|
+
const unspecified = {
|
|
45424
|
+
source: "legacy_unspecified",
|
|
45425
|
+
include: [],
|
|
45426
|
+
exclude: [],
|
|
45427
|
+
modules: []
|
|
45428
|
+
};
|
|
45429
|
+
return { ...unspecified, digest: digestCanonicalJson(unspecified) };
|
|
45430
|
+
}
|
|
45240
45431
|
const explicit = {
|
|
45241
45432
|
source: "explicit",
|
|
45242
|
-
include: [...explicitScope
|
|
45243
|
-
exclude: [...explicitScope
|
|
45244
|
-
modules: [...explicitScope
|
|
45433
|
+
include: [...explicitScope.include ?? []],
|
|
45434
|
+
exclude: [...explicitScope.exclude ?? []],
|
|
45435
|
+
modules: [...explicitScope.modules ?? []]
|
|
45245
45436
|
};
|
|
45246
45437
|
return { ...explicit, digest: digestCanonicalJson(explicit) };
|
|
45247
45438
|
}
|
|
@@ -45703,10 +45894,22 @@ async function changeGitRefWorkflowScope(input) {
|
|
|
45703
45894
|
operationId,
|
|
45704
45895
|
timestamp4
|
|
45705
45896
|
);
|
|
45897
|
+
const review = markTaskReviewStale(
|
|
45898
|
+
opened.context.task.review,
|
|
45899
|
+
operationId,
|
|
45900
|
+
timestamp4
|
|
45901
|
+
);
|
|
45902
|
+
const verification = markTaskVerificationStale(
|
|
45903
|
+
opened.context.task.verification,
|
|
45904
|
+
operationId,
|
|
45905
|
+
timestamp4
|
|
45906
|
+
);
|
|
45706
45907
|
const metadata = scopeChangedMetadata(
|
|
45707
45908
|
pendingMetadata,
|
|
45708
45909
|
scope,
|
|
45709
45910
|
checkpointId,
|
|
45911
|
+
review.contentDigest,
|
|
45912
|
+
verification.contentDigest,
|
|
45710
45913
|
operationId,
|
|
45711
45914
|
timestamp4
|
|
45712
45915
|
);
|
|
@@ -45717,6 +45920,9 @@ async function changeGitRefWorkflowScope(input) {
|
|
|
45717
45920
|
summary: input.checkpointSummary,
|
|
45718
45921
|
nextAction: input.checkpointNextAction,
|
|
45719
45922
|
codeRef: opened.bundle.codeRef,
|
|
45923
|
+
planVersion: pendingMetadata.governance.planVersion + 1,
|
|
45924
|
+
reviewLedgerDigest: review.contentDigest,
|
|
45925
|
+
verificationLedgerDigest: verification.contentDigest,
|
|
45720
45926
|
timestamp: timestamp4
|
|
45721
45927
|
});
|
|
45722
45928
|
const finalMetadata = parseWorkflowMetadata({
|
|
@@ -45730,8 +45936,8 @@ async function changeGitRefWorkflowScope(input) {
|
|
|
45730
45936
|
const aggregate = buildTaskAggregateManifest({
|
|
45731
45937
|
metadata: finalMetadata,
|
|
45732
45938
|
requirements: opened.context.task.requirements,
|
|
45733
|
-
review
|
|
45734
|
-
verification
|
|
45939
|
+
review,
|
|
45940
|
+
verification,
|
|
45735
45941
|
planDigest: opened.context.task.plan?.digest ?? null,
|
|
45736
45942
|
latestCheckpoint: checkpoint
|
|
45737
45943
|
});
|
|
@@ -45754,6 +45960,8 @@ async function changeGitRefWorkflowScope(input) {
|
|
|
45754
45960
|
task: {
|
|
45755
45961
|
...opened.context.task,
|
|
45756
45962
|
metadata: finalMetadata,
|
|
45963
|
+
review,
|
|
45964
|
+
verification,
|
|
45757
45965
|
latestCheckpoint: checkpoint,
|
|
45758
45966
|
aggregate
|
|
45759
45967
|
},
|
|
@@ -46173,12 +46381,20 @@ function assertClaimsFresh(context, bundle, claims) {
|
|
|
46173
46381
|
}
|
|
46174
46382
|
}
|
|
46175
46383
|
}
|
|
46176
|
-
function scopeChangedMetadata(previous, scope, checkpointId, operationId, updatedAt) {
|
|
46384
|
+
function scopeChangedMetadata(previous, scope, checkpointId, reviewLedgerDigest2, verificationLedgerDigest2, operationId, updatedAt) {
|
|
46177
46385
|
const next = parseWorkflowMetadata({
|
|
46178
46386
|
...previous,
|
|
46179
46387
|
revision: previous.revision + 1,
|
|
46180
46388
|
transitionState: "stable",
|
|
46181
46389
|
implementationScope: scope,
|
|
46390
|
+
governance: {
|
|
46391
|
+
...previous.governance,
|
|
46392
|
+
planVersion: previous.governance.planVersion + 1,
|
|
46393
|
+
reviewStatus: "stale",
|
|
46394
|
+
reviewLedgerDigest: reviewLedgerDigest2,
|
|
46395
|
+
verificationStatus: "stale",
|
|
46396
|
+
verificationLedgerDigest: verificationLedgerDigest2
|
|
46397
|
+
},
|
|
46182
46398
|
latestCheckpointRef: {
|
|
46183
46399
|
taskRef: previous.taskRef,
|
|
46184
46400
|
kind: "checkpoint",
|
|
@@ -46207,9 +46423,9 @@ function scopeChangedCheckpoint(input) {
|
|
|
46207
46423
|
summary: input.summary ?? "Changed the implementation scope and replaced affected coordination claims.",
|
|
46208
46424
|
governance: {
|
|
46209
46425
|
requirementsDigest: input.context.task.requirements.contentDigest,
|
|
46210
|
-
planVersion: input.
|
|
46211
|
-
reviewLedgerDigest: input.
|
|
46212
|
-
verificationLedgerDigest: input.
|
|
46426
|
+
planVersion: input.planVersion,
|
|
46427
|
+
reviewLedgerDigest: input.reviewLedgerDigest,
|
|
46428
|
+
verificationLedgerDigest: input.verificationLedgerDigest
|
|
46213
46429
|
},
|
|
46214
46430
|
nextAction: input.nextAction ?? "Re-read the updated scope and continue only with the successor claim.",
|
|
46215
46431
|
createdBy: {
|
|
@@ -47400,7 +47616,7 @@ async function workflowPlanV3(rootDir, args, options) {
|
|
|
47400
47616
|
return printV3Error(
|
|
47401
47617
|
options.json,
|
|
47402
47618
|
"MANCODE_PLAN_ARGUMENT_INVALID",
|
|
47403
|
-
"Use: workflow plan <namespace:ULID> revise --expected-revision <n> --file <path
|
|
47619
|
+
"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
47620
|
EXIT_INVALID_ARG3
|
|
47405
47621
|
);
|
|
47406
47622
|
}
|
|
@@ -47429,6 +47645,14 @@ async function workflowPlanV3(rootDir, args, options) {
|
|
|
47429
47645
|
EXIT_INVALID_ARG3
|
|
47430
47646
|
);
|
|
47431
47647
|
}
|
|
47648
|
+
if (action === "confirm" && options.scopeFile !== void 0) {
|
|
47649
|
+
return printV3Error(
|
|
47650
|
+
options.json,
|
|
47651
|
+
"MANCODE_PLAN_SCOPE_REVISE_REQUIRED",
|
|
47652
|
+
"Bind implementation scope with workflow plan revise before confirmation.",
|
|
47653
|
+
EXIT_INVALID_ARG3
|
|
47654
|
+
);
|
|
47655
|
+
}
|
|
47432
47656
|
try {
|
|
47433
47657
|
const project = await readV3CommandProject(rootDir);
|
|
47434
47658
|
const taskRef = parseTaskRef(task);
|
|
@@ -47445,12 +47669,17 @@ async function workflowPlanV3(rootDir, args, options) {
|
|
|
47445
47669
|
if (plan === void 0 || plan === null) {
|
|
47446
47670
|
throw new Error("MANCODE_PLAN_FILE_REQUIRED");
|
|
47447
47671
|
}
|
|
47672
|
+
const implementationScope = action === "revise" && options.scopeFile !== void 0 ? await readWorkflowJsonInputFile(
|
|
47673
|
+
project.projectRoot,
|
|
47674
|
+
options.scopeFile
|
|
47675
|
+
) : void 0;
|
|
47448
47676
|
const result2 = await reviseV3Plan({
|
|
47449
47677
|
projectRoot: project.projectRoot,
|
|
47450
47678
|
taskRef,
|
|
47451
47679
|
sessionId: session.sessionId,
|
|
47452
47680
|
expectedTaskRevision,
|
|
47453
47681
|
plan,
|
|
47682
|
+
implementationScope,
|
|
47454
47683
|
planDecision: parseV3PlanDecision(options.planDecision)
|
|
47455
47684
|
});
|
|
47456
47685
|
return printV3Result(options.json, {
|
|
@@ -47703,6 +47932,7 @@ async function workflowRequirements(rootDir, args, options) {
|
|
|
47703
47932
|
const inputPath = path69.isAbsolute(options.file) ? options.file : path69.resolve(rootDir, options.file);
|
|
47704
47933
|
const input = await readFile48(inputPath, "utf-8");
|
|
47705
47934
|
const requirements = parseRequirementsLedger2(input);
|
|
47935
|
+
assertRequirementsScopeConsistent2(requirements);
|
|
47706
47936
|
[originalJson, originalMarkdown, originalMetadata] = await Promise.all([
|
|
47707
47937
|
readOptionalText2(jsonPath),
|
|
47708
47938
|
readOptionalText2(markdownPath),
|
|
@@ -48887,6 +49117,9 @@ program.command("workflow <subcommand> [args...]").description("Manage mancode w
|
|
|
48887
49117
|
).option(
|
|
48888
49118
|
"--file <path>",
|
|
48889
49119
|
"Semantic requirements JSON, plan Markdown, or ledger input file"
|
|
49120
|
+
).option(
|
|
49121
|
+
"--scope-file <path>",
|
|
49122
|
+
"Plan implementation scope JSON {include,exclude,modules}"
|
|
48890
49123
|
).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
49124
|
const code = await workflow(process.cwd(), subcommand, args ?? [], {
|
|
48892
49125
|
...options,
|