instar 1.3.1092 → 1.3.1093
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/dist/data/standards-guard-index.json +1 -1
- package/dist/data/standards-guard-index.meta.json +2 -2
- package/dist/data/standards-registry.meta.json +1 -1
- package/dist/remediation/IntentAuditReconciler.d.ts +17 -0
- package/dist/remediation/IntentAuditReconciler.d.ts.map +1 -0
- package/dist/remediation/IntentAuditReconciler.js +28 -0
- package/dist/remediation/IntentAuditReconciler.js.map +1 -0
- package/dist/remediation/IntentJournal.d.ts.map +1 -1
- package/dist/remediation/IntentJournal.js +4 -2
- package/dist/remediation/IntentJournal.js.map +1 -1
- package/dist/remediation/RemediatorBootstrap.d.ts +2 -0
- package/dist/remediation/RemediatorBootstrap.d.ts.map +1 -1
- package/dist/remediation/RemediatorBootstrap.js +7 -0
- package/dist/remediation/RemediatorBootstrap.js.map +1 -1
- package/dist/remediation/audit/AuditWriter.d.ts +9 -3
- package/dist/remediation/audit/AuditWriter.d.ts.map +1 -1
- package/dist/remediation/audit/AuditWriter.js +28 -3
- package/dist/remediation/audit/AuditWriter.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +2 -2
- package/src/data/standards-guard-index.json +1 -1
- package/src/data/standards-guard-index.meta.json +2 -2
- package/src/data/standards-registry.meta.json +1 -1
- package/upgrades/1.3.1093.md +26 -0
- package/upgrades/side-effects/remediation-boot-reconciliation.md +31 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"generatedFrom": "source-tree",
|
|
4
4
|
"registrySha256": "7874d3c188714b80d0f49d7e22bcd795422452be9b1ca74a71765fd7bc85180f",
|
|
5
|
-
"packageVersion": "1.3.
|
|
5
|
+
"packageVersion": "1.3.1093",
|
|
6
6
|
"guards": [
|
|
7
7
|
{
|
|
8
8
|
"ref": "docs/canonical-migration-contracts.json",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"sha256": "
|
|
2
|
+
"sha256": "0f036b8899deea493d9a64e6f73d198f5fbd953fb9fe130a2ec901808e01527d",
|
|
3
3
|
"registrySha256": "7874d3c188714b80d0f49d7e22bcd795422452be9b1ca74a71765fd7bc85180f",
|
|
4
|
-
"packageVersion": "1.3.
|
|
4
|
+
"packageVersion": "1.3.1093"
|
|
5
5
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot-time reconciliation between durable remediation intents and the
|
|
3
|
+
* writer's bounded, hydrated audit tail.
|
|
4
|
+
*
|
|
5
|
+
* An intent is written before the first `started` audit row. If the process
|
|
6
|
+
* dies or audit persistence fails in that gap, the next process must make the
|
|
7
|
+
* mismatch visible instead of leaving both read APIs dormant.
|
|
8
|
+
*/
|
|
9
|
+
import type { IntentJournal } from './IntentJournal.js';
|
|
10
|
+
import type { AuditWriter } from './audit/AuditWriter.js';
|
|
11
|
+
export interface IntentAuditReconciliation {
|
|
12
|
+
intentsRead: number;
|
|
13
|
+
auditEntriesRead: number;
|
|
14
|
+
unmatchedIntentAttemptIds: string[];
|
|
15
|
+
}
|
|
16
|
+
export declare function reconcileIntentAudit(intentJournal: IntentJournal, auditWriter: AuditWriter): Promise<IntentAuditReconciliation>;
|
|
17
|
+
//# sourceMappingURL=IntentAuditReconciler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IntentAuditReconciler.d.ts","sourceRoot":"","sources":["../../src/remediation/IntentAuditReconciler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC;AASD,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,yBAAyB,CAAC,CAwBpC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Intent persistence immediately precedes the first audit append. Include a
|
|
2
|
+
// generous overlap before the oldest retained audit row so a missing `started`
|
|
3
|
+
// row remains detectable even when key derivation or a busy host delayed the
|
|
4
|
+
// append. Remediation dispatch is rate-bounded, so this cannot pull an
|
|
5
|
+
// operationally large intent set into the comparison window.
|
|
6
|
+
const INTENT_AUDIT_OVERLAP_MS = 5 * 60 * 1000;
|
|
7
|
+
export async function reconcileIntentAudit(intentJournal, auditWriter) {
|
|
8
|
+
const auditTail = auditWriter.recentTail();
|
|
9
|
+
const earliestAuditTimestamp = auditTail.reduce((earliest, entry) => Math.min(earliest, entry.timestamp), Number.POSITIVE_INFINITY);
|
|
10
|
+
// The tail is a bounded window. Only compare intents inside that window so
|
|
11
|
+
// an old, valid intent is never called unmatched merely because its audit
|
|
12
|
+
// row has aged out of memory. With no audit rows, read all intents: a
|
|
13
|
+
// non-empty intent journal beside an empty projection is itself the signal.
|
|
14
|
+
const cursor = Number.isFinite(earliestAuditTimestamp)
|
|
15
|
+
? Math.max(0, earliestAuditTimestamp - INTENT_AUDIT_OVERLAP_MS)
|
|
16
|
+
: 0;
|
|
17
|
+
const intents = await intentJournal.readSince(cursor);
|
|
18
|
+
const auditedAttemptIds = new Set(auditTail.map((entry) => entry.attemptId));
|
|
19
|
+
const unmatchedIntentAttemptIds = intents
|
|
20
|
+
.filter((intent) => !auditedAttemptIds.has(intent.attemptId))
|
|
21
|
+
.map((intent) => intent.attemptId);
|
|
22
|
+
return {
|
|
23
|
+
intentsRead: intents.length,
|
|
24
|
+
auditEntriesRead: auditTail.length,
|
|
25
|
+
unmatchedIntentAttemptIds,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=IntentAuditReconciler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IntentAuditReconciler.js","sourceRoot":"","sources":["../../src/remediation/IntentAuditReconciler.ts"],"names":[],"mappings":"AAiBA,4EAA4E;AAC5E,+EAA+E;AAC/E,6EAA6E;AAC7E,uEAAuE;AACvE,6DAA6D;AAC7D,MAAM,uBAAuB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,aAA4B,EAC5B,WAAwB;IAExB,MAAM,SAAS,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC;IAC3C,MAAM,sBAAsB,GAAG,SAAS,CAAC,MAAM,CAC7C,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,EACxD,MAAM,CAAC,iBAAiB,CACzB,CAAC;IACF,2EAA2E;IAC3E,0EAA0E;IAC1E,sEAAsE;IACtE,4EAA4E;IAC5E,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACpD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,sBAAsB,GAAG,uBAAuB,CAAC;QAC/D,CAAC,CAAC,CAAC,CAAC;IACN,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7E,MAAM,yBAAyB,GAAG,OAAO;SACtC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;SAC5D,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAErC,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,gBAAgB,EAAE,SAAS,CAAC,MAAM;QAClC,yBAAyB;KAC1B,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntentJournal.d.ts","sourceRoot":"","sources":["../../src/remediation/IntentJournal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;
|
|
1
|
+
{"version":3,"file":"IntentJournal.d.ts","sourceRoot":"","sources":["../../src/remediation/IntentJournal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAOH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAChE,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,YAAY,CAAC;AAE3E,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IAErC;;;OAGG;gBACS,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IAM3D;;;;;;;OAOG;IACG,aAAa,CACjB,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,YAAY,GAAG,aAAa,CAAC,GAClE,OAAO,CAAC,WAAW,CAAC;IAoBvB;;;;OAIG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;CAkBxD"}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
import crypto from 'node:crypto';
|
|
25
25
|
import fs from 'node:fs';
|
|
26
26
|
import path from 'node:path';
|
|
27
|
+
import readline from 'node:readline';
|
|
27
28
|
export class IntentJournal {
|
|
28
29
|
journalPath;
|
|
29
30
|
/**
|
|
@@ -71,9 +72,10 @@ export class IntentJournal {
|
|
|
71
72
|
async readSince(cursor) {
|
|
72
73
|
if (!fs.existsSync(this.journalPath))
|
|
73
74
|
return [];
|
|
74
|
-
const raw = fs.readFileSync(this.journalPath, 'utf8');
|
|
75
75
|
const out = [];
|
|
76
|
-
|
|
76
|
+
const input = fs.createReadStream(this.journalPath, { encoding: 'utf8' });
|
|
77
|
+
const lines = readline.createInterface({ input, crlfDelay: Infinity });
|
|
78
|
+
for await (const line of lines) {
|
|
77
79
|
if (!line)
|
|
78
80
|
continue;
|
|
79
81
|
let parsed;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntentJournal.js","sourceRoot":"","sources":["../../src/remediation/IntentJournal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"IntentJournal.js","sourceRoot":"","sources":["../../src/remediation/IntentJournal.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
* "leave the legacy alert path running."
|
|
41
41
|
*/
|
|
42
42
|
import { RemediationKeyVault } from './RemediationKeyVault.js';
|
|
43
|
+
import { type IntentAuditReconciliation } from './IntentAuditReconciler.js';
|
|
43
44
|
import { type TrustedApprovalChannel } from './TrustElevationSource.js';
|
|
44
45
|
import { Remediator, type ApprovedRunbook } from './Remediator.js';
|
|
45
46
|
import type { ServerSupervisor } from '../lifeline/ServerSupervisor.js';
|
|
@@ -78,6 +79,7 @@ export type BootstrapResult = {
|
|
|
78
79
|
remediator: Remediator;
|
|
79
80
|
vault: RemediationKeyVault;
|
|
80
81
|
registeredRunbookIds: string[];
|
|
82
|
+
intentAuditReconciliation: IntentAuditReconciliation;
|
|
81
83
|
} | {
|
|
82
84
|
disabled: true;
|
|
83
85
|
reason: 'no-secret-backend' | 'config-flag-false';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemediatorBootstrap.d.ts","sourceRoot":"","sources":["../../src/remediation/RemediatorBootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAIH,OAAO,EACL,mBAAmB,EAEpB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAI7D,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,KAAK,CAAC;AAErD,MAAM,WAAW,0BAA0B;IACzC,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,+FAA+F;IAC/F,SAAS,EAAE,MAAM,CAAC;IAClB;;kEAE8D;IAC9D,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;OAGG;IACH,eAAe,CAAC,EAAE,oBAAoB,CAAC;IACvC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,mBAAmB,CAAC;IAC7C;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;CACxC;AAED,MAAM,MAAM,eAAe,GACvB;IACE,QAAQ,EAAE,KAAK,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,oBAAoB,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"RemediatorBootstrap.d.ts","sourceRoot":"","sources":["../../src/remediation/RemediatorBootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAIH,OAAO,EACL,mBAAmB,EAEpB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAI7D,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,KAAK,CAAC;AAErD,MAAM,WAAW,0BAA0B;IACzC,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,+FAA+F;IAC/F,SAAS,EAAE,MAAM,CAAC;IAClB;;kEAE8D;IAC9D,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;OAGG;IACH,eAAe,CAAC,EAAE,oBAAoB,CAAC;IACvC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,mBAAmB,CAAC;IAC7C;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;CACxC;AAED,MAAM,MAAM,eAAe,GACvB;IACE,QAAQ,EAAE,KAAK,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,yBAAyB,EAAE,yBAAyB,CAAC;CACtD,GACD;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,mBAAmB,GAAG,mBAAmB,CAAA;CAAE,CAAC;AAI1E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,eAAe,CAAC,CA4I1B;AAID;;;;;GAKG;AACH,iBAAS,qBAAqB,CAC5B,OAAO,EAAE,mBAAmB,GAC3B,sBAAsB,EAAE,CAM1B;AAED;;;;;GAKG;AACH,iBAAS,sBAAsB,CAC7B,KAAK,EAAE,mBAAmB,GACzB,CAAC,KAAK,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAY5C;AAED,iBAAS,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAKxD;AAED;;;;;;;;;;GAUG;AACH,iBAAS,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAQpE;AAID,0EAA0E;AAC1E,eAAO,MAAM,SAAS;;;;;CAKrB,CAAC;AAGF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D"}
|
|
@@ -44,6 +44,7 @@ import { RemediationKeyVault, RemediationKeyVaultError, } from './RemediationKey
|
|
|
44
44
|
import { MachineLock } from './MachineLock.js';
|
|
45
45
|
import { IntentJournal } from './IntentJournal.js';
|
|
46
46
|
import { AuditWriter } from './audit/AuditWriter.js';
|
|
47
|
+
import { reconcileIntentAudit, } from './IntentAuditReconciler.js';
|
|
47
48
|
import { TrustElevationSource, } from './TrustElevationSource.js';
|
|
48
49
|
import { TelegramApprovalChannel } from './channels/TelegramApprovalChannel.js';
|
|
49
50
|
import { CliApprovalChannel } from './channels/CliApprovalChannel.js';
|
|
@@ -111,6 +112,11 @@ export async function bootstrapRemediator(opts) {
|
|
|
111
112
|
// the rest of the integrity envelope.
|
|
112
113
|
tokenVerifier: makeAuditTokenVerifier(vault),
|
|
113
114
|
});
|
|
115
|
+
const intentAuditReconciliation = await reconcileIntentAudit(intentJournal, auditWriter);
|
|
116
|
+
if (intentAuditReconciliation.unmatchedIntentAttemptIds.length > 0) {
|
|
117
|
+
console.warn(`[RemediatorBootstrap] ${intentAuditReconciliation.unmatchedIntentAttemptIds.length} ` +
|
|
118
|
+
'durable remediation intent(s) have no matching row in the hydrated audit window');
|
|
119
|
+
}
|
|
114
120
|
// 3. F-5 TrustElevationSource. Default autonomy profile is 'supervised' —
|
|
115
121
|
// the minimum that gates upward transitions; matches the spec's stated
|
|
116
122
|
// default for a fresh live-mode opt-in.
|
|
@@ -176,6 +182,7 @@ export async function bootstrapRemediator(opts) {
|
|
|
176
182
|
remediator,
|
|
177
183
|
vault,
|
|
178
184
|
registeredRunbookIds,
|
|
185
|
+
intentAuditReconciliation,
|
|
179
186
|
};
|
|
180
187
|
}
|
|
181
188
|
// ── Internals ────────────────────────────────────────────────────────────
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemediatorBootstrap.js","sourceRoot":"","sources":["../../src/remediation/RemediatorBootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EACL,oBAAoB,GAErB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"RemediatorBootstrap.js","sourceRoot":"","sources":["../../src/remediation/RemediatorBootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* - <stateDir>/remediation/audit-projection-<machineId>.jsonl (accepted)
|
|
14
14
|
* - <stateDir>/remediation/audit-rejected.jsonl (rejected)
|
|
15
15
|
*
|
|
16
|
-
* In-memory tail (A29): the writer keeps the last 1,000 accepted
|
|
17
|
-
*
|
|
16
|
+
* In-memory tail (A29): the writer hydrates and keeps the last 1,000 accepted
|
|
17
|
+
* entries for hot-path reads by boot reconciliation and projection consumers.
|
|
18
18
|
*/
|
|
19
19
|
export type AuditOutcome = 'started' | 'verified-healthy' | 'verify-failed' | 'verify-inconclusive' | 'aborted-deadline' | 'no-matching-runbook' | 'covered-by-inline';
|
|
20
20
|
export interface AuditEntry {
|
|
@@ -77,11 +77,17 @@ export declare class AuditWriter {
|
|
|
77
77
|
* file and DO NOT touch the projection.
|
|
78
78
|
*/
|
|
79
79
|
append(entry: AuditEntry): Promise<AppendResult>;
|
|
80
|
-
/**
|
|
80
|
+
/** Hydrated in-memory tail of the last N accepted entries (A29). */
|
|
81
81
|
recentTail(): AuditEntry[];
|
|
82
82
|
private persistAccepted;
|
|
83
83
|
private persistRejected;
|
|
84
84
|
private pushTail;
|
|
85
|
+
/**
|
|
86
|
+
* Restore the hot read index from the durable projection at process boot.
|
|
87
|
+
* The tail is bounded by both entry count and bytes so a long-lived audit
|
|
88
|
+
* log never turns construction into a whole-file synchronous read.
|
|
89
|
+
*/
|
|
90
|
+
private hydrateTail;
|
|
85
91
|
}
|
|
86
92
|
export declare function deserializeAuditEntry(line: string): AuditEntry;
|
|
87
93
|
//# sourceMappingURL=AuditWriter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuditWriter.d.ts","sourceRoot":"","sources":["../../../src/remediation/audit/AuditWriter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;
|
|
1
|
+
{"version":3,"file":"AuditWriter.d.ts","sourceRoot":"","sources":["../../../src/remediation/audit/AuditWriter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,kBAAkB,GAClB,eAAe,GACf,qBAAqB,GACrB,kBAAkB,GAClB,qBAAqB,GACrB,mBAAmB,CAAC;AAExB,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC;IAC9C,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAKD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiC;IAC/D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,IAAI,CAAoB;IAChC;;;;OAIG;IACH,OAAO,CAAC,aAAa,CAAkC;gBAE3C,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;IAUzD;;;;OAIG;IACG,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC;IAkBtD,oEAAoE;IACpE,UAAU,IAAI,UAAU,EAAE;IAM1B,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,QAAQ;IAOhB;;;;OAIG;IACH,OAAO,CAAC,WAAW;CAoBpB;AAsBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAc9D"}
|
|
@@ -13,12 +13,14 @@
|
|
|
13
13
|
* - <stateDir>/remediation/audit-projection-<machineId>.jsonl (accepted)
|
|
14
14
|
* - <stateDir>/remediation/audit-rejected.jsonl (rejected)
|
|
15
15
|
*
|
|
16
|
-
* In-memory tail (A29): the writer keeps the last 1,000 accepted
|
|
17
|
-
*
|
|
16
|
+
* In-memory tail (A29): the writer hydrates and keeps the last 1,000 accepted
|
|
17
|
+
* entries for hot-path reads by boot reconciliation and projection consumers.
|
|
18
18
|
*/
|
|
19
19
|
import fs from 'node:fs';
|
|
20
20
|
import path from 'node:path';
|
|
21
|
+
import { readJsonlTailLastLines } from '../../utils/jsonl-tail.js';
|
|
21
22
|
const DEFAULT_TAIL_SIZE = 1000;
|
|
23
|
+
const AUDIT_TAIL_MAX_BYTES = 2 * 1024 * 1024;
|
|
22
24
|
export class AuditWriter {
|
|
23
25
|
projectionPath;
|
|
24
26
|
rejectedPath;
|
|
@@ -38,6 +40,7 @@ export class AuditWriter {
|
|
|
38
40
|
this.rejectedPath = path.join(dir, 'audit-rejected.jsonl');
|
|
39
41
|
this.tokenVerifier = options.tokenVerifier;
|
|
40
42
|
this.tailSize = options.tailSize ?? DEFAULT_TAIL_SIZE;
|
|
43
|
+
this.hydrateTail();
|
|
41
44
|
}
|
|
42
45
|
/**
|
|
43
46
|
* Append an entry. Verified entries land in the projection file and the
|
|
@@ -61,7 +64,7 @@ export class AuditWriter {
|
|
|
61
64
|
this.pushTail(entry);
|
|
62
65
|
return { accepted: true };
|
|
63
66
|
}
|
|
64
|
-
/**
|
|
67
|
+
/** Hydrated in-memory tail of the last N accepted entries (A29). */
|
|
65
68
|
recentTail() {
|
|
66
69
|
return [...this.tail];
|
|
67
70
|
}
|
|
@@ -98,6 +101,28 @@ export class AuditWriter {
|
|
|
98
101
|
this.tail.splice(0, this.tail.length - this.tailSize);
|
|
99
102
|
}
|
|
100
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Restore the hot read index from the durable projection at process boot.
|
|
106
|
+
* The tail is bounded by both entry count and bytes so a long-lived audit
|
|
107
|
+
* log never turns construction into a whole-file synchronous read.
|
|
108
|
+
*/
|
|
109
|
+
hydrateTail() {
|
|
110
|
+
const lines = readJsonlTailLastLines(this.projectionPath, this.tailSize, AUDIT_TAIL_MAX_BYTES);
|
|
111
|
+
for (const line of lines) {
|
|
112
|
+
try {
|
|
113
|
+
const entry = deserializeAuditEntry(line);
|
|
114
|
+
this.pushTail(entry);
|
|
115
|
+
const key = `${entry.subsystem}:${entry.attemptId}`;
|
|
116
|
+
const previous = this.highWatermark.get(key) ?? 0;
|
|
117
|
+
this.highWatermark.set(key, Math.max(previous, entry.timestamp));
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// A malformed durable row is omitted from the hot read index. The
|
|
121
|
+
// append path remains available, and boot reconciliation will surface
|
|
122
|
+
// any intent whose matching audit evidence is consequently absent.
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
101
126
|
}
|
|
102
127
|
function serializeEntryObj(e) {
|
|
103
128
|
const obj = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuditWriter.js","sourceRoot":"","sources":["../../../src/remediation/audit/AuditWriter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"AuditWriter.js","sourceRoot":"","sources":["../../../src/remediation/audit/AuditWriter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAoDnE,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,oBAAoB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7C,MAAM,OAAO,WAAW;IACL,cAAc,CAAS;IACvB,YAAY,CAAS;IACrB,aAAa,CAAiC;IAC9C,QAAQ,CAAS;IAC1B,IAAI,GAAiB,EAAE,CAAC;IAChC;;;;OAIG;IACK,aAAa,GAAwB,IAAI,GAAG,EAAE,CAAC;IAEvD,YAAY,QAAgB,EAAE,OAA2B;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QAC/C,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,OAAO,CAAC,SAAS,QAAQ,CAAC,CAAC;QACpF,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;QAC3D,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,iBAAiB,CAAC;QACtD,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,KAAiB;QAC5B,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;YACnD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,CAAC;QACpE,CAAC;QACD,MAAM,YAAY,GAAG,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,GAAG,IAAI,EAAE,CAAC;YACjD,sEAAsE;YACtE,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;YACpD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,CAAC;QACrE,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,oEAAoE;IACpE,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,sEAAsE;IAE9D,eAAe,CAAC,KAAiB;QACvC,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1C,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACxD,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACvB,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,KAAiB,EAAE,MAAc;QACvD,MAAM,OAAO,GACX,IAAI,CAAC,SAAS,CAAC;YACb,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,MAAM;YACN,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC;SAChC,CAAC,GAAG,IAAI,CAAC;QACZ,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YAC1B,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAEO,QAAQ,CAAC,KAAiB;QAChC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,WAAW;QACjB,MAAM,KAAK,GAAG,sBAAsB,CAClC,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,QAAQ,EACb,oBAAoB,CACrB,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;gBAC1C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACrB,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAClD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YACnE,CAAC;YAAC,MAAM,CAAC;gBACP,kEAAkE;gBAClE,sEAAsE;gBACtE,mEAAmE;YACrE,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED,SAAS,iBAAiB,CAAC,CAAa;IACtC,MAAM,GAAG,GAA4B;QACnC,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE;QACrC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;KAC5C,CAAC;IACF,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS;QAAE,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;IAC3D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,cAAc,CAAC,CAAa;IACnC,OAAO,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;QAC5B,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;QAChC,OAAO,EAAE,GAAG,CAAC,OAAuB;QACpC,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;QAC5D,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;QAChC,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;QAC5D,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;QAChC,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC;QACpC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC;KAC1D,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-07-31T23:
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-07-31T23:29:36.335Z",
|
|
5
|
+
"instarVersion": "1.3.1093",
|
|
6
6
|
"entryCount": 202,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"generatedFrom": "source-tree",
|
|
4
4
|
"registrySha256": "7874d3c188714b80d0f49d7e22bcd795422452be9b1ca74a71765fd7bc85180f",
|
|
5
|
-
"packageVersion": "1.3.
|
|
5
|
+
"packageVersion": "1.3.1093",
|
|
6
6
|
"guards": [
|
|
7
7
|
{
|
|
8
8
|
"ref": "docs/canonical-migration-contracts.json",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"sha256": "
|
|
2
|
+
"sha256": "0f036b8899deea493d9a64e6f73d198f5fbd953fb9fe130a2ec901808e01527d",
|
|
3
3
|
"registrySha256": "7874d3c188714b80d0f49d7e22bcd795422452be9b1ca74a71765fd7bc85180f",
|
|
4
|
-
"packageVersion": "1.3.
|
|
4
|
+
"packageVersion": "1.3.1093"
|
|
5
5
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
Remediator startup now restores its bounded audit tail and compares recent
|
|
9
|
+
durable intents with audit evidence. Missing evidence is surfaced during boot.
|
|
10
|
+
|
|
11
|
+
## What to Tell Your User
|
|
12
|
+
|
|
13
|
+
- **Restart-safe remediation evidence**: "After a restart, I now check that recent remediation intents have matching audit records instead of leaving the journals unread."
|
|
14
|
+
|
|
15
|
+
## Summary of New Capabilities
|
|
16
|
+
|
|
17
|
+
| Capability | How to Use |
|
|
18
|
+
|---|---|
|
|
19
|
+
| Detect an intent-to-audit persistence gap | Automatic whenever live remediation bootstraps |
|
|
20
|
+
| Inspect reconciliation proof | Read the bootstrap reconciliation counts and boot warning |
|
|
21
|
+
|
|
22
|
+
## Evidence
|
|
23
|
+
|
|
24
|
+
Twenty-three focused tests cover audit-tail hydration and bounds, matching and
|
|
25
|
+
missing intent evidence, real bootstrap reachability, corrupt intent rows, and
|
|
26
|
+
existing token/watermark enforcement.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Side-effect review — remediation boot reconciliation
|
|
2
|
+
|
|
3
|
+
## Changed boundary
|
|
4
|
+
|
|
5
|
+
`AuditWriter` hydrates its existing recent-tail read view from the durable
|
|
6
|
+
projection during construction. `RemediatorBootstrap` invokes that view and
|
|
7
|
+
`IntentJournal.readSince()` through a dedicated reconciler before it registers
|
|
8
|
+
the live Remediator with the degradation path.
|
|
9
|
+
|
|
10
|
+
## Expected effects
|
|
11
|
+
|
|
12
|
+
- Restarted remediation processes retain a bounded hot audit window.
|
|
13
|
+
- Recent intent-without-audit gaps produce one boot warning with a count.
|
|
14
|
+
- The bootstrap result exposes reconciliation counts for diagnostics and tests.
|
|
15
|
+
|
|
16
|
+
## Bounds and failure behavior
|
|
17
|
+
|
|
18
|
+
- Audit hydration reads at most 1,000 rows and two megabytes from the file tail.
|
|
19
|
+
- Intent scanning uses an asynchronous stream rather than blocking on a full
|
|
20
|
+
synchronous read; malformed individual lines retain the existing skip rule.
|
|
21
|
+
- The comparison uses a five-minute overlap before the oldest retained audit
|
|
22
|
+
row so the intent that immediately preceded it remains visible.
|
|
23
|
+
- Reconciliation is signal-only. It never retries, rolls back, or performs a
|
|
24
|
+
remediation, and an old intent outside the retained audit window is not
|
|
25
|
+
misclassified as a current mismatch.
|
|
26
|
+
|
|
27
|
+
## Class-closure declaration
|
|
28
|
+
|
|
29
|
+
This closes a dormant-reader wiring class at bootstrap. The dedicated unit test
|
|
30
|
+
proves both readers are invoked, and the bootstrap test proves persisted rows
|
|
31
|
+
survive construction and reach the reconciliation result.
|