Context. surface studio · domain neith · route /studio/neith/inverse-modeling · auth signed-in + studio entitlement (fit-quality lane is admin-scoped: admin:* | admin:studio, fail-closed) · source apps/oshun/web/src/app/studio/neith/inverse-modeling/page.tsx
Last walked. 2026-06-25 by Codex (V1 reference-image feature extraction, four-model parameter estimates, confidence scoring, export manifest, domain tests, and E2E), against commit HEAD' '2026-06-25 by Codex (recoverable catalog retry, submit busy state, mobile tap targets, and live-BFF evaluator coverage), against commit HEAD' '2026-06-23 by Codex (direct-route auth readiness + live E2E), against commit HEAD
Purpose#
Studio-only Neith inverse procedural modeling console. The route now has two lanes:
- Reference Inversion Lane — paste a compact RGBA reference-image payload,
extract the V1 feature vector (
mean,contrast,edgeEnergy,entropy,warmBias), estimate parameters for all four Neith model families (terrain,vegetation,urban,noise), score confidence, and emit a deterministic export manifest for downstream Studio handoff. - Goodness-of-Fit Lane — admin-scoped JSON sample evaluator backed by the
real BFF (
/v1/admin/studio/fit-quality) that reports per-sample residuals, RMSE, MAE, R², and the worst-fitting sample.
The page mounts ShellLayout (active=studio), the
StudioNeithInverseModelingWorkspace body, the canonical route-map, and a
quick-action lane to two Isis sibling workspaces.
Entry points#
- Linked from
/studiobody — Domain-bridge studios section lists Neith - Quick action lanes from siblings: isis/reference-image-processing, isis/live-preview (cross-domain links into Isis)
- Direct URL / bookmark — yes; metadata sets
alternates.canonicalto/studio/neith/inverse-modeling
Layout regions#
page.tsx renders inside <ShellLayout active="studio">:
- Header: shell header (active=studio)
- Main:
<StudioNeithInverseModelingWorkspace />— client component ('use client') withuseAuth()access-token readiness plus state hooks foroutcome(catalog load result), fit-qualitypayloadText,result,evaluateError, reference-imagereferenceText,inverseReport, andinverseError- Eyebrow "Neith Procgen"
<h1>"Inverse Modeling Workspace" (viaWorkspaceHeading)- Summary
<p data-neith-inverse-modeling-summary>describing the feature-extraction, four-model estimate, export-manifest, and goodness-of-fit flow - Reference Inversion Lane (
data-neith-reference-lane) with<h2 data-neith-reference-lane-heading>"Reference Inversion Lane":<form data-neith-reference-form>with<textarea data-neith-reference-payload>(aria-label="Neith reference image json",rows={14}, monospace, seeded withDEFAULT_NEITH_REFERENCE_IMAGE) and<button data-neith-reference-submit>"Run inverse modeling"- Error:
<div data-neith-reference-error role="alert">with parser or validation error; priorinverseReportremains rendered - Feature grid:
<div data-neith-feature-grid>with cells keyed bydata-neith-feature="mean|contrast|edgeEnergy|entropy|warmBias" - Model grid: four
<article data-neith-model-card data-neith-model="terrain|vegetation|urban|noise">cards withdata-neith-model-confidence, parameter rows (data-neith-param-row data-neith-param-name), and rationale copy - Export manifest: keyboard-focusable
<pre data-neith-export-manifest tabindex="0" aria-label="Neith inverse modeling export manifest">
- Goodness-of-Fit Lane (
WorkspaceSection) with<h2 data-fq-lane-heading>"Goodness-of-Fit Lane". Its body depends on the catalog-load outcome:- Loading:
<p data-fq-loading>"Loading fit-quality evaluator…" - Unauthorized:
<div data-fq-unauthorized>"Access restricted." + reason - Error:
<div data-fq-error>"Could not load the fit-quality evaluator." + reason - Ready (catalog present):
<p data-fq-enums>"metrics" (from catalog.metrics.length)<form data-fq-form>with a labelled<textarea data-fq-payload>(aria-label="fit quality samples json",rows={16}, monospace, seeded withDEFAULT_PAYLOAD) and a<button data-fq-submit type="submit">"Evaluate fit quality" / "Evaluating fit quality…"- On catalog error:
<div data-fq-error role="alert">with the message and<button data-fq-retry>"Retry evaluator" - On evaluate error:
<div data-fq-evaluate-error role="alert">with the message - On result:
<div data-fq-result role="status">containing a<div data-fq-headline>("RMSE … · MAE … · R² … · worst …" withdata-fq-rmse/data-fq-mae/data-fq-r2/data-fq-worstspans) and a<table data-fq-samples>of<tr data-fq-sample-row data-sample-id>rows (sample /data-fq-sample-residual/data-fq-sample-abs)
- Loading:
- Route Map panel (
data-neith-inverse-modeling-route-map): renders 5 entries fromSTUDIO_NEITH_INVERSE_MODELING_ROUTE_MAP— primary,sessions/[sessionId],presets/[presetId],exports/[exportId],audit/[auditId] - Quick-action lane: three
Link.quickActionanchors — Isis Reference Image Processing, Isis Live Preview, Back to Studio workspace index
States#
- Reference ready (default known image) —
analyzeNeithReferenceImage(DEFAULT_NEITH_REFERENCE_IMAGE)runs at mount. The feature grid shows the known reference vector: mean0.373, contrast0.118, edgeEnergy0.135, entropy0.583, warmBias0.004. Domain-covered inneith-inverse-modeling.test.tsand E2E-covered instudio-neith-inverse-modeling.spec.ts. - Reference estimate populated — four
data-neith-model-cardcards render forterrain,vegetation,urban, andnoise. The known reference estimates include terrain erosionStrength0.565, vegetation canopyDensity0.502, urban blockDensity0.649, and noiseKindperlin. - Reference export manifest —
data-neith-export-manifestrendersmanifestVersion: neith.inverse.v1,modelCount: 4, checksumfnv1a-82598ffa, source dimensions, feature vector, four estimates, and Studio handoff targets. The manifest<pre>is focusable and labelled so its scrollable region has keyboard access. - Reference error (malformed/invalid image payload) — invalid JSON or
validation failures set
<div data-neith-reference-error role="alert">; the prior inverse report stays visible so an operator does not lose the last known-good feature vector. - Loading — server component for outer page; workspace mounts with
outcome === nulland renders<p data-fq-loading>"Loading fit-quality evaluator…" while auth hydrates and then whilefetchCatalog()runs (GET/v1/admin/studio/fit-quality). Unit-covered inStudioNeithInverseModelingWorkspace.test.tsx - Ready (catalog loaded) — GET returns a
Catalog({ metrics: string[] });<p data-fq-enums>shows "metrics" and the data-fq-formpayload form renders, seeded withDEFAULT_PAYLOAD(4 sample rows) - Gated (unauthorized) — GET returns 401/403;
<div data-fq-unauthorized>"Access restricted." renders with the server message, or the fallback "Studio admin scope required to evaluate fit quality." The form is NOT rendered (nocatalog) - Error (recoverable) — GET non-OK (other than 401/403), malformed
catalog body, or fetch rejection;
<div data-fq-error>"Could not load the fit-quality evaluator." renders with the reason (Fit-quality catalog request failed (<status>).,Fit-quality catalog response was malformed.,Could not reach the fit-quality evaluator., orNetwork unavailable.). The retry button (data-fq-retry) reissues the catalog request and returns to the ready form when the real evaluator catalog responds. - Evaluate success — POST
/v1/admin/studio/fit-quality/evaluatereturns 200 with a validresult;<div data-fq-result>renders the headline metrics and per-sample table - Evaluate error (invalid JSON) —
JSON.parse(payloadText)throws;setEvaluateError('Payload must be valid JSON.');<div data-fq-evaluate-error>renders; no network call is made - Evaluate error (server) — POST is non-200 or the body fails
isResult(); error is the serverdetailstring orEvaluation failed (<status>).; on fetch rejection,Could not reach the fit-quality evaluator.;data-fq-resultis cleared - Network unavailable —
typeof fetch === 'undefined': catalog load yields the error state; submit setsevaluateError = 'Network unavailable.' - Offline — both catalog GET and evaluate POST require the BFF; offline, they surface as the error states above; PWA cache serves the shell
- Standalone PWA — workspace section and route-map panels stack; form
maxWidth: 900, textarea full-width - Empty — N/A; the payload textarea is seeded with
DEFAULT_PAYLOAD - Populated (long) — N/A; sample-count is driven by the user-supplied JSON, not a paginated list
Interactions#
Reference Inversion Lane — image payload form#
- Reference image JSON textarea
(
<textarea data-neith-reference-payload>,aria-label="Neith reference image json")- Function: controlled input bound to
referenceText; accepts{ width, height, sourceArtifactId, label, pixels }wherepixelsis a row-major RGB/RGBA tuple array. - Keyboard: standard multiline editing in tab order inside
data-neith-reference-form. - Touch target: full-width textarea; measured at 390 px in the E2E path.
- Validation: payload must parse as JSON, include non-empty
sourceArtifactIdandlabel, positive integerwidth/height, and exactlywidth * heightpixels with channel values in0..=255.
- Function: controlled input bound to
- "Run inverse modeling" (
<button data-neith-reference-submit>)- Function: submits
data-neith-reference-form; callsanalyzeNeithReferenceImage(), updates the feature vector, all model estimates, confidence values, and export manifest. - Failure: parser/validation errors render
data-neith-reference-errorwithout clearing the prior report. - Keyboard: Enter/Space activates; Enter inside the form submits.
- Touch target: 44 px minimum height; measured at 390 px.
- Function: submits
- Feature cells (
data-neith-feature)- Non-interactive; exact keys are
mean,contrast,edgeEnergy,entropy, andwarmBias.
- Non-interactive; exact keys are
- Model estimate cards (
data-neith-model-card)- Non-interactive; one card each for
terrain,vegetation,urban, andnoise; each card exposes confidence and parameter rows throughdata-neith-model-confidenceanddata-neith-param-row.
- Non-interactive; one card each for
- Export manifest (
data-neith-export-manifest)- Non-interactive JSON manifest for downstream Studio handoff; focusable with an accessible label because it can scroll.
Goodness-of-Fit Lane — payload form#
- Samples JSON textarea (
<textarea data-fq-payload>,aria-label="fit quality samples json")- Function: controlled input bound to
payloadTextviaonChange; seeded withDEFAULT_PAYLOAD(4{ sampleId, observed, predicted }rows);rows={16}, monospace - Keyboard: standard multiline text editing; in tab order inside
data-fq-form - Screen reader: labelled "fit quality samples json" (also a visible
<span>label "Samples (JSON: { samples[{ sampleId, observed, predicted }] })") - Touch target: full-width textarea with 240 px minimum height; measured at 390 px.
- Telemetry: not instrumented in current code
- Function: controlled input bound to
- "Evaluate fit quality" (
<button data-fq-submit type="submit">)- Function: submits
data-fq-form;submitEvaluate()clears prior error + result,JSON.parseespayloadText, then POSTs the parsed object to/v1/admin/studio/fit-quality/evaluatewith the hydrated AuthProvider access token (local-dev fallback viabuildBffAuthHeaders()) +content-type: application/json,cache: 'no-store' - On 200 + valid
result: setsresult(rendersdata-fq-result) - On invalid JSON: short-circuits to
data-fq-evaluate-error"Payload must be valid JSON." before any fetch - On non-200 / malformed / rejection: sets
evaluateError - Keyboard: Enter/Space activates (also Enter within the form submits)
- Touch target: 44 px minimum height; measured at 390 px.
- Disabled when: while a POST is pending, native
disabledplusaria-disabled="true"/aria-busy="true"; the label reads "Evaluating fit quality…". - Telemetry: not instrumented in current code
- Function: submits
- "Retry evaluator" (
<button data-fq-retry type="button">)- Function: shown only in catalog-load error state; clears the error back to
data-fq-loadingand reissuesGET /v1/admin/studio/fit-quality - Touch target: 44 px minimum height; measured in the recoverable-error E2E leg.
- Function: shown only in catalog-load error state; clears the error back to
- Result table rows (
<tr data-fq-sample-row data-sample-id=<id>>)- Non-interactive; one row per
result.samples[]entry with sample id,data-fq-sample-residual, anddata-fq-sample-abscells
- Non-interactive; one row per
- Result headline (
<div data-fq-headline>)- Non-interactive; shows
data-fq-rmse/data-fq-mae/data-fq-r2/data-fq-worstfrom theFitResult
- Non-interactive; shows
Route Map panel#
- Route entries (5 ×
<article>)/studio/neith/inverse-modeling— primary inverse-modeling workspace…/sessions/[sessionId]— reference provenance + tuning deltas + snapshots…/presets/[presetId]— reusable parameter packs…/exports/[exportId]— generated manifests + Neith pipeline handoff…/audit/[auditId]— estimator confidence + reproducibility evidence- Non-interactive listing
Quick-action lane#
- "Open Isis Reference Image Processing workspace" (link →
/studio/isis/reference-image-processing) - "Open Isis Live Preview workspace" (link →
/studio/isis/live-preview) - "Back to Studio workspace index" (link →
/studio)- Keyboard: included in tab order after route map; touch ≥ 44×44 px
(
quickActionclass) - Mobile: anchors wrap (
flexWrap: 'wrap')
- Keyboard: included in tab order after route map; touch ≥ 44×44 px
(
Data & contracts#
- Local reference analysis:
apps/oshun/web/src/lib/studio/neith-inverse-modeling.tsexportsanalyzeNeithReferenceImage(),parseReferenceImage(),extractReferenceFeatures(),estimateModelParameters(), andbuildExportManifest().- Input:
{ sourceArtifactId, label, width, height, pixels };pixelsis a row-major RGB/RGBA tuple array with channel values in0..=255. - Feature vector:
{ mean, contrast, edgeEnergy, entropy, warmBias }. - Model estimates: four records keyed by
terrain,vegetation,urban, andnoise, each with confidence and model-specific parameters. - Manifest:
manifestVersion: neith.inverse.v1, source metadata, feature vector,modelCount, estimates, handoff targets (/studio/isis/reference-image-processing,/studio/bellona/interchange,/studio/hathor/world-configuration), and deterministic FNV-1a checksum.
- Input:
- Reads:
GET /v1/admin/studio/fit-quality— returnsCatalog({ metrics: string[] }); sent with the hydrated AuthProvider access token,cache: 'no-store'. 401/403 → unauthorized state; other non-OK / malformed → error state - Writes:
POST /v1/admin/studio/fit-quality/evaluate— accepts the user-supplied JSON object (default shape{ samples: [{ sampleId, observed, predicted }] }); returns{ result: FitResult }on 200, else{ detail }.FitResult={ samples: { sampleId, residual, absError }[], worstSample, rmse, mae, r2, summary: { sampleCount, rmse, mae, r2 } } - Realtime: none
- Caching: static server render; both calls use
cache: 'no-store'; metadata sets canonical URL - Auth/role check:
/studio/*requires signed-in (middleware); the fit-quality endpoints are admin-scoped (admin:* | admin:studio) and fail-closed — a non-admin sees thedata-fq-unauthorizedstate
Cross-references#
- Parent:
../../studio-overview.md - Shell:
../../../shell/04-auth-session.md - Cross-domain partners (per quick-action lane):
/studio/isis/reference-image-processing/studio/isis/live-preview
- Component sources:
apps/oshun/web/src/components/studio/StudioNeithInverseModelingWorkspace.tsx(client component: reference inversion lane + auth-ready catalog load + JSON-payload evaluate form wired to/v1/admin/studio/fit-quality)apps/oshun/web/src/lib/studio/neith-inverse-modeling.ts(deterministic reference-image feature extraction, four-model parameter estimates, confidence scoring, export manifest checksum)apps/oshun/web/src/components/studio/StudioNeithInverseModelingRouteMap.ts
- E2E:
apps/oshun/web/e2e/studio-neith-inverse-modeling.spec.tscovers direct admin navigation, reference feature extraction, four model estimates, manifest JSON, live catalog/evaluate success, non-admin fail-closed, recoverable catalog retry, 390 px form/quick-action touch targets, pending submit disabled/busy semantics, invalid reference payload, invalid fit-quality JSON with no POST, BFF invalid-payload detail, route-map, and Isis quick links - Domain tests:
apps/oshun/web/src/lib/studio/neith-inverse-modeling.test.tsproves the known reference image maps to exact feature values, model estimates, and manifest checksum.pnpm nx run @neith/procgen:testpassed for the underlying Neith procgen crate family named by V1 §34.
- Feature spec:
V1/TODOS.md§34 andV1/architecture/cross-domain-support.mddefine Bellona/Hathor/Neith as Studio-only V1 substrates (confirmed in-v1 2026-05-29); the route matrix marks/studio/neith/inverse-modelingasin-v1.
Open questions / known gaps#
- The header's stated auth (signed-in + studio entitlement) is broader than
the lane's actual requirement (admin:* | admin:studio). Confirm whether
the whole route should be admin-gated at middleware, or only the
fit-quality lane (current behavior: non-admins reach the page but see
data-fq-unauthorized). - The route map lists
sessions/[sessionId],presets/[presetId],exports/[exportId], andaudit/[auditId]sub-routes that are absent from the repo — confirm whether these are V1, V2, or out of scope. - No telemetry events fire for catalog load, payload edits, or evaluate submit; instrument when wiring to BFF analytics. The reference inversion lane also has no telemetry on payload edits or manifest generation.
- Quick-action lane crosses into Isis
(
/studio/isis/reference-image-processing,/studio/isis/live-preview); verify Isis is the canonical owner of image processing while Neith owns inverse-modeling.