Files
reverse-engineering-anything/src/domain/analysisView/environmentStateWriteReferences.test.ts
T
aba487eec0 feat(environment): learn creates from every call, with sorted arrays and referenced entities (#7034)
* 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>

* feat(environment): learn a create plan from every call

A later create the plan does not take is explained on its own and merged when both calls show the same fields, every field both rule they rule alike, and a field neither rules holds one value: members either call sent are accepted, only those every call sent are required, and an echoed member a call left out takes the value that call stored, kept in the body's defaults.

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

* feat(environment): sorted arrays, referenced entities and nested view keys

- An echo is `sorted` when the application stored the sent strings in
  code-point order; serving stores them sorted, and a plain echo and a
  sorted one agree in update and create plans.
- A `reference` is an object field holding fields of the entity a sent
  member names, as the state holds it. The member is accepted with any
  value; replay and serving look the entity up, and serving refuses a call
  naming one the environment does not hold.
- A view names in `nested_fields` the keys it always shows of objects it
  shows with fewer keys than an entity stores; a stored object it never
  recorded renders with them. The view spelling learner moves to its own
  module.
- Every later create, not only one the plan refuses, is merged into its
  plan when it agrees, keeping the plan's rule order.

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>

* docs(environment): record the create-calls verification

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

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

* docs(environment): note the create-calls census on current main

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>

* fix(environment): keep optional references across create calls and in answers

- A reference a later create added stays while further creates leave its
  member out, and agrees with a later call that shows it again.
- A create's answer shows optional reference and echo fields only when the
  call wrote them, whichever recorded call the answer came from.
- An update that re-sends the id of the entity a field already repeats keeps
  the plan's reference instead of pinning the member.
- An id naming entities of one type in several collections teaches no
  reference, and serving or replay refuses a call that names one.
- An echo is not promoted to sorted once a call stored its strings out of
  code-point order as sent.
- Nested view keys compare as sets and keep the first recording's order.

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): respect earlier clock widths and left-out members in later creates

- The create merge widens a clock to trimmed only against the value that
  showed its width: a held entity or accepted call at a fixed width keeps it
  untrimmed.
- A later create that left out a member the plan fills, with a default or a
  reference's absence, while its observation shows that field otherwise is
  unexplained-change, so the plan cannot serve the stale value.

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

* fix(environment): reject contradictory create references

---------

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

187 lines
6.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
timedCaptureEvidence,
type TimedCaptureRow,
} from "../../../tests/fixtures/analysisView.js";
import {
FILED_ROWS,
REFILED_ROWS,
TAGGED_ROWS,
} from "../../../tests/fixtures/environmentStateDerivedValues.js";
import { environmentStateViewOf } from "../../../tests/fixtures/environmentStateWrites.js";
import type { StateEntity } from "./environmentStateRules.js";
import { ClockSpellings } from "./environmentStateViewSpellings.js";
import { alikeRules, type FieldRule } from "./environmentStateWriteRules.js";
import {
referenceRule,
referencedValue,
} from "./environmentStateWriteReferences.js";
const SHELF = { id: 2, name: "Map Room", floor: "upper" };
const held = (
type: string,
id: string,
fields: StateEntity["fields"],
): StateEntity => ({
type,
collection: type,
id,
fields,
view_fields: [],
record_ordinals: [],
});
describe("objects that repeat the entity a member names", () => {
it("serves creates that embed the named shelf, and lists show it with the keys they list", () => {
const view = environmentStateViewOf(timedCaptureEvidence(FILED_ROWS));
expect(
view.writes.find((plan) => plan.tool === "post_books"),
).toMatchObject({
served: true,
body: { accepted: expect.arrayContaining(["name", "shelf_id"]) },
rules: expect.arrayContaining([
{
field: "shelf",
rule: "reference",
member: "shelf_id",
type: "/api/shelves",
fields: ["id", "name", "floor"],
},
]),
});
expect(
view.views.find((candidate) => candidate.tool === "get_books"),
).toMatchObject({
nested_fields: { shelf: ["id", "name"] },
});
});
it("learns the keys a view shows of a shelf in whatever order each object gives them, keeping the first order", () => {
const spellings = new ClockSpellings(() => undefined);
spellings.note({ shelf: SHELF }, { shelf: { id: 2, name: "Map Room" } });
spellings.note({ shelf: SHELF }, { shelf: { name: "Map Room", id: 2 } });
expect(spellings.view).toEqual({
nested_fields: { shelf: ["id", "name"] },
});
spellings.note({ shelf: SHELF }, { shelf: { id: 2 } });
expect(spellings.view).toEqual({});
});
it("serves updates that keep a shelf a later call names again", () => {
const view = environmentStateViewOf(timedCaptureEvidence(REFILED_ROWS));
expect(view.writes.find((plan) => plan.effect === "update")).toMatchObject({
served: true,
body: { accepted: expect.arrayContaining(["name", "shelf_id"]) },
rules: expect.arrayContaining([
expect.objectContaining({ field: "shelf", rule: "reference" }),
]),
});
});
it("names the member whose entity the object repeats, the one named like the field when several do", () => {
const named = (id: string) =>
id === "2"
? [held("/api/shelves", "2", SHELF), held("/api/rooms", "2", SHELF)]
: [];
expect(
referenceRule("shelf", SHELF, { shelf_id: 2 }, named),
).toBeUndefined();
const shelves = (id: string) =>
id === "2" ? [held("/api/shelves", "2", SHELF)] : [];
expect(
referenceRule("shelf", SHELF, { shelf_id: 2, room_id: 2 }, shelves),
).toMatchObject({ member: "shelf_id", type: "/api/shelves" });
expect(
referenceRule("shelf", { id: 2 }, { shelf_id: 2 }, shelves),
).toBeUndefined();
// One id naming a shelf in two collections names neither.
expect(
referenceRule("shelf", SHELF, { shelf_id: 2 }, (id) =>
id === "2"
? [
held("/api/shelves", "2", SHELF),
{ ...held("/api/shelves", "2", SHELF), collection: "/api/annex" },
]
: [],
),
).toBeUndefined();
expect(
referenceRule(
"shelf",
{ ...SHELF, floor: "lower" },
{ shelf_id: 2 },
shelves,
),
).toBeUndefined();
});
it("refuses a call naming an entity the environment does not hold, or holds in several collections", () => {
const rule: Extract<FieldRule, { rule: "reference" }> = {
field: "shelf",
rule: "reference",
member: "shelf_id",
type: "/api/shelves",
fields: ["id", "name"],
};
expect(referencedValue(rule, { shelf_id: 9 }, () => [])).toMatchObject({
ok: false,
});
expect(referencedValue(rule, {}, () => [])).toEqual({
ok: true,
value: undefined,
});
expect(referencedValue(rule, { shelf_id: 2 }, () => [SHELF])).toEqual({
ok: true,
value: { id: 2, name: "Map Room" },
});
expect(
referencedValue(rule, { shelf_id: 2 }, () => [SHELF, SHELF]),
).toMatchObject({
ok: false,
error: expect.stringContaining("2 collections"),
});
});
});
describe("arrays an application stores sorted", () => {
it("does not sort tags an earlier create stored out of order as sent", () => {
const kept = TAGGED_ROWS.map((row, index): TimedCaptureRow => {
if (index !== 2 && index !== 3) return row;
const [method, path, response, ...rest] = row;
return [
method,
path,
{ ...(response as object), tags: ["zoning", "maps"] },
...rest,
];
});
const plan = environmentStateViewOf(timedCaptureEvidence(kept)).writes.find(
(candidate) => candidate.tool === "post_books",
);
expect(plan?.rules).toContainEqual({ field: "tags", rule: "echo" });
expect(plan).toMatchObject({ served: false });
});
it("keeps an echo sorted only while no call kept its strings out of order", () => {
const plain: FieldRule = { field: "tags", rule: "echo" };
const sorted: FieldRule = { field: "tags", rule: "echo", sorted: true };
expect(alikeRules(plain, sorted)).toEqual(sorted);
expect(alikeRules(sorted, plain)).toEqual(sorted);
expect(alikeRules(plain, sorted, new Set(["tags"]))).toBeUndefined();
expect(alikeRules(sorted, plain, new Set(["tags"]))).toBeUndefined();
});
it("serves creates that store sent tags in code-point order", () => {
const view = environmentStateViewOf(timedCaptureEvidence(TAGGED_ROWS));
expect(
view.writes.find((plan) => plan.tool === "post_books"),
).toMatchObject({
served: true,
rules: expect.arrayContaining([
{ field: "tags", rule: "echo", sorted: true },
]),
});
});
});