@deftai/directive-runtime 0.129.7 → 0.129.8
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/Taskfile.yml +9 -3
- package/commands.md +4 -1
- package/package.json +1 -1
- package/scm/github.md +5 -0
- package/skills/deft-directive-swarm/references/host-claude-code.md +11 -1
- package/vendor/directive-content/Taskfile.yml +9 -3
- package/vendor/directive-content/commands.md +4 -1
- package/vendor/directive-content/scm/github.md +5 -0
- package/vendor/directive-content/skills/deft-directive-swarm/references/host-claude-code.md +11 -1
- package/vendor/directive-core/dist/.tsbuildinfo +1 -1
- package/vendor/directive-core/dist/check/context.d.ts.map +1 -1
- package/vendor/directive-core/dist/check/context.js +3 -31
- package/vendor/directive-core/dist/check/context.js.map +1 -1
- package/vendor/directive-core/dist/check/gate-lists.d.ts.map +1 -1
- package/vendor/directive-core/dist/check/gate-lists.js +4 -32
- package/vendor/directive-core/dist/check/gate-lists.js.map +1 -1
- package/vendor/directive-core/dist/check/walk-test-files.d.ts +3 -0
- package/vendor/directive-core/dist/check/walk-test-files.d.ts.map +1 -0
- package/vendor/directive-core/dist/check/walk-test-files.js +67 -0
- package/vendor/directive-core/dist/check/walk-test-files.js.map +1 -0
- package/vendor/directive-core/dist/hooks/dispatcher.d.ts +6 -0
- package/vendor/directive-core/dist/hooks/dispatcher.d.ts.map +1 -1
- package/vendor/directive-core/dist/hooks/dispatcher.js +64 -6
- package/vendor/directive-core/dist/hooks/dispatcher.js.map +1 -1
- package/vendor/directive-core/dist/hooks/scope.d.ts +54 -0
- package/vendor/directive-core/dist/hooks/scope.d.ts.map +1 -1
- package/vendor/directive-core/dist/hooks/scope.js +83 -2
- package/vendor/directive-core/dist/hooks/scope.js.map +1 -1
- package/vendor/directive-core/dist/intake/reconcile-issues.d.ts +33 -1
- package/vendor/directive-core/dist/intake/reconcile-issues.d.ts.map +1 -1
- package/vendor/directive-core/dist/intake/reconcile-issues.js +288 -12
- package/vendor/directive-core/dist/intake/reconcile-issues.js.map +1 -1
- package/vendor/directive-core/dist/intake/thin-brief.d.ts +78 -0
- package/vendor/directive-core/dist/intake/thin-brief.d.ts.map +1 -0
- package/vendor/directive-core/dist/intake/thin-brief.js +224 -0
- package/vendor/directive-core/dist/intake/thin-brief.js.map +1 -0
- package/vendor/directive-core/dist/policy/ceremony-dial.d.ts.map +1 -1
- package/vendor/directive-core/dist/policy/ceremony-dial.js +2 -1
- package/vendor/directive-core/dist/policy/ceremony-dial.js.map +1 -1
- package/vendor/directive-core/dist/policy/small-change-lane.d.ts +193 -0
- package/vendor/directive-core/dist/policy/small-change-lane.d.ts.map +1 -0
- package/vendor/directive-core/dist/policy/small-change-lane.js +690 -0
- package/vendor/directive-core/dist/policy/small-change-lane.js.map +1 -0
- package/vendor/directive-core/dist/preflight/evaluate.d.ts +3 -0
- package/vendor/directive-core/dist/preflight/evaluate.d.ts.map +1 -1
- package/vendor/directive-core/dist/preflight/evaluate.js +15 -0
- package/vendor/directive-core/dist/preflight/evaluate.js.map +1 -1
- package/vendor/directive-core/dist/product-first-done-gate/evaluate.d.ts +6 -0
- package/vendor/directive-core/dist/product-first-done-gate/evaluate.d.ts.map +1 -1
- package/vendor/directive-core/dist/product-first-done-gate/evaluate.js +26 -0
- package/vendor/directive-core/dist/product-first-done-gate/evaluate.js.map +1 -1
- package/vendor/directive-core/dist/scope/decomposed-refs.d.ts +7 -0
- package/vendor/directive-core/dist/scope/decomposed-refs.d.ts.map +1 -1
- package/vendor/directive-core/dist/scope/decomposed-refs.js +27 -10
- package/vendor/directive-core/dist/scope/decomposed-refs.js.map +1 -1
- package/vendor/directive-core/dist/scope/delivery-evidence.d.ts +18 -2
- package/vendor/directive-core/dist/scope/delivery-evidence.d.ts.map +1 -1
- package/vendor/directive-core/dist/scope/delivery-evidence.js +30 -5
- package/vendor/directive-core/dist/scope/delivery-evidence.js.map +1 -1
- package/vendor/directive-core/dist/scope/transition.d.ts +3 -0
- package/vendor/directive-core/dist/scope/transition.d.ts.map +1 -1
- package/vendor/directive-core/dist/scope/transition.js +43 -3
- package/vendor/directive-core/dist/scope/transition.js.map +1 -1
- package/vendor/directive-core/dist/scope-provenance/base-fence.d.ts +2 -1
- package/vendor/directive-core/dist/scope-provenance/base-fence.d.ts.map +1 -1
- package/vendor/directive-core/dist/scope-provenance/base-fence.js +9 -1
- package/vendor/directive-core/dist/scope-provenance/base-fence.js.map +1 -1
- package/vendor/directive-core/dist/swarm/finalize-cohort.d.ts +20 -1
- package/vendor/directive-core/dist/swarm/finalize-cohort.d.ts.map +1 -1
- package/vendor/directive-core/dist/swarm/finalize-cohort.js +78 -33
- package/vendor/directive-core/dist/swarm/finalize-cohort.js.map +1 -1
- package/vendor/directive-core/dist/swarm/finalize-owed.d.ts +18 -3
- package/vendor/directive-core/dist/swarm/finalize-owed.d.ts.map +1 -1
- package/vendor/directive-core/dist/swarm/finalize-owed.js +139 -32
- package/vendor/directive-core/dist/swarm/finalize-owed.js.map +1 -1
- package/vendor/directive-core/dist/swarm/launch.d.ts.map +1 -1
- package/vendor/directive-core/dist/swarm/launch.js +4 -8
- package/vendor/directive-core/dist/swarm/launch.js.map +1 -1
- package/vendor/directive-core/dist/swarm/worker-auth-assignment.d.ts +7 -0
- package/vendor/directive-core/dist/swarm/worker-auth-assignment.d.ts.map +1 -1
- package/vendor/directive-core/dist/swarm/worker-auth-assignment.js +16 -1
- package/vendor/directive-core/dist/swarm/worker-auth-assignment.js.map +1 -1
- package/vendor/directive-core/dist/task-surface/index.d.ts.map +1 -1
- package/vendor/directive-core/dist/task-surface/index.js +41 -0
- package/vendor/directive-core/dist/task-surface/index.js.map +1 -1
- package/vendor/directive-core/dist/vbrief-reconcile/types.d.ts +5 -1
- package/vendor/directive-core/dist/vbrief-reconcile/types.d.ts.map +1 -1
- package/vendor/directive-core/dist/vbrief-reconcile/umbrellas.d.ts.map +1 -1
- package/vendor/directive-core/dist/vbrief-reconcile/umbrellas.js +19 -7
- package/vendor/directive-core/dist/vbrief-reconcile/umbrellas.js.map +1 -1
|
@@ -17,7 +17,11 @@ export type FinalizeOwedState = "owed" | "close-owed" | "stale"
|
|
|
17
17
|
/** Stale claim age, but origin issue not verified — blocks session, never reclaim. */
|
|
18
18
|
| "stale-unverified" | "in-flight" | "unverified" | "backlog" | "unknown";
|
|
19
19
|
export interface FinalizeOwedStory {
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Origin issue, or null for an issue-less brief whose identity is the stamped
|
|
22
|
+
* product PR (`pr-only`, #5710 / #680 P2). Never a fake `#0`.
|
|
23
|
+
*/
|
|
24
|
+
readonly issue: number | null;
|
|
21
25
|
readonly productPr: number;
|
|
22
26
|
readonly relPath: string;
|
|
23
27
|
readonly state: FinalizeOwedState;
|
|
@@ -50,7 +54,12 @@ export interface FinalizeOwedArgs {
|
|
|
50
54
|
readonly now?: () => number;
|
|
51
55
|
/** Test seam: skip live finalizeCohort. */
|
|
52
56
|
readonly runFinalize?: (args: {
|
|
53
|
-
issue: number;
|
|
57
|
+
issue: number | null;
|
|
58
|
+
/**
|
|
59
|
+
* Tip-relative brief paths: the story tokens for issue-less rows. Rows that share
|
|
60
|
+
* a product PR share one claim, so they finalize together (#680 P2).
|
|
61
|
+
*/
|
|
62
|
+
relPaths: readonly string[];
|
|
54
63
|
productPr: number;
|
|
55
64
|
claimRef: string;
|
|
56
65
|
projectRoot: string;
|
|
@@ -66,11 +75,16 @@ export interface FinalizeOwedResult {
|
|
|
66
75
|
readonly stories: readonly FinalizeOwedStory[];
|
|
67
76
|
readonly finalized: readonly number[];
|
|
68
77
|
readonly skipped: readonly number[];
|
|
78
|
+
/** Issue-less rows, by product PR (#680 P2). */
|
|
79
|
+
readonly finalized_prs: readonly number[];
|
|
80
|
+
readonly skipped_prs: readonly number[];
|
|
69
81
|
readonly errors: readonly string[];
|
|
70
82
|
readonly warnings: readonly string[];
|
|
71
83
|
readonly fetch_error: string | null;
|
|
72
84
|
readonly ok: boolean;
|
|
73
85
|
}
|
|
86
|
+
/** `#N`, or `pr #P` for an issue-less row; never `#0` (#680 P2). */
|
|
87
|
+
export declare function owedStoryLabel(story: Pick<FinalizeOwedStory, "issue" | "productPr">): string;
|
|
74
88
|
/**
|
|
75
89
|
* One list → one chunked `showBlobsBatch` → Map. Truncate/parse miss bisects;
|
|
76
90
|
* whole-N `git show` fallback is not a green inventory path (#5171).
|
|
@@ -87,7 +101,8 @@ export type UnmarkedFinalizeBind = {
|
|
|
87
101
|
readonly kind: "omit";
|
|
88
102
|
} | {
|
|
89
103
|
readonly kind: "unverified" | "refuse" | "admit";
|
|
90
|
-
|
|
104
|
+
/** Null when the plan has no origin issue; never a fake `#0` (#680 P2). */
|
|
105
|
+
readonly issue: number | null;
|
|
91
106
|
readonly productPr: number;
|
|
92
107
|
readonly detail: string;
|
|
93
108
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finalize-owed.d.ts","sourceRoot":"","sources":["../../src/swarm/finalize-owed.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AAetC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"finalize-owed.d.ts","sourceRoot":"","sources":["../../src/swarm/finalize-owed.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ import { deriveUnmarkedFinalizeAdmit, } from "../orphan-active/evaluate.js";
|
|
|
14
14
|
import { briefPairingKey, briefPlanIdentity, completedTwinRelPath, productPullRequestFromPlan, } from "../orphan-active/running-briefs.js";
|
|
15
15
|
import { assertSafeBranchName, FIELD_DELIVERY_BRANCH, isSafeBranchName, privateDestFetchArgv, resolveDeliveryBranch, } from "../policy/delivery-branch.js";
|
|
16
16
|
import { defaultRunGh } from "../pr-protected-issues/gh.js";
|
|
17
|
+
import { resolvePlanGithubIssueRef, resolvePrOnlyDeliveryIdentity, } from "../scope/delivery-evidence.js";
|
|
17
18
|
import { defaultGitRunner, envGitRunner, showBlobsBatch, timedGitRunner, } from "../session/git.js";
|
|
18
19
|
import { parseGithubIssueUri } from "../triage/reconcile/parse-uri.js";
|
|
19
20
|
import { EXIT_CONFIG_ERROR, EXIT_GATE_FAILED, EXIT_INCOMPLETE, EXIT_OK } from "./constants.js";
|
|
@@ -31,6 +32,22 @@ export const CLAIM_PROBE_UNKNOWN_DETAIL = "claim metadata unavailable";
|
|
|
31
32
|
export function createFinalizeClaimRunner() {
|
|
32
33
|
return envGitRunner({ GIT_TERMINAL_PROMPT: "0" });
|
|
33
34
|
}
|
|
35
|
+
/** `#N`, or `pr #P` for an issue-less row; never `#0` (#680 P2). */
|
|
36
|
+
export function owedStoryLabel(story) {
|
|
37
|
+
if (story.issue !== null) {
|
|
38
|
+
return `#${String(story.issue)}`;
|
|
39
|
+
}
|
|
40
|
+
return story.productPr > 0 ? `pr #${String(story.productPr)}` : "(no issue, no product PR)";
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Issue-less owed rows have no origin issue to verify or close (#680 P2): they
|
|
44
|
+
* stay owed until the brief completes on the delivery tip.
|
|
45
|
+
*/
|
|
46
|
+
const ISSUELESS_ORIGIN_STATE = {
|
|
47
|
+
state: "open",
|
|
48
|
+
protectedUmbrella: false,
|
|
49
|
+
error: null,
|
|
50
|
+
};
|
|
34
51
|
const NONTERMINAL_PREFIXES = (() => {
|
|
35
52
|
const out = [];
|
|
36
53
|
for (const root of ["xbrief", "vbrief"]) {
|
|
@@ -110,6 +127,25 @@ function issueFromPlan(plan, expectedRepo) {
|
|
|
110
127
|
}
|
|
111
128
|
return number;
|
|
112
129
|
}
|
|
130
|
+
/** Tip path under `xbrief|vbrief/active/` (#680 P2: only active briefs complete). */
|
|
131
|
+
function isActiveTipPath(relPath) {
|
|
132
|
+
return /^(?:xbrief|vbrief)\/active\//.test(relPath.replace(/\\/g, "/"));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Issue-less brief with PR-only identity (#5710 P1 / #680 P2): no github-issue
|
|
136
|
+
* origin at all, a stamped productPullRequest, and the configured repo as the
|
|
137
|
+
* canonical remote. The same predicate the delivery gate's PR-only join reads.
|
|
138
|
+
*/
|
|
139
|
+
function isPrOnlyOwedPlan(plan, repo) {
|
|
140
|
+
if (resolvePlanGithubIssueRef(plan) !== null || extractIssueRef(plan)[1] !== null) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
if (countPlanGithubIssueReferences(plan) > 0) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return resolvePrOnlyDeliveryIdentity(plan, () => (repo.trim().length > 0 ? repo.trim() : null))
|
|
147
|
+
.ok;
|
|
148
|
+
}
|
|
113
149
|
/**
|
|
114
150
|
* Count distinct `references[]` github-issue origins — never `x-tracking` (#5122).
|
|
115
151
|
* Origin key is repo+number; duplicate URIs for one origin stay one; two
|
|
@@ -150,7 +186,7 @@ export function bindUnmarkedFinalizePair(input) {
|
|
|
150
186
|
if (countPlanGithubIssueReferences(input.plan) > 1) {
|
|
151
187
|
return {
|
|
152
188
|
kind: "refuse",
|
|
153
|
-
issue: input.issueFromPlan
|
|
189
|
+
issue: input.issueFromPlan,
|
|
154
190
|
productPr: 0,
|
|
155
191
|
detail: "unmarked refuse: multiple github-issue references",
|
|
156
192
|
};
|
|
@@ -169,7 +205,7 @@ export function bindUnmarkedFinalizePair(input) {
|
|
|
169
205
|
if (input.issueFromPlan === null) {
|
|
170
206
|
return {
|
|
171
207
|
kind: "refuse",
|
|
172
|
-
issue:
|
|
208
|
+
issue: null,
|
|
173
209
|
productPr: 0,
|
|
174
210
|
detail: "unmarked refuse: origin missing from issueFromPlan",
|
|
175
211
|
};
|
|
@@ -184,7 +220,7 @@ export function bindUnmarkedFinalizePair(input) {
|
|
|
184
220
|
}
|
|
185
221
|
return {
|
|
186
222
|
kind: "admit",
|
|
187
|
-
issue: input.
|
|
223
|
+
issue: input.issueFromPlan,
|
|
188
224
|
productPr: input.admit.productPr,
|
|
189
225
|
detail: input.admit.detail,
|
|
190
226
|
};
|
|
@@ -549,7 +585,7 @@ export function discoverFinalizeOwed(projectRoot, options) {
|
|
|
549
585
|
productPr: bound.productPr,
|
|
550
586
|
relPath,
|
|
551
587
|
state: "unverified",
|
|
552
|
-
claimRef: finalizeClaimRef(null, bound.productPr > 0 ? [bound.productPr] : [], bound.issue
|
|
588
|
+
claimRef: finalizeClaimRef(null, bound.productPr > 0 ? [bound.productPr] : [], bound.issue !== null ? [String(bound.issue)] : []),
|
|
553
589
|
pairingKey: briefPairingKey(relPath),
|
|
554
590
|
planIdentity: briefPlanIdentity(plan),
|
|
555
591
|
detail: bound.detail,
|
|
@@ -561,9 +597,14 @@ export function discoverFinalizeOwed(projectRoot, options) {
|
|
|
561
597
|
issue = bound.issue;
|
|
562
598
|
unmarkedDetail = bound.detail;
|
|
563
599
|
}
|
|
564
|
-
|
|
600
|
+
// Issue-less brief with a stamped productPullRequest and PR-only identity joins
|
|
601
|
+
// the same discovery (#680 P2); a foreign or unreadable issue ref does not.
|
|
602
|
+
// Only an active brief can complete, so only active/ rows are admitted (#680 P2).
|
|
603
|
+
const prOnlyIdentity = issue === null && unmarkedDetail === null && isPrOnlyOwedPlan(plan, options.repo);
|
|
604
|
+
const prOnly = prOnlyIdentity && isActiveTipPath(relPath);
|
|
605
|
+
if (issue === null && !prOnly) {
|
|
565
606
|
stories.push({
|
|
566
|
-
issue:
|
|
607
|
+
issue: null,
|
|
567
608
|
productPr,
|
|
568
609
|
relPath,
|
|
569
610
|
state: "unverified",
|
|
@@ -572,12 +613,14 @@ export function discoverFinalizeOwed(projectRoot, options) {
|
|
|
572
613
|
planIdentity: briefPlanIdentity(plan),
|
|
573
614
|
detail: unmarkedDetail !== null
|
|
574
615
|
? `${unmarkedDetail}; issue ref missing or foreign repo`
|
|
575
|
-
:
|
|
616
|
+
: prOnlyIdentity
|
|
617
|
+
? "pr-only identity but not in active/; only an active brief can complete"
|
|
618
|
+
: "mark present but issue ref missing or foreign repo",
|
|
576
619
|
blocks: false,
|
|
577
620
|
});
|
|
578
621
|
continue;
|
|
579
622
|
}
|
|
580
|
-
const claimRef = finalizeClaimRef(null, [productPr], [String(issue)]);
|
|
623
|
+
const claimRef = finalizeClaimRef(null, [productPr], issue === null ? [] : [String(issue)]);
|
|
581
624
|
const snap = snapshotAccepts(productPr, options.repo, options.deliveryBranch, projectRoot, options.tip, runGh, runGit);
|
|
582
625
|
if (!snap.ok) {
|
|
583
626
|
stories.push({
|
|
@@ -637,7 +680,7 @@ export function discoverFinalizeOwed(projectRoot, options) {
|
|
|
637
680
|
});
|
|
638
681
|
continue;
|
|
639
682
|
}
|
|
640
|
-
const issueState = fetchIssueState(issue, options.repo, runGh);
|
|
683
|
+
const issueState = issue === null ? ISSUELESS_ORIGIN_STATE : fetchIssueState(issue, options.repo, runGh);
|
|
641
684
|
if (claim.kind === "unknown") {
|
|
642
685
|
// Unverifiable issue-state stays unknown+blocking; closed / unmarked protected exempt (#6008).
|
|
643
686
|
if (issueState.error !== null || issueState.state === null) {
|
|
@@ -737,10 +780,13 @@ export function discoverFinalizeOwed(projectRoot, options) {
|
|
|
737
780
|
planIdentity: briefPlanIdentity(plan),
|
|
738
781
|
detail: unmarkedDetail !== null
|
|
739
782
|
? `${unmarkedDetail}; snapshot accepted; no twin`
|
|
740
|
-
:
|
|
783
|
+
: prOnly
|
|
784
|
+
? "pr-only identity (no origin issue); snapshot accepted; no twin"
|
|
785
|
+
: "marked nonterminal; snapshot accepted; no twin",
|
|
741
786
|
blocks: true,
|
|
742
787
|
});
|
|
743
788
|
}
|
|
789
|
+
// Completed issue-less briefs are done: no origin issue to close (#680 P2).
|
|
744
790
|
for (const relPath of completed) {
|
|
745
791
|
const plan = readTipPlan(projectRoot, options.tip, relPath, runGit, tipBodies);
|
|
746
792
|
if (plan === null) {
|
|
@@ -891,7 +937,7 @@ export function discoverFinalizeOwed(projectRoot, options) {
|
|
|
891
937
|
blocks: true,
|
|
892
938
|
});
|
|
893
939
|
}
|
|
894
|
-
stories.sort((a, b) => a.issue - b.issue || a.relPath.localeCompare(b.relPath));
|
|
940
|
+
stories.sort((a, b) => (a.issue ?? 0) - (b.issue ?? 0) || a.relPath.localeCompare(b.relPath));
|
|
895
941
|
return {
|
|
896
942
|
deliveryBranch: options.deliveryBranch,
|
|
897
943
|
tip: options.tip,
|
|
@@ -1088,7 +1134,8 @@ export function finalizeOwed(args = {}) {
|
|
|
1088
1134
|
tip: fetched.tip,
|
|
1089
1135
|
stories: inventory.stories,
|
|
1090
1136
|
finalized: [],
|
|
1091
|
-
skipped: inventory.stories.
|
|
1137
|
+
skipped: inventory.stories.flatMap((s) => (s.issue === null ? [] : [s.issue])),
|
|
1138
|
+
skippedPrs: inventory.stories.flatMap((s) => (s.issue === null ? [s.productPr] : [])),
|
|
1092
1139
|
errors,
|
|
1093
1140
|
warnings,
|
|
1094
1141
|
fetch_error: null,
|
|
@@ -1101,40 +1148,60 @@ export function finalizeOwed(args = {}) {
|
|
|
1101
1148
|
: undefined,
|
|
1102
1149
|
});
|
|
1103
1150
|
}
|
|
1151
|
+
// Issue-less rows report by product PR (#680 P2); never a fake issue number.
|
|
1152
|
+
const finalizedPrs = [];
|
|
1153
|
+
const skippedPrs = [];
|
|
1154
|
+
const skip = (story) => {
|
|
1155
|
+
if (story.issue === null) {
|
|
1156
|
+
skippedPrs.push(story.productPr);
|
|
1157
|
+
}
|
|
1158
|
+
else {
|
|
1159
|
+
skipped.push(story.issue);
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1162
|
+
let refusedOwnMark = false;
|
|
1163
|
+
// Issue-less rows that share a product PR share one claim ref and branch, so they
|
|
1164
|
+
// finalize in one call under that claim (#680 P2).
|
|
1165
|
+
const runnable = (s) => s.state === "owed" || s.state === "stale";
|
|
1166
|
+
const issuelessGroupDone = new Set();
|
|
1104
1167
|
for (const story of inventory.stories) {
|
|
1168
|
+
const label = owedStoryLabel(story);
|
|
1169
|
+
if (story.issue === null && runnable(story) && issuelessGroupDone.has(story.claimRef)) {
|
|
1170
|
+
continue;
|
|
1171
|
+
}
|
|
1105
1172
|
if (story.state === "in-flight" ||
|
|
1106
1173
|
story.state === "unverified" ||
|
|
1107
1174
|
story.state === "backlog" ||
|
|
1108
1175
|
story.state === "unknown") {
|
|
1109
1176
|
if (story.state === "unknown") {
|
|
1110
|
-
warnings.push(
|
|
1177
|
+
warnings.push(`${label}: ${CLAIM_PROBE_UNKNOWN_DETAIL}`);
|
|
1111
1178
|
}
|
|
1112
|
-
|
|
1179
|
+
skip(story);
|
|
1113
1180
|
continue;
|
|
1114
1181
|
}
|
|
1115
1182
|
if (story.state === "stale-unverified") {
|
|
1116
1183
|
// Keep claim; block remains until issue verify succeeds (#4919).
|
|
1117
|
-
warnings.push(
|
|
1118
|
-
|
|
1184
|
+
warnings.push(`${label}: origin-issue unverified; claim still blocking (stale-unverified)`);
|
|
1185
|
+
skip(story);
|
|
1119
1186
|
continue;
|
|
1120
1187
|
}
|
|
1121
1188
|
if (story.state === "stale") {
|
|
1122
1189
|
const deleted = deleteStaleClaim(projectRoot, story.claimRef, runGit);
|
|
1123
1190
|
if (!deleted.ok) {
|
|
1124
|
-
warnings.push(
|
|
1125
|
-
|
|
1191
|
+
warnings.push(`${label}: stale reclaim failed: ${deleted.detail}`);
|
|
1192
|
+
skip(story);
|
|
1126
1193
|
continue;
|
|
1127
1194
|
}
|
|
1128
1195
|
}
|
|
1129
1196
|
if (story.state !== "owed" && story.state !== "close-owed" && story.state !== "stale") {
|
|
1130
|
-
|
|
1197
|
+
skip(story);
|
|
1131
1198
|
continue;
|
|
1132
1199
|
}
|
|
1133
1200
|
const claim = tryClaimRef(projectRoot, story.claimRef, fetched.tip, runGit);
|
|
1134
1201
|
if (!claim.claimed) {
|
|
1135
1202
|
// Close-owed also requires the create-only claim; another live owner must win (#4919).
|
|
1136
|
-
warnings.push(
|
|
1137
|
-
|
|
1203
|
+
warnings.push(`${label}: in flight (${claim.detail})`);
|
|
1204
|
+
skip(story);
|
|
1138
1205
|
continue;
|
|
1139
1206
|
}
|
|
1140
1207
|
const runFinalize = args.runFinalize ??
|
|
@@ -1142,7 +1209,8 @@ export function finalizeOwed(args = {}) {
|
|
|
1142
1209
|
const result = finalizeCohort({
|
|
1143
1210
|
projectRoot: input.projectRoot,
|
|
1144
1211
|
prNumbers: [input.productPr],
|
|
1145
|
-
|
|
1212
|
+
// Issue-less rows select the brief by path; origin-close then has no issue (#680 P2).
|
|
1213
|
+
storyTokens: input.issue === null ? [...input.relPaths] : [String(input.issue)],
|
|
1146
1214
|
repo: repo.trim(),
|
|
1147
1215
|
deliveryBranch,
|
|
1148
1216
|
label: null,
|
|
@@ -1163,26 +1231,57 @@ export function finalizeOwed(args = {}) {
|
|
|
1163
1231
|
return { exitCode: result.exitCode, result: result.result, stdout: result.stdout };
|
|
1164
1232
|
});
|
|
1165
1233
|
// Fresh checkout isolation: finalize-cohort prepareLifecycleCheckout owns this.
|
|
1234
|
+
const relPaths = story.issue === null
|
|
1235
|
+
? inventory.stories
|
|
1236
|
+
.filter((s) => s.issue === null && s.claimRef === story.claimRef && runnable(s))
|
|
1237
|
+
.map((s) => s.relPath)
|
|
1238
|
+
: [story.relPath];
|
|
1239
|
+
if (story.issue === null) {
|
|
1240
|
+
issuelessGroupDone.add(story.claimRef);
|
|
1241
|
+
}
|
|
1166
1242
|
const outcome = runFinalize({
|
|
1167
1243
|
issue: story.issue,
|
|
1244
|
+
relPaths,
|
|
1168
1245
|
productPr: story.productPr,
|
|
1169
1246
|
claimRef: story.claimRef,
|
|
1170
1247
|
projectRoot,
|
|
1171
1248
|
});
|
|
1172
|
-
|
|
1249
|
+
const ownMarkRefused = story.issue !== null &&
|
|
1250
|
+
(outcome.result.refused_marks ?? []).some((mark) => mark.issue === story.issue);
|
|
1251
|
+
if (ownMarkRefused) {
|
|
1252
|
+
// A refused mark leaves the story pending, not finalized (#680 P3).
|
|
1253
|
+
refusedOwnMark = true;
|
|
1254
|
+
warnings.push(`${label}: deft-story mark refused; story left pending`);
|
|
1255
|
+
skip(story);
|
|
1256
|
+
}
|
|
1257
|
+
else if (outcome.exitCode === EXIT_OK ||
|
|
1173
1258
|
outcome.exitCode === EXIT_INCOMPLETE ||
|
|
1174
1259
|
outcome.result.pending !== null) {
|
|
1175
|
-
|
|
1260
|
+
if (story.issue === null) {
|
|
1261
|
+
finalizedPrs.push(story.productPr);
|
|
1262
|
+
}
|
|
1263
|
+
else {
|
|
1264
|
+
finalized.push(story.issue);
|
|
1265
|
+
}
|
|
1176
1266
|
if (outcome.exitCode === EXIT_INCOMPLETE || outcome.result.pending !== null) {
|
|
1177
|
-
|
|
1267
|
+
const otherRefused = (outcome.result.refused_marks ?? []).map((m) => `#${String(m.issue)}`);
|
|
1268
|
+
warnings.push(outcome.result.pending === null && otherRefused.length > 0
|
|
1269
|
+
? `${label}: finalize incomplete (refused deft-story mark pending: ${otherRefused.join(", ")})`
|
|
1270
|
+
: story.issue === null
|
|
1271
|
+
? `${label}: finalize incomplete (lifecycle land pending; no origin issue to close); leftover handed off`
|
|
1272
|
+
: `${label}: finalize incomplete (origin-close pending); leftover handed off`);
|
|
1178
1273
|
}
|
|
1179
1274
|
}
|
|
1180
1275
|
else {
|
|
1181
|
-
errors.push(
|
|
1182
|
-
|
|
1276
|
+
errors.push(`${label}: finalize failed (exit ${String(outcome.exitCode)}): ${outcome.result.errors[0] ?? outcome.stdout.trim().split("\n").pop() ?? "unknown"}`);
|
|
1277
|
+
skip(story);
|
|
1183
1278
|
}
|
|
1184
1279
|
}
|
|
1185
|
-
const incomplete =
|
|
1280
|
+
const incomplete = refusedOwnMark ||
|
|
1281
|
+
warnings.some((w) => w.includes("origin-close pending") ||
|
|
1282
|
+
w.includes("lifecycle land pending") ||
|
|
1283
|
+
w.includes("refused deft-story mark pending") ||
|
|
1284
|
+
w.includes("origin-issue unverified"));
|
|
1186
1285
|
const failed = errors.length > 0;
|
|
1187
1286
|
// Ordinary path: unknown stories force non-zero so session gate cannot stay blocked while exit 0 (#6008).
|
|
1188
1287
|
const hasUnknown = inventory.stories.some((s) => s.state === "unknown");
|
|
@@ -1193,6 +1292,8 @@ export function finalizeOwed(args = {}) {
|
|
|
1193
1292
|
stories: inventory.stories,
|
|
1194
1293
|
finalized,
|
|
1195
1294
|
skipped,
|
|
1295
|
+
finalizedPrs,
|
|
1296
|
+
skippedPrs,
|
|
1196
1297
|
errors,
|
|
1197
1298
|
warnings,
|
|
1198
1299
|
fetch_error: null,
|
|
@@ -1208,6 +1309,8 @@ function respondFinalizeOwed(input) {
|
|
|
1208
1309
|
stories: input.stories,
|
|
1209
1310
|
finalized: input.finalized,
|
|
1210
1311
|
skipped: input.skipped,
|
|
1312
|
+
finalized_prs: input.finalizedPrs ?? [],
|
|
1313
|
+
skipped_prs: input.skippedPrs ?? [],
|
|
1211
1314
|
errors: input.errors,
|
|
1212
1315
|
warnings: input.warnings,
|
|
1213
1316
|
fetch_error: input.fetch_error,
|
|
@@ -1237,15 +1340,19 @@ function respondFinalizeOwed(input) {
|
|
|
1237
1340
|
if (input.stories.length > 0) {
|
|
1238
1341
|
lines.push(" Inventory:");
|
|
1239
1342
|
for (const story of input.stories) {
|
|
1240
|
-
lines.push(`
|
|
1343
|
+
lines.push(` ${owedStoryLabel(story)} pr=#${String(story.productPr)} state=${story.state}` +
|
|
1241
1344
|
`${story.blocks ? " [blocks]" : ""} -- ${story.detail}`);
|
|
1242
1345
|
}
|
|
1243
1346
|
}
|
|
1244
1347
|
else if (input.fetch_error === null) {
|
|
1245
1348
|
lines.push(" Inventory: (empty)");
|
|
1246
1349
|
}
|
|
1247
|
-
|
|
1248
|
-
|
|
1350
|
+
const finalizedLabels = [
|
|
1351
|
+
...input.finalized.map((n) => `#${String(n)}`),
|
|
1352
|
+
...(input.finalizedPrs ?? []).map((n) => `pr #${String(n)}`),
|
|
1353
|
+
];
|
|
1354
|
+
if (finalizedLabels.length > 0) {
|
|
1355
|
+
lines.push(` Finalized: ${finalizedLabels.join(", ")}`);
|
|
1249
1356
|
}
|
|
1250
1357
|
if (input.warnings.length > 0) {
|
|
1251
1358
|
lines.push(" Warnings:");
|
|
@@ -1289,7 +1396,7 @@ export function formatFinalizeOwedInventoryLines(inventory) {
|
|
|
1289
1396
|
}
|
|
1290
1397
|
const lines = ["finalize owed inventory:"];
|
|
1291
1398
|
for (const story of nonBacklog) {
|
|
1292
|
-
lines.push(`
|
|
1399
|
+
lines.push(` ${owedStoryLabel(story)} ${story.state}${story.blocks ? " [blocks]" : ""}` +
|
|
1293
1400
|
` pr=#${String(story.productPr)} ${story.relPath}`);
|
|
1294
1401
|
}
|
|
1295
1402
|
return lines;
|