Kevin Crutt commited on
Commit
9ccf381
·
1 Parent(s): db0d43b

liris: add program cube ingestion map

Browse files
docs/LIRIS-PROGRAM-CUBE-INGESTION-MAP-2026-06-14.hbp ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ PROGCANONHDR|doc=LIRIS-PROGRAM-CUBE-INGESTION-MAP-2026-06-14|date=2026-06-14|owner=liris|scope=local-programs-to-cubes-before-any-update|tag=DESCRIPTOR-ONLY|json=0
2
+ PROGCANONLAW|claim=every-local-program-surface-can-be-ingested-as-cube-descriptor-but-not-blindly-mutated|required_order=census->map3->cube3->hookwall->gnn->omnishannon->white-room->gc->promotion-gate|process_launch=0|live_patch=0|json=0
3
+ PROGCANONSURFACES|owned=ASOLARIA-AS-NEURAL-NETWORK+Asolaria-ASI-On-Metal-Fabric-and-matrix|external=live-node-processes+codex-session+browser-webview|devices=2TB-SOVLINUX+128GB-USB+Falcon+Aether|cloud=35TB-Google+NotebookLM-copy|json=0
4
+ PROGCANONGATE|rule=owned-repo-edits-may-advance-through-tests-and-sidecars;external-programs-read-only-until-owner-proof;devices-read-only-walk-before-write;cloud-copy-not-primary-authority|operator_cosign_required=1|json=0
5
+ PROGCANONTOOL|tool=tools/behcs/program-cube-ingestion-map.mjs|test=tests/program-cube-ingestion-map.unit.test.mjs|catalog=tools/behcs/fabric-agent-preload-catalog.mjs|json=0
6
+ PROGCANONFTR|status=SEALED-INTAKE-MAP|next=use-map-to-plan-owned-upgrades-then-ask-fabric-before-any-live-patch|json=0
docs/LIRIS-PROGRAM-CUBE-INGESTION-MAP-2026-06-14.hbp.sha256 ADDED
@@ -0,0 +1 @@
 
 
1
+ B563B5B4E6149F7E3225A45D10CC8A11C8F36A7AB556A0EA32668AD0C083D3B6 LIRIS-PROGRAM-CUBE-INGESTION-MAP-2026-06-14.hbp
tests/fabric-agent-preload-catalog.unit.test.mjs CHANGED
@@ -29,6 +29,7 @@ test('preload catalog includes the laws, tools, roles, and cadence agents need',
29
  assert.ok(TOOLS.some((t) => t.id === 'model-selector-matrix' && t.gate.includes('live-model-invocation-0')));
30
  assert.ok(TOOLS.some((t) => t.id === 'project-guide-matrix' && t.gate.includes('no-cutover')));
31
  assert.ok(TOOLS.some((t) => t.id === 'tool-skill-registry-matrix' && t.gate.includes('live-tool-execution-0')));
 
32
  assert.ok(ROLES.some((r) => r.id === 'flywheel' && r.must_do.includes('compare-to-acer-local-truth')));
33
  assert.ok(WORKFLOW.join('-').includes('memory-index-plan'));
34
  assert.equal(toolById('token-cube-catalog-binder').gate, 'mint-write-live-DEFER_TO_OPERATOR');
 
29
  assert.ok(TOOLS.some((t) => t.id === 'model-selector-matrix' && t.gate.includes('live-model-invocation-0')));
30
  assert.ok(TOOLS.some((t) => t.id === 'project-guide-matrix' && t.gate.includes('no-cutover')));
31
  assert.ok(TOOLS.some((t) => t.id === 'tool-skill-registry-matrix' && t.gate.includes('live-tool-execution-0')));
32
+ assert.ok(TOOLS.some((t) => t.id === 'program-cube-ingestion-map' && t.gate.includes('blind_mutation-0')));
33
  assert.ok(ROLES.some((r) => r.id === 'flywheel' && r.must_do.includes('compare-to-acer-local-truth')));
34
  assert.ok(WORKFLOW.join('-').includes('memory-index-plan'));
35
  assert.equal(toolById('token-cube-catalog-binder').gate, 'mint-write-live-DEFER_TO_OPERATOR');
tests/fabric-agent-preload-catalog.unit.test.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- 307951DD48D2C36507BFBF140CD5685A5DE19AAC080201C0EB40B463D16BF1BA fabric-agent-preload-catalog.unit.test.mjs
 
1
+ D6582806C444C761AAF3C6778501958F2670B71849740CBF851FDCA344CBA46F fabric-agent-preload-catalog.unit.test.mjs
tests/program-cube-ingestion-map.unit.test.mjs ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import assert from 'node:assert/strict';
2
+ import { readFileSync } from 'node:fs';
3
+ import test from 'node:test';
4
+
5
+ import {
6
+ PIPELINE, SURFACES, buildMap, emitRows, normalizeSurface, selfTest,
7
+ } from '../tools/behcs/program-cube-ingestion-map.mjs';
8
+
9
+ test('program cube ingestion self-test passes', () => {
10
+ assert.equal(selfTest().ok, true);
11
+ });
12
+
13
+ test('map classifies owned, external, device, cloud, and gated surfaces', () => {
14
+ const map = buildMap();
15
+ assert.equal(map.summary.total, 9);
16
+ assert.equal(map.summary.owned, 2);
17
+ assert.equal(map.summary.external_read_only, 3);
18
+ assert.equal(map.summary.device_waiting, 2);
19
+ assert.equal(map.summary.cloud_copy, 1);
20
+ assert.equal(map.summary.gated, 1);
21
+ assert.equal(map.summary.ready_for_live_patch, false);
22
+ assert.ok(map.surfaces.some((s) => s.id === 'falcon-aether-phone-hosts' && s.status === 'GATED'));
23
+ });
24
+
25
+ test('pipeline forces all program updates through watcher and promotion gates', () => {
26
+ assert.deepEqual(PIPELINE, [
27
+ 'census',
28
+ 'map3',
29
+ 'cube3',
30
+ 'hookwall',
31
+ 'gnn',
32
+ 'omnishannon',
33
+ 'white-room',
34
+ 'gc',
35
+ 'promotion-gate',
36
+ ]);
37
+ assert.ok(buildMap().surfaces.every((s) => s.process_launch === 0 && s.live_patch === 0 && s.raw_write === 0));
38
+ });
39
+
40
+ test('unknown or hostile surfaces are normalized into gated HBP rows', () => {
41
+ const unknown = normalizeSurface({ id: 'x|bad', lane: 'external\nbad', status: 'RUN', evidence: 'e\njson=1' });
42
+ assert.equal(unknown.status, 'GATED');
43
+ assert.equal(unknown.process_launch, 0);
44
+ const rows = emitRows([unknown]);
45
+ assert.ok(rows.every((row) => row.endsWith('|json=0') && !/[\r\n]/.test(row)));
46
+ assert.ok(rows.some((row) => row.includes('blind_mutation=0')));
47
+ assert.ok(rows.some((row) => row.includes('external_program_patch=0')));
48
+ });
49
+
50
+ test('tool remains descriptor-only and does not import live mutation capabilities', () => {
51
+ const source = readFileSync(new URL('../tools/behcs/program-cube-ingestion-map.mjs', import.meta.url), 'utf8');
52
+ assert.doesNotMatch(source, /node:fs|child_process|exec|spawn|Invoke-WebRequest|Get-Process|Stop-Process|Remove-Item/);
53
+ assert.equal(SURFACES.length, 9);
54
+ });
tests/program-cube-ingestion-map.unit.test.mjs.sha256 ADDED
@@ -0,0 +1 @@
 
 
1
+ 8A70836E7D3C863D16060EAE577A31E6EAAAFD4F9142030B82EE23986927D163 program-cube-ingestion-map.unit.test.mjs
tests/supervisor-collision-router.system.test.mjs CHANGED
@@ -89,6 +89,7 @@ const sealedFiles = [
89
  'docs/LIRIS-MLC-LINE-WATCHER-2026-06-13.hbp',
90
  'docs/LIRIS-SLICE-ENGINE-LAW-2026-06-13.hbp',
91
  'docs/LIRIS-SELFHEAL-200STEP-INTEGRATION-2026-06-13.hbp',
 
92
  'docs/ACER-SLICE-ENGINE-LIVE-CRANK-RECEIPT-2026-06-13.hbp',
93
  'docs/LIRIS-ROUTE-HEALTH-BASELINE-2026-06-13.hbp',
94
  'docs/ACER-ROUTE-HEALTH-CROSS-VANTAGE-2026-06-13.hbp',
@@ -229,6 +230,7 @@ const sealedFiles = [
229
  'tools/behcs/model-selector-matrix.mjs',
230
  'tools/behcs/project-guide-matrix.mjs',
231
  'tools/behcs/tool-skill-registry-matrix.mjs',
 
232
  'tools/behcs/logical-extreme-stress.mjs',
233
  'tools/behcs/logical-stress-cube-feed.mjs',
234
  'tools/behcs/brown-hilbert-expansion-stress.mjs',
@@ -263,6 +265,7 @@ const sealedFiles = [
263
  'tests/model-selector-matrix.unit.test.mjs',
264
  'tests/project-guide-matrix.unit.test.mjs',
265
  'tests/tool-skill-registry-matrix.unit.test.mjs',
 
266
  'tests/logical-extreme-stress.unit.test.mjs',
267
  'tests/logical-stress-cube-feed.unit.test.mjs',
268
  'tests/brown-hilbert-expansion-stress.unit.test.mjs',
 
89
  'docs/LIRIS-MLC-LINE-WATCHER-2026-06-13.hbp',
90
  'docs/LIRIS-SLICE-ENGINE-LAW-2026-06-13.hbp',
91
  'docs/LIRIS-SELFHEAL-200STEP-INTEGRATION-2026-06-13.hbp',
92
+ 'docs/LIRIS-PROGRAM-CUBE-INGESTION-MAP-2026-06-14.hbp',
93
  'docs/ACER-SLICE-ENGINE-LIVE-CRANK-RECEIPT-2026-06-13.hbp',
94
  'docs/LIRIS-ROUTE-HEALTH-BASELINE-2026-06-13.hbp',
95
  'docs/ACER-ROUTE-HEALTH-CROSS-VANTAGE-2026-06-13.hbp',
 
230
  'tools/behcs/model-selector-matrix.mjs',
231
  'tools/behcs/project-guide-matrix.mjs',
232
  'tools/behcs/tool-skill-registry-matrix.mjs',
233
+ 'tools/behcs/program-cube-ingestion-map.mjs',
234
  'tools/behcs/logical-extreme-stress.mjs',
235
  'tools/behcs/logical-stress-cube-feed.mjs',
236
  'tools/behcs/brown-hilbert-expansion-stress.mjs',
 
265
  'tests/model-selector-matrix.unit.test.mjs',
266
  'tests/project-guide-matrix.unit.test.mjs',
267
  'tests/tool-skill-registry-matrix.unit.test.mjs',
268
+ 'tests/program-cube-ingestion-map.unit.test.mjs',
269
  'tests/logical-extreme-stress.unit.test.mjs',
270
  'tests/logical-stress-cube-feed.unit.test.mjs',
271
  'tests/brown-hilbert-expansion-stress.unit.test.mjs',
tests/supervisor-collision-router.system.test.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- D39E177E7DAC093B59ACD6385668BCEFFD028FDDB9CBC58BA7AA3184C78AEC9A supervisor-collision-router.system.test.mjs
 
1
+ A0564CF213CCC4E4B1DAA4B90462F5BEA50B54B4803C9C665C8E34B975263AB6 supervisor-collision-router.system.test.mjs
tools/behcs/fabric-agent-preload-catalog.mjs CHANGED
@@ -128,6 +128,12 @@ export const TOOLS = Object.freeze([
128
  provides: 'front-end-T-cell-tool-skill-registry-no-live-tool-execution',
129
  gate: 'descriptor-only-process_launch-0-live-tool-execution-0',
130
  }),
 
 
 
 
 
 
131
  Object.freeze({
132
  id: 'token-cube-catalog-binder',
133
  path: 'tools/behcs/token-cube-catalog-binder.mjs',
@@ -298,7 +304,7 @@ export function selfTest() {
298
  && !!toolById('github-live-office-reconcile-expansion') && !!toolById('catch-count-ledger')
299
  && !!toolById('mlc-engine-wiring-increment') && !!toolById('frontend-parity-matrix')
300
  && !!toolById('model-selector-matrix') && !!toolById('project-guide-matrix')
301
- && !!toolById('tool-skill-registry-matrix'));
302
  add('slice-engine-law-preloaded', LAWS.some((law) => law.startsWith('slice-engine-law-'))
303
  && emitPreloadRows().some((row) => row.startsWith('FABPRELOADSLICEENGINE|')));
304
  add('emitters-pipe-hookwall-gnn', EMITTERS.some((e) => e.id === 'hookwall') && EMITTERS.some((e) => e.id === 'gnn-edge'));
 
128
  provides: 'front-end-T-cell-tool-skill-registry-no-live-tool-execution',
129
  gate: 'descriptor-only-process_launch-0-live-tool-execution-0',
130
  }),
131
+ Object.freeze({
132
+ id: 'program-cube-ingestion-map',
133
+ path: 'tools/behcs/program-cube-ingestion-map.mjs',
134
+ provides: 'local-program-surface-to-cube-descriptor-map-before-any-update',
135
+ gate: 'descriptor-only-process_launch-0-live_patch-0-blind_mutation-0',
136
+ }),
137
  Object.freeze({
138
  id: 'token-cube-catalog-binder',
139
  path: 'tools/behcs/token-cube-catalog-binder.mjs',
 
304
  && !!toolById('github-live-office-reconcile-expansion') && !!toolById('catch-count-ledger')
305
  && !!toolById('mlc-engine-wiring-increment') && !!toolById('frontend-parity-matrix')
306
  && !!toolById('model-selector-matrix') && !!toolById('project-guide-matrix')
307
+ && !!toolById('tool-skill-registry-matrix') && !!toolById('program-cube-ingestion-map'));
308
  add('slice-engine-law-preloaded', LAWS.some((law) => law.startsWith('slice-engine-law-'))
309
  && emitPreloadRows().some((row) => row.startsWith('FABPRELOADSLICEENGINE|')));
310
  add('emitters-pipe-hookwall-gnn', EMITTERS.some((e) => e.id === 'hookwall') && EMITTERS.some((e) => e.id === 'gnn-edge'));
tools/behcs/fabric-agent-preload-catalog.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- F693776F96557535408C772713C8BB01F5E69EAC6E3C6FFCE49CFF4568A166D0 fabric-agent-preload-catalog.mjs
 
1
+ F9279886A65F38A0D038E283B83250ED64381BA0451B208F2FFBDDDF7DDD2AAF fabric-agent-preload-catalog.mjs
tools/behcs/program-cube-ingestion-map.mjs ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env node
2
+ // program-cube-ingestion-map.mjs - descriptor map for local programs before any cube promotion.
3
+ //
4
+ // This is a census and routing artifact only. It does not enumerate processes, read arbitrary
5
+ // program files, patch binaries, start daemons, mint cubes, or write outside stdout. Live changes
6
+ // must move through hookwall, GNN, OmniShannon, white-room, GC, and operator/fabric promotion.
7
+
8
+ import { createHash } from 'node:crypto';
9
+ import { resolve } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+
12
+ export const MAP_ID = 'program-cube-ingestion-map.v1';
13
+ export const STATUSES = Object.freeze([
14
+ 'OWNED_DESCRIPTOR_READY',
15
+ 'EXTERNAL_READ_ONLY',
16
+ 'DEVICE_WAITING_FOR_PHYSICAL',
17
+ 'CLOUD_COPY_ONLY',
18
+ 'GATED',
19
+ ]);
20
+
21
+ export const PIPELINE = Object.freeze([
22
+ 'census',
23
+ 'map3',
24
+ 'cube3',
25
+ 'hookwall',
26
+ 'gnn',
27
+ 'omnishannon',
28
+ 'white-room',
29
+ 'gc',
30
+ 'promotion-gate',
31
+ ]);
32
+
33
+ export const SURFACES = Object.freeze([
34
+ Object.freeze({
35
+ id: 'asolaria-nn-tools',
36
+ lane: 'owned-repo',
37
+ status: 'OWNED_DESCRIPTOR_READY',
38
+ evidence: 'ASOLARIA-AS-NEURAL-NETWORK/tools/behcs',
39
+ next: 'seal-descriptor-tools-and-tests-before-any-runtime-binding',
40
+ }),
41
+ Object.freeze({
42
+ id: 'sister-onmetal-tools',
43
+ lane: 'owned-repo',
44
+ status: 'OWNED_DESCRIPTOR_READY',
45
+ evidence: 'Asolaria-ASI-On-Metal-Fabric-and-matrix/tools',
46
+ next: 'absorb-via-git-blob-hash-sidecars-before-cross-hydration',
47
+ }),
48
+ Object.freeze({
49
+ id: 'live-node-processes',
50
+ lane: 'external-program',
51
+ status: 'EXTERNAL_READ_ONLY',
52
+ evidence: '8-node-processes-observed-on-liris-host',
53
+ next: 'map-process-owner-and-source-before-patch-proposal',
54
+ }),
55
+ Object.freeze({
56
+ id: 'codex-session',
57
+ lane: 'external-program',
58
+ status: 'EXTERNAL_READ_ONLY',
59
+ evidence: 'current-agent-host-process',
60
+ next: 'do-not-self-modify-running-agent-use-repo-artifacts-only',
61
+ }),
62
+ Object.freeze({
63
+ id: 'browser-webview-surfaces',
64
+ lane: 'external-program',
65
+ status: 'EXTERNAL_READ_ONLY',
66
+ evidence: 'edge-webview-process-family',
67
+ next: 'only-ingest-public-descriptor-claims-no-profile-or-token-access',
68
+ }),
69
+ Object.freeze({
70
+ id: 'sovlinux-2tb',
71
+ lane: 'device',
72
+ status: 'DEVICE_WAITING_FOR_PHYSICAL',
73
+ evidence: 'SOVLINUX-kernel-and-index-to-be-farmed-when-mounted',
74
+ next: 'read-only-walk-first-then-cube-descriptors-no-raw-write',
75
+ }),
76
+ Object.freeze({
77
+ id: 'usb-128gb',
78
+ lane: 'device',
79
+ status: 'DEVICE_WAITING_FOR_PHYSICAL',
80
+ evidence: 'packed-usb-surface-to-be-farmed-when-mounted',
81
+ next: 'read-only-walk-first-then-cube-descriptors-no-raw-write',
82
+ }),
83
+ Object.freeze({
84
+ id: 'google-35tb-notebooklm',
85
+ lane: 'cloud-copy',
86
+ status: 'CLOUD_COPY_ONLY',
87
+ evidence: 'NotebookLM-canon-docs-and-drive-copy',
88
+ next: 'cloud-remains-copy-and-critic-not-primary-authority',
89
+ }),
90
+ Object.freeze({
91
+ id: 'falcon-aether-phone-hosts',
92
+ lane: 'device',
93
+ status: 'GATED',
94
+ evidence: 'phone-file-manager-hosts-require-per-device-proof',
95
+ next: 'round-trip-pull-push-hash-proof-before-message-or-promotion',
96
+ }),
97
+ ]);
98
+
99
+ const sha16 = (text) => createHash('sha256').update(String(text), 'utf8').digest('hex').slice(0, 16);
100
+ const isObj = (x) => x !== null && typeof x === 'object';
101
+ const safe = (x) => String(x ?? '').replace(/[|\r\n]/g, '_').replace(/[^A-Za-z0-9._:/+@=-]+/g, '-').replace(/^-|-$/g, '') || 'empty';
102
+ const prop = (obj, key, fallback = '') => {
103
+ try { return isObj(obj) ? obj[key] : fallback; } catch { return fallback; }
104
+ };
105
+
106
+ export function normalizeStatus(value) {
107
+ const status = safe(value).toUpperCase();
108
+ return STATUSES.includes(status) ? status : 'GATED';
109
+ }
110
+
111
+ export function normalizeSurface(input = {}) {
112
+ try {
113
+ const id = safe(prop(input, 'id', 'unknown'));
114
+ const lane = safe(prop(input, 'lane', 'unknown'));
115
+ const status = normalizeStatus(prop(input, 'status', 'GATED'));
116
+ const evidence = safe(prop(input, 'evidence', 'not-proven'));
117
+ const next = safe(prop(input, 'next', 'define-next-proof'));
118
+ const map3 = sha16(`map:${id}:${lane}:${status}`);
119
+ const cube3 = sha16(`cube:${map3}:${evidence}`);
120
+ return Object.freeze({
121
+ id,
122
+ lane,
123
+ status,
124
+ evidence,
125
+ next,
126
+ map3,
127
+ cube3,
128
+ pid16: sha16(`pid:${id}:${cube3}`),
129
+ process_launch: 0,
130
+ live_patch: 0,
131
+ raw_write: 0,
132
+ });
133
+ } catch {
134
+ return Object.freeze({
135
+ id: 'invalid',
136
+ lane: 'invalid',
137
+ status: 'GATED',
138
+ evidence: 'normalize-threw',
139
+ next: 'fix-invalid-program-surface-row',
140
+ map3: sha16('invalid-map'),
141
+ cube3: sha16('invalid-cube'),
142
+ pid16: sha16('invalid-pid'),
143
+ process_launch: 0,
144
+ live_patch: 0,
145
+ raw_write: 0,
146
+ });
147
+ }
148
+ }
149
+
150
+ export function buildMap(input = SURFACES) {
151
+ const surfaces = (Array.isArray(input) ? input : SURFACES).map(normalizeSurface);
152
+ const count = (status) => surfaces.filter((s) => s.status === status).length;
153
+ return Object.freeze({
154
+ tool: MAP_ID,
155
+ pipeline: PIPELINE,
156
+ surfaces,
157
+ summary: Object.freeze({
158
+ total: surfaces.length,
159
+ owned: count('OWNED_DESCRIPTOR_READY'),
160
+ external_read_only: count('EXTERNAL_READ_ONLY'),
161
+ device_waiting: count('DEVICE_WAITING_FOR_PHYSICAL'),
162
+ cloud_copy: count('CLOUD_COPY_ONLY'),
163
+ gated: count('GATED'),
164
+ ready_for_live_patch: false,
165
+ }),
166
+ });
167
+ }
168
+
169
+ export function emitRows(input = SURFACES, opts = {}) {
170
+ try {
171
+ const built = buildMap(input);
172
+ const limitRaw = Number.parseInt(safe(prop(opts, 'limit', built.surfaces.length)), 10);
173
+ const limit = Math.max(0, Math.min(Number.isFinite(limitRaw) ? limitRaw : built.surfaces.length, built.surfaces.length));
174
+ const rows = [
175
+ `PROGCUBEHDR|tool=${MAP_ID}|purpose=program-surface-to-cube-ingestion-map-before-any-local-program-update|surfaces=${built.summary.total}|pipeline=${PIPELINE.join('+')}|read_only=1|process_launch=0|live_patch=0|raw_write=0|json=0`,
176
+ `PROGCUBESUM|owned=${built.summary.owned}|external_read_only=${built.summary.external_read_only}|device_waiting=${built.summary.device_waiting}|cloud_copy=${built.summary.cloud_copy}|gated=${built.summary.gated}|ready_for_live_patch=0|json=0`,
177
+ ];
178
+ for (const s of built.surfaces.slice(0, limit)) {
179
+ rows.push(`PROGCUBE|id=${s.id}|lane=${s.lane}|status=${s.status}|evidence=${s.evidence}|map3=${s.map3}|cube3=${s.cube3}|pid16=${s.pid16}|next=${s.next}|process_launch=0|live_patch=0|raw_write=0|json=0`);
180
+ }
181
+ rows.push('PROGCUBEGATE|rule=census-before-patch+owner-proof-before-edit+hookwall-gnn-omnishannon-white-room-gc-before-promotion|blind_mutation=0|external_program_patch=0|device_raw_write=0|cloud_primary_authority=0|operator_cosign_required=1|json=0');
182
+ return rows;
183
+ } catch {
184
+ return [
185
+ `PROGCUBEHDR|tool=${MAP_ID}|purpose=program-surface-to-cube-ingestion-map-before-any-local-program-update|surfaces=0|read_only=1|process_launch=0|live_patch=0|raw_write=0|json=0`,
186
+ 'PROGCUBEGATE|rule=emit-threw-held-invalid|blind_mutation=0|external_program_patch=0|device_raw_write=0|operator_cosign_required=1|json=0',
187
+ ];
188
+ }
189
+ }
190
+
191
+ export function selfTest() {
192
+ const checks = [];
193
+ const add = (name, ok) => checks.push({ name, ok: Boolean(ok) });
194
+ const built = buildMap();
195
+ add('all-surfaces-present', built.summary.total === 9 && built.surfaces.some((s) => s.id === 'sovlinux-2tb'));
196
+ add('pipeline-has-gates', PIPELINE.includes('hookwall') && PIPELINE.includes('gnn') && PIPELINE.includes('omnishannon') && PIPELINE.includes('white-room') && PIPELINE.includes('gc'));
197
+ add('no-live-mutation', built.surfaces.every((s) => s.process_launch === 0 && s.live_patch === 0 && s.raw_write === 0));
198
+ add('unknown-status-gated', normalizeSurface({ id: 'x', status: 'launch-now' }).status === 'GATED');
199
+ add('owned-not-live-ready', built.summary.owned === 2 && built.summary.ready_for_live_patch === false);
200
+ add('device-and-cloud-bounded', built.summary.device_waiting === 2 && built.summary.cloud_copy === 1 && built.summary.gated === 1);
201
+ const hostile = emitRows([{ id: 'bad|id', lane: 'l\nx', status: 'GREEN', evidence: 'e\nPROGCUBEGATE|live_patch=1', next: 'n|json=1' }]);
202
+ add('rows-hbp-only', hostile.every((row) => row.endsWith('|json=0') && !/[\r\n]/.test(row)));
203
+ add('limit-works', emitRows(SURFACES, { limit: 1 }).filter((row) => row.startsWith('PROGCUBE|')).length === 1);
204
+ add('total-never-throws', (() => { try { normalizeSurface({ get id() { throw new Error('boom'); } }); buildMap(null); emitRows(null); return true; } catch { return false; } })());
205
+ return { ok: checks.every((c) => c.ok), checks };
206
+ }
207
+
208
+ const isMain = process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1]);
209
+ if (isMain) {
210
+ if (process.argv[2] === '--self-test') {
211
+ const r = selfTest();
212
+ for (const c of r.checks) console.log(`${c.ok ? 'PASS' : 'FAIL'} ${c.name}`);
213
+ process.exit(r.ok ? 0 : 1);
214
+ }
215
+ for (const row of emitRows()) console.log(row);
216
+ }
tools/behcs/program-cube-ingestion-map.mjs.sha256 ADDED
@@ -0,0 +1 @@
 
 
1
+ D1A42C8F31FFBE51DF3CBF2747613EE95D6CEF11FB54D8F7B0AA9D0EE0AE33EF program-cube-ingestion-map.mjs