mapspinner 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/workflows/fps-perf.js +147 -0
- package/.claude/workflows/optimize-dna.js +201 -0
- package/.claude/workflows/shader-bottleneck-dna.js +168 -0
- package/.claude/workflows/speed-dna.js +209 -0
- package/.claude/workflows/startup-perf.js +117 -0
- package/.github/workflows/publish.yml +43 -0
- package/AGENTS.md +265 -0
- package/CHANGELOG.md +31 -0
- package/CLAUDE.md +1 -0
- package/README.md +82 -0
- package/examples/basic-sdk-usage.html +114 -0
- package/package.json +28 -0
- package/planet.html +2181 -0
- package/planet.zip +0 -0
- package/scripts/backend-ab.mjs +88 -0
- package/scripts/dev-chrome.cmd +22 -0
- package/scripts/verify.mjs +69 -0
- package/server.js +127 -0
- package/src/anchor-field.js +559 -0
- package/src/gl-render.js +944 -0
- package/src/index.js +41 -0
- package/src/planet-orchestrator.js +790 -0
- package/src/quadtree.js +160 -0
- package/src/shaders/atmosphere.glsl +215 -0
- package/src/shaders/terrain.glsl +2109 -0
- package/src/terrain-gen-controls.js +122 -0
- package/tests/run.js +58 -0
- package/textures/grass-color.jpg +0 -0
- package/textures/grass-displacement.jpg +0 -0
- package/textures/rock-color.jpg +0 -0
- package/textures/rock-displacement.jpg +0 -0
- package/textures/sand-color.jpg +0 -0
- package/textures/sand-displacement.jpg +0 -0
- package/textures/snow-color.jpg +0 -0
- package/textures/snow-displacement.jpg +0 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
name: 'fps-perf',
|
|
3
|
+
description: 'Find + attack TV8 runtime FPS bottlenecks: measure the GPU VS/FS split on a headed browser, rank the lever, cut, re-measure, verify no visual regression',
|
|
4
|
+
whenToUse: 'When the live frame rate is low (close-approach / low-alt especially). Runs the measure-first loop: __diag.gpuTimer attributes frame ms to VS (per-vertex 14-oct broadShapeM x3/vertex) vs FS (per-pixel shade) vs CPU emit, ranks the most-performant lever, proposes the cut, and re-measures. Needs a headed browser (EXT_disjoint_timer_query_webgl2 is absent in headless node-gl).',
|
|
5
|
+
phases: [
|
|
6
|
+
{ title: 'Map', detail: 'parallel readers over the runtime frame path: gl-render.js draw/emit, planet-orchestrator.js LOD/cull, terrain.glsl VS displace + FS shade' },
|
|
7
|
+
{ title: 'Measure', detail: 'headed-browser __diag.gpuTimer baseline: fullMs (VS+FS), vsRasterMs (VS+raster), fsMs delta, per rung (orbit/lowalt/closeup/deck)' },
|
|
8
|
+
{ title: 'Rank', detail: 'pick the dominant cost (VS triple-fractal / GRID tessellation / deck maxLevel / over-subdivision / FS per-pixel / CPU emit) as the single most-performant lever' },
|
|
9
|
+
{ title: 'Cut', detail: 'one reduction for the ranked lever, with the LOD-invariance + no-seam constraint stated' },
|
|
10
|
+
{ title: 'Verify', detail: 'per cut: re-measure gpuTimer delta + continuous-normals/no-seam visual witness + lab gates; each shader edit = one cold compile so batch reloads' },
|
|
11
|
+
],
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// ----------------------------------------------------------------------------
|
|
15
|
+
// TV8 fps-perf workflow. The BEHIND-LIMB cull (planet-orchestrator.js limb cull + forward-cone
|
|
16
|
+
// rescue) already removes ~50-80% of generated leaves, and frustum cull is intentionally OFF (it
|
|
17
|
+
// mis-culled bulged on-screen quads). So the remaining runtime cost is the KEPT VISIBLE quads x the
|
|
18
|
+
// per-vertex work. The known prime lever: terrain.glsl's lit-normal FD runs TWO extra full broadShapeM
|
|
19
|
+
// (14-octave) calls per vertex on top of the displacement call = 3x fractal/vertex over GRID=24 ->
|
|
20
|
+
// (24+2)^2=676 verts/quad. broadShapeM MUST stay a pure LOD-invariant world-dir function (a per-tile /
|
|
21
|
+
// LOD octave fade was TRIED + REFUTED: adjacent tiles diverge at the shared edge = seams/popping), so
|
|
22
|
+
// any cheaper gradient must not reintroduce that seam. The measurement gap this workflow closes: node
|
|
23
|
+
// headless gl has no EXT_disjoint_timer_query_webgl2, so VS-vs-FS attribution was impossible -- a HEADED
|
|
24
|
+
// browser + __diag.gpuTimer (full frame vs __fsCheap short-circuit frame) finally names the split, so
|
|
25
|
+
// the lever is PICKED from a number, not guessed.
|
|
26
|
+
// ----------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
const FRAME_FILES = [
|
|
29
|
+
{ path: 'src/gl-render.js', lens: 'per-frame instBuf Float32Array(n*5)+bufferData upload, drawElementsInstanced, GRID mesh size, uniform set, _lastInstQuads reuse guard' },
|
|
30
|
+
{ path: 'src/planet-orchestrator.js', lens: 'per-frame quadtree split (splitFactor/altSplitMul low-alt PEAK/distFactor), maxLevel + altitude-gated deck cap, behind-limb cull + forward-cone rescue, leaf emit count. NOTE the altSplitMul PEAK is the highest-payoff LOD-quad-count lever measured (2026-06-04): a LIVE window.__splitFactor sweep at the worst rung names the quads-vs-pxPerPoly knee with NO edit/cold-compile.' },
|
|
31
|
+
{ path: 'src/shaders/terrain.glsl', lens: 'VS vtxDisplace + the lit-normal FD (2 extra full broadShapeM/vertex), broadShapeM octave count, FS per-pixel shade (riverMask/strata/biome/detail-normal taps)' },
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
const COST_SCHEMA = {
|
|
35
|
+
type: 'object',
|
|
36
|
+
properties: {
|
|
37
|
+
costs: {
|
|
38
|
+
type: 'array',
|
|
39
|
+
items: {
|
|
40
|
+
type: 'object',
|
|
41
|
+
properties: {
|
|
42
|
+
name: { type: 'string' },
|
|
43
|
+
file: { type: 'string' },
|
|
44
|
+
stage: { type: 'string', description: 'VS | FS | CPU-emit | LOD-quad-count' },
|
|
45
|
+
perWhat: { type: 'string', description: 'per-vertex | per-pixel | per-quad | per-frame' },
|
|
46
|
+
cutIdea: { type: 'string' },
|
|
47
|
+
lodInvariant:{ type: 'boolean', description: 'true if the cut keeps broadShapeM a pure LOD-invariant world-dir fn (no seam)' },
|
|
48
|
+
regressionRisk: { type: 'string', description: 'low | medium | high, and the witness that proves no-regression (continuous normals / no seam / lab gate)' },
|
|
49
|
+
},
|
|
50
|
+
required: ['name', 'file', 'stage', 'cutIdea', 'regressionRisk'],
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
required: ['costs'],
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
phase('Map')
|
|
58
|
+
const maps = await parallel(FRAME_FILES.map(f => () =>
|
|
59
|
+
agent(
|
|
60
|
+
`Read ${f.path} in the TV8 repo and map every per-frame RUNTIME cost it carries (focus: ${f.lens}). ` +
|
|
61
|
+
`For each cost return name, file, stage (VS|FS|CPU-emit|LOD-quad-count), perWhat, a concrete cutIdea, ` +
|
|
62
|
+
`whether it keeps broadShapeM LOD-invariant (no seam), and regressionRisk with the witness that proves no-regression. ` +
|
|
63
|
+
`Do NOT edit anything; this is a read+map pass.`,
|
|
64
|
+
{ label: `map:${f.path.split('/').pop()}`, phase: 'Map', schema: COST_SCHEMA }
|
|
65
|
+
)
|
|
66
|
+
))
|
|
67
|
+
const costs = maps.filter(Boolean).flatMap(m => m.costs)
|
|
68
|
+
|
|
69
|
+
// MEASURE is a HEADED-browser dispatch the human (or the gm chain) runs OUTSIDE this workflow, because
|
|
70
|
+
// the workflow's subagents have no browser surface -- they reason over the map + the gpuTimer numbers
|
|
71
|
+
// the chain captured. The chain passes the measured split in via args.measured (fullMs/vsRasterMs/fsMs
|
|
72
|
+
// per rung). If absent, the Rank agent reasons from the static map + the known triple-fractal prior.
|
|
73
|
+
// MEASURE health-check FIRST (2026-06-04 lesson): before trusting any gpuTimer number, read
|
|
74
|
+
// window.__pageErr and confirm dbg.quads()>0 with __altM tracking dbg.gotoDown(km). A FROZEN __altM +
|
|
75
|
+
// zero quads + the loading overlay still up is a CRASHED render loop (e.g. a ReferenceError thrown
|
|
76
|
+
// per-frame), NOT a slow one -- gpuTimer will read ~0.002ms on an empty frame and mislead the rank.
|
|
77
|
+
// LIVEST lever-finding: sweep window.__splitFactor live ([2.0,1.4,1.0,0.7]) + orch.clearCache() at the
|
|
78
|
+
// worst rung, reading gpuTimer + pxPerPoly each step; the quads/vsRaster/pxPerPoly knee names the cut
|
|
79
|
+
// with no source edit and no ~190s cold compile. Then bake the winning value into altSplitMul's PEAK.
|
|
80
|
+
phase('Measure')
|
|
81
|
+
const measured = (typeof args === 'object' && args && args.measured) ? args.measured : null
|
|
82
|
+
log(measured
|
|
83
|
+
? `gpuTimer split provided: ${JSON.stringify(measured)}`
|
|
84
|
+
: 'no measured split passed (args.measured); ranking from the static map + the triple-fractal VS prior')
|
|
85
|
+
|
|
86
|
+
phase('Rank')
|
|
87
|
+
const ranking = await agent(
|
|
88
|
+
`Rank these TV8 per-frame runtime costs to pick the SINGLE most-performant FPS lever. ` +
|
|
89
|
+
`Context: behind-limb cull already removes ~50-80% of leaves; frustum cull is intentionally OFF; the ` +
|
|
90
|
+
`prime known cost is the VS running 3x full broadShapeM/vertex (displace + 2 FD taps) over 676 verts/quad. ` +
|
|
91
|
+
(measured ? `MEASURED gpuTimer split (authoritative): ${JSON.stringify(measured, null, 2)}. ` : `No live measurement; weight the VS triple-fractal prior. `) +
|
|
92
|
+
`Pick the lever with the highest payoff that keeps broadShapeM LOD-invariant (no seam). Costs:\n${JSON.stringify(costs, null, 2)}`,
|
|
93
|
+
{ label: 'rank', phase: 'Rank', schema: {
|
|
94
|
+
type: 'object',
|
|
95
|
+
properties: {
|
|
96
|
+
lever: { type: 'string', description: 'the single chosen lever' },
|
|
97
|
+
stage: { type: 'string', description: 'VS | FS | CPU-emit | LOD-quad-count' },
|
|
98
|
+
rationale: { type: 'string' },
|
|
99
|
+
ranked: { type: 'array', items: { type: 'object', properties: {
|
|
100
|
+
name: { type: 'string' }, rank: { type: 'number' }, expectedSaving: { type: 'string' },
|
|
101
|
+
gate: { type: 'string' } }, required: ['name', 'rank', 'expectedSaving', 'gate'] } },
|
|
102
|
+
}, required: ['lever', 'stage', 'ranked'] } }
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
phase('Cut')
|
|
106
|
+
// Propose the concrete edit for the chosen lever + the witness that proves it (re-measured gpuTimer
|
|
107
|
+
// delta + continuous-normals/no-seam visual witness). Adversarially verify each before it is applied.
|
|
108
|
+
const cuts = await pipeline(
|
|
109
|
+
ranking.ranked.sort((a, b) => a.rank - b.rank),
|
|
110
|
+
sec => agent(
|
|
111
|
+
`Propose the concrete code edit for TV8 FPS lever "${sec.name}" (expected saving ${sec.expectedSaving}). ` +
|
|
112
|
+
`Give the exact file, the old snippet, the new snippet, and the WITNESS that proves it: the re-measured ` +
|
|
113
|
+
`__diag.gpuTimer fullMs/fsMs delta AND the visual invariant (continuous normals across a tile boundary, ` +
|
|
114
|
+
`no seam/popping, glError 0). Gate: ${sec.gate}. broadShapeM MUST stay a pure LOD-invariant world-dir fn ` +
|
|
115
|
+
`(a per-tile / screen-space gradient that diverges at shared edges = the refuted seam). If risk is high, say so.`,
|
|
116
|
+
{ label: `cut:${sec.name}`, phase: 'Cut', schema: {
|
|
117
|
+
type: 'object',
|
|
118
|
+
properties: {
|
|
119
|
+
file: { type: 'string' }, oldSnippet: { type: 'string' }, newSnippet: { type: 'string' },
|
|
120
|
+
witness: { type: 'string' }, safe: { type: 'boolean' }, notes: { type: 'string' },
|
|
121
|
+
}, required: ['file', 'witness', 'safe'] } }
|
|
122
|
+
),
|
|
123
|
+
(proposal, sec) => agent(
|
|
124
|
+
`Adversarially verify this TV8 FPS cut for "${sec.name}". Could it reintroduce a tile-edge seam, break ` +
|
|
125
|
+
`LOD invariance, change the rendered terrain (shape/biome/lighting), break a uniform, or fail to compile? ` +
|
|
126
|
+
`Default to safe=false if uncertain. Proposal:\n${JSON.stringify(proposal, null, 2)}`,
|
|
127
|
+
{ label: `verify:${sec.name}`, phase: 'Verify', schema: {
|
|
128
|
+
type: 'object',
|
|
129
|
+
properties: { real: { type: 'boolean' }, safe: { type: 'boolean' }, reason: { type: 'string' } },
|
|
130
|
+
required: ['real', 'safe', 'reason'] } }
|
|
131
|
+
).then(v => ({ section: sec.name, proposal, verdict: v }))
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
const safe = cuts.filter(Boolean).filter(c => c.proposal.safe && c.verdict.safe)
|
|
135
|
+
const risky = cuts.filter(Boolean).filter(c => !(c.proposal.safe && c.verdict.safe))
|
|
136
|
+
return {
|
|
137
|
+
lever: ranking.lever,
|
|
138
|
+
stage: ranking.stage,
|
|
139
|
+
rationale: ranking.rationale,
|
|
140
|
+
measured,
|
|
141
|
+
ranked: ranking.ranked,
|
|
142
|
+
safeCuts: safe.map(c => ({ section: c.section, file: c.proposal.file, witness: c.proposal.witness })),
|
|
143
|
+
gatedCuts: risky.map(c => ({ section: c.section, reason: c.verdict.reason })),
|
|
144
|
+
note: 'Re-measure __diag.gpuTimer after each cut on a headed browser; broadShapeM stays LOD-invariant ' +
|
|
145
|
+
'(no per-tile/screen-space gradient that seams). Batch terrain.glsl edits into ONE reload ' +
|
|
146
|
+
'(each shader edit = a fresh ~188s cold compile). Witness continuous normals + glError 0 before COMPLETE.',
|
|
147
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
name: 'optimize-dna',
|
|
3
|
+
description: 'Maximize whole-project optimization through the 12-principle synthesized-engineering-DNA lens. Fans out per-axis finders (correctness, speed, simplification/maintenance-burden, architecture-pliability, jank/tell-tale-AI), adversarially verifies each finding (is it real? does fixing it regress another axis?), then arbitrates ALL findings across axes into ONE DNA-ranked plan. Composes the speed-dna workflow for the speed axis rather than re-implementing it.',
|
|
4
|
+
whenToUse: 'When the user wants a holistic optimization pass over the WHOLE project (not just speed) -- correctness/bugs, runtime/compile speed, simplification + maintenance-burden reduction, architecture pliability, and machine-shaped jank -- ranked and arbitrated as one budget through the compound DNA lens. The cross-axis arbitration is the capability no single skill has: code-review finds bugs, simplify finds cleanups, speed-dna finds speed levers, but nothing weighs a simplification that costs perf against a perf cut that adds risk.',
|
|
5
|
+
phases: [
|
|
6
|
+
{ title: 'Constraints', detail: 'P5 physics-first: fix the hard project constraints + the measured-dead record (FS source-shrink dead, atlas is the only compile lever, broadShapeM LOD-invariant/no-seam, 141s/shader-edit) so no finder proposes refuted or physics-fighting work' },
|
|
7
|
+
{ title: 'Map', detail: 'one reader per optimization AXIS maps that axis surface (correctness, speed, simplification, architecture, jank) tagged with the DNA principle that judges it' },
|
|
8
|
+
{ title: 'Find', detail: 'parallel finders per axis surface findings (a bug, a perf lever, a dedupe/simplification, a bespoke->native swap that NET-SHRINKS, a tell-tale-AI shape)' },
|
|
9
|
+
{ title: 'Verify', detail: 'P6 adversarial: each finding gets refuted -- is it REAL, and does fixing it REGRESS another axis (a simplification that costs perf, a perf cut that adds risk, a dep that net-grows surface)?' },
|
|
10
|
+
{ title: 'Arbitrate', detail: 'P11 crucible / P2+P9+P12: rank ALL surviving cross-axis findings into ONE budget by DNA-principle order weighted by felt human-value; resolve every cross-axis conflict explicitly' },
|
|
11
|
+
{ title: 'Plan', detail: 'P10 honest interface: return the DNA-justified, witness-bearing, cross-axis-arbitrated optimization plan, each item with the no-regression witness and the principle that ranked it' },
|
|
12
|
+
],
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// ----------------------------------------------------------------------------
|
|
16
|
+
// optimize-dna -- the whole-project optimization workflow. It does NOT duplicate the existing
|
|
17
|
+
// single-concern tooling (P2 subtractive / P4 composition spine): the SPEED axis is delegated to
|
|
18
|
+
// the speed-dna workflow (which already arbitrates compile-vs-fps); code-review / simplify already
|
|
19
|
+
// own bug-hunting and cleanup. What this workflow ADDS is the layer above them: a CROSS-AXIS
|
|
20
|
+
// arbitration that ranks a bug fix, a perf lever, a simplification, an architecture swap, and a
|
|
21
|
+
// jank cleanup against EACH OTHER in one budget, by DNA-principle order, weighted by felt impact.
|
|
22
|
+
//
|
|
23
|
+
// The load-bearing priors every finder must respect (P7 measure-don't-assume, P3 revert-and-don't-
|
|
24
|
+
// rechase):
|
|
25
|
+
// - COLD-COMPILE: FS source-shrink is MEASURED-DEAD; the only real compile lever is atlas/THC
|
|
26
|
+
// height-bake (removes the per-vertex fractal from the VS). FPS prime lever = the VS 3x-fractal
|
|
27
|
+
// /vertex + LOD quad count. broadShapeM MUST stay a pure LOD-invariant world-dir fn (per-tile/
|
|
28
|
+
// screen-space octave fade was TRIED + REFUTED = seams).
|
|
29
|
+
// - Each terrain.glsl edit = one ~141s cold ANGLE compile -> a finder that proposes a shader micro-
|
|
30
|
+
// edit must justify it against that cost (P5/P12: a change a user never feels but costs 141s to
|
|
31
|
+
// ship is negative value).
|
|
32
|
+
// - Net-smaller-surface rule (P2): a bespoke->library/native swap is only a win if it NET-SHRINKS
|
|
33
|
+
// the shipped+maintained surface; adding a heavy dep to delete a few lines is the failure mode.
|
|
34
|
+
//
|
|
35
|
+
// args (all optional): { axes: <string[] subset of the 5 axis keys to run; default all>,
|
|
36
|
+
// runSpeedChild: <bool, run the speed-dna child for the speed axis; default false
|
|
37
|
+
// since it needs headed-browser numbers -- when false the speed finder reasons
|
|
38
|
+
// from the static map + the measured priors>,
|
|
39
|
+
// speedArgs: <forwarded to the speed-dna child: {measured, compile}> }
|
|
40
|
+
// ----------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
const A = (typeof args === 'object' && args) ? args : {}
|
|
43
|
+
|
|
44
|
+
// The 12 principles as the ranking lens handed to every finder + the arbiter (P1 data-first: kept as
|
|
45
|
+
// data, never branched on).
|
|
46
|
+
const DNA = [
|
|
47
|
+
'P1 data-first: is this a state/data-model problem (fix the model, not the control flow around it)?',
|
|
48
|
+
'P2 subtractive: can the thing be REMOVED rather than improved? does a fix NET-SHRINK the surface?',
|
|
49
|
+
'P3 evolutionary: ship the simplest thing that works; revert-first on regressions.',
|
|
50
|
+
'P4 composition-spine: does each module do one thing, understandable at its call site?',
|
|
51
|
+
'P5 physics-first: what hardware/driver constraint bounds this (ANGLE compile, ALU, bandwidth, vert count)?',
|
|
52
|
+
'P6 adversarial: is misuse structurally possible? make the wrong thing hard.',
|
|
53
|
+
'P7 empirical: is there a MEASURED number, or a guess? refuse measured-dead levers.',
|
|
54
|
+
'P8 automated-correctness: can a guardrail (lint/type/pure-fn/gate) prevent this class of bug?',
|
|
55
|
+
'P9 worst-case: does it help the WORST case (close-approach fps / cold first-load), not just average?',
|
|
56
|
+
'P10 honest-interface: does any public contract / default behaviour lie about what it guarantees?',
|
|
57
|
+
'P11 crucible: does the hardest integration (close-approach, cold load, real input) still hold?',
|
|
58
|
+
'P12 human-value: does a real user FEEL this? trace the impact chain to a human outcome.',
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
// The optimization AXES. Each is one finder surface; speed is delegated to the speed-dna child.
|
|
62
|
+
const AXES = [
|
|
63
|
+
{ key: 'correctness', principles: 'P6/P8/P9/P11',
|
|
64
|
+
prompt: 'Hunt CORRECTNESS issues: real bugs, unguarded invalid states, worst-case failure modes (close-approach, cold load, degenerate input), silent-catastrophic paths, missing guardrails. For each: the bug, the file:line, the failure trigger, and the structural guardrail (P8) that would prevent the class.' },
|
|
65
|
+
{ key: 'speed', principles: 'P5/P7/P9', delegate: 'speed-dna',
|
|
66
|
+
prompt: 'Map the SPEED levers (cold compile + runtime fps) WITHOUT re-deriving the speed-dna analysis. Respect the measured-dead record (FS source-shrink dead; atlas is the only compile lever; VS triple-fractal + LOD-quad-count are the fps levers). Surface only the top levers + their expected saving + the no-seam/LOD-invariance gate.' },
|
|
67
|
+
{ key: 'simplification', principles: 'P2/P4',
|
|
68
|
+
prompt: 'Hunt SIMPLIFICATION + maintenance-burden cuts: duplicated logic (drift-prone reimplementations like a second copy of a mirror), dead code, abstractions that cost more than they deliver, config options that could be a default, kitchen-sink modules. For each: what to REMOVE/merge, the net-lines-saved, and the risk witness (lint/gate that proves no behaviour change).' },
|
|
69
|
+
{ key: 'architecture', principles: 'P1/P4/P10',
|
|
70
|
+
prompt: 'Hunt ARCHITECTURE-pliability improvements: a bad data model the code works around (P1), a bespoke reimplementation a popular well-maintained library/native API replaces with a NET-SMALLER surface (P2 -- reject if the dep net-grows surface), a layer boundary that is bypassed, a dishonest default/interface (P10). For each: the change, the net-surface delta, and why it is clearly outstanding.' },
|
|
71
|
+
{ key: 'jank', principles: 'P12 + gm-discipline',
|
|
72
|
+
prompt: 'Hunt JANK + tell-tale-AI shapes: unfinished edges, half-wired paths, immaturity across gui/ux/client-state/server-state and the client/server boundary; AND machine-authored tells (boilerplate flourishes, over-hedged comments, generic scaffold names, decorative non-ASCII glyphs that should be ASCII). For each: the surface, what unfinished/machine-shaped thing it is, and the polish/convert fix.' },
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
const FINDING_SCHEMA = {
|
|
76
|
+
type: 'object',
|
|
77
|
+
properties: {
|
|
78
|
+
findings: {
|
|
79
|
+
type: 'array',
|
|
80
|
+
items: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
properties: {
|
|
83
|
+
title: { type: 'string' },
|
|
84
|
+
axis: { type: 'string', description: 'correctness | speed | simplification | architecture | jank' },
|
|
85
|
+
file: { type: 'string', description: 'file:line if known' },
|
|
86
|
+
what: { type: 'string', description: 'the concrete issue + the concrete fix' },
|
|
87
|
+
dnaPrinciple: { type: 'string', description: 'the principle that most justifies acting (e.g. P2 subtractive)' },
|
|
88
|
+
surfaceDelta: { type: 'string', description: 'net lines/files/deps added or removed by the fix (P2 net-shrink test)' },
|
|
89
|
+
crossAxisRisk:{ type: 'string', description: 'does the fix regress another axis? (simplify costs perf, perf cut adds risk, dep net-grows surface)' },
|
|
90
|
+
measuredDead: { type: 'boolean', description: 'true if this is a known refuted/measured-dead lever (e.g. FS source-shrink for cold compile)' },
|
|
91
|
+
felt: { type: 'string', description: 'P12: the human outcome a real user feels, or "internal only"' },
|
|
92
|
+
},
|
|
93
|
+
required: ['title', 'axis', 'what', 'dnaPrinciple'],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
required: ['findings'],
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// --- Constraints (P5 physics-first) ---------------------------------------------------------
|
|
101
|
+
phase('Constraints')
|
|
102
|
+
const CONSTRAINTS = [
|
|
103
|
+
'COLD COMPILE: FS source-shrink is MEASURED-DEAD (ANGLE DCEs unused funcs; cost is intrinsic HLSL translation of the FS/VS main). The only real compile lever is the atlas/THC height-bake (removes the per-vertex broadShapeM fractal from the VS). Driver-cached: warm 41ms, cold ~141s, recurs on shader SOURCE change.',
|
|
104
|
+
'FPS: the VS runs 3x full 12-oct broadShapeM/vertex (displace + 2 central-diff taps); behind-limb cull removes ~50-80% leaves; frustum cull intentionally OFF.',
|
|
105
|
+
'broadShapeM MUST stay a pure LOD-invariant world-dir fn: a per-tile/screen-space octave fade was TRIED + REFUTED (seams at shared tile edges).',
|
|
106
|
+
'Each terrain.glsl edit = one ~141s cold compile -> a shader micro-edit a user never feels is negative value (P5/P12). BATCH shader edits.',
|
|
107
|
+
'NET-SMALLER-SURFACE (P2): a bespoke->library/native swap is a win ONLY if it net-shrinks the shipped+maintained surface; a heavy dep to delete a few lines net-grows it.',
|
|
108
|
+
'There is ONE canonical broadShapeM Node mirror (terrain-lab-shape.js, 2026-06-09 consolidation); a finder proposing a second copy is reintroducing refuted drift.',
|
|
109
|
+
]
|
|
110
|
+
log('Constraints fixed (' + CONSTRAINTS.length + '); measured-dead + refuted levers will be refused.')
|
|
111
|
+
|
|
112
|
+
// --- Map + Find (fan-out, one finder per axis) ----------------------------------------------
|
|
113
|
+
phase('Map')
|
|
114
|
+
const selected = Array.isArray(A.axes) && A.axes.length ? AXES.filter(x => A.axes.includes(x.key)) : AXES
|
|
115
|
+
log('running ' + selected.length + ' optimization axes: ' + selected.map(x => x.key).join(', '))
|
|
116
|
+
|
|
117
|
+
phase('Find')
|
|
118
|
+
const perAxis = await parallel(selected.map(ax => async () => {
|
|
119
|
+
// The SPEED axis is delegated to the speed-dna workflow (compose, do not re-implement).
|
|
120
|
+
if (ax.delegate === 'speed-dna' && A.runSpeedChild) {
|
|
121
|
+
try {
|
|
122
|
+
const speed = await workflow('speed-dna', A.speedArgs || {})
|
|
123
|
+
const ranked = (speed && speed.ranked) || []
|
|
124
|
+
return { findings: ranked.map(r => ({
|
|
125
|
+
title: 'speed: ' + (r.name || r.lever || 'lever'), axis: 'speed', file: speed.topAxis || '',
|
|
126
|
+
what: (r.expectedSaving ? ('expected ' + r.expectedSaving + '. ') : '') + (speed.rationale || ''),
|
|
127
|
+
dnaPrinciple: r.dnaPrinciple || 'P5', surfaceDelta: '', crossAxisRisk: (r.gate || ''),
|
|
128
|
+
measuredDead: false, felt: 'frame rate / load time',
|
|
129
|
+
})) }
|
|
130
|
+
} catch (e) {
|
|
131
|
+
log('speed-dna child failed (' + String(e.message || e) + '); falling back to static speed map')
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return agent(
|
|
135
|
+
ax.prompt + '\n' +
|
|
136
|
+
'Judge each finding through the synthesized-engineering-DNA lens (this axis leans on ' + ax.principles + '):\n' +
|
|
137
|
+
DNA.map(d => ' - ' + d).join('\n') + '\n' +
|
|
138
|
+
'HARD CONSTRAINTS (a finding that violates one is invalid -- flag measuredDead=true):\n' +
|
|
139
|
+
CONSTRAINTS.map(c => ' - ' + c).join('\n') + '\n' +
|
|
140
|
+
'Return findings with title, axis="' + ax.key + '", file:line, what (issue + concrete fix), dnaPrinciple, surfaceDelta (P2 net-shrink), crossAxisRisk, measuredDead, felt (P12). Read-only; do NOT edit.',
|
|
141
|
+
{ label: 'find:' + ax.key, phase: 'Find', schema: FINDING_SCHEMA }
|
|
142
|
+
)
|
|
143
|
+
}))
|
|
144
|
+
const found = perAxis.filter(Boolean).flatMap(r => (r && r.findings) || [])
|
|
145
|
+
const live = found.filter(f => !f.measuredDead)
|
|
146
|
+
const dead = found.filter(f => f.measuredDead)
|
|
147
|
+
log('found ' + found.length + ' (' + live.length + ' live, ' + dead.length + ' measured-dead dropped)')
|
|
148
|
+
|
|
149
|
+
// --- Verify (P6 adversarial: is it real, does it regress another axis?) ----------------------
|
|
150
|
+
phase('Verify')
|
|
151
|
+
const verified = await pipeline(
|
|
152
|
+
live,
|
|
153
|
+
f => agent(
|
|
154
|
+
'Adversarially verify this TV8 optimization finding. (1) Is it REAL -- not a false positive, not already handled, not a measured-dead lever (FS source-shrink for cold compile, a per-tile broadShapeM fade, a second mirror copy)? (2) Does fixing it REGRESS another optimization axis -- a simplification that costs perf, a perf cut that adds correctness risk or a seam, a dep that net-GROWS the surface, an architecture change that breaks a public default? Default real=false / regresses=true if uncertain. Finding:\n' + JSON.stringify(f, null, 2),
|
|
155
|
+
{ label: 'verify:' + (f.axis || '?') + ':' + (f.title || '').slice(0, 24), phase: 'Verify', schema: {
|
|
156
|
+
type: 'object',
|
|
157
|
+
properties: { real: { type: 'boolean' }, regressesOtherAxis: { type: 'boolean' }, reason: { type: 'string' } },
|
|
158
|
+
required: ['real', 'regressesOtherAxis', 'reason'] } }
|
|
159
|
+
).then(v => ({ ...f, verdict: v }))
|
|
160
|
+
)
|
|
161
|
+
const confirmed = verified.filter(Boolean).filter(f => f.verdict && f.verdict.real && !f.verdict.regressesOtherAxis)
|
|
162
|
+
const gated = verified.filter(Boolean).filter(f => !(f.verdict && f.verdict.real && !f.verdict.regressesOtherAxis))
|
|
163
|
+
log('confirmed ' + confirmed.length + '/' + live.length + ' after adversarial verify')
|
|
164
|
+
|
|
165
|
+
// --- Arbitrate (P11 crucible / P2+P9+P12: ONE budget across all axes) ------------------------
|
|
166
|
+
phase('Arbitrate')
|
|
167
|
+
const ranking = confirmed.length ? await agent(
|
|
168
|
+
'You are arbitrating the TV8 whole-project optimization budget across ALL axes (correctness, speed, simplification, architecture, jank) as ONE ranked plan, through the synthesized-engineering-DNA lens. Rank the CONFIRMED findings below highest-payoff first, applying the principle order P1>P2>...>P12 (earlier principles win conflicts) weighted by P12 human-value (a thing a user FEELS continuously outranks an internal nicety). ' +
|
|
169
|
+
'Resolve every CROSS-AXIS conflict explicitly: when two findings touch the same code or trade against each other (a simplification vs a perf lever, a correctness guardrail vs subtractive removal), state which wins and cite the principle. Prefer the change that REMOVES surface (P2) and helps the WORST case (P9). Confirmed findings:\n' + JSON.stringify(confirmed, null, 2),
|
|
170
|
+
{ label: 'arbitrate', phase: 'Arbitrate', schema: {
|
|
171
|
+
type: 'object',
|
|
172
|
+
properties: {
|
|
173
|
+
topItem: { type: 'string', description: 'the single highest-payoff optimization to do first' },
|
|
174
|
+
rationale: { type: 'string', description: 'why first, in DNA-principle terms' },
|
|
175
|
+
crossAxisConflicts: { type: 'array', items: { type: 'object', properties: {
|
|
176
|
+
conflict: { type: 'string' }, winner: { type: 'string' }, principle: { type: 'string' } },
|
|
177
|
+
required: ['conflict', 'winner', 'principle'] } },
|
|
178
|
+
ranked: { type: 'array', items: { type: 'object', properties: {
|
|
179
|
+
title: { type: 'string' }, axis: { type: 'string' }, rank: { type: 'number' },
|
|
180
|
+
dnaPrinciple: { type: 'string' }, expectedValue: { type: 'string' }, gate: { type: 'string' } },
|
|
181
|
+
required: ['title', 'axis', 'rank', 'expectedValue'] } },
|
|
182
|
+
}, required: ['topItem', 'ranked'] } }
|
|
183
|
+
) : { topItem: null, rationale: 'no confirmed findings survived adversarial verify', crossAxisConflicts: [], ranked: [] }
|
|
184
|
+
|
|
185
|
+
// --- Plan (P10 honest interface) ------------------------------------------------------------
|
|
186
|
+
phase('Plan')
|
|
187
|
+
return {
|
|
188
|
+
workflow: 'optimize-dna',
|
|
189
|
+
constraints: CONSTRAINTS,
|
|
190
|
+
axesRun: selected.map(x => x.key),
|
|
191
|
+
measuredDeadDropped: dead.map(f => ({ title: f.title, axis: f.axis, why: f.what })),
|
|
192
|
+
topItem: ranking.topItem,
|
|
193
|
+
rationale: ranking.rationale,
|
|
194
|
+
crossAxisConflicts: ranking.crossAxisConflicts || [],
|
|
195
|
+
ranked: ranking.ranked,
|
|
196
|
+
gatedFindings: gated.map(f => ({ title: f.title, axis: f.axis, reason: f.verdict && f.verdict.reason })),
|
|
197
|
+
note: 'Apply ranked items highest-first. Each is cross-axis-verified (real + does not regress another axis). ' +
|
|
198
|
+
'Speed items: re-measure on a HEADED browser; broadShapeM stays LOD-invariant; FS source-shrink for cold compile is measured-dead. ' +
|
|
199
|
+
'Architecture/dep swaps must NET-SHRINK the surface. BATCH terrain.glsl edits (each = ~141s cold compile). ' +
|
|
200
|
+
'Run the speed-dna workflow directly for a deep speed pass; this workflow is the cross-axis layer above it.',
|
|
201
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
name: 'shader-bottleneck-dna',
|
|
3
|
+
description: 'Profile + eliminate every possible bottleneck in the TV8 shaders (terrain.glsl VS+FS, water path, probe variant) through the synthesized-engineering-DNA lens: physics-first constraints, measure-first, subtract-before-add, adversarial refute-by-default verify. Fans out per-surface finders + web-research agents; outputs a ranked, witness-bearing cut plan.',
|
|
4
|
+
whenToUse: 'When the user wants an exhaustive shader-only bottleneck sweep (runtime ALU/varying/branch cost AND FXC/ANGLE compile shape), honouring the refuted-lever record (VS no-loss frontier, FS source-shrink dead, atlas faceting) so no dead lever is re-chased.',
|
|
5
|
+
phases: [
|
|
6
|
+
{ title: 'Constraints', detail: 'P5 physics-first: fix the hard priors as data -- VS-bound (96%), FD 3-tap irreducible at no-loss, FXC uOctMax/fdIters invariants, refuted-lever list' },
|
|
7
|
+
{ title: 'Research', detail: 'P7: web agents gather external evidence (FXC codegen pitfalls, ANGLE translation cost, snoise cost models, varying/interpolator pressure) -- evidence feeds finders, never ships unverified' },
|
|
8
|
+
{ title: 'Find', detail: 'fan-out finders per shader surface, each blind to the others, each handed the constraints + research digest' },
|
|
9
|
+
{ title: 'Verify', detail: 'P6 adversarial: every candidate refuted by 3 lenses (correctness/fidelity, FXC-invariant, actually-measurable); 2-of-3 survive threshold' },
|
|
10
|
+
{ title: 'Rank', detail: 'P2+P9+P12 arbitration into ONE ranked plan with per-cut witness' },
|
|
11
|
+
],
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// The refuted record (P7: measured-dead, finders must NOT propose these):
|
|
16
|
+
// - VS octave reduction below 12 / wider FD step / analytic-derivative normal / full-height
|
|
17
|
+
// atlas: ALL refuted 2026-06-10 (tv8-VS-perf-frontier record) -- fidelity loss measured.
|
|
18
|
+
// - FS source-shrink for cold compile: measured-dead (cost = FXC optimize, not chars).
|
|
19
|
+
// - per-tile/screen-space octave fade: seams at shared tile edges.
|
|
20
|
+
// - constant-bound fractal loops / differencing composeHeight across call sites: FXC
|
|
21
|
+
// mis-translation roots (uOctMax + fdIters fixes, commits f062365 + d56a202) -- INVARIANT.
|
|
22
|
+
// - CPU-frame alloc/upload churn: 96% GPU-bound, refuted wb08pmga5.
|
|
23
|
+
// What HAS CHANGED since those records (fresh ground the finders target):
|
|
24
|
+
// - 4770801 moved the domain warp to the VS (vTexWarp varying, -9 snoise3/px) and halved freqs.
|
|
25
|
+
// - d56a202 rewrote the FD normal as a runtime-bounded fdIters loop (3x height in ONE loop).
|
|
26
|
+
// - The FS still carries ~17 snoise3/px in places (rockface fBm, mottle, overlay) -- FS was
|
|
27
|
+
// "not the bottleneck" pre-warp-move; the VS/FS split MUST be re-measured post-change.
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
const A = (typeof args === 'object' && args) ? args : {}
|
|
31
|
+
const measured = A.measured || null // fresh gpuTimer split {fullMs, vsRasterMs, fsMs} per rung
|
|
32
|
+
|
|
33
|
+
const DNA = [
|
|
34
|
+
'P2 subtractive: prefer REMOVING a tap/branch/varying outright over speeding it',
|
|
35
|
+
'P5 physics-first: name the bound (ALU, interpolator count, register pressure, FXC optimize time)',
|
|
36
|
+
'P7 empirical: every claim needs a measurable witness; UNMEASURED is a flag, not a guess',
|
|
37
|
+
'P9 worst-case: the deck (close-approach) rung and the d3d11 cold path outrank averages',
|
|
38
|
+
'P12 human-value: per-frame stutter > once-per-machine compile',
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
const CONSTRAINTS = [
|
|
42
|
+
'VS-bound: ~96% of frame GPU is VS+raster at the deck (measured). The lit-normal FD 3-tap through the fdIters loop is the irreducible VS cost at zero fidelity loss (frontier record 2026-06-10) -- do not re-propose octave cuts, wider FD, analytic normals, or full-height atlas.',
|
|
43
|
+
'FXC invariants (d3d11 default Chrome): uOctMax + fdIters loops stay runtime-bounded; never difference composeHeight across call sites; any NEW VS fractal loop gets a runtime bound.',
|
|
44
|
+
'highp islands on every planet-scale quantity stay; global mediump elsewhere.',
|
|
45
|
+
'broadShapeM stays a pure LOD-invariant world-dir fn (per-tile octave fade = seams, refuted).',
|
|
46
|
+
'FS source-shrink is dead as a compile lever; cold d3d11 compile is 31s (corrected figure) and acceptable.',
|
|
47
|
+
'Each terrain.glsl edit = one cold FXC compile for d3d11 users; BATCH shader edits into one reload; dev loop is vulkan (140ms).',
|
|
48
|
+
'Verification surface: warm-tab /cmd + __diag (gpuTimer, bisect, groundTruth, seamProbe, verify.mjs suite). gpuTimer through the spool-browser verb TIMES OUT -- use /cmd.',
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
// Shader surfaces, each a finder lens. Fresh-ground emphasis per the changed-since record.
|
|
52
|
+
const SURFACES = [
|
|
53
|
+
{ key: 'vs-height', lens: 'terrain.glsl VS height path: vtxDisplace, broadShapeM call count, the fdIters FD loop shape (is any height work duplicated outside it? is the water uIsWater gate still dead-code-free?), carve fns, anchor cbias. Count snoise3 evaluations per vertex on the worst path.' },
|
|
54
|
+
{ key: 'vs-varyings', lens: 'VS->FS interface: count every varying (incl. new vTexWarp), their precision, packing opportunities (vec2 pairs into vec4), interpolator pressure on mobile-class GPUs, and any varying computed but consumed only on a gated FS path.' },
|
|
55
|
+
{ key: 'fs-material', lens: 'terrain.glsl FS material/splat: per-pixel snoise3 census post-4770801 (rockface 3-oct fBm, mottle, detail overlay, strata), texture tap count per layer (4 layers x albedo+normal A/B), texIdent path, slope/rock gates -- which taps are live on FLAT ground (the common case, P9)?' },
|
|
56
|
+
{ key: 'fs-lighting', lens: 'terrain.glsl FS lighting: detail-normal biplanar RNM taps, slope/gorge AO, aerial perspective single-scatter, haze/overlay fades -- distance/pxWorld gating completeness: does every expensive term fade out where invisible?' },
|
|
57
|
+
{ key: 'fs-water', lens: 'water shading path: per-pixel cost, whether water pixels pay terrain-material costs before the water branch, ocean/lake/river branch structure under d3d11 (branch flattening = both sides paid).' },
|
|
58
|
+
{ key: 'compile-shape', lens: 'FXC compile-time shape: loop bounds, function inlining sites, anything that could regress the 31s cold figure or re-trigger per-callsite divergence; probe _PROBE_ variant sharing.' },
|
|
59
|
+
{ key: 'branch-divergence', lens: 'branch + precision audit: mediump leaks onto hot math, highp where mediump suffices on non-planet-scale values, branches FXC will flatten (both sides executed), redundant normalize/pow/exp on hot paths.' },
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
const FINDING_SCHEMA = {
|
|
63
|
+
type: 'object',
|
|
64
|
+
properties: {
|
|
65
|
+
findings: { type: 'array', items: { type: 'object', properties: {
|
|
66
|
+
name: { type: 'string' }, file: { type: 'string' }, line: { type: 'string' },
|
|
67
|
+
stage: { type: 'string', description: 'VS | FS | varying | compile' },
|
|
68
|
+
perWhat: { type: 'string', description: 'per-vertex | per-pixel | per-frame | once-cold' },
|
|
69
|
+
mechanism: { type: 'string', description: 'the physical cost mechanism (ALU taps, interpolators, branch flatten, FXC inline)' },
|
|
70
|
+
cutIdea: { type: 'string' },
|
|
71
|
+
estSaving: { type: 'string' },
|
|
72
|
+
refutedLever: { type: 'boolean', description: 'true if this matches the refuted record -- finder must self-flag' },
|
|
73
|
+
fidelityRisk: { type: 'string', description: 'none | low | medium | high + what could visibly change' },
|
|
74
|
+
witness: { type: 'string', description: 'the measurable probe that proves the cut worked with no regression' },
|
|
75
|
+
}, required: ['name', 'file', 'stage', 'mechanism', 'cutIdea', 'fidelityRisk', 'witness'] } },
|
|
76
|
+
},
|
|
77
|
+
required: ['findings'],
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const VERDICT_SCHEMA = {
|
|
81
|
+
type: 'object',
|
|
82
|
+
properties: {
|
|
83
|
+
real: { type: 'boolean' }, safe: { type: 'boolean' }, reason: { type: 'string' },
|
|
84
|
+
},
|
|
85
|
+
required: ['real', 'safe', 'reason'],
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// --- Constraints ---------------------------------------------------------------------------
|
|
89
|
+
phase('Constraints')
|
|
90
|
+
log('Constraints fixed (' + CONSTRAINTS.length + '); refuted levers will be self-flagged and dropped, not re-chased.')
|
|
91
|
+
|
|
92
|
+
// --- Research (web evidence, P7) -------------------------------------------------------------
|
|
93
|
+
phase('Research')
|
|
94
|
+
const RESEARCH_TOPICS = [
|
|
95
|
+
'ANGLE D3D11 FXC HLSL codegen performance pitfalls for WebGL2 GLSL: loop unrolling, branch flattening, interpolator limits, dynamic indexing penalties. Cite sources.',
|
|
96
|
+
'GPU vertex-shader optimization for procedural terrain: simplex noise ALU cost models, fewest-instruction snoise/simplex variants, vertex cache and varying-count costs on AMD RDNA and mobile GPUs. Cite sources.',
|
|
97
|
+
'WebGL2 fragment shader cost on flattened branches and mediump vs highp throughput on AMD and mobile; best practice for distance-gated shading terms. Cite sources.',
|
|
98
|
+
]
|
|
99
|
+
const research = await parallel(RESEARCH_TOPICS.map((t, i) => () =>
|
|
100
|
+
agent('Research via web search (WebSearch/WebFetch): ' + t + ' Return a compact digest of CLAIMS with source URLs; mark each claim verified-by-source vs speculative.',
|
|
101
|
+
{ label: 'research:' + i, phase: 'Research' })
|
|
102
|
+
))
|
|
103
|
+
const researchDigest = research.filter(Boolean).join('\n---\n').slice(0, 8000)
|
|
104
|
+
log('research digests gathered: ' + research.filter(Boolean).length + '/' + RESEARCH_TOPICS.length)
|
|
105
|
+
|
|
106
|
+
// --- Find (fan-out per surface) --------------------------------------------------------------
|
|
107
|
+
phase('Find')
|
|
108
|
+
const found = await pipeline(
|
|
109
|
+
SURFACES,
|
|
110
|
+
s => agent(
|
|
111
|
+
'TV8 shader bottleneck finder, surface "' + s.key + '". Read src/shaders/terrain.glsl (and src/gl-render.js for uniform/varying wiring) and enumerate EVERY cost on this lens: ' + s.lens + '\n' +
|
|
112
|
+
'Judge through the DNA lens:\n' + DNA.map(d => ' - ' + d).join('\n') + '\n' +
|
|
113
|
+
'HARD CONSTRAINTS (violating proposals are auto-dead):\n' + CONSTRAINTS.map(c => ' - ' + c).join('\n') + '\n' +
|
|
114
|
+
(measured ? 'MEASURED gpuTimer split: ' + JSON.stringify(measured) + '\n' : 'No fresh measurement passed -- flag every estSaving UNMEASURED.\n') +
|
|
115
|
+
'External research digest (claims with sources; treat as hypotheses to check against the actual code):\n' + researchDigest + '\n' +
|
|
116
|
+
'Return findings with file:line, the cost MECHANISM, a concrete cutIdea, fidelityRisk, and the witness probe. Self-flag refutedLever=true for anything matching the refuted record. Read-only pass; do not edit.',
|
|
117
|
+
{ label: 'find:' + s.key, phase: 'Find', schema: FINDING_SCHEMA }
|
|
118
|
+
),
|
|
119
|
+
(res, s) => {
|
|
120
|
+
const live = (res && res.findings || []).filter(f => !f.refutedLever)
|
|
121
|
+
return parallel(live.map(f => () =>
|
|
122
|
+
parallel(['fidelity-correctness', 'fxc-invariant', 'measurability'].map(lens => () =>
|
|
123
|
+
agent(
|
|
124
|
+
'Adversarially REFUTE this TV8 shader cut candidate via the ' + lens + ' lens. ' +
|
|
125
|
+
(lens === 'fidelity-correctness' ? 'Could it visibly change terrain shape/material/lighting, seam at tile edges, or break LOD invariance? Read the actual code at the cited location.' :
|
|
126
|
+
lens === 'fxc-invariant' ? 'Does it reintroduce a constant-bound fractal loop, difference composeHeight across call sites, drop a highp island, or otherwise risk the FXC d3d11 mis-translation class? Read the cited code.' :
|
|
127
|
+
'Is the claimed saving actually measurable with the named witness, and plausibly non-noise given the VS-bound 96% prior? An FS-only cut at the deck is likely noise.') +
|
|
128
|
+
' Default real=false/safe=false if uncertain. Candidate:\n' + JSON.stringify(f, null, 2),
|
|
129
|
+
{ label: 'verify:' + f.name + ':' + lens, phase: 'Verify', schema: VERDICT_SCHEMA }
|
|
130
|
+
)
|
|
131
|
+
)).then(vs => {
|
|
132
|
+
const ok = vs.filter(Boolean).filter(v => v.real && v.safe).length >= 2
|
|
133
|
+
return { surface: s.key, finding: f, confirmed: ok, verdicts: vs }
|
|
134
|
+
})
|
|
135
|
+
))
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
const all = found.filter(Boolean).flat().filter(Boolean)
|
|
140
|
+
const confirmed = all.filter(x => x.confirmed)
|
|
141
|
+
const refuted = all.filter(x => !x.confirmed)
|
|
142
|
+
log('candidates: ' + all.length + ' -> confirmed ' + confirmed.length + ', refuted ' + refuted.length)
|
|
143
|
+
|
|
144
|
+
// --- Rank (single budget) --------------------------------------------------------------------
|
|
145
|
+
phase('Rank')
|
|
146
|
+
const ranking = confirmed.length ? await agent(
|
|
147
|
+
'Rank these CONFIRMED TV8 shader cuts into ONE ordered plan (highest payoff first) through the DNA lens: ' +
|
|
148
|
+
'P2 removal>speedup, P9 worst-rung (deck FPS, d3d11 path) first, P12 per-frame>once-cold, P7 measured>estimated. ' +
|
|
149
|
+
'Batch note: all terrain.glsl edits ship as ONE reload. Confirmed cuts:\n' + JSON.stringify(confirmed.map(c => c.finding), null, 2),
|
|
150
|
+
{ label: 'rank', phase: 'Rank', schema: { type: 'object', properties: {
|
|
151
|
+
ranked: { type: 'array', items: { type: 'object', properties: {
|
|
152
|
+
rank: { type: 'number' }, name: { type: 'string' }, file: { type: 'string' },
|
|
153
|
+
expectedSaving: { type: 'string' }, witness: { type: 'string' } },
|
|
154
|
+
required: ['rank', 'name', 'file', 'witness'] } },
|
|
155
|
+
rationale: { type: 'string' } }, required: ['ranked'] } }
|
|
156
|
+
) : { ranked: [], rationale: 'no confirmed cuts survived adversarial verify' }
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
workflow: 'shader-bottleneck-dna',
|
|
160
|
+
constraints: CONSTRAINTS,
|
|
161
|
+
researchSources: researchDigest.slice(0, 2000),
|
|
162
|
+
candidates: all.length,
|
|
163
|
+
confirmed: confirmed.map(c => ({ surface: c.surface, ...c.finding })),
|
|
164
|
+
refuted: refuted.map(c => ({ surface: c.surface, name: c.finding.name, why: (c.verdicts || []).filter(v => v && !(v.real && v.safe)).map(v => v.reason).join(' | ') })),
|
|
165
|
+
ranked: ranking.ranked,
|
|
166
|
+
rationale: ranking.rationale,
|
|
167
|
+
note: 'Apply ranked cuts as ONE batched terrain.glsl reload; witness each via /cmd warm-tab (compile clean, glError 0, gpuTimer delta, bisect/seamProbe no-regression, backend-ab d3d11 parity); then verify.mjs full suite.',
|
|
168
|
+
}
|