aontu

Change a pinned value

Rewrite a pinned literal where the author wrote it with aontu model set --in-place, and know the cases where the verb appends instead.

Rendered from docs/how-to/change-a-pinned-value.md in the engine repository, where a correction belongs, and where the test suite executes every example on this page.

Appending cannot change a pinned value: the append makes two concrete facts at one path, and the lattice refuses both. --in-place closes the loop by rewriting the literal where the author wrote it. To see both behaviours, write a schema.aon that constrains the fields:

replicas: integer & min(1) & max(24)
port: integer

and a deploy.aon overlay that pins them, comments included:

# the deployment
replicas: 42 # too many
port: 0x1F

Plain aontu model set refuses, because the overlay would then disagree with itself:

$ aontu model set '$.replicas=5' --entry schema.aon --overlay deploy.aon
verdict: invalid

$.replicas: scalar_value [conflict]
  [aontu/scalar_value]: Cannot unify values at path $.replicas
  data: deploy.aon:4:13 (5)
  data: deploy.aon:2:11 (42)
$ echo $?
1

Both sites are labelled data:: the pin and the contradiction live in the same file, which is exactly why appending cannot help. Add --in-place and the literal is rewritten instead:

$ aontu model set '$.replicas=5' --entry schema.aon --overlay deploy.aon --in-place
verdict: valid
replaced: deploy.aon:2:11 42 -> 5
wrote: deploy.aon
$ echo $?
0

The file now reads:

# the deployment
replicas: 5 # too many
port: 0x1F

Comments and layout survive, including the one on the edited line, because nothing is re-serialised: the span at (row, col, len) is replaced and every other byte is left exactly as it was. The edit is also verified before it is written: a site carries the source text it claims to cover, and the text at the span must match it. That is what makes a hex literal safe to rewrite even though its value is 31:

$ aontu model set '$.port=80' --entry schema.aon --overlay deploy.aon --in-place
verdict: valid
replaced: deploy.aon:3:7 0x1F -> 80
wrote: deploy.aon

The report speaks in source text (0x1F -> 80), because replacing a spelling is a different edit from replacing a value.

Where it cannot rewrite, it appends as plain set would and says why in a warning. A warning never moves a verdict, so --in-place is never worse than set without it:

the overlay sayswhy notwhat happens
a: min(1), a: 1+2, a: {b:1}the site names the opening token of a compound, not the whole valueappended, patch_not_editable
a: 1 twicetwo statements pin it; there is no single place to editappended, patch_ambiguous
a &: template, a $refthe value comes from elsewhere; edit it thereappended, patch_not_editable
a: integer, a: above(0)a constraint, not a pin: appending narrows it without discarding itappended, patch_not_editable
anything, when the overlay itself @"includes" another documenta loaded literal’s position cannot be told from the overlay’s ownappended, patch_not_editable

A default (a: *1) is not in the table: appending already overrides it correctly, so --in-place leaves it alone and says nothing.

The last row cuts both ways, and the reverse direction is easy to get wrong. To change a value that lives in an included file, name that file as the overlay, but give --entry something that constrains the value without also pulling the file in. Write a stack.aon entry that loads deploy.aon, the natural arrangement and the wrong one here:

@"./deploy.aon"
replicas: integer & min(1) & max(24)
port: integer
$ aontu model set '$.replicas=9' --entry stack.aon --overlay deploy.aon --in-place
verdict: invalid
would replace: deploy.aon:2:11 5 -> 9

$.replicas: scalar_value [conflict]
  [aontu/scalar_value]: Cannot unify values at path $.replicas
  data: deploy.aon:2:11 (9)
  schema: deploy.aon:2:11 (5)
$ echo $?
1

The overlay’s value meets itself through the entry’s include, so the run is refused and nothing is written. would replace: (rather than replaced:) tells you the edit itself was possible and the conflict lay elsewhere: here, in the shape of the invocation. Pass schema.aon as the entry, as the earlier runs do, and the same command holds. (Why the tool refuses the shape instead of detecting the collision.)

Pair --in-place with --dry-run to see the rewritten overlay without writing it. The full editability rules are under aontu set; after any refusal, aontu why lists every line involved; and the live version, an ops overlay repeatedly rewritten in place, is use-cases/08-feature-flags.