@nexus-cortex/core 4.124.11 → 4.124.12
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/.env.defaults +25 -0
- package/dist/config/RuntimeConfigRegistry.d.ts.map +1 -1
- package/dist/config/RuntimeConfigRegistry.js +5 -0
- package/dist/config/RuntimeConfigRegistry.js.map +1 -1
- package/dist/config/SettingsLoader.d.ts.map +1 -1
- package/dist/config/SettingsLoader.js +5 -0
- package/dist/config/SettingsLoader.js.map +1 -1
- package/dist/config/SettingsSchema.d.ts +5 -0
- package/dist/config/SettingsSchema.d.ts.map +1 -1
- package/dist/config/SettingsSchema.js +13 -0
- package/dist/config/SettingsSchema.js.map +1 -1
- package/dist/config/effectiveConfig.d.ts.map +1 -1
- package/dist/config/effectiveConfig.js +5 -0
- package/dist/config/effectiveConfig.js.map +1 -1
- package/dist/middleware/HelperModelMiddleware.d.ts +11 -0
- package/dist/middleware/HelperModelMiddleware.d.ts.map +1 -1
- package/dist/middleware/HelperModelMiddleware.js +18 -0
- package/dist/middleware/HelperModelMiddleware.js.map +1 -1
- package/dist/orchestrator/CortexOrchestrator.d.ts +12 -0
- package/dist/orchestrator/CortexOrchestrator.d.ts.map +1 -1
- package/dist/orchestrator/CortexOrchestrator.js +127 -3
- package/dist/orchestrator/CortexOrchestrator.js.map +1 -1
- package/dist/training/DecisionStore.d.ts +1 -1
- package/dist/training/DecisionStore.d.ts.map +1 -1
- package/dist/training/endTurnResolver.d.ts +9 -0
- package/dist/training/endTurnResolver.d.ts.map +1 -1
- package/dist/training/endTurnResolver.js +6 -1
- package/dist/training/endTurnResolver.js.map +1 -1
- package/dist/training/requirementLedger.d.ts +84 -0
- package/dist/training/requirementLedger.d.ts.map +1 -0
- package/dist/training/requirementLedger.js +155 -0
- package/dist/training/requirementLedger.js.map +1 -0
- package/package.json +3 -3
|
@@ -23,6 +23,7 @@ import { resolveEndTurnResolverConfig, parseResolverVerdict, effectiveMaxRejects
|
|
|
23
23
|
import { jevAvailable, jevNoul, buildGapHoldState, GAP_HOLD_QUESTIONS } from '../training/jevGate.js'; // R173b
|
|
24
24
|
import { resolveFrameConfig, FRAME_CONTRACT, FRAME_TOOL_NAME } from '../frames/frameConfig.js'; // R179
|
|
25
25
|
import { FrameRunner } from '../frames/frameRunner.js'; // R179
|
|
26
|
+
import { parseRequirementLedger, initLedger, updateLedger, ledgerCounts, ledgerHoldable, formatLedgerForWriter, formatLedgerForJudge, formatLedgerHoldMessage, buildLedgerJevState, buildLedgerJevQuestions, applyLedgerJevAnswers } from '../training/requirementLedger.js'; // R187
|
|
26
27
|
import { isValueShapedTask, parseDerivationReply, methodsDiffer, parseValueLines, extractNumbers, reconcile, buildDerivationHoldMessage, isDerivationCommandAllowed, checkRunPassed, checkRunBody } from '../training/independentDerivation.js'; // R176
|
|
27
28
|
import { resolveDeadlineExitConfig, deadlineExitCallBudget, parseDeadlineExitVerdict } from '../training/deadlineExitMentor.js';
|
|
28
29
|
import { isTaskShaped } from './requirementsVerification.js';
|
|
@@ -249,6 +250,10 @@ export class CortexOrchestrator {
|
|
|
249
250
|
specChecks = null; // R174: blind spec-derived checks authored for this turn (null = not yet)
|
|
250
251
|
specChecksMeta = { genLatencyMs: 0, refused: 0, raw: 0 }; // R174
|
|
251
252
|
specChecksPromise = null; // R174b: authored at lift in the background (CORTEX_JUDGE_SPEC_TESTS_AT=lift)
|
|
253
|
+
reqLedger = null; // R187: the stated-requirement ledger for this turn (null = not yet authored)
|
|
254
|
+
reqLedgerPromise = null; // R187: authored at lift in the background
|
|
255
|
+
reqLedgerHolds = 0; // R187: ledger holds used this turn
|
|
256
|
+
reqLedgerMeta = { genLatencyMs: 0, raw: 0, refused: 0 }; // R187
|
|
252
257
|
specFailHistory = new Map(); // R174b: consecutive identical spec failures
|
|
253
258
|
lastHoldMs = 0; // R173c: wall clock of the last hold/veto this turn
|
|
254
259
|
derivationHolds = 0; // R176: independent-derivation holds this turn (max 1)
|
|
@@ -542,6 +547,7 @@ export class CortexOrchestrator {
|
|
|
542
547
|
void store.recordEvent({
|
|
543
548
|
sessionId, kind: 'lift_plan', detail: { fired: true, planChars: 0, empty: true, ...r171, mentor: this.mentorWire('lift-plan', resolveLiftPlanConfig().effort, resolveLiftPlanConfig().outputBudgetTokens) },
|
|
544
549
|
}).catch(() => { });
|
|
550
|
+
await this.deliverRequirementLedgerToWriter(lastMsg); // R187: the ledger rides even when the plan is empty
|
|
545
551
|
return; // fail-open: proceed without a plan
|
|
546
552
|
}
|
|
547
553
|
const retire = /\bRETIRE\b/i.test(plan);
|
|
@@ -564,6 +570,7 @@ export class CortexOrchestrator {
|
|
|
564
570
|
if (this.config.debug) {
|
|
565
571
|
console.log(`[LiftPlan] plan delivered at lift (${plan.length} chars, retire=${retire}, criteria=${criteriaStated})`);
|
|
566
572
|
}
|
|
573
|
+
await this.deliverRequirementLedgerToWriter(lastMsg); // R187
|
|
567
574
|
}
|
|
568
575
|
catch (e) {
|
|
569
576
|
if (store)
|
|
@@ -574,6 +581,26 @@ export class CortexOrchestrator {
|
|
|
574
581
|
console.warn(`[LiftPlan] delivery failed (continuing without): ${e?.message ?? e}`);
|
|
575
582
|
}
|
|
576
583
|
}
|
|
584
|
+
/** R187: append the requirement ledger to the lift observation the writer is about to see (waits for the lift-time authoring,
|
|
585
|
+
* bounded by the resolver timeout; fail-open to nothing). One-shot per turn. */
|
|
586
|
+
reqLedgerDelivered = false;
|
|
587
|
+
async deliverRequirementLedgerToWriter(lastMsg) {
|
|
588
|
+
const cfg = resolveEndTurnResolverConfig();
|
|
589
|
+
if (!cfg.reqLedger || this.reqLedgerDelivered)
|
|
590
|
+
return;
|
|
591
|
+
this.reqLedgerDelivered = true;
|
|
592
|
+
try {
|
|
593
|
+
const entries = this.reqLedger ?? (this.reqLedgerPromise ? await withTimeout(this.reqLedgerPromise, mentorSurfaceTimeoutMs('endturn-resolver', parseInt(process.env.CORTEX_ENDTURN_RESOLVER_TIMEOUT_MS ?? '90000', 10))) : null);
|
|
594
|
+
const text = formatLedgerForWriter(entries ?? []);
|
|
595
|
+
if (!text)
|
|
596
|
+
return;
|
|
597
|
+
lastMsg?.message?.content?.push?.({ type: 'text', text: `<system-reminder>\n${text}\n</system-reminder>` });
|
|
598
|
+
const store = this.getDecisionStore();
|
|
599
|
+
if (store)
|
|
600
|
+
void store.recordEvent({ sessionId: this.currentSessionId ?? 'unknown', kind: 'requirement_ledger_delivered', toolName: 'EndTurn', detail: { lines: (entries ?? []).length, chars: text.length } }).catch(() => { });
|
|
601
|
+
}
|
|
602
|
+
catch { /* fail-open */ }
|
|
603
|
+
}
|
|
577
604
|
/** Bounded read-only environment recon (ENV_RECON_COMMAND), gathered ONCE and cached — shared by the
|
|
578
605
|
* lift planner and the EndTurn resolver. Fail-open: partial stdout on timeout/non-zero, else empty. */
|
|
579
606
|
gatherEnvReport(opts = {}) {
|
|
@@ -762,6 +789,47 @@ export class CortexOrchestrator {
|
|
|
762
789
|
console.warn(`[EndTurnResolver] R174 SPEC-TESTS — ${this.specChecks.length} blind check(s) authored at ${cfg.specTestsAt} in ${this.specChecksMeta.genLatencyMs} ms (${this.specChecksMeta.refused} refused)`);
|
|
763
790
|
return this.specChecks;
|
|
764
791
|
}
|
|
792
|
+
/** R187: author the requirement ledger (task text + env report ONLY). Sets reqLedger/reqLedgerMeta; never throws. */
|
|
793
|
+
async authorRequirementLedger(task) {
|
|
794
|
+
const cfg = resolveEndTurnResolverConfig();
|
|
795
|
+
const store = this.getDecisionStore();
|
|
796
|
+
const sessionId = this.currentSessionId ?? 'unknown';
|
|
797
|
+
const g0 = Date.now();
|
|
798
|
+
if (!this.helperMiddleware?.deriveRequirementLedger) {
|
|
799
|
+
this.reqLedger = [];
|
|
800
|
+
return [];
|
|
801
|
+
}
|
|
802
|
+
const tmo = mentorSurfaceTimeoutMs('endturn-resolver', parseInt(process.env.CORTEX_ENDTURN_RESOLVER_TIMEOUT_MS ?? '90000', 10));
|
|
803
|
+
try {
|
|
804
|
+
const raw = await withTimeout(this.helperMiddleware.deriveRequirementLedger({ task, envReport: this.gatherEnvReport({ fresh: false }), max: cfg.reqLedgerMax, helperModelId: this.config.reactiveMentorship?.helperModelId }), tmo);
|
|
805
|
+
const lines = parseRequirementLedger(raw ?? '', cfg.reqLedgerMax);
|
|
806
|
+
// a check that is not read-only is dropped (the line stays, unverifiable) — same denylist as every other harness-run check
|
|
807
|
+
let refused = 0;
|
|
808
|
+
const safe = lines.map((l) => (l.check && !isInvestigateCommandAllowed(l.check) ? (refused += 1, { ...l, check: null }) : l));
|
|
809
|
+
this.reqLedger = initLedger(safe);
|
|
810
|
+
this.reqLedgerMeta = { genLatencyMs: Date.now() - g0, raw: (raw ?? '').length, refused };
|
|
811
|
+
}
|
|
812
|
+
catch {
|
|
813
|
+
this.reqLedger = [];
|
|
814
|
+
this.reqLedgerMeta = { genLatencyMs: Date.now() - g0, raw: 0, refused: 0 };
|
|
815
|
+
}
|
|
816
|
+
if (store)
|
|
817
|
+
void store.recordEvent({ sessionId, kind: 'requirement_ledger', toolName: 'EndTurn', detail: { lines: this.reqLedger.map((e) => ({ id: e.id, kind: e.kind, text: e.text, check: e.check })), ...this.reqLedgerMeta, mentor: this.mentorWire('endturn-resolver', cfg.effort, 2000) } }).catch(() => { });
|
|
818
|
+
console.warn(`[EndTurnResolver] R187 REQUIREMENT LEDGER — ${this.reqLedger.length} line(s) (${this.reqLedger.filter((e) => e.check).length} with checks, ${this.reqLedgerMeta.refused} refused) in ${this.reqLedgerMeta.genLatencyMs} ms`);
|
|
819
|
+
return this.reqLedger;
|
|
820
|
+
}
|
|
821
|
+
/** R187: at lift, start authoring the ledger in the background (delivered to the writer by deliverLiftPlanAtLift when ready). */
|
|
822
|
+
maybeAuthorRequirementLedgerAtLift() {
|
|
823
|
+
const cfg = resolveEndTurnResolverConfig();
|
|
824
|
+
if (!cfg.reqLedger || this.reqLedger !== null || this.reqLedgerPromise)
|
|
825
|
+
return;
|
|
826
|
+
if (!resolveEndTurnResolver(process.env))
|
|
827
|
+
return;
|
|
828
|
+
const task = this.lastRealUserText();
|
|
829
|
+
if (!task.trim())
|
|
830
|
+
return;
|
|
831
|
+
this.reqLedgerPromise = this.authorRequirementLedger(task).catch(() => []);
|
|
832
|
+
}
|
|
765
833
|
/** R174b: at lift, start authoring the spec checks in the background so a late first finish still has them. */
|
|
766
834
|
maybeAuthorSpecChecksAtLift() {
|
|
767
835
|
const cfg = resolveEndTurnResolverConfig();
|
|
@@ -872,8 +940,34 @@ export class CortexOrchestrator {
|
|
|
872
940
|
specResults += (specResults ? '\n\n' : '') + x.r + (ev === 'suspect' ? '\n(this check has failed identically at consecutive finishes while everything else passed — treat it as SUSPECT, not as proof of a gap)' : '');
|
|
873
941
|
}
|
|
874
942
|
}
|
|
943
|
+
// R187 HB-REQUIREMENT-LEDGER: run each stated requirement's check; a FAILED line is R166 evidence; an OPEN line (never exercised) can hold once.
|
|
944
|
+
let reqResults = '';
|
|
945
|
+
let reqCounts = { lines: 0, open: 0, exercised: 0, failed: 0, unverifiable: 0 };
|
|
946
|
+
let reqJev = null;
|
|
947
|
+
if (cfg.reqLedger) {
|
|
948
|
+
if (this.reqLedger === null)
|
|
949
|
+
this.reqLedger = await (this.reqLedgerPromise ?? this.authorRequirementLedger(task));
|
|
950
|
+
const runs = this.reqLedger.filter((e) => e.check).map((e) => { const r = runCheck(judgeCwd, e.check, jcfg); return { id: e.id, result: r, cls: classifyCheckRun(r) }; });
|
|
951
|
+
this.reqLedger = updateLedger(this.reqLedger, runs);
|
|
952
|
+
// R187b: Jev decides the lines the shell could not — typed per-line questions on the writer's attestation + harness evidence.
|
|
953
|
+
if (cfg.reqLedgerJev && jevAvailable() && this.reqLedger.some((e) => e.status === 'open' || e.status === 'unverifiable')) {
|
|
954
|
+
const j0 = Date.now();
|
|
955
|
+
try {
|
|
956
|
+
const jr = await jevNoul(buildLedgerJevState({ task, entries: this.reqLedger, attestation, workProduct }), buildLedgerJevQuestions(this.reqLedger));
|
|
957
|
+
const applied = applyLedgerJevAnswers(this.reqLedger, jr ? jr.probabilities : null, cfg.reqLedgerJevMin);
|
|
958
|
+
this.reqLedger = applied.entries;
|
|
959
|
+
reqJev = { asked: applied.asked, closed: applied.closed, latencyMs: Date.now() - j0 };
|
|
960
|
+
}
|
|
961
|
+
catch {
|
|
962
|
+
reqJev = { asked: 0, closed: [], latencyMs: Date.now() - j0, error: true };
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
reqCounts = ledgerCounts(this.reqLedger);
|
|
966
|
+
reqResults = formatLedgerForJudge(this.reqLedger);
|
|
967
|
+
}
|
|
875
968
|
const combinedCheck = [checkResult, namedResults ? `JUDGE-NAMED CHECKS (from your previous fix plan; executed by the harness just now):\n${namedResults}` : '',
|
|
876
|
-
specResults ? `SPEC CHECKS (derived from the TASK text before any work was seen; executed by the harness just now — a FAILED one is a requirement not yet met):\n${specResults}` : ''
|
|
969
|
+
specResults ? `SPEC CHECKS (derived from the TASK text before any work was seen; executed by the harness just now — a FAILED one is a requirement not yet met):\n${specResults}` : '', // R174
|
|
970
|
+
reqResults] // R187
|
|
877
971
|
.filter(Boolean).join('\n\n');
|
|
878
972
|
const callsSince = this.turnToolCallTotal - this.toolCallsAtLastVeto;
|
|
879
973
|
const progressed = this.endTurnResolverRejects === 0 || callsSince >= cfg.progressMinCalls || namedPassed > this.judgePriorNamedPassed; // R166a: newly-passing checks, not any passing check
|
|
@@ -999,7 +1093,7 @@ export class CortexOrchestrator {
|
|
|
999
1093
|
}
|
|
1000
1094
|
}
|
|
1001
1095
|
const holdable = gapHoldable({ gapHold: cfg.gapHold, remainingFrac: resolverRemainingFrac, minRemaining: resolveBudgetContinueMinRemaining(), planChars: verdict.plan.length, jevMode: cfg.gapHoldJev, jevFixable, jevMin: cfg.gapHoldJevMin });
|
|
1002
|
-
const checksFailed = namedFailed > 0 || specFailed > 0; // R166 + R174
|
|
1096
|
+
const checksFailed = namedFailed > 0 || specFailed > 0 || reqCounts.failed > 0; // R166 + R174 + R187
|
|
1003
1097
|
// R173c: a re-hold needs real work since the last hold (elapsed time or a changed open-items list), not just tool calls.
|
|
1004
1098
|
const msSinceLastHold = this.lastHoldMs > 0 ? Date.now() - this.lastHoldMs : null;
|
|
1005
1099
|
const holdProg = holdProgressed({ rejects: this.endTurnResolverRejects, msSinceLastHold, priorPlan: this.judgePriorPlan, plan: verdict.plan, minIntervalMs: cfg.gapHoldMinIntervalMs, maxSimilarity: cfg.gapHoldPlanMaxSimilarity });
|
|
@@ -1026,11 +1120,18 @@ export class CortexOrchestrator {
|
|
|
1026
1120
|
// R173c: the budget floor — below CORTEX_JUDGE_VETO_MIN_REMAINING nothing holds the finish (the gap is recorded).
|
|
1027
1121
|
const belowFloor = cfg.vetoMinRemaining > 0 && resolverRemainingFrac !== null && resolverRemainingFrac < cfg.vetoMinRemaining && action === 'veto';
|
|
1028
1122
|
action = applyVetoFloor(action, resolverRemainingFrac, cfg.vetoMinRemaining);
|
|
1123
|
+
// R187: a finish that would otherwise stand while a STATED requirement is still OPEN (its check never passed nor failed — never
|
|
1124
|
+
// exercised) is held once with the open lines named. Never below the budget floor; a FAILED line already went the R166 evidence way.
|
|
1125
|
+
let reqHold = null;
|
|
1126
|
+
if (cfg.reqLedger && this.reqLedger && action !== 'veto' && action !== 'escalate' && !belowFloor &&
|
|
1127
|
+
ledgerHoldable({ open: reqCounts.open, holdsUsed: this.reqLedgerHolds, maxHolds: cfg.reqLedgerHoldMax, remainingFrac: resolverRemainingFrac, minRemaining: cfg.vetoMinRemaining })) {
|
|
1128
|
+
reqHold = { message: formatLedgerHoldMessage({ entries: this.reqLedger, holdIndex: this.reqLedgerHolds + 1, maxHolds: cfg.reqLedgerHoldMax, remainingFrac: resolverRemainingFrac }) };
|
|
1129
|
+
}
|
|
1029
1130
|
// R176 HB-INDEPENDENT-DERIVATION: on a value-shaped task, before a finish that would otherwise STAND, recompute the result by a
|
|
1030
1131
|
// different method and hold ONCE on disagreement. Never below the budget floor; never more than once per turn.
|
|
1031
1132
|
let derivationHold = null;
|
|
1032
1133
|
let derivationInfo = null;
|
|
1033
|
-
if (cfg.derivation === 'on' && action !== 'veto' && action !== 'escalate' && this.derivationHolds < 1 && !belowFloor &&
|
|
1134
|
+
if (cfg.derivation === 'on' && !reqHold && action !== 'veto' && action !== 'escalate' && this.derivationHolds < 1 && !belowFloor &&
|
|
1034
1135
|
!(cfg.vetoMinRemaining > 0 && resolverRemainingFrac !== null && resolverRemainingFrac < cfg.vetoMinRemaining) && this.helperMiddleware.deriveIndependentCheck) {
|
|
1035
1136
|
const shape = isValueShapedTask(task);
|
|
1036
1137
|
derivationInfo = { valueShaped: shape.valueShaped, reason: shape.reason, artifacts: shape.artifacts };
|
|
@@ -1098,6 +1199,7 @@ export class CortexOrchestrator {
|
|
|
1098
1199
|
specTests: cfg.specTests, specChecks: this.specChecks?.length ?? 0, specRan, specPassed, specFailed, specInconclusive, specSuspect, specGenLatencyMs: this.specChecksMeta.genLatencyMs, specTestsAt: cfg.specTestsAt, // R174 / R174b
|
|
1099
1200
|
vetoMinRemaining: cfg.vetoMinRemaining, belowFloor, holdProgressed: holdProg, holdGapMs: msSinceLastHold, planSim: Number(planSimilarity(this.judgePriorPlan, verdict.plan).toFixed(3)), msSinceLastHold, // R173c
|
|
1100
1201
|
derivation: cfg.derivation, derivationAgreement: derivationInfo?.agreement ?? null, derivationHeld: !!derivationHold, // R176
|
|
1202
|
+
reqLedger: cfg.reqLedger, reqLines: reqCounts.lines, reqOpen: reqCounts.open, reqExercised: reqCounts.exercised, reqFailed: reqCounts.failed, reqUnverifiable: reqCounts.unverifiable, reqHeld: !!reqHold, reqHolds: this.reqLedgerHolds, reqGenLatencyMs: this.reqLedgerMeta.genLatencyMs, reqJev: cfg.reqLedgerJev, reqJevAsked: reqJev?.asked ?? 0, reqJevClosed: reqJev?.closed ?? [], reqJevLatencyMs: reqJev?.latencyMs ?? 0, // R187/R187b
|
|
1101
1203
|
latencyMs, rawLen: (text ?? '').length,
|
|
1102
1204
|
deltaChars: workspaceDelta.length, checkRan: !!checkResult, checkPassed: checkResult ? /→ PASSED/.test(checkResult) : null,
|
|
1103
1205
|
liftPlanChars: this.liftPlanText.length,
|
|
@@ -1137,10 +1239,20 @@ export class CortexOrchestrator {
|
|
|
1137
1239
|
`${verdict.plan}\n\nDo this, verify against the task's own criteria (not your own tests), then call EndTurn again.` +
|
|
1138
1240
|
(namedResultsNow ? `\n\nHARNESS-RUN CHECKS (named by the reviewer, executed just now — the failing ones are the gap):\n${namedResultsNow.slice(0, 3000)}` : '') + // R166
|
|
1139
1241
|
(specFailed > 0 ? `\n\nSPEC CHECKS (derived from the TASK text before your work was seen, executed just now — a FAILED one is a stated requirement not yet met):\n${specResults.slice(0, 3000)}` : '') + // R174
|
|
1242
|
+
(reqCounts.failed > 0 ? `\n\nREQUIREMENT LEDGER (stated requirements, checked just now — a FAILED line is a stated requirement not yet met):\n${reqResults.slice(0, 3000)}` : '') + // R187
|
|
1140
1243
|
(holdable && !checksFailed ? `\n\nNo harness-run check failed, but the reviewer named open items and budget remains — this hold returns them to you (hold ${this.endTurnResolverRejects}/${resolverCap}).` : '') + // R173
|
|
1141
1244
|
budgetedVetoEscalation(this.endTurnResolverRejects, resolverCap, resolverRemainingMs ?? 0, this.turnDeadlineMsActive); // R160
|
|
1142
1245
|
console.warn(`[EndTurnResolver] GAP — vetoed finish (${verdict.plan.length}-char plan, reject ${this.endTurnResolverRejects}/${resolverCap}${resolverRemainingFrac === null ? '' : `, budget remaining ${Math.round(resolverRemainingFrac * 100)}%`})`);
|
|
1143
1246
|
}
|
|
1247
|
+
else if (reqHold) {
|
|
1248
|
+
// R187: the finish would stand, but a stated requirement was never exercised — hold once with the open lines named.
|
|
1249
|
+
this.reqLedgerHolds += 1;
|
|
1250
|
+
this.lastHoldMs = Date.now();
|
|
1251
|
+
ev.endTurnCalled = false;
|
|
1252
|
+
et.is_error = true;
|
|
1253
|
+
et.content = reqHold.message;
|
|
1254
|
+
console.warn(`[EndTurnResolver] R187 LEDGER-HOLD — finish held (${reqCounts.open} open of ${reqCounts.lines} stated requirements; hold ${this.reqLedgerHolds}/${cfg.reqLedgerHoldMax})`);
|
|
1255
|
+
}
|
|
1144
1256
|
else if (derivationHold) {
|
|
1145
1257
|
// R176: the finish would stand, but an independent recomputation disagrees — hold once with both values shown.
|
|
1146
1258
|
this.derivationHolds += 1;
|
|
@@ -2136,6 +2248,11 @@ export class CortexOrchestrator {
|
|
|
2136
2248
|
this.specChecksMeta = { genLatencyMs: 0, refused: 0, raw: 0 };
|
|
2137
2249
|
this.specChecksPromise = null;
|
|
2138
2250
|
this.specFailHistory.clear();
|
|
2251
|
+
this.reqLedger = null;
|
|
2252
|
+
this.reqLedgerPromise = null;
|
|
2253
|
+
this.reqLedgerHolds = 0;
|
|
2254
|
+
this.reqLedgerMeta = { genLatencyMs: 0, raw: 0, refused: 0 };
|
|
2255
|
+
this.reqLedgerDelivered = false;
|
|
2139
2256
|
this.lastHoldMs = 0;
|
|
2140
2257
|
this.derivationHolds = 0; // R165 per-turn / R174 / R173c / R176
|
|
2141
2258
|
this.recordDsmlRecovery(currentAssistantCanonicalMessage);
|
|
@@ -3353,6 +3470,7 @@ export class CortexOrchestrator {
|
|
|
3353
3470
|
await this.deliverDeferredCorpusAtLift(effectiveModel);
|
|
3354
3471
|
this.deliverLiftNudge(allTools, effectiveModel); // A′ proposal-1: SearchTools/AskForAdvice signpost at lift
|
|
3355
3472
|
await this.deliverLiftPlanAtLift(effectiveModel); // LIFT_MENTOR_PLANNER: bounded mentor-planner at lift (dark unless CORTEX_LIFT_PLAN)
|
|
3473
|
+
this.maybeAuthorRequirementLedgerAtLift(); // R187: the stated-requirement ledger, authored in the background at lift
|
|
3356
3474
|
this.maybeAuthorSpecChecksAtLift(); // R174b: blind spec checks authored in the background at lift (CORTEX_JUDGE_SPEC_TESTS_AT=lift)
|
|
3357
3475
|
if (this.config.debug)
|
|
3358
3476
|
console.log('[Anchor] lifted at first tool_result boundary — session profile applies');
|
|
@@ -4350,6 +4468,11 @@ export class CortexOrchestrator {
|
|
|
4350
4468
|
this.specChecksMeta = { genLatencyMs: 0, refused: 0, raw: 0 };
|
|
4351
4469
|
this.specChecksPromise = null;
|
|
4352
4470
|
this.specFailHistory.clear();
|
|
4471
|
+
this.reqLedger = null;
|
|
4472
|
+
this.reqLedgerPromise = null;
|
|
4473
|
+
this.reqLedgerHolds = 0;
|
|
4474
|
+
this.reqLedgerMeta = { genLatencyMs: 0, raw: 0, refused: 0 };
|
|
4475
|
+
this.reqLedgerDelivered = false;
|
|
4353
4476
|
this.lastHoldMs = 0;
|
|
4354
4477
|
this.derivationHolds = 0; // R165 per-turn / R174 / R173c / R176
|
|
4355
4478
|
this.recordDsmlRecovery(currentAssistantCanonicalMessage);
|
|
@@ -5150,6 +5273,7 @@ export class CortexOrchestrator {
|
|
|
5150
5273
|
await this.deliverDeferredCorpusAtLift(effectiveModel);
|
|
5151
5274
|
this.deliverLiftNudge(allTools, effectiveModel); // A′ proposal-1: SearchTools/AskForAdvice signpost at lift
|
|
5152
5275
|
await this.deliverLiftPlanAtLift(effectiveModel); // LIFT_MENTOR_PLANNER: bounded mentor-planner at lift (dark unless CORTEX_LIFT_PLAN)
|
|
5276
|
+
this.maybeAuthorRequirementLedgerAtLift(); // R187: the stated-requirement ledger, authored in the background at lift
|
|
5153
5277
|
this.maybeAuthorSpecChecksAtLift(); // R174b: blind spec checks authored in the background at lift (CORTEX_JUDGE_SPEC_TESTS_AT=lift)
|
|
5154
5278
|
if (this.config.debug)
|
|
5155
5279
|
console.log('[Anchor] lifted at first tool_result boundary — session profile applies');
|