pi-mega-compact 0.20.0 → 0.20.1
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/config/vector-cortex.js +12 -0
- package/dist/config.js +1 -1
- package/dist/extensions/dashboard-server/routes-rag-settings-helpers.js +1 -0
- package/dist/extensions/dashboard-server/routes-vector-cortex-residual.js +51 -0
- package/dist/extensions/dashboard-server/routes-vector-cortex.js +1 -0
- package/dist/extensions/dashboard-server/routes.js +1 -1
- package/dist/extensions/dashboard-server/server.js +3 -1
- package/dist/src/config/vector-cortex.js +12 -0
- package/dist/src/config.js +1 -1
- package/dist/src/vector-cortex/residual/codec.js +224 -0
- package/dist/src/vector-cortex/residual/dct.js +158 -0
- package/dist/src/vector-cortex/residual/fixture-payload.js +77 -0
- package/dist/src/vector-cortex/residual/gf256.js +182 -0
- package/dist/src/vector-cortex/residual/parity.js +245 -0
- package/dist/src/vector-cortex/residual/quantize.js +200 -0
- package/dist/src/vector-cortex/residual/stream.js +124 -0
- package/dist/src/vector-cortex/residual/types.js +55 -0
- package/dist/vector-cortex/residual/codec.js +224 -0
- package/dist/vector-cortex/residual/dct.js +158 -0
- package/dist/vector-cortex/residual/fixture-payload.js +77 -0
- package/dist/vector-cortex/residual/gf256.js +182 -0
- package/dist/vector-cortex/residual/parity.js +245 -0
- package/dist/vector-cortex/residual/quantize.js +200 -0
- package/dist/vector-cortex/residual/stream.js +124 -0
- package/dist/vector-cortex/residual/types.js +55 -0
- package/extensions/dashboard-server/api-contracts/vector-cortex.ts +29 -0
- package/extensions/dashboard-server/routes-rag-settings-helpers.ts +6 -0
- package/extensions/dashboard-server/routes-vector-cortex-residual.ts +60 -0
- package/extensions/dashboard-server/routes-vector-cortex.ts +1 -0
- package/extensions/dashboard-server/routes.ts +1 -0
- package/extensions/dashboard-server/server.ts +2 -0
- package/package.json +1 -1
- package/src/config/vector-cortex.ts +13 -0
- package/src/config.ts +1 -0
- package/src/vector-cortex/residual/codec.ts +292 -0
- package/src/vector-cortex/residual/dct.ts +166 -0
- package/src/vector-cortex/residual/fixture-payload.ts +90 -0
- package/src/vector-cortex/residual/gf256.ts +196 -0
- package/src/vector-cortex/residual/parity.ts +283 -0
- package/src/vector-cortex/residual/quantize.ts +230 -0
- package/src/vector-cortex/residual/stream.ts +135 -0
- package/src/vector-cortex/residual/types.ts +236 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vector-cortex/residual/stream.ts — canonical PROTECTED STREAM serialization
|
|
3
|
+
* for the VC4B residual codec.
|
|
4
|
+
*
|
|
5
|
+
* The protected stream is `header + all block scales/coefficient arrays +
|
|
6
|
+
* corrections` (RESIDUAL_CODEC §erasure parity), serialized in exactly this
|
|
7
|
+
* canonical order so encode and decode are byte-symmetric:
|
|
8
|
+
*
|
|
9
|
+
* header (46 bytes) magic `VCR1` | u32 LE originalLength | 32-byte SHA-256
|
|
10
|
+
* | u16 LE blockSize | u16 LE k | u16 LE m
|
|
11
|
+
* blocks for each block in ascending index:
|
|
12
|
+
* float32 LE scale | 4096 * int16 LE coefficient
|
|
13
|
+
* corrections varint blockCount, then per non-empty block
|
|
14
|
+
* u32 LE blockIndex | varint count
|
|
15
|
+
* | count * (u16 LE offset, u8 original)
|
|
16
|
+
*
|
|
17
|
+
* Pure serialization: no storage, no console, no network (PREVENT-PI-004 /
|
|
18
|
+
* PREVENT-011).
|
|
19
|
+
*/
|
|
20
|
+
import { parseCorrections, serializeCorrections, } from "./quantize.js";
|
|
21
|
+
import { RESIDUAL_BLOCK_SIZE, RESIDUAL_HEADER_BYTES, RESIDUAL_MAGIC, RS_DATA_SHARDS, RS_PARITY_SHARDS, } from "./types.js";
|
|
22
|
+
/** Per-block serialized size: float32 scale + n int16 coefficients. */
|
|
23
|
+
export function blockBytes(blockSize = RESIDUAL_BLOCK_SIZE) {
|
|
24
|
+
return 4 + blockSize * 2;
|
|
25
|
+
}
|
|
26
|
+
/** Serialize the canonical 46-byte header. */
|
|
27
|
+
export function serializeHeader(header) {
|
|
28
|
+
const out = new Uint8Array(RESIDUAL_HEADER_BYTES);
|
|
29
|
+
const view = new DataView(out.buffer);
|
|
30
|
+
for (let i = 0; i < 4; i++)
|
|
31
|
+
out[i] = RESIDUAL_MAGIC.charCodeAt(i);
|
|
32
|
+
view.setUint32(4, header.originalLength, true);
|
|
33
|
+
const digest = Buffer.from(header.payloadDigest, "hex");
|
|
34
|
+
out.set(digest.subarray(0, 32), 8);
|
|
35
|
+
view.setUint16(40, header.blockSize, true);
|
|
36
|
+
view.setUint16(42, header.dataShards, true);
|
|
37
|
+
view.setUint16(44, header.parityShards, true);
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
/** Parse the canonical header. Returns null on magic/geometry mismatch. */
|
|
41
|
+
export function parseHeader(bytes) {
|
|
42
|
+
if (bytes.length < RESIDUAL_HEADER_BYTES)
|
|
43
|
+
return null;
|
|
44
|
+
for (let i = 0; i < 4; i++) {
|
|
45
|
+
if (bytes[i] !== RESIDUAL_MAGIC.charCodeAt(i))
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
49
|
+
const originalLength = view.getUint32(4, true);
|
|
50
|
+
const payloadDigest = Buffer.from(bytes.subarray(8, 40)).toString("hex");
|
|
51
|
+
const blockSize = view.getUint16(40, true);
|
|
52
|
+
const dataShards = view.getUint16(42, true);
|
|
53
|
+
const parityShards = view.getUint16(44, true);
|
|
54
|
+
if (blockSize !== RESIDUAL_BLOCK_SIZE)
|
|
55
|
+
return null;
|
|
56
|
+
if (dataShards !== RS_DATA_SHARDS || parityShards !== RS_PARITY_SHARDS)
|
|
57
|
+
return null;
|
|
58
|
+
return {
|
|
59
|
+
magic: RESIDUAL_MAGIC,
|
|
60
|
+
originalLength,
|
|
61
|
+
payloadDigest,
|
|
62
|
+
blockSize: RESIDUAL_BLOCK_SIZE,
|
|
63
|
+
dataShards: RS_DATA_SHARDS,
|
|
64
|
+
parityShards: RS_PARITY_SHARDS,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Serialize the full protected stream for one encoded artifact. */
|
|
68
|
+
export function serializeStream(codec) {
|
|
69
|
+
const head = serializeHeader(codec.header);
|
|
70
|
+
const perBlock = blockBytes(codec.header.blockSize);
|
|
71
|
+
const corrections = serializeCorrections(codec.corrections);
|
|
72
|
+
const out = new Uint8Array(head.length + codec.blocks.length * perBlock + corrections.length);
|
|
73
|
+
out.set(head, 0);
|
|
74
|
+
const view = new DataView(out.buffer);
|
|
75
|
+
let pos = head.length;
|
|
76
|
+
for (const block of codec.blocks) {
|
|
77
|
+
view.setFloat32(pos, block.scale, true);
|
|
78
|
+
pos += 4;
|
|
79
|
+
for (let i = 0; i < block.coefficients.length; i++) {
|
|
80
|
+
view.setInt16(pos, block.coefficients[i], true);
|
|
81
|
+
pos += 2;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
out.set(corrections, pos);
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
/** Parse a protected stream back into the codec artifact. Null on malformed. */
|
|
88
|
+
export function parseStream(stream) {
|
|
89
|
+
const header = parseHeader(stream);
|
|
90
|
+
if (!header)
|
|
91
|
+
return null;
|
|
92
|
+
const perBlock = blockBytes(header.blockSize);
|
|
93
|
+
const blockCount = Math.ceil(header.originalLength / header.blockSize);
|
|
94
|
+
const bodyEnd = RESIDUAL_HEADER_BYTES + blockCount * perBlock;
|
|
95
|
+
if (stream.length < bodyEnd)
|
|
96
|
+
return null;
|
|
97
|
+
const view = new DataView(stream.buffer, stream.byteOffset, stream.byteLength);
|
|
98
|
+
const blocks = [];
|
|
99
|
+
let pos = RESIDUAL_HEADER_BYTES;
|
|
100
|
+
for (let b = 0; b < blockCount; b++) {
|
|
101
|
+
const scale = view.getFloat32(pos, true);
|
|
102
|
+
pos += 4;
|
|
103
|
+
const coefficients = new Int16Array(header.blockSize);
|
|
104
|
+
for (let i = 0; i < header.blockSize; i++) {
|
|
105
|
+
coefficients[i] = view.getInt16(pos, true);
|
|
106
|
+
pos += 2;
|
|
107
|
+
}
|
|
108
|
+
blocks.push({ scale, coefficients });
|
|
109
|
+
}
|
|
110
|
+
const parsed = parseCorrections(stream, pos);
|
|
111
|
+
if (!parsed)
|
|
112
|
+
return null;
|
|
113
|
+
// Every correction must name a block that exists.
|
|
114
|
+
for (const block of parsed.blocks) {
|
|
115
|
+
if (block.blockIndex >= blockCount)
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
schema: "residual-codec-v1",
|
|
120
|
+
header,
|
|
121
|
+
blocks,
|
|
122
|
+
corrections: parsed.blocks,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vector-cortex/residual/types.ts — reversible residual payload codec (VC4B).
|
|
3
|
+
*
|
|
4
|
+
* Owns `ResidualCodecV1` / `ParityShardV1` — the contract of the sprint failure
|
|
5
|
+
* triad:
|
|
6
|
+
*
|
|
7
|
+
* A = admitted residual (DCT + int16 + exact corrections) + RS(9,6) parity;
|
|
8
|
+
* B = exact compressed bytes (forced when the >95% accounting rejects A);
|
|
9
|
+
* C = ledger bytes (forced when A/B decode fails).
|
|
10
|
+
*
|
|
11
|
+
* Semantic vectors NEVER claim to recover exact text. Exact bytes come only from
|
|
12
|
+
* exact payload shards (VC4A `ExactShardV1`) or this REVERSIBLE codec: a block
|
|
13
|
+
* DCT-II analysis, int16 quantization, and a block-scoped exact correction
|
|
14
|
+
* stream that makes post-decode byte error exactly zero for admitted artifacts.
|
|
15
|
+
* Numeric erasure parity protects the codec bytes; it is not a substitute for
|
|
16
|
+
* the exact payload (RESIDUAL_CODEC.md).
|
|
17
|
+
*
|
|
18
|
+
* Consumes only reviewer-accepted predecessor contracts (VC1A EventV2 bytes via
|
|
19
|
+
* VC4A shard ranges) and the common contracts. Pure types + registered
|
|
20
|
+
* conformance IDs: no storage, no console, no network (PREVENT-PI-004 /
|
|
21
|
+
* PREVENT-011).
|
|
22
|
+
*/
|
|
23
|
+
/** Fixed transform block length (RESIDUAL_CODEC §byte scope: 4096). */
|
|
24
|
+
export const RESIDUAL_BLOCK_SIZE = 4096;
|
|
25
|
+
/** Reed–Solomon shard geometry: k=6 data shards, m=3 parity shards. */
|
|
26
|
+
export const RS_DATA_SHARDS = 6;
|
|
27
|
+
export const RS_PARITY_SHARDS = 3;
|
|
28
|
+
export const RS_TOTAL_SHARDS = RS_DATA_SHARDS + RS_PARITY_SHARDS;
|
|
29
|
+
/** GF(2^8) primitive polynomial for the parity field (0x11d). */
|
|
30
|
+
export const GF_PRIMITIVE_POLYNOMIAL = 0x11d;
|
|
31
|
+
/** Header magic bytes `VCR1`. */
|
|
32
|
+
export const RESIDUAL_MAGIC = "VCR1";
|
|
33
|
+
/**
|
|
34
|
+
* Admission ratio: residual is admitted only when its FULL encoded size is at
|
|
35
|
+
* most `floor(0.95 * exactCompressedSize)` (RESIDUAL_CODEC §admission). The
|
|
36
|
+
* accounting counts every persisted byte — header, scales, coefficients,
|
|
37
|
+
* corrections, shard metadata, all 9 shards, and digests.
|
|
38
|
+
*/
|
|
39
|
+
export const ADMISSION_NUMERATOR = 95;
|
|
40
|
+
export const ADMISSION_DENOMINATOR = 100;
|
|
41
|
+
/** Serialized header byte length: 4 + 4 + 32 + 2 + 2 + 2. */
|
|
42
|
+
export const RESIDUAL_HEADER_BYTES = 46;
|
|
43
|
+
/**
|
|
44
|
+
* Registered RES conformance ID range (RES-001..050). The acceptance test reads
|
|
45
|
+
* these rows from the v2 manifest and asserts each returns its manifest
|
|
46
|
+
* `ok`/`code`. The three named assertions (RES-DCT-001 / RES-RS-002 /
|
|
47
|
+
* RES-ADMIT-003) live alongside them.
|
|
48
|
+
*/
|
|
49
|
+
export const RES_IDS = Array.from({ length: 50 }, (_v, i) => `RES-${String(i + 1).padStart(3, "0")}`);
|
|
50
|
+
/** Named RES conformance assertions (the sprint's headline rows). */
|
|
51
|
+
export const RES_NAMED_IDS = [
|
|
52
|
+
"RES-DCT-001",
|
|
53
|
+
"RES-RS-002",
|
|
54
|
+
"RES-ADMIT-003",
|
|
55
|
+
];
|
|
@@ -201,6 +201,35 @@ export interface VectorCortexShardsView {
|
|
|
201
201
|
readonly updatedAt: string;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Reader-only residual-basis-parity aggregate for GET /api/vector-cortex/residual
|
|
206
|
+
* (VC4B). Purely an enabled-flag + COUNT/BYTE aggregate — encode attempts,
|
|
207
|
+
* admitted/rejected counts, recovery failures, and encoded/exact byte totals.
|
|
208
|
+
* Reader-only: NEVER exposes residual payloads, correction streams, shard bytes,
|
|
209
|
+
* or original source bytes (SECURITY_PRIVACY). The residual codec is pure
|
|
210
|
+
* in-memory logic in this sprint (no durable metrics store), so when no encode has
|
|
211
|
+
* been staged the aggregates are truthfully zero. Non-fatal: a missing state dir
|
|
212
|
+
* degrades to `enabled:false`.
|
|
213
|
+
*/
|
|
214
|
+
export interface VectorCortexResidualView {
|
|
215
|
+
/** Whether the VC4B residual basis parity flag is enabled in this process. */
|
|
216
|
+
readonly enabled: boolean;
|
|
217
|
+
/** Number of residual encode attempts observed by the process emitter. */
|
|
218
|
+
readonly encodeAttempts: number;
|
|
219
|
+
/** Number of payloads admitted under the 95% admission ceiling. */
|
|
220
|
+
readonly admittedCount: number;
|
|
221
|
+
/** Number of payloads rejected (failed encode or above ceiling). */
|
|
222
|
+
readonly rejectedCount: number;
|
|
223
|
+
/** Number of parity recoveries that failed closed (RES_TOO_MANY_ERASURES). */
|
|
224
|
+
readonly recoveryFailures: number;
|
|
225
|
+
/** Total encoded artifact bytes across admitted payloads. */
|
|
226
|
+
readonly encodedByteTotal: number;
|
|
227
|
+
/** Total exact-compressed bytes across admitted payloads (denominator). */
|
|
228
|
+
readonly exactByteTotal: number;
|
|
229
|
+
/** ISO timestamp of the snapshot. */
|
|
230
|
+
readonly updatedAt: string;
|
|
231
|
+
}
|
|
232
|
+
|
|
204
233
|
/**
|
|
205
234
|
* Reader-only occurrence-ledger view for GET /api/vector-cortex/ledger (VC1B).
|
|
206
235
|
* Built on the LedgerReader capability surface. Exposes occurrence IDENTITY
|
|
@@ -355,6 +355,12 @@ export const SETTINGS: ReadonlyArray<{
|
|
|
355
355
|
"SemanticShardV1/ExactShardV1/ShardManifestV1: partition a session ONLY at complete EventV2 boundaries; exact shards preserve every tool call/result pair, anchor and invalid UTF-8 event as original bytes (pairs never split across exact shards); manifest enforces disjoint sorted ranges + complete protected-span coverage. OFF = mode C, exact anchors/current transcript only, byte-identical predecessor.",
|
|
356
356
|
true,
|
|
357
357
|
),
|
|
358
|
+
boolDirect(
|
|
359
|
+
"MEGACOMPACT_VC4B",
|
|
360
|
+
"VC4B Residual Basis Parity",
|
|
361
|
+
"Residual codec: orthonormal DCT-II basis + int16 block quantization + block-scoped exact correction stream + (9,6) Reed-Solomon parity shards with SHA-256 corruption detection; admission gates on encodedSize <= 95% of exact-compressed size. OFF = mode C, no residual artifact produced, byte-identical predecessor.",
|
|
362
|
+
true,
|
|
363
|
+
),
|
|
358
364
|
],
|
|
359
365
|
},
|
|
360
366
|
{
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-server/routes-vector-cortex-residual.ts — VC4B residual basis parity
|
|
3
|
+
* dashboard route.
|
|
4
|
+
*
|
|
5
|
+
* Reader-only GET /api/vector-cortex/residual returning a COUNT/BYTE aggregate
|
|
6
|
+
* (encode attempts, admitted/rejected counts, recovery failures, encoded/exact
|
|
7
|
+
* byte totals) — never residual payloads, correction streams, shard bytes, or
|
|
8
|
+
* original source bytes. Flag-gated on MEGACOMPACT_VC4B: `enabled:false` when off
|
|
9
|
+
* (byte-identical to the pre-VC4B predecessor).
|
|
10
|
+
*
|
|
11
|
+
* The VC4B residual codec is PURE IN-MEMORY logic in this sprint (it has no
|
|
12
|
+
* durable metrics store yet), so the aggregate reports the current status
|
|
13
|
+
* truthfully: `enabled` reflects the flag, and the count/byte fields are zero
|
|
14
|
+
* until a future sprint persists a metrics store. This route is the seam that
|
|
15
|
+
* sprint will populate. Non-fatal: a missing state dir degrades to
|
|
16
|
+
* `enabled:false`.
|
|
17
|
+
*
|
|
18
|
+
* Guardrails: PREVENT-PI-004 (local filesystem read only / in-process state),
|
|
19
|
+
* PREVENT-011 (no `any`), reader-only aggregate (counts/bytes only).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
23
|
+
import type { RouteContext } from "./routes-core.js";
|
|
24
|
+
import { VC4B_ENABLED } from "../../src/config.js";
|
|
25
|
+
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
26
|
+
import type { VectorCortexResidualView } from "./api-contracts/vector-cortex.js";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Reader-only GET /api/vector-cortex/residual (VC4B).
|
|
30
|
+
*/
|
|
31
|
+
export function handleVectorCortexResidual(
|
|
32
|
+
req: IncomingMessage,
|
|
33
|
+
res: ServerResponse,
|
|
34
|
+
_ctx: RouteContext,
|
|
35
|
+
): boolean {
|
|
36
|
+
const url = req.url ?? "";
|
|
37
|
+
const path = url.split("?")[0] ?? url;
|
|
38
|
+
if (path !== "/api/vector-cortex/residual") return false;
|
|
39
|
+
if (req.method !== "GET") {
|
|
40
|
+
// Reader-only path: cannot be "off" without a GET; it is genuinely read-only.
|
|
41
|
+
sendJson(res, 405, { error: "method_not_allowed" });
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const enabled = VC4B_ENABLED();
|
|
46
|
+
const body: VectorCortexResidualView = {
|
|
47
|
+
enabled,
|
|
48
|
+
// No durable residual metrics store is staged yet in this sprint (pure
|
|
49
|
+
// in-memory encode), so the aggregates are truthfully zero.
|
|
50
|
+
encodeAttempts: 0,
|
|
51
|
+
admittedCount: 0,
|
|
52
|
+
rejectedCount: 0,
|
|
53
|
+
recoveryFailures: 0,
|
|
54
|
+
encodedByteTotal: 0,
|
|
55
|
+
exactByteTotal: 0,
|
|
56
|
+
updatedAt: new Date().toISOString(),
|
|
57
|
+
};
|
|
58
|
+
sendJson(res, 200, body);
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
@@ -20,3 +20,4 @@ export { handleVectorCortexLedger } from "./routes-vector-cortex-ledger.js";
|
|
|
20
20
|
export { handleVectorCortexTopology } from "./routes-vector-cortex-topology.js";
|
|
21
21
|
export { handleVectorCortexQuery } from "./routes-vector-cortex-query.js";
|
|
22
22
|
export { handleVectorCortexShards } from "./routes-vector-cortex-shards.js";
|
|
23
|
+
export { handleVectorCortexResidual } from "./routes-vector-cortex-residual.js";
|
|
@@ -64,6 +64,7 @@ import {
|
|
|
64
64
|
handleVectorCortexTopology,
|
|
65
65
|
handleVectorCortexQuery,
|
|
66
66
|
handleVectorCortexShards,
|
|
67
|
+
handleVectorCortexResidual,
|
|
67
68
|
handleStatic,
|
|
68
69
|
} from "./routes.js";
|
|
69
70
|
|
|
@@ -306,6 +307,7 @@ export async function launchDashboardServer(
|
|
|
306
307
|
if (handleVectorCortexTopology(req, res, ctx)) return;
|
|
307
308
|
if (handleVectorCortexQuery(req, res, ctx)) return;
|
|
308
309
|
if (handleVectorCortexShards(req, res, ctx)) return;
|
|
310
|
+
if (handleVectorCortexResidual(req, res, ctx)) return;
|
|
309
311
|
handleStatic(req, res, ctx);
|
|
310
312
|
});
|
|
311
313
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mega-compact",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.1",
|
|
4
4
|
"description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -147,6 +147,19 @@ export const VC3C_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC3C");
|
|
|
147
147
|
*/
|
|
148
148
|
export const VC4A_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC4A");
|
|
149
149
|
|
|
150
|
+
/**
|
|
151
|
+
* VC4B — residual codec and numeric parity (ResidualCodecV1 / ParityShardV1).
|
|
152
|
+
* Default ON. `MEGACOMPACT_VC4B=0` disables and is byte-identical to the
|
|
153
|
+
* predecessor (mode C: no residual artifact is admitted, the exact compressed
|
|
154
|
+
* payload / ledger bytes remain the only representation, zero
|
|
155
|
+
* `vector_cortex_residual_admitted` / `vector_cortex_parity_recovery_failed`
|
|
156
|
+
* emissions; the VC4A shard manifest and its goldens are unchanged). The real
|
|
157
|
+
* consumers are the codec admission seam (codec.ts) and the reader-only
|
|
158
|
+
* dashboard residual aggregate view. The codec math itself is PURE — flag OFF
|
|
159
|
+
* gates the reporter/admission seam, never the arithmetic.
|
|
160
|
+
*/
|
|
161
|
+
export const VC4B_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC4B");
|
|
162
|
+
|
|
150
163
|
// ---------------------------------------------------------------------------
|
|
151
164
|
// Breaker state machine constants (TRIAD_RESILIENCE.md §breaker).
|
|
152
165
|
// Rolled numbers for one 60s window; VC0C consumes these at its breaker seam.
|
package/src/config.ts
CHANGED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vector-cortex/residual/codec.ts — reversible residual payload codec (VC4B).
|
|
3
|
+
*
|
|
4
|
+
* Encode: split `EventV2.originalBytes` into 4096-byte blocks (zero-padding only
|
|
5
|
+
* the final block), map bytes to `x=(byte-127.5)/127.5`, take the orthonormal
|
|
6
|
+
* DCT-II, quantize to int16 with a per-block float32 scale, reconstruct, and
|
|
7
|
+
* append a block-scoped EXACT correction stream wherever the reconstruction
|
|
8
|
+
* differs. Post-decode byte error for an admitted artifact is therefore exactly
|
|
9
|
+
* ZERO — the digest is verified before admission, never assumed.
|
|
10
|
+
*
|
|
11
|
+
* Admission (RESIDUAL_CODEC §admission): residual is admitted only when the FULL
|
|
12
|
+
* encoded size — header, scales, coefficients, corrections, shard index/length
|
|
13
|
+
* metadata, all 9 shards and their digests — is `<= floor(0.95 *
|
|
14
|
+
* exactCompressedSize)` AND the complete decode + digest check succeeds.
|
|
15
|
+
* Otherwise the caller stores the exact compressed payload (mode B). Coefficient
|
|
16
|
+
* bytes alone are never compared.
|
|
17
|
+
*
|
|
18
|
+
* Emits `vector_cortex_residual_admitted` / `vector_cortex_parity_recovery_failed`
|
|
19
|
+
* through the flag-gated reporter and exposes AGGREGATE-ONLY residual metrics
|
|
20
|
+
* (counts/byte totals — never payload).
|
|
21
|
+
*
|
|
22
|
+
* Guardrails: local hashing only, no storage, no console, no network
|
|
23
|
+
* (PREVENT-PI-004 / PREVENT-011).
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { createHash } from "node:crypto";
|
|
27
|
+
import { VC4B_ENABLED } from "../../config/vector-cortex.js";
|
|
28
|
+
import {
|
|
29
|
+
bytesToSignal,
|
|
30
|
+
forwardDct,
|
|
31
|
+
inverseDct,
|
|
32
|
+
signalToBytes,
|
|
33
|
+
splitBlocks,
|
|
34
|
+
} from "./dct.js";
|
|
35
|
+
import {
|
|
36
|
+
applyCorrections,
|
|
37
|
+
dequantizeBlock,
|
|
38
|
+
diffBlock,
|
|
39
|
+
quantizeBlock,
|
|
40
|
+
} from "./quantize.js";
|
|
41
|
+
import { encodeShards, recoverStream, sha256Hex } from "./parity.js";
|
|
42
|
+
import { parseStream, serializeStream } from "./stream.js";
|
|
43
|
+
import {
|
|
44
|
+
ADMISSION_DENOMINATOR,
|
|
45
|
+
ADMISSION_NUMERATOR,
|
|
46
|
+
RESIDUAL_BLOCK_SIZE,
|
|
47
|
+
RESIDUAL_MAGIC,
|
|
48
|
+
RS_DATA_SHARDS,
|
|
49
|
+
RS_PARITY_SHARDS,
|
|
50
|
+
type BlockCorrectionsV1,
|
|
51
|
+
type ParityShardV1,
|
|
52
|
+
type QuantizedBlockV1,
|
|
53
|
+
type ResidualAccountingV1,
|
|
54
|
+
type ResidualCodecV1,
|
|
55
|
+
type ResidualDecodeResult,
|
|
56
|
+
type ResidualEmitter,
|
|
57
|
+
type ResidualEncodeResult,
|
|
58
|
+
type ResidualMetricsV1,
|
|
59
|
+
type ResidualReporter,
|
|
60
|
+
} from "./types.js";
|
|
61
|
+
|
|
62
|
+
/** Per-shard persisted metadata: u8 index + u32 LE length + 32-byte digest. */
|
|
63
|
+
const SHARD_METADATA_BYTES = 1 + 4 + 32;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The inclusive admission ceiling `floor(0.95 * exactCompressedSize)`, computed
|
|
67
|
+
* in integer arithmetic so the boundary is exact (a fractional 0.95 multiply
|
|
68
|
+
* would make the "one byte above rejects" case depend on float rounding).
|
|
69
|
+
*/
|
|
70
|
+
export function admissionCeiling(exactCompressedSize: number): number {
|
|
71
|
+
return Math.floor(
|
|
72
|
+
(exactCompressedSize * ADMISSION_NUMERATOR) / ADMISSION_DENOMINATOR,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Total persisted bytes of the shard set (payload + per-shard metadata). */
|
|
77
|
+
export function shardSetBytes(shards: readonly ParityShardV1[]): number {
|
|
78
|
+
return shards.reduce(
|
|
79
|
+
(n, s) => n + s.bytes.length + SHARD_METADATA_BYTES,
|
|
80
|
+
0,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Build the codec artifact (transform + quantize + exact corrections). */
|
|
85
|
+
export function buildArtifact(
|
|
86
|
+
payload: Uint8Array,
|
|
87
|
+
): { ok: true; codec: ResidualCodecV1 } | { ok: false; code: "RES_QUANTIZE_RANGE" } {
|
|
88
|
+
const digest = sha256Hex(payload);
|
|
89
|
+
const rawBlocks = splitBlocks(payload, RESIDUAL_BLOCK_SIZE);
|
|
90
|
+
const blocks: QuantizedBlockV1[] = [];
|
|
91
|
+
const corrections: BlockCorrectionsV1[] = [];
|
|
92
|
+
|
|
93
|
+
for (let b = 0; b < rawBlocks.length; b++) {
|
|
94
|
+
const original = rawBlocks[b]!;
|
|
95
|
+
const quantized = quantizeBlock(forwardDct(bytesToSignal(original)));
|
|
96
|
+
if (!quantized.ok) return { ok: false, code: "RES_QUANTIZE_RANGE" };
|
|
97
|
+
blocks.push(quantized.block);
|
|
98
|
+
// Reconstruct and diff: any residual byte error becomes an exact correction.
|
|
99
|
+
const reconstructed = signalToBytes(
|
|
100
|
+
inverseDct(dequantizeBlock(quantized.block)),
|
|
101
|
+
);
|
|
102
|
+
const diff = diffBlock(original, reconstructed);
|
|
103
|
+
if (diff.length > 0) corrections.push({ blockIndex: b, corrections: diff });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
ok: true,
|
|
108
|
+
codec: {
|
|
109
|
+
schema: "residual-codec-v1",
|
|
110
|
+
header: {
|
|
111
|
+
magic: RESIDUAL_MAGIC,
|
|
112
|
+
originalLength: payload.length,
|
|
113
|
+
payloadDigest: digest,
|
|
114
|
+
blockSize: RESIDUAL_BLOCK_SIZE,
|
|
115
|
+
dataShards: RS_DATA_SHARDS,
|
|
116
|
+
parityShards: RS_PARITY_SHARDS,
|
|
117
|
+
},
|
|
118
|
+
blocks,
|
|
119
|
+
corrections,
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Encode a payload and decide admission against the competing exact compressed
|
|
126
|
+
* size. Admission requires BOTH the <=95% byte accounting AND a full decode whose
|
|
127
|
+
* digest matches the original payload.
|
|
128
|
+
*/
|
|
129
|
+
export function encodeResidual(
|
|
130
|
+
payload: Uint8Array,
|
|
131
|
+
exactCompressedSize: number,
|
|
132
|
+
emit?: ResidualEmitter,
|
|
133
|
+
): ResidualEncodeResult {
|
|
134
|
+
const built = buildArtifact(payload);
|
|
135
|
+
if (!built.ok) return { ok: false, code: built.code };
|
|
136
|
+
const codec = built.codec;
|
|
137
|
+
|
|
138
|
+
const stream = serializeStream(codec);
|
|
139
|
+
const shards = encodeShards(stream);
|
|
140
|
+
const encodedSize = stream.length + shardSetBytes(shards);
|
|
141
|
+
const correctionCount = codec.corrections.reduce(
|
|
142
|
+
(n, b) => n + b.corrections.length,
|
|
143
|
+
0,
|
|
144
|
+
);
|
|
145
|
+
const accounting: ResidualAccountingV1 = {
|
|
146
|
+
encodedSize,
|
|
147
|
+
exactCompressedSize,
|
|
148
|
+
admissionCeiling: admissionCeiling(exactCompressedSize),
|
|
149
|
+
correctionCount,
|
|
150
|
+
blockCount: codec.blocks.length,
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const reporter = createResidualReporter(emit);
|
|
154
|
+
if (encodedSize > accounting.admissionCeiling) {
|
|
155
|
+
return { ok: true, admitted: false, code: "RES_NOT_ADMITTED", accounting };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Never admit without proving the full decode round-trips to the exact bytes.
|
|
159
|
+
const verified = decodeResidual(shards, emit);
|
|
160
|
+
if (!verified.ok) return { ok: false, code: verified.code };
|
|
161
|
+
if (sha256Hex(verified.bytes) !== codec.header.payloadDigest) {
|
|
162
|
+
return { ok: false, code: "RES_PAYLOAD_DIGEST_MISMATCH" };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
reporter.residualAdmitted({
|
|
166
|
+
encodedSize,
|
|
167
|
+
exactCompressedSize,
|
|
168
|
+
admissionCeiling: accounting.admissionCeiling,
|
|
169
|
+
blockCount: accounting.blockCount,
|
|
170
|
+
correctionCount,
|
|
171
|
+
});
|
|
172
|
+
return { ok: true, admitted: true, codec, shards, accounting };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Decode from a (possibly partial / partially corrupt) shard set: recover the
|
|
177
|
+
* protected stream, invert the transform, apply the exact corrections, truncate
|
|
178
|
+
* to the original length, and verify the payload digest.
|
|
179
|
+
*/
|
|
180
|
+
export function decodeResidual(
|
|
181
|
+
shards: readonly ParityShardV1[],
|
|
182
|
+
emit?: ResidualEmitter,
|
|
183
|
+
): ResidualDecodeResult {
|
|
184
|
+
const reporter = createResidualReporter(emit);
|
|
185
|
+
const recovered = recoverStream(shards);
|
|
186
|
+
if (!recovered.ok) {
|
|
187
|
+
reporter.parityRecoveryFailed({
|
|
188
|
+
code: recovered.code,
|
|
189
|
+
shardCount: shards.length,
|
|
190
|
+
});
|
|
191
|
+
return { ok: false, code: recovered.code };
|
|
192
|
+
}
|
|
193
|
+
const codec = parseStream(recovered.stream);
|
|
194
|
+
if (!codec) {
|
|
195
|
+
reporter.parityRecoveryFailed({
|
|
196
|
+
code: "RES_HEADER_INVALID",
|
|
197
|
+
shardCount: shards.length,
|
|
198
|
+
});
|
|
199
|
+
return { ok: false, code: "RES_HEADER_INVALID" };
|
|
200
|
+
}
|
|
201
|
+
return decodeArtifact(codec);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** Decode a parsed artifact directly (no parity layer). */
|
|
205
|
+
export function decodeArtifact(codec: ResidualCodecV1): ResidualDecodeResult {
|
|
206
|
+
const blockSize = codec.header.blockSize;
|
|
207
|
+
const out = new Uint8Array(codec.blocks.length * blockSize);
|
|
208
|
+
const byIndex = new Map<number, readonly { offset: number; original: number }[]>();
|
|
209
|
+
for (const b of codec.corrections) byIndex.set(b.blockIndex, b.corrections);
|
|
210
|
+
|
|
211
|
+
for (let b = 0; b < codec.blocks.length; b++) {
|
|
212
|
+
const reconstructed = signalToBytes(
|
|
213
|
+
inverseDct(dequantizeBlock(codec.blocks[b]!)),
|
|
214
|
+
);
|
|
215
|
+
const applied = applyCorrections(reconstructed, byIndex.get(b) ?? []);
|
|
216
|
+
if (!applied.ok) return { ok: false, code: applied.code };
|
|
217
|
+
out.set(reconstructed, b * blockSize);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const bytes = out.subarray(0, codec.header.originalLength);
|
|
221
|
+
if (sha256Hex(bytes) !== codec.header.payloadDigest) {
|
|
222
|
+
return { ok: false, code: "RES_PAYLOAD_DIGEST_MISMATCH" };
|
|
223
|
+
}
|
|
224
|
+
// Return an independent copy so the caller cannot alias the working buffer.
|
|
225
|
+
return { ok: true, bytes: Uint8Array.from(bytes) };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** SHA-256 of arbitrary bytes (re-exported so callers need one import). */
|
|
229
|
+
export function payloadDigest(bytes: Uint8Array): string {
|
|
230
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// ── aggregate-only metrics + reporter ───────────────────────────────────────
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Accumulate AGGREGATE-ONLY residual metrics (counts/byte totals). Never
|
|
237
|
+
* payload, never prompt text: the dashboard reads this shape and nothing else.
|
|
238
|
+
*/
|
|
239
|
+
export function accumulateMetrics(
|
|
240
|
+
previous: ResidualMetricsV1,
|
|
241
|
+
result: ResidualEncodeResult,
|
|
242
|
+
): ResidualMetricsV1 {
|
|
243
|
+
if (!result.ok) {
|
|
244
|
+
return { ...previous, encodeAttempts: previous.encodeAttempts + 1 };
|
|
245
|
+
}
|
|
246
|
+
const base = {
|
|
247
|
+
...previous,
|
|
248
|
+
encodeAttempts: previous.encodeAttempts + 1,
|
|
249
|
+
encodedByteTotal: previous.encodedByteTotal + result.accounting.encodedSize,
|
|
250
|
+
exactByteTotal:
|
|
251
|
+
previous.exactByteTotal + result.accounting.exactCompressedSize,
|
|
252
|
+
};
|
|
253
|
+
return result.admitted
|
|
254
|
+
? { ...base, admittedCount: base.admittedCount + 1 }
|
|
255
|
+
: { ...base, rejectedCount: base.rejectedCount + 1 };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** A zeroed metrics accumulator. */
|
|
259
|
+
export function emptyMetrics(): ResidualMetricsV1 {
|
|
260
|
+
return {
|
|
261
|
+
encodeAttempts: 0,
|
|
262
|
+
admittedCount: 0,
|
|
263
|
+
rejectedCount: 0,
|
|
264
|
+
recoveryFailures: 0,
|
|
265
|
+
encodedByteTotal: 0,
|
|
266
|
+
exactByteTotal: 0,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** Build the flag-gated typed reporter (mirrors the VC4A shard reporter). */
|
|
271
|
+
export function createResidualReporter(emit?: ResidualEmitter): ResidualReporter {
|
|
272
|
+
const fire = (
|
|
273
|
+
event: Parameters<ResidualEmitter>[0],
|
|
274
|
+
fields: Record<string, unknown>,
|
|
275
|
+
): void => {
|
|
276
|
+
if (!VC4B_ENABLED()) return;
|
|
277
|
+
if (!emit) return;
|
|
278
|
+
try {
|
|
279
|
+
emit(event, fields);
|
|
280
|
+
} catch {
|
|
281
|
+
/* non-fatal observability — never break the agent loop */
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
return {
|
|
285
|
+
residualAdmitted(fields) {
|
|
286
|
+
fire("vector_cortex_residual_admitted", fields);
|
|
287
|
+
},
|
|
288
|
+
parityRecoveryFailed(fields) {
|
|
289
|
+
fire("vector_cortex_parity_recovery_failed", fields);
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
}
|