ai-foreman 1.7.29 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/adapters/claude.d.ts +23 -12
- package/dist/adapters/claude.js +227 -23
- package/dist/adapters/codex.d.ts +17 -7
- package/dist/adapters/codex.js +195 -17
- package/dist/adapters/recovering.d.ts +2 -0
- package/dist/adapters/recovering.js +5 -1
- package/dist/adapters/structured.d.ts +71 -0
- package/dist/adapters/structured.js +213 -0
- package/dist/adapters/types.d.ts +85 -9
- package/dist/agentRun.d.ts +2 -0
- package/dist/agentRun.js +2 -1
- package/dist/boundedTurnEvidence.d.ts +18 -0
- package/dist/boundedTurnEvidence.js +76 -0
- package/dist/branch/currentGuard.d.ts +2 -0
- package/dist/branch/currentGuard.js +2 -0
- package/dist/branch/planner.js +1 -4
- package/dist/branch/runner.d.ts +2 -1
- package/dist/branch/runner.js +10 -7
- package/dist/buildAdmission.js +4 -0
- package/dist/buildApproval.d.ts +15 -0
- package/dist/buildApproval.js +25 -0
- package/dist/buildAssignment.d.ts +1 -0
- package/dist/buildAssignment.js +82 -23
- package/dist/buildInterventions.d.ts +2 -2
- package/dist/buildInterventions.js +11 -4
- package/dist/buildLaunchGate.js +3 -2
- package/dist/builderGuidanceFollowup.js +17 -6
- package/dist/cli/manager.js +22 -20
- package/dist/cli/start.js +22 -26
- package/dist/cli/tickets.d.ts +0 -7
- package/dist/cli/tickets.js +41 -40
- package/dist/continuity.d.ts +10 -14
- package/dist/continuity.js +198 -179
- package/dist/continuityOrigin.d.ts +13 -0
- package/dist/continuityOrigin.js +91 -0
- package/dist/foreman.d.ts +10 -4
- package/dist/foreman.js +51 -193
- package/dist/graph/boundary.d.ts +1 -1
- package/dist/graph/boundary.js +1 -1
- package/dist/graph/host.js +8 -19
- package/dist/graph/manager.d.ts +1 -1
- package/dist/graph/manager.js +1 -1
- package/dist/graph/preparation.d.ts +38 -0
- package/dist/graph/preparation.js +7 -6
- package/dist/graph/semantic.d.ts +1 -0
- package/dist/graph/semantic.js +4 -1
- package/dist/graph/session.js +7 -2
- package/dist/graph/turn.d.ts +2 -3
- package/dist/graph/turn.js +28 -40
- package/dist/handoffProtocol.js +2 -2
- package/dist/handoffs.d.ts +3 -1
- package/dist/handoffs.js +90 -59
- package/dist/hostGraphApplicability.d.ts +2 -1
- package/dist/hostGraphApplicability.js +17 -19
- package/dist/hostQaAugmentation.js +21 -4
- package/dist/hostQaComparison.d.ts +21 -2
- package/dist/hostQaComparison.js +43 -29
- package/dist/hostSourcePreservation.d.ts +38 -0
- package/dist/hostSourcePreservation.js +72 -0
- package/dist/interviews.d.ts +7 -0
- package/dist/interviews.js +18 -1
- package/dist/legacyCommunicationDisplay.d.ts +2 -0
- package/dist/legacyCommunicationDisplay.js +2 -0
- package/dist/managerPacket.js +3 -3
- package/dist/markers.d.ts +4 -3
- package/dist/markers.js +4 -20
- package/dist/probeIpc.d.ts +14 -0
- package/dist/probeIpc.js +29 -0
- package/dist/qaBuildGate.d.ts +21 -0
- package/dist/qaBuildGate.js +47 -12
- package/dist/qaBuilderCoverage.js +22 -13
- package/dist/qaBuilderEvidence.d.ts +16 -1
- package/dist/qaBuilderEvidence.js +48 -8
- package/dist/qaContractCoverage.d.ts +2 -2
- package/dist/qaContractCoverage.js +4 -9
- package/dist/qaContractDelivery.js +34 -20
- package/dist/qaCoverageAssembly.d.ts +22 -0
- package/dist/qaCoverageAssembly.js +16 -0
- package/dist/qaDeliveryJournal.d.ts +2 -0
- package/dist/qaDeliveryJournal.js +19 -0
- package/dist/qaFailureDelivery.js +97 -85
- package/dist/qaHostTransformation.d.ts +26 -0
- package/dist/qaHostTransformation.js +100 -0
- package/dist/qaPreparation.d.ts +8 -20
- package/dist/qaPreparation.js +133 -248
- package/dist/qaPreparationInputs.js +19 -0
- package/dist/qaPrerequisites.d.ts +2 -1
- package/dist/qaPrerequisites.js +21 -1
- package/dist/qaProtocolV2.d.ts +15 -0
- package/dist/qaRecovery.js +21 -4
- package/dist/qaReview.js +220 -395
- package/dist/qaReviewEvidence.d.ts +7 -3
- package/dist/qaReviewEvidence.js +15 -4
- package/dist/qaRuntime.js +1 -1
- package/dist/qaSnapshot.js +71 -21
- package/dist/qaStructuredResponse.d.ts +10 -0
- package/dist/qaStructuredResponse.js +57 -0
- package/dist/qaTimeline.js +5 -3
- package/dist/qaVerificationContract.d.ts +1 -2
- package/dist/qaVerificationContract.js +24 -35
- package/dist/readinessGate.js +5 -4
- package/dist/runtimeReadiness.js +23 -15
- package/dist/statusReporter.d.ts +2 -0
- package/dist/statusReporter.js +2 -0
- package/dist/structuredCutover.d.ts +31 -0
- package/dist/structuredCutover.js +510 -0
- package/dist/structuredCutoverFiles.d.ts +10 -0
- package/dist/structuredCutoverFiles.js +181 -0
- package/dist/structuredDispatchAuthority.d.ts +22 -0
- package/dist/structuredDispatchAuthority.js +110 -0
- package/dist/structuredDispatchRecord.d.ts +29 -0
- package/dist/structuredDispatchRecord.js +36 -0
- package/dist/structuredLiveBudget.d.ts +2 -0
- package/dist/structuredLiveBudget.js +23 -0
- package/dist/structuredOperation.d.ts +18 -0
- package/dist/structuredOperation.js +257 -0
- package/dist/supervisedStart.js +35 -21
- package/dist/ticketPlanning.d.ts +1 -373
- package/dist/ticketPlanning.js +2 -26
- package/dist/ticketPopulation.d.ts +0 -3
- package/dist/ticketPopulation.js +4 -21
- package/dist/ticketPopulationPageAuthority.d.ts +13 -0
- package/dist/ticketPopulationPageAuthority.js +30 -0
- package/dist/ticketPopulationPaging.d.ts +27 -0
- package/dist/ticketPopulationPaging.js +105 -0
- package/dist/tickets/renderMarkdown.d.ts +14 -0
- package/dist/tickets/renderMarkdown.js +39 -5
- package/dist/tickets/ticketLoader.js +10 -0
- package/dist/tickets/ticketSchema.d.ts +107 -0
- package/dist/tickets/ticketSchema.js +4 -1
- package/dist/workflowDb.d.ts +100 -2
- package/dist/workflowDb.js +763 -39
- package/dist/workflowReader.d.ts +1 -0
- package/dist/workflowReader.js +9 -0
- package/package.json +15 -7
|
@@ -45,6 +45,25 @@ export function admittedPlanInput(projectDir, ticket) {
|
|
|
45
45
|
requirements.push({ id: `req-plan-${fingerprint.slice(0, 24)}-${occurrence}`, inputRef: input.id, locator: `${location}${field}[${index}]`, statement, digest: contractDigest("statement", statement), obligation: "mandatory", origin: "explicit", authority: "approved" });
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
+
if (slice.verification_version === 2) {
|
|
49
|
+
for (const requirement of slice.verification_requirements ?? []) {
|
|
50
|
+
const statement = requirement.summary;
|
|
51
|
+
requirements.push({
|
|
52
|
+
id: `req-plan-v2-${slice.slice_ref}-${requirement.id}`,
|
|
53
|
+
inputRef: input.id,
|
|
54
|
+
locator: `slices.${slice.slice_ref}.verification_requirements.${requirement.id}`,
|
|
55
|
+
statement,
|
|
56
|
+
// A RequirementRef's historical digest domain is its statement.
|
|
57
|
+
// Keep that invariant and bind the executable V2 intent separately.
|
|
58
|
+
digest: contractDigest("statement", statement),
|
|
59
|
+
verificationIntentDigest: contractDigest("verification-intent-v2", requirement),
|
|
60
|
+
obligation: "mandatory",
|
|
61
|
+
origin: "explicit",
|
|
62
|
+
authority: "approved",
|
|
63
|
+
verificationIntent: structuredClone(requirement),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
48
67
|
return { input, plan, requirements };
|
|
49
68
|
}
|
|
50
69
|
throw new Error("Exact admitted approved-plan revision unavailable; restore its immutable artifact before preparation");
|
|
@@ -6,10 +6,11 @@ export interface QaPrerequisiteEvidence {
|
|
|
6
6
|
checkedAt: string;
|
|
7
7
|
/** Host absence is actionable; host availability never proves provider access. */
|
|
8
8
|
authority: "host-preflight";
|
|
9
|
+
/** not_applicable: a typed applicability condition is false, so the requirement does not apply (never a missing prerequisite). */
|
|
9
10
|
checks: Array<{
|
|
10
11
|
requirement: string;
|
|
11
12
|
capability: string;
|
|
12
|
-
outcome: "available" | "not_run";
|
|
13
|
+
outcome: "available" | "not_run" | "not_applicable";
|
|
13
14
|
evidence: string;
|
|
14
15
|
}>;
|
|
15
16
|
sourceDefects: string[];
|
package/dist/qaPrerequisites.js
CHANGED
|
@@ -17,12 +17,32 @@ export async function checkQaPrerequisites(input) {
|
|
|
17
17
|
catch { /* malformed manifests remain source findings */ }
|
|
18
18
|
const evidence = {
|
|
19
19
|
version: 3, snapshotPath: realpathSync(input.snapshotPath), checkedAt: new Date().toISOString(), authority: "host-preflight",
|
|
20
|
-
scopeDigest: qaDigest("qa-prerequisites-
|
|
20
|
+
scopeDigest: qaDigest("qa-prerequisites-v4", { sourceDigest: input.sourceDigest, snapshotPath: realpathSync(input.snapshotPath), manifests, node: process.version, path: env.PATH ?? "", runtimeContext: input.runtimeContext ?? null, requirements: input.ticket.verification_version === 2 ? input.ticket.verification_requirements : input.ticket.required_tests }),
|
|
21
21
|
checks: [], sourceDefects: [],
|
|
22
22
|
};
|
|
23
23
|
const probe = input.probe ?? ((executable, args) => new Promise(resolve => {
|
|
24
24
|
execFile(executable, args, { cwd: input.snapshotPath, env, timeout: timeoutMs, maxBuffer: 4096, windowsHide: true }, error => resolve(!error));
|
|
25
25
|
}));
|
|
26
|
+
// V2 never extracts or executes a command from provider prose. Its closed
|
|
27
|
+
// probe vocabulary is resolved by the host and records availability only.
|
|
28
|
+
if (input.ticket.verification_version === 2) {
|
|
29
|
+
for (const requirement of input.ticket.verification_requirements ?? []) {
|
|
30
|
+
if (requirement.applicability.kind !== "host-executable-available")
|
|
31
|
+
continue;
|
|
32
|
+
const executable = resolveExecutablePath(requirement.applicability.executable, env);
|
|
33
|
+
const available = Boolean(executable);
|
|
34
|
+
const expected = requirement.applicability.expected;
|
|
35
|
+
evidence.checks.push({
|
|
36
|
+
requirement: requirement.id,
|
|
37
|
+
capability: `host-probe:executable-available:${requirement.applicability.executable}`,
|
|
38
|
+
outcome: available === expected ? "available" : "not_applicable",
|
|
39
|
+
evidence: `Host registry resolved executable availability=${available}; expected=${expected}; ${available === expected ? "requirement applies" : "requirement does not apply"}; snapshot=${evidence.snapshotPath}`,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return evidence;
|
|
43
|
+
}
|
|
44
|
+
// V1 compatibility only: historical prose is read conservatively and never
|
|
45
|
+
// promoted to a typed applicability condition.
|
|
26
46
|
for (const requirement of input.ticket.required_tests) {
|
|
27
47
|
const command = /^\s*`?(pnpm|npm|yarn|bun|node|docker|python3|pytest|cargo|go)\b/.exec(requirement)?.[1];
|
|
28
48
|
if (command) {
|
package/dist/qaProtocolV2.d.ts
CHANGED
|
@@ -73,6 +73,13 @@ export interface QaSessionHandleV2 {
|
|
|
73
73
|
acceptedHandoffReceiptDigest?: string;
|
|
74
74
|
}
|
|
75
75
|
export interface QaTurnIntentV2 {
|
|
76
|
+
sealedDispatch?: import("./structuredDispatchRecord.js").SealedDispatchRecordV2;
|
|
77
|
+
outputContract?: {
|
|
78
|
+
protocolVersion: 2;
|
|
79
|
+
operation: string;
|
|
80
|
+
schemaVersion: number;
|
|
81
|
+
schemaDigest: string;
|
|
82
|
+
};
|
|
76
83
|
version: 2;
|
|
77
84
|
operationId: string;
|
|
78
85
|
runId: string;
|
|
@@ -87,6 +94,14 @@ export interface QaTurnIntentV2 {
|
|
|
87
94
|
intendedAt: string;
|
|
88
95
|
}
|
|
89
96
|
export interface QaTurnReceiptV2 {
|
|
97
|
+
retainedEvidence?: {
|
|
98
|
+
rawOriginalBytes?: number;
|
|
99
|
+
rawRetainedBytes?: number;
|
|
100
|
+
cleanedOriginalBytes: number;
|
|
101
|
+
cleanedRetainedBytes: number;
|
|
102
|
+
};
|
|
103
|
+
sealedDispatch?: import("./structuredDispatchRecord.js").SealedDispatchRecordV2;
|
|
104
|
+
structuredResponseDigest?: string;
|
|
90
105
|
version: 2;
|
|
91
106
|
operationId: string;
|
|
92
107
|
dispatch: "not-dispatched" | "completed" | "uncertain";
|
package/dist/qaRecovery.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
2
2
|
import { execFileSync } from "node:child_process";
|
|
3
3
|
import { chmodSync, closeSync, cpSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, readlinkSync, readdirSync, realpathSync, renameSync, writeFileSync, } from "node:fs";
|
|
4
4
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
5
|
-
import { parseProviderContract,
|
|
5
|
+
import { parseProviderContract, parseStrictJson, validateQaFailureReport, QA_FAILURE_REPORT_MAX_BYTES, qaRecoveryAcknowledgementV1Schema } from "rafi-spec";
|
|
6
6
|
import { calculateFrozenQaStateDigest, captureFrozenQaSource } from "./qaSnapshot.js";
|
|
7
7
|
import { WorkflowDb } from "./workflowDb.js";
|
|
8
8
|
export const QA_RECOVERY_ROOT = ".foreman/qa-report-recovery";
|
|
@@ -81,6 +81,8 @@ export function canonicalizeQaRecoveryRequirements(packet) {
|
|
|
81
81
|
return revise(loaded, { resources });
|
|
82
82
|
}
|
|
83
83
|
export function loadQaRecoveryPacket(directory) {
|
|
84
|
+
if (existsSync(join(directory, ".structured-communication-v2-cutover")))
|
|
85
|
+
throw new Error("structured-communication-v2-cutover: this recovery packet cannot resume; start a new native dispatch");
|
|
84
86
|
const root = resolve(directory);
|
|
85
87
|
const manifestPath = join(root, "manifest.json");
|
|
86
88
|
if (!existsSync(manifestPath) || lstatSync(manifestPath).isSymbolicLink())
|
|
@@ -455,7 +457,22 @@ export function readManualQaReport(packetDirectory) { return JSON.parse(readFile
|
|
|
455
457
|
export function validateManualQaReport(packet) {
|
|
456
458
|
const path = join(packet.directory, "report.json");
|
|
457
459
|
const raw = existsSync(path) ? readFileSync(path) : Buffer.alloc(0);
|
|
458
|
-
|
|
460
|
+
let value;
|
|
461
|
+
let errors = [];
|
|
462
|
+
if (raw.length > QA_FAILURE_REPORT_MAX_BYTES)
|
|
463
|
+
errors = [`serialized report exceeds ${QA_FAILURE_REPORT_MAX_BYTES} bytes`];
|
|
464
|
+
else {
|
|
465
|
+
try {
|
|
466
|
+
value = parseStrictJson(raw.toString());
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
errors = [`invalid JSON: ${String(error)}`];
|
|
470
|
+
}
|
|
471
|
+
if (!errors.length)
|
|
472
|
+
errors = validateQaFailureReport(value).errors;
|
|
473
|
+
}
|
|
474
|
+
const parsed = { report: errors.length ? undefined : value,
|
|
475
|
+
validation: { valid: errors.length === 0, errors } };
|
|
459
476
|
let next = appendQaRecoveryResource(packet, `validation/manual-repair-r${packet.manifest.revision + 1}.json`, parsed.validation, { purpose: "Validation result for the latest operator-edited report.json" });
|
|
460
477
|
const editable = writeEditableReport(packet.directory, raw);
|
|
461
478
|
next = revise(next, { resources: next.manifest.resources.filter((resource) => resource.path !== "report.json").concat(editable).sort(resourceOrder) });
|
|
@@ -499,8 +516,8 @@ export function renderQaRecoveryAcknowledgementInstruction(packet, relativePath)
|
|
|
499
516
|
`Packet digest: ${packet.manifest.packetDigest}`,
|
|
500
517
|
`Reviewed-state digest: ${packet.manifest.reviewedStateDigest}`,
|
|
501
518
|
"Required resources:", required,
|
|
502
|
-
"
|
|
503
|
-
|
|
519
|
+
"Return the following payload in the native qa-recovery-acceptance response, with bounded continuity in the same object:",
|
|
520
|
+
JSON.stringify({ packet: packet.manifest.packetDigest, reviewed_state: packet.manifest.reviewedStateDigest, required_resources_read: "all" }),
|
|
504
521
|
].join("\n");
|
|
505
522
|
}
|
|
506
523
|
export function validateQaRecoveryAcknowledgement(text, packet, options = {}) {
|