loopforge 3.0.0 → 3.6.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 +126 -143
- package/dist/audit.d.ts +50 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +131 -0
- package/dist/audit.js.map +1 -0
- package/dist/canonical-state.d.ts +98 -23
- package/dist/canonical-state.d.ts.map +1 -1
- package/dist/canonical-state.js +257 -181
- package/dist/canonical-state.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +40 -33
- package/dist/cli.js.map +1 -1
- package/dist/cognitive-facts.d.ts +17 -0
- package/dist/cognitive-facts.d.ts.map +1 -0
- package/dist/cognitive-facts.js +99 -0
- package/dist/cognitive-facts.js.map +1 -0
- package/dist/cognitive-governance.d.ts +25 -33
- package/dist/cognitive-governance.d.ts.map +1 -1
- package/dist/cognitive-governance.js +38 -138
- package/dist/cognitive-governance.js.map +1 -1
- package/dist/committed-round.d.ts +59 -0
- package/dist/committed-round.d.ts.map +1 -0
- package/dist/committed-round.js +222 -0
- package/dist/committed-round.js.map +1 -0
- package/dist/enforcement-gate.d.ts +78 -0
- package/dist/enforcement-gate.d.ts.map +1 -0
- package/dist/enforcement-gate.js +1109 -0
- package/dist/enforcement-gate.js.map +1 -0
- package/dist/engine.d.ts +111 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +887 -0
- package/dist/engine.js.map +1 -0
- package/dist/evidence-claims.d.ts +50 -0
- package/dist/evidence-claims.d.ts.map +1 -0
- package/dist/evidence-claims.js +116 -0
- package/dist/evidence-claims.js.map +1 -0
- package/dist/evidence-provider.d.ts +50 -23
- package/dist/evidence-provider.d.ts.map +1 -1
- package/dist/evidence-provider.js +167 -50
- package/dist/evidence-provider.js.map +1 -1
- package/dist/generate-schema.js +1 -84
- package/dist/generate-schema.js.map +1 -1
- package/dist/index.d.ts +19 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -15
- package/dist/index.js.map +1 -1
- package/dist/loop-compiler.d.ts +58 -3
- package/dist/loop-compiler.d.ts.map +1 -1
- package/dist/loop-compiler.js +841 -304
- package/dist/loop-compiler.js.map +1 -1
- package/dist/loop-extras-parser.d.ts +2 -2
- package/dist/loop-extras-parser.d.ts.map +1 -1
- package/dist/loop-extras-parser.js +2 -2
- package/dist/loop-extras-parser.js.map +1 -1
- package/dist/loop-projection.d.ts +6 -0
- package/dist/loop-projection.d.ts.map +1 -0
- package/dist/loop-projection.js +26 -0
- package/dist/loop-projection.js.map +1 -0
- package/dist/loop-store.d.ts +115 -24
- package/dist/loop-store.d.ts.map +1 -1
- package/dist/loop-store.js +365 -218
- package/dist/loop-store.js.map +1 -1
- package/dist/mcp/round-lifecycle.d.ts +214 -0
- package/dist/mcp/round-lifecycle.d.ts.map +1 -0
- package/dist/mcp/round-lifecycle.js +935 -0
- package/dist/mcp/round-lifecycle.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +29 -43
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/session.d.ts +64 -101
- package/dist/mcp/session.d.ts.map +1 -1
- package/dist/mcp/session.js +433 -1110
- package/dist/mcp/session.js.map +1 -1
- package/dist/mcp/tools.d.ts +20 -11
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +587 -413
- package/dist/mcp/tools.js.map +1 -1
- package/dist/policy-metrics.d.ts +12 -24
- package/dist/policy-metrics.d.ts.map +1 -1
- package/dist/policy-metrics.js +78 -184
- package/dist/policy-metrics.js.map +1 -1
- package/dist/policy.d.ts +61 -50
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +48 -146
- package/dist/policy.js.map +1 -1
- package/dist/prompt-assembler.d.ts +37 -6
- package/dist/prompt-assembler.d.ts.map +1 -1
- package/dist/prompt-assembler.js +487 -278
- package/dist/prompt-assembler.js.map +1 -1
- package/dist/prompt-policy.d.ts +1 -8
- package/dist/prompt-policy.d.ts.map +1 -1
- package/dist/prompt-policy.js +8 -26
- package/dist/prompt-policy.js.map +1 -1
- package/dist/protocol.d.ts +398 -236
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +147 -17
- package/dist/protocol.js.map +1 -1
- package/dist/replay.d.ts +5 -13
- package/dist/replay.d.ts.map +1 -1
- package/dist/replay.js +32 -69
- package/dist/replay.js.map +1 -1
- package/dist/round-contract.d.ts +64 -0
- package/dist/round-contract.d.ts.map +1 -0
- package/dist/round-contract.js +80 -0
- package/dist/round-contract.js.map +1 -0
- package/dist/round-coordinator.d.ts +23 -25
- package/dist/round-coordinator.d.ts.map +1 -1
- package/dist/round-coordinator.js +103 -92
- package/dist/round-coordinator.js.map +1 -1
- package/dist/round-driver.d.ts +13 -13
- package/dist/round-driver.d.ts.map +1 -1
- package/dist/round-driver.js +25 -14
- package/dist/round-driver.js.map +1 -1
- package/dist/round-transaction.d.ts +14 -18
- package/dist/round-transaction.d.ts.map +1 -1
- package/dist/round-transaction.js +37 -47
- package/dist/round-transaction.js.map +1 -1
- package/dist/self-eval.d.ts +48 -0
- package/dist/self-eval.d.ts.map +1 -0
- package/dist/self-eval.js +248 -0
- package/dist/self-eval.js.map +1 -0
- package/dist/storage.d.ts +9 -4
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +18 -6
- package/dist/storage.js.map +1 -1
- package/dist/token-utils.d.ts +15 -3
- package/dist/token-utils.d.ts.map +1 -1
- package/dist/token-utils.js +24 -5
- package/dist/token-utils.js.map +1 -1
- package/dist/verification-gate.d.ts +149 -0
- package/dist/verification-gate.d.ts.map +1 -0
- package/dist/verification-gate.js +1343 -0
- package/dist/verification-gate.js.map +1 -0
- package/dist/workspace.d.ts +29 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +61 -0
- package/dist/workspace.js.map +1 -0
- package/loop_policy.json +37 -16
- package/package.json +5 -10
- package/skills/perception/SKILL.md +184 -202
- package/dist/canonical-event-writer.d.ts +0 -20
- package/dist/canonical-event-writer.d.ts.map +0 -1
- package/dist/canonical-event-writer.js +0 -131
- package/dist/canonical-event-writer.js.map +0 -1
- package/dist/compiler-subgoals.d.ts +0 -7
- package/dist/compiler-subgoals.d.ts.map +0 -1
- package/dist/compiler-subgoals.js +0 -93
- package/dist/compiler-subgoals.js.map +0 -1
- package/dist/derive-id.d.ts +0 -12
- package/dist/derive-id.d.ts.map +0 -1
- package/dist/derive-id.js +0 -31
- package/dist/derive-id.js.map +0 -1
- package/dist/mcp/session-projection.d.ts +0 -5
- package/dist/mcp/session-projection.d.ts.map +0 -1
- package/dist/mcp/session-projection.js +0 -18
- package/dist/mcp/session-projection.js.map +0 -1
- package/dist/mcp/session-queue.d.ts +0 -3
- package/dist/mcp/session-queue.d.ts.map +0 -1
- package/dist/mcp/session-queue.js +0 -18
- package/dist/mcp/session-queue.js.map +0 -1
- package/dist/mcp/session-types.d.ts +0 -72
- package/dist/mcp/session-types.d.ts.map +0 -1
- package/dist/mcp/session-types.js +0 -2
- package/dist/mcp/session-types.js.map +0 -1
- package/dist/round-commit-store.d.ts +0 -12
- package/dist/round-commit-store.d.ts.map +0 -1
- package/dist/round-commit-store.js +0 -13
- package/dist/round-commit-store.js.map +0 -1
- package/dist/round-gate.d.ts +0 -31
- package/dist/round-gate.d.ts.map +0 -1
- package/dist/round-gate.js +0 -259
- package/dist/round-gate.js.map +0 -1
- package/dist/round-recovery.d.ts +0 -17
- package/dist/round-recovery.d.ts.map +0 -1
- package/dist/round-recovery.js +0 -117
- package/dist/round-recovery.js.map +0 -1
- package/dist/round-report.d.ts +0 -16
- package/dist/round-report.d.ts.map +0 -1
- package/dist/round-report.js +0 -401
- package/dist/round-report.js.map +0 -1
- package/dist/runtime-services.d.ts +0 -59
- package/dist/runtime-services.d.ts.map +0 -1
- package/dist/runtime-services.js +0 -460
- package/dist/runtime-services.js.map +0 -1
- package/dist/vault-format.d.ts +0 -4
- package/dist/vault-format.d.ts.map +0 -1
- package/dist/vault-format.js +0 -4
- package/dist/vault-format.js.map +0 -1
- package/dist/vault-types.d.ts +0 -24
- package/dist/vault-types.d.ts.map +0 -1
- package/dist/vault-types.js +0 -2
- package/dist/vault-types.js.map +0 -1
- package/loopforge-policy.json +0 -340
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { deriveItemId, jaccardSimilarity } from "./token-utils.js";
|
|
2
|
+
import { getPolicy } from "./policy.js";
|
|
3
|
+
// ── Criterion reference matching ──────────────────────────────────────────
|
|
4
|
+
// Mirrors criteriaMatch (loop-compiler.ts) without importing loop-compiler
|
|
5
|
+
// (round-contract is imported BY loop-compiler — importing back would be a
|
|
6
|
+
// cycle). Parity is locked by round-contract.test.ts.
|
|
7
|
+
const CRITERION_ID_RE = /^cr-[a-f0-9]{8}$/;
|
|
8
|
+
function isCriterionId(ref) {
|
|
9
|
+
return CRITERION_ID_RE.test(ref);
|
|
10
|
+
}
|
|
11
|
+
function deriveCriterionId(text) {
|
|
12
|
+
return "cr-" + deriveItemId(text);
|
|
13
|
+
}
|
|
14
|
+
/** Match two done_when / met-claim references for completion testing.
|
|
15
|
+
* cr-ID-aware + Jaccard fallback, identical to criteriaMatch. */
|
|
16
|
+
export function contractItemMatches(a, b) {
|
|
17
|
+
const aIsId = isCriterionId(a);
|
|
18
|
+
const bIsId = isCriterionId(b);
|
|
19
|
+
if (aIsId && bIsId)
|
|
20
|
+
return a === b;
|
|
21
|
+
if (aIsId)
|
|
22
|
+
return a === deriveCriterionId(b);
|
|
23
|
+
if (bIsId)
|
|
24
|
+
return deriveCriterionId(a) === b;
|
|
25
|
+
return jaccardSimilarity(a, b) >= getPolicy().evolution.criteria_dedup_threshold;
|
|
26
|
+
}
|
|
27
|
+
/** Whether every done_when item of `contract` matches a claim in `met`.
|
|
28
|
+
* Vacuous when done_when is empty (such contracts were already warned
|
|
29
|
+
* round_underspecified at declaration; they close at the first eval
|
|
30
|
+
* committed while active). */
|
|
31
|
+
export function contractDoneWhenSatisfied(contract, met) {
|
|
32
|
+
if (contract.done_when.length === 0)
|
|
33
|
+
return true;
|
|
34
|
+
return contract.done_when.every((item) => met.some((claim) => contractItemMatches(item, claim)));
|
|
35
|
+
}
|
|
36
|
+
/** Walk committed evals (ASCENDING by round; the caller already restricts
|
|
37
|
+
* them to rounds earlier than the compile/verify round) and return the
|
|
38
|
+
* ACTIVE contract for the round after the last committed one — null means
|
|
39
|
+
* the Current Task falls back to the original task text.
|
|
40
|
+
*
|
|
41
|
+
* State machine per committed eval r, with `active` the contract carried
|
|
42
|
+
* into r (null = whole-task round):
|
|
43
|
+
* - active && r.outcome === "blocked" → active = r.proposal
|
|
44
|
+
* - active && all done_when in r.met → active = r.proposal
|
|
45
|
+
* - active && neither → active unchanged (r's
|
|
46
|
+
* different proposal is a premature replacement and is ignored)
|
|
47
|
+
* - !active → active = r.proposal
|
|
48
|
+
* (a proposal never activates on its own declaration round — it becomes
|
|
49
|
+
* active only for the rounds that follow the commit). */
|
|
50
|
+
export function deriveActiveRoundContract(committed) {
|
|
51
|
+
let active = null;
|
|
52
|
+
for (const r of committed) {
|
|
53
|
+
if (active === null) {
|
|
54
|
+
active = r.proposal ?? null;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (r.outcome === "blocked") {
|
|
58
|
+
active = r.proposal ?? null;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (contractDoneWhenSatisfied(active, r.met)) {
|
|
62
|
+
active = r.proposal ?? null;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
// active !== null and not closed — it continues; r's proposal (if any)
|
|
66
|
+
// is a premature replacement and is ignored.
|
|
67
|
+
}
|
|
68
|
+
return active;
|
|
69
|
+
}
|
|
70
|
+
/** Narrow the shared committed-round view to the contract state machine's
|
|
71
|
+
* inputs. Contract code never interprets persistence envelopes itself. */
|
|
72
|
+
export function contractRoundEvaluations(rounds) {
|
|
73
|
+
return rounds.map((view) => ({
|
|
74
|
+
round: view.round,
|
|
75
|
+
proposal: view.contractProposal,
|
|
76
|
+
outcome: view.outcome,
|
|
77
|
+
met: view.executionEvidence?.success_criteria_met ?? [],
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=round-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"round-contract.js","sourceRoot":"","sources":["../src/round-contract.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAaxC,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,sDAAsD;AAEtD,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAE3C,SAAS,aAAa,CAAC,GAAW;IAChC,OAAO,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;kEACkE;AAClE,MAAM,UAAU,mBAAmB,CAAC,CAAS,EAAE,CAAS;IACtD,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,KAAK,IAAI,KAAK;QAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,KAAK;QAAE,OAAO,CAAC,KAAK,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAC7C,IAAI,KAAK;QAAE,OAAO,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC7C,OAAO,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,SAAS,CAAC,wBAAwB,CAAC;AACnF,CAAC;AAED;;;+BAG+B;AAC/B,MAAM,UAAU,yBAAyB,CACvC,QAAuB,EACvB,GAAa;IAEb,IAAI,QAAQ,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CACvC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CACtD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;0DAa0D;AAC1D,MAAM,UAAU,yBAAyB,CACvC,SAAkD;IAElD,IAAI,MAAM,GAAyB,IAAI,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,MAAM,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,IAAI,yBAAyB,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7C,MAAM,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,uEAAuE;QACvE,6CAA6C;IAC/C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;0EAC0E;AAC1E,MAAM,UAAU,wBAAwB,CACtC,MAAyC;IAEzC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,gBAAgB;QAC/B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,EAAE,IAAI,CAAC,iBAAiB,EAAE,oBAAoB,IAAI,EAAE;KACxD,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
*
|
|
6
6
|
* verify → enforce → stop decision
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Before this module, runtime.ts and session.ts each maintained their
|
|
9
|
+
* own copy of the pipeline (~60 lines each). Drift between the two
|
|
10
|
+
* paths (e.g. git verification only wired into one side) was a known
|
|
11
|
+
* risk. The RoundCoordinator is the single source of truth.
|
|
10
12
|
*
|
|
11
13
|
* State transitions:
|
|
12
14
|
* RoundStarted → EvidenceCaptured → EvaluationSubmitted
|
|
@@ -17,17 +19,17 @@
|
|
|
17
19
|
*/
|
|
18
20
|
import type { LoopStore } from "./loop-store.js";
|
|
19
21
|
import type { ProviderSnapshot } from "./evidence-provider.js";
|
|
20
|
-
import type {
|
|
22
|
+
import type { SelfEvaluation, StopReason, VerificationFlag } from "./protocol.js";
|
|
21
23
|
/** Input to a single round processing step. */
|
|
22
24
|
export interface RoundProcessInput {
|
|
23
25
|
loopId: string;
|
|
24
26
|
task: string;
|
|
25
27
|
currentRound: number;
|
|
26
28
|
maxRounds: number;
|
|
27
|
-
/** The
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
|
|
29
|
+
/** The agent's self-evaluation for this round. */
|
|
30
|
+
selfEval: SelfEvaluation;
|
|
31
|
+
/** The previous round's validated SelfEvaluation (null for round 1). */
|
|
32
|
+
lastSelfEval?: SelfEvaluation;
|
|
31
33
|
/** How many consecutive rounds have been rejected by enforcement. */
|
|
32
34
|
consecutiveRejections: number;
|
|
33
35
|
/** v1.18: Evidence snapshots from configured providers. */
|
|
@@ -37,15 +39,9 @@ export interface RoundProcessInput {
|
|
|
37
39
|
/** v2.13: Files from skipped backtrack rounds. Passed to verification
|
|
38
40
|
* gate for post-backtrack workspace restore check. */
|
|
39
41
|
backtrackSkippedFiles?: string[];
|
|
40
|
-
/** v2.
|
|
41
|
-
*
|
|
42
|
+
/** v2.12: Git HEAD of the backtrack restore point. The verification gate
|
|
43
|
+
* checks the workspace returns to this commit before accepting work. */
|
|
42
44
|
backtrackTargetGitHead?: string;
|
|
43
|
-
/** Runtime-derived action from the prompt being completed. */
|
|
44
|
-
expectedAction?: string;
|
|
45
|
-
/** Terminal enforcement checks that already consumed their guided retry. */
|
|
46
|
-
escalatedRejectionChecks?: string[];
|
|
47
|
-
/** Criteria still open when the report was compiled. */
|
|
48
|
-
remainingCriteria?: string[];
|
|
49
45
|
}
|
|
50
46
|
/** Result of processing a round through the coordinator. */
|
|
51
47
|
export interface RoundProcessResult {
|
|
@@ -69,7 +65,7 @@ export interface RoundProcessResult {
|
|
|
69
65
|
enforcementAction?: "accept" | "reject" | "terminate" | "backtrack";
|
|
70
66
|
/** Enforcement reason (set when rejected or terminated). */
|
|
71
67
|
enforcementReason?: string;
|
|
72
|
-
/** Whether this round was successful
|
|
68
|
+
/** Whether this round was successful (from selfEval.success). */
|
|
73
69
|
roundSuccess: boolean;
|
|
74
70
|
/** Whether the verification gate returned "contradicted". */
|
|
75
71
|
gateContradicted: boolean;
|
|
@@ -78,17 +74,19 @@ export interface RoundProcessResult {
|
|
|
78
74
|
/** Which enforcement check fired (set when action is "reject" or "terminate").
|
|
79
75
|
* Used by callers to track per-rule rejection counters. */
|
|
80
76
|
rejectionCheck?: string;
|
|
81
|
-
/** The
|
|
77
|
+
/** The selfEval to store as lastSelfEval for the next round
|
|
82
78
|
* (undefined when action is "reject" — caller should NOT update). */
|
|
83
|
-
|
|
79
|
+
newLastSelfEval?: SelfEvaluation;
|
|
84
80
|
/** Whether the caller should push roundSuccess onto the success trajectory.
|
|
85
81
|
* false when gateContradicted or when action is "reject". */
|
|
86
82
|
shouldPushSuccessTrajectory: boolean;
|
|
87
83
|
/** v2.12: True when this round's intent_drift was waived via substantive
|
|
88
|
-
* drift_clarification. The caller uses this to track clarification streaks.
|
|
84
|
+
* drift_clarification. The caller uses this to track clarification streaks.
|
|
85
|
+
* v3.3.1: false when R7 itself rejected/terminated on a weak or missing
|
|
86
|
+
* clarification (the caller increments the streak); undefined when R7 did
|
|
87
|
+
* not participate in the decision — a higher-priority rule's rejection
|
|
88
|
+
* must never touch the streak. */
|
|
89
89
|
clarificationAccepted?: boolean;
|
|
90
|
-
/** True when a terminal enforcement rule was converted into one final reject. */
|
|
91
|
-
escalationIssued?: boolean;
|
|
92
90
|
/** v2.13: Git HEAD commit hash of the backtrack target round.
|
|
93
91
|
* Set when action is "backtrack". The verification gate uses this
|
|
94
92
|
* to check that the agent restored the workspace before working. */
|
|
@@ -99,9 +97,9 @@ export interface RoundProcessResult {
|
|
|
99
97
|
backtrackSkippedFiles?: string[];
|
|
100
98
|
}
|
|
101
99
|
export declare class RoundCoordinator {
|
|
102
|
-
private
|
|
103
|
-
constructor(
|
|
104
|
-
/** Process a single round's
|
|
100
|
+
private store;
|
|
101
|
+
constructor(store?: LoopStore);
|
|
102
|
+
/** Process a single round's self-evaluation through the decision pipeline:
|
|
105
103
|
* verify → enforce → stop decision.
|
|
106
104
|
*
|
|
107
105
|
* This is the single entry point called by SessionManager.
|
|
@@ -109,7 +107,7 @@ export declare class RoundCoordinator {
|
|
|
109
107
|
* - Compiling the next prompt (if action is "continue")
|
|
110
108
|
* - Managing heartbeat / signal handlers (runtime only)
|
|
111
109
|
* - Memory injection (both paths, before calling processRound)
|
|
112
|
-
* - Transactional
|
|
110
|
+
* - Transactional feedback commit (accepted rounds only)
|
|
113
111
|
* - State file I/O (both paths, after compiling)
|
|
114
112
|
*
|
|
115
113
|
* @param driftClarificationStreak v2.12: Current clarification streak
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round-coordinator.d.ts","sourceRoot":"","sources":["../src/round-coordinator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"round-coordinator.d.ts","sourceRoot":"","sources":["../src/round-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAEV,cAAc,EACd,UAAU,EACV,gBAAgB,EAEjB,MAAM,eAAe,CAAC;AAgBvB,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,QAAQ,EAAE,cAAc,CAAC;IACzB,wEAAwE;IACxE,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,qEAAqE;IACrE,qBAAqB,EAAE,MAAM,CAAC;IAC9B,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACvC,oDAAoD;IACpD,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC9B;2DACuD;IACvD,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC;6EACyE;IACzE,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,4DAA4D;AAC5D,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IACnE,kEAAkE;IAClE,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,2BAA2B,CAAC,EAAE,MAAM,EAAE,CAAC;IACvC,6DAA6D;IAC7D,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,2EAA2E;IAC3E,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IACpE,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAC;IACtB,6DAA6D;IAC7D,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iEAAiE;IACjE,wBAAwB,EAAE,MAAM,CAAC;IACjC;gEAC4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;0EACsE;IACtE,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC;kEAC8D;IAC9D,2BAA2B,EAAE,OAAO,CAAC;IACrC;;;;;uCAKmC;IACnC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;yEAEqE;IACrE,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;gEAE4D;IAC5D,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAsBD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAAwB;gBAEzB,KAAK,CAAC,EAAE,SAAS;IAI7B;;;;;;;;;;;;gFAY4E;IAC5E,YAAY,CACV,KAAK,EAAE,iBAAiB,EACxB,wBAAwB,GAAE,MAAU,GACnC,kBAAkB;CAsRtB"}
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
*
|
|
6
6
|
* verify → enforce → stop decision
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Before this module, runtime.ts and session.ts each maintained their
|
|
9
|
+
* own copy of the pipeline (~60 lines each). Drift between the two
|
|
10
|
+
* paths (e.g. git verification only wired into one side) was a known
|
|
11
|
+
* risk. The RoundCoordinator is the single source of truth.
|
|
10
12
|
*
|
|
11
13
|
* State transitions:
|
|
12
14
|
* RoundStarted → EvidenceCaptured → EvaluationSubmitted
|
|
@@ -15,18 +17,31 @@
|
|
|
15
17
|
* Persistence is owned by round-transaction.ts so reject paths remain
|
|
16
18
|
* side-effect free and accepted decisions can be replayed idempotently.
|
|
17
19
|
*/
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
+
import { queryLoopEntries } from "./loop-store.js";
|
|
21
|
+
import { CHECK_SUCCESS_WITHOUT_VERIFIED_EVIDENCE, verifySelfEvaluation, entryRound } from "./verification-gate.js";
|
|
22
|
+
import { effectiveSuccess } from "./self-eval.js";
|
|
23
|
+
import { enforceRound, buildRejectionPrompt, findSafeRestorePoint, buildBacktrackPrompt, findBacktrackTargetGitHead, } from "./enforcement-gate.js";
|
|
20
24
|
import { logEvent } from "./observability.js";
|
|
21
25
|
import { getPolicy } from "./policy.js";
|
|
22
|
-
|
|
26
|
+
/** v3.2/v3.6: Whether a round's success enters the success trajectory.
|
|
27
|
+
* Excluded when the gate contradicted the round, or when the success claim
|
|
28
|
+
* carries no machine-verified observation — the merged R8 check fires a
|
|
29
|
+
* warn under machine_backed_success "warn" (v3.6: success_unverified merged
|
|
30
|
+
* into R8; its warn-level trajectory exclusion moved with it) — an
|
|
31
|
+
* accepted-but-unverified round is not evidence of progress. */
|
|
32
|
+
function shouldPushSuccess(gateContradicted, verificationFlags) {
|
|
33
|
+
if (gateContradicted)
|
|
34
|
+
return false;
|
|
35
|
+
return !verificationFlags.some((flag) => flag.severity === "warn" &&
|
|
36
|
+
flag.check === CHECK_SUCCESS_WITHOUT_VERIFIED_EVIDENCE);
|
|
37
|
+
}
|
|
23
38
|
// ── RoundCoordinator ───────────────────────────────────────────────────────
|
|
24
39
|
export class RoundCoordinator {
|
|
25
|
-
|
|
26
|
-
constructor(
|
|
27
|
-
this.
|
|
40
|
+
store;
|
|
41
|
+
constructor(store) {
|
|
42
|
+
this.store = store;
|
|
28
43
|
}
|
|
29
|
-
/** Process a single round's
|
|
44
|
+
/** Process a single round's self-evaluation through the decision pipeline:
|
|
30
45
|
* verify → enforce → stop decision.
|
|
31
46
|
*
|
|
32
47
|
* This is the single entry point called by SessionManager.
|
|
@@ -34,36 +49,30 @@ export class RoundCoordinator {
|
|
|
34
49
|
* - Compiling the next prompt (if action is "continue")
|
|
35
50
|
* - Managing heartbeat / signal handlers (runtime only)
|
|
36
51
|
* - Memory injection (both paths, before calling processRound)
|
|
37
|
-
* - Transactional
|
|
52
|
+
* - Transactional feedback commit (accepted rounds only)
|
|
38
53
|
* - State file I/O (both paths, after compiling)
|
|
39
54
|
*
|
|
40
55
|
* @param driftClarificationStreak v2.12: Current clarification streak
|
|
41
56
|
* from session state. Passed through to enforceRound for R7 escalation. */
|
|
42
57
|
processRound(input, driftClarificationStreak = 0) {
|
|
43
|
-
const { loopId, task, currentRound, maxRounds,
|
|
44
|
-
const
|
|
45
|
-
const roundSuccess = roundReport.outcome === "success";
|
|
58
|
+
const { loopId, task, currentRound, maxRounds, selfEval, lastSelfEval, consecutiveRejections, evidenceSnapshots, } = input;
|
|
59
|
+
const roundSuccess = selfEval.success ?? false;
|
|
46
60
|
// ── 1. Query vault entries ──────────────────────────────────────────
|
|
47
|
-
//
|
|
61
|
+
// Lineage entries (constraint violations, output summaries) and feedback
|
|
62
|
+
// entries (execution_evidence, progress estimates) are both needed by
|
|
63
|
+
// the enforcement gate. queryLoopEntries excludes feedback by default,
|
|
64
|
+
// so we issue a second query and merge both result sets.
|
|
48
65
|
const prefix = `loop:${loopId}:r`;
|
|
49
|
-
const vaultEntries = this.
|
|
50
|
-
?
|
|
66
|
+
const vaultEntries = this.store
|
|
67
|
+
? [
|
|
68
|
+
...queryLoopEntries(this.store, loopId, { prefix }),
|
|
69
|
+
...queryLoopEntries(this.store, loopId, { prefix, feedbackOnly: true }),
|
|
70
|
+
]
|
|
51
71
|
: [];
|
|
52
72
|
// ── 2. Verification gate ────────────────────────────────────────────
|
|
53
|
-
const
|
|
54
|
-
previous: previousProjection ?? null,
|
|
55
|
-
expectedAction: input.expectedAction,
|
|
56
|
-
backtrackSkippedFiles: input.backtrackSkippedFiles,
|
|
57
|
-
backtrackTargetGitHead: input.backtrackTargetGitHead,
|
|
58
|
-
consecutiveRejections,
|
|
59
|
-
driftClarificationStreak,
|
|
60
|
-
escalatedRejectionChecks: input.escalatedRejectionChecks,
|
|
61
|
-
});
|
|
62
|
-
const currentProjection = deriveCompilerProjection(roundReport, currentRound, input.remainingCriteria ?? [], evidenceSnapshots ?? []);
|
|
63
|
-
const verifyResult = verifyRoundReport(gateContext);
|
|
73
|
+
const verifyResult = verifySelfEvaluation(selfEval, currentRound, vaultEntries, lastSelfEval ?? null, evidenceSnapshots ?? [], input.backtrackSkippedFiles ?? [], input.backtrackTargetGitHead);
|
|
64
74
|
const verificationFlags = verifyResult.flags;
|
|
65
75
|
const gateContradicted = verifyResult.verdict === "contradicted";
|
|
66
|
-
const clarificationAccepted = verificationFlags.some((item) => item.check === "intent_drift" && item.severity === "warn");
|
|
67
76
|
if (gateContradicted) {
|
|
68
77
|
logEvent("gate_contradicted", {
|
|
69
78
|
loopId,
|
|
@@ -72,8 +81,12 @@ export class RoundCoordinator {
|
|
|
72
81
|
});
|
|
73
82
|
}
|
|
74
83
|
// ── 3. Enforcement gate ──────────────────────────────────────────
|
|
75
|
-
//
|
|
76
|
-
|
|
84
|
+
// v3.3.1: extraction failures stall the round upstream (round-lifecycle,
|
|
85
|
+
// v2.6 design — the runtime never guesses state from text), so every
|
|
86
|
+
// transaction reaches enforcement with a fully extracted self-evaluation.
|
|
87
|
+
// The old v2.5 "heuristic partial enforcement" plumbing (extractionSucceeded
|
|
88
|
+
// flag, enforcement skipEvidenceRules mode) was removed as unreachable.
|
|
89
|
+
const enforceResult = enforceRound(selfEval, verifyResult, currentRound, vaultEntries, consecutiveRejections, driftClarificationStreak);
|
|
77
90
|
if (enforceResult.action === "reject") {
|
|
78
91
|
const newRejections = consecutiveRejections + 1;
|
|
79
92
|
const rejectionPrompt = buildRejectionPrompt(currentRound, task, enforceResult, verificationFlags);
|
|
@@ -91,13 +104,22 @@ export class RoundCoordinator {
|
|
|
91
104
|
enforcementAction: "reject",
|
|
92
105
|
enforcementReason: enforceResult.reason,
|
|
93
106
|
rejectionCheck: enforceResult.check,
|
|
107
|
+
// v3.3.1: an R7-participated reject (weak or missing
|
|
108
|
+
// drift_clarification) echoes clarificationAccepted: false so the
|
|
109
|
+
// caller's streak tracking increments — without this the
|
|
110
|
+
// drift_clarification_max_streak terminate ladder was unreachable
|
|
111
|
+
// (the increment branch required the field, and only the continue
|
|
112
|
+
// path ever set it). Higher-priority rules' rejects keep it
|
|
113
|
+
// undefined, preserving the v3.2.1 "R7-only streak" semantics.
|
|
114
|
+
...(enforceResult.check === "intent_drift"
|
|
115
|
+
? { clarificationAccepted: false }
|
|
116
|
+
: {}),
|
|
94
117
|
roundSuccess,
|
|
95
118
|
gateContradicted,
|
|
96
119
|
newConsecutiveRejections: newRejections,
|
|
97
|
-
// Don't update
|
|
98
|
-
|
|
120
|
+
// Don't update lastSelfEval on reject — the agent redoes the same round
|
|
121
|
+
newLastSelfEval: undefined,
|
|
99
122
|
shouldPushSuccessTrajectory: false,
|
|
100
|
-
escalationIssued: enforceResult.escalation_issued ?? false,
|
|
101
123
|
};
|
|
102
124
|
}
|
|
103
125
|
if (enforceResult.action === "terminate") {
|
|
@@ -113,10 +135,16 @@ export class RoundCoordinator {
|
|
|
113
135
|
enforcementAction: "terminate",
|
|
114
136
|
enforcementReason: enforceResult.reason,
|
|
115
137
|
rejectionCheck: enforceResult.check,
|
|
138
|
+
// v3.3.1: same echo as the reject branch — R7-participated
|
|
139
|
+
// terminates keep the streak contract consistent for the
|
|
140
|
+
// snapshot/audit record (harmless: the session is ending).
|
|
141
|
+
...(enforceResult.check === "intent_drift"
|
|
142
|
+
? { clarificationAccepted: false }
|
|
143
|
+
: {}),
|
|
116
144
|
roundSuccess,
|
|
117
145
|
gateContradicted,
|
|
118
146
|
newConsecutiveRejections: 0,
|
|
119
|
-
|
|
147
|
+
newLastSelfEval: selfEval,
|
|
120
148
|
shouldPushSuccessTrajectory: false,
|
|
121
149
|
};
|
|
122
150
|
}
|
|
@@ -141,18 +169,34 @@ export class RoundCoordinator {
|
|
|
141
169
|
roundSuccess,
|
|
142
170
|
gateContradicted,
|
|
143
171
|
newConsecutiveRejections: 0,
|
|
144
|
-
|
|
172
|
+
newLastSelfEval: selfEval,
|
|
145
173
|
shouldPushSuccessTrajectory: false,
|
|
146
174
|
};
|
|
147
175
|
}
|
|
148
|
-
// Collect files changed in skipped rounds for the restore prompt
|
|
149
|
-
const skippedFiles =
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
176
|
+
// v2.13: Collect files changed in skipped rounds for the restore prompt
|
|
177
|
+
const skippedFiles = [];
|
|
178
|
+
for (let r = restorePoint.round + 1; r < currentRound; r++) {
|
|
179
|
+
// v3.2.1: match the feedback entry (execution_evidence lives there) —
|
|
180
|
+
// the compile-time lineage entry for the same round precedes it in
|
|
181
|
+
// the flat view and carries no evidence.
|
|
182
|
+
const entry = vaultEntries.find((e) => entryRound(e) === r && e.task_type !== "loop_lineage");
|
|
183
|
+
if (entry?.execution_evidence) {
|
|
184
|
+
const ev = entry.execution_evidence;
|
|
185
|
+
const files = Array.isArray(ev.files_changed)
|
|
186
|
+
? ev.files_changed.filter((f) => typeof f === "string")
|
|
187
|
+
: [];
|
|
188
|
+
for (const f of files) {
|
|
189
|
+
if (!skippedFiles.includes(f))
|
|
190
|
+
skippedFiles.push(f);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// v2.12: Capture the restore point's git HEAD so the next round's
|
|
195
|
+
// verification can confirm the workspace returned to this commit.
|
|
196
|
+
const targetGitHead = findBacktrackTargetGitHead(restorePoint.round, vaultEntries);
|
|
153
197
|
const backtrackPrompt = buildBacktrackPrompt(currentRound, restorePoint.round, enforceResult.check ?? "progress_stall", getPolicy().engine.backtrack_preserve_discoveries
|
|
154
198
|
? restorePoint.skippedDiscoveries
|
|
155
|
-
: [], skippedFiles);
|
|
199
|
+
: [], skippedFiles, targetGitHead ?? undefined);
|
|
156
200
|
logEvent("enforcement_backtrack", {
|
|
157
201
|
loopId,
|
|
158
202
|
round: currentRound,
|
|
@@ -165,11 +209,11 @@ export class RoundCoordinator {
|
|
|
165
209
|
action: "backtrack",
|
|
166
210
|
backtrackPrompt,
|
|
167
211
|
backtrackTarget: restorePoint.round,
|
|
168
|
-
backtrackTargetGitHead,
|
|
169
212
|
backtrackSkippedDiscoveries: getPolicy().engine.backtrack_preserve_discoveries
|
|
170
213
|
? restorePoint.skippedDiscoveries
|
|
171
214
|
: [],
|
|
172
215
|
backtrackSkippedFiles: skippedFiles,
|
|
216
|
+
backtrackTargetGitHead: targetGitHead ?? undefined,
|
|
173
217
|
backtrackTriggerRule: enforceResult.check,
|
|
174
218
|
verificationFlags,
|
|
175
219
|
enforcementAction: "backtrack",
|
|
@@ -178,22 +222,22 @@ export class RoundCoordinator {
|
|
|
178
222
|
roundSuccess,
|
|
179
223
|
gateContradicted,
|
|
180
224
|
newConsecutiveRejections: 0, // reset — fresh start
|
|
181
|
-
|
|
225
|
+
newLastSelfEval: undefined,
|
|
182
226
|
shouldPushSuccessTrajectory: false,
|
|
183
227
|
};
|
|
184
228
|
}
|
|
185
229
|
// Accept: reset rejection counter
|
|
186
230
|
// (consecutiveRejections reset to 0 — caller persists)
|
|
187
|
-
// ── 4.
|
|
231
|
+
// ── 4. Auto-feedback (AFTER enforcement, only if accepted) ──────────
|
|
188
232
|
// ── 5. Stop condition checks ────────────────────────────────────────
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
if (roundReport.continuation === "stop") {
|
|
233
|
+
// 5b. Agent says stop
|
|
234
|
+
if (!selfEval.should_continue) {
|
|
192
235
|
let reason;
|
|
193
|
-
if (
|
|
236
|
+
if (effectiveSuccess(selfEval)) {
|
|
194
237
|
reason = "completed";
|
|
195
238
|
}
|
|
196
|
-
else if (
|
|
239
|
+
else if (selfEval.outcome === "blocked" ||
|
|
240
|
+
selfEval.stop_reason === "blocked" || selfEval.stop_reason === "needs_human_input") {
|
|
197
241
|
reason = "blocked";
|
|
198
242
|
}
|
|
199
243
|
else {
|
|
@@ -206,47 +250,14 @@ export class RoundCoordinator {
|
|
|
206
250
|
roundSuccess,
|
|
207
251
|
gateContradicted,
|
|
208
252
|
newConsecutiveRejections: 0,
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
shouldPushSuccessTrajectory: !gateContradicted,
|
|
253
|
+
newLastSelfEval: selfEval,
|
|
254
|
+
shouldPushSuccessTrajectory: shouldPushSuccess(gateContradicted, verificationFlags),
|
|
212
255
|
};
|
|
213
256
|
}
|
|
214
|
-
// 5b. Circuit breaker — max consecutive failed rounds.
|
|
215
|
-
//
|
|
216
|
-
// When the last N accepted rounds (including this one) all reported
|
|
217
|
-
// failure with no recovery, the loop is failing faster than it can
|
|
218
|
-
// self-correct. Stop before errors compound (p^N). The trajectory only
|
|
219
|
-
// contains committed, non-contradicted rounds, so this never fires on
|
|
220
|
-
// an enforcement-rejected round (those never reach this point).
|
|
221
|
-
const breakerMax = getPolicy().engine.max_circuit_breaker;
|
|
222
|
-
if (breakerMax > 0) {
|
|
223
|
-
const breakerWindow = [...(input.successTrajectory ?? []), roundSuccess]
|
|
224
|
-
.slice(-breakerMax);
|
|
225
|
-
if (breakerWindow.length === breakerMax &&
|
|
226
|
-
breakerWindow.every((value) => value === false)) {
|
|
227
|
-
logEvent("session_end", {
|
|
228
|
-
loopId,
|
|
229
|
-
stopReason: "circuit_breaker",
|
|
230
|
-
round: currentRound,
|
|
231
|
-
});
|
|
232
|
-
return {
|
|
233
|
-
action: "stop",
|
|
234
|
-
stopReason: "circuit_breaker",
|
|
235
|
-
verificationFlags,
|
|
236
|
-
roundSuccess,
|
|
237
|
-
gateContradicted,
|
|
238
|
-
newConsecutiveRejections: 0,
|
|
239
|
-
newRoundProjection: currentProjection,
|
|
240
|
-
clarificationAccepted,
|
|
241
|
-
shouldPushSuccessTrajectory: false,
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
257
|
// 5c. Max rounds reached
|
|
246
258
|
//
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
// success flag or from an agent-supplied progress estimate.
|
|
259
|
+
// Progress stalls are handled before this point by the R4 delta tier and
|
|
260
|
+
// R5 flatline tier. Max rounds is an independent hard boundary.
|
|
250
261
|
if (currentRound >= maxRounds) {
|
|
251
262
|
return {
|
|
252
263
|
action: "stop",
|
|
@@ -255,9 +266,8 @@ export class RoundCoordinator {
|
|
|
255
266
|
roundSuccess,
|
|
256
267
|
gateContradicted,
|
|
257
268
|
newConsecutiveRejections: 0,
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
shouldPushSuccessTrajectory: !gateContradicted,
|
|
269
|
+
newLastSelfEval: selfEval,
|
|
270
|
+
shouldPushSuccessTrajectory: shouldPushSuccess(gateContradicted, verificationFlags),
|
|
261
271
|
};
|
|
262
272
|
}
|
|
263
273
|
// ── 6. Continue — caller compiles next round ────────────────────────
|
|
@@ -268,9 +278,10 @@ export class RoundCoordinator {
|
|
|
268
278
|
roundSuccess,
|
|
269
279
|
gateContradicted,
|
|
270
280
|
newConsecutiveRejections: 0,
|
|
271
|
-
|
|
272
|
-
shouldPushSuccessTrajectory:
|
|
273
|
-
|
|
281
|
+
newLastSelfEval: selfEval,
|
|
282
|
+
shouldPushSuccessTrajectory: shouldPushSuccess(gateContradicted, verificationFlags),
|
|
283
|
+
// v2.12: Propagate clarification acceptance signal for streak tracking
|
|
284
|
+
clarificationAccepted: enforceResult.clarification_accepted ?? false,
|
|
274
285
|
};
|
|
275
286
|
}
|
|
276
287
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round-coordinator.js","sourceRoot":"","sources":["../src/round-coordinator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"round-coordinator.js","sourceRoot":"","sources":["../src/round-coordinator.ts"],"names":[],"mappings":"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"}
|
package/dist/round-driver.d.ts
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* in their adapters.
|
|
7
7
|
*/
|
|
8
8
|
import type { LoopStore } from "./loop-store.js";
|
|
9
|
-
import {
|
|
9
|
+
import { LoopForgeEngine } from "./engine.js";
|
|
10
10
|
import type { ProviderSnapshot } from "./evidence-provider.js";
|
|
11
|
-
import type {
|
|
11
|
+
import type { LoopForgeRequest, LoopForgeResponse, PromptArtifact, SelfEvaluation } from "./protocol.js";
|
|
12
12
|
import type { RoundTransactionOutcome, RoundTransactionSnapshot } from "./round-transaction.js";
|
|
13
13
|
export interface PreparedRound {
|
|
14
14
|
prompt: string;
|
|
@@ -18,28 +18,25 @@ export interface PreparedRound {
|
|
|
18
18
|
snapshot: RoundTransactionSnapshot;
|
|
19
19
|
stateFileContent?: string;
|
|
20
20
|
warnings?: string[];
|
|
21
|
-
|
|
21
|
+
/** v3.0.1: The full compile response. Callers may cache it (e.g. for the
|
|
22
|
+
* typed projection) instead of recompiling for derived views. */
|
|
23
|
+
compileResponse?: LoopForgeResponse;
|
|
22
24
|
}
|
|
23
25
|
export interface CompleteRoundInput {
|
|
24
26
|
snapshot: RoundTransactionSnapshot;
|
|
25
27
|
loopId: string;
|
|
26
28
|
task: string;
|
|
27
29
|
maxRounds: number;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
selfEval: SelfEvaluation;
|
|
31
|
+
lastSelfEval?: SelfEvaluation;
|
|
30
32
|
consecutiveRejections: number;
|
|
31
33
|
successTrajectory: boolean[];
|
|
32
34
|
/** v2.12: Current clarification streak for R7 escalation. */
|
|
33
35
|
driftClarificationStreak?: number;
|
|
34
|
-
/** Terminal enforcement checks that already consumed their guided retry. */
|
|
35
|
-
escalatedRejectionChecks?: string[];
|
|
36
36
|
/** v2.13: Files from skipped backtrack rounds for restore check. */
|
|
37
37
|
backtrackSkippedFiles?: string[];
|
|
38
|
-
/** v2.
|
|
39
|
-
* verification gate; the post-backtrack round must match it. */
|
|
38
|
+
/** v2.12: Git HEAD of the backtrack restore point (workspace restore check). */
|
|
40
39
|
backtrackTargetGitHead?: string;
|
|
41
|
-
expectedAction?: string;
|
|
42
|
-
remainingCriteria?: string[];
|
|
43
40
|
}
|
|
44
41
|
export interface CompletedRound {
|
|
45
42
|
outcome: RoundTransactionOutcome;
|
|
@@ -47,9 +44,12 @@ export interface CompletedRound {
|
|
|
47
44
|
}
|
|
48
45
|
export declare class RoundDriver {
|
|
49
46
|
private readonly engine;
|
|
50
|
-
private readonly
|
|
51
|
-
constructor(engine:
|
|
47
|
+
private readonly store;
|
|
48
|
+
constructor(engine: LoopForgeEngine, store?: LoopStore);
|
|
52
49
|
prepare(request: LoopForgeRequest, loopId: string, round: number): Promise<PreparedRound | null>;
|
|
50
|
+
/** Synchronous fallback for legacy embedding APIs. Async evidence providers
|
|
51
|
+
* are deliberately skipped by EvidenceCollector.collect(). */
|
|
52
|
+
prepareSync(request: LoopForgeRequest, loopId: string, round: number): PreparedRound | null;
|
|
53
53
|
private compile;
|
|
54
54
|
/** Compile a fresh prompt for a zero-commit enforcement retry. The logical
|
|
55
55
|
* round ID and before-evidence snapshot remain stable; only attempt changes. */
|