instar 1.3.1211 → 1.3.1213

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.
Files changed (45) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +12 -0
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/BetweenWindowAdmissionGate.d.ts +2 -0
  5. package/dist/core/BetweenWindowAdmissionGate.d.ts.map +1 -1
  6. package/dist/core/BetweenWindowAdmissionGate.js +2 -0
  7. package/dist/core/BetweenWindowAdmissionGate.js.map +1 -1
  8. package/dist/core/PeerEndpointRecorder.d.ts +30 -0
  9. package/dist/core/PeerEndpointRecorder.d.ts.map +1 -1
  10. package/dist/core/PeerEndpointRecorder.js +53 -3
  11. package/dist/core/PeerEndpointRecorder.js.map +1 -1
  12. package/dist/core/WindowLifecycleObligationLedger.d.ts +382 -0
  13. package/dist/core/WindowLifecycleObligationLedger.d.ts.map +1 -0
  14. package/dist/core/WindowLifecycleObligationLedger.js +734 -0
  15. package/dist/core/WindowLifecycleObligationLedger.js.map +1 -0
  16. package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
  17. package/dist/core/WriteDomainRegistry.js +7 -0
  18. package/dist/core/WriteDomainRegistry.js.map +1 -1
  19. package/dist/data/standards-guard-index.json +1 -1
  20. package/dist/data/standards-guard-index.meta.json +2 -2
  21. package/dist/data/standards-registry.meta.json +1 -1
  22. package/dist/monitoring/SessionWatchdog.d.ts +29 -0
  23. package/dist/monitoring/SessionWatchdog.d.ts.map +1 -1
  24. package/dist/monitoring/SessionWatchdog.js +52 -0
  25. package/dist/monitoring/SessionWatchdog.js.map +1 -1
  26. package/dist/server/AgentServer.d.ts +5 -0
  27. package/dist/server/AgentServer.d.ts.map +1 -1
  28. package/dist/server/AgentServer.js +22 -0
  29. package/dist/server/AgentServer.js.map +1 -1
  30. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  31. package/dist/server/CapabilityIndex.js +25 -0
  32. package/dist/server/CapabilityIndex.js.map +1 -1
  33. package/dist/server/routes.d.ts +5 -0
  34. package/dist/server/routes.d.ts.map +1 -1
  35. package/dist/server/routes.js +806 -1
  36. package/dist/server/routes.js.map +1 -1
  37. package/package.json +1 -1
  38. package/src/data/builtin-manifest.json +47 -47
  39. package/src/data/standards-guard-index.json +1 -1
  40. package/src/data/standards-guard-index.meta.json +2 -2
  41. package/src/data/standards-registry.meta.json +1 -1
  42. package/upgrades/1.3.1212.md +28 -0
  43. package/upgrades/1.3.1213.md +45 -0
  44. package/upgrades/side-effects/mesh-endpoint-degradation-retention.md +106 -0
  45. package/upgrades/side-effects/window-lifecycle-obligation-ledger.md +94 -0
@@ -8,7 +8,7 @@ import { Router } from 'express';
8
8
  import { telegramFetch } from '../messaging/telegram-egress.js';
9
9
  import { emergencyStopUserMessage } from '../messaging/shared/emergencyStopUserMessage.js';
10
10
  import { execFileSync } from 'node:child_process';
11
- import { createHash, timingSafeEqual, randomUUID } from 'node:crypto';
11
+ import { createHash, createHmac, timingSafeEqual, randomBytes, randomUUID } from 'node:crypto';
12
12
  import { governor as selfActionGovernorSurface } from '../monitoring/selfaction/governor.js';
13
13
  import { classifyActionClaim } from '../core/action-claim.js';
14
14
  import { sharedG3SoakLedger, decideLeaseGatedSpawn } from '../core/leaseGatedSpawn.js';
@@ -145,6 +145,8 @@ import { ATTENTION_PRIORITIES, ATTENTION_STATUSES, normalizeAttentionPriority, n
145
145
  import { dashboardRefreshFailure } from './DashboardRefreshDiagnostics.js';
146
146
  import { formatLocalTimestamp } from '../utils/localTime.js';
147
147
  import { evaluateBetweenWindowAdmission } from '../core/BetweenWindowAdmissionGate.js';
148
+ import { signMessage as signAgentMessage, verifyMessage as verifyAgentSignature } from '../core/agentSignatureProvenance.js';
149
+ import { WINDOW_LEDGER_AGENT, WINDOW_LEDGER_SCOPE, EchoWindowLedgerStore, ProductionMessageEvidenceAuthority, ProductionRuntimeRegistry, compileWindowSources, createLedger, evaluateFromAuthorities, evaluateClosure, transitionLedger, runNativeAdmissionAdapter, applyWaiver, evaluateLifecycleTick, admissionSnapshotDigest, sourceFreshnessIssues, evaluateLifecycleGuard, deriveFailureRemediation, runWindowLifecyclePostLiveCheck, bindRuntimeAuthority, evaluateExecutor, REQUIRED_WINDOW_DUTIES, WINDOW_DRY_RUN_INVENTORY, } from '../core/WindowLifecycleObligationLedger.js';
148
150
  const execFile = promisify(execFileCb);
149
151
  /**
150
152
  * Per-session continue-ceiling (spec § (b) Outcomes).
@@ -1069,6 +1071,809 @@ export function createRoutes(ctx) {
1069
1071
  });
1070
1072
  return res.status(result.admitted ? 200 : 409).json(result);
1071
1073
  });
1074
+ // @write-domain:machine-local — Echo-only Window-28 lifecycle authority.
1075
+ // Every handler validates immutable agent/scope before touching its local store.
1076
+ const windowRequestScope = (body) => {
1077
+ const b = body;
1078
+ return b?.agentId === WINDOW_LEDGER_AGENT && b.scope === WINDOW_LEDGER_SCOPE && ctx.config.projectName === WINDOW_LEDGER_AGENT;
1079
+ };
1080
+ const windowStore = new EchoWindowLedgerStore(ctx.config.stateDir);
1081
+ const windowNow = () => ctx.windowLifecycleNow?.() ?? new Date().toISOString();
1082
+ const runtimeRegistry = () => new ProductionRuntimeRegistry(() => {
1083
+ const running = ctx.sessionManager.listRunningSessions();
1084
+ const duties = new Map((windowStore.load(WINDOW_LEDGER_AGENT, WINDOW_LEDGER_SCOPE)?.obligations ?? []).map(duty => [duty.id, duty]));
1085
+ return (ctx.commitmentTracker?.getAll() ?? []).flatMap(commitment => {
1086
+ if (!commitment.externalKey || !commitment.beaconEnabled)
1087
+ return [];
1088
+ const duty = duties.get(commitment.externalKey);
1089
+ if (!duty || !commitment.createdAt || !Number.isFinite(Date.parse(commitment.createdAt)) || Date.parse(commitment.createdAt) > Date.parse(duty.deadline.dueAt))
1090
+ return [];
1091
+ const session = commitment.sessionEpoch ? running.find(s => s.claudeSessionId === commitment.sessionEpoch) : undefined;
1092
+ const driverPath = commitment.topicId === undefined ? null : path.join(ctx.config.stateDir, 'autonomous', `active-${commitment.topicId}.json`);
1093
+ let driverPresent = false;
1094
+ let driverMatches = false;
1095
+ if (driverPath) {
1096
+ try {
1097
+ const driver = JSON.parse(fs.readFileSync(driverPath, 'utf8'));
1098
+ driverPresent = true;
1099
+ driverMatches = String(driver.topic) === String(commitment.topicId) && driver.windowId === duty.windowId && driver.status !== 'stopped';
1100
+ }
1101
+ catch { /* @silent-fallback-ok — unreadable authority fails closed as not live */ }
1102
+ }
1103
+ const completionMature = commitment.status === 'delivered' && !!commitment.resolvedAt && Date.parse(commitment.resolvedAt) <= Date.parse(windowNow());
1104
+ return [{ executorId: commitment.id, owner: commitment.boundBy ?? 'server:commitment-tracker', kind: 'commitment-beacon', registryCoordinates: `obligation:${commitment.externalKey}`,
1105
+ enabled: commitment.beaconEnabled === true, dryRun: false, running: !!session, heartbeatAt: commitment.lastHeartbeatAt,
1106
+ nextAttemptAt: commitment.nextUpdateDueAt, deliversOutput: true, sinkReachable: ctx.telegram !== null,
1107
+ suppressionActive: commitment.beaconSuppressed === true || commitment.beaconPaused === true,
1108
+ needsClientDriver: true, driverPresent, driverMatches,
1109
+ triggerEnabled: commitment.status === 'pending' && !!commitment.checkInAt, durableTriggerState: !!commitment.checkInAt, eligibilityAt: commitment.checkInAt,
1110
+ assignedAt: commitment.createdAt, completedAt: completionMature ? commitment.resolvedAt : undefined, completionDigest: completionMature ? createHash('sha256').update(`${commitment.id}:${commitment.resolvedAt}:${commitment.deliveryMessageId ?? ''}`).digest('hex') : undefined, deliveryMessageId: commitment.deliveryMessageId, deliveryTopicId: commitment.topicId }];
1111
+ });
1112
+ });
1113
+ const messageEvidenceAuthority = () => new ProductionMessageEvidenceAuthority(path.join(ctx.config.stateDir, 'telegram-messages.jsonl'), (topicId, messageId) => {
1114
+ const row = ctx.telegram?.getTopicHistory(topicId, 1_000).find(item => item.messageId === messageId);
1115
+ if (!row || row.topicId === null)
1116
+ return null;
1117
+ const operator = ctx.topicOperatorStore?.asVerifiedOperator(topicId);
1118
+ const verifiedOperator = !!operator && String(row.telegramUserId) === String(operator.uid) && row.fromUser && row.forwarded === false;
1119
+ return { messageId: row.messageId, topicId: row.topicId, text: row.text, fromUser: row.fromUser, timestamp: row.timestamp, senderUid: row.telegramUserId === undefined ? undefined : String(row.telegramUserId), verifiedOperator, sessionName: row.sessionName, provenance: row.provenance, authorship: row.authorship };
1120
+ });
1121
+ const runtimeSemanticFacts = (obligation) => {
1122
+ if (/^start\.(?:named-worker-lanes|delegation-majority-boundary|machine-model-distribution)$/.test(obligation.id)) {
1123
+ const charterPath = obligation.sourceSpans.map(span => span.source).find(source => /CHARTER/i.test(path.basename(source))) ?? path.join(ctx.config.stateDir, obligation.windowId, `WINDOW-${obligation.windowId.replace(/^w/i, '')}-CHARTER.md`);
1124
+ let charter = '';
1125
+ try {
1126
+ if (charterPath)
1127
+ charter = fs.readFileSync(charterPath, 'utf8');
1128
+ }
1129
+ catch { /* @silent-fallback-ok — unavailable authority fails closed as empty */ }
1130
+ const laneIds = [...new Set(Array.from(charter.matchAll(/\bLane\s+([A-Z])\b/g), match => match[1]))];
1131
+ const workerRecords = ctx.subagentTracker ? ctx.subagentTracker.listSessions().flatMap(sessionId => ctx.subagentTracker.getSessionRecords(sessionId)).filter(record => /codey|worker/i.test(`${record.agentType} ${record.agentId}`)) : [];
1132
+ const machines = ctx.listPoolMachines?.() ?? [];
1133
+ const blocker = charter.match(/(?:offline|unavailable|memory pressure|blocked)[^.\n]*/i)?.[0] ?? '';
1134
+ const workerAssignments = workerRecords.flatMap(record => { const laneId = record.agentType.match(/lane[- :]+([A-Z])/i)?.[1]?.toUpperCase(); const machineId = record.agentType.match(/machine[- :]+([A-Za-z0-9_-]+)/i)?.[1]; if (!laneId || !machineId || !record.transcriptPath || !record.startedAt || (!record.stoppedAt && !ctx.sessionManager.listRunningSessions().some(session => session.claudeSessionId === record.sessionId)))
1135
+ return []; try {
1136
+ const bytes = fs.readFileSync(record.transcriptPath);
1137
+ if (!bytes.length)
1138
+ return [];
1139
+ return [{ workerId: record.agentId, laneId, machineId, transcriptHash: createHash('sha256').update(bytes).digest('hex'), transcriptBytes: bytes.length }];
1140
+ }
1141
+ catch { /* @silent-fallback-ok — absent worker transcript is negative authority */
1142
+ return [];
1143
+ } });
1144
+ const poolIds = new Set(machines.map(machine => machine.machineId));
1145
+ const unavailableNamed = blocker.match(/\b(?:laptop|mini|studio|[A-Za-z0-9_-]+)\b/i)?.[0]?.toLowerCase();
1146
+ const machineBlockerVerified = !!blocker && !!unavailableNamed && !machines.some(machine => machine.machineId.toLowerCase() === unavailableNamed || machine.nickname?.toLowerCase() === unavailableNamed) && machines.every(machine => machine.lastKnownUrl !== null);
1147
+ if (obligation.id === 'start.named-worker-lanes')
1148
+ return { laneIds, laneSourceHash: charter ? createHash('sha256').update(charter).digest('hex') : '' };
1149
+ if (obligation.id === 'start.delegation-majority-boundary')
1150
+ return { workerAssignments, offloadedLaneShare: laneIds.length ? new Set(workerAssignments.map(item => item.laneId)).size / laneIds.length : 0, laneIds };
1151
+ return { workerAssignments: workerAssignments.filter(item => poolIds.has(item.machineId)), machineIds: machines.map(machine => machine.machineId), namedBlocker: blocker, machineBlockerVerified };
1152
+ }
1153
+ if (obligation.id === 'continuous.telegram.profile-resolved') {
1154
+ const registry = ctx.playwrightRegistry?.() ?? new PlaywrightProfileRegistry({ stateDir: ctx.config.stateDir, projectDir: ctx.config.projectDir, listVaultNames: () => [] });
1155
+ const resolved = registry.resolve('telegram');
1156
+ const profile = resolved.profile;
1157
+ if (profile && profile.id === obligation.predicate.expected?.profile && resolved.dirExists !== false)
1158
+ return { profile: profile.id, profileAuthority: 'playwright-profile-registry' };
1159
+ return {};
1160
+ }
1161
+ if (obligation.id === 'continuous.telegram.signature-verified') {
1162
+ try {
1163
+ const raw = JSON.parse(fs.readFileSync(path.join(ctx.config.stateDir, 'identity.json'), 'utf8'));
1164
+ if (typeof raw.publicKey !== 'string')
1165
+ return {};
1166
+ const key = Buffer.from(raw.publicKey, 'base64');
1167
+ const fingerprint = key.toString('hex').slice(0, 32);
1168
+ return key.length === 32 && fingerprint === obligation.predicate.expected?.fingerprint ? { signatureVerified: true, fingerprint } : {};
1169
+ }
1170
+ catch { /* @silent-fallback-ok — missing identity is a fail-closed negative */
1171
+ return {};
1172
+ }
1173
+ }
1174
+ return {};
1175
+ };
1176
+ const verifyEchoSignedOutbound = (row) => {
1177
+ if (row.fromUser || row.authorship !== 'agent-outbound' || row.topicId === null)
1178
+ return null;
1179
+ try {
1180
+ const raw = JSON.parse(fs.readFileSync(path.join(ctx.config.stateDir, 'identity.json'), 'utf8'));
1181
+ if (typeof raw.publicKey !== 'string')
1182
+ return null;
1183
+ const key = Buffer.from(raw.publicKey, 'base64');
1184
+ const verdict = verifyAgentSignature({ raw: row.text, expectedTopicId: row.topicId, resolvePublicKey: agentId => agentId === 'echo' ? key : null, nowSeconds: Math.floor(Date.parse(windowNow()) / 1000) });
1185
+ return verdict.classification === 'agent-verified' && verdict.agentId === 'echo' ? verdict : null;
1186
+ }
1187
+ catch { /* @silent-fallback-ok — signature uncertainty fails closed */
1188
+ return null;
1189
+ }
1190
+ };
1191
+ const isHighLevelSynthesis = (text) => text.trim().length >= 120 && /\b(?:synthesis|summary)\b/i.test(text) && /\b(?:progress|completed|landed)\b/i.test(text) && /\b(?:blocker|risk|none)\b/i.test(text) && /\bnext\b/i.test(text);
1192
+ const parseCanonicalPlanPosition = (markdown) => { const nodeId = markdown.match(/^Node-ID:\s*([A-Za-z0-9_-]+)\s*$/m)?.[1]; const charterId = markdown.match(/^Charter-ID:\s*([A-Za-z0-9_-]+)\s*$/m)?.[1]; const pathIds = markdown.match(/^Leaf-to-root:\s*([A-Za-z0-9_-]+(?:\s*>\s*[A-Za-z0-9_-]+)+)\s*$/m)?.[1]?.split(/\s*>\s*/); return nodeId && charterId && pathIds?.[0] === nodeId && pathIds.at(-1) === 'root' ? { nodeId, charterId, pathIds } : null; };
1193
+ const stallInspectionPath = path.join(ctx.config.stateDir, 'window-lifecycle', 'stall-inspections.jsonl');
1194
+ const remediationPath = path.join(ctx.config.stateDir, 'window-lifecycle', 'remediations.jsonl');
1195
+ const readRemediationEpisodes = () => { try {
1196
+ return fs.readFileSync(remediationPath, 'utf8').trim().split('\n').filter(Boolean).map(line => JSON.parse(line));
1197
+ }
1198
+ catch { /* @silent-fallback-ok — no readable episodes grants no exemption */
1199
+ return [];
1200
+ } };
1201
+ const remediationEpisodeDigest = (obligation) => createHash('sha256').update(JSON.stringify({ windowId: obligation.windowId, obligationId: obligation.id, action: obligation.failureAction, status: obligation.status, evidenceNonces: obligation.evidence.map(item => item.nonce).sort() })).digest('hex');
1202
+ const remediationResolutionIsLive = (obligation, episode) => {
1203
+ if (episode.disposition !== 'resolved-with-live-evidence' || !episode.topicId || !episode.messageId || !episode.evidenceHash || !episode.resolvedAt)
1204
+ return false;
1205
+ const row = ctx.telegram?.getTopicHistory(episode.topicId, 1_000).find(item => item.messageId === episode.messageId);
1206
+ if (!row || Date.parse(row.timestamp) <= Date.parse(episode.createdAt) || Date.parse(row.timestamp) > Date.parse(windowNow()) || createHash('sha256').update(row.text).digest('hex') !== episode.evidenceHash)
1207
+ return false;
1208
+ const remediation = deriveFailureRemediation(obligation);
1209
+ const signed = !row.fromUser ? verifyEchoSignedOutbound(row) : null;
1210
+ const correctedCounts = obligation.failureAction === 'correct-before-report' && /corrected counts?:/i.test(row.text) && /\bsource:/i.test(row.text) && /\b[A-Za-z][\w -]*\s*=\s*\d+\b/.test(row.text);
1211
+ const replacementSynthesis = obligation.failureAction === 'correct-next-synthesis' && isHighLevelSynthesis(row.text);
1212
+ return remediation.repostRequired ? episode.topicId === 43003 && !!signed && row.text.length >= 80 && /\b(?:coordination|assessment|disagreement)\b/i.test(row.text) : remediation.correctionRequired ? episode.topicId === 36966 && !!signed && (correctedCounts || replacementSynthesis) : remediation.scopeReviewRequired && row.fromUser && episode.topicId === 36966 && String(row.telegramUserId) === String(ctx.topicOperatorStore?.asVerifiedOperator(episode.topicId)?.uid) && /\bscope\b/i.test(row.text) && /\b(?:continue|stop|timebox)\b/i.test(row.text);
1213
+ };
1214
+ const stallInspectionDigest = (row) => createHash('sha256').update(JSON.stringify(row)).digest('hex');
1215
+ const readStallInspection = (obligationId) => { try {
1216
+ const rows = fs.readFileSync(stallInspectionPath, 'utf8').trim().split('\n').filter(Boolean).map(line => JSON.parse(line)).reverse();
1217
+ const row = rows.find(item => item.obligationId === obligationId);
1218
+ if (!row)
1219
+ return null;
1220
+ const { inspectionHash, ...payload } = row;
1221
+ return inspectionHash === stallInspectionDigest(payload) ? row : null;
1222
+ }
1223
+ catch { /* @silent-fallback-ok — unreadable inspection cannot prove completion */
1224
+ return null;
1225
+ } };
1226
+ const ensureStallInspection = (obligation) => { if (!/^cadence\.stall-check\.30m@/.test(obligation.id) || Date.parse(windowNow()) > Date.parse(obligation.deadline.dueAt) + obligation.deadline.graceMs || !ctx.watchdog?.isEnabled())
1227
+ return null; const activeSessionIds = ctx.sessionManager.listRunningSessions().map(session => session.tmuxSession).sort(); const observation = ctx.watchdog.inspectSessionsForStall(windowNow()); const watchdogIds = observation.sessions.map(session => session.name).sort(); if (!ctx.watchdog.verifyStallInspection(observation) || !Number.isSafeInteger(observation.pollRevision) || observation.pollRevision < 1 || observation.observedAt !== windowNow() || JSON.stringify(activeSessionIds) !== JSON.stringify(watchdogIds) || observation.sessions.some(session => typeof session.outputObserved !== 'boolean' || typeof session.escalationActive !== 'boolean' || session.decisionEvaluated !== true || typeof session.decisionEvaluatedAt !== 'string' || Date.parse(session.decisionEvaluatedAt) < Date.parse(obligation.deadline.dueAt)))
1228
+ return null; const payload = { obligationId: obligation.id, inspectedAt: observation.observedAt, watchdogPollRevision: observation.pollRevision, watchdogAuthorityEpoch: observation.authorityEpoch, watchdogAuthorityProof: observation.authorityProof, activeSessionIds, inspectedSessionIds: watchdogIds, sessionResults: observation.sessions, watchdogEnabled: true }; const row = { ...payload, inspectionHash: stallInspectionDigest(payload) }; fs.mkdirSync(path.dirname(stallInspectionPath), { recursive: true, mode: 0o700 }); fs.appendFileSync(stallInspectionPath, `${JSON.stringify(row)}\n`, { mode: 0o600 }); return row; };
1229
+ const runtimeCompletionProof = (obligation, real) => { const base = { executorId: real.executorId, completedAt: real.completedAt, completionDigest: real.completionDigest }; if (!/^cadence\.stall-check\.30m@/.test(obligation.id))
1230
+ return { runtimeCompletion: base }; const inspection = readStallInspection(obligation.id); if (!inspection || !ctx.watchdog?.isEnabled())
1231
+ return null; const authorityValid = ctx.watchdog.verifyStallInspection({ observedAt: inspection.inspectedAt, authorityEpoch: inspection.watchdogAuthorityEpoch, pollRevision: inspection.watchdogPollRevision, authorityProof: inspection.watchdogAuthorityProof, sessions: inspection.sessionResults }); return authorityValid ? { runtimeCompletion: base, ...inspection } : null; };
1232
+ const proofPayload = (obligation, extra = {}) => JSON.stringify({ obligationId: obligation.id, verdict: 'pass', sourceHashes: obligation.sourceSpans.map(s => s.hash), ...obligation.predicate.expected, ...runtimeSemanticFacts(obligation), ...extra });
1233
+ const deterministicPayload = (ledger, obligation) => {
1234
+ if (sourceFreshnessIssues(ledger).length)
1235
+ return null;
1236
+ if (obligation.id === 'start.compilation-proof')
1237
+ return REQUIRED_WINDOW_DUTIES.every(d => ledger.compiledObligationIds.includes(d.id)) ? proofPayload(obligation, { compiledIds: ledger.compiledObligationIds }) : null;
1238
+ if (obligation.id === 'continuous.derive-counts')
1239
+ return proofPayload(obligation, { counts: [{ name: 'compiled', value: ledger.compiledObligationIds.length, items: ledger.compiledObligationIds }, { name: 'materialized', value: ledger.obligations.length, items: ledger.obligations.map(o => o.id) }] });
1240
+ if (obligation.id === 'close.plan-staleness-guard') {
1241
+ const planId = obligation.predicate.expected?.canonicalPlanId;
1242
+ const view = planId ? ctx.viewer?.get(planId) : null;
1243
+ const outcome = ledger.obligations.find(o => o.id === 'close.plan-outcome.semantic-diff')?.evidence.find(e => e.verifierPassed);
1244
+ if (!view || !outcome?.verifiedPayload)
1245
+ return null;
1246
+ let proof;
1247
+ try {
1248
+ proof = JSON.parse(outcome.verifiedPayload);
1249
+ }
1250
+ catch { /* @silent-fallback-ok — malformed proof fails closed */
1251
+ return null;
1252
+ }
1253
+ const version = view.updatedAt ?? view.createdAt;
1254
+ if (proof.canonicalPlanId !== planId || proof.planVersionAtOutcome !== version || Date.parse(outcome.timestamp) < Date.parse(version))
1255
+ return null;
1256
+ return proofPayload(obligation, { planNodeId: proof.planNodeId, charterIncluded: proof.charterIncluded, canonicalPlanId: planId, planVersionAtOutcome: version });
1257
+ }
1258
+ if (obligation.id === 'close.consumer-proof') {
1259
+ const check = runWindowLifecyclePostLiveCheck(ledger);
1260
+ return check.passed ? proofPayload(obligation, { consumerObserved: true, consumerCheck: check }) : null;
1261
+ }
1262
+ if (obligation.id === 'close.terminal-census') {
1263
+ const others = ledger.obligations.filter(o => o.id !== obligation.id && o.phase !== 'post-live');
1264
+ if (!others.every(o => ['satisfied', 'waived-for-phase-transition', 'waived-for-debt'].includes(o.status)) || ledger.compiledObligationIds.some(id => !ledger.obligations.some(o => o.id === id)))
1265
+ return null;
1266
+ return proofPayload(obligation, { expectedIds: ledger.compiledObligationIds, actualIds: ledger.obligations.map(o => o.id) });
1267
+ }
1268
+ if (obligation.id === 'postlive.verdict.pass-required') {
1269
+ if (ledger.state !== 'delivered_pending_post_live' || !ledger.obligations.filter(o => o.id !== obligation.id).every(o => ['satisfied', 'waived-for-phase-transition', 'waived-for-debt'].includes(o.status)))
1270
+ return null;
1271
+ const check = runWindowLifecyclePostLiveCheck(ledger);
1272
+ return check.passed ? proofPayload(obligation, { postLivePassed: true, ...check }) : null;
1273
+ }
1274
+ return null;
1275
+ };
1276
+ const evidenceAuthority = () => ({ requery: (record) => {
1277
+ const ledger = windowStore.load(WINDOW_LEDGER_AGENT, WINDOW_LEDGER_SCOPE);
1278
+ const native = ledger?.nativeEvaluations.find(item => item.nonce === record.nonce);
1279
+ const obligation = ledger?.obligations.find(o => o.id === record.obligationId);
1280
+ if (record.authority === 'runtime-registry-proof' && obligation) {
1281
+ const real = runtimeRegistry().resolve(obligation.executorBinding.executorId, obligation.id);
1282
+ if (!real)
1283
+ return null;
1284
+ const requiresCompletion = obligation.predicate.recurring === true || obligation.id.includes('@');
1285
+ let payload;
1286
+ if (requiresCompletion) {
1287
+ if (!real.completedAt || !real.completionDigest || Date.parse(real.completedAt) > Date.parse(obligation.deadline.dueAt) + obligation.deadline.graceMs)
1288
+ return null;
1289
+ const completion = runtimeCompletionProof(obligation, real);
1290
+ if (!completion)
1291
+ return null;
1292
+ payload = proofPayload(obligation, completion);
1293
+ }
1294
+ else {
1295
+ const bound = bindRuntimeAuthority(obligation, runtimeRegistry());
1296
+ if (evaluateExecutor(bound, windowNow()).issues.length)
1297
+ return null;
1298
+ payload = proofPayload(obligation, { runtimeSnapshot: { executorId: real.executorId, registryCoordinates: real.registryCoordinates, heartbeatAt: real.heartbeatAt, nextAttemptAt: real.nextAttemptAt, running: real.running, driverPresent: real.driverPresent, driverMatches: real.driverMatches } });
1299
+ }
1300
+ if (createHash('sha256').update(payload).digest('hex') !== record.canonicalPayloadHash)
1301
+ return null;
1302
+ return { ...record, verifierPassed: true, verifiedPayload: payload };
1303
+ }
1304
+ if (record.authority === 'deterministic-replay' && obligation) {
1305
+ const payload = deterministicPayload(ledger, obligation);
1306
+ if (!payload || createHash('sha256').update(payload).digest('hex') !== record.canonicalPayloadHash)
1307
+ return null;
1308
+ return { ...record, verifierPassed: true, verifiedPayload: payload };
1309
+ }
1310
+ if (record.authority === 'content-bound-store-row' && obligation && record.nativeCoordinates?.storePath) {
1311
+ try {
1312
+ const bytes = fs.readFileSync(record.nativeCoordinates.storePath);
1313
+ if (!obligation.sourceSpans.some(s => s.source === record.nativeCoordinates.storePath && s.hash === createHash('sha256').update(bytes).digest('hex')))
1314
+ return null;
1315
+ const payload = proofPayload(obligation, { charterExpiry: obligation.predicate.expected?.charterExpiry });
1316
+ if (createHash('sha256').update(payload).digest('hex') !== record.canonicalPayloadHash)
1317
+ return null;
1318
+ return { ...record, verifierPassed: true, verifiedPayload: payload };
1319
+ }
1320
+ catch { /* @silent-fallback-ok — store read uncertainty fails closed */
1321
+ return null;
1322
+ }
1323
+ }
1324
+ if (record.authority !== 'native-local-store-presence') {
1325
+ const verified = messageEvidenceAuthority().requery(record);
1326
+ if (!verified || !obligation || verified.authority === 'content-bound-store-row')
1327
+ return verified;
1328
+ const coords = record.nativeCoordinates;
1329
+ const row = coords?.topicId !== undefined && coords.messageId !== undefined ? ctx.telegram?.getTopicHistory(coords.topicId, 1_000).find(item => item.messageId === coords.messageId) : undefined;
1330
+ if (!row)
1331
+ return null;
1332
+ const agentAuthorship = row.authorship === 'agent-outbound' || row.authorship === 'agent-verified';
1333
+ const assignedProducer = obligation.executorBinding.owner;
1334
+ const producerMatchesAssignment = typeof assignedProducer === 'string' && assignedProducer === record.producer && record.producer === `session:${row.sessionName ?? 'unknown'}`;
1335
+ if (verified.authority === 'verified-operator-approval')
1336
+ return row.fromUser && row.forwarded === false ? verified : null;
1337
+ if (/^continuous\.telegram\.(?:send-path-classified|signature-verified|act-as-principal-guard)$/.test(obligation.id)) {
1338
+ const signed = verifyEchoSignedOutbound(row);
1339
+ if (!signed || row.forwarded !== false || row.topicId !== 36966 || !producerMatchesAssignment)
1340
+ return null;
1341
+ return { ...verified, verifiedPayload: proofPayload(obligation, { signedMessageId: row.messageId, signedTopicId: row.topicId, signedAgentId: signed.agentId, signatureVerified: true, principalRiskCleared: true }) };
1342
+ }
1343
+ if (/^cadence\.report\.3h@/.test(obligation.id)) {
1344
+ if (!agentAuthorship || !producerMatchesAssignment || row.forwarded !== false || row.topicId !== 36966 || !isHighLevelSynthesis(row.text))
1345
+ return null;
1346
+ return { ...verified, verifiedPayload: proofPayload(obligation, { deliveredTopicId: row.topicId, deliveryMessageId: row.messageId, reportBodyHash: createHash('sha256').update(row.text).digest('hex'), synthesisSectionsVerified: true }) };
1347
+ }
1348
+ if (/plan-(?:input|position|outcome)/.test(obligation.id)) {
1349
+ let claim;
1350
+ try {
1351
+ claim = JSON.parse(row.text);
1352
+ }
1353
+ catch {
1354
+ return null;
1355
+ }
1356
+ const planId = obligation.predicate.expected?.canonicalPlanId;
1357
+ const view = typeof planId === 'string' ? ctx.viewer?.get(planId) : null;
1358
+ const position = view ? parseCanonicalPlanPosition(view.markdown) : null;
1359
+ if (!view || !position || claim.canonicalPlanId !== planId || claim.planNodeId !== position.nodeId || claim.charterIncluded !== true || position.charterId !== obligation.windowId || JSON.stringify(claim.leafToRoot) !== JSON.stringify(position.pathIds))
1360
+ return null;
1361
+ }
1362
+ const roleOk = obligation.responsibleRole === 'echo' ? agentAuthorship && producerMatchesAssignment : obligation.responsibleRole.startsWith('observer-') ? agentAuthorship && row.topicId === 43003 && producerMatchesAssignment : true;
1363
+ return roleOk ? verified : null;
1364
+ }
1365
+ if (!native || native.windowId !== record.windowId || native.inputHash !== record.canonicalPayloadHash || native.output.admitted !== true)
1366
+ return null;
1367
+ try {
1368
+ const current = fs.readFileSync(native.storePath);
1369
+ if (current.length < native.storeBytesLength || createHash('sha256').update(current.subarray(0, native.storeBytesLength)).digest('hex') !== native.storeHash)
1370
+ return null;
1371
+ }
1372
+ catch { /* @silent-fallback-ok — native store uncertainty fails closed */
1373
+ return null;
1374
+ }
1375
+ return { ...record, verifierPassed: true, verifiedPayload: JSON.stringify(native.output) };
1376
+ } });
1377
+ const materializeMachineEvidence = (ledger) => {
1378
+ for (const obligation of ledger.obligations.filter(o => ['pending', 'unknown', 'open-unexecuted', 'blocked', 'failed'].includes(o.status) && (!o.eligibleAt || Date.parse(o.eligibleAt) <= Date.parse(windowNow())))) {
1379
+ let payload = null;
1380
+ let producer = '';
1381
+ let storePath;
1382
+ if (obligation.evidencePolicy.requiredAuthority === 'runtime-registry-proof') {
1383
+ const bound = bindRuntimeAuthority(obligation, runtimeRegistry());
1384
+ const real = runtimeRegistry().resolve(bound.executorBinding.executorId, obligation.id);
1385
+ if (!real)
1386
+ continue;
1387
+ const requiresCompletion = obligation.predicate.recurring === true || obligation.id.includes('@');
1388
+ if (requiresCompletion) {
1389
+ if (!real.completedAt || !real.completionDigest || Date.parse(real.completedAt) > Date.parse(obligation.deadline.dueAt) + obligation.deadline.graceMs)
1390
+ continue;
1391
+ if (/^cadence\.stall-check\.30m@/.test(obligation.id) && !ensureStallInspection(obligation))
1392
+ continue;
1393
+ const completion = runtimeCompletionProof(obligation, real);
1394
+ if (!completion)
1395
+ continue;
1396
+ payload = proofPayload(obligation, completion);
1397
+ }
1398
+ else {
1399
+ if (evaluateExecutor(bound, windowNow()).issues.length)
1400
+ continue;
1401
+ payload = proofPayload(obligation, { runtimeSnapshot: { executorId: real.executorId, registryCoordinates: real.registryCoordinates, heartbeatAt: real.heartbeatAt, nextAttemptAt: real.nextAttemptAt, running: real.running, driverPresent: real.driverPresent, driverMatches: real.driverMatches } });
1402
+ }
1403
+ obligation.executorBinding = bound.executorBinding;
1404
+ producer = `executor:${bound.executorBinding.executorId}`;
1405
+ }
1406
+ else if (obligation.evidencePolicy.requiredAuthority === 'deterministic-replay') {
1407
+ payload = deterministicPayload(ledger, obligation);
1408
+ producer = 'server:window-deterministic-replay';
1409
+ }
1410
+ else if (obligation.evidencePolicy.requiredAuthority === 'content-bound-store-row' && /^start\.(?:source-ingestion|window-expiry)/.test(obligation.id) && sourceFreshnessIssues(ledger).length === 0) {
1411
+ storePath = obligation.sourceSpans[0]?.source;
1412
+ payload = proofPayload(obligation, { charterExpiry: obligation.predicate.expected?.charterExpiry });
1413
+ producer = 'server:source-authority';
1414
+ }
1415
+ if (!payload)
1416
+ continue;
1417
+ const digest = createHash('sha256').update(payload).digest('hex');
1418
+ const nonce = `${obligation.evidencePolicy.requiredAuthority}:${digest}`;
1419
+ if (obligation.evidence.some(e => e.nonce === nonce) || ledger.usedNonces.includes(nonce))
1420
+ continue;
1421
+ ledger.usedNonces.push(nonce);
1422
+ obligation.evidence.push({ authority: obligation.evidencePolicy.requiredAuthority, agentId: 'echo', scope: 'echo-window-lifecycle', windowId: ledger.windowId, obligationId: obligation.id, sourceHashes: obligation.sourceSpans.map(s => s.hash), producer, timestamp: windowNow(), nonce, canonicalPayloadHash: digest, verifierPassed: true, verifiedPayload: payload, nativeCoordinates: storePath ? { storePath } : undefined });
1423
+ }
1424
+ };
1425
+ const enforcementStatePath = path.join(ctx.config.stateDir, 'window-lifecycle', 'enforcement-state.json');
1426
+ const shadowAuditPath = path.join(ctx.config.stateDir, 'window-lifecycle', 'shadow-would-block.jsonl');
1427
+ const shadowCensusPath = path.join(ctx.config.stateDir, 'window-lifecycle', 'shadow-audit-census.json');
1428
+ const maturationAuthorityPath = path.join(ctx.config.stateDir, 'window-lifecycle', 'maturation-authority.json');
1429
+ const maturationAuthority = (() => { try {
1430
+ const value = JSON.parse(fs.readFileSync(maturationAuthorityPath, 'utf8'));
1431
+ const key = Buffer.from(value.key, 'base64');
1432
+ if (!value.epoch || key.length !== 32)
1433
+ throw new Error('invalid');
1434
+ return { epoch: value.epoch, key };
1435
+ }
1436
+ catch { /* @silent-fallback-ok — first boot creates the machine-local authority */
1437
+ const value = { epoch: randomUUID(), key: randomBytes(32) };
1438
+ fs.mkdirSync(path.dirname(maturationAuthorityPath), { recursive: true, mode: 0o700 });
1439
+ fs.writeFileSync(maturationAuthorityPath, `${JSON.stringify({ epoch: value.epoch, key: value.key.toString('base64') })}\n`, { mode: 0o600 });
1440
+ return value;
1441
+ } })();
1442
+ const graduationPath = (kind) => path.join(ctx.config.stateDir, 'window-lifecycle', kind === 'synthetic' ? 'graduation-synthetic.json' : 'graduation-real-window-shadow.json');
1443
+ const signGraduation = (payload) => createHmac('sha256', maturationAuthority.key).update(JSON.stringify(payload)).digest('hex');
1444
+ const validateGraduationReport = (report, kind) => { const { signature, ...payload } = report; const authoritativeWindow = kind === 'synthetic' ? 'synthetic-w28' : 'w28'; return report.lifecycleKind === kind && report.windowId === authoritativeWindow && report.producer === 'server:window-lifecycle-shadow' && report.authorityEpoch === maturationAuthority.epoch && report.falsePasses === 0 && report.falseBlocks === 0 && report.censusComplete === true && report.controlledOmissionBlocked === true && /^[a-f0-9]{64}$/.test(report.ledgerDigest) && /^[a-f0-9]{64}$/.test(report.admissionDigest) && /^[a-f0-9]{64}$/.test(report.closureDigest) && /^[a-f0-9]{64}$/.test(report.auditDigest) && typeof report.controlledOmissionReason === 'string' && report.controlledOmissionReason.includes('predicate') && report.controlledOmissionReason.includes('executor') && Date.parse(report.completedAt) <= Date.parse(windowNow()) && signature === signGraduation(payload); };
1445
+ const readGraduationReports = () => { try {
1446
+ const synthetic = JSON.parse(fs.readFileSync(graduationPath('synthetic'), 'utf8'));
1447
+ const real = JSON.parse(fs.readFileSync(graduationPath('real-window-shadow'), 'utf8'));
1448
+ const distinct = synthetic.lifecycleId !== real.lifecycleId && synthetic.lifecycleRunId !== real.lifecycleRunId && synthetic.ledgerDigest !== real.ledgerDigest && synthetic.auditDigest !== real.auditDigest;
1449
+ return validateGraduationReport(synthetic, 'synthetic') && validateGraduationReport(real, 'real-window-shadow') && distinct ? { synthetic, real } : null;
1450
+ }
1451
+ catch { /* @silent-fallback-ok — absent/invalid reports cannot graduate */
1452
+ return null;
1453
+ } };
1454
+ const saveEnforcementState = (state) => { fs.mkdirSync(path.dirname(enforcementStatePath), { recursive: true, mode: 0o700 }); const tmp = `${enforcementStatePath}.${process.pid}.tmp`; fs.writeFileSync(tmp, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 }); fs.renameSync(tmp, enforcementStatePath); };
1455
+ const loadEnforcementState = () => { let state; try {
1456
+ state = JSON.parse(fs.readFileSync(enforcementStatePath, 'utf8'));
1457
+ if (!['off', 'dry-run', 'enforced'].includes(state.mode) || !Number.isFinite(Date.parse(state.startedAt)) || !Number.isFinite(Date.parse(state.expiresAt)))
1458
+ throw new Error('invalid');
1459
+ if (state.mode === 'enforced') {
1460
+ const reports = readGraduationReports();
1461
+ if (!state.graduatedAt || !reports || JSON.stringify(state.evidenceDigests) !== JSON.stringify([reports.synthetic.signature, reports.real.signature])) {
1462
+ state = { mode: 'dry-run', startedAt: state.startedAt, expiresAt: state.expiresAt, fault: 'graduation-authority-invalid' };
1463
+ saveEnforcementState(state);
1464
+ }
1465
+ }
1466
+ }
1467
+ catch { /* @silent-fallback-ok — invalid state fails safe to dry-run and records a durable fault */
1468
+ const startedAt = windowNow();
1469
+ state = { mode: 'dry-run', startedAt, expiresAt: new Date(Date.parse(startedAt) + 14 * 86_400_000).toISOString(), fault: 'invalid-or-missing-enforcement-state' };
1470
+ saveEnforcementState(state);
1471
+ } if (state.mode === 'dry-run' && Date.parse(windowNow()) >= Date.parse(state.expiresAt)) {
1472
+ state = { ...state, mode: 'off', fault: 'dark-window-expired-without-graduation' };
1473
+ saveEnforcementState(state);
1474
+ } return state; };
1475
+ const signCensus = (entry) => createHmac('sha256', maturationAuthority.key).update(JSON.stringify(entry)).digest('hex');
1476
+ const readShadowCensus = () => { try {
1477
+ return JSON.parse(fs.readFileSync(shadowCensusPath, 'utf8'));
1478
+ }
1479
+ catch { /* @silent-fallback-ok — absent census grants no maturation authority */
1480
+ return {};
1481
+ } };
1482
+ const saveShadowCensus = (value) => { fs.mkdirSync(path.dirname(shadowCensusPath), { recursive: true, mode: 0o700 }); const tmp = `${shadowCensusPath}.${process.pid}.tmp`; fs.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 }); fs.renameSync(tmp, shadowCensusPath); };
1483
+ const initializeShadowCensus = (lifecycleRunId) => { const census = readShadowCensus(); const unsigned = { lifecycleRunId, count: 0, headHash: '0'.repeat(64) }; census[lifecycleRunId] = { ...unsigned, signature: signCensus(unsigned) }; saveShadowCensus(census); };
1484
+ const auditWouldBlock = (action, reasons) => {
1485
+ const ledger = windowStore.load(WINDOW_LEDGER_AGENT, WINDOW_LEDGER_SCOPE);
1486
+ if (!ledger)
1487
+ return;
1488
+ let expectedReasons;
1489
+ if (action === 'admission')
1490
+ expectedReasons = evaluateFromAuthorities(ledger.obligations, runtimeRegistry(), evidenceAuthority(), windowNow()).issues;
1491
+ else if (action === 'lifecycle-tick')
1492
+ expectedReasons = evaluateLifecycleTick(structuredClone(ledger), runtimeRegistry(), evidenceAuthority(), windowNow()).issues;
1493
+ else
1494
+ expectedReasons = evaluateLifecycleGuard(ledger, action).reasons;
1495
+ const authorityDigest = createHash('sha256').update(JSON.stringify({ lifecycleRunId: ledger.lifecycleRunId, sourceHashes: ledger.sourceHashes, native: ledger.nativeEvaluations.at(-1) ?? null, obligations: ledger.obligations.map(item => ({ id: item.id, status: item.status, evidence: item.evidence.map(record => ({ nonce: record.nonce, hash: record.canonicalPayloadHash })), executor: item.executorBinding })) })).digest('hex');
1496
+ const census = readShadowCensus();
1497
+ const current = census[ledger.lifecycleRunId];
1498
+ if (!current || current.signature !== signCensus({ lifecycleRunId: current.lifecycleRunId, count: current.count, headHash: current.headHash }))
1499
+ return;
1500
+ const unsigned = { at: windowNow(), mode: 'dry-run', lifecycleRunId: ledger.lifecycleRunId, sequence: current.count + 1, previousHash: current.headHash, action, observedBlock: true, reasons, expectedBlock: expectedReasons.length > 0, expectedReasons, authorityDigest };
1501
+ const adjudicationSignature = createHmac('sha256', maturationAuthority.key).update(JSON.stringify(unsigned)).digest('hex');
1502
+ const rowHash = createHash('sha256').update(JSON.stringify({ ...unsigned, adjudicationSignature })).digest('hex');
1503
+ const row = { ...unsigned, adjudicationSignature, rowHash };
1504
+ fs.mkdirSync(path.dirname(shadowAuditPath), { recursive: true, mode: 0o700 });
1505
+ fs.appendFileSync(shadowAuditPath, `${JSON.stringify(row)}\n`, { mode: 0o600 });
1506
+ const next = { lifecycleRunId: ledger.lifecycleRunId, count: row.sequence, headHash: row.rowHash };
1507
+ census[ledger.lifecycleRunId] = { ...next, signature: signCensus(next) };
1508
+ saveShadowCensus(census);
1509
+ };
1510
+ const produceGraduationReports = (ledger) => {
1511
+ const closure = evaluateClosure(ledger);
1512
+ if (ledger.state !== 'closed_clean' || closure.state !== 'closed_clean' || !ledger.admissionEvaluatedAt || !ledger.nativeEvaluations.length)
1513
+ return false;
1514
+ const kind = ledger.windowId === 'synthetic-w28' ? 'synthetic' : ledger.windowId === 'w28' ? 'real-window-shadow' : null;
1515
+ if (!kind)
1516
+ return false;
1517
+ const postLive = runWindowLifecyclePostLiveCheck(ledger);
1518
+ if (!postLive.passed)
1519
+ return false;
1520
+ let runAudits = [];
1521
+ try {
1522
+ runAudits = fs.readFileSync(shadowAuditPath, 'utf8').trim().split('\n').filter(Boolean).map(line => JSON.parse(line)).filter(row => row.lifecycleRunId === ledger.lifecycleRunId);
1523
+ }
1524
+ catch { /* @silent-fallback-ok — signed zero-row census is checked immediately below */ }
1525
+ const censusEntry = readShadowCensus()[ledger.lifecycleRunId];
1526
+ if (!censusEntry || censusEntry.signature !== signCensus({ lifecycleRunId: censusEntry.lifecycleRunId, count: censusEntry.count, headHash: censusEntry.headHash }) || censusEntry.count !== runAudits.length)
1527
+ return false;
1528
+ let expectedPrevious = '0'.repeat(64);
1529
+ if (runAudits.some((row, index) => { const { adjudicationSignature, rowHash, ...unsigned } = row; const computedHash = createHash('sha256').update(JSON.stringify({ ...unsigned, adjudicationSignature })).digest('hex'); const invalid = row.sequence !== index + 1 || row.previousHash !== expectedPrevious || row.mode !== 'dry-run' || typeof row.expectedBlock !== 'boolean' || typeof row.observedBlock !== 'boolean' || !Array.isArray(row.expectedReasons) || !/^[a-f0-9]{64}$/.test(row.authorityDigest) || adjudicationSignature !== createHmac('sha256', maturationAuthority.key).update(JSON.stringify(unsigned)).digest('hex') || rowHash !== computedHash; expectedPrevious = rowHash; return invalid; }) || censusEntry.headHash !== expectedPrevious)
1530
+ return false;
1531
+ const omissionLedger = structuredClone(ledger);
1532
+ omissionLedger.state = 'pre_start_gate';
1533
+ const omissionTarget = omissionLedger.obligations.find(item => item.id === 'start.cadence-commitment');
1534
+ if (!omissionTarget)
1535
+ return false;
1536
+ omissionTarget.status = 'pending';
1537
+ omissionTarget.evidence = [];
1538
+ omissionTarget.executorBinding = { ...omissionTarget.executorBinding, executorId: `controlled-omission:${ledger.lifecycleRunId}`, enabled: false, running: false };
1539
+ const omissionEvaluation = evaluateFromAuthorities(omissionLedger.obligations, runtimeRegistry(), evidenceAuthority(), windowNow());
1540
+ omissionLedger.obligations = omissionEvaluation.obligations;
1541
+ const omissionClosure = evaluateClosure(omissionLedger);
1542
+ const omissionReasons = [...omissionEvaluation.issues.filter(reason => reason.startsWith(`${omissionTarget.id}:`)), ...omissionClosure.issues.filter(reason => reason.includes(omissionTarget.id))];
1543
+ const predicateRefused = omissionReasons.some(reason => reason.includes('predicate'));
1544
+ const executorRefused = omissionReasons.some(reason => reason.includes('executor'));
1545
+ const omissionObservedBlock = predicateRefused && executorRefused && !omissionEvaluation.admitted && omissionClosure.state === 'close_blocked';
1546
+ if (!omissionObservedBlock)
1547
+ return false;
1548
+ const omissionReason = [...new Set(omissionReasons)].join(';');
1549
+ const adjudicatedComparisons = [{ lifecycleRunId: ledger.lifecycleRunId, check: 'closed-clean-positive', expectedBlock: false, observedBlock: closure.state !== 'closed_clean', reasons: closure.issues }, { lifecycleRunId: ledger.lifecycleRunId, check: 'controlled-completion-omission', expectedBlock: true, observedBlock: omissionObservedBlock, reasons: omissionReasons }];
1550
+ const comparisons = [...runAudits, ...adjudicatedComparisons];
1551
+ const typed = [...runAudits, ...adjudicatedComparisons];
1552
+ const falsePasses = typed.filter(item => item.expectedBlock === true && item.observedBlock !== true).length;
1553
+ const falseBlocks = typed.filter(item => item.expectedBlock === false && item.observedBlock === true).length;
1554
+ const censusComplete = ledger.compiledObligationIds.length === ledger.obligations.length && new Set(ledger.compiledObligationIds).size === ledger.compiledObligationIds.length && ledger.compiledObligationIds.every(id => ledger.obligations.some(item => item.id === id));
1555
+ const ledgerDigest = createHash('sha256').update(JSON.stringify(ledger)).digest('hex');
1556
+ const closureDigest = createHash('sha256').update(JSON.stringify(closure)).digest('hex');
1557
+ const auditDigest = createHash('sha256').update(JSON.stringify(comparisons)).digest('hex');
1558
+ const admissionDigest = createHash('sha256').update(JSON.stringify({ evaluatedAt: ledger.admissionEvaluatedAt, native: ledger.nativeEvaluations.at(-1), start: ledger.obligations.filter(item => item.phase === 'pre-start' || item.phase === 'start').map(item => ({ id: item.id, status: item.status, evidence: item.evidence.map(record => record.canonicalPayloadHash) })) })).digest('hex');
1559
+ const payload = { lifecycleId: `${kind}:${ledger.lifecycleRunId}`, lifecycleRunId: ledger.lifecycleRunId, lifecycleKind: kind, windowId: ledger.windowId, completedAt: windowNow(), falsePasses, falseBlocks, censusComplete, controlledOmissionBlocked: omissionObservedBlock, controlledOmissionReason: omissionReason, ledgerDigest, admissionDigest, closureDigest, auditDigest, producer: 'server:window-lifecycle-shadow', authorityEpoch: maturationAuthority.epoch };
1560
+ const report = { ...payload, signature: signGraduation(payload) };
1561
+ fs.writeFileSync(graduationPath(kind), `${JSON.stringify(report, null, 2)}\n`, { mode: 0o600 });
1562
+ return validateGraduationReport(report, kind);
1563
+ };
1564
+ ctx.windowLifecycleTick = ctx.config.projectName === WINDOW_LEDGER_AGENT ? () => {
1565
+ const enforcement = loadEnforcementState();
1566
+ if (enforcement.mode === 'off')
1567
+ return;
1568
+ const ledger = windowStore.load(WINDOW_LEDGER_AGENT, WINDOW_LEDGER_SCOPE);
1569
+ if (!ledger)
1570
+ return;
1571
+ if (ledger.state === 'closed_clean')
1572
+ return;
1573
+ if (ledger.state === 'closed_with_operator_waiver' || ledger.state === 'rolled_back')
1574
+ return;
1575
+ const stale = sourceFreshnessIssues(ledger);
1576
+ if (stale.length) {
1577
+ ledger.admission = undefined;
1578
+ ledger.state = ledger.state.startsWith('active') ? 'active_mid_blocked' : ['close_due', 'delivered_pending_post_live', 'close_blocked'].includes(ledger.state) ? 'close_blocked' : 'start_blocked';
1579
+ ledger.surfacedIssues ??= [];
1580
+ const novelStale = stale.filter(issue => !ledger.surfacedIssues.includes(issue));
1581
+ ledger.surfacedIssues.push(...novelStale);
1582
+ windowStore.save(ledger);
1583
+ if (novelStale.length && ctx.telegram)
1584
+ void ctx.telegram.sendToTopic(43003, `Window lifecycle source authority changed:\n${novelStale.map(v => `- ${v}`).join('\n')}`, { provenance: 'automation' }).catch(error => { /* @silent-fallback-ok — delivery failure is logged; the durable block remains authoritative */ console.warn('[window-lifecycle] stale-source escalation failed:', error); });
1585
+ return;
1586
+ }
1587
+ materializeMachineEvidence(ledger);
1588
+ const result = evaluateLifecycleTick(ledger, runtimeRegistry(), evidenceAuthority(), windowNow());
1589
+ result.ledger.surfacedIssues ??= [];
1590
+ const novel = result.issues.filter(issue => !result.ledger.surfacedIssues.includes(issue));
1591
+ result.ledger.surfacedIssues.push(...novel);
1592
+ windowStore.save(result.ledger);
1593
+ const episodes = readRemediationEpisodes();
1594
+ const novelRemediations = (enforcement.mode === 'enforced' ? (result.ledger.requiredRemediations ?? []) : []).filter(remediation => { const duty = result.ledger.obligations.find(item => item.id === remediation.obligationId); if (!duty)
1595
+ return false; const digest = remediationEpisodeDigest(duty); return !episodes.some(item => item.episodeDigest === digest); });
1596
+ for (const remediation of novelRemediations) {
1597
+ const duty = result.ledger.obligations.find(item => item.id === remediation.obligationId);
1598
+ const episodeDigest = remediationEpisodeDigest(duty);
1599
+ const remediationId = randomUUID();
1600
+ const marker = `remediation:${remediationId}`;
1601
+ result.ledger.surfacedIssues.push(marker);
1602
+ fs.mkdirSync(path.dirname(remediationPath), { recursive: true, mode: 0o700 });
1603
+ fs.appendFileSync(remediationPath, `${JSON.stringify({ remediationId, episodeDigest, obligationId: remediation.obligationId, action: remediation.action, owner: duty.responsibleRole, reason: duty.statement, createdAt: windowNow(), disposition: remediation.debtRequired ? 'registered-debt' : 'awaiting-authoritative-evidence', resolutionRoute: remediation.debtRequired ? undefined : `/window-lifecycle/remediation/${encodeURIComponent(remediation.obligationId)}/resolve` })}\n`, { mode: 0o600 });
1604
+ if (remediation.observerTopicId && ctx.telegram) {
1605
+ const verb = remediation.repostRequired ? 'Visible repost required' : remediation.scopeReviewRequired ? 'Operator scope/timebox review required' : remediation.correctionRequired ? 'Correction required before delivery' : remediation.debtRequired ? 'Debt registered' : 'Lifecycle duty blocked';
1606
+ void ctx.telegram.sendToTopic(remediation.observerTopicId, `${verb}: ${remediation.obligationId} (${remediation.action}); remediation ${remediationId}`, { provenance: 'automation' }).catch(error => console.warn('[window-lifecycle] remediation delivery failed:', error));
1607
+ }
1608
+ }
1609
+ if (novelRemediations.length)
1610
+ windowStore.save(result.ledger);
1611
+ if (enforcement.mode === 'dry-run' && novel.length)
1612
+ auditWouldBlock('lifecycle-tick', novel);
1613
+ if (novel.length && ctx.telegram)
1614
+ void ctx.telegram.sendToTopic(43003, `Window lifecycle ${enforcement.mode === 'dry-run' ? 'shadow would block' : 'enforcement blocked progress'}:\n${novel.slice(0, 12).map(v => `- ${v}`).join('\n')}`, { provenance: 'automation' }).catch(error => console.warn('[window-lifecycle] escalation delivery failed:', error));
1615
+ } : null;
1616
+ router.post('/window-lifecycle/compile', (req, res) => {
1617
+ if (!windowRequestScope(req.body))
1618
+ return res.status(403).json({ error: 'echo-scope-required' });
1619
+ const windowId = typeof req.body.windowId === 'string' && /^[a-z0-9-]{1,40}$/i.test(req.body.windowId) ? req.body.windowId : null;
1620
+ if (!windowId)
1621
+ return res.status(400).json({ error: 'valid windowId required' });
1622
+ const charterPath = path.join(ctx.config.stateDir, windowId, `WINDOW-${windowId.replace(/^w/i, '')}-CHARTER.md`);
1623
+ try {
1624
+ const compiled = compileWindowSources({ agentId: 'echo', scope: 'echo-window-lifecycle', windowId, tenetsPath: path.join(ctx.config.projectDir, '.instar', 'TENETS.md'), charterPath, now: windowNow() });
1625
+ const ledger = createLedger({ agentId: 'echo', scope: 'echo-window-lifecycle', windowId, compiled });
1626
+ windowStore.save(ledger);
1627
+ initializeShadowCensus(ledger.lifecycleRunId);
1628
+ return res.status(201).json(ledger);
1629
+ }
1630
+ catch (error) { /* @silent-fallback-ok — compilation refusal is returned explicitly as HTTP 409 */
1631
+ return res.status(409).json({ error: error instanceof Error ? error.message : String(error) });
1632
+ }
1633
+ });
1634
+ router.post('/window-lifecycle/evidence', (req, res) => {
1635
+ if (!windowRequestScope(req.body))
1636
+ return res.status(403).json({ error: 'echo-scope-required' });
1637
+ const ledger = windowStore.load('echo', 'echo-window-lifecycle');
1638
+ if (!ledger)
1639
+ return res.status(404).json({ error: 'ledger-not-found' });
1640
+ const obligation = ledger.obligations.find(o => o.id === req.body.obligationId);
1641
+ if (!obligation)
1642
+ return res.status(404).json({ error: 'obligation-not-found' });
1643
+ const topicId = Number(req.body.topicId);
1644
+ const messageId = Number(req.body.messageId);
1645
+ const requested = req.body.authority === 'verified-operator-approval' ? 'verified-operator-approval' : req.body.authority === 'live-requeried-message' ? 'live-requeried-message' : 'content-bound-store-row';
1646
+ const live = ctx.telegram?.getTopicHistory(topicId, 1_000).find(item => item.messageId === messageId);
1647
+ if (!live)
1648
+ return res.status(409).json({ error: 'live-message-not-found' });
1649
+ const producer = live.fromUser ? (live.telegramUserId === undefined ? 'telegram:unknown' : `telegram:${live.telegramUserId}`) : `session:${live.sessionName ?? 'unknown'}`;
1650
+ const agentAuthorship = live.authorship === 'agent-outbound' || live.authorship === 'agent-verified';
1651
+ const assignedProducer = obligation.executorBinding.owner;
1652
+ const producerMatchesAssignment = typeof assignedProducer === 'string' && assignedProducer === producer;
1653
+ const signedTelegramGuard = /^continuous\.telegram\.(?:send-path-classified|signature-verified|act-as-principal-guard)$/.test(obligation.id);
1654
+ const operatorReport = /^cadence\.report\.3h@/.test(obligation.id) && topicId === 36966;
1655
+ const roleMatches = signedTelegramGuard ? !!verifyEchoSignedOutbound(live) && producerMatchesAssignment : operatorReport ? agentAuthorship && producerMatchesAssignment : obligation.responsibleRole === 'echo' ? agentAuthorship && producerMatchesAssignment : obligation.responsibleRole.startsWith('observer-') ? agentAuthorship && topicId === 43003 && producerMatchesAssignment : true;
1656
+ if (requested === 'live-requeried-message' && !roleMatches)
1657
+ return res.status(409).json({ error: 'responsible-role-mismatch', expected: obligation.responsibleRole });
1658
+ const nonce = randomUUID();
1659
+ const candidate = { authority: requested, agentId: 'echo', scope: 'echo-window-lifecycle', windowId: ledger.windowId, obligationId: obligation.id, sourceHashes: obligation.sourceSpans.map(s => s.hash), producer, timestamp: live.timestamp, nonce, canonicalPayloadHash: createHash('sha256').update(live.text).digest('hex'), verifierPassed: false, nativeCoordinates: { topicId, messageId } };
1660
+ const verified = evidenceAuthority().requery(candidate);
1661
+ if (!verified)
1662
+ return res.status(409).json({ error: 'evidence-verification-failed' });
1663
+ if (ledger.usedNonces.includes(nonce))
1664
+ return res.status(409).json({ error: 'nonce-replay' });
1665
+ ledger.usedNonces.push(nonce);
1666
+ obligation.evidence.push(verified);
1667
+ obligation.status = 'satisfied';
1668
+ ledger.admission = undefined;
1669
+ windowStore.save(ledger);
1670
+ return res.status(201).json(verified);
1671
+ });
1672
+ router.post('/window-lifecycle/evaluate', (req, res) => {
1673
+ if (!windowRequestScope(req.body))
1674
+ return res.status(403).json({ error: 'echo-scope-required' });
1675
+ const ledger = windowStore.load('echo', 'echo-window-lifecycle');
1676
+ if (!ledger)
1677
+ return res.status(404).json({ error: 'ledger-not-found' });
1678
+ const stale = sourceFreshnessIssues(ledger);
1679
+ if (stale.length)
1680
+ return res.status(409).json({ admitted: false, state: 'start_blocked', issues: stale });
1681
+ const native = ledger.nativeEvaluations.at(-1)?.output;
1682
+ if (native?.admitted !== true)
1683
+ return res.status(409).json({ admitted: false, state: 'start_blocked', issues: ['native-structural-preflight-missing-or-refused'] });
1684
+ materializeMachineEvidence(ledger);
1685
+ const result = evaluateFromAuthorities(ledger.obligations, runtimeRegistry(), evidenceAuthority(), windowNow());
1686
+ ledger.obligations = result.obligations;
1687
+ ledger.state = result.admitted ? 'active_start' : 'start_blocked';
1688
+ ledger.admissionEvaluatedAt = windowNow();
1689
+ ledger.admission = result.admitted ? { admitted: true, evaluatedAt: ledger.admissionEvaluatedAt, snapshotDigest: admissionSnapshotDigest(ledger) } : undefined;
1690
+ windowStore.save(ledger);
1691
+ if (!result.admitted && loadEnforcementState().mode === 'dry-run')
1692
+ auditWouldBlock('admission', result.issues);
1693
+ return res.status(result.admitted ? 200 : 409).json({ ...result, state: ledger.state });
1694
+ });
1695
+ router.post('/window-lifecycle/tick', (req, res) => { if (!windowRequestScope(req.body))
1696
+ return res.status(403).json({ error: 'echo-scope-required' }); const ledger = windowStore.load('echo', 'echo-window-lifecycle'); if (!ledger)
1697
+ return res.status(404).json({ error: 'ledger-not-found' }); const stale = sourceFreshnessIssues(ledger); if (stale.length) {
1698
+ ctx.windowLifecycleTick?.();
1699
+ return res.status(409).json({ ledger: windowStore.load('echo', 'echo-window-lifecycle'), issues: stale });
1700
+ } materializeMachineEvidence(ledger); const result = evaluateLifecycleTick(ledger, runtimeRegistry(), evidenceAuthority(), windowNow()); windowStore.save(result.ledger); if (req.body.actuateRemediations === true)
1701
+ ctx.windowLifecycleTick?.(); return res.status(result.issues.length ? 409 : 200).json(result); });
1702
+ router.get('/window-lifecycle', (_req, res) => { if (ctx.config.projectName !== 'echo')
1703
+ return res.status(404).json({ error: 'echo-scope-required' }); const ledger = windowStore.load('echo', 'echo-window-lifecycle'); return ledger ? res.json({ ledger, closure: evaluateClosure(ledger) }) : res.status(404).json({ error: 'ledger-not-found' }); });
1704
+ router.post('/window-lifecycle/transition', (req, res) => { if (!windowRequestScope(req.body))
1705
+ return res.status(403).json({ error: 'echo-scope-required' }); const stored = windowStore.load('echo', 'echo-window-lifecycle'); if (!stored)
1706
+ return res.status(404).json({ error: 'ledger-not-found' }); try {
1707
+ const stale = sourceFreshnessIssues(stored);
1708
+ if (stale.length) {
1709
+ ctx.windowLifecycleTick?.();
1710
+ return res.status(409).json({ error: 'source-authority-stale', issues: stale });
1711
+ }
1712
+ materializeMachineEvidence(stored);
1713
+ const checked = evaluateLifecycleTick(stored, runtimeRegistry(), evidenceAuthority(), windowNow()).ledger;
1714
+ const next = transitionLedger(checked, req.body.target, { now: windowNow(), requeryWaiverApproval: waiver => { const evidence = checked.obligations.flatMap(o => o.evidence).find(e => e.authority === 'verified-operator-approval' && e.nativeCoordinates?.topicId === waiver.approvalCoordinates?.topicId && e.nativeCoordinates?.messageId === waiver.approvalCoordinates?.messageId); const verified = evidence ? evidenceAuthority().requery(evidence) : null; return verified?.verifiedPayload?.trim() === `approve waiver ${waiver.digest}`; } });
1715
+ windowStore.save(next);
1716
+ ctx.windowLifecycleTick?.();
1717
+ return res.json(next);
1718
+ }
1719
+ catch (error) {
1720
+ return res.status(409).json({ error: error instanceof Error ? error.message : String(error) });
1721
+ } });
1722
+ router.post('/window-lifecycle/native-admission', (req, res) => { if (!windowRequestScope(req.body))
1723
+ return res.status(403).json({ error: 'echo-scope-required' }); try {
1724
+ const current = windowStore.load('echo', 'echo-window-lifecycle');
1725
+ if (!current)
1726
+ return res.status(404).json({ error: 'ledger-not-found' });
1727
+ if (req.body.windowId !== current.windowId)
1728
+ return res.status(409).json({ error: 'wrong-window' });
1729
+ const record = runNativeAdmissionAdapter({ agentId: 'echo', scope: 'echo-window-lifecycle', windowId: current.windowId, stateDir: ctx.config.stateDir, package: req.body.package, nonce: req.body.nonce });
1730
+ const ledger = windowStore.appendNativeEvaluation('echo', 'echo-window-lifecycle', record);
1731
+ const admitted = record.output.admitted === true;
1732
+ if (admitted) {
1733
+ const duty = ledger.obligations.find(o => o.id === 'preground.native-structural-preflight');
1734
+ if (!duty)
1735
+ throw new Error('native-preflight-obligation-missing');
1736
+ duty.evidence.push({ authority: 'native-local-store-presence', agentId: 'echo', scope: 'echo-window-lifecycle', windowId: ledger.windowId, obligationId: duty.id, sourceHashes: duty.sourceSpans.map(s => s.hash), producer: `native:${record.evaluatorVersion}`, timestamp: record.evaluatedAt, nonce: record.nonce, canonicalPayloadHash: record.inputHash, verifierPassed: true, verifiedPayload: JSON.stringify(record.output), nativeCoordinates: { storePath: record.storePath } });
1737
+ duty.status = 'satisfied';
1738
+ windowStore.save(ledger);
1739
+ }
1740
+ ctx.windowLifecycleTick?.();
1741
+ return res.status(admitted ? 200 : 409).json({ record, state: ledger.state });
1742
+ }
1743
+ catch (error) {
1744
+ return res.status(409).json({ error: error instanceof Error ? error.message : String(error) });
1745
+ } });
1746
+ router.post('/window-lifecycle/waiver', (req, res) => { if (!windowRequestScope(req.body))
1747
+ return res.status(403).json({ error: 'echo-scope-required' }); const ledger = windowStore.load('echo', 'echo-window-lifecycle'); if (!ledger)
1748
+ return res.status(404).json({ error: 'ledger-not-found' }); const waiver = req.body.waiver; const approval = ledger.obligations.flatMap(o => o.evidence).find(e => e.authority === 'verified-operator-approval' && e.nativeCoordinates?.topicId === waiver?.approvalCoordinates?.topicId && e.nativeCoordinates?.messageId === waiver?.approvalCoordinates?.messageId); const verified = approval ? evidenceAuthority().requery(approval) : null; if (!verified || verified.verifiedPayload?.trim() !== `approve waiver ${waiver.digest}`)
1749
+ return res.status(403).json({ error: 'verified-exact-digest-operator-approval-required' }); try {
1750
+ const next = applyWaiver(ledger, waiver, verified.producer);
1751
+ next.admission = undefined;
1752
+ windowStore.save(next);
1753
+ ctx.windowLifecycleTick?.();
1754
+ return res.json(next);
1755
+ }
1756
+ catch (error) { /* @silent-fallback-ok — invalid waiver refusal is returned explicitly as HTTP 409 */
1757
+ return res.status(409).json({ error: error instanceof Error ? error.message : String(error) });
1758
+ } });
1759
+ router.post('/window-lifecycle/rollback', (req, res) => { if (!windowRequestScope(req.body))
1760
+ return res.status(403).json({ error: 'echo-scope-required' }); const ledger = windowStore.load('echo', 'echo-window-lifecycle'); if (!ledger)
1761
+ return res.status(404).json({ error: 'ledger-not-found' }); const request = req.body.rollback; const approval = ledger.obligations.flatMap(o => o.evidence).find(e => e.authority === 'verified-operator-approval' && e.nativeCoordinates?.topicId === request?.approvalCoordinates?.topicId && e.nativeCoordinates?.messageId === request?.approvalCoordinates?.messageId); if (!approval)
1762
+ return res.status(403).json({ error: 'verified-exact-digest-operator-rollback-required' }); try {
1763
+ return res.json(windowStore.rollback('echo', 'echo-window-lifecycle', request, approval, evidenceAuthority()));
1764
+ }
1765
+ catch (error) {
1766
+ return res.status(409).json({ error: error instanceof Error ? error.message : String(error) });
1767
+ } });
1768
+ router.post('/window-lifecycle/reenable', (req, res) => { if (!windowRequestScope(req.body))
1769
+ return res.status(403).json({ error: 'echo-scope-required' }); try {
1770
+ const inventory = [...WINDOW_DRY_RUN_INVENTORY];
1771
+ return res.json(windowStore.reenable('echo', 'echo-window-lifecycle', path.join(ctx.config.stateDir, 'window-lifecycle', 'fault-fixed-evidence.json'), () => { const runner = path.join(ctx.config.projectDir, 'node_modules', '.bin', 'vitest'); const output = withSyncOp(() => execFileSync(runner, ['run', ...inventory], { cwd: ctx.config.projectDir, encoding: 'utf8', timeout: 300_000, maxBuffer: 16 * 1024 * 1024 })); return { passed: true, command: `${runner} run ${inventory.join(' ')}`, completedAt: windowNow(), outputHash: createHash('sha256').update(output).digest('hex'), testInventory: inventory }; }, windowNow()));
1772
+ }
1773
+ catch (error) {
1774
+ return res.status(409).json({ error: error instanceof Error ? error.message : String(error) });
1775
+ } });
1776
+ router.get('/window-lifecycle/enforcement', (_req, res) => ctx.config.projectName === 'echo' ? res.json(loadEnforcementState()) : res.status(404).json({ error: 'echo-scope-required' }));
1777
+ router.post('/window-lifecycle/enforcement/record-shadow', (req, res) => { if (!windowRequestScope(req.body))
1778
+ return res.status(403).json({ error: 'echo-scope-required' }); if (loadEnforcementState().mode !== 'dry-run')
1779
+ return res.status(409).json({ error: 'shadow-recording-requires-dry-run' }); const ledger = windowStore.load('echo', 'echo-window-lifecycle'); if (!ledger)
1780
+ return res.status(404).json({ error: 'ledger-not-found' }); return produceGraduationReports(ledger) ? res.status(201).json({ recorded: true, reports: readGraduationReports() }) : res.status(409).json({ error: 'shadow-lifecycle-incomplete-or-criteria-failed', closure: evaluateClosure(ledger), postLive: runWindowLifecyclePostLiveCheck(ledger) }); });
1781
+ router.post('/window-lifecycle/enforcement/graduate', (req, res) => { if (!windowRequestScope(req.body))
1782
+ return res.status(403).json({ error: 'echo-scope-required' }); const state = loadEnforcementState(); if (state.mode !== 'dry-run')
1783
+ return res.status(409).json({ error: 'graduation-requires-dry-run' }); const reports = readGraduationReports(); if (!reports)
1784
+ return res.status(409).json({ error: 'graduation-authority-evidence-missing-or-invalid' }); const next = { ...state, mode: 'enforced', graduatedAt: windowNow(), evidenceDigests: [reports.synthetic.signature, reports.real.signature] }; saveEnforcementState(next); return res.json(next); });
1785
+ router.post('/window-lifecycle/enforcement/off', (req, res) => { if (!windowRequestScope(req.body))
1786
+ return res.status(403).json({ error: 'echo-scope-required' }); const reason = typeof req.body.reason === 'string' && req.body.reason.trim() ? req.body.reason.trim() : 'operator-disabled'; const next = { ...loadEnforcementState(), mode: 'off', fault: reason }; saveEnforcementState(next); return res.json(next); });
1787
+ router.post('/window-lifecycle/remediation/:obligationId/resolve', (req, res) => {
1788
+ if (!windowRequestScope(req.body))
1789
+ return res.status(403).json({ error: 'echo-scope-required' });
1790
+ const ledger = windowStore.load('echo', 'echo-window-lifecycle');
1791
+ if (!ledger)
1792
+ return res.status(404).json({ error: 'ledger-not-found' });
1793
+ const obligation = ledger.obligations.find(item => item.id === req.params.obligationId);
1794
+ if (!obligation)
1795
+ return res.status(404).json({ error: 'obligation-not-found' });
1796
+ if (!['pending', 'unknown', 'open-unexecuted', 'failed', 'blocked', 'expired'].includes(obligation.status))
1797
+ return res.status(409).json({ error: 'remediation-duty-not-unresolved' });
1798
+ const remediation = deriveFailureRemediation(obligation);
1799
+ if (!remediation.repostRequired && !remediation.correctionRequired && !remediation.scopeReviewRequired)
1800
+ return res.status(409).json({ error: 'remediation-not-evidence-resolvable' });
1801
+ const remediationId = typeof req.body.remediationId === 'string' ? req.body.remediationId : '';
1802
+ const episodes = readRemediationEpisodes();
1803
+ const episode = [...episodes].reverse().find(item => item.remediationId === remediationId && item.obligationId === obligation.id && item.episodeDigest === remediationEpisodeDigest(obligation) && item.disposition === 'awaiting-authoritative-evidence');
1804
+ if (!episode || episodes.some(item => item.remediationId === remediationId && item.disposition === 'resolved-with-live-evidence'))
1805
+ return res.status(409).json({ error: 'active-remediation-episode-required' });
1806
+ const topicId = Number(req.body.topicId);
1807
+ const messageId = Number(req.body.messageId);
1808
+ const row = ctx.telegram?.getTopicHistory(topicId, 1_000).find(item => item.messageId === messageId);
1809
+ if (!row || Date.parse(row.timestamp) <= Date.parse(episode.createdAt) || Date.parse(row.timestamp) > Date.parse(windowNow()))
1810
+ return res.status(409).json({ error: 'fresh-live-remediation-evidence-required' });
1811
+ const artifact = { ...episode, disposition: 'resolved-with-live-evidence', resolvedAt: windowNow(), topicId, messageId, evidenceHash: createHash('sha256').update(row.text).digest('hex') };
1812
+ if (!remediationResolutionIsLive(obligation, artifact))
1813
+ return res.status(409).json({ error: 'remediation-evidence-semantic-mismatch' });
1814
+ fs.appendFileSync(remediationPath, `${JSON.stringify(artifact)}\n`, { mode: 0o600 });
1815
+ return res.json(artifact);
1816
+ });
1817
+ // Echo-only enforcement plane over the production mutation doors declared by
1818
+ // the lifecycle duties. Registered after the lifecycle recovery/evidence
1819
+ // routes so those remain usable while enforcement is blocking progress.
1820
+ router.use((req, res, next) => {
1821
+ if (ctx.config.projectName !== WINDOW_LEDGER_AGENT || req.method !== 'POST')
1822
+ return next();
1823
+ const ledger = windowStore.load(WINDOW_LEDGER_AGENT, WINDOW_LEDGER_SCOPE);
1824
+ if (!ledger)
1825
+ return next();
1826
+ const enforcement = loadEnforcementState();
1827
+ if (enforcement.mode === 'off')
1828
+ return next();
1829
+ const action = /^\/sessions\/(?:spawn|create|refresh|restart-all)|^\/autonomous\/(?:register|native-goal\/set)|^\/autonomous\/[^/]+\/scope-accretion-override|^\/jobs\/[^/]+\/(?:trigger|run)|^\/messages\/spawn-request|^\/telegram\/topics/.test(req.path) ? 'new-scope'
1830
+ : /^\/telegram\/(?:reply|post-update)/.test(req.path) ? 'telegram-send'
1831
+ : /^\/autonomous\/(?:evaluate-completion|[^/]+\/run-end)/.test(req.path) ? 'completion-claim' : null;
1832
+ if (!action)
1833
+ return next();
1834
+ const verdict = evaluateLifecycleGuard(ledger, action);
1835
+ if (enforcement.mode === 'dry-run') {
1836
+ if (!verdict.allowed)
1837
+ auditWouldBlock(action, verdict.reasons);
1838
+ return next();
1839
+ }
1840
+ if (!verdict.allowed)
1841
+ return res.status(409).json({ error: 'window-lifecycle-enforcement', action, reasons: verdict.reasons });
1842
+ if (action === 'telegram-send') {
1843
+ const episodes = readRemediationEpisodes();
1844
+ const corrections = ledger.obligations.filter(item => { if (!['pending', 'unknown', 'open-unexecuted', 'failed', 'blocked', 'expired'].includes(item.status) || !deriveFailureRemediation(item).correctionRequired)
1845
+ return false; const digest = remediationEpisodeDigest(item); return !episodes.some(episode => episode.episodeDigest === digest && episode.disposition === 'resolved-with-live-evidence' && remediationResolutionIsLive(item, episode)); });
1846
+ const selected = corrections.find(item => { const episode = [...episodes].reverse().find(entry => entry.remediationId === req.body?.remediationId && entry.obligationId === item.id && entry.episodeDigest === remediationEpisodeDigest(item) && entry.disposition === 'awaiting-authoritative-evidence'); if (!episode || typeof req.body?.text !== 'string')
1847
+ return false; return item.failureAction === 'correct-before-report' ? /corrected counts?:/i.test(req.body.text) && /\bsource:/i.test(req.body.text) && /\b[A-Za-z][\w -]*\s*=\s*\d+\b/.test(req.body.text) : isHighLevelSynthesis(req.body.text); });
1848
+ if (corrections.length && !selected)
1849
+ return res.status(409).json({ error: 'window-lifecycle-correction-required', remediationIds: episodes.filter(episode => corrections.some(item => item.id === episode.obligationId) && episode.disposition === 'awaiting-authoritative-evidence').map(episode => episode.remediationId) });
1850
+ }
1851
+ if (action === 'telegram-send') {
1852
+ try {
1853
+ const topicMatch = req.path.match(/^\/telegram\/(?:reply|post-update)\/(\d+)/);
1854
+ const topicId = Number(topicMatch?.[1] ?? (req.path === '/telegram/post-update' ? ctx.state.get('agent-updates-topic') : req.body?.topicId));
1855
+ const text = req.body?.text;
1856
+ const registry = ctx.playwrightRegistry?.() ?? new PlaywrightProfileRegistry({ stateDir: ctx.config.stateDir, projectDir: ctx.config.projectDir, listVaultNames: () => [] });
1857
+ const profileId = registry.resolve('telegram').profile?.id;
1858
+ if (profileId !== 'justin-telegram')
1859
+ throw new Error(`send-time-profile-invalid:${profileId ?? 'missing'}`);
1860
+ if (!Number.isSafeInteger(topicId) || typeof text !== 'string')
1861
+ throw new Error(`send-time-payload-invalid:topic=${topicId}:text=${typeof text}`);
1862
+ const identity = JSON.parse(fs.readFileSync(path.join(ctx.config.stateDir, 'identity.json'), 'utf8'));
1863
+ if (identity.privateKeyEncryption && identity.privateKeyEncryption !== 'none' || typeof identity.privateKey !== 'string')
1864
+ throw new Error('send-time-signing-key-unavailable');
1865
+ const signed = signAgentMessage({ agentId: 'echo', topicId, body: text, privateKey: Buffer.from(identity.privateKey, 'base64'), timestamp: Math.floor(Date.parse(windowNow()) / 1000) });
1866
+ req.body.text = signed.text;
1867
+ const checked = verifyEchoSignedOutbound({ text: signed.text, topicId, timestamp: windowNow(), fromUser: false, authorship: 'agent-outbound' });
1868
+ if (!checked)
1869
+ throw new Error('send-time-signature-verification-failed');
1870
+ }
1871
+ catch (error) {
1872
+ return res.status(409).json({ error: 'window-lifecycle-send-time-guard', reason: error instanceof Error ? error.message : String(error) });
1873
+ }
1874
+ }
1875
+ return next();
1876
+ });
1072
1877
  // Content-hash dedup for the agent-to-agent relay-agent ingress path. Guards
1073
1878
  // the duplicate-reply bug where a sender that times out on the receiver's
1074
1879
  // session spawn retries with a FRESH message.id, slipping past the id-based