# Setup

How far a profile has been looked at on the profile screen - which sections were saved or marked "Looks right", which values the shooter answered "Don't know yet" for, and (on older profiles) when setup was marked finished.

## Generated table

**Record:** profile · **Covers:** `setup`

| Field | Type | Required | Limits in the schema | Solver reads | In a shared log |
|---|---|---|---|---|---|
| `setup.finished_at` | string | no | - | no | removed for every reader |
| `setup.sections` | array of `'rifle'` or `'scope'` or `'zero'` or `'ammo'` or `'bullet'` or `'calipers'` | no | at most 6 items | no | as stored |
| `setup.unknown` | array of string | no | at most 40 items | no | removed for public readers |

## What it holds

This optional block of a profile version records how far the profile has been looked at. Since 2026-10-18 the profile screen is where a profile is seen and changed: a list of sections, Today first, each opening on its own (it grew out of the earlier guided setup, which no longer exists as a separate screen). The block has three members: the sections the shooter saved or marked "Looks right", a list of values they answered "Don't know yet" for, and, on profiles from before 2026-10-18, the moment they marked setup finished. It is bookkeeping, not part of the rifle or the load: no solver, fit or come-up reads it. A profile from the connector has no block, which means only that nobody was asked.

## What to know first

**A flagged value is still a number the solver flies.** A field on `setup.unknown` keeps the value it has, a default or a guess, and every solve, fit and range card uses it. The mark changes no answer; it says nobody measured the number.

**The app clears a mark when the value changes; the connector does not.** The profile screen drops a mark when the field's value changes. `edit_profile`, a fit and "Use this one again" change the value and leave the mark.

**The list is hidden from the public.** A reader of a public share sees the finished sections, but not the list. A share with one person, a share with the admins, and an admin reader see both. No reader gets the finished time (since 2026-10-24).

**An absent block means nothing was looked at yet.** The profile screen's list shows every step "Not looked at yet". Nothing is refused because a section was not looked at.

## The fields

**`setup`** The whole block. Absent when no section was finished, no value is flagged and setup was not marked finished: a save that leaves all three empty removes the key instead of storing an empty block. The schema allows no other member.

**`setup.sections`** The sections the shooter saved or marked "Looks right", each once, in the order they were first marked. The six stored ids keep their names; the profile screen shows them under its own titles:

- `rifle` (screen title Rifle): the profile's name, rifle make and model, cartridge, twist, twist direction, barrel length and muzzle device. It can flag `rifle.twist_in`.
- `scope` (Scope): scope make and model, turret units, reticle, sight height and the elevation the scope can dial. It can flag `rifle.sight_height_in`.
- `zero` (Zero): zero range, the slope the zero was shot on and the air of the zero. It flags nothing.
- `ammo` (screen title Today): the muzzle velocity, today's measured velocity, the chronograph strings and the velocity-by-temperature table. It can flag `ammo.mv_fps`.
- `bullet` (screen title Load and bullet): load name, lot, factory or handload and its recipe, then the bullet's name, weight, diameter, drag model, BCs and construction. It can flag `ammo.bc_g7`.
- `calipers` (Calipers): up to three caliper readings for each measurement of a bullet. It can flag `ammo.bullet.length_in`.

The screen has seven step sections; the seventh, Model, has no stored id, so its state is not kept and its row always shows the model. A stored step is either looked at or "Not looked at yet". Looked at is the shooter's word, not a check: it is added even when every value in the section is still flagged, and nothing ever removes an id. Saving a section again, or pressing "Looks right" again, changes nothing in the list. When all six are looked at the list says "Every section is looked at."

**`setup.unknown`** The values answered "Don't know yet": a list of dotted paths into the profile, such as `rifle.sight_height_in`, in the order they were flagged, with no repeats from the app. A path on it names a field that still holds a value. The app can flag exactly five paths, the five named in the list above, and a new guided profile starts with all five flagged. Example: `rifle.sight_height_in` and `ammo.bullet.length_in`. The schema accepts any text as a path and at most 40 of them; readers ignore a path they do not know, but they still count it (see Who reads it).

**`setup.finished_at`** The time the shooter pressed "Mark setup finished" on the guided setup of before 2026-10-18, as an ISO date and time. The profile screen has no such button and never writes it; since 2026-10-24 the app's next save of the profile drops a stored time, and no share passes it on. It is a note, not a lock.

There is no number among these three members, so there is no limits table. The record schema limits the number of items (6 and 40) and fixes the six section ids. The app's save check, the connector's inputs and the conversion to the solver look at none of the three: a block with a path that names no field, or a time that is not a time, saves and syncs as long as it fits the schema.

## Who writes it

**The app.** Four things write the block. The last three go through the one save in `applyChanges`; the first stores a new profile directly.

- A new profile (the "New profile" button on the profile list, the start button on an invite page, or "another rifle" on the invite banner) is stored as version 1 named "My rifle" ("My second rifle" from the invite banner), with the five flags set and nothing else.
- "Save this section" saves that section's answers, adds its stored id, and sets or clears the "Don't know yet" tick of every flaggable value on that screen. The tick wins over the value: if the shooter changes a value and leaves the tick on, the path is flagged again.
- "Looks right", shown on a stored step while nothing in it is changed, adds the section's id and nothing else. Like any save it is refused while the stored profile fails the app's save check (a velocity of 5200 gives "Muzzle velocity must be 300 to 5000" and saves nothing).

Every one of these saves a new version, even a save that changes only this block. In the Load and bullet section, when the bullet's length is flagged and a save changes the weight, the diameter or the construction, the profile screen also replaces the length with a new estimate for the new bullet and keeps the flag.

**The connector.** None of its tools can set or clear any member. `edit_profile` starts from a copy of the stored version and so carries the block through unchanged, including marks on values it has just changed. `create_profile` stores no block, and an input called `setup` is not used, and the reply names it ("I ignored: ..."). `copy_shared_profile` writes the block as the reader saw it, without the finished time, as the app's "Save a copy" does; the [origin](origin.md) and [versions](versions.md) pages describe the copy and the restore of a deleted profile.

**The fitter.** Since 2026-10-24 a fit or a direct save clears the mark on each value it sets, whether saved from the app or by `calibrate_profile` and `tall_target`: "MV true" clears `ammo.mv_fps`, the tall-target save `scope.ssf_elev`, the velocity-temperature save `ammo.mv_temp_table`. "Use this one again" in the app clears the marks on the velocity, the velocity table, the drag curve and factors and both scope factors. Other marks stay; when none is left the list is removed, and the block with it if nothing else is in it. See [calibration](calibration.md).

## Who reads it

**The solver and the fitter** read nothing here. A profile with the block and the same profile without it give the same solved profile, the same flight and the same fit (run for this page).

**The app.** The profile screen's list shows each stored step as "Not looked at yet" or with its values, adds " · Don't know yet: N" for the flagged values in it, and the screen always opens on that list, at any width, until a section is picked (since 2026-10-20; before, it opened on the first step not looked at). Today's row and heading say what it holds: "Muzzle velocity and chronograph". The Calculator's line "Rough guess: N values not measured · fix" counts every entry on the list; "fix" links to the profile screen (plain text on a shared profile). A shared log's Profile tab opens the same screen on the shared profile, read-only: the same list, every control off, no save; the finished date is not shown. The printable worksheet uses the section state. A path the app does not know has no section and no name: it is counted by the Calculator and never shown by name.

**The connector.** Three tools use it.

- `check_profile` reports each path it can word (sight height, twist, zero range, barrel length, bullet length, weight, diameter, velocity, G7 and G1 BC, overall length, powder charge, bullet jump, elevation travel) as "Not measured yet: sight height." at the "check" level (the spoken reply gives the first two findings and how many more), and counts any other path in one note, "N other values are marked not measured.", which it does not speak. On a shared or copied profile, entries that are not field paths are removed before the check and are not counted. A flagged bullet length adds a note that the Spin model would run on an estimated length.
- `explain_dope` reads one path only, `rifle.sight_height_in`. A sight height that explains the remembered come-ups counts as believable when it is anywhere from 1.5 to 3.0 in if the sight height is flagged, and only within 0.25 in of the entered number if it is not. Every other flagged value is treated as measured: a flagged velocity or BC is judged against its usual margin. In a run for this page, with a made-up 144 gr, 0.264 in bullet at 2840 fps and one remembered come-up of 11.0 MOA at 600 yd in 60 °F air at 29.1 inHg, the sight-height explanation (2.87 in against 2.5 entered) is "ruled out" when the sight height is measured and "fits exactly, unchecked" when flagged. My own numbers, not a measurement.
- `get_shared_profile` returns a shared profile's block as `setup`: the finished sections and the flagged paths under `unmeasured` when the share showed them. A string stays in either list only when it is built from the app's own fixed words: a dotted path made of profile field names, one of the app's code words, or a date. Anything else the sharer wrote there is moved to `sharer_text`, cleaned and cut like their other words. The speech counts the list as returned ("3 values are not measured yet"). Since 2026-10-24 a share carries no finished time, and since 2026-10-25 the tool's output schema no longer lists a `finished` field either.

`get_profile` returns the whole stored version of the shooter's own profile, block included (since 2026-10-15 its names and notes come apart under `stored_text`; the block's paths stay in the record).

**The share filter** is the one other reader; see Sharing and privacy.

## Why it is stored

The answers on the profile screen are the profile's own fields, so the block stores only what those fields cannot say. A shooter who does not know the sight height still needs a number to get a come-up; the guess is kept as the value and the list says it is a guess, so the shooter, a helper reading a shared copy, and Claude can tell a typed sight height from a placeholder. The looked-at sections let the profile screen open where the shooter left off, on any device. The finished time, on older profiles, says the shooter called setup done; a helper reading the log can still see it. It lives on the profile version, not on the device, so it syncs and shows in the history.

## Changing it

An edit that changes only this block saves a new version, and so does saving a section or pressing "Looks right" again, though nothing in the block changes. It is in no edit category, so it never asks keep or reset and never touches a calibration; older groups stay eligible for a fit. The shooter can mark a value flagged or measured at any time without affecting a fit or a logged group.

A mark is dropped by the app in two cases: the field's stored value is different after the edit (compared exactly, so retyping the same number keeps the mark), or the profile screen's "Don't know yet" was unticked. Adding a flag wins over the drop in the same save. Three things keep a mark the shooter may expect to go: an edit by `edit_profile`, a calibration that changes the same value, and a path that names no field of this build, which stays while its value, empty, does not change. A path that names a whole block the save rebuilds (`ammo`, `ammo.bullet`, `ammo.drag`) is the exception: the next app save drops it.

## Sharing and privacy

The unmeasured list is the one member that is held back, and it is held back with the handload recipe, by the same rule, which fails closed.

| Reader | `setup.sections` | `setup.unknown` | `setup.finished_at` |
|---|---|---|---|
| A share with one person | shown | shown | removed |
| A share with the admins | shown | shown | removed |
| A public share, an ordinary reader | shown | removed | removed |
| A public share, an admin reader | shown | shown | removed |
| A share the code cannot place (no or unknown audience), ordinary reader | shown | removed | removed |
| A share the code cannot place, admin reader | shown | shown | removed |

The "hide location" and "hide notes" switches do not touch any of the three. When the list is removed the rest stays, and since 2026-10-24 a block left empty is removed whole, so a reader cannot tell that a list was taken out. A block that is not the shape the schema describes (a list, a number, a word) is dropped whole on a hiding share and passed on as it is on the others. A copy keeps the sections and the list as the reader saw them. What a reader can work out: which sections the owner finished and, on the shares that show the list, which values are guesses.

---

[All reference pages](../index.md)
