mirror of
https://github.com/morluto/rea.git
synced 2026-11-03 21:36:13 +00:00
* 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>
112 lines
2.9 KiB
TypeScript
112 lines
2.9 KiB
TypeScript
import { expect, it } from "vitest";
|
|
import type { JsonValue } from "../jsonValue.js";
|
|
import {
|
|
clockDigits,
|
|
fittedClockFormat,
|
|
trimmedLike,
|
|
} from "./environmentStateWriteClockFormats.js";
|
|
import type { ClockFormat } from "./environmentStateWriteValues.js";
|
|
|
|
const iso = (
|
|
separator: "T" | " ",
|
|
fraction: number,
|
|
zone: string,
|
|
): ClockFormat => ({ kind: "iso", separator, fraction, zone });
|
|
|
|
const WITH_MS = Date.UTC(2026, 2, 4, 5, 6, 7) + 123;
|
|
|
|
const TRIMMED_9: ClockFormat = {
|
|
kind: "iso",
|
|
separator: "T",
|
|
fraction: 9,
|
|
zone: "Z",
|
|
trimmed: true,
|
|
};
|
|
|
|
it.each<
|
|
[string, ClockFormat, string, string | undefined, ClockFormat | undefined]
|
|
>([
|
|
[
|
|
"the format's own spelling",
|
|
iso("T", 9, "Z"),
|
|
"2026-03-04T05:06:07.123456789Z",
|
|
"2026-03-04T05:06:07.123456781Z",
|
|
iso("T", 9, "Z"),
|
|
],
|
|
[
|
|
"a shorter trimmed fraction",
|
|
iso("T", 9, "Z"),
|
|
"2026-03-04T05:06:07.12345678Z",
|
|
"2026-03-04T05:06:07.123456781Z",
|
|
TRIMMED_9,
|
|
],
|
|
[
|
|
"a longer one than a trimmed exemplar",
|
|
iso("T", 8, "Z"),
|
|
"2026-03-04T05:06:07.123456781Z",
|
|
"2026-03-04T05:06:07.12345678Z",
|
|
TRIMMED_9,
|
|
],
|
|
[
|
|
"no fraction beside a trimmed one",
|
|
iso("T", 9, "Z"),
|
|
"2026-03-04T05:06:07Z",
|
|
"2026-03-04T05:06:07.123456781Z",
|
|
TRIMMED_9,
|
|
],
|
|
[
|
|
"a fraction ending in a zero",
|
|
iso("T", 8, "Z"),
|
|
"2026-03-04T05:06:07.123456780Z",
|
|
"2026-03-04T05:06:07.12345678Z",
|
|
undefined,
|
|
],
|
|
[
|
|
"an exemplar ending in a zero",
|
|
iso("T", 3, "Z"),
|
|
"2026-03-04T05:06:07.123456Z",
|
|
"2026-03-04T05:06:07.120Z",
|
|
undefined,
|
|
],
|
|
[
|
|
"another zone",
|
|
iso("T", 9, "Z"),
|
|
"2026-03-04T05:06:07.1234567+00:00",
|
|
"2026-03-04T05:06:07.123456781Z",
|
|
undefined,
|
|
],
|
|
[
|
|
"a shorter value under a trimmed format",
|
|
TRIMMED_9,
|
|
"2026-03-04T05:06:07.1Z",
|
|
undefined,
|
|
TRIMMED_9,
|
|
],
|
|
])("fits %s to a clock format", (_name, format, value, exemplar, expected) => {
|
|
expect(fittedClockFormat(format, value, exemplar)).toEqual(expected);
|
|
});
|
|
|
|
it("trims a sibling clock spelled alike unless its own value shows a fixed width", () => {
|
|
expect(
|
|
trimmedLike(iso("T", 9, "Z"), TRIMMED_9, "2026-03-04T05:06:07.123456789Z"),
|
|
).toEqual(TRIMMED_9);
|
|
expect(
|
|
trimmedLike(iso("T", 9, "Z"), TRIMMED_9, "2026-03-04T05:06:07.123456780Z"),
|
|
).toEqual(iso("T", 9, "Z"));
|
|
expect(
|
|
trimmedLike(iso(" ", 9, "Z"), TRIMMED_9, "2026-03-04 05:06:07.123456789Z"),
|
|
).toEqual(iso(" ", 9, "Z"));
|
|
});
|
|
|
|
it.each<[JsonValue, string, string | undefined]>([
|
|
["2026-03-04T05:06:07.123Z", "YYYYMMDDhhmmss", "20260304050607"],
|
|
["2026-03-04T05:06:07Z", "YYYYMMDD", "20260304"],
|
|
["2026-03-04T23:30:00-05:00", "YYYY-MM-DD", "2026-03-04"],
|
|
[WITH_MS, "YYYY/MM/DD", "2026/03/04"],
|
|
["not a clock", "YYYYMMDD", undefined],
|
|
])("spells the clock %j's wall clock in %s", (value, pattern, expected) => {
|
|
expect(clockDigits(value, pattern as Parameters<typeof clockDigits>[1])).toBe(
|
|
expected,
|
|
);
|
|
});
|