Port steps 0-1: scaffold, the oracle, and the pure bottom
Scaffolds frontend/ (shadow-cljs, reagent 1.2.0, re-frame 1.4.3) and ports everything below the data model, with the JS kept as a numeric oracle. domain/landmarks index tables, verbatim domain/ring subsample, offset, simplicity domain/geom similarity fit, procrustes, moving average domain/raster indexed scanline fill, stencil, disc, rect domain/palette the ramp, and the no-sampled-RGB rule 58 tests, 166 assertions. Parity with js/ on the identical 72-frame synthetic track: fit-similarity, procrustes-mean, fit-residual, moving-average, smooth-transforms, offset-ring and subsample-slots to 1e-9; the raster pixel-for-pixel over the whole buffer. Three deviations from the JS, each for a reason: - synth.cljs jitters from a SEEDED generator, not Math.random. Parity is only checkable if both sides can be handed the same track, and a failing assertion has to be reproducible. `:rand-fn` takes the generator over, so oracle.mjs stubs js/Math.random and js/ itself stays untouched. - raster/->rgba replaces toImageData. ImageData is a DOM type and domain/ may not touch the DOM; returning plain bytes also lets the no-intermediate-colours assertion run in node. ui/canvas wraps it later. - offset-ring lives in domain/ring, not domain/geom, per architecture.md: it is an operation on an ordered traversal, not on a transform. Step 1's "done" also names the swapped-iris vote, but pairIrises is in pipeline.js and belongs to step 7. The precondition is asserted instead -- `:swap-iris` really does move both blocks -- so the vote will have a track that disagrees with it when it arrives. One finding, recorded in full in the test that measures it: smooth-transforms buys nothing on the synthetic track. Against jitter-free ground truth, radius 1 helps by 17% on one noise realisation and hurts by 0.5% on another, so its benefit is within noise; from radius 2 up the cost is unambiguous, and by radius 5 the filter is below the true motion's own high-frequency energy, i.e. smoothing away performance. The test pins the shape of the knob rather than a preferred value. This may say more about the synth's jitter being unrealistically small (+/-0.001 normalised) than about the knob; step 6 settles it on real footage. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
082d8561d2
commit
eb06be005c
25 changed files with 4932 additions and 0 deletions
41
frontend/shadow-cljs.edn
Normal file
41
frontend/shadow-cljs.edn
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
;; Two builds and no more:
|
||||
;;
|
||||
;; app the tool. Output goes straight into the Django staticfiles tree, so
|
||||
;; `python manage.py runserver` and `shadow-cljs watch app` are the whole
|
||||
;; dev loop with nothing copying files between them.
|
||||
;; test :node-test, because everything below `ui/` and `fx/` is pure and has
|
||||
;; no business needing a browser to be asserted about. The canvas-facing
|
||||
;; parts get asserted through domain/raster's byte buffer instead, which
|
||||
;; is what the JS selftest already did.
|
||||
{:source-paths ["src" "test"]
|
||||
|
||||
:dependencies [[reagent "1.2.0"]
|
||||
[re-frame "1.4.3"]]
|
||||
|
||||
;; Dev server for the CLJS half, on a different port from serve.py (8777) so the
|
||||
;; old tool and the port can run side by side — which is the whole point of
|
||||
;; keeping js/ around as the numeric oracle.
|
||||
;;
|
||||
;; Two roots: `public` holds the host page, `..` is the repo root so the bundle
|
||||
;; at /static/arthur/js/ resolves, and so manifest.json, audio.wav and frames/
|
||||
;; are reachable when step 6 needs real footage.
|
||||
;;
|
||||
;; THE ORDER IS LOAD-BEARING. The repo root has an index.html too — the old
|
||||
;; tool's — so with `..` first, /index.html would quietly serve the prototype
|
||||
;; instead of the port. That would look like the CLJS build having regressed to
|
||||
;; a suspiciously complete tool rather than like a misconfigured server.
|
||||
;;
|
||||
;; Open /index.html, not /. This shadow-cljs does no directory-index resolution,
|
||||
;; so bare / is a 404 whatever the roots are. Django serves the page from step 9
|
||||
;; and this whole key goes away.
|
||||
:dev-http {8778 ["public" ".."]}
|
||||
|
||||
:builds
|
||||
{:app {:target :browser
|
||||
:output-dir "../static/arthur/js"
|
||||
:asset-path "/static/arthur/js"
|
||||
:modules {:main {:init-fn arthur.core/init}}}
|
||||
|
||||
:test {:target :node-test
|
||||
:output-to "out/node-tests.js"
|
||||
:ns-regexp "-test$"}}}
|
||||
Loading…
Add table
Add a link
Reference in a new issue