@open-agent-toolkit/cli 0.3.36 → 0.3.38
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/assets/bundle-metadata.json +1 -1
- package/assets/docs/provider-sync/pilot-with-a-team.md +6 -6
- package/assets/docs/provider-sync/providers.md +1 -0
- package/assets/docs/reference/cli-reference.md +3 -3
- package/assets/docs/reference/project-artifacts.md +12 -3
- package/assets/docs/reference/what-oat-writes.md +14 -11
- package/assets/docs/skills/repo-improve.md +23 -19
- package/assets/docs/workflows/advanced/workflow-gates.md +7 -1
- package/assets/docs/workflows/projects/closeout/closeout-skills.md +3 -1
- package/assets/docs/workflows/projects/lifecycle.md +3 -1
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-project-brief/SKILL.md +1 -1
- package/assets/skills/oat-project-brief/references/brief-contract.md +32 -9
- package/assets/skills/oat-project-implement/SKILL.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +14 -4
- package/assets/skills/oat-project-pr-progress/SKILL.md +23 -12
- package/assets/skills/oat-repo-knowledge-index/SKILL.md +226 -131
- package/dist/commands/project/closeout-check/index.d.ts.map +1 -1
- package/dist/commands/project/closeout-check/index.js +4 -8
- package/dist/commands/project/delivery/check.d.ts.map +1 -1
- package/dist/commands/project/delivery/check.js +32 -14
- package/dist/commands/project/delivery/evidence.d.ts +39 -0
- package/dist/commands/project/delivery/evidence.d.ts.map +1 -1
- package/dist/commands/project/delivery/evidence.js +163 -17
- package/dist/commands/project/delivery/refresh.d.ts.map +1 -1
- package/dist/commands/project/delivery/refresh.js +13 -16
- package/dist/commands/project/journal-check/index.d.ts +2 -0
- package/dist/commands/project/journal-check/index.d.ts.map +1 -1
- package/dist/commands/project/journal-check/index.js +78 -1
- package/dist/commands/project/journal-check/types.d.ts +1 -1
- package/dist/commands/project/journal-check/types.d.ts.map +1 -1
- package/dist/providers/codex/codec/config-merge.d.ts +5 -1
- package/dist/providers/codex/codec/config-merge.d.ts.map +1 -1
- package/dist/providers/codex/codec/config-merge.js +111 -62
- package/dist/providers/codex/codec/config-toml-edit.d.ts +8 -0
- package/dist/providers/codex/codec/config-toml-edit.d.ts.map +1 -0
- package/dist/providers/codex/codec/config-toml-edit.js +718 -0
- package/package.json +3 -3
|
@@ -8,7 +8,7 @@ import { CliError } from '../../../errors/cli-error.js';
|
|
|
8
8
|
import { resolveProjectRoot } from '../../../fs/paths.js';
|
|
9
9
|
import { getProjectState, milestonePhaseScope, normalizeMilestoneId, } from '@open-agent-toolkit/control-plane';
|
|
10
10
|
import { Command } from 'commander';
|
|
11
|
-
import { deliveryEvidenceScope,
|
|
11
|
+
import { deliveryEvidenceScope, evaluateDeliveryExitCarrier, evaluateDeliveryReview, evaluateGateCarrier, evaluateSuccessor, gateEvidenceArtifacts, latestDeliveryForMilestone, reviewRowsFor, } from './evidence.js';
|
|
12
12
|
/** The skill whose gate the milestone exit carrier records. */
|
|
13
13
|
const EXIT_GATE_SKILL = 'oat-project-implement';
|
|
14
14
|
export const DEFAULT_DELIVERY_PROJECT_DEPENDENCIES = {
|
|
@@ -82,17 +82,18 @@ export async function evaluateSubjectEvidence(project, subject, git) {
|
|
|
82
82
|
if (delivery) {
|
|
83
83
|
const milestoneId = delivery.milestone;
|
|
84
84
|
const scope = deliveryEffectiveScope(deliveries, delivery);
|
|
85
|
-
const
|
|
85
|
+
const workingCarrier = milestoneId === null
|
|
86
|
+
? null
|
|
87
|
+
: (project.state.milestoneGates?.[milestoneId]?.exit ?? null);
|
|
88
|
+
const evidence = deliveryEvidenceScope({ ...project, evidenceCarrier: workingCarrier }, deliveries, delivery);
|
|
86
89
|
const publishedHeads = delivery.members.map((member) => member.observed_head);
|
|
87
90
|
const review = await evaluateDeliveryReview(git, evidence, delivery, scope);
|
|
88
|
-
const exitEvaluation = await
|
|
89
|
-
? null
|
|
90
|
-
: (project.state.milestoneGates?.[milestoneId]?.exit ?? null), {
|
|
91
|
+
const exitEvaluation = await evaluateDeliveryExitCarrier(workingCarrier, {
|
|
91
92
|
kind: 'code',
|
|
92
93
|
scope,
|
|
93
94
|
match: 'covers',
|
|
94
95
|
overrideDisabled: project.exitGateDisabled,
|
|
95
|
-
}, { git, scope: evidence,
|
|
96
|
+
}, { git, scope: evidence, delivery });
|
|
96
97
|
const exit = { ...exitEvaluation, source: 'milestone-carrier' };
|
|
97
98
|
return {
|
|
98
99
|
subject,
|
|
@@ -129,13 +130,20 @@ export async function evaluateSubjectEvidence(project, subject, git) {
|
|
|
129
130
|
const publishedHead = head.code === 0 ? head.stdout.trim() : null;
|
|
130
131
|
const rows = reviewRowsFor(project.state.reviews, [milestoneId]);
|
|
131
132
|
const row = rows.at(-1) ?? null;
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
.
|
|
138
|
-
|
|
133
|
+
const milestoneDelivery = latestDeliveryForMilestone(deliveries, milestoneId);
|
|
134
|
+
const workingCarrier = project.state.milestoneGates?.[milestoneId]?.exit ?? null;
|
|
135
|
+
const evidence = milestoneDelivery === undefined
|
|
136
|
+
? {
|
|
137
|
+
repoRoot: project.repoRoot,
|
|
138
|
+
projectDir: project.projectDir,
|
|
139
|
+
evidenceArtifacts: [
|
|
140
|
+
...rows
|
|
141
|
+
.map((entry) => entry.artifact)
|
|
142
|
+
.filter((artifact) => artifact !== '' && artifact !== '-'),
|
|
143
|
+
...gateEvidenceArtifacts(project.state.reviews, workingCarrier),
|
|
144
|
+
],
|
|
145
|
+
}
|
|
146
|
+
: deliveryEvidenceScope({ ...project, evidenceCarrier: workingCarrier }, deliveries, milestoneDelivery);
|
|
139
147
|
let review;
|
|
140
148
|
if (row === null || row.artifact === '' || row.artifact === '-') {
|
|
141
149
|
review = {
|
|
@@ -156,8 +164,18 @@ export async function evaluateSubjectEvidence(project, subject, git) {
|
|
|
156
164
|
members: [],
|
|
157
165
|
};
|
|
158
166
|
}
|
|
167
|
+
const expectedCarrier = {
|
|
168
|
+
kind: 'code',
|
|
169
|
+
scope,
|
|
170
|
+
overrideDisabled: project.exitGateDisabled,
|
|
171
|
+
};
|
|
172
|
+
const exitEvaluation = await evaluateGateCarrier(workingCarrier, expectedCarrier, {
|
|
173
|
+
git,
|
|
174
|
+
scope: evidence,
|
|
175
|
+
publishedHeads: [publishedHead],
|
|
176
|
+
});
|
|
159
177
|
const exit = {
|
|
160
|
-
...
|
|
178
|
+
...exitEvaluation,
|
|
161
179
|
source: 'milestone-carrier',
|
|
162
180
|
};
|
|
163
181
|
return {
|
|
@@ -75,6 +75,20 @@ export declare function classifyPath(scope: EvidenceScope, repoPath: string): Bo
|
|
|
75
75
|
* an existing entry, or a change to the synthesis section is a rewrite.
|
|
76
76
|
*/
|
|
77
77
|
export declare function isProjectLogAppend(before: string, after: string): boolean;
|
|
78
|
+
export type JournalRewrite = {
|
|
79
|
+
kind: 'recorded-line-rewritten' | 'extraction-marker';
|
|
80
|
+
line: string;
|
|
81
|
+
} | {
|
|
82
|
+
kind: 'frontmatter-unparseable';
|
|
83
|
+
line: '';
|
|
84
|
+
side: 'before' | 'after' | 'both';
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* List every recorded journal line removed or rewritten by `after`, followed
|
|
88
|
+
* by every newly introduced extraction marker. Mutable progress fields,
|
|
89
|
+
* placeholders, table rendering, and append-only additions are excluded.
|
|
90
|
+
*/
|
|
91
|
+
export declare function journalRewrites(before: string, after: string): JournalRewrite[];
|
|
78
92
|
export interface CarrierExpectation {
|
|
79
93
|
/** The subject kind the carrier must bind. */
|
|
80
94
|
kind: 'plan' | 'code';
|
|
@@ -115,6 +129,18 @@ export declare function evaluateGateCarrier(carrier: MilestoneGateCarrier | null
|
|
|
115
129
|
scope: EvidenceScope;
|
|
116
130
|
publishedHeads: readonly (string | null)[];
|
|
117
131
|
}): Promise<CarrierEvaluation>;
|
|
132
|
+
/**
|
|
133
|
+
* Evaluate a delivery's exit carrier without letting callers bypass stack
|
|
134
|
+
* topology. A stack is recorded base to tip: every lower observed head must
|
|
135
|
+
* be the tip or its ancestor, then only the tip is published to the carrier.
|
|
136
|
+
* Missing and unreviewed carriers delegate before topology because they are
|
|
137
|
+
* not head-bound. Other delivery kinds retain every-member evaluation.
|
|
138
|
+
*/
|
|
139
|
+
export declare function evaluateDeliveryExitCarrier(carrier: MilestoneGateCarrier | null, expected: CarrierExpectation, successor: {
|
|
140
|
+
git: GitRunner;
|
|
141
|
+
scope: EvidenceScope;
|
|
142
|
+
delivery: GoalDelivery;
|
|
143
|
+
}): Promise<CarrierEvaluation>;
|
|
118
144
|
export interface ReviewEvaluation {
|
|
119
145
|
artifact: string | null;
|
|
120
146
|
/** The recorded disposition or Reviews-row status, as stored. */
|
|
@@ -148,6 +174,17 @@ export declare function evaluateDeliveryReview(git: GitRunner, scope: EvidenceSc
|
|
|
148
174
|
export declare function deliveryEvidenceArtifacts(delivery: GoalDelivery, reviewRowArtifacts?: readonly string[], sharing?: readonly GoalDelivery[]): string[];
|
|
149
175
|
/** Code review rows whose Scope cell names a label (the bare id or `<id>: …`). */
|
|
150
176
|
export declare function reviewRowsFor(reviews: readonly ReviewStatus[], labels: readonly string[]): ReviewStatus[];
|
|
177
|
+
/**
|
|
178
|
+
* Artifacts emitted by the configured gate run that produced `carrier`.
|
|
179
|
+
* These join the shared bookkeeping allowlist only; they never join a
|
|
180
|
+
* delivery's own evidence set or integrated-review selection.
|
|
181
|
+
*/
|
|
182
|
+
export declare function gateEvidenceArtifacts(reviews: readonly ReviewStatus[], carrier: MilestoneGateCarrier | null): string[];
|
|
183
|
+
/**
|
|
184
|
+
* The newest active registry entry for a milestone. Registration-in-progress
|
|
185
|
+
* and superseded entries cannot carry the milestone's current evidence.
|
|
186
|
+
*/
|
|
187
|
+
export declare function latestDeliveryForMilestone(deliveries: readonly GoalDelivery[], milestone: string): GoalDelivery | undefined;
|
|
151
188
|
/** The project facts the evidence scope of a delivery is built from. */
|
|
152
189
|
export interface DeliveryEvidenceProject {
|
|
153
190
|
repoRoot: string;
|
|
@@ -155,6 +192,8 @@ export interface DeliveryEvidenceProject {
|
|
|
155
192
|
state: {
|
|
156
193
|
reviews: readonly ReviewStatus[];
|
|
157
194
|
};
|
|
195
|
+
/** Carrier whose own gate artifact may join shared bookkeeping evidence. */
|
|
196
|
+
evidenceCarrier?: MilestoneGateCarrier | null;
|
|
158
197
|
}
|
|
159
198
|
/**
|
|
160
199
|
* The one evidence scope for a registered delivery, shared by `delivery
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/delivery/evidence.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EAClB,MAAM,mCAAmC,CAAC;AAG3C;;;;;;;;;;;;GAYG;AAEH,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;CAC/D;AAED,MAAM,MAAM,oBAAoB,GAC5B,kBAAkB,GAClB,gBAAgB,GAChB,cAAc,GACd,mBAAmB,GACnB,iBAAiB,GACjB,oBAAoB,GACpB,cAAc,CAAC;AAEnB,MAAM,MAAM,eAAe,GACvB;IACE,KAAK,EAAE,IAAI,CAAC;IACZ,IAAI,EAAE,WAAW,GAAG,uBAAuB,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,GACD;IACE,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAwCN;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACnC,OAAO,CAAC,eAAe,CAAC,CAqG1B;AAoFD,MAAM,MAAM,mBAAmB,GAC3B,OAAO,GACP,MAAM,GACN,gBAAgB,GAChB,aAAa,GACb,SAAS,GACT,iBAAiB,CAAC;AAmBtB;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,MAAM,GACf,mBAAmB,GAAG,IAAI,CAsB5B;AA6CD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAmBzE;
|
|
1
|
+
{"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/delivery/evidence.ts"],"names":[],"mappings":"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"}
|
|
@@ -596,6 +596,12 @@ function readReviewRows(lines) {
|
|
|
596
596
|
function placeholder(cell) {
|
|
597
597
|
return cell === '' || cell === '-' || cell === '—';
|
|
598
598
|
}
|
|
599
|
+
function reviewArtifactPath(cell) {
|
|
600
|
+
const artifact = cell.replace(/^\.\//, '');
|
|
601
|
+
return (!posix.isAbsolute(artifact) &&
|
|
602
|
+
posix.normalize(artifact) === artifact &&
|
|
603
|
+
artifact.startsWith('reviews/'));
|
|
604
|
+
}
|
|
599
605
|
/**
|
|
600
606
|
* Review rows record evidence: rows may be added and their status, date and
|
|
601
607
|
* lineage cells updated, but no row disappears and an existing row's
|
|
@@ -622,24 +628,15 @@ function judgeReviewRows(beforeLines, afterLines) {
|
|
|
622
628
|
const PROGRESS_FIELD = /^(?:-[ \t]+)?\*\*(Status|Head|Completed|Updated|Last Updated|Started|Total):\*\*\s*(.*)$/;
|
|
623
629
|
const PLACEHOLDER_FIELD = /^(?:-[ \t]+)?\*\*[^*\n]+:\*\*\s*(?:-|—|pending|tbd|null)?\s*$/i;
|
|
624
630
|
const EXTRACTION_MARKER = /^\*\*(?:Status:\*\*\s+extracted|Extracted to:\*\*)/;
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
* rewritten and tables re-rendered, but no recorded observation is removed
|
|
628
|
-
* or rewritten, and marking a phase extracted changes scope.
|
|
629
|
-
*/
|
|
630
|
-
function judgeJournalChange(before, after) {
|
|
631
|
-
const previous = splitFrontmatter(before);
|
|
632
|
-
const next = splitFrontmatter(after);
|
|
633
|
-
if (previous === null || next === null) {
|
|
634
|
-
return refuse('implementation.md frontmatter could not be parsed');
|
|
635
|
-
}
|
|
631
|
+
function listJournalRewrites(previousBody, nextBody) {
|
|
632
|
+
const rewrites = [];
|
|
636
633
|
const remaining = new Map();
|
|
637
|
-
for (const line of
|
|
634
|
+
for (const line of nextBody.split('\n')) {
|
|
638
635
|
const key = line.trimEnd();
|
|
639
636
|
remaining.set(key, (remaining.get(key) ?? 0) + 1);
|
|
640
637
|
}
|
|
641
638
|
const previousLines = new Set();
|
|
642
|
-
for (const line of
|
|
639
|
+
for (const line of previousBody.split('\n')) {
|
|
643
640
|
const key = line.trimEnd();
|
|
644
641
|
previousLines.add(key.trim());
|
|
645
642
|
const count = remaining.get(key) ?? 0;
|
|
@@ -655,15 +652,58 @@ function judgeJournalChange(before, after) {
|
|
|
655
652
|
(progress !== null &&
|
|
656
653
|
!(progress[1] === 'Status' && /^extracted\b/.test(progress[2] ?? '')));
|
|
657
654
|
if (!mutable) {
|
|
658
|
-
|
|
655
|
+
rewrites.push({ kind: 'recorded-line-rewritten', line: trimmed });
|
|
659
656
|
}
|
|
660
657
|
}
|
|
661
|
-
for (const line of
|
|
658
|
+
for (const line of nextBody.split('\n')) {
|
|
662
659
|
const trimmed = line.trim();
|
|
663
660
|
if (EXTRACTION_MARKER.test(trimmed) && !previousLines.has(trimmed)) {
|
|
664
|
-
|
|
661
|
+
rewrites.push({ kind: 'extraction-marker', line: trimmed });
|
|
665
662
|
}
|
|
666
663
|
}
|
|
664
|
+
return rewrites;
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* List every recorded journal line removed or rewritten by `after`, followed
|
|
668
|
+
* by every newly introduced extraction marker. Mutable progress fields,
|
|
669
|
+
* placeholders, table rendering, and append-only additions are excluded.
|
|
670
|
+
*/
|
|
671
|
+
export function journalRewrites(before, after) {
|
|
672
|
+
const previous = splitFrontmatter(before);
|
|
673
|
+
const next = splitFrontmatter(after);
|
|
674
|
+
if (previous === null || next === null) {
|
|
675
|
+
return [
|
|
676
|
+
{
|
|
677
|
+
kind: 'frontmatter-unparseable',
|
|
678
|
+
line: '',
|
|
679
|
+
side: previous === null && next === null
|
|
680
|
+
? 'both'
|
|
681
|
+
: previous === null
|
|
682
|
+
? 'before'
|
|
683
|
+
: 'after',
|
|
684
|
+
},
|
|
685
|
+
];
|
|
686
|
+
}
|
|
687
|
+
return listJournalRewrites(previous.body, next.body);
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* The journal is append-mostly: progress fields and placeholders may be
|
|
691
|
+
* rewritten and tables re-rendered, but no recorded observation is removed
|
|
692
|
+
* or rewritten, and marking a phase extracted changes scope.
|
|
693
|
+
*/
|
|
694
|
+
function judgeJournalChange(before, after) {
|
|
695
|
+
const previous = splitFrontmatter(before);
|
|
696
|
+
const next = splitFrontmatter(after);
|
|
697
|
+
if (previous === null || next === null) {
|
|
698
|
+
return refuse('implementation.md frontmatter could not be parsed');
|
|
699
|
+
}
|
|
700
|
+
const [first] = listJournalRewrites(previous.body, next.body);
|
|
701
|
+
if (first?.kind === 'recorded-line-rewritten') {
|
|
702
|
+
return refuse(`recorded journal line "${first.line}" was removed or rewritten`);
|
|
703
|
+
}
|
|
704
|
+
if (first?.kind === 'extraction-marker') {
|
|
705
|
+
return refuse(`"${first.line}" marks a phase extracted`);
|
|
706
|
+
}
|
|
667
707
|
return OK;
|
|
668
708
|
}
|
|
669
709
|
const UNREVIEWED_RESOLUTIONS = new Set(['no_gate', 'project_disabled']);
|
|
@@ -750,6 +790,76 @@ export async function evaluateGateCarrier(carrier, expected, successor) {
|
|
|
750
790
|
}
|
|
751
791
|
return { outcome, freshness: 'fresh', reason: null };
|
|
752
792
|
}
|
|
793
|
+
/**
|
|
794
|
+
* Evaluate a delivery's exit carrier without letting callers bypass stack
|
|
795
|
+
* topology. A stack is recorded base to tip: every lower observed head must
|
|
796
|
+
* be the tip or its ancestor, then only the tip is published to the carrier.
|
|
797
|
+
* Missing and unreviewed carriers delegate before topology because they are
|
|
798
|
+
* not head-bound. Other delivery kinds retain every-member evaluation.
|
|
799
|
+
*/
|
|
800
|
+
export async function evaluateDeliveryExitCarrier(carrier, expected, successor) {
|
|
801
|
+
const { delivery, git, scope } = successor;
|
|
802
|
+
const publishedHeads = delivery.members.map((member) => member.observed_head);
|
|
803
|
+
if (carrier === null || isUnreviewedResolution(carrier)) {
|
|
804
|
+
return evaluateGateCarrier(carrier, expected, {
|
|
805
|
+
git,
|
|
806
|
+
scope,
|
|
807
|
+
publishedHeads,
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
if (delivery.kind !== 'stack') {
|
|
811
|
+
return evaluateGateCarrier(carrier, expected, {
|
|
812
|
+
git,
|
|
813
|
+
scope,
|
|
814
|
+
publishedHeads,
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
const stale = (reason) => ({
|
|
818
|
+
outcome: carrier.status === 'allowed' ? 'allowed' : 'blocked',
|
|
819
|
+
freshness: 'stale',
|
|
820
|
+
reason,
|
|
821
|
+
});
|
|
822
|
+
if (publishedHeads.length === 0) {
|
|
823
|
+
return stale('member-missing: the stack has no members');
|
|
824
|
+
}
|
|
825
|
+
const unobserved = publishedHeads.findIndex((head) => head === null);
|
|
826
|
+
if (unobserved >= 0) {
|
|
827
|
+
return stale(`member-unobserved: stack member ${unobserved} has no observed head`);
|
|
828
|
+
}
|
|
829
|
+
const resolvedHeads = [];
|
|
830
|
+
try {
|
|
831
|
+
for (const head of publishedHeads) {
|
|
832
|
+
const resolved = await resolveCommit(git, scope.repoRoot, head);
|
|
833
|
+
if (resolved === null) {
|
|
834
|
+
return stale(`missing-object: commit ${head} is not available locally`);
|
|
835
|
+
}
|
|
836
|
+
resolvedHeads.push(resolved);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
catch (error) {
|
|
840
|
+
return stale(`inspection-failed: commit resolution failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
841
|
+
}
|
|
842
|
+
const tip = resolvedHeads.at(-1);
|
|
843
|
+
try {
|
|
844
|
+
for (const [index, lower] of resolvedHeads.slice(0, -1).entries()) {
|
|
845
|
+
const ancestry = await git.run(['merge-base', '--is-ancestor', lower, tip], { cwd: scope.repoRoot, allowFailure: true });
|
|
846
|
+
if (ancestry.code === 1) {
|
|
847
|
+
return stale(`stack-order: member ${index} head ${lower} is not an ancestor of tip ${tip}`);
|
|
848
|
+
}
|
|
849
|
+
if (ancestry.code !== 0) {
|
|
850
|
+
return stale(`inspection-failed: ancestry inspection failed for member ${index}: ${ancestry.stderr || `git exited ${ancestry.code}`}`);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
catch (error) {
|
|
855
|
+
return stale(`inspection-failed: ancestry inspection failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
856
|
+
}
|
|
857
|
+
return evaluateGateCarrier(carrier, expected, {
|
|
858
|
+
git,
|
|
859
|
+
scope,
|
|
860
|
+
publishedHeads: [tip],
|
|
861
|
+
});
|
|
862
|
+
}
|
|
753
863
|
/**
|
|
754
864
|
* Evaluate a registered delivery's integrated review against its observed
|
|
755
865
|
* members (A2): each member's reviewed revision must cover its observed head
|
|
@@ -856,6 +966,39 @@ export function reviewRowsFor(reviews, labels) {
|
|
|
856
966
|
ids.some((id) => cell === id || cell.startsWith(`${id}:`)));
|
|
857
967
|
});
|
|
858
968
|
}
|
|
969
|
+
/**
|
|
970
|
+
* Artifacts emitted by the configured gate run that produced `carrier`.
|
|
971
|
+
* These join the shared bookkeeping allowlist only; they never join a
|
|
972
|
+
* delivery's own evidence set or integrated-review selection.
|
|
973
|
+
*/
|
|
974
|
+
export function gateEvidenceArtifacts(reviews, carrier) {
|
|
975
|
+
if (carrier?.reviewed_head === null ||
|
|
976
|
+
carrier?.reviewed_head === undefined ||
|
|
977
|
+
placeholder(carrier.reviewed_head)) {
|
|
978
|
+
return [];
|
|
979
|
+
}
|
|
980
|
+
return reviews
|
|
981
|
+
.filter((review) => review.type === 'code' &&
|
|
982
|
+
review.invocation === 'gate' &&
|
|
983
|
+
review.reviewedHead === carrier.reviewed_head &&
|
|
984
|
+
reviewArtifactPath(review.artifact) &&
|
|
985
|
+
!placeholder(review.artifact))
|
|
986
|
+
.map((review) => review.artifact);
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* The newest active registry entry for a milestone. Registration-in-progress
|
|
990
|
+
* and superseded entries cannot carry the milestone's current evidence.
|
|
991
|
+
*/
|
|
992
|
+
export function latestDeliveryForMilestone(deliveries, milestone) {
|
|
993
|
+
for (let index = deliveries.length - 1; index >= 0; index -= 1) {
|
|
994
|
+
const delivery = deliveries[index];
|
|
995
|
+
if (delivery.milestone === milestone &&
|
|
996
|
+
(delivery.status === 'open' || delivery.status === 'at_endpoint')) {
|
|
997
|
+
return delivery;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
return undefined;
|
|
1001
|
+
}
|
|
859
1002
|
/**
|
|
860
1003
|
* The one evidence scope for a registered delivery, shared by `delivery
|
|
861
1004
|
* check`, `delivery refresh` and the closeout boundary: the review rows
|
|
@@ -883,7 +1026,10 @@ export function deliveryEvidenceScope(project, deliveries, delivery) {
|
|
|
883
1026
|
return {
|
|
884
1027
|
repoRoot: project.repoRoot,
|
|
885
1028
|
projectDir: project.projectDir,
|
|
886
|
-
evidenceArtifacts:
|
|
1029
|
+
evidenceArtifacts: [
|
|
1030
|
+
...deliveryEvidenceArtifacts(delivery, reviewRowsFor(project.state.reviews, labels).map((row) => row.artifact), sharing),
|
|
1031
|
+
...gateEvidenceArtifacts(project.state.reviews, project.evidenceCarrier ?? null),
|
|
1032
|
+
],
|
|
887
1033
|
ownEvidenceArtifacts,
|
|
888
1034
|
};
|
|
889
1035
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/delivery/refresh.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,QAAQ,EACd,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAK9E,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EAClB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAIL,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACzB,MAAM,SAAS,CAAC;AACjB,OAAO,
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/delivery/refresh.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ import { normalizeMilestoneId, } from '@open-agent-toolkit/control-plane';
|
|
|
10
10
|
import { Command } from 'commander';
|
|
11
11
|
import YAML, { isMap, isScalar, isSeq } from 'yaml';
|
|
12
12
|
import { DEFAULT_DELIVERY_PROJECT_DEPENDENCIES, deliveryEffectiveScope, loadGoalDeliveryProject, } from './check.js';
|
|
13
|
-
import { deliveryEvidenceScope, evaluateDeliveryReview,
|
|
13
|
+
import { deliveryEvidenceScope, evaluateDeliveryExitCarrier, evaluateDeliveryReview, latestDeliveryForMilestone, } from './evidence.js';
|
|
14
14
|
/** The only frontmatter keys a refresh writes under. */
|
|
15
15
|
const REFRESH_WRITE_ROOTS = new Set(['oat_deliveries', 'oat_milestone_gates']);
|
|
16
16
|
const MEMBER_OBSERVATION_LEAVES = new Set([
|
|
@@ -235,28 +235,22 @@ export async function planDeliveryRefresh(project, runners) {
|
|
|
235
235
|
// registered delivery. Refresh records only staleness: it never upgrades a
|
|
236
236
|
// carrier to fresh, which only implement's scoped closeout writes.
|
|
237
237
|
const exitCarriers = [];
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
for (const [milestone, delivery] of latestByMilestone) {
|
|
238
|
+
const observedDeliveries = [...observedById.values()];
|
|
239
|
+
const milestones = new Set(observedDeliveries
|
|
240
|
+
.map((delivery) => delivery.milestone)
|
|
241
|
+
.filter((milestone) => milestone !== null));
|
|
242
|
+
for (const milestone of milestones) {
|
|
243
|
+
const delivery = latestDeliveryForMilestone(observedDeliveries, milestone);
|
|
246
244
|
const carrier = project.state.milestoneGates?.[milestone]?.exit ?? null;
|
|
247
245
|
if (carrier === null)
|
|
248
246
|
continue;
|
|
249
247
|
const scope = evidenceScope(project, delivery);
|
|
250
|
-
const evaluation = await
|
|
248
|
+
const evaluation = await evaluateDeliveryExitCarrier(carrier, {
|
|
251
249
|
kind: 'code',
|
|
252
250
|
scope: deliveryEffectiveScope(deliveries, delivery),
|
|
253
251
|
match: 'covers',
|
|
254
252
|
overrideDisabled: project.exitGateDisabled,
|
|
255
|
-
}, {
|
|
256
|
-
git: runners.git,
|
|
257
|
-
scope,
|
|
258
|
-
publishedHeads: delivery.members.map((member) => member.observed_head),
|
|
259
|
-
});
|
|
253
|
+
}, { git: runners.git, scope, delivery });
|
|
260
254
|
exitCarriers.push({
|
|
261
255
|
milestone,
|
|
262
256
|
delivery: delivery.delivery_id,
|
|
@@ -282,7 +276,10 @@ export async function planDeliveryRefresh(project, runners) {
|
|
|
282
276
|
return { deliveries: results, exitCarriers, writes, changed: false };
|
|
283
277
|
}
|
|
284
278
|
function evidenceScope(project, delivery) {
|
|
285
|
-
|
|
279
|
+
const evidenceCarrier = delivery.milestone === null
|
|
280
|
+
? null
|
|
281
|
+
: (project.state.milestoneGates?.[delivery.milestone]?.exit ?? null);
|
|
282
|
+
return deliveryEvidenceScope({ ...project, evidenceCarrier }, project.state.deliveries ?? [], delivery);
|
|
286
283
|
}
|
|
287
284
|
// ---------------------------------------------------------------------------
|
|
288
285
|
// Applying writes to state.md frontmatter
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type CommandContext, type GlobalOptions } from '../../../app/command-context.js';
|
|
2
|
+
import { type GitRunner } from '../../project/sync/git.js';
|
|
2
3
|
import { type ActiveProjectResolution } from '../../../config/oat-config.js';
|
|
3
4
|
import { Command } from 'commander';
|
|
4
5
|
import { type JournalCheckReason, type JournalCheckResult } from './types.js';
|
|
@@ -16,6 +17,7 @@ export interface JournalCheckDependencies {
|
|
|
16
17
|
readFile: (path: string, encoding: 'utf8') => Promise<string>;
|
|
17
18
|
dirExists: (path: string) => Promise<boolean>;
|
|
18
19
|
fileExists: (path: string) => Promise<boolean>;
|
|
20
|
+
git: GitRunner;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Read the three inputs the evaluator needs. A missing journal or plan is a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/journal-check/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAS5B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACxB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9D,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/journal-check/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE9E,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAS5B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACxB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9D,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,GAAG,EAAE,SAAS,CAAC;CAChB;AAYD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,IAAI,CAAC,wBAAwB,EAAE,UAAU,GAAG,YAAY,CAAC,GACtE,OAAO,CAAC,iBAAiB,CAAC,CAa5B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GAAG,YAAY,GAClC,MAAM,EAAE,CAuBV;AA0ED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAItE;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,GACzB,MAAM,CAKR;AA0JD,wBAAgB,2BAA2B,CACzC,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAChD,OAAO,CAiCT"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { readFile as defaultReadFile } from 'node:fs/promises';
|
|
2
2
|
import { isAbsolute, join, resolve } from 'node:path';
|
|
3
3
|
import { buildCommandContext, } from '../../../app/command-context.js';
|
|
4
|
+
import { journalRewrites } from '../../project/delivery/evidence.js';
|
|
5
|
+
import { defaultGitRunner } from '../../project/sync/git.js';
|
|
4
6
|
import { readGlobalOptions } from '../../shared/shared.utils.js';
|
|
5
7
|
import { resolveActiveProject, } from '../../../config/oat-config.js';
|
|
6
8
|
import { CliError } from '../../../errors/cli-error.js';
|
|
@@ -18,6 +20,7 @@ const DEFAULT_DEPENDENCIES = {
|
|
|
18
20
|
readFile: (path, encoding) => defaultReadFile(path, encoding),
|
|
19
21
|
dirExists,
|
|
20
22
|
fileExists,
|
|
23
|
+
git: defaultGitRunner,
|
|
21
24
|
};
|
|
22
25
|
/**
|
|
23
26
|
* Read the three inputs the evaluator needs. A missing journal or plan is a
|
|
@@ -69,6 +72,41 @@ function readWorkflowMode(stateContent) {
|
|
|
69
72
|
const mode = metadata.state === 'ok' ? metadata.record.oat_workflow_mode : undefined;
|
|
70
73
|
return typeof mode === 'string' && mode.length > 0 ? mode : 'spec-driven';
|
|
71
74
|
}
|
|
75
|
+
async function readCommittedJournal(projectDir, git) {
|
|
76
|
+
const head = await git.run(['rev-parse', '--verify', '--quiet', 'HEAD^{commit}'], { cwd: projectDir, allowFailure: true });
|
|
77
|
+
if (head.code === 1) {
|
|
78
|
+
const symbolic = await git.run(['symbolic-ref', '-q', 'HEAD'], {
|
|
79
|
+
cwd: projectDir,
|
|
80
|
+
allowFailure: true,
|
|
81
|
+
});
|
|
82
|
+
if (symbolic.code !== 0 || symbolic.stdout === '') {
|
|
83
|
+
throw new CliError(`Unable to inspect the committed journal: HEAD does not resolve and its branch could not be identified${symbolic.stderr ? `: ${symbolic.stderr}` : ''}`, 2);
|
|
84
|
+
}
|
|
85
|
+
const branch = await git.run(['show-ref', '--verify', '--quiet', symbolic.stdout], { cwd: projectDir, allowFailure: true });
|
|
86
|
+
if (branch.code === 1) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
throw new CliError(`Unable to inspect the committed journal: HEAD does not resolve${branch.stderr ? `: ${branch.stderr}` : ''}`, 2);
|
|
90
|
+
}
|
|
91
|
+
if (head.code !== 0) {
|
|
92
|
+
throw new CliError(`Unable to inspect the committed journal: ${head.stderr || `git exited ${head.code}`}`, 2);
|
|
93
|
+
}
|
|
94
|
+
const entry = await git.run(['ls-tree', '--full-name', '-z', 'HEAD', '--', 'implementation.md'], { cwd: projectDir, allowFailure: true });
|
|
95
|
+
if (entry.code !== 0) {
|
|
96
|
+
throw new CliError(`Unable to inspect the committed journal path: ${entry.stderr || `git exited ${entry.code}`}`, 2);
|
|
97
|
+
}
|
|
98
|
+
if (entry.stdout === '') {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
const blob = await git.run(['show', 'HEAD:./implementation.md'], {
|
|
102
|
+
cwd: projectDir,
|
|
103
|
+
allowFailure: true,
|
|
104
|
+
});
|
|
105
|
+
if (blob.code !== 0) {
|
|
106
|
+
throw new CliError(`Unable to read the committed journal: ${blob.stderr || `git exited ${blob.code}`}`, 2);
|
|
107
|
+
}
|
|
108
|
+
return blob.stdout;
|
|
109
|
+
}
|
|
72
110
|
export function formatJournalReason(reason) {
|
|
73
111
|
const location = reason.line === null ? reason.path : `${reason.path}:${reason.line}`;
|
|
74
112
|
return `${reason.code} ${location} (${reason.owner}): ${reason.message}`;
|
|
@@ -118,7 +156,46 @@ async function runJournalCheck(options, context, dependencies) {
|
|
|
118
156
|
? 'phase-unit'
|
|
119
157
|
: 'task')
|
|
120
158
|
: null;
|
|
121
|
-
|
|
159
|
+
let result = evaluateJournal({ boundary, scope, ...files });
|
|
160
|
+
if (workflowMode === 'goal' &&
|
|
161
|
+
(boundary === 'implement-preflight' || boundary === 'review')) {
|
|
162
|
+
const committed = await readCommittedJournal(projectDir, dependencies.git);
|
|
163
|
+
if (committed !== null) {
|
|
164
|
+
const reasons = journalRewrites(committed, files.journalContent).flatMap((rewrite) => {
|
|
165
|
+
if (rewrite.kind === 'recorded-line-rewritten') {
|
|
166
|
+
return [
|
|
167
|
+
{
|
|
168
|
+
code: 'journal-line-rewritten',
|
|
169
|
+
path: 'implementation.md',
|
|
170
|
+
line: null,
|
|
171
|
+
owner: 'oat-project-implement',
|
|
172
|
+
message: `Committed journal line "${rewrite.line}" was removed or rewritten; the journal is append-only — restore the committed line and append the correction.`,
|
|
173
|
+
},
|
|
174
|
+
];
|
|
175
|
+
}
|
|
176
|
+
if (rewrite.kind === 'frontmatter-unparseable' &&
|
|
177
|
+
rewrite.side !== 'after') {
|
|
178
|
+
return [
|
|
179
|
+
{
|
|
180
|
+
code: 'journal-frontmatter-malformed',
|
|
181
|
+
path: 'implementation.md',
|
|
182
|
+
line: null,
|
|
183
|
+
owner: 'oat-project-reconcile',
|
|
184
|
+
message: 'Committed implementation.md frontmatter could not be parsed; repair the frontmatter and commit it before re-running.',
|
|
185
|
+
},
|
|
186
|
+
];
|
|
187
|
+
}
|
|
188
|
+
return [];
|
|
189
|
+
});
|
|
190
|
+
if (reasons.length > 0) {
|
|
191
|
+
result = {
|
|
192
|
+
...result,
|
|
193
|
+
status: 'refused',
|
|
194
|
+
reasons: [...result.reasons, ...reasons],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
122
199
|
if (context.json) {
|
|
123
200
|
context.logger.json({ ...result, projectPath: projectDir });
|
|
124
201
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
export declare const JOURNAL_CHECK_BOUNDARIES: readonly ['implement-preflight', 'review', 'completion'];
|
|
12
12
|
export type JournalCheckBoundary = (typeof JOURNAL_CHECK_BOUNDARIES)[number];
|
|
13
13
|
export type JournalArtifactPath = 'implementation.md' | 'plan.md' | 'state.md';
|
|
14
|
-
export type JournalReasonCode = 'journal-frontmatter-malformed' | 'journal-frontmatter-missing' | 'journal-missing' | 'state-frontmatter-malformed' | 'journal-status-not-terminal' | 'journal-pointer-not-cleared' | 'state-status-disagrees' | 'state-pointer-not-cleared' | 'task-block-missing' | 'task-duplicate-block' | 'task-unplanned' | 'task-status-missing' | 'task-status-ambiguous' | 'task-status-invalid' | 'task-not-completed' | 'task-commit-missing' | 'task-misplaced' | 'plan-task-duplicate' | 'plan-task-misplaced' | 'execution-record-open' | 'phase-status-disagrees' | 'phase-status-ambiguous' | 'phase-duplicate-section' | 'phase-head-missing' | 'phase-not-accepted' | 'overview-total-mismatch' | 'references-not-last' | 'receipt-misplaced' | 'deferral-misplaced' | 'dispatch-payload' | 'run-line-malformed' | 'run-line-misplaced' | 'run-line-duplicate' | 'run-line-unresolved' | 'template-residue' | 'override-malformed' | 'override-misplaced' | 'override-unused';
|
|
14
|
+
export type JournalReasonCode = 'journal-frontmatter-malformed' | 'journal-frontmatter-missing' | 'journal-missing' | 'journal-line-rewritten' | 'state-frontmatter-malformed' | 'journal-status-not-terminal' | 'journal-pointer-not-cleared' | 'state-status-disagrees' | 'state-pointer-not-cleared' | 'task-block-missing' | 'task-duplicate-block' | 'task-unplanned' | 'task-status-missing' | 'task-status-ambiguous' | 'task-status-invalid' | 'task-not-completed' | 'task-commit-missing' | 'task-misplaced' | 'plan-task-duplicate' | 'plan-task-misplaced' | 'execution-record-open' | 'phase-status-disagrees' | 'phase-status-ambiguous' | 'phase-duplicate-section' | 'phase-head-missing' | 'phase-not-accepted' | 'overview-total-mismatch' | 'references-not-last' | 'receipt-misplaced' | 'deferral-misplaced' | 'dispatch-payload' | 'run-line-malformed' | 'run-line-misplaced' | 'run-line-duplicate' | 'run-line-unresolved' | 'template-residue' | 'override-malformed' | 'override-misplaced' | 'override-unused';
|
|
15
15
|
export interface JournalCheckReason {
|
|
16
16
|
code: JournalReasonCode;
|
|
17
17
|
path: JournalArtifactPath;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/journal-check/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,wBAAwB,YACnC,qBAAqB,EACrB,QAAQ,EACR,YAAY,CACJ,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7E,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/E,MAAM,MAAM,iBAAiB,GAEzB,+BAA+B,GAC/B,6BAA6B,GAC7B,iBAAiB,GACjB,6BAA6B,GAC7B,6BAA6B,GAC7B,6BAA6B,GAC7B,wBAAwB,GACxB,2BAA2B,GAE3B,oBAAoB,GACpB,sBAAsB,GACtB,gBAAgB,GAChB,qBAAqB,GACrB,uBAAuB,GACvB,qBAAqB,GACrB,oBAAoB,GACpB,qBAAqB,GACrB,gBAAgB,GAChB,qBAAqB,GACrB,qBAAqB,GACrB,uBAAuB,GAEvB,wBAAwB,GACxB,wBAAwB,GACxB,yBAAyB,GACzB,oBAAoB,GACpB,oBAAoB,GACpB,yBAAyB,GAEzB,qBAAqB,GACrB,mBAAmB,GACnB,oBAAoB,GACpB,kBAAkB,GAClB,oBAAoB,GACpB,oBAAoB,GACpB,oBAAoB,GACpB,qBAAqB,GACrB,kBAAkB,GAElB,oBAAoB,GACpB,oBAAoB,GACpB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,YACjC,4BAA4B,EAC5B,eAAe,EACf,uBAAuB,CACf,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,IAAI,GAAG,SAAS,CAAC;IACzB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/journal-check/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,wBAAwB,YACnC,qBAAqB,EACrB,QAAQ,EACR,YAAY,CACJ,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7E,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/E,MAAM,MAAM,iBAAiB,GAEzB,+BAA+B,GAC/B,6BAA6B,GAC7B,iBAAiB,GACjB,wBAAwB,GACxB,6BAA6B,GAC7B,6BAA6B,GAC7B,6BAA6B,GAC7B,wBAAwB,GACxB,2BAA2B,GAE3B,oBAAoB,GACpB,sBAAsB,GACtB,gBAAgB,GAChB,qBAAqB,GACrB,uBAAuB,GACvB,qBAAqB,GACrB,oBAAoB,GACpB,qBAAqB,GACrB,gBAAgB,GAChB,qBAAqB,GACrB,qBAAqB,GACrB,uBAAuB,GAEvB,wBAAwB,GACxB,wBAAwB,GACxB,yBAAyB,GACzB,oBAAoB,GACpB,oBAAoB,GACpB,yBAAyB,GAEzB,qBAAqB,GACrB,mBAAmB,GACnB,oBAAoB,GACpB,kBAAkB,GAClB,oBAAoB,GACpB,oBAAoB,GACpB,oBAAoB,GACpB,qBAAqB,GACrB,kBAAkB,GAElB,oBAAoB,GACpB,oBAAoB,GACpB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,YACjC,4BAA4B,EAC5B,eAAe,EACf,uBAAuB,CACf,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,IAAI,GAAG,SAAS,CAAC;IACzB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B"}
|
|
@@ -22,7 +22,11 @@ export interface CodexConfigMergeResult {
|
|
|
22
22
|
}
|
|
23
23
|
/** Reads a valid numeric agents.max_depth value from Codex TOML content. */
|
|
24
24
|
export declare function readCodexMaxDepth(content: string | null): number | null;
|
|
25
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Merges managed Codex roles and required shared agent configuration in place:
|
|
27
|
+
* other tools keep ownership markers in this file's comments, so unmanaged
|
|
28
|
+
* content must survive byte for byte.
|
|
29
|
+
*/
|
|
26
30
|
export declare function mergeCodexConfig({ existingContent, desiredRoles, staleManagedRoles, inheritedMaxDepth, }: CodexConfigMergeArgs): CodexConfigMergeResult;
|
|
27
31
|
/** Merges one managed Codex role using the shared configuration contract. */
|
|
28
32
|
export declare function mergeCodexConfigForRole({ existingContent, role, staleManagedRoles, inheritedMaxDepth, }: CodexSingleRoleConfigMergeArgs): CodexConfigMergeResult;
|