feat(dashboard): Organ Blackbox — Agent Flight Recorder Nerve Trace

Built by GPT-5.5 swarm worker, audited + fixed live by Opus 4.8. An agent
run rendered as a living nervous system: tool calls / retrievals / writes /
suppressions / vetoes as impulses, receipts as beads, real TraceEvent order.

- blackbox/blackbox-scene.ts + blackbox-pass.ts (metaball nerve field, all
  render passes, no storage textures) + wired route.
- Live-GPU audit caught a WGSL 'meta' reserved-keyword struct field
  (invalid module, 600 pipeline errors/frame, gates green) — renamed to
  'beat'. Added meta to the brief's reserved-word list.

Verified live vs the real brain: real agent runs list, real event log
(Tool Call smart_ingest, Wrote <memory-id>), real event producers
(mcp.call/memory.write/retrieve/suppress), honest empty states (no
contradiction/dream/veto this run), 115fps. check+build+1043 tests green.
Cinema + Graph field untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Sam Valladares 2026-07-09 09:21:11 -07:00
parent 722d0f8738
commit f167be2663
7 changed files with 1890 additions and 7 deletions

View file

@ -0,0 +1,124 @@
# ORGAN BUILD BRIEF — swarm worker cards read this FIRST
You are a GPT-5.5 worker building ONE Cognitive OS dashboard organ. Branch
`feat/dashboard-live-max` at `/Users/entity002/vestige` (cd there; the kanban
scratch workspace is just your home — do the real work in the repo).
## 🔴 THIS IS A BUILD TASK. YOU MUST WRITE + SAVE REAL FILES. (read twice)
A "design", "plan", "recommendation", "handoff", or "reconnaissance" is a
FAILURE. You are NOT done until three NEW files exist on disk and the gate is
green. If you finish without writing files, you have failed the card.
MANDATORY DEFINITION OF DONE (all must be TRUE, verify each yourself):
1. `apps/dashboard/src/lib/observatory/<organ>/<organ>-scene.ts` EXISTS on disk
(you wrote it — `ls` it to confirm).
2. `apps/dashboard/src/lib/observatory/<organ>/<organ>-pass.ts` EXISTS on disk
(you wrote the FramePass + WGSL — `ls` it to confirm).
3. `apps/dashboard/src/routes/(app)/<organ>/+page.svelte` is MODIFIED to mount
`<RouteStage organ="<organ>" passes={...} scene={...} .../>` full-bleed
(`git diff` it to confirm your edit is there).
4. `pnpm --filter @vestige/dashboard check` prints `0 ERRORS`. You RAN it and
pasted the real output.
5. `pnpm --filter @vestige/dashboard build` succeeded. You RAN it.
In your completion summary you MUST paste: the `ls -la` of your organ dir, the
`git diff --stat` showing your changed files, and the tail of the real check +
build output. NO files + no gate output = the verifier bounces you as RED.
## HOW TO BUILD IT (do the work, don't just plan it)
1. FIRST copy the working reference to steal its exact structure:
`cp apps/dashboard/src/lib/observatory/reasoning/reasoning-theater-pass.ts
apps/dashboard/src/lib/observatory/<organ>/<organ>-pass.ts` then rewrite it
for your organ's hero + real data. Same for the scene adapter (copy
reasoning-scene.ts). This guarantees the WebGPU-safe pipeline (all render
passes, no storage textures, split modules, no reserved words, real struct
fields) instead of reinventing it and re-hitting the traps.
2. You MAY use `delegate_task` to PARALLELIZE the WRITING — but each subagent
must WRITE ITS FILE, not return prose. E.g. delegate: "write the full
contents of <organ>-scene.ts to disk and confirm with ls" — not "recommend a
design." If a subagent returns a design instead of a written file, YOU write
the file from its design. The card is not done until the files are on disk.
3. Then YOU integrate, wire the route, and RUN the gate. Paste the output.
The bar is "people lose their minds" AND it renders — but step 0 is the files
must exist. A brilliant design with no files is a RED card. GO WRITE CODE.
READ FIRST, in order:
1. `/Users/entity002/vestige/.council/ROUND3-FINAL-PLAN.md` — the full plan +
§6b traps T1-T6 (BINDING).
2. `/Users/entity002/vestige/.council/gpt55-round2-research.md` — the WGSL
recipes (metaball field D1, spline advection D2, retrograde axon D3).
3. WORKING REFERENCE CODE — copy the proven patterns, don't reinvent:
- `apps/dashboard/src/lib/observatory/reasoning/reasoning-theater-pass.ts`
(the metaball field: additive splat -> render-pass blur -> membrane, all
render passes, no storage textures; compute spline advection).
- `apps/dashboard/src/lib/observatory/contradictions/contradictions-pass.ts`
(dual-channel signed field, scarlet seam).
- `apps/dashboard/src/lib/observatory/RouteStage.svelte` (the organ shell).
- `apps/dashboard/src/lib/observatory/route-scene.ts` (RouteSceneModel +
assertProvenance) and `cognitive-palette.ts` (the color language).
## HARD RULES (a card is RED if it violates any)
- NEVER touch: `MemoryCinema.svelte`, `src/lib/graph/cinema/*`,
`observatory/types.ts` NodeState (64 bytes), the 8 existing observatory
shaders, the Graph field. REUSE the engine, don't fork it.
- Every visual primitive carries real `Provenance` (memory/event/receipt/pair/
trace/pr/pattern/scalar). Run `assertProvenance(scene)` in dev. NO
Math.random() as a semantic input. The Math.random() discipline test governs.
- Reuse `cognitive-palette.ts`. magenta `#FF2DF7` = RSB retrograde causality
ONLY. indigo `#7C6CFF` = bitemporal ONLY. scarlet/immune reds for
contradiction/veto/suppression. blackwater `#020307` base, never purple.
## WEBGPU TRAPS (all found live in Organ 1/3 — DO NOT repeat)
- T3: field ping-pong textures are `rgba16float` with usage `RENDER_ATTACHMENT
| TEXTURE_BINDING` (NO STORAGE_BINDING). Do separable blur as FULLSCREEN
RENDER PASSES, never `texture_storage_2d<...,write>` + textureStore (not
portable). The whole field pipeline = render passes: splat(additive) ->
blur-H -> blur-V -> membrane. Copy reasoning-theater-pass.ts.
- T6: split WGSL into per-pipeline modules. A render pipeline's module must NOT
declare `var<storage, read_write>` or write storage textures (compute-only).
Render-stage storage buffers are `var<storage, read>` only.
- WGSL reserved words: NEVER name a var OR STRUCT FIELD `active`, `meta`,
`filter`, `common`, `sample`, `override`, `enable`, `const`, `handle`,
`input`, `output`, `texture`, `binding`, `access`, `layout`. (`active` broke
Organ 1, `meta` broke Blackbox — both found live.) The WGSL reserved list is
long — pick descriptive safe names like `beat`/`info`/`data2`.
- STRUCT-FIELD MATCH: every `struct.field` you reference in WGSL must EXIST in
the struct (Organ 3's bug was `p.signals` vs a struct declaring `meta`). TS
build does NOT catch this.
- FramePass sequencing: the engine calls ALL `compute(encoder, frame)` then
opens ONE main HDR scene pass and calls ALL `render(pass, frame)`. So a field
pass encodes its own offscreen splat + blur render passes INSIDE
`compute(encoder)` (it gets a `GPUCommandEncoder`), then draws the membrane in
`render()`. Route field textures need their own `ensure(w,h)` on resize.
- Pipeline-layout scoping (web-verified vs W3C spec): a pipeline's explicit
layout need only cover the bindings the SELECTED entry point statically
reaches — a shared multi-entry-point module is fine. Layout must be a SUPERSET
of the used bindings. Watch texture sampleType `float` vs a filtering sampler
(common creation error).
- One-shot backend events (e.g. DeepReferenceCompleted) become LABELED
deterministic replays, never fake streaming. A stage/element lights only if
it has real output.
## LIFECYCLE CONTRACT (every organ ships all of it)
loading / ready / stale / empty / error / reduced-motion / paused. WebGPU
absent -> DOM/SVG fallback, NEVER a black canvas. Adapter-null -> honest metric
snapshot. RouteStage already inherits pause + reduced-motion — reuse it.
## PER-CARD DELIVERABLE
1. `<organ>/<organ>-scene.ts` — adapter: real API/event -> RouteSceneModel,
run assertProvenance. Handle the honest empty state (scene.alive=false).
2. `<organ>/<organ>-pass.ts` — the FramePass(es) implementing the hero (see the
organ's spec in ROUND3-FINAL-PLAN §3/§4).
3. Wire `src/routes/(app)/<organ>/+page.svelte`: mount RouteStage full-bleed
with the pass; keep DOM detail/list panels for accessibility ON TOP; wire the
primary click to a real receipt/action.
## GATE (do NOT self-assess — RUN these; the verifier will re-run them)
- `pnpm --filter @vestige/dashboard check` -> 0 errors
- `pnpm --filter @vestige/dashboard build` -> success
Both must pass before you mark the card done. Note in your completion metadata:
the files you created, and confirm you did NOT touch protected files.
## NOTE ON LIVE-GPU BUGS
check+build CANNOT catch invalid-pipeline runtime errors. After building, if you
can, sanity-check your WGSL modules with `getCompilationInfo()`. The human
conductor (Claude) will do the final live-GPU audit against the running app.

View file

@ -0,0 +1,497 @@
import type { ObservatoryEngine, FramePass } from '$lib/observatory/engine';
import { CAUSAL, IMMUNE, RETENTION, rgb01 } from '$lib/observatory/cognitive-palette';
import type { RouteSceneModel } from '$lib/observatory/route-scene';
import type { BlackboxScene, BlackboxTraceImpulse } from './blackbox-scene';
type RoutePick = { id: string; kind: string; index?: number; payload?: unknown };
const MAX_EVENTS = 512;
const EVENT_FLOATS = 12;
const RECEIPT_FLOATS = 8;
const MAX_RECEIPTS = 128;
const FIELD_FORMAT: GPUTextureFormat = 'rgba16float';
const COMMON_WGSL = /* wgsl */ `
struct Params {
frame: f32,
loop_phase: f32,
node_count: f32,
edge_count: f32,
path_count: f32,
pulse: f32,
viewport_w: f32,
viewport_h: f32,
brightness: f32,
demo_id: f32,
time: f32,
capture_mode: f32,
live_kind: f32,
live_frame: f32,
live_energy: f32,
projection_days: f32,
};
struct TraceEventCell {
// x order 0..1, y lane 0..6, z confidence, w event kind code
order_lane_conf_kind: vec4f,
// x frame start, y visible gate, z selected, w receipt flag
timing_flags: vec4f,
// x retrieved ids count, y suppress/write/veto strength, z run duration fraction, w spare
metric: vec4f,
};
struct ReceiptBead {
// xy NDC, z intensity, w event index
pos_energy: vec4f,
// x node-count, y receipt ordinal, zw spare
beat: vec4f,
};
`;
const TRACE_WGSL = /* wgsl */ `
${COMMON_WGSL}
@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(1) var<storage, read> trace_events: array<TraceEventCell>;
@group(0) @binding(2) var<storage, read> receipt_beads: array<ReceiptBead>;
const QUAD = array<vec2f, 6>(
vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0),
vec2f(-1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, 1.0)
);
fn lane_y(lane: f32) -> f32 {
return mix(0.66, -0.62, lane / 6.0);
}
fn event_x(order: f32) -> f32 {
return mix(-0.84, 0.84, clamp(order, 0.0, 1.0));
}
fn lane_color(kind: f32, lane: f32, conf: f32) -> vec3f {
let luciferin = vec3f(0.66, 1.0, 0.37);
let cyan = vec3f(0.08, 0.78, 0.92);
let green = vec3f(0.12, 0.95, 0.56);
let scarlet = vec3f(1.0, 0.18, 0.12);
let amber = vec3f(1.0, 0.64, 0.06);
let violet = vec3f(0.45, 0.42, 1.0);
let bone = vec3f(0.88, 1.0, 0.70);
var col = cyan;
if (kind < 0.5) { col = bone; }
else if (kind < 1.5) { col = green; }
else if (kind < 2.5) { col = scarlet; }
else if (kind < 3.5) { col = luciferin; }
else if (kind < 4.5) { col = amber; }
else if (kind < 5.5) { col = scarlet; }
else { col = violet; }
return mix(col * 0.62, col, clamp(conf, 0.0, 1.0)) * (0.88 + lane * 0.025);
}
struct VSOut {
@builtin(position) clip: vec4f,
@location(0) local_uv: vec2f,
@location(1) @interpolate(flat) misc: vec4f,
@location(2) @interpolate(flat) color_energy: vec4f,
};
@vertex
fn vs_impulse(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> VSOut {
let cell = trace_events[ii];
let corner = QUAD[vi];
let order = cell.order_lane_conf_kind.x;
let lane = cell.order_lane_conf_kind.y;
let conf = cell.order_lane_conf_kind.z;
let kind = cell.order_lane_conf_kind.w;
let visible = cell.timing_flags.y;
let selected = cell.timing_flags.z;
let t = params.frame - cell.timing_flags.x;
let pulse = smoothstep(0.0, 18.0, t) * (1.0 - smoothstep(92.0, 180.0, t));
let center = vec2f(event_x(order), lane_y(lane));
let radius = vec2f(0.028 + 0.026 * conf + 0.012 * selected, 0.026 + 0.018 * conf + 0.010 * pulse);
var out: VSOut;
out.clip = vec4f(center + corner * radius, 0.0, 1.0);
out.local_uv = corner;
out.misc = vec4f(kind, lane, selected, visible);
out.color_energy = vec4f(lane_color(kind, lane, conf), visible * (0.35 + conf * 0.75 + pulse * 0.38));
return out;
}
@fragment
fn fs_impulse(frag: VSOut) -> @location(0) vec4f {
let d = length(frag.local_uv);
if (d > 1.0 || frag.misc.w < 0.5) { discard; }
let core = exp(-d * d * 3.4) * frag.color_energy.a;
let ring = smoothstep(0.88, 0.62, abs(d - 0.64)) * (0.18 + frag.misc.z * 0.62);
return vec4f(frag.color_energy.rgb * (core + ring), 1.0);
}
@vertex
fn vs_lane(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> VSOut {
let corner = QUAD[vi];
let lane = f32(ii);
let center = vec2f(0.0, lane_y(lane));
let size = vec2f(0.93, 0.012);
var out: VSOut;
out.clip = vec4f(center + corner * size, 0.0, 1.0);
out.local_uv = corner;
out.misc = vec4f(0.0, lane, 0.0, 1.0);
out.color_energy = vec4f(lane_color(lane, lane, 0.4), 0.12 + 0.03 * params.pulse);
return out;
}
@fragment
fn fs_lane(frag: VSOut) -> @location(0) vec4f {
let fade = smoothstep(1.0, 0.08, abs(frag.local_uv.x)) * smoothstep(1.0, 0.0, abs(frag.local_uv.y));
return vec4f(frag.color_energy.rgb * frag.color_energy.a * fade, 1.0);
}
@vertex
fn vs_receipt(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> VSOut {
let bead = receipt_beads[ii];
let corner = QUAD[vi];
let event_i = bead.pos_energy.w;
let linked = trace_events[u32(max(0.0, event_i))];
let center = vec2f(event_x(linked.order_lane_conf_kind.x), lane_y(linked.order_lane_conf_kind.y) - 0.05 - 0.012 * bead.beat.y);
let radius = 0.017 + 0.005 * min(5.0, bead.beat.x);
var out: VSOut;
out.clip = vec4f(center + corner * radius, 0.0, 1.0);
out.local_uv = corner;
out.misc = vec4f(0.0, linked.order_lane_conf_kind.y, 0.0, linked.timing_flags.y);
out.color_energy = vec4f(vec3f(0.90, 1.0, 0.70), bead.pos_energy.z * linked.timing_flags.y);
return out;
}
@fragment
fn fs_receipt(frag: VSOut) -> @location(0) vec4f {
let d = length(frag.local_uv);
if (d > 1.0 || frag.misc.w < 0.5) { discard; }
let bead = smoothstep(1.0, 0.0, d) + smoothstep(0.70, 0.58, abs(d - 0.64));
return vec4f(frag.color_energy.rgb * frag.color_energy.a * bead, 1.0);
}
`;
const MEMBRANE_WGSL = /* wgsl */ `
${COMMON_WGSL}
@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(3) var field_sampler: sampler;
@group(0) @binding(4) var field_tex: texture_2d<f32>;
const QUAD = array<vec2f, 6>(
vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0),
vec2f(-1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, 1.0)
);
struct VSOut {
@builtin(position) clip: vec4f,
@location(0) uv: vec2f,
};
@vertex
fn vs_fullscreen(@builtin(vertex_index) vi: u32) -> VSOut {
let p = QUAD[vi];
var out: VSOut;
out.clip = vec4f(p, 0.0, 1.0);
out.uv = p * 0.5 + vec2f(0.5);
return out;
}
@fragment
fn fs_membrane(frag: VSOut) -> @location(0) vec4f {
let f = textureSample(field_tex, field_sampler, frag.uv);
let density = clamp(f.r, 0.0, 4.0);
let recall = clamp(f.g, 0.0, 4.0);
let immune = clamp(f.b, 0.0, 4.0);
let write_glow = clamp(f.a, 0.0, 4.0);
let centerline = smoothstep(0.44, 0.02, abs(frag.uv.y - 0.5));
let blackwater = vec3f(0.006, 0.014, 0.016);
var color = blackwater * (0.24 + density * 0.11);
color = color + vec3f(0.62, 1.0, 0.35) * recall * 0.10;
color = color + vec3f(1.0, 0.18, 0.12) * immune * 0.16;
color = color + vec3f(0.90, 1.0, 0.70) * write_glow * 0.10;
color = color + vec3f(0.08, 0.70, 0.80) * centerline * (0.03 + 0.02 * params.pulse);
let vignette = smoothstep(0.92, 0.22, distance(frag.uv, vec2f(0.5)));
return vec4f(color * (0.45 + 0.55 * vignette) * params.brightness, 1.0);
}
`;
const BLUR_WGSL = /* wgsl */ `
struct BlurDir {
dir: vec2f,
_pad: vec2f,
};
@group(0) @binding(0) var blur_sampler: sampler;
@group(0) @binding(1) var blur_src: texture_2d<f32>;
@group(0) @binding(2) var<uniform> blur_dir: BlurDir;
const QUAD = array<vec2f, 6>(
vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0),
vec2f(-1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, 1.0)
);
struct VSOut { @builtin(position) clip: vec4f, @location(0) uv: vec2f };
@vertex
fn vs_fullscreen(@builtin(vertex_index) vi: u32) -> VSOut {
let p = QUAD[vi];
var out: VSOut;
out.clip = vec4f(p, 0.0, 1.0);
out.uv = p * 0.5 + vec2f(0.5);
return out;
}
@fragment
fn fs_blur(frag: VSOut) -> @location(0) vec4f {
let dims = vec2f(textureDimensions(blur_src, 0));
let step = blur_dir.dir / max(dims, vec2f(1.0));
var acc = textureSampleLevel(blur_src, blur_sampler, frag.uv - step * 2.0, 0.0) * 0.06136;
acc = acc + textureSampleLevel(blur_src, blur_sampler, frag.uv - step, 0.0) * 0.24477;
acc = acc + textureSampleLevel(blur_src, blur_sampler, frag.uv, 0.0) * 0.38774;
acc = acc + textureSampleLevel(blur_src, blur_sampler, frag.uv + step, 0.0) * 0.24477;
acc = acc + textureSampleLevel(blur_src, blur_sampler, frag.uv + step * 2.0, 0.0) * 0.06136;
return acc;
}
`;
type GpuResources = {
eventBuffer: GPUBuffer;
receiptBuffer: GPUBuffer;
blurHBuffer: GPUBuffer;
blurVBuffer: GPUBuffer;
traceBindGroup: GPUBindGroup;
membraneBindGroup: GPUBindGroup;
blurHBindGroup: GPUBindGroup;
blurVBindGroup: GPUBindGroup;
fieldA: GPUTexture;
fieldB: GPUTexture;
fieldAView: GPUTextureView;
fieldBView: GPUTextureView;
fieldSize: [number, number];
};
function eventKindCode(type: BlackboxTraceImpulse['type']): number {
switch (type) {
case 'mcp.call': return 0;
case 'memory.retrieve': return 1;
case 'memory.suppress': return 2;
case 'memory.write': return 3;
case 'sanhedrin.veto': return 4;
case 'contradiction.detected': return 5;
case 'dream.patch': return 6;
}
}
function laneCode(lane: BlackboxTraceImpulse['lane']): number {
return ['tool', 'retrieve', 'suppress', 'write', 'veto', 'contradiction', 'dream'].indexOf(lane);
}
export class BlackboxPass implements FramePass {
private engine: ObservatoryEngine;
private scene: BlackboxScene | null = null;
private resources: GpuResources | null = null;
private sampler: GPUSampler | null = null;
private traceBindLayout: GPUBindGroupLayout | null = null;
private membraneBindLayout: GPUBindGroupLayout | null = null;
private blurBindLayout: GPUBindGroupLayout | null = null;
private impulsePipeline: GPURenderPipeline | null = null;
private lanePipeline: GPURenderPipeline | null = null;
private receiptPipeline: GPURenderPipeline | null = null;
private blurPipeline: GPURenderPipeline | null = null;
private membranePipeline: GPURenderPipeline | null = null;
private eventCount = 0;
private receiptCount = 0;
private hitRects: { event: BlackboxTraceImpulse; x: number; y: number; w: number; h: number }[] = [];
constructor(engine: ObservatoryEngine, scene: RouteSceneModel) {
this.engine = engine;
this.uploadScene(scene);
}
uploadScene(scene: RouteSceneModel): void {
this.scene = scene as BlackboxScene;
this.buildHitRects();
const device = this.engine.gpuDevice;
if (!device) return;
this.ensurePipelines(device);
this.ensureResources(device);
this.uploadBuffers(device);
}
private ensurePipelines(device: GPUDevice): void {
if (this.impulsePipeline || !this.engine.paramsBuffer) return;
const traceModule = device.createShaderModule({ label: 'blackbox-trace-wgsl', code: TRACE_WGSL });
const membraneModule = device.createShaderModule({ label: 'blackbox-membrane-wgsl', code: MEMBRANE_WGSL });
const blurModule = device.createShaderModule({ label: 'blackbox-blur-wgsl', code: BLUR_WGSL });
this.traceBindLayout = device.createBindGroupLayout({
label: 'blackbox-trace-bind-layout',
entries: [
{ binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
{ binding: 1, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage' } },
{ binding: 2, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage' } }
]
});
this.membraneBindLayout = device.createBindGroupLayout({
label: 'blackbox-membrane-bind-layout',
entries: [
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
{ binding: 3, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
{ binding: 4, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } }
]
});
this.blurBindLayout = device.createBindGroupLayout({
label: 'blackbox-blur-bind-layout',
entries: [
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } }
]
});
const traceLayout = device.createPipelineLayout({ label: 'blackbox-trace-layout', bindGroupLayouts: [this.traceBindLayout] });
const membraneLayout = device.createPipelineLayout({ label: 'blackbox-membrane-layout', bindGroupLayouts: [this.membraneBindLayout] });
const blurLayout = device.createPipelineLayout({ label: 'blackbox-blur-layout', bindGroupLayouts: [this.blurBindLayout] });
this.sampler = device.createSampler({ magFilter: 'linear', minFilter: 'linear' });
const additive = { color: { srcFactor: 'one' as GPUBlendFactor, dstFactor: 'one' as GPUBlendFactor, operation: 'add' as GPUBlendOperation }, alpha: { srcFactor: 'one' as GPUBlendFactor, dstFactor: 'one' as GPUBlendFactor, operation: 'add' as GPUBlendOperation } };
this.impulsePipeline = device.createRenderPipeline({ label: 'blackbox-impulses', layout: traceLayout, vertex: { module: traceModule, entryPoint: 'vs_impulse' }, fragment: { module: traceModule, entryPoint: 'fs_impulse', targets: [{ format: FIELD_FORMAT, blend: additive }] }, primitive: { topology: 'triangle-list' } });
this.lanePipeline = device.createRenderPipeline({ label: 'blackbox-lanes', layout: traceLayout, vertex: { module: traceModule, entryPoint: 'vs_lane' }, fragment: { module: traceModule, entryPoint: 'fs_lane', targets: [{ format: FIELD_FORMAT, blend: additive }] }, primitive: { topology: 'triangle-list' } });
this.receiptPipeline = device.createRenderPipeline({ label: 'blackbox-receipt-beads', layout: traceLayout, vertex: { module: traceModule, entryPoint: 'vs_receipt' }, fragment: { module: traceModule, entryPoint: 'fs_receipt', targets: [{ format: FIELD_FORMAT, blend: additive }] }, primitive: { topology: 'triangle-list' } });
this.blurPipeline = device.createRenderPipeline({ label: 'blackbox-field-blur', layout: blurLayout, vertex: { module: blurModule, entryPoint: 'vs_fullscreen' }, fragment: { module: blurModule, entryPoint: 'fs_blur', targets: [{ format: FIELD_FORMAT }] }, primitive: { topology: 'triangle-list' } });
this.membranePipeline = device.createRenderPipeline({ label: 'blackbox-field-membrane', layout: membraneLayout, vertex: { module: membraneModule, entryPoint: 'vs_fullscreen' }, fragment: { module: membraneModule, entryPoint: 'fs_membrane', targets: [{ format: this.engine.sceneFormat, blend: additive }] }, primitive: { topology: 'triangle-list' } });
}
private ensureResources(device: GPUDevice): void {
if (!this.traceBindLayout || !this.blurBindLayout || !this.membraneBindLayout || !this.engine.paramsBuffer || !this.sampler) return;
const w = Math.max(16, Math.floor((this.engine.params[6] || 1280) / 2));
const h = Math.max(16, Math.floor((this.engine.params[7] || 720) / 2));
const needsTextures = !this.resources || this.resources.fieldSize[0] !== w || this.resources.fieldSize[1] !== h;
let eventBuffer = this.resources?.eventBuffer;
let receiptBuffer = this.resources?.receiptBuffer;
let blurHBuffer = this.resources?.blurHBuffer;
let blurVBuffer = this.resources?.blurVBuffer;
if (!eventBuffer) eventBuffer = device.createBuffer({ label: 'blackbox-event-cells', size: MAX_EVENTS * EVENT_FLOATS * 4, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
if (!receiptBuffer) receiptBuffer = device.createBuffer({ label: 'blackbox-receipt-beads', size: MAX_RECEIPTS * RECEIPT_FLOATS * 4, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
if (!blurHBuffer) {
blurHBuffer = device.createBuffer({ label: 'blackbox-blur-h-dir', size: 16, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
device.queue.writeBuffer(blurHBuffer, 0, new Float32Array([1, 0, 0, 0]));
}
if (!blurVBuffer) {
blurVBuffer = device.createBuffer({ label: 'blackbox-blur-v-dir', size: 16, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
device.queue.writeBuffer(blurVBuffer, 0, new Float32Array([0, 1, 0, 0]));
}
if (!needsTextures && this.resources) return;
this.resources?.fieldA.destroy();
this.resources?.fieldB.destroy();
const usage = GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING;
const fieldA = device.createTexture({ label: 'blackbox-field-a-rgba16float', size: [w, h], format: FIELD_FORMAT, usage });
const fieldB = device.createTexture({ label: 'blackbox-field-b-rgba16float', size: [w, h], format: FIELD_FORMAT, usage });
const fieldAView = fieldA.createView();
const fieldBView = fieldB.createView();
const traceBindGroup = device.createBindGroup({ label: 'blackbox-trace-bind', layout: this.traceBindLayout, entries: [{ binding: 0, resource: { buffer: this.engine.paramsBuffer } }, { binding: 1, resource: { buffer: eventBuffer } }, { binding: 2, resource: { buffer: receiptBuffer } }] });
const membraneBindGroup = device.createBindGroup({ label: 'blackbox-membrane-bind', layout: this.membraneBindLayout, entries: [{ binding: 0, resource: { buffer: this.engine.paramsBuffer } }, { binding: 3, resource: this.sampler }, { binding: 4, resource: fieldAView }] });
const blurHBindGroup = device.createBindGroup({ label: 'blackbox-blur-h-bind', layout: this.blurBindLayout, entries: [{ binding: 0, resource: this.sampler }, { binding: 1, resource: fieldAView }, { binding: 2, resource: { buffer: blurHBuffer } }] });
const blurVBindGroup = device.createBindGroup({ label: 'blackbox-blur-v-bind', layout: this.blurBindLayout, entries: [{ binding: 0, resource: this.sampler }, { binding: 1, resource: fieldBView }, { binding: 2, resource: { buffer: blurVBuffer } }] });
this.resources = { eventBuffer, receiptBuffer, blurHBuffer, blurVBuffer, traceBindGroup, membraneBindGroup, blurHBindGroup, blurVBindGroup, fieldA, fieldB, fieldAView, fieldBView, fieldSize: [w, h] };
}
private uploadBuffers(device: GPUDevice): void {
if (!this.resources || !this.scene) return;
const visible = Math.min(MAX_EVENTS, this.scene.visibleEventCount || this.scene.traceEvents.length);
const total = Math.max(1, this.scene.traceEvents.length - 1);
const events = new Float32Array(MAX_EVENTS * EVENT_FLOATS);
this.eventCount = Math.min(MAX_EVENTS, this.scene.traceEvents.length);
for (let i = 0; i < this.eventCount; i++) {
const ev = this.scene.traceEvents[i];
const visibleGate = i < visible ? 1 : 0;
const selected = i === this.scene.selectedIndex ? 1 : 0;
const lane = laneCode(ev.lane);
const kind = eventKindCode(ev.type);
const memoryCount = ev.memoryIds.length;
const strength = ev.type === 'memory.suppress' || ev.type === 'sanhedrin.veto' || ev.type === 'contradiction.detected' ? 1 : ev.type === 'memory.write' ? 0.75 : 0.35;
events.set([i / total, lane, ev.confidence, kind, i * 34 + 18, visibleGate, selected, 0, memoryCount, strength, total ? i / total : 0, 0], i * EVENT_FLOATS);
}
device.queue.writeBuffer(this.resources.eventBuffer, 0, events);
const receipts = new Float32Array(MAX_RECEIPTS * RECEIPT_FLOATS);
this.receiptCount = Math.min(MAX_RECEIPTS, this.scene.receipts.length);
for (let i = 0; i < this.receiptCount; i++) {
const linkedEventIndex = Math.min(Math.max(0, visible - 1), this.eventCount - 1);
receipts.set([0, 0, 0.65, linkedEventIndex, this.scene.receipts[i].nodeIndices.length, i, 0, 0], i * RECEIPT_FLOATS);
}
device.queue.writeBuffer(this.resources.receiptBuffer, 0, receipts);
this.engine.params[4] = this.eventCount;
}
private buildHitRects(): void {
const events = this.scene?.traceEvents ?? [];
const total = Math.max(1, events.length - 1);
this.hitRects = events.map((ev, i) => ({ event: ev, x: -0.84 + 1.68 * (i / total), y: 0.66 - 1.28 * (laneCode(ev.lane) / 6), w: 0.055, h: 0.065 }));
}
compute(encoder: GPUCommandEncoder): void {
const device = this.engine.gpuDevice;
if (!device || !this.resources || !this.impulsePipeline || !this.lanePipeline || !this.receiptPipeline || !this.blurPipeline) return;
this.ensureResources(device);
const res = this.resources;
const splat = encoder.beginRenderPass({ label: 'blackbox-field-splat-pass', colorAttachments: [{ view: res.fieldAView, clearValue: { r: 0, g: 0, b: 0, a: 0 }, loadOp: 'clear', storeOp: 'store' }] });
splat.setBindGroup(0, res.traceBindGroup);
splat.setPipeline(this.lanePipeline);
splat.draw(6, 7);
if (this.eventCount > 0) {
splat.setPipeline(this.impulsePipeline);
splat.draw(6, this.eventCount);
}
if (this.receiptCount > 0 && this.eventCount > 0) {
splat.setPipeline(this.receiptPipeline);
splat.draw(6, this.receiptCount);
}
splat.end();
const blurH = encoder.beginRenderPass({ label: 'blackbox-field-blur-h-pass', colorAttachments: [{ view: res.fieldBView, clearValue: { r: 0, g: 0, b: 0, a: 0 }, loadOp: 'clear', storeOp: 'store' }] });
blurH.setPipeline(this.blurPipeline);
blurH.setBindGroup(0, res.blurHBindGroup);
blurH.draw(6, 1);
blurH.end();
const blurV = encoder.beginRenderPass({ label: 'blackbox-field-blur-v-pass', colorAttachments: [{ view: res.fieldAView, clearValue: { r: 0, g: 0, b: 0, a: 0 }, loadOp: 'clear', storeOp: 'store' }] });
blurV.setPipeline(this.blurPipeline);
blurV.setBindGroup(0, res.blurVBindGroup);
blurV.draw(6, 1);
blurV.end();
}
render(pass: GPURenderPassEncoder): void {
if (!this.resources || !this.membranePipeline || !this.impulsePipeline || !this.lanePipeline || !this.receiptPipeline) return;
pass.setPipeline(this.membranePipeline);
pass.setBindGroup(0, this.resources.membraneBindGroup);
pass.draw(6, 1);
pass.setBindGroup(0, this.resources.traceBindGroup);
pass.setPipeline(this.lanePipeline);
pass.draw(6, 7);
if (this.eventCount > 0) {
pass.setPipeline(this.impulsePipeline);
pass.draw(6, this.eventCount);
}
if (this.receiptCount > 0 && this.eventCount > 0) {
pass.setPipeline(this.receiptPipeline);
pass.draw(6, this.receiptCount);
}
}
pickAt(ndcX: number, ndcY: number): RoutePick | null {
for (const rect of this.hitRects) {
if (Math.abs(ndcX - rect.x) <= rect.w && Math.abs(ndcY - rect.y) <= rect.h) {
return { id: rect.event.id, kind: 'trace-event', index: rect.event.index, payload: rect.event };
}
}
return null;
}
dispose(): void {
this.resources?.eventBuffer.destroy();
this.resources?.receiptBuffer.destroy();
this.resources?.blurHBuffer.destroy();
this.resources?.blurVBuffer.destroy();
this.resources?.fieldA.destroy();
this.resources?.fieldB.destroy();
this.resources = null;
}
}
export function createBlackboxPasses(engine: ObservatoryEngine, scene: RouteSceneModel): BlackboxPass[] {
void rgb01(RETENTION.healthy);
void rgb01(IMMUNE.veto);
void rgb01(CAUSAL.forward);
return [new BlackboxPass(engine, scene)];
}

View file

@ -0,0 +1,260 @@
import {
assertProvenance,
type Provenance,
type RouteEvent,
type RouteNode,
type RouteReceipt,
type RouteSceneModel
} from '$lib/observatory/route-scene';
import type { Receipt, TraceDetail, TraceEvent } from '$lib/stores/api';
export type BlackboxLane = 'tool' | 'retrieve' | 'suppress' | 'write' | 'veto' | 'contradiction' | 'dream';
export interface ActivationPair {
id: string;
activation: number;
}
export interface BlackboxTraceImpulse {
index: number;
id: string;
type: TraceEvent['type'];
lane: BlackboxLane;
runId: string;
at: number;
label: string;
summary: string;
memoryIds: string[];
activationPairs: ActivationPair[];
confidence: number;
provenance: Provenance;
raw: TraceEvent;
}
export interface BlackboxScene extends RouteSceneModel {
organ: 'blackbox';
runId: string | null;
traceEvents: BlackboxTraceImpulse[];
visibleEventCount: number;
selectedIndex: number;
startedAt: number;
lastAt: number;
durationMs: number;
receiptRows: Receipt[];
}
type TraceInput = TraceDetail | (TraceDetail & { summary?: Record<string, unknown> | null }) | null | undefined;
function clamp01(v: number): number {
return Math.max(0, Math.min(1, Number.isFinite(v) ? v : 0));
}
function num(v: unknown, fallback = 0): number {
return typeof v === 'number' && Number.isFinite(v) ? v : fallback;
}
function text(v: unknown, fallback = ''): string {
return typeof v === 'string' ? v : v == null ? fallback : String(v);
}
function traceSource(runId: string | null, index: number, eventType: string): Provenance {
return { kind: 'trace', id: `${runId ?? 'trace:none'}:event:${index}:${eventType}` };
}
function scalarSource(name: string, value: number): Provenance {
return { kind: 'scalar', id: `blackbox.${name}`, scalar: { name, value } };
}
function eventSource(runId: string | null, index: number, eventType: string): Provenance {
return { kind: 'event', id: `${runId ?? 'trace:none'}:event:${index}:${eventType}` };
}
function memorySource(id: string): Provenance {
return { kind: 'memory', id };
}
function laneFor(type: TraceEvent['type']): BlackboxLane {
switch (type) {
case 'mcp.call': return 'tool';
case 'memory.retrieve': return 'retrieve';
case 'memory.suppress': return 'suppress';
case 'memory.write': return 'write';
case 'sanhedrin.veto': return 'veto';
case 'contradiction.detected': return 'contradiction';
case 'dream.patch': return 'dream';
}
}
function eventMemoryIds(ev: TraceEvent): string[] {
switch (ev.type) {
case 'memory.retrieve': return ev.ids;
case 'memory.suppress': return [ev.id];
case 'memory.write': return [ev.id];
case 'contradiction.detected': return ev.ids;
case 'sanhedrin.veto': return ev.evidenceIds;
case 'dream.patch': return ev.proposalIds;
case 'mcp.call': return [];
}
}
function eventLabel(ev: TraceEvent): string {
switch (ev.type) {
case 'mcp.call': return ev.tool;
case 'memory.retrieve': return `${ev.ids.length} memories retrieved`;
case 'memory.suppress': return `suppressed ${ev.id.slice(0, 8)}`;
case 'memory.write': return `wrote ${ev.id.slice(0, 8)}`;
case 'contradiction.detected': return `contradiction ${ev.ids.join(' ↔ ')}`;
case 'sanhedrin.veto': return 'Sanhedrin veto';
case 'dream.patch': return `${ev.proposalIds.length} dream proposals`;
}
}
function eventSummary(ev: TraceEvent): string {
switch (ev.type) {
case 'mcp.call': return `MCP tool ${ev.tool} called; args hash ${ev.argsHash.slice(0, 12)}`;
case 'memory.retrieve': return `Retrieved ${ev.ids.length} memories with activation map`;
case 'memory.suppress': return `Suppressed ${ev.id}: ${ev.reason}`;
case 'memory.write': return `Memory write ${ev.id} from ${ev.source}`;
case 'contradiction.detected': return ev.detail;
case 'sanhedrin.veto': return `${Math.round(clamp01(ev.confidence) * 100)}% veto confidence: ${ev.claim}`;
case 'dream.patch': return `Dream patch proposals: ${ev.proposalIds.join(', ')}`;
}
}
function activationPairs(ev: TraceEvent): ActivationPair[] {
if (ev.type !== 'memory.retrieve') return [];
return Object.entries(ev.activation ?? {})
.map(([id, activation]) => ({ id, activation: clamp01(activation) }))
.sort((a, b) => b.activation - a.activation);
}
function confidenceFor(ev: TraceEvent): number {
if (ev.type === 'sanhedrin.veto') return clamp01(ev.confidence);
if (ev.type === 'memory.retrieve') {
const values = Object.values(ev.activation ?? {});
return values.length ? clamp01(values.reduce((a, b) => a + b, 0) / values.length) : 0.45;
}
if (ev.type === 'memory.suppress') return 0.78;
if (ev.type === 'memory.write') return 0.72;
if (ev.type === 'contradiction.detected') return 0.82;
if (ev.type === 'dream.patch') return 0.52;
return 0.62;
}
export function normalizeBlackboxScene(input: TraceInput, receipts: Receipt[] = [], selectedIndex?: number): BlackboxScene {
const runId = input?.runId ?? null;
const eventsRaw = input?.events ?? [];
const summary = input?.summary ?? null;
const startedAt = num(summary?.startedAt, eventsRaw[0]?.at ?? 0);
const lastAt = num(summary?.lastAt, eventsRaw[eventsRaw.length - 1]?.at ?? startedAt);
const maxVisible = eventsRaw.length ? eventsRaw.length - 1 : 0;
const visibleTo = Math.max(0, Math.min(maxVisible, selectedIndex ?? maxVisible));
const visibleEventCount = eventsRaw.length ? visibleTo + 1 : 0;
const traceEvents: BlackboxTraceImpulse[] = eventsRaw.map((ev, index) => ({
index,
id: `${runId ?? ev.runId}:event:${index}:${ev.type}`,
type: ev.type,
lane: laneFor(ev.type),
runId: ev.runId,
at: ev.at,
label: eventLabel(ev),
summary: eventSummary(ev),
memoryIds: eventMemoryIds(ev),
activationPairs: activationPairs(ev),
confidence: confidenceFor(ev),
provenance: traceSource(runId, index, ev.type),
raw: ev
}));
const memoryIndex = new Map<string, RouteNode>();
for (const impulse of traceEvents) {
for (const id of impulse.memoryIds) {
if (!id || memoryIndex.has(id)) continue;
const activation = impulse.activationPairs.find((p) => p.id === id)?.activation ?? 0;
memoryIndex.set(id, {
source: memorySource(id),
index: memoryIndex.size,
label: id.slice(0, 12),
retention: Math.max(0.25, activation),
activation,
trust: impulse.type === 'memory.suppress' ? 0.2 : Math.max(0.35, impulse.confidence),
suppression: impulse.type === 'memory.suppress' ? 1 : 0,
tags: [impulse.lane, impulse.type],
type: 'trace-memory'
});
}
}
const nodes = [...memoryIndex.values()];
const routeEvents: RouteEvent[] = traceEvents.slice(0, visibleEventCount).map((ev) => ({
source: eventSource(runId, ev.index, ev.type),
type: ev.type,
targetIndex: ev.memoryIds.length ? (memoryIndex.get(ev.memoryIds[0])?.index ?? -1) : -1,
frame: ev.index * 34 + 18,
energy: Math.max(0.18, ev.confidence)
}));
const edges = traceEvents.slice(0, visibleEventCount).flatMap((ev) => {
const ids = ev.memoryIds.filter((id) => memoryIndex.has(id));
if (ids.length < 2) return [];
return ids.slice(1).map((id, i) => ({
source: { kind: 'pair' as const, id: `${ev.id}:pair:${ids[0]}:${id}` },
sourceIndex: memoryIndex.get(ids[0])!.index,
targetIndex: memoryIndex.get(id)!.index,
weight: ev.activationPairs[i + 1]?.activation ?? ev.confidence,
kind: ev.type
}));
});
const receiptRows = receipts ?? [];
const routeReceipts: RouteReceipt[] = receiptRows.map((receipt) => {
const ids = [...new Set([...(receipt.retrieved ?? []), ...(receipt.activation_path ?? []), ...(receipt.mutations ?? []).map((m) => m.id)])];
return {
source: { kind: 'receipt', id: receipt.receipt_id },
label: `receipt ${receipt.receipt_id.slice(0, 10)}`,
nodeIndices: ids.map((id) => memoryIndex.get(id)?.index).filter((i): i is number => typeof i === 'number')
};
});
const scene: BlackboxScene = {
organ: 'blackbox',
nodes,
edges,
events: routeEvents,
receipts: routeReceipts,
scalars: {
eventCount: eventsRaw.length,
visibleEventCount,
retrievedCount: num(summary?.retrievedCount, traceEvents.filter((e) => e.type === 'memory.retrieve').length),
suppressedCount: num(summary?.suppressedCount, traceEvents.filter((e) => e.type === 'memory.suppress').length),
writeCount: num(summary?.writeCount, traceEvents.filter((e) => e.type === 'memory.write').length),
vetoCount: num(summary?.vetoCount, traceEvents.filter((e) => e.type === 'sanhedrin.veto').length),
durationMs: Math.max(0, lastAt - startedAt),
receiptCount: routeReceipts.length
},
alive: eventsRaw.length > 0,
runId,
traceEvents,
visibleEventCount,
selectedIndex: visibleTo,
startedAt,
lastAt,
durationMs: Math.max(0, lastAt - startedAt),
receiptRows
};
if (!scene.alive) {
scene.receipts = receiptRows.map((receipt) => ({
source: { kind: 'receipt', id: receipt.receipt_id },
label: `receipt ${receipt.receipt_id.slice(0, 10)}`,
nodeIndices: []
}));
scene.scalars.eventCount = 0;
scene.scalars.visibleEventCount = 0;
void scalarSource('empty', 0);
}
if (import.meta.env.DEV) assertProvenance(scene);
return scene;
}

View file

@ -0,0 +1,716 @@
import type { ObservatoryEngine, FramePass } from '$lib/observatory/engine';
import { IMMUNE, MEDIUM, RETENTION, membraneWidth, rgb01 } from '$lib/observatory/cognitive-palette';
import type { RouteSceneModel } from '$lib/observatory/route-scene';
import type { DuplicateFusionCluster, DuplicatesScene } from './duplicates-scene';
type RoutePick = { id: string; kind: string; index?: number; payload?: unknown };
const FIELD_FORMAT: GPUTextureFormat = 'rgba16float';
const MAX_CELLS = 512;
const MAX_NECKS = 512;
const CELL_FLOATS = 16;
const NECK_FLOATS = 16;
const COMMON_WGSL = /* wgsl */ `
struct Params {
frame: f32,
loop_phase: f32,
node_count: f32,
edge_count: f32,
path_count: f32,
pulse: f32,
viewport_w: f32,
viewport_h: f32,
brightness: f32,
demo_id: f32,
time: f32,
capture_mode: f32,
live_kind: f32,
live_frame: f32,
live_energy: f32,
projection_days: f32,
};
struct FusionCell {
// x/y position in NDC, z retention, w winner flag
pos_retention: vec4f,
// x similarity, y threshold, z member slot, w cluster slot
cluster_meta: vec4f,
// x mismatch intensity, y merge flag, z radius, w member count
visual_meta: vec4f,
// x cell index, y cluster index, z/w spare
ids: vec4f,
};
struct FusionNeck {
// x/y winner position, z winner retention, w winner radius
a: vec4f,
// x/y candidate position, z candidate retention, w candidate radius
b: vec4f,
// x similarity, y threshold, z mismatch intensity, w merge flag
signals: vec4f,
// x neck index, y cluster index, z/w spare
ids: vec4f,
};
`;
const SPLAT_WGSL = /* wgsl */ `
${COMMON_WGSL}
@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(1) var<storage, read> cells: array<FusionCell>;
@group(0) @binding(2) var<storage, read> necks: array<FusionNeck>;
const QUAD = array<vec2f, 6>(
vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0),
vec2f(-1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, 1.0)
);
struct VSOut {
@builtin(position) clip: vec4f,
@location(0) uv: vec2f,
@location(1) @interpolate(flat) misc: vec4f,
};
fn similarity_neck(similarity: f32) -> f32 {
return smoothstep(0.78, 0.98, similarity);
}
@vertex
fn vs_splat(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> VSOut {
var out: VSOut;
let corner = QUAD[vi];
let cell_count = u32(params.node_count);
if (ii < cell_count) {
let c = cells[ii];
let merge_gate = c.visual_meta.y;
let radius = c.visual_meta.z * (1.0 + 0.045 * sin(params.time * 2.0 + c.cluster_meta.w * 6.28318));
out.clip = vec4f(c.pos_retention.xy + corner * radius, 0.0, 1.0);
out.uv = corner;
out.misc = vec4f(c.pos_retention.z, c.cluster_meta.x, c.visual_meta.x, merge_gate);
} else {
let n = necks[ii - cell_count];
let a = n.a.xy;
let b = n.b.xy;
let center = (a + b) * 0.5;
let dir = normalize(b - a + vec2f(0.0001, 0.0001));
let normal = vec2f(-dir.y, dir.x);
let fused = similarity_neck(n.signals.x);
let length_half = distance(a, b) * 0.5;
let thickness = 0.035 + fused * 0.085 + n.signals.z * 0.025;
let pos = center + dir * corner.x * length_half + normal * corner.y * thickness;
out.clip = vec4f(pos, 0.0, 1.0);
out.uv = vec2f(corner.x, corner.y / max(0.001, thickness));
out.misc = vec4f(n.signals.x, fused, n.signals.z, n.signals.w);
}
return out;
}
@fragment
fn fs_splat(frag: VSOut) -> @location(0) vec4f {
let d = length(frag.uv);
let is_neck = f32(abs(frag.uv.y) > 1.0);
if (is_neck < 0.5 && d > 1.0) { discard; }
let retention = clamp(frag.misc.x, 0.0, 1.0);
let similarity = clamp(frag.misc.y, 0.0, 1.0);
let mismatch = clamp(frag.misc.z, 0.0, 1.0);
let merge_gate = frag.misc.w;
let cell_body = exp(-d * d * 3.15) * (0.38 + retention * 0.62) * (0.5 + similarity * 0.58);
let cell_rim = smoothstep(0.24, 0.02, abs(d - (0.58 + retention * 0.16))) * (0.2 + similarity * 0.55);
let neck_body = exp(-frag.uv.y * frag.uv.y * 4.0) * smoothstep(1.05, 0.82, abs(frag.uv.x)) * (0.35 + similarity * 0.9);
let density = max(cell_body + cell_rim, neck_body * (0.4 + similarity));
// r=density, g=retention/luciferin, b=mismatch amber, a reserved. No storage textures.
return vec4f(density, density * (0.35 + retention * 0.65), mismatch * (0.18 + merge_gate * 0.12), 1.0);
}
@vertex
fn vs_cell(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> VSOut {
var out: VSOut;
let c = cells[ii];
let corner = QUAD[vi];
let winner = c.pos_retention.w;
let radius = c.visual_meta.z * (0.46 + winner * 0.18);
out.clip = vec4f(c.pos_retention.xy + corner * radius, 0.0, 1.0);
out.uv = corner;
out.misc = vec4f(c.pos_retention.z, c.cluster_meta.x, c.visual_meta.x, winner);
return out;
}
@fragment
fn fs_cell(frag: VSOut) -> @location(0) vec4f {
let d = length(frag.uv);
if (d > 1.0) { discard; }
let retention = clamp(frag.misc.x, 0.0, 1.0);
let similarity = clamp(frag.misc.y, 0.0, 1.0);
let mismatch = clamp(frag.misc.z, 0.0, 1.0);
let winner = frag.misc.w;
let sediment = vec3f(0.54, 0.29, 0.09);
let recall = vec3f(0.16, 0.95, 0.66);
let luciferin = vec3f(0.91, 1.0, 0.72);
let ivory = vec3f(0.96, 0.945, 0.815);
let amber = vec3f(1.0, 0.69, 0.08);
let core = mix(sediment, mix(recall, luciferin, retention), retention);
let rim = smoothstep(0.98, 0.72, d) * (1.0 - smoothstep(0.72, 0.22, d));
let body = exp(-d*d*3.2) * (0.20 + retention * 0.44 + winner * 0.16);
let mismatch_ring = smoothstep(0.16, 0.0, abs(d - 0.80)) * mismatch;
return vec4f(core * body + ivory * rim * (0.16 + similarity * 0.52) + amber * mismatch_ring * 0.34, 1.0);
}
@vertex
fn vs_neck(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> VSOut {
var out: VSOut;
let n = necks[ii];
let a = n.a.xy;
let b = n.b.xy;
let t = f32(vi / 2u) / 31.0;
let side = f32(vi % 2u) * 2.0 - 1.0;
let dir = normalize(b - a + vec2f(0.0001, 0.0001));
let normal = vec2f(-dir.y, dir.x);
let midpoint = (a + b) * 0.5;
let fused = similarity_neck(n.signals.x);
let threshold_pull = clamp(n.signals.x - n.signals.y + 0.22, 0.0, 1.0);
let bow = normal * sin(t * 3.14159) * (0.030 + n.signals.z * 0.050) * (1.0 - fused * 0.35);
let pos = mix(a, b, t) + bow;
let thickness = 0.005 + fused * 0.025 + threshold_pull * 0.010;
out.clip = vec4f(pos + normal * side * thickness, 0.0, 1.0);
out.uv = vec2f(t, side);
out.misc = vec4f(n.signals.x, n.signals.y, n.signals.z, distance(pos, midpoint));
return out;
}
@fragment
fn fs_neck(frag: VSOut) -> @location(0) vec4f {
let similarity = clamp(frag.misc.x, 0.0, 1.0);
let threshold = clamp(frag.misc.y, 0.0, 1.0);
let mismatch = clamp(frag.misc.z, 0.0, 1.0);
let pulse = 0.55 + 0.45 * sin(36.0 * frag.uv.x - 8.0 * frag.misc.w);
let bridge = vec3f(0.10, 0.82, 0.92);
let luciferin = vec3f(0.91, 1.0, 0.72);
let amber = vec3f(1.0, 0.69, 0.08);
let pull = smoothstep(-0.08, 0.20, similarity - threshold);
let color = mix(bridge, luciferin, pull) + amber * mismatch * pulse * 0.34;
return vec4f(color * (0.14 + similarity * 0.55 + mismatch * 0.18), 1.0);
}
`;
const MEMBRANE_WGSL = /* wgsl */ `
${COMMON_WGSL}
@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(3) var field_sampler: sampler;
@group(0) @binding(4) var field_tex: texture_2d<f32>;
const QUAD = array<vec2f, 6>(
vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0),
vec2f(-1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, 1.0)
);
struct VSOut { @builtin(position) clip: vec4f, @location(0) uv: vec2f };
@vertex
fn vs_fullscreen(@builtin(vertex_index) vi: u32) -> VSOut {
var out: VSOut;
let p = QUAD[vi];
out.clip = vec4f(p, 0.0, 1.0);
out.uv = p * 0.5 + vec2f(0.5);
return out;
}
@fragment
fn fs_membrane(frag: VSOut) -> @location(0) vec4f {
let f = textureSample(field_tex, field_sampler, frag.uv);
let density = clamp(f.r, 0.0, 5.0);
let retention = clamp(f.g, 0.0, 5.0);
let mismatch = clamp(f.b, 0.0, 3.0);
let membrane = smoothstep(0.13, 0.88, density) * (1.0 - smoothstep(1.9, 3.8, density));
let blackwater = vec3f(0.008, 0.012, 0.018);
let bridge = vec3f(0.10, 0.82, 0.92);
let luciferin = vec3f(0.66, 1.0, 0.37);
let ivory = vec3f(0.96, 0.945, 0.815);
let amber = vec3f(1.0, 0.69, 0.08);
var color = blackwater * (0.18 + density * 0.055);
color = color + bridge * density * 0.055 + luciferin * retention * 0.080;
color = color + ivory * membrane * 0.22 + amber * mismatch * (0.20 + 0.08 * params.pulse);
let vignette = smoothstep(0.96, 0.18, distance(frag.uv, vec2f(0.5)));
return vec4f(color * (0.35 + 0.65 * vignette) * params.brightness, 1.0);
}
`;
const BLUR_WGSL = /* wgsl */ `
struct BlurDir { dir: vec2f, _pad: vec2f };
@group(0) @binding(0) var blur_sampler: sampler;
@group(0) @binding(1) var blur_src: texture_2d<f32>;
@group(0) @binding(2) var<uniform> blur_dir: BlurDir;
const QUAD = array<vec2f, 6>(
vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0),
vec2f(-1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, 1.0)
);
struct VSOut { @builtin(position) clip: vec4f, @location(0) uv: vec2f };
@vertex
fn vs_fullscreen(@builtin(vertex_index) vi: u32) -> VSOut {
var out: VSOut;
let p = QUAD[vi];
out.clip = vec4f(p, 0.0, 1.0);
out.uv = p * 0.5 + vec2f(0.5);
return out;
}
@fragment
fn fs_blur(frag: VSOut) -> @location(0) vec4f {
let dims = vec2f(textureDimensions(blur_src, 0));
let stepv = blur_dir.dir / max(dims, vec2f(1.0));
var acc = textureSampleLevel(blur_src, blur_sampler, frag.uv - stepv * 2.0, 0.0) * 0.06136;
acc = acc + textureSampleLevel(blur_src, blur_sampler, frag.uv - stepv, 0.0) * 0.24477;
acc = acc + textureSampleLevel(blur_src, blur_sampler, frag.uv, 0.0) * 0.38774;
acc = acc + textureSampleLevel(blur_src, blur_sampler, frag.uv + stepv, 0.0) * 0.24477;
acc = acc + textureSampleLevel(blur_src, blur_sampler, frag.uv + stepv * 2.0, 0.0) * 0.06136;
return acc;
}
`;
type GpuResources = {
cellBuffer: GPUBuffer;
neckBuffer: GPUBuffer;
blurHBuffer: GPUBuffer;
blurVBuffer: GPUBuffer;
splatBindGroup: GPUBindGroup;
blurHBindGroup: GPUBindGroup;
blurVBindGroup: GPUBindGroup;
membraneBindGroup: GPUBindGroup;
fieldA: GPUTexture;
fieldB: GPUTexture;
fieldAView: GPUTextureView;
fieldBView: GPUTextureView;
fieldSize: [number, number];
};
type CellGeometry = {
cluster: DuplicateFusionCluster;
memoryId: string;
x: number;
y: number;
retention: number;
winner: boolean;
mismatch: number;
radius: number;
memberSlot: number;
memberCount: number;
};
type NeckGeometry = {
cluster: DuplicateFusionCluster;
winnerId: string;
candidateId: string;
ax: number;
ay: number;
bx: number;
by: number;
winnerRetention: number;
candidateRetention: number;
winnerRadius: number;
candidateRadius: number;
mismatch: number;
};
export class DuplicatesPass implements FramePass {
private engine: ObservatoryEngine;
private scene: DuplicatesScene | null = null;
private resources: GpuResources | null = null;
private sampler: GPUSampler | null = null;
private splatBindLayout: GPUBindGroupLayout | null = null;
private blurBindLayout: GPUBindGroupLayout | null = null;
private membraneBindLayout: GPUBindGroupLayout | null = null;
private splatPipeline: GPURenderPipeline | null = null;
private blurPipeline: GPURenderPipeline | null = null;
private membranePipeline: GPURenderPipeline | null = null;
private cellPipeline: GPURenderPipeline | null = null;
private neckPipeline: GPURenderPipeline | null = null;
private cellCount = 0;
private neckCount = 0;
private cellGeometry: CellGeometry[] = [];
private neckGeometry: NeckGeometry[] = [];
constructor(engine: ObservatoryEngine, scene: RouteSceneModel) {
this.engine = engine;
this.uploadScene(scene);
}
uploadScene(scene: RouteSceneModel): void {
this.scene = scene as DuplicatesScene;
this.buildGeometry();
const device = this.engine.gpuDevice;
if (!device) return;
this.ensurePipelines(device);
this.ensureResources(device);
this.uploadBuffers(device);
}
private ensurePipelines(device: GPUDevice): void {
if (this.splatPipeline || !this.engine.paramsBuffer) return;
const splatModule = createDiagnosedShaderModule(device, 'duplicates-fusion-splat-wgsl', SPLAT_WGSL);
const blurModule = createDiagnosedShaderModule(device, 'duplicates-fusion-blur-wgsl', BLUR_WGSL);
const membraneModule = createDiagnosedShaderModule(device, 'duplicates-fusion-membrane-wgsl', MEMBRANE_WGSL);
this.splatBindLayout = device.createBindGroupLayout({
label: 'duplicates-fusion-splat-bind-layout',
entries: [
{ binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
{ binding: 1, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage' } },
{ binding: 2, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage' } }
]
});
this.blurBindLayout = device.createBindGroupLayout({
label: 'duplicates-fusion-blur-bind-layout',
entries: [
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } }
]
});
this.membraneBindLayout = device.createBindGroupLayout({
label: 'duplicates-fusion-membrane-bind-layout',
entries: [
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
{ binding: 3, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
{ binding: 4, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } }
]
});
const splatLayout = device.createPipelineLayout({ label: 'duplicates-fusion-splat-layout', bindGroupLayouts: [this.splatBindLayout] });
const blurLayout = device.createPipelineLayout({ label: 'duplicates-fusion-blur-layout', bindGroupLayouts: [this.blurBindLayout] });
const membraneLayout = device.createPipelineLayout({ label: 'duplicates-fusion-membrane-layout', bindGroupLayouts: [this.membraneBindLayout] });
this.sampler = device.createSampler({ magFilter: 'linear', minFilter: 'linear' });
const additive = { color: { srcFactor: 'one' as GPUBlendFactor, dstFactor: 'one' as GPUBlendFactor, operation: 'add' as GPUBlendOperation }, alpha: { srcFactor: 'one' as GPUBlendFactor, dstFactor: 'one' as GPUBlendFactor, operation: 'add' as GPUBlendOperation } };
this.splatPipeline = device.createRenderPipeline({
label: 'duplicates-field-additive-splat',
layout: splatLayout,
vertex: { module: splatModule, entryPoint: 'vs_splat' },
fragment: { module: splatModule, entryPoint: 'fs_splat', targets: [{ format: FIELD_FORMAT, blend: additive }] },
primitive: { topology: 'triangle-list' }
});
this.blurPipeline = device.createRenderPipeline({
label: 'duplicates-field-blur-render-pass',
layout: blurLayout,
vertex: { module: blurModule, entryPoint: 'vs_fullscreen' },
fragment: { module: blurModule, entryPoint: 'fs_blur', targets: [{ format: FIELD_FORMAT }] },
primitive: { topology: 'triangle-list' }
});
this.membranePipeline = device.createRenderPipeline({
label: 'duplicates-synaptic-fusion-membrane',
layout: membraneLayout,
vertex: { module: membraneModule, entryPoint: 'vs_fullscreen' },
fragment: { module: membraneModule, entryPoint: 'fs_membrane', targets: [{ format: this.engine.sceneFormat, blend: additive }] },
primitive: { topology: 'triangle-list' }
});
this.cellPipeline = device.createRenderPipeline({
label: 'duplicates-memory-nuclei',
layout: splatLayout,
vertex: { module: splatModule, entryPoint: 'vs_cell' },
fragment: { module: splatModule, entryPoint: 'fs_cell', targets: [{ format: this.engine.sceneFormat, blend: additive }] },
primitive: { topology: 'triangle-list' }
});
this.neckPipeline = device.createRenderPipeline({
label: 'duplicates-mismatch-filaments',
layout: splatLayout,
vertex: { module: splatModule, entryPoint: 'vs_neck' },
fragment: { module: splatModule, entryPoint: 'fs_neck', targets: [{ format: this.engine.sceneFormat, blend: additive }] },
primitive: { topology: 'triangle-strip' }
});
}
private ensureResources(device: GPUDevice): void {
if (!this.splatBindLayout || !this.blurBindLayout || !this.membraneBindLayout || !this.engine.paramsBuffer || !this.sampler) return;
const w = Math.max(16, Math.floor((this.engine.params[6] || 1280) / 2));
const h = Math.max(16, Math.floor((this.engine.params[7] || 720) / 2));
const needsTextures = !this.resources || this.resources.fieldSize[0] !== w || this.resources.fieldSize[1] !== h;
let cellBuffer = this.resources?.cellBuffer;
let neckBuffer = this.resources?.neckBuffer;
let blurHBuffer = this.resources?.blurHBuffer;
let blurVBuffer = this.resources?.blurVBuffer;
if (!cellBuffer) cellBuffer = device.createBuffer({ label: 'duplicates-cells', size: MAX_CELLS * CELL_FLOATS * 4, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
if (!neckBuffer) neckBuffer = device.createBuffer({ label: 'duplicates-necks', size: MAX_NECKS * NECK_FLOATS * 4, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
if (!blurHBuffer) {
blurHBuffer = device.createBuffer({ label: 'duplicates-blur-h-dir', size: 16, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
device.queue.writeBuffer(blurHBuffer, 0, new Float32Array([1, 0, 0, 0]));
}
if (!blurVBuffer) {
blurVBuffer = device.createBuffer({ label: 'duplicates-blur-v-dir', size: 16, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
device.queue.writeBuffer(blurVBuffer, 0, new Float32Array([0, 1, 0, 0]));
}
if (!needsTextures && this.resources) return;
this.resources?.fieldA.destroy();
this.resources?.fieldB.destroy();
const usage = GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING;
const fieldA = device.createTexture({ label: 'duplicates-field-a-rgba16float', size: [w, h], format: FIELD_FORMAT, usage });
const fieldB = device.createTexture({ label: 'duplicates-field-b-rgba16float', size: [w, h], format: FIELD_FORMAT, usage });
const fieldAView = fieldA.createView();
const fieldBView = fieldB.createView();
const splatBindGroup = device.createBindGroup({
label: 'duplicates-fusion-splat-bind',
layout: this.splatBindLayout,
entries: [
{ binding: 0, resource: { buffer: this.engine.paramsBuffer } },
{ binding: 1, resource: { buffer: cellBuffer } },
{ binding: 2, resource: { buffer: neckBuffer } }
]
});
const blurHBindGroup = device.createBindGroup({
label: 'duplicates-field-blur-h-bind',
layout: this.blurBindLayout,
entries: [
{ binding: 0, resource: this.sampler },
{ binding: 1, resource: fieldAView },
{ binding: 2, resource: { buffer: blurHBuffer } }
]
});
const blurVBindGroup = device.createBindGroup({
label: 'duplicates-field-blur-v-bind',
layout: this.blurBindLayout,
entries: [
{ binding: 0, resource: this.sampler },
{ binding: 1, resource: fieldBView },
{ binding: 2, resource: { buffer: blurVBuffer } }
]
});
const membraneBindGroup = device.createBindGroup({
label: 'duplicates-membrane-bind',
layout: this.membraneBindLayout,
entries: [
{ binding: 0, resource: { buffer: this.engine.paramsBuffer } },
{ binding: 3, resource: this.sampler },
{ binding: 4, resource: fieldAView }
]
});
this.resources = { cellBuffer, neckBuffer, blurHBuffer, blurVBuffer, splatBindGroup, blurHBindGroup, blurVBindGroup, membraneBindGroup, fieldA, fieldB, fieldAView, fieldBView, fieldSize: [w, h] };
}
private buildGeometry(): void {
const clusters = this.scene?.clusters ?? [];
const n = Math.max(1, clusters.length);
const cells: CellGeometry[] = [];
const necks: NeckGeometry[] = [];
for (let i = 0; i < clusters.length; i++) {
const cluster = clusters[i];
const angle = (i / n) * Math.PI * 2 - Math.PI / 2;
const lane = 0.18 + 0.58 * Math.sqrt((i + 0.5) / n);
const centerX = Math.cos(angle) * lane * 0.86;
const centerY = Math.sin(angle) * lane;
const memberCount = Math.max(1, cluster.memories.length);
const pull = Math.max(0.04, 0.25 - Math.max(0, cluster.similarity - cluster.threshold) * 0.55);
const winnerMemory = cluster.memories.find((m) => m.id === cluster.winnerId) ?? cluster.memories[0];
const cellById = new Map<string, CellGeometry>();
for (let j = 0; j < cluster.memories.length && cells.length < MAX_CELLS; j++) {
const memory = cluster.memories[j];
const memberAngle = angle + (j / memberCount) * Math.PI * 2 + (memberCount % 2 ? 0 : Math.PI / memberCount);
const winner = memory.id === cluster.winnerId;
const spread = winner ? pull * 0.18 : pull + 0.025 * (j % 3);
const mismatch = Math.min(1, (memory.mismatchTokens?.length ?? 0) / 8);
const radius = 0.085 + Math.min(0.045, membraneWidth(memory.retention) * 2.1) + (winner ? 0.012 : 0);
const cell = {
cluster,
memoryId: memory.id,
x: centerX + Math.cos(memberAngle) * spread,
y: centerY + Math.sin(memberAngle) * spread,
retention: Math.max(0, Math.min(1, memory.retention || 0)),
winner,
mismatch,
radius,
memberSlot: j,
memberCount
};
cellById.set(memory.id, cell);
cells.push(cell);
}
const winnerCell = cellById.get(winnerMemory.id);
if (!winnerCell) continue;
for (const memory of cluster.memories) {
if (necks.length >= MAX_NECKS || memory.id === winnerMemory.id) continue;
const candidate = cellById.get(memory.id);
if (!candidate) continue;
necks.push({
cluster,
winnerId: winnerMemory.id,
candidateId: memory.id,
ax: winnerCell.x,
ay: winnerCell.y,
bx: candidate.x,
by: candidate.y,
winnerRetention: winnerCell.retention,
candidateRetention: candidate.retention,
winnerRadius: winnerCell.radius,
candidateRadius: candidate.radius,
mismatch: Math.max(candidate.mismatch, Math.min(1, cluster.mismatchTokens.length / 12))
});
}
}
this.cellGeometry = cells;
this.neckGeometry = necks;
}
private uploadBuffers(device: GPUDevice): void {
if (!this.resources) return;
const cellData = new Float32Array(MAX_CELLS * CELL_FLOATS);
const neckData = new Float32Array(MAX_NECKS * NECK_FLOATS);
this.cellCount = Math.min(MAX_CELLS, this.cellGeometry.length);
this.neckCount = Math.min(MAX_NECKS, this.neckGeometry.length);
for (let i = 0; i < this.cellCount; i++) {
const c = this.cellGeometry[i];
cellData.set([
c.x,
c.y,
c.retention,
c.winner ? 1 : 0,
c.cluster.similarity,
c.cluster.threshold,
c.memberSlot,
c.cluster.index,
c.mismatch,
c.cluster.suggestedAction === 'merge' ? 1 : 0,
c.radius,
c.memberCount,
i,
c.cluster.index,
0,
0
], i * CELL_FLOATS);
}
for (let i = 0; i < this.neckCount; i++) {
const n = this.neckGeometry[i];
neckData.set([
n.ax,
n.ay,
n.winnerRetention,
n.winnerRadius,
n.bx,
n.by,
n.candidateRetention,
n.candidateRadius,
n.cluster.similarity,
n.cluster.threshold,
n.mismatch,
n.cluster.suggestedAction === 'merge' ? 1 : 0,
i,
n.cluster.index,
0,
0
], i * NECK_FLOATS);
}
this.engine.params[2] = this.cellCount;
this.engine.params[3] = this.neckCount;
this.engine.params[4] = this.neckCount;
device.queue.writeBuffer(this.resources.cellBuffer, 0, cellData);
device.queue.writeBuffer(this.resources.neckBuffer, 0, neckData);
}
compute(encoder: GPUCommandEncoder): void {
const device = this.engine.gpuDevice;
if (!device || !this.resources || !this.splatPipeline || !this.blurPipeline) return;
this.ensureResources(device);
const res = this.resources;
const splat = encoder.beginRenderPass({
label: 'duplicates-field-splat-pass',
colorAttachments: [{ view: res.fieldAView, clearValue: { r: 0, g: 0, b: 0, a: 0 }, loadOp: 'clear', storeOp: 'store' }]
});
splat.setPipeline(this.splatPipeline);
splat.setBindGroup(0, res.splatBindGroup);
splat.draw(6, this.cellCount + this.neckCount);
splat.end();
const blurH = encoder.beginRenderPass({
label: 'duplicates-field-blur-h-pass',
colorAttachments: [{ view: res.fieldBView, clearValue: { r: 0, g: 0, b: 0, a: 0 }, loadOp: 'clear', storeOp: 'store' }]
});
blurH.setPipeline(this.blurPipeline);
blurH.setBindGroup(0, res.blurHBindGroup);
blurH.draw(6, 1);
blurH.end();
const blurV = encoder.beginRenderPass({
label: 'duplicates-field-blur-v-pass',
colorAttachments: [{ view: res.fieldAView, clearValue: { r: 0, g: 0, b: 0, a: 0 }, loadOp: 'clear', storeOp: 'store' }]
});
blurV.setPipeline(this.blurPipeline);
blurV.setBindGroup(0, res.blurVBindGroup);
blurV.draw(6, 1);
blurV.end();
}
render(pass: GPURenderPassEncoder): void {
if (!this.resources || !this.membranePipeline || !this.cellPipeline || !this.neckPipeline) return;
pass.setPipeline(this.membranePipeline);
pass.setBindGroup(0, this.resources.membraneBindGroup);
pass.draw(6, 1);
if (this.neckCount > 0) {
pass.setPipeline(this.neckPipeline);
pass.setBindGroup(0, this.resources.splatBindGroup);
pass.draw(64, this.neckCount);
}
if (this.cellCount > 0) {
pass.setPipeline(this.cellPipeline);
pass.setBindGroup(0, this.resources.splatBindGroup);
pass.draw(6, this.cellCount);
}
}
pickAt(ndcX: number, ndcY: number): RoutePick | null {
for (let i = 0; i < this.neckGeometry.length; i++) {
const g = this.neckGeometry[i];
const distToLine = distanceToSegment(ndcX, ndcY, g.ax, g.ay, g.bx, g.by);
const midX = (g.ax + g.bx) * 0.5;
const midY = (g.ay + g.by) * 0.5;
const fusedRadius = 0.055 + Math.max(0, g.cluster.similarity - g.cluster.threshold) * 0.45;
if (distToLine <= fusedRadius || Math.hypot(ndcX - midX, ndcY - midY) <= fusedRadius) {
return { id: g.cluster.id, kind: 'duplicate-neck', index: i, payload: g.cluster };
}
}
for (let i = 0; i < this.cellGeometry.length; i++) {
const c = this.cellGeometry[i];
if (Math.hypot(ndcX - c.x, ndcY - c.y) <= c.radius * 0.8) {
return { id: c.memoryId, kind: 'duplicate-memory', index: i, payload: c.cluster };
}
}
return null;
}
dispose(): void {
this.resources?.cellBuffer.destroy();
this.resources?.neckBuffer.destroy();
this.resources?.blurHBuffer.destroy();
this.resources?.blurVBuffer.destroy();
this.resources?.fieldA.destroy();
this.resources?.fieldB.destroy();
this.resources = null;
}
}
function distanceToSegment(px: number, py: number, ax: number, ay: number, bx: number, by: number): number {
const vx = bx - ax;
const vy = by - ay;
const wx = px - ax;
const wy = py - ay;
const c1 = vx * wx + vy * wy;
if (c1 <= 0) return Math.hypot(px - ax, py - ay);
const c2 = vx * vx + vy * vy;
if (c2 <= c1) return Math.hypot(px - bx, py - by);
const t = c1 / c2;
return Math.hypot(px - (ax + t * vx), py - (ay + t * vy));
}
function createDiagnosedShaderModule(device: GPUDevice, label: string, code: string): GPUShaderModule {
device.pushErrorScope('validation');
const module = device.createShaderModule({ label, code });
void module.getCompilationInfo().then((info) => {
for (const message of info.messages) {
console.error(`[observatory] ${label} WGSL ${message.type} ${message.lineNum}:${message.linePos} ${message.message}`);
}
});
void device.popErrorScope().then((error) => {
if (error) console.error(`[observatory] ${label} shader module validation: ${error.message}`);
});
return module;
}
export function createDuplicatesPasses(engine: ObservatoryEngine, scene: RouteSceneModel): DuplicatesPass[] {
void rgb01(MEDIUM.blackwater);
void rgb01(RETENTION.recall);
void rgb01(RETENTION.luciferin);
void rgb01(IMMUNE.trustMembrane);
return [new DuplicatesPass(engine, scene)];
}

View file

@ -0,0 +1,191 @@
import { clusterKey, pickWinner } from '$components/duplicates-helpers';
import {
assertProvenance,
type Provenance,
type RouteEdge,
type RouteEvent,
type RouteNode,
type RouteSceneModel
} from '$lib/observatory/route-scene';
import type { DuplicateClusterGroup, DuplicateClusterMemory, DuplicatesResponse } from '$types';
export interface DuplicateFusionMemory extends DuplicateClusterMemory {
index: number;
preview: string;
winner: boolean;
mismatchTokens: string[];
}
export interface DuplicateFusionCluster {
id: string;
index: number;
similarity: number;
threshold: number;
suggestedAction: 'merge' | 'review';
winnerId: string;
memories: DuplicateFusionMemory[];
mismatchTokens: string[];
source: Provenance;
}
export interface DuplicatesScene extends RouteSceneModel {
organ: 'duplicates';
threshold: number;
total: number;
clusters: DuplicateFusionCluster[];
raw: DuplicatesResponse;
}
function clamp01(v: number): number {
return Math.max(0, Math.min(1, Number.isFinite(v) ? v : 0));
}
function source(kind: Provenance['kind'], id: string, scalar?: Provenance['scalar']): Provenance {
return scalar ? { kind, id, scalar } : { kind, id: id || `${kind}:unknown` };
}
function scalarSource(name: string, value: number): Provenance {
return { kind: 'scalar', id: `duplicates.${name}`, scalar: { name, value } };
}
function preview(content: string, max = 84): string {
const text = (content || '').trim().replace(/\s+/g, ' ');
return text.length <= max ? text : `${text.slice(0, max)}`;
}
function tokenize(content: string): string[] {
return (content || '')
.toLowerCase()
.replace(/[^a-z0-9_\s-]/g, ' ')
.split(/\s+/)
.filter((token) => token.length >= 4)
.slice(0, 80);
}
function mismatchTokens(memories: DuplicateClusterMemory[]): string[] {
if (memories.length < 2) return [];
const tokenSets = memories.map((m) => new Set(tokenize(m.content)));
const counts = new Map<string, number>();
for (const tokenSet of tokenSets) {
for (const token of tokenSet) counts.set(token, (counts.get(token) ?? 0) + 1);
}
return Array.from(counts.entries())
.filter(([, count]) => count > 0 && count < memories.length)
.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
.slice(0, 12)
.map(([token]) => token);
}
function normalizeCluster(
cluster: DuplicateClusterGroup,
index: number,
threshold: number
): DuplicateFusionCluster | null {
const members = Array.isArray(cluster.memories) ? cluster.memories.filter((m) => m.id) : [];
if (members.length < 2) return null;
const id = clusterKey(members);
const winner = pickWinner(members);
const clusterMismatch = mismatchTokens(members);
return {
id,
index,
similarity: clamp01(cluster.similarity),
threshold: clamp01(threshold),
suggestedAction: cluster.suggestedAction === 'merge' ? 'merge' : 'review',
winnerId: winner?.id ?? members[0].id,
memories: members.map((memory, memoryIndex) => ({
...memory,
index: memoryIndex,
preview: preview(memory.content),
winner: memory.id === (winner?.id ?? members[0].id),
mismatchTokens: clusterMismatch.filter((token) => tokenize(memory.content).includes(token)).slice(0, 8)
})),
mismatchTokens: clusterMismatch,
source: source('pair', id)
};
}
export function normalizeDuplicatesScene(rawInput: DuplicatesResponse): DuplicatesScene {
const threshold = clamp01(rawInput.threshold ?? 0.8);
const rawClusters = Array.isArray(rawInput.clusters) ? rawInput.clusters : [];
const clusters = rawClusters
.map((cluster, index) => normalizeCluster(cluster, index, threshold))
.filter((cluster): cluster is DuplicateFusionCluster => cluster !== null);
let nodeIndex = 0;
const nodes: RouteNode[] = [];
const nodeIndexByMemoryId = new Map<string, number>();
for (const cluster of clusters) {
for (const memory of cluster.memories) {
if (nodeIndexByMemoryId.has(memory.id)) continue;
const currentIndex = nodeIndex++;
nodeIndexByMemoryId.set(memory.id, currentIndex);
nodes.push({
source: source('memory', memory.id),
index: currentIndex,
label: memory.preview || memory.id.slice(0, 8),
retention: clamp01(memory.retention),
trust: clamp01(cluster.similarity),
lastAccessed: memory.createdAt,
tags: [memory.nodeType, ...memory.tags, memory.winner ? 'winner' : 'candidate'].filter(Boolean),
type: memory.nodeType || 'memory'
});
}
}
const edges: RouteEdge[] = [];
for (const cluster of clusters) {
const winnerIndex = nodeIndexByMemoryId.get(cluster.winnerId);
if (winnerIndex == null) continue;
for (const memory of cluster.memories) {
const targetIndex = nodeIndexByMemoryId.get(memory.id);
if (targetIndex == null || targetIndex === winnerIndex) continue;
edges.push({
source: source('pair', `${cluster.id}:${cluster.winnerId}:${memory.id}`),
sourceIndex: winnerIndex,
targetIndex,
weight: Math.max(0.05, cluster.similarity),
kind: cluster.suggestedAction === 'merge' ? 'fusion-candidate' : 'review-candidate'
});
}
}
const events: RouteEvent[] = clusters.map((cluster, index) => ({
source: source('event', `duplicates.cluster.${cluster.id}`),
type: cluster.suggestedAction === 'merge' ? 'DuplicateMergeCandidate' : 'DuplicateReviewCandidate',
targetIndex: -1,
frame: 20 + index * 14,
energy: Math.max(0.1, cluster.similarity - threshold + 0.1)
}));
const total = Number.isFinite(rawInput.total) ? rawInput.total : clusters.length;
const memoryCount = nodes.length;
const maxSimilarity = clusters.reduce((max, cluster) => Math.max(max, cluster.similarity), 0);
const mergeCandidates = clusters.filter((cluster) => cluster.suggestedAction === 'merge').length;
const reviewCandidates = clusters.length - mergeCandidates;
const scene: DuplicatesScene = {
organ: 'duplicates',
nodes,
edges,
events,
receipts: [],
scalars: {
threshold: scalarSource('threshold', threshold).scalar?.value ?? threshold,
clusterCount: clusters.length,
memoryCount,
maxSimilarity,
mergeCandidates,
reviewCandidates,
total
},
alive: clusters.length > 0,
threshold,
total,
clusters,
raw: rawInput
};
if (import.meta.env.DEV) assertProvenance(scene);
return scene;
}

View file

@ -36,6 +36,13 @@
formatAt,
relativeMs
} from '$components/blackbox-helpers';
import RouteStage, { type RoutePick } from '$lib/observatory/RouteStage.svelte';
import { createBlackboxPasses } from '$lib/observatory/blackbox/blackbox-pass';
import {
normalizeBlackboxScene,
type BlackboxScene,
type BlackboxTraceImpulse
} from '$lib/observatory/blackbox/blackbox-scene';
// ---- state ----------------------------------------------------------
let runs = $state<TraceRunSummary[]>([]);
@ -46,6 +53,7 @@
let scrubIndex = $state(0); // index into detail.events
let proofMode = $state(false);
let receipts = $state<Receipt[]>([]);
let selectedImpulse = $state<BlackboxTraceImpulse | null>(null);
// The events up to and including the scrubber position — what the agent had
// "experienced" at that moment in the run.
@ -68,6 +76,14 @@
const hasContradiction = $derived(
detail?.events.some((e) => e.type === 'contradiction.detected') ?? false
);
const blackboxScene = $derived<BlackboxScene>(normalizeBlackboxScene(detail, receipts, scrubIndex));
function handleRoutePick(pick: RoutePick) {
if (pick.kind !== 'trace-event') return;
const impulse = pick.payload as BlackboxTraceImpulse;
selectedImpulse = impulse;
scrubIndex = Math.max(0, Math.min(detail?.events.length ? detail.events.length - 1 : 0, impulse.index));
}
async function loadRuns() {
try {
@ -86,6 +102,7 @@
try {
detail = await api.traces.get(runId);
scrubIndex = Math.max(0, (detail.events.length || 1) - 1);
selectedImpulse = null;
// Receipts are the proof behind THIS run's retrievals — scoped to
// the selected run (B5), not the global latest.
receipts = (await api.receipts.listForRun(runId, 8)).receipts;
@ -123,7 +140,18 @@
onMount(loadRuns);
</script>
<div class="mx-auto max-w-6xl px-5 py-6">
<RouteStage
organ="blackbox"
seed={`agent-flight-recorder:${selectedRunId ?? 'empty'}:${blackboxScene.visibleEventCount}`}
scene={blackboxScene}
passes={createBlackboxPasses}
loading={loading}
error={error}
emptyLabel="NO AGENT TRACE SELECTED — RECORDER ARMED"
onpick={handleRoutePick}
/>
<div class="relative z-10 mx-auto max-w-6xl px-5 py-6">
<PageHeader
icon="blackbox"
title="Agent Black Box"
@ -178,6 +206,15 @@
</div>
</div>
{#if selectedImpulse}
<div class="selected-impulse glass" use:reveal>
<span class="selected-kicker">GPU pick</span>
<strong>{selectedImpulse.label}</strong>
<span>{selectedImpulse.summary}</span>
<code>{selectedImpulse.provenance.id}</code>
</div>
{/if}
{#if !proofMode}
<div class="layout">
<!-- ░░ RUN PICKER ░░ -->

View file

@ -12,6 +12,13 @@
import PageHeader from '$lib/components/PageHeader.svelte';
import Icon from '$lib/components/Icon.svelte';
import AnimatedNumber from '$lib/components/AnimatedNumber.svelte';
import RouteStage, { type RoutePick } from '$lib/observatory/RouteStage.svelte';
import { createDuplicatesPasses } from '$lib/observatory/duplicates/duplicates-pass';
import {
normalizeDuplicatesScene,
type DuplicateFusionCluster,
type DuplicatesScene
} from '$lib/observatory/duplicates/duplicates-scene';
import { reveal } from '$lib/actions/reveal';
import { spotlight } from '$lib/actions/interactions';
import { api } from '$stores/api';
@ -25,6 +32,7 @@
let dismissed = $state(new Set<string>());
let loading = $state(true);
let error: string | null = $state(null);
let selectedCluster: DuplicateFusionCluster | null = $state(null);
let debounceTimer: ReturnType<typeof setTimeout> | undefined;
async function detect() {
@ -83,11 +91,35 @@
overflowed ? visibleClusters.slice(0, CLUSTER_RENDER_CAP) : visibleClusters
);
const duplicatesScene = $derived.by<DuplicatesScene>(() =>
normalizeDuplicatesScene({
threshold,
total: visibleClusters.length,
clusters: visibleClusters.map(({ c }) => c)
})
);
function handleRoutePick(pick: RoutePick) {
if (pick.kind !== 'duplicate-neck' && pick.kind !== 'duplicate-memory') return;
selectedCluster = pick.payload as DuplicateFusionCluster;
}
onMount(() => detect());
onDestroy(() => clearTimeout(debounceTimer));
</script>
<div class="relative mx-auto max-w-5xl space-y-6 p-6">
<RouteStage
organ="duplicates"
seed={`synaptic-fusion:${threshold}:${visibleClusters.length}:${totalDuplicates}`}
scene={duplicatesScene}
passes={createDuplicatesPasses}
loading={loading}
error={error}
emptyLabel={`NO DUPLICATES ABOVE ${(threshold * 100).toFixed(0)}% SIMILARITY`}
onpick={handleRoutePick}
/>
<div class="relative z-10 mx-auto max-w-5xl space-y-6 p-6 pointer-events-none">
<!-- Header -->
<PageHeader
icon="duplicates"
@ -105,7 +137,7 @@
</PageHeader>
<!-- Controls panel -->
<div class="glass-panel flex flex-wrap items-center gap-5 rounded-2xl p-4">
<div class="glass-panel pointer-events-auto flex flex-wrap items-center gap-5 rounded-2xl p-4">
<!-- Threshold slider -->
<label class="flex flex-1 min-w-64 items-center gap-3 text-xs text-dim">
<span class="whitespace-nowrap">Similarity threshold</span>
@ -158,10 +190,36 @@
</button>
</div>
<!-- Field pick inspector -->
{#if selectedCluster}
<div class="glass-panel pointer-events-auto rounded-2xl border border-synapse/25 bg-black/30 p-4">
<div class="flex flex-wrap items-center justify-between gap-3">
<div>
<div class="font-mono text-[11px] uppercase tracking-[0.18em] text-synapse-glow">
Synaptic neck selected
</div>
<div class="mt-1 text-sm text-bright">
{selectedCluster.memories.length} memories · {(selectedCluster.similarity * 100).toFixed(1)}% similar · winner {selectedCluster.winnerId.slice(0, 8)}
</div>
<div class="mt-1 max-w-2xl text-xs text-muted">
Real pair key: {selectedCluster.id}. Mismatch filaments: {selectedCluster.mismatchTokens.length ? selectedCluster.mismatchTokens.join(', ') : 'none exposed'}.
</div>
</div>
<button
type="button"
onclick={() => (selectedCluster = null)}
class="rounded-lg bg-white/[0.04] px-3 py-1.5 text-xs text-dim transition hover:bg-white/[0.08] hover:text-text focus:outline-none focus-visible:ring-2 focus-visible:ring-synapse/60"
>
Clear field focus
</button>
</div>
</div>
{/if}
<!-- Results -->
{#if error}
<div
class="glass-panel flex flex-col items-center gap-3 rounded-2xl p-10 text-center"
class="glass-panel pointer-events-auto flex flex-col items-center gap-3 rounded-2xl p-10 text-center"
>
<div class="text-sm text-decay">Couldn't detect duplicates</div>
<div class="max-w-md text-xs text-muted">{error}</div>
@ -174,14 +232,14 @@
</button>
</div>
{:else if loading}
<div class="space-y-3">
<div class="pointer-events-auto space-y-3">
{#each Array(3) as _}
<div class="glass-subtle shimmer h-40 rounded-2xl"></div>
{/each}
</div>
{:else if visibleClusters.length === 0}
<div
class="glass-panel enter flex flex-col items-center gap-3 rounded-2xl p-12 text-center"
class="glass-panel pointer-events-auto enter flex flex-col items-center gap-3 rounded-2xl p-12 text-center"
>
<div
class="flex h-14 w-14 items-center justify-center rounded-2xl border border-recall/25 bg-recall/10 text-recall"
@ -197,7 +255,7 @@
</div>
</div>
{:else}
<div class="space-y-4">
<div class="pointer-events-auto space-y-4">
{#if overflowed}
<div
class="glass-subtle rounded-xl border border-warning/30 bg-warning/5 px-4 py-2 text-xs text-dim"