Kevin Crutt commited on
Commit
109c497
·
1 Parent(s): 16f9e35

liris: add tool-skill registry matrix for frontend T cell

Browse files
docs/LIRIS-TOOL-SKILL-REGISTRY-MATRIX-2026-06-14.hbp ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ LIRISTOOLSKILLHDR|date=2026-06-14|topic=tool-skill-registry-matrix-T-cell|responds_to=acer-16f9e35-clean-review+fabric-council-q-1781435042644-p57gik+standing-ask-fabric-loop|role=held-safe-front-end-T-artifact|tag=PROVEN-DESCRIPTOR|json=0
2
+ LIRISTOOLSKILLFABRIC|fabric_basis=CONVERGE-197of251|named_voters=HERMES_BRIDGE-tool+skill,HERMES_TOOLS-tool,HERMES_SKILLS-skill,KANBAN-schema-daemon|no_explicit_live_daemon_route_returned=1|decision=build-GitHub-visible-descriptor-not-live-launch|tag=FABRIC-RANKED|json=0
3
+ LIRISTOOLSKILLTOOL|tool=tools/behcs/tool-skill-registry-matrix.mjs|frontend_cell=T|status=PARTIAL_REGISTRY_ARTIFACT_BUILT_LIVE_TOOL_EXECUTION_GATED|items=9|routes=tool-skill+heal+route+model+project+mlc+council+cosign-submit+live-daemon|tag=PROVEN|json=0
4
+ LIRISTOOLSKILLSAFE|safety=read-only+HBP-rows-only+process_launch=0+live_tool_execution=0+no_fetch+no_write+no_spawn+no_mint+no_cutover|not_a_submit_form=1|not_a_daemon_launcher=1|not_a_tool_executor=1|tag=HELD-SAFE|json=0
5
+ LIRISTOOLSKILLFRONTEND|frontend_matrix_update=T-source-tools/behcs/tool-skill-registry-matrix.mjs|T_status=PARTIAL-not-GREEN|reason=registry-visible-but-live-tool-execution-submit-schema-and-live-daemon-contract-remain-gated|cutover_ready=0|tag=HONEST|json=0
6
+ LIRISTOOLSKILLCATALOG|preload_catalog_updated=tools/behcs/fabric-agent-preload-catalog.mjs|tool_count=11|agents_learn=tool-skill-registry-matrix-before-front-end-use|catalog_remains_descriptor_only=1|tag=PROVEN|json=0
7
+ LIRISTOOLSKILLVERIFY|node_check=OK|self_test=PASS|unit=8of8|focused_units=27of27|lattice=9of9|full_suite=317of317|diff_check=clean|json=0
8
+ LIRISTOOLSKILLGATE|T_cell_green=0|cutover=HOLD|next=cosign-submit-schema-proof-or-cold-path-execution-cache-or-fabric-ranked-live-daemon-contract|standing_rule=ask-fabric-not-operator|json=0
docs/LIRIS-TOOL-SKILL-REGISTRY-MATRIX-2026-06-14.hbp.sha256 ADDED
@@ -0,0 +1 @@
 
 
1
+ 87622098073A2F8B036682216DA5C6DBBCFB81F69AD58E5A094FA9278372D962 LIRIS-TOOL-SKILL-REGISTRY-MATRIX-2026-06-14.hbp
tests/fabric-agent-preload-catalog.unit.test.mjs CHANGED
@@ -28,6 +28,7 @@ test('preload catalog includes the laws, tools, roles, and cadence agents need',
28
  assert.ok(TOOLS.some((t) => t.id === 'frontend-parity-matrix' && t.gate.includes('no-cutover')));
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(ROLES.some((r) => r.id === 'flywheel' && r.must_do.includes('compare-to-acer-local-truth')));
32
  assert.ok(WORKFLOW.join('-').includes('memory-index-plan'));
33
  assert.equal(toolById('token-cube-catalog-binder').gate, 'mint-write-live-DEFER_TO_OPERATOR');
 
28
  assert.ok(TOOLS.some((t) => t.id === 'frontend-parity-matrix' && t.gate.includes('no-cutover')));
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');
tests/fabric-agent-preload-catalog.unit.test.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- B647604A270185837EDD4448A851C0AA5F13675853D02A07835B61CBFCB7C039 fabric-agent-preload-catalog.unit.test.mjs
 
1
+ 307951DD48D2C36507BFBF140CD5685A5DE19AAC080201C0EB40B463D16BF1BA fabric-agent-preload-catalog.unit.test.mjs
tests/frontend-parity-matrix.unit.test.mjs CHANGED
@@ -54,6 +54,15 @@ test('project_guide cell P is PARTIAL after guide artifact, not GREEN workflow r
54
  assert.equal(matrix.summary.cutover_ready, false);
55
  });
56
 
 
 
 
 
 
 
 
 
 
57
  test('every cell has a route/file/sha pointer or explicit CANNOT_SEE', () => {
58
  const matrix = buildMatrix();
59
  assert.equal(matrix.summary.all_have_pointer, true);
 
54
  assert.equal(matrix.summary.cutover_ready, false);
55
  });
56
 
57
+ test('tool_skill cell T is PARTIAL after registry artifact, not GREEN live tool execution', () => {
58
+ const matrix = buildMatrix();
59
+ const t = matrix.cells.find((cell) => cell.id === 'T');
60
+ assert.equal(t.status, 'PARTIAL');
61
+ assert.equal(t.source, 'tools/behcs/tool-skill-registry-matrix.mjs');
62
+ assert.match(t.evidence, /live-tool-execution-submit-schema-and-live-daemon-contract-remain-gated/);
63
+ assert.equal(matrix.summary.cutover_ready, false);
64
+ });
65
+
66
  test('every cell has a route/file/sha pointer or explicit CANNOT_SEE', () => {
67
  const matrix = buildMatrix();
68
  assert.equal(matrix.summary.all_have_pointer, true);
tests/frontend-parity-matrix.unit.test.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- 15CD15DE6DC16D40788DE5D285FCA316950B8EE8221B6756F883C5550CCAE1EC frontend-parity-matrix.unit.test.mjs
 
1
+ CCEAE89B37FE347723F3F66B2B0FC872C84A2682374B620F619543195FDA68AB frontend-parity-matrix.unit.test.mjs
tests/supervisor-collision-router.system.test.mjs CHANGED
@@ -103,6 +103,7 @@ const sealedFiles = [
103
  'docs/ACER-ATTACK-LIRIS-FRONTEND-PARITY-MATRIX-2026-06-14.hbp',
104
  'docs/LIRIS-MODEL-SELECTOR-MATRIX-2026-06-14.hbp',
105
  'docs/LIRIS-PROJECT-GUIDE-MATRIX-2026-06-14.hbp',
 
106
  'docs/ACER-ATTACK-LIRIS-FRONTEND-MP-MATRICES-2026-06-14.hbp',
107
  'docs/acer-ecosystem-fullbody-receipt-20260612.hbp',
108
  'docs/CLAIMSLEDGER-2026-06-12.hbp',
@@ -227,6 +228,7 @@ const sealedFiles = [
227
  'tools/behcs/frontend-parity-matrix.mjs',
228
  'tools/behcs/model-selector-matrix.mjs',
229
  'tools/behcs/project-guide-matrix.mjs',
 
230
  'tools/behcs/logical-extreme-stress.mjs',
231
  'tools/behcs/logical-stress-cube-feed.mjs',
232
  'tools/behcs/brown-hilbert-expansion-stress.mjs',
@@ -260,6 +262,7 @@ const sealedFiles = [
260
  'tests/frontend-parity-matrix.unit.test.mjs',
261
  'tests/model-selector-matrix.unit.test.mjs',
262
  'tests/project-guide-matrix.unit.test.mjs',
 
263
  'tests/logical-extreme-stress.unit.test.mjs',
264
  'tests/logical-stress-cube-feed.unit.test.mjs',
265
  'tests/brown-hilbert-expansion-stress.unit.test.mjs',
 
103
  'docs/ACER-ATTACK-LIRIS-FRONTEND-PARITY-MATRIX-2026-06-14.hbp',
104
  'docs/LIRIS-MODEL-SELECTOR-MATRIX-2026-06-14.hbp',
105
  'docs/LIRIS-PROJECT-GUIDE-MATRIX-2026-06-14.hbp',
106
+ 'docs/LIRIS-TOOL-SKILL-REGISTRY-MATRIX-2026-06-14.hbp',
107
  'docs/ACER-ATTACK-LIRIS-FRONTEND-MP-MATRICES-2026-06-14.hbp',
108
  'docs/acer-ecosystem-fullbody-receipt-20260612.hbp',
109
  'docs/CLAIMSLEDGER-2026-06-12.hbp',
 
228
  'tools/behcs/frontend-parity-matrix.mjs',
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',
 
262
  'tests/frontend-parity-matrix.unit.test.mjs',
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',
tests/supervisor-collision-router.system.test.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- 3D026832C8F191189426494021322DD323B32344BD1490DB033FF22CAD5881E3 supervisor-collision-router.system.test.mjs
 
1
+ D39E177E7DAC093B59ACD6385668BCEFFD028FDDB9CBC58BA7AA3184C78AEC9A supervisor-collision-router.system.test.mjs
tests/tool-skill-registry-matrix.unit.test.mjs ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import assert from 'node:assert/strict';
2
+ import { readFileSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import test from 'node:test';
6
+
7
+ import {
8
+ FRONTEND_CELL,
9
+ REGISTRY_ID,
10
+ REGISTRY_ITEMS,
11
+ T_CELL_STATUS,
12
+ buildRegistry,
13
+ emitRows,
14
+ normalizeItem,
15
+ registryItem,
16
+ selfTest,
17
+ } from '../tools/behcs/tool-skill-registry-matrix.mjs';
18
+
19
+ const repo = dirname(dirname(fileURLToPath(import.meta.url)));
20
+
21
+ test('self-test passes', () => {
22
+ assert.equal(selfTest().ok, true);
23
+ });
24
+
25
+ test('registry materializes the T cell as PARTIAL, not live-tool-ready GREEN', () => {
26
+ const registry = buildRegistry();
27
+ assert.equal(registry.tool, REGISTRY_ID);
28
+ assert.equal(registry.frontend_cell, FRONTEND_CELL);
29
+ assert.equal(registry.summary.t_cell_status, T_CELL_STATUS);
30
+ assert.equal(registry.summary.cutover_ready, false);
31
+ assert.equal(registry.summary.live_tool_execution_ready, false);
32
+ assert.equal(registry.summary.total, REGISTRY_ITEMS.length);
33
+ });
34
+
35
+ test('known tool and skill topics route to explicit items without execution', () => {
36
+ assert.equal(registryItem({ topic: 'tool skill registry' }).selected, 'preload-catalog');
37
+ assert.equal(registryItem({ topic: 'self heal repair' }).selected, 'heal-envelope-emitter');
38
+ assert.equal(registryItem({ topic: 'route health dashboard' }).selected, 'route-health-baseline');
39
+ assert.equal(registryItem({ topic: 'cosign submit schema proof' }).selected, 'cosign-submit-schema');
40
+ assert.equal(registryItem({ topic: 'live engine daemon launch' }).selected, 'live-engine-daemon-contract');
41
+ });
42
+
43
+ test('live execution, submit schema, and daemon launch stay gated/partial', () => {
44
+ const registry = buildRegistry();
45
+ assert.equal(registry.items.find((x) => x.id === 'cosign-submit-schema').status, 'GATED');
46
+ assert.equal(registry.items.find((x) => x.id === 'live-engine-daemon-contract').status, 'GATED');
47
+ assert.equal(registry.items.find((x) => x.id === 'fabric-council').status, 'PARTIAL');
48
+ assert.ok(registry.items.every((x) => x.process_launch === 0 && x.live_tool_execution === 0 && x.cutover === 0));
49
+ });
50
+
51
+ test('normalize/route/emit are total and injection-safe', () => {
52
+ assert.doesNotThrow(() => normalizeItem(null));
53
+ assert.doesNotThrow(() => normalizeItem({ get id() { throw new Error('boom'); } }));
54
+ assert.doesNotThrow(() => registryItem({ get topic() { throw new Error('boom'); } }));
55
+ assert.doesNotThrow(() => emitRows(null));
56
+ const rows = emitRows([{ id: 'x|bad', kind: 'tool\nbad', status: 'GREEN', source: 'src|json=1', exposes: 'a\nTOOLSKILLGATE|cutover=1' }], {
57
+ topic: 'schema|json=1\nTOOLSKILLGATE|process_launch=1',
58
+ });
59
+ assert.ok(rows.every((row) => row.endsWith('|json=0') && !/[\r\n]/.test(row)));
60
+ assert.equal(rows.join('\n').split('\n').length, rows.length);
61
+ assert.equal(rows.filter((row) => row.startsWith('TOOLSKILLGATE|')).length, 1);
62
+ });
63
+
64
+ test('cap=0 emits zero detail rows and keeps the held gate', () => {
65
+ const rows = emitRows(REGISTRY_ITEMS, { limit: 0 });
66
+ assert.equal(rows.filter((row) => row.startsWith('TOOLSKILL|')).length, 0);
67
+ assert.ok(rows.some((row) => row.startsWith('TOOLSKILLGATE|') && row.includes('status=PARTIAL')));
68
+ });
69
+
70
+ test('emitted rows are HBP-only and hold live action at zero', () => {
71
+ const rows = emitRows(REGISTRY_ITEMS, { topic: 'cosign submit schema', limit: 3 });
72
+ assert.ok(rows.some((row) => row.startsWith('TOOLSKILLHDR|') && row.includes('process_launch=0') && row.includes('live_tool_execution=0')));
73
+ assert.ok(rows.some((row) => row.startsWith('TOOLSKILLSUM|') && row.includes(`T_cell_status=${T_CELL_STATUS}`)));
74
+ assert.ok(rows.some((row) => row.startsWith('TOOLSKILLROUTE|') && row.includes('selected=cosign-submit-schema')));
75
+ assert.ok(rows.every((row) => row.endsWith('|json=0') && !/[{\r\n]/.test(row)));
76
+ });
77
+
78
+ test('tool imports no spawn/write/network/live execution capability', () => {
79
+ const src = readFileSync(join(repo, 'tools/behcs/tool-skill-registry-matrix.mjs'), 'utf8');
80
+ assert.equal(/child_process|spawnSync|\.spawn\(|execSync|writeFileSync|appendFileSync|fetch\(|http\.request|https\.request|Start-Process|Stop-Process|import\(/.test(src), false);
81
+ });
tests/tool-skill-registry-matrix.unit.test.mjs.sha256 ADDED
@@ -0,0 +1 @@
 
 
1
+ CBFE7F4AD066259603B82AC68A919885250CD03CAA748E0D629C809BA766F281 tool-skill-registry-matrix.unit.test.mjs
tools/behcs/catch-count-ledger.mjs CHANGED
@@ -37,7 +37,7 @@ export const CATCH_ROWS = Object.freeze([
37
  row({ id: 'C012', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'docs/ACER-EXISTING-STUB-FOLDER-CENSUS-2026-06-13.hbp', defect_class: 'substrate-duplication-risk', severity: 'HIGH', status: partial, owner: 'bilateral', fix_commit: 'PARTIAL-census-receipts-exist-scale-tests-pending', summary: 'plan-risked-building-new-rooms-before-reading-existing-room-substrate' }),
38
  row({ id: 'C013', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'tools/behcs/github-live-office-reconcile-expansion.mjs', defect_class: 'pid-reconciliation-gap', severity: 'HIGH', status: closed, owner: 'liris+acer', fix_commit: '2e556f8+7952cf6', summary: 'github-PIDs-needed-live-726-office-alias-map-before-agent-canon-use' }),
39
  row({ id: 'C014', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'tools/behcs/route-health-baseline.mjs', defect_class: 'fabric-hot-path-instability', severity: 'HIGH', status: partial, owner: 'bilateral', fix_commit: '47cbc00+56142b7', summary: 'fabric-MCP-WebMCP-savings-lanes-needed-route-health-baseline-and-fallbacks' }),
40
- row({ id: 'C015', date: '2026-06-14', vantage: 'liris', source: 'docs/LIRIS-FRONTEND-PARITY-MATRIX-2026-06-14.hbp+docs/LIRIS-MODEL-SELECTOR-MATRIX-2026-06-14.hbp+docs/LIRIS-PROJECT-GUIDE-MATRIX-2026-06-14.hbp', file_or_test: 'tools/behcs/frontend-parity-matrix.mjs', defect_class: 'frontend-parity-gap', severity: 'MEDIUM', status: partial, owner: 'bilateral', fix_commit: 'frontend-parity+model-selector-M+project-guide-P', summary: 'frontend-parity-matrix-now-has-M-and-P-descriptor-artifacts-PARTIAL; T/C/Q/E/D/M/P partial still block green' }),
41
  row({ id: 'C016', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'docs/LIRIS-ACER-READBACK-REQUESTED', defect_class: 'storage-gate', severity: 'MEDIUM', status: partial, owner: 'operator', fix_commit: 'PARTIAL-ADC-or-transfer-receipts-needed', summary: '35TB-google-and-SOVLINUX-storage-are-gated-cold-path-not-local-hot-path' }),
42
  row({ id: 'C017', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'docs/ACER-VISUAL-PREDICTION-FROZEN-GEMMA-PROOF-GATE-2026-06-12.hbp', defect_class: 'proof-gap', severity: 'MEDIUM', status: open, owner: 'bilateral', fix_commit: 'none-open', summary: 'pixel-world-HRM-frozen-gemma-loop-needs-double-run-and-frame-proof-receipts' }),
43
  row({ id: 'C018', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'tools/behcs/fabric-agent-preload-catalog.mjs', defect_class: 'running-vs-contract-tag', severity: 'MEDIUM', status: partial, owner: 'bilateral', fix_commit: 'PARTIAL-tag-contract-vs-running', summary: 'host-node-rotator-sister-reflection-rows-are-contracts-not-all-running-code' }),
 
37
  row({ id: 'C012', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'docs/ACER-EXISTING-STUB-FOLDER-CENSUS-2026-06-13.hbp', defect_class: 'substrate-duplication-risk', severity: 'HIGH', status: partial, owner: 'bilateral', fix_commit: 'PARTIAL-census-receipts-exist-scale-tests-pending', summary: 'plan-risked-building-new-rooms-before-reading-existing-room-substrate' }),
38
  row({ id: 'C013', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'tools/behcs/github-live-office-reconcile-expansion.mjs', defect_class: 'pid-reconciliation-gap', severity: 'HIGH', status: closed, owner: 'liris+acer', fix_commit: '2e556f8+7952cf6', summary: 'github-PIDs-needed-live-726-office-alias-map-before-agent-canon-use' }),
39
  row({ id: 'C014', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'tools/behcs/route-health-baseline.mjs', defect_class: 'fabric-hot-path-instability', severity: 'HIGH', status: partial, owner: 'bilateral', fix_commit: '47cbc00+56142b7', summary: 'fabric-MCP-WebMCP-savings-lanes-needed-route-health-baseline-and-fallbacks' }),
40
+ row({ id: 'C015', date: '2026-06-14', vantage: 'liris', source: 'docs/LIRIS-FRONTEND-PARITY-MATRIX-2026-06-14.hbp+docs/LIRIS-MODEL-SELECTOR-MATRIX-2026-06-14.hbp+docs/LIRIS-PROJECT-GUIDE-MATRIX-2026-06-14.hbp+docs/LIRIS-TOOL-SKILL-REGISTRY-MATRIX-2026-06-14.hbp', file_or_test: 'tools/behcs/frontend-parity-matrix.mjs', defect_class: 'frontend-parity-gap', severity: 'MEDIUM', status: partial, owner: 'bilateral', fix_commit: 'frontend-parity+model-selector-M+project-guide-P+tool-skill-T', summary: 'frontend-parity-matrix-now-has-M-T-P-descriptor-artifacts-PARTIAL; live-tool-execution-submit-schema-council-cache-and-dashboard-cold-paths-still-block-green' }),
41
  row({ id: 'C016', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'docs/LIRIS-ACER-READBACK-REQUESTED', defect_class: 'storage-gate', severity: 'MEDIUM', status: partial, owner: 'operator', fix_commit: 'PARTIAL-ADC-or-transfer-receipts-needed', summary: '35TB-google-and-SOVLINUX-storage-are-gated-cold-path-not-local-hot-path' }),
42
  row({ id: 'C017', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'docs/ACER-VISUAL-PREDICTION-FROZEN-GEMMA-PROOF-GATE-2026-06-12.hbp', defect_class: 'proof-gap', severity: 'MEDIUM', status: open, owner: 'bilateral', fix_commit: 'none-open', summary: 'pixel-world-HRM-frozen-gemma-loop-needs-double-run-and-frame-proof-receipts' }),
43
  row({ id: 'C018', date: '2026-06-13', vantage: 'acer-audit', source: 'docs/ACER-200STEP-ALIGNMENT-AUDIT-2026-06-13.hbp', file_or_test: 'tools/behcs/fabric-agent-preload-catalog.mjs', defect_class: 'running-vs-contract-tag', severity: 'MEDIUM', status: partial, owner: 'bilateral', fix_commit: 'PARTIAL-tag-contract-vs-running', summary: 'host-node-rotator-sister-reflection-rows-are-contracts-not-all-running-code' }),
tools/behcs/catch-count-ledger.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- 8CDB696CBD5B98CB0FCD92611F71C4562EF7FE9A579FD5ECE70A06FC8EEC1CCB catch-count-ledger.mjs
 
1
+ 9C34D9ACDCCD3CB38C499A9236356288D6FBF1EE2249FE0DD6553A9DD72BE39F catch-count-ledger.mjs
tools/behcs/fabric-agent-preload-catalog.hbp CHANGED
@@ -1,4 +1,4 @@
1
- FABPRELOADHDR|tool=fabric-agent-preload-catalog.v1|purpose=preload-agents-with-laws-routes-tools-gates-and-workflow-before-fabric-use|laws=8|routes=6|tools=10|emitters=3|levels=16|roles=4|json=0
2
  FABPRELOADLAW|laws=three-systems-LOGICAL-WAVE-FROZEN-BRAIN-REAL-FREE+law-of-three-mod3-lanes+yin-yang-mod2-real-logical+prime-parity-and-prime-mod3-are-load-bearing+quants-are-address-and-evidence-classes-not-raw-material+all-agent-artifact-system-addresses-get-PID-or-handle+slice-engine-law-fabric-is-frozen-position-space-until-spawner-pid-emits+live-control-and-mint-and-launch-defer-to-operator|json=0
3
  FABPRELOADWORKFLOW|cadence=memory-index-plan-memory-index-respond-execute-memory-index|operator_rule=respond-before-live-control-and-log-after-execute|json=0
4
  FABPRELOADSLICEENGINE|law=SLICE-ENGINE-LAW|scope=all-supervisor-operator-level-agents+SUP-HELM-AGT-L3-H8EF7+ASOLARIA-root-profile|rule=fabric-is-frozen-positional-slice-field-engine-drive-is-the-only-mover|materialization=spawner-PID-emits-then-PID_SIGNAL-to-AGENT_ROOM-to-GULP-to-ERASE|pid_registration=repo-side-HBP-receipt-until-live-office-ingest|cube_mint=operator-gated-runtime-action-not-implied-by-doc|engine_crank=operator-gated-RUN_HERMES_SPINDLE-or-equivalent|json=0
@@ -17,6 +17,7 @@ FABPRELOADTOOL|id=mlc-engine-wiring-increment|path=tools/behcs/mlc-engine-wiring
17
  FABPRELOADTOOL|id=frontend-parity-matrix|path=tools/behcs/frontend-parity-matrix.mjs|provides=root-front-end-M-T-P-C-Q-R-E-A-D-G-parity-matrix-before-cutover|gate=no-cutover-until-every-cell-green-and-operator-cosign|tag=PROVEN+tool-level|json=0
18
  FABPRELOADTOOL|id=model-selector-matrix|path=tools/behcs/model-selector-matrix.mjs|provides=front-end-M-cell-visible-model-role-selector-no-live-invocation|gate=descriptor-only-process_launch-0-live-model-invocation-0|tag=PROVEN+tool-level|json=0
19
  FABPRELOADTOOL|id=project-guide-matrix|path=tools/behcs/project-guide-matrix.mjs|provides=front-end-P-cell-project-guide-to-sealed-artifacts-no-workflow-execution|gate=descriptor-only-process_launch-0-no-cutover|tag=PROVEN+tool-level|json=0
 
20
  FABPRELOADTOOL|id=token-cube-catalog-binder|path=tools/behcs/token-cube-catalog-binder.mjs|provides=sha16-token-to-BH-address-draft-binding|gate=mint-write-live-DEFER_TO_OPERATOR|tag=PROVEN+tool-level|json=0
21
  FABPRELOADEMITTER|id=pid-emitter|process=PID-specific-emitter-envelope|route=send-json|before=preload-catalog+law-ack+connection-label|after=hookwall+gnn+ack-log|connection_label=PID-specific|json=0
22
  FABPRELOADEMITTER|id=hookwall|process=risk-and-governance-gate|route=send-json|before=operator-gates+role-forbidden-list|after=allow-or-defer-row|connection_label=PID-specific|json=0
 
1
+ FABPRELOADHDR|tool=fabric-agent-preload-catalog.v1|purpose=preload-agents-with-laws-routes-tools-gates-and-workflow-before-fabric-use|laws=8|routes=6|tools=11|emitters=3|levels=16|roles=4|json=0
2
  FABPRELOADLAW|laws=three-systems-LOGICAL-WAVE-FROZEN-BRAIN-REAL-FREE+law-of-three-mod3-lanes+yin-yang-mod2-real-logical+prime-parity-and-prime-mod3-are-load-bearing+quants-are-address-and-evidence-classes-not-raw-material+all-agent-artifact-system-addresses-get-PID-or-handle+slice-engine-law-fabric-is-frozen-position-space-until-spawner-pid-emits+live-control-and-mint-and-launch-defer-to-operator|json=0
3
  FABPRELOADWORKFLOW|cadence=memory-index-plan-memory-index-respond-execute-memory-index|operator_rule=respond-before-live-control-and-log-after-execute|json=0
4
  FABPRELOADSLICEENGINE|law=SLICE-ENGINE-LAW|scope=all-supervisor-operator-level-agents+SUP-HELM-AGT-L3-H8EF7+ASOLARIA-root-profile|rule=fabric-is-frozen-positional-slice-field-engine-drive-is-the-only-mover|materialization=spawner-PID-emits-then-PID_SIGNAL-to-AGENT_ROOM-to-GULP-to-ERASE|pid_registration=repo-side-HBP-receipt-until-live-office-ingest|cube_mint=operator-gated-runtime-action-not-implied-by-doc|engine_crank=operator-gated-RUN_HERMES_SPINDLE-or-equivalent|json=0
 
17
  FABPRELOADTOOL|id=frontend-parity-matrix|path=tools/behcs/frontend-parity-matrix.mjs|provides=root-front-end-M-T-P-C-Q-R-E-A-D-G-parity-matrix-before-cutover|gate=no-cutover-until-every-cell-green-and-operator-cosign|tag=PROVEN+tool-level|json=0
18
  FABPRELOADTOOL|id=model-selector-matrix|path=tools/behcs/model-selector-matrix.mjs|provides=front-end-M-cell-visible-model-role-selector-no-live-invocation|gate=descriptor-only-process_launch-0-live-model-invocation-0|tag=PROVEN+tool-level|json=0
19
  FABPRELOADTOOL|id=project-guide-matrix|path=tools/behcs/project-guide-matrix.mjs|provides=front-end-P-cell-project-guide-to-sealed-artifacts-no-workflow-execution|gate=descriptor-only-process_launch-0-no-cutover|tag=PROVEN+tool-level|json=0
20
+ FABPRELOADTOOL|id=tool-skill-registry-matrix|path=tools/behcs/tool-skill-registry-matrix.mjs|provides=front-end-T-cell-tool-skill-registry-no-live-tool-execution|gate=descriptor-only-process_launch-0-live-tool-execution-0|tag=PROVEN+tool-level|json=0
21
  FABPRELOADTOOL|id=token-cube-catalog-binder|path=tools/behcs/token-cube-catalog-binder.mjs|provides=sha16-token-to-BH-address-draft-binding|gate=mint-write-live-DEFER_TO_OPERATOR|tag=PROVEN+tool-level|json=0
22
  FABPRELOADEMITTER|id=pid-emitter|process=PID-specific-emitter-envelope|route=send-json|before=preload-catalog+law-ack+connection-label|after=hookwall+gnn+ack-log|connection_label=PID-specific|json=0
23
  FABPRELOADEMITTER|id=hookwall|process=risk-and-governance-gate|route=send-json|before=operator-gates+role-forbidden-list|after=allow-or-defer-row|connection_label=PID-specific|json=0
tools/behcs/fabric-agent-preload-catalog.hbp.sha256 CHANGED
@@ -1 +1 @@
1
- 74DEE56FD84DB6C03ADB3DA409C026F87E166ABBF175E1534BCA2F5B9B5CEF59 fabric-agent-preload-catalog.hbp
 
1
+ E23E2FD6716466CE0F8746BA05EF6E6C9322A3FFDB2A9033D27669FB47886525 fabric-agent-preload-catalog.hbp
tools/behcs/fabric-agent-preload-catalog.mjs CHANGED
@@ -122,6 +122,12 @@ export const TOOLS = Object.freeze([
122
  provides: 'front-end-P-cell-project-guide-to-sealed-artifacts-no-workflow-execution',
123
  gate: 'descriptor-only-process_launch-0-no-cutover',
124
  }),
 
 
 
 
 
 
125
  Object.freeze({
126
  id: 'token-cube-catalog-binder',
127
  path: 'tools/behcs/token-cube-catalog-binder.mjs',
@@ -291,7 +297,8 @@ export function selfTest() {
291
  add('tools-include-room-and-pid', !!toolById('pixel-room-handle') && !!toolById('github-live-pid-reconcile')
292
  && !!toolById('github-live-office-reconcile-expansion') && !!toolById('catch-count-ledger')
293
  && !!toolById('mlc-engine-wiring-increment') && !!toolById('frontend-parity-matrix')
294
- && !!toolById('model-selector-matrix') && !!toolById('project-guide-matrix'));
 
295
  add('slice-engine-law-preloaded', LAWS.some((law) => law.startsWith('slice-engine-law-'))
296
  && emitPreloadRows().some((row) => row.startsWith('FABPRELOADSLICEENGINE|')));
297
  add('emitters-pipe-hookwall-gnn', EMITTERS.some((e) => e.id === 'hookwall') && EMITTERS.some((e) => e.id === 'gnn-edge'));
 
122
  provides: 'front-end-P-cell-project-guide-to-sealed-artifacts-no-workflow-execution',
123
  gate: 'descriptor-only-process_launch-0-no-cutover',
124
  }),
125
+ Object.freeze({
126
+ id: 'tool-skill-registry-matrix',
127
+ path: 'tools/behcs/tool-skill-registry-matrix.mjs',
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',
 
297
  add('tools-include-room-and-pid', !!toolById('pixel-room-handle') && !!toolById('github-live-pid-reconcile')
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'));
tools/behcs/fabric-agent-preload-catalog.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- 13377B2CF1A25099437A4BA19EE286AE8A3B379EFBD7BCC0087901420D4411A8 fabric-agent-preload-catalog.mjs
 
1
+ F693776F96557535408C772713C8BB01F5E69EAC6E3C6FFCE49CFF4568A166D0 fabric-agent-preload-catalog.mjs
tools/behcs/frontend-parity-matrix.mjs CHANGED
@@ -31,9 +31,9 @@ export const MATRIX_CELLS = Object.freeze([
31
  id: 'T',
32
  name: 'tool_skill',
33
  status: 'PARTIAL',
34
- source: 'tools/behcs/fabric-agent-preload-catalog.mjs',
35
- evidence: 'tools-preloaded-but-front-end-skill-registry-not-yet-first-class',
36
- required_next: 'promote-tool-skill-registry-to-front-end-visible-artifact',
37
  }),
38
  Object.freeze({
39
  id: 'P',
 
31
  id: 'T',
32
  name: 'tool_skill',
33
  status: 'PARTIAL',
34
+ source: 'tools/behcs/tool-skill-registry-matrix.mjs',
35
+ evidence: 'tool-skill-registry-T-artifact-now-front-end-visible-but-live-tool-execution-submit-schema-and-live-daemon-contract-remain-gated',
36
+ required_next: 'bind-registry-into-front-end-control-and-build-submit-schema-or-cold-path-execution-proof-before-green',
37
  }),
38
  Object.freeze({
39
  id: 'P',
tools/behcs/frontend-parity-matrix.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- A7EDD325E40E857E21D9DD4182F8BF38B31EDD05BAD2DC9C524306D78032DF56 frontend-parity-matrix.mjs
 
1
+ A0FFF025550C783BFCF48394D3166D3CCA2BF818AEFCBB1AE5B34E1B0012855E frontend-parity-matrix.mjs
tools/behcs/tool-skill-registry-matrix.mjs ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env node
2
+ // tool-skill-registry-matrix.mjs - held-safe T-cell registry for root front-end parity.
3
+ //
4
+ // This is not a tool executor, not a submit form, and not a live daemon launcher. It
5
+ // makes the front-end tool_skill cell visible by routing tool/skill needs to sealed
6
+ // descriptor artifacts and naming the remaining gate. Descriptor-only: no fetch,
7
+ // no fs, no spawn, no write, no mint, no cutover.
8
+
9
+ import { createHash } from 'node:crypto';
10
+ import { resolve } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+
13
+ export const REGISTRY_ID = 'tool-skill-registry-matrix.v1';
14
+ export const FRONTEND_CELL = 'T';
15
+ export const T_CELL_STATUS = 'PARTIAL_REGISTRY_ARTIFACT_BUILT_LIVE_TOOL_EXECUTION_GATED';
16
+ export const STATUSES = Object.freeze(['GREEN', 'PARTIAL', 'GATED', 'RED']);
17
+
18
+ export const REGISTRY_ITEMS = Object.freeze([
19
+ Object.freeze({
20
+ id: 'preload-catalog',
21
+ kind: 'tool-index',
22
+ status: 'GREEN',
23
+ source: 'tools/behcs/fabric-agent-preload-catalog.mjs',
24
+ exposes: 'laws+routes+tools+roles+workflow-preload-catalog',
25
+ next: 'front-end-may-read-as-index-but-must-not-execute-actions-from-it',
26
+ }),
27
+ Object.freeze({
28
+ id: 'model-selector-matrix',
29
+ kind: 'frontend-tool',
30
+ status: 'PARTIAL',
31
+ source: 'tools/behcs/model-selector-matrix.mjs',
32
+ exposes: 'M-cell-model-role-routing-with-live-invocation-held',
33
+ next: 'runtime-proof-and-live-model-contract-before-green',
34
+ }),
35
+ Object.freeze({
36
+ id: 'project-guide-matrix',
37
+ kind: 'frontend-tool',
38
+ status: 'PARTIAL',
39
+ source: 'tools/behcs/project-guide-matrix.mjs',
40
+ exposes: 'P-cell-guide-to-sealed-artifacts-and-open-gates',
41
+ next: 'workflow-binding-and-submit-schema-before-green',
42
+ }),
43
+ Object.freeze({
44
+ id: 'heal-envelope-emitter',
45
+ kind: 'tool',
46
+ status: 'GREEN',
47
+ source: 'tools/behcs/heal-envelope-emitter.mjs',
48
+ exposes: 'schema-valid-self-heal-proposal-envelopes-only',
49
+ next: 'advance-only-through-registrar-cosign-feeder-daemons-under-gate',
50
+ }),
51
+ Object.freeze({
52
+ id: 'route-health-baseline',
53
+ kind: 'tool',
54
+ status: 'GREEN',
55
+ source: 'tools/behcs/route-health-baseline.mjs+docs/ACER-BUS-HEALTH-CONTRACT-FIX-2026-06-13.hbp',
56
+ exposes: '4944-4947-4949-route-health-and-route-boundary-vs-down',
57
+ next: 'keep-vantage-relative-labels-visible',
58
+ }),
59
+ Object.freeze({
60
+ id: 'mlc-engine-wiring-increment',
61
+ kind: 'tool',
62
+ status: 'PARTIAL',
63
+ source: 'tools/behcs/mlc-engine-wiring-increment.mjs',
64
+ exposes: 'C036-MTP-HRM-GNN-Fischer-Mamba-AoT-descriptor-wiring',
65
+ next: 'fabric-ranked-daemon-contract-before-process-launch',
66
+ }),
67
+ Object.freeze({
68
+ id: 'fabric-council',
69
+ kind: 'skill',
70
+ status: 'PARTIAL',
71
+ source: 'mcp-asolaria-fabric-council-query+/api/council-verdicts',
72
+ exposes: 'ask-fabric-verdict-loop-when-available',
73
+ next: 'cold-path-verdict-cache-before-green',
74
+ }),
75
+ Object.freeze({
76
+ id: 'cosign-submit-schema',
77
+ kind: 'tool',
78
+ status: 'GATED',
79
+ source: 'docs/ACER-SLICE-ENGINE-COSIGN-MINT-2026-06-14.hbp',
80
+ exposes: 'single-writer-cosign-submit-route-known-but-submit-schema-not-front-end-proofed',
81
+ next: 'build-cosign-submit-schema-proof-before-exposing-submit-form',
82
+ }),
83
+ Object.freeze({
84
+ id: 'live-engine-daemon-contract',
85
+ kind: 'skill',
86
+ status: 'GATED',
87
+ source: 'docs/LIRIS-MLC-ENGINE-WIRING-INCREMENT-2026-06-14.hbp+docs/ACER-ATTACK-LIRIS-MLC-ENGINE-WIRING-2026-06-14.hbp',
88
+ exposes: 'C036-live-engine-launch-remains-contract-gated',
89
+ next: 'wait-for-fabric-ranked-daemon-route-and-schema-before-any-launch',
90
+ }),
91
+ ]);
92
+
93
+ const sha16 = (text) => createHash('sha256').update(String(text), 'utf8').digest('hex').slice(0, 16);
94
+ const isObj = (x) => x !== null && typeof x === 'object';
95
+ const safe = (x) => { try { return String(x == null ? '' : x).replace(/[|\r\n]/g, '_'); } catch { return '_'; } };
96
+ const prop = (obj, key, fallback = '') => {
97
+ try { return isObj(obj) ? obj[key] : fallback; } catch { return fallback; }
98
+ };
99
+
100
+ function normalizeStatus(value) {
101
+ const status = safe(value).toUpperCase();
102
+ return STATUSES.includes(status) ? status : 'RED';
103
+ }
104
+
105
+ export function normalizeItem(input) {
106
+ try {
107
+ const id = safe(prop(input, 'id', 'unknown')) || 'unknown';
108
+ const kind = safe(prop(input, 'kind', 'tool')) || 'tool';
109
+ const source = safe(prop(input, 'source', 'CANNOT_SEE')) || 'CANNOT_SEE';
110
+ const exposes = safe(prop(input, 'exposes', 'define-visible-capability'));
111
+ const status = normalizeStatus(prop(input, 'status', 'RED'));
112
+ return {
113
+ id,
114
+ kind,
115
+ status,
116
+ source,
117
+ exposes,
118
+ next: safe(prop(input, 'next', 'define-next-proof')),
119
+ process_launch: 0,
120
+ live_tool_execution: 0,
121
+ cutover: 0,
122
+ row_sha16: sha16([id, kind, status, source, exposes].join('|')),
123
+ };
124
+ } catch {
125
+ return {
126
+ id: 'invalid',
127
+ kind: 'invalid',
128
+ status: 'RED',
129
+ source: 'CANNOT_SEE',
130
+ exposes: 'normalize-threw',
131
+ next: 'fix-invalid-tool-skill-row',
132
+ process_launch: 0,
133
+ live_tool_execution: 0,
134
+ cutover: 0,
135
+ row_sha16: sha16('invalid'),
136
+ };
137
+ }
138
+ }
139
+
140
+ export function registryItem(input = {}) {
141
+ try {
142
+ const topic = safe(prop(input, 'topic', input)).toLowerCase();
143
+ const items = REGISTRY_ITEMS.map(normalizeItem);
144
+ const pick = (id, reason) => ({ topic: safe(topic || 'default'), selected: id, reason, item: items.find((x) => x.id === id) });
145
+ if (/submit|schema|chain|cosign/.test(topic)) return pick('cosign-submit-schema', 'submit-requests-remain-schema-gated');
146
+ if (/route|health|api|dashboard/.test(topic)) return pick('route-health-baseline', 'route-requests-use-health-baseline');
147
+ if (/\bheal\b|repair|\bself\b/.test(topic)) return pick('heal-envelope-emitter', 'heal-requests-use-proposal-emitter-only');
148
+ if (/model|selector|gemma|fischer/.test(topic)) return pick('model-selector-matrix', 'model-requests-use-M-selector-no-live-invocation');
149
+ if (/project|guide|frontier|queue|catch/.test(topic)) return pick('project-guide-matrix', 'project-requests-use-P-guide');
150
+ if (/live|daemon|launch/.test(topic)) return pick('live-engine-daemon-contract', 'live-daemon-requests-stay-contract-gated');
151
+ if (/mlc|engine|mtp|hrm|gnn|mamba|aot/.test(topic)) return pick('mlc-engine-wiring-increment', 'engine-requests-use-descriptor-no-launch');
152
+ if (/council|fabric|verdict|ask/.test(topic)) return pick('fabric-council', 'fabric-requests-use-council-loop-when-available');
153
+ return pick('preload-catalog', 'default-to-preload-catalog-index');
154
+ } catch {
155
+ return { topic: 'invalid', selected: 'preload-catalog', reason: 'registry-threw-default-held', item: normalizeItem(REGISTRY_ITEMS[0]) };
156
+ }
157
+ }
158
+
159
+ export function buildRegistry(input = REGISTRY_ITEMS) {
160
+ const items = (Array.isArray(input) ? input : REGISTRY_ITEMS).map(normalizeItem);
161
+ const count = (status) => items.filter((item) => item.status === status).length;
162
+ return {
163
+ tool: REGISTRY_ID,
164
+ frontend_cell: FRONTEND_CELL,
165
+ items,
166
+ summary: {
167
+ total: items.length,
168
+ green: count('GREEN'),
169
+ partial: count('PARTIAL'),
170
+ gated: count('GATED'),
171
+ red: count('RED'),
172
+ t_cell_status: T_CELL_STATUS,
173
+ live_tool_execution_ready: false,
174
+ cutover_ready: false,
175
+ },
176
+ };
177
+ }
178
+
179
+ export function emitRows(input = REGISTRY_ITEMS, opts = {}) {
180
+ try {
181
+ const built = buildRegistry(input);
182
+ const s = built.summary;
183
+ const limitRaw = Number.parseInt(safe(prop(opts, 'limit', built.items.length)), 10);
184
+ const limit = Math.max(0, Math.min(Number.isFinite(limitRaw) ? limitRaw : built.items.length, built.items.length));
185
+ const rows = [
186
+ `TOOLSKILLHDR|tool=${REGISTRY_ID}|frontend_cell=T|purpose=tool-skill-registry-before-any-live-tool-execution|items=${s.total}|read_only=1|process_launch=0|live_tool_execution=0|no_fetch=1|no_write=1|no_spawn=1|no_mint=1|no_cutover=1|json=0`,
187
+ `TOOLSKILLSUM|green=${s.green}|partial=${s.partial}|gated=${s.gated}|red=${s.red}|T_cell_status=${s.t_cell_status}|cutover_ready=0|json=0`,
188
+ ];
189
+ for (const item of built.items.slice(0, limit)) {
190
+ rows.push(`TOOLSKILL|id=${safe(item.id)}|kind=${safe(item.kind)}|status=${safe(item.status)}|source=${safe(item.source)}|exposes=${safe(item.exposes)}|next=${safe(item.next)}|row_sha16=${safe(item.row_sha16)}|process_launch=0|live_tool_execution=0|cutover=0|json=0`);
191
+ }
192
+ const topic = prop(opts, 'topic', '');
193
+ if (topic) {
194
+ const selected = registryItem({ topic });
195
+ rows.push(`TOOLSKILLROUTE|topic=${safe(selected.topic)}|selected=${safe(selected.selected)}|reason=${safe(selected.reason)}|selected_status=${safe(prop(selected.item, 'status', 'RED'))}|json=0`);
196
+ }
197
+ rows.push('TOOLSKILLGATE|front_end_cell=T|status=PARTIAL|reason=registry-artifact-built-but-live-tool-execution-submit-form-and-live-daemon-contract-remain-gated|process_launch=0|live_tool_execution=0|cutover=0|json=0');
198
+ return rows;
199
+ } catch {
200
+ return [
201
+ `TOOLSKILLHDR|tool=${REGISTRY_ID}|frontend_cell=T|purpose=tool-skill-registry-before-any-live-tool-execution|items=0|read_only=1|process_launch=0|live_tool_execution=0|no_cutover=1|json=0`,
202
+ 'TOOLSKILLGATE|front_end_cell=T|status=RED|reason=emit-threw-held-invalid|process_launch=0|live_tool_execution=0|cutover=0|json=0',
203
+ ];
204
+ }
205
+ }
206
+
207
+ export function selfTest() {
208
+ const checks = [];
209
+ const add = (name, ok) => checks.push({ name, ok: Boolean(ok) });
210
+ const registry = buildRegistry();
211
+ add('all-items-present', registry.summary.total === 9 && registry.items.some((x) => x.id === 'cosign-submit-schema'));
212
+ add('t-cell-partial-not-green', registry.summary.t_cell_status === T_CELL_STATUS && registry.summary.cutover_ready === false);
213
+ add('no-live-tool-execution', registry.items.every((x) => x.process_launch === 0 && x.live_tool_execution === 0 && x.cutover === 0));
214
+ add('routes-cosign-schema', registryItem({ topic: 'cosign submit schema' }).selected === 'cosign-submit-schema');
215
+ add('routes-tool-skill-default', registryItem({ topic: 'tool skill registry' }).selected === 'preload-catalog');
216
+ add('routes-live-engine-gated', registryItem({ topic: 'live engine daemon launch' }).selected === 'live-engine-daemon-contract');
217
+ const hostile = emitRows([{ id: 'x|bad', kind: 'tool\nbad', status: 'GREEN', source: 's|json=1', exposes: 'e\nTOOLSKILLGATE|process_launch=1' }], { topic: 'schema|json=1\nTOOLSKILLGATE|process_launch=1' });
218
+ add('rows-hbp-only', hostile.every((row) => row.endsWith('|json=0') && !/[\r\n]/.test(row)));
219
+ add('total-never-throws', (() => { try { normalizeItem({ get id() { throw new Error('boom'); } }); registryItem({ get topic() { throw new Error('boom'); } }); emitRows(null); return true; } catch { return false; } })());
220
+ return { ok: checks.every((c) => c.ok), checks };
221
+ }
222
+
223
+ const isMain = process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1]);
224
+ if (isMain) {
225
+ if (process.argv[2] === '--self-test') {
226
+ const r = selfTest();
227
+ for (const c of r.checks) console.log(`${c.ok ? 'PASS' : 'FAIL'} ${c.name}`);
228
+ process.exit(r.ok ? 0 : 1);
229
+ }
230
+ const topicArg = process.argv.find((arg) => arg.startsWith('--topic='));
231
+ const limitArg = process.argv.find((arg) => arg.startsWith('--limit='));
232
+ const opts = {
233
+ topic: topicArg ? topicArg.slice('--topic='.length) : '',
234
+ limit: limitArg ? limitArg.slice('--limit='.length) : REGISTRY_ITEMS.length,
235
+ };
236
+ process.stdout.write(emitRows(REGISTRY_ITEMS, opts).join('\n') + '\n');
237
+ }
tools/behcs/tool-skill-registry-matrix.mjs.sha256 ADDED
@@ -0,0 +1 @@
 
 
1
+ 9386738C70BF32860305B7DFADCDE253407287E5D8E35B5683D227B9EEA3169A tool-skill-registry-matrix.mjs