Skip to content

Commit 4817336

Browse files
committed
docs(cli): document os migrate value-shapes alongside its sibling
The docs-drift check on the command's own PR flagged content/docs/deployment/cli.mdx, and that one was a real gap rather than package-level noise: the file documents `os migrate files-to-references` in full, so shipping a second gated data migration without an entry would have left it discoverable only by reading the source. Covers the deliberate asymmetry (this run converts nothing — a malformed `location` is application data whose correct value only its author knows), the truncation rule (a partial scan cannot open the gate), and why the flag is separate from the file migration's rather than reusing it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016zgA8CQMJeJbFEjnbib1Uv
1 parent 7832233 commit 4817336

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

content/docs/deployment/cli.mdx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ where the data lives.
628628
| Command | Description |
629629
|---------|-------------|
630630
| `os migrate files-to-references` | Convert legacy file-field values to `sys_file` references, verify the ownership ledger, and record the deployment's migration flag |
631+
| `os migrate value-shapes` | Scan stored reference and structured-JSON field values against the platform's value contract, and record the deployment's migration flag when clean |
631632

632633
```bash
633634
os migrate files-to-references # Dry run: full report, writes nothing
@@ -659,6 +660,49 @@ Exit status is `0` only when the self-check passes, so CI can gate on it.
659660
| **Media value shapes** | A malformed `file` / `image` / `avatar` / `video` / `audio` value is **rejected** (`400 invalid_type`) instead of warned about. Set `OS_ALLOW_LAX_MEDIA_VALUES=1` to re-open leniency while diagnosing. |
660661
| **Released-file collection** | A field file whose one owning record lets go (the field is cleared or the record deleted) is tombstoned into the declared 30-day grace window; re-referencing the id within the window revives it, and after it the platform sweep reclaims the row and its bytes. Unverified deployments keep every released file forever. |
661662

663+
#### `os migrate value-shapes`
664+
665+
The same gate for the **non-media** value classes — references (`lookup`,
666+
`master_detail`, `user`, `tree`) and structured JSON (`location`, `address`,
667+
`composite`, `repeater`, `record`, `vector`).
668+
669+
```bash
670+
os migrate value-shapes # Scan: full report, writes nothing
671+
os migrate value-shapes --apply # Scan, then record the flag if clean (prompts)
672+
os migrate value-shapes --apply --yes --json # CI / scripts
673+
os migrate value-shapes --object contact # Restrict to one object (repeatable)
674+
```
675+
676+
**This one converts nothing.** Its sibling rewrites legacy file values because
677+
the platform narrowed that storage form and therefore owes the conversion; a
678+
`location` stored as `{latitude, longitude}` instead of `{lat, lng}` is
679+
*application* data whose correct value only its author knows. So the run reports
680+
— object, field, type, how many records, sample record ids, and the parse issue
681+
— and you fix the values (or the code writing them) and re-run until it is
682+
green. Because there is nothing to convert, `--apply`'s only write is the flag
683+
row itself.
684+
685+
A scan that is **truncated** (by `--max-records`) or that cannot read an object
686+
fails the gate even with zero violations found: "none in the part we read" is
687+
not the claim the flag makes.
688+
689+
| Once verified | Effect |
690+
| :--- | :--- |
691+
| **Reference + structured-JSON value shapes** | A malformed value of those classes is **rejected** (`400 invalid_type`) instead of warned about. Set `OS_ALLOW_LAX_VALUE_SHAPES=1` to re-open leniency while diagnosing. |
692+
693+
This flag is deliberately **separate** from the file migration's. That one
694+
attests that file values were migrated and their ownership reconciled — it says
695+
nothing about whether a `lookup` id or a `location` payload is well formed, so
696+
it may not vouch for these classes. A deployment can legitimately have passed
697+
either without the other.
698+
699+
<Callout type="warn">
700+
`OS_DATA_VALUE_SHAPE_STRICT_ENABLED=1` turns on **every** value class at once,
701+
regardless of which migrations this deployment has run. It is the "I already
702+
know my data" lever, not the route to strictness — the route is running the
703+
migration that produces the evidence.
704+
</Callout>
705+
662706
Other value classes are unaffected: a `lookup` or `location` value keeps its own
663707
warn-first rollout, because this migration is evidence about *file* values and
664708
says nothing about theirs.

0 commit comments

Comments
 (0)