Complex identification: the field guide

The one-page working reference. The concept page explains why it works this way and the authoring page covers building a pack from scratch; this page is what you keep open while running one. Examples use the shipped garden-survey pack.

The mental model, in six steps

  1. Detect. Every sampled frame is scanned: the wide-net model pass proposes codeable things with boxes, and free geometric detectors add candidates the model misses (thin linear features especially).
  2. Track. Proposals are followed across frames. One physical thing = one track, however many frames it appears in. Code flip-flop within a family never splits a track.
  3. Funnel. Free checks decide what deserves a paid call: an area floor, shape routing for thin candidates, sheet screening for unproposed regions, the registry gates run on proposals, and tracks cluster into whole features.
  4. Confirm. Each feature gets ONE model call with its best views, the stage-1 proposal, and a verdict expected: confirm, reclassify with a reason, or withdraw.
  5. Gate. The answer passes the deterministic gates: enum lock, legality, surface, region, host, channel, extent, residual, readings, grade lookup. Anything contradictory is kept and flagged to review, never dropped, never silently accepted.
  6. Record. Instances project to records per each code's record mode; the report collapses runs to start-finish, the portal layer keeps every frame.

One sentence: the model sees, the standard decides, and everything doubtful goes to review with its reason attached.

Commands

# codebook lifecycle
neuraframe codebook                  # what pack is set, and the reuse setting
neuraframe codebook check DIR        # validate a pack: every problem listed, nothing silent
sudo neuraframe codebook use DIR     # set the pack
sudo neuraframe codebook off
neuraframe codebook reuse on|off     # reuse gate while coding (default off)

# the runner
neuraframe codebook run --input FILE_OR_FRAMEDIR --out DIR [--config run.json] [--stub]
neuraframe codebook run --help       # every run-block knob as a --flag

--stub runs the whole spine with zero model calls. Use it before every live run and after any pack edit. A folder of ordered frames works as input too. Common overrides (flags win over the config file):

--sample-fps 4                       # examine more frames per second (0 = every frame)
--start-ms 60000 --end-ms 120000     # code one window of the footage
--equirect off                       # flat footage instead of 360
--detector local                     # free detection instead of the model wide net
--residual-pass on                   # second look after masking confirmed findings
--workers 8                          # concurrent confirmation calls

The pack: seven files, all yours

my_pack/
  manifest.json    the domain tables: context, bands, legality, regions, hosts, readings, surfaces
  registry.json    every code: family, mode, grading, evidence, hosts, regions, floors
  rules.md         domain knowledge, rides on EVERY model call
  detect.md        task framing for the wide-net pass (used verbatim)
  confirm.md       task framing for the confirmation pass (used verbatim)
  notes.md         optional standing site guidance, appended to confirmations
  excluded.json    codes out of scope for this deployment

Edits to the .md files apply on the next run, no rebuild. After editing the .json files, run check, then use again.

A registry entry, every key that matters

{"code": "WGD", "title": "Growth, dense run",
 "family": "growth",              groups codes for tracking and remap; families never merge
 "record_mode": "EXTENSIVE",      SINGULAR point | EXTENSIVE run | REPEATED per host |
                                  PROMOTABLE point-that-can-become-run | STATE reader
 "graded": true, "band_set": "A",
 "grading": {"ornamental": {"type": "threshold", "rules": [
     {"band": "<=10", "grade": 2}, ...]}},   per context column; fixed or threshold
 "expected_region": "ground",     geometric legality, checked against OUR tracked position
 "evidence_primary": "L",         L structure | C colour | T rate and motion
 "requires_host": ["stake"],      what must independently exist nearby (manifest hosts says how)
 "state_trigger": "survey_start", STATE only: survey_start (always exists, anchored at start)
                                  | on_change (exists ONLY at a transition; absent is normal)
 "residual_code": true,           a last-resort bucket: rejections required, downgrades logged
 "min_extent": {"min_sightings": 6, "min_clock_span_hours": 3},  extent floor, BOTH must hold
 "anchored": true,                survey structure from the job header, never inferred from imagery
 "position_constraint": "survey_boundary",   may only exist at the survey start or end
 "clock_applicable": false,       occupies the full view; a position-localised candidate is not it
 "fields": {"cont": "-"}}         cont "-" forbids a run for this code

Rule of thumb: the model only ever answers what a camera can see (a code, a band, real or not, a note, declared readings). Everything else in the entry is deterministic engine work.

The manifest tables, what each does

TableWhat it does
context_fields + defaultsThe job facts. Anything defaulted is stamped on every record as an assumption a reviewer can see.
grading_field / grading_columnsWhich context field selects the grading column.
band_setsThe percentage ladders codes resolve grades on.
legalityContext value to illegal families. Unknown context = the gate stands down, never blocks.
conditional_legalityCodes only legal under certain context. Blocking, not advisory.
presence_gated_familiesFamilies only legal when a context flag is true.
remap_familiesLetter-to-family routing for loose model codes; kept for recoding, never dropped.
surfaces + surface_rulesWhat surface a code may sit on.
regionsClock-position definitions that make expected_region machine-checkable.
hostsWhat satisfies each requires_host name: nearby codes/families, a context fact, external (never inferable from imagery, routes to review), or visual (the confirmation call judges).
readingsNumeric values some codes carry, asked in YOUR words with the datum named, range-validated.
state_at_startFallback list of anchored states; the registry's state_trigger wins when declared.

run config: the four blocks

One JSON (--config): run (sampling, detection, funnel, tracking - also CLI flags), coder (endpoint, dossier, location, channels), records (projection and verification thresholds), context (the job facts). The Vision CLI reference documents every knob; the ones you will actually reach for:

KnobDefaultWhy you would touch it
run.sample_fps2More frames examined = more sightings, more cost. 0 = every frame.
run.detectorlocalmodel is the propose-then-confirm accuracy setup.
run.equirectoffOn for 360 footage: seam-aware, clock-aware tracking.
run.min_seen2Sightings to qualify; singles go to review.
coder.views_per_dossier4Frames of the same feature per confirmation call.
coder.constrained_codesoffOn = the model answers item numbers; transposition impossible.
records.merge_gap_ms4000The same-physical-thing constant (also drives feature clustering).
run.price_in / price_out-Your $/1M tokens; the cost block then shows dollars.

Outputs

FileWhat it is
report.mdThe deliverable: one row per finding (runs as start-finish spans, wrapping findings as clock spans), then the review queue with reasons.
portal.jsonlOne row per FRAME per finding, all tagged the same feature_id. Scrub anywhere, see the finding. Never collapsed.
segment.jsonRecords, ratings, review, assumptions, the funnel and cost metrics, and the exact configuration used.
observations.jsonlEvery per-frame annotation, dense, with the stage-1 proposals.
dossiers/*.jpgExactly what the model was shown, per decision.

The review queue, decoded

The review queue is the recode workbench: everything the engine kept but would not certify, each with its reason. What the reasons mean:

Reason starts withIt meansWhat to do
below_min_seenSeen once - usually a blipConfirm real, or ignore
uncoded_or_off_bookNo valid code (a failed call, or an unknown answer; the evidence rides along)Recode by hand
gate_flagged: surface/region_mismatchCoded somewhere that code cannot beUsually a recode
gate_flagged: suspect_channelA structure code with colour-only support - probably a stainCheck the dossier
gate_flagged: residual_unjustifiedA catch-all answered with no rejections of the specific alternativesRecode to the specific
gate_flagged: residual_downgrade_reviewOne call overrode a well-supported proposal with a catch-allJudge the dossier yourself
host_missingThe code asserts something else exists nearby, and it does notCheck the host, or recode
pregate_*Refuted before any money was spent (the same rules, run on the proposal)Scan; mostly ignore
extent_below_floorAn extent-gated code below its sighting or span floorRecode - it is not that thing
state_unchangedA state sighting with no real changeIgnore - kept for comparison
context_contradictionA record inconsistent with what the rest of the record set impliesCheck the job facts
anchored_structureThe model named a boundary landmark for a tracked feature; the real record comes from the job headerSet the anchor type in context
position_constraintA boundary-only code seen mid-survey - a contradiction, not an observationUsually the scene ahead
clock_localisedA full-view code localised to one position - a wall feature by constructionRecode to what it actually is

The numbers to watch

Recipes