Files
Edgar Arakelyan 38719a6fa9 feat(environment): explain values an application derives from other fields (#7025)
* feat(environment): explain values an application derives from other fields

Prompt-built environments withheld creates whose responses carry values the
application derives deterministically, which the write model kept as
constants or could not match across calls:

- A composed string is literal text plus parts read from the fields other
  rules write: a field's value, its slug, or a clock's calendar digits. A
  create composes a string only when another entity of the type spells it
  the same way and none spells it otherwise, and never from two sources
  serving could tell apart; an update composes an unsent change from members
  stored as sent and unchanged fields that also spell its value before the
  call. A composed field no longer pins the members it reads.
- A trimmed clock format drops trailing fraction zeros, as Go spells
  nanoseconds. It is learned from the type's values, a later create or a
  later update, and spreads to the plan's other clocks unless a value shows
  a fixed width.
- A large integer no entity of the type holds, among distinct ones of the
  same length and kind, is a generated unique value, served as a seeded
  integer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(environment): record the derived-values verification

Gates, tests, write plans over 69 recorded captures and served write tasks on the baseline and on this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep clock spellings, linked ids and word boundaries honest

- A later update's clocks take the plan's spelling, sibling-trimmed
  clocks included, wherever the call's values fit it, so an update whose
  later call trims only one of two clocks is served.
- A held value that ends its fraction in a zero keeps a create's clock
  at a fixed width, whatever order the held spellings come in.
- A large integer that another field of the created entity also holds
  is linked, as a repeated token is: it is never unique, and the create
  is withheld as unexplained-change.
- Composed parts are delimited by whole characters through the shared
  joinsBefore/joinsAfter, so an astral letter joins a match to its word.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(environment): keep a same-width fixed clock out of trimming

A held .123456780 beside a held .12345678 keeps the create's clock at
nine digits in either order; the cases fail on 8ce1127b5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): check composed parts and clock fits before they shape a plan

- A composed string whose part has nothing to spell refuses the create
  or update through the apply Result instead of keeping a stale value.
- A composition learned on a later call is rebuilt from each earlier
  call's fields, so an earlier call that left the value otherwise
  contradicts it.
- An update adopts its fitted clock spellings only after the
  unknown-entity and contradiction checks, so a call on an entity an
  unmodelled write left unknown no longer trims a served plan's clock.
- Sibling trimming on a later create also checks that call's fields,
  so a sibling clock it shows with a trailing zero stays fixed-width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(environment): split the derived-values view tests by rule

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep fixed-width, zone and generated-integer evidence through a plan

- A plan keeps the first value that showed each clock at a fixed width,
  from held entities and every accepted create or update. No later fit
  or sibling trim widens that field, and a later call that shows it
  shorter is withheld.
- Two stamped clocks are one composed source only when they share a
  zone offset. A held entity that holds the target field as anything
  the parts do not spell, a non-string included, vetoes the
  composition. The token index is built once, and only when a string is
  left to compose.
- A generated integer that another field repeats as a number at any
  depth is linked. Compare treats two integers of one JSON kind and
  length under a unique rule as generated values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(setup): share registration prewarm host preparation

* fix(environment): retain write evidence and match trimmed response clocks

* fix(environment): withhold creates whose generated integer another string repeats

A unique integer whose digits show in another top-level string that no
template or composed rule rebuilds from it (an echoed serialText, or a
token like folder-<id>) withholds the create as unexplained-change,
since serving would seed the integer and keep the string. A templated
copy is still served.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): hold later creates and compare to the composed and integer forms

- A later create whose response spells a composed field otherwise than
  the plan rebuilds it is withheld as unexplained-change.
- A unique field learned from a generated integer accepts only an
  integer of the same length and kind from a later create, as serving
  seeds one.
- Compare counts a composed field as equal when each side's response
  spells it from its own fields, which compare under their own rules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): preserve composed parts and unique generator families

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-25 05:06:21 +08:00

4.4 KiB

Explain values an application derives from other fields

Issue: https://github.com/morluto/rea/issues/4933

Outcome

Environments an agent built from a prompt withheld creates in three of five applications, each for a value the write model could not explain, though the application derives it deterministically:

  • Linkding's web_archive_snapshot_url is https://web.archive.org/web/<creation time as YYYYMMDDhhmmss>/<sent url>. The plan kept it as a constant, which pinned url to its recorded value, so a later create with another URL was refused.
  • Grafana's folder url is /dashboards/f/<uid>/<slug of the title>, which pinned uid the same way, and its numeric id is a large time-based integer the plan copied from the first create, which the second create's read-back contradicted.
  • Homebox, written in Go, spells nanosecond clocks with trailing fraction zeros dropped (…34.38812218Z), so a later create's clock did not follow the format learned from the first.

Behaviour

  • Composed strings. A created field no other rule explains may be a composed string: literal text and parts read from the fields other rules write, each a field's value, its slug, or a clock's calendar digits (YYYYMMDDhhmmss, YYYYMMDD, YYYY-MM-DD, YYYY/MM/DD, in the clock's zone). Parts are found left to right, longest first, delimited by non-alphanumerics; generated values may be short, other values need eight characters, as a copy does. A create composes a string only when at least one other entity of the type spells it with the same parts and none spells it otherwise, and never when one text comes from two sources serving could tell apart (two clocks the write stamps are one source when they spell the same zone), and never when another entity holds the field as something other than the parts spell, a non-string value included. An update's unsent change may be composed from members it stored as sent and fields it left as they were, when the same parts also spell the value before the call and no other entity spells it otherwise. Serving rebuilds the string from the written fields after every other rule and refuses a call when a part's field holds nothing to spell, and a composed field no longer pins the members it reads. A composition learned on a later call is checked against every earlier call, and a later create whose response spells a composed field otherwise is withheld.
  • Trimmed clocks. A clock format may be trimmed: its values differ only in how many fraction digits they show and none ends a fraction in a zero. It is learned from the type's held values of the field, from a later create, and from a later update; other clocks the plan stamps take the spelling too, and no clock takes it once a held entity, the exemplar or any call the plan accepted showed the field at a fixed width; a later call that then shows it shorter is withheld. fraction is the most digits shown, and serving drops trailing zeros and the point with them.
  • Generated integers. A created integer of 10 to 20 digits that no entity of the type holds, where every held entity holds a distinct one of the same length and JSON kind and none is a clock, is unique. Serving draws a seeded integer of that length and kind that no held entity has. One that another field of the created entity also holds, as a value, a number at any depth or a delimited part of a nested string, is not unique, and the create is withheld as unexplained-change, since seeding cannot keep the two equal. A create is also withheld when another string holds its digits and no template or composed rule rebuilds that string from it, or when a later create answers the field with anything but an integer of the same length and kind. Compare treats two such integers of one JSON kind and length under a unique rule as generated values.

Plans that need none of this are unchanged.

Later creates must retain the exemplar's unique-value family (UUID, integer with the same digit count and JSON kind, or opaque token). Their recorded composed fields must equal the values the plan rebuilds; simulation cannot replace a contradictory captured value and then count that replacement as confirmation.

Acceptance

  • The prompt-built Linkding, Homebox and Grafana captures serve the creates and renames they withheld, and write tasks that use them pass.
  • No write tool of the 50 published captures or the earlier prompt-built captures goes from served to withheld.