Docs: the context-pack map (2026-10-08)
Body facts, model page and rationale for the context-pack cuts in eureka-substrate. The cut specs are the typed record in the mind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
95d7f67c38
commit
776cc54ccd
1 changed files with 363 additions and 0 deletions
363
docs/context-pack-map.md
Normal file
363
docs/context-pack-map.md
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
# Context pack: map (eureka-substrate, 2026-10-08)
|
||||
|
||||
Imagination pass `imagination-context-pack`, session `self-2026-10-08`, for
|
||||
ruling `eureka-substrate:ruling:context-pack-resolving-anchors`. Evidence:
|
||||
`F:\Projects\eureka-toolcall-patterns-2026-10-08.md` (Eyes facts) and
|
||||
`F:\Projects\eureka-context-pack-prior-art-2026-10-08.md` (prior art).
|
||||
The cut_specs and the question are the typed record; this page holds body
|
||||
facts, the model page and rationale only.
|
||||
|
||||
Pinned heads: Eureka main `0bb414d92728db61d2d587d749c94970ed2e5582` (also the
|
||||
head of `hands/toolcall-relief`, whose changes are uncommitted in
|
||||
`C:\eureka-toolcalls`); CultLib `05e67014`; Huginn `6b496eba`; Epiphany
|
||||
`4006b14b`; Aetheria `e75083fe`.
|
||||
|
||||
## Body facts
|
||||
|
||||
Scratch: `C:\Users\Meta\AppData\Local\Temp\claude\F--Projects-CultLib\8ee3cab1-a20c-498d-a46b-e503a25ac030\scratchpad\cp\`
|
||||
(`anchor-map.sh` prototype, `mindview.py`, `mindq.py`, `drift.py`, `all.json`).
|
||||
This scratchpad is volatile; Hands re-derives from the specs, not from it.
|
||||
|
||||
B1. Diff-hunk line mapping resolves a (base, path, start, end) anchor onto any
|
||||
later tree with git alone. Prototype `anchor-map.sh` parses `git diff -U0
|
||||
<base> <target> -- <path>` hunk headers: hunks wholly before the range shift it
|
||||
(MOVED), a hunk overlapping it marks it TOUCHED and widens the range by its net
|
||||
lines, no hunk is SAME; `git diff -M --name-status` gives rename (RENAMED) and
|
||||
delete (GONE). Target may be a commit or the working tree (`git diff <base>`
|
||||
with no second commit). Dependencies: git and awk; no ctags, rg or tree-sitter.
|
||||
|
||||
B2. Real spec, real drift: `cultmath-tapes:cut_spec:cut-affine-shaders.r2`
|
||||
(base `a7966142`) mapped onto `05150acd` (the merge the affine-shaders Hands
|
||||
started from). Result: `CultMath.hlsl:509-510` MOVED to 510-511 (the same two
|
||||
`#include` lines, checked by `git show`); `GlslMirrorTests.cs:317-319` TOUCHED,
|
||||
mapped to 336-340, which is the end of `Families` with snoise-tie's two new
|
||||
families inside it (checked); five anchors SAME. The spec's own prose carried
|
||||
the workaround: "(GlslMirrorTests.cs:317-319 at a7966142; the lines move with
|
||||
the merge)". `cut-huginn-persona-state.r2` carries another: "Hands re-takes the
|
||||
anchor at the merged 13a/13b tip".
|
||||
|
||||
B3. Anchor accuracy at base: the four affine-shaders anchors read at
|
||||
`a7966142` show exactly the code each `change` names
|
||||
(`cultmath_iv_snoise_ball(float3, float)` at Interval.hlsl:83-89, the
|
||||
`InlineData` list at HlslMirrorTests.cs:64-68, the presence asserts at
|
||||
HlslSourceCompatibilityTests.cs:34-35, the Interval.hlsl lines in
|
||||
build-unity-package.ps1:86-87). Imagination's line numbers are right at base;
|
||||
what goes wrong is drift.
|
||||
|
||||
B4. Drift across the whole mind (`drift.py` over `all.json`: 203 cut_specs,
|
||||
143 cut_reports, 1,260 file_changes). For every spec with a report and a local
|
||||
repo, each file_change was mapped from `spec.base` to the first report's
|
||||
`range.base`, the tree Hands started on. 557 anchors: SAME 444 (79.7%),
|
||||
MOVED 64 (11.5%), TOUCHED 17 (3.1%), path absent at base 32 (5.7%). All 32
|
||||
absent paths exist at the report head: they anchor files the cut creates
|
||||
(none were typos). No base was unreachable. By repo: gamecult-site 55 of 125
|
||||
drifted (44%), CultLib 17 of 245, Aetheria 5 of 127, Idunn 3 of 24, Bifrost 1
|
||||
of 19, Epiphany, gamecult-ops and Huginn none. So about one anchor in seven was
|
||||
stale when Hands first read it, concentrated in campaigns whose cuts land in
|
||||
parallel.
|
||||
|
||||
B5. Worktree, rename, delete and failure probes (scratch clone of Eureka at
|
||||
`0bb414d`): two lines inserted at 100 and line 185 edited, uncommitted:
|
||||
`briefs.md:50-60` SAME, `180-190` TOUCHED to 182-192, `300-310` MOVED to
|
||||
302-312. A staged `git mv` reads SAME+RENAMED; a staged `git rm` reads GONE.
|
||||
Unreachable base prints `UNRESOLVED base <sha> not in this clone: git fetch
|
||||
origin <sha>`; path absent at base prints `UNRESOLVED <path> absent at base`.
|
||||
Limit: an unstaged delete plus an untracked new file is not detected as a
|
||||
rename (git's rename detection needs both sides in the index or a commit).
|
||||
Windows Git Bash prints an LF/CRLF warning per diff on stderr; the tool must
|
||||
discard stderr of these calls. Line numbers are unaffected by CRLF.
|
||||
|
||||
B6. Cost: rename detection over a whole tree takes about 0.5-1 s per call on
|
||||
Aetheria (`git diff -M --name-status`), so the drift script, which ran it per
|
||||
anchor, took over 10 minutes for 557 anchors. The tool runs it once per
|
||||
invocation and one `-U0` diff per distinct path.
|
||||
|
||||
B7. Symbol by name alone is not an identity. `git grep -W` with git's csharp
|
||||
driver (supplied without touching the repo through `git -c
|
||||
core.attributesFile=<file>`) prints the whole enclosing function, but the
|
||||
probe name `Dispose` matched several members in one file
|
||||
(`CultMeshContentSessions.cs`), and a bare name has no namespace. A symbol is
|
||||
usable as a check that the resolved window contains it, and as the key for a
|
||||
caller list, not as the anchor itself. Git's built-in funcname drivers cover
|
||||
csharp, rust, python, kotlin and cpp (usable for HLSL/GLSL), and none covers
|
||||
TypeScript.
|
||||
|
||||
B8. Tool availability. Starfire: Exuberant Ctags 5.8 (Strawberry Perl; no
|
||||
TypeScript, Kotlin or HLSL), rg (Codex's copy), no tree-sitter, Python 3.13
|
||||
via `py -3` (no `tree_sitter` module), git 2.53, gawk, perl. Yggdrasil host:
|
||||
git 2.47, python3, awk, perl; no ctags, no rg. So git plus the Python standard
|
||||
library is the only toolset common to both.
|
||||
|
||||
B9. Caller lists: `git grep -n -w -F <symbol>` takes about 0.4-0.6 s on CultLib
|
||||
and Aetheria. `cultmath_iv_snoise_ball` has 20 hits in 8 files, including docs
|
||||
and fixtures. `Dispose` has 386 hits, so a caller list needs a cap, and above
|
||||
the cap it needs per-file counts rather than lines (SWE-agent: more than 50
|
||||
results returns none and asks for a narrower query).
|
||||
|
||||
B10. Unity YAML: across the three most-modified Aetheria prefabs, fileIDs
|
||||
(`--- !u!<class> &<id>`) are unique within each file and survive edits
|
||||
(Djinni.prefab at 122e9292: 440 of 446 ids shared across a 91-hunk commit;
|
||||
Inventory 116 of 116; Longinus 107 of 107). Diff-hunk mapping works on YAML
|
||||
as on code. `&<fileID>` is a good symbol for a YAML anchor.
|
||||
|
||||
B11. The spec can be read without the model copying it. `mindview.py` spawns
|
||||
`~/.eureka/bin/eureka-state.exe` (the binding in `~/.claude.json`
|
||||
`mcpServers.eureka-state`: command plus `EUREKA_INSTANCE` and
|
||||
`HUGINN_ENDPOINT`), speaks MCP JSON-RPC over stdio (initialize, initialized,
|
||||
tools/call view) and prints the document, in 1.3 s. eureka-state has no CLI
|
||||
mode of its own (`crates/eureka-state/src/main.rs:298`, stdio MCP only).
|
||||
|
||||
B12. Schema facts for a typed home. `CodeLocation { path: Short, line: u32,
|
||||
end_line: Option<u32> }` (Epiphany `epiphany-pipeline/src/lib.rs:463`) is
|
||||
shared by cut_spec file_changes, finding and follow_up locations, and mutation
|
||||
records. The epoch doc (`lib.rs:879-886`) says evolution is additive at
|
||||
`epiphany.pipeline.epoch.v2`: "a new named field with a serde default". No
|
||||
`#[serde(default)]` exists in the leaf yet, so the `value_types!` macro has
|
||||
never carried one. Huginn pins the leaf by git rev
|
||||
(`crates/huginn-mind/Cargo.toml:22`, `ef956865`), so a field reaches the mind
|
||||
only after a leaf change, a Huginn re-pin and a daemon plus eureka-state
|
||||
redeploy.
|
||||
|
||||
B13. The Hands brief already asks for a hand-made pack: "Orient in one script.
|
||||
One Bash call prints git status, the base and the spec's anchor ranges (`sed
|
||||
-n`)" (briefs.md:276-278 at 0bb414d). That reads the frozen line numbers, so it
|
||||
reads the wrong lines for the one anchor in seven that has drifted (B4).
|
||||
|
||||
B14. Prose `path:line` references in spec text (first, adds, keeps_moves,
|
||||
change): 224 across 99 of 203 specs. Imagination already writes read anchors
|
||||
inline, untyped (for example "as iv_frustum_ball's FrustumBall check
|
||||
(GlslMirrorTests.cs:191) does").
|
||||
|
||||
## Model page
|
||||
|
||||
| Kind | Identity | Lifecycle | Authority |
|
||||
|---|---|---|---|
|
||||
| Edit anchor | `(cut_spec id, file_changes index)`; content `(spec.repo, spec.base, path, line, end_line)`. Namespace: the spec's repo at its base commit, which is injective: one path and range at one commit. A short `base` is resolved with `git rev-parse --verify <base>^{commit}`, and ambiguity is a loud failure. | Created with a spec revision and immutable. Changed only by revision N+1 with a superseding resolution. Its position at a later tree is derived at read time, never stored. A path absent at base is a file the cut creates (B4); it belongs in `adds`, and the tool reports it as NEW. | Imagination writes it (admits the spec). Hands and the tool never rewrite it. A wrong anchor is a deviation in Hands' report and a revision by Imagination. |
|
||||
| Read anchor (code to see, not to change) | **Empty cell.** It has no typed home. Today it is prose `path:line` (B14) with no namespace (basenames), no base and no check. | None: it is not a document. | None. This is question `context-pack-read-anchors`. |
|
||||
| Symbol (a check and a caller key) | **Empty cell.** A name is not injective (B7). Its only sound role is a needle that the resolved window must contain, plus a caller-list key. | Would be the anchor's. | Same question. |
|
||||
| Resolved anchor and window (the expanded pack) | `(spec id, worktree HEAD, working-tree state)`. Derived and never persisted. | Printed into Hands' context. Stale once Hands edits inside it, and re-expanded for edited anchors only with `--since <start sha>`. No cache, no pack file. | `tools/context-pack.py` derives it. Nothing stores it. A stored pack would be a cache pretending to be truth. |
|
||||
| The reader tool | `tools/context-pack.py` in GameCult/Eureka. | Lands by Forgejo PR after a Soul pass. Pruned when no brief names it (tools/INDEX.md rule). | Eureka repo. Owns "what Hands sees of a spec's anchors at its tree". It does not own anchors and does not write the mind. |
|
||||
| Measurement baseline | The Eyes report above and its scripts (`cls.py`, `an2/an3/an4.py`) under this session's scratchpad `eyes-toolcalls\`. | **Volatile.** The scratchpad is session-scoped, so the scripts can vanish before the re-measure. | Self (follow_up `context-pack-measurement`). |
|
||||
|
||||
## Rationale
|
||||
|
||||
**Anchor grammar: base-pinned line range, resolved by diff-hunk mapping.** The
|
||||
candidates were: symbol paths (`File::Type.Member`), git funcname (`git grep
|
||||
-W`, `git log -L :fn:file`), ctags, tree-sitter queries, LSP document symbols,
|
||||
and a text needle plus line hint. Every one of them except the line range needs
|
||||
a per-language parser, and most need a dependency that is missing on Yggdrasil
|
||||
or on both hosts (B8). Unity YAML has no symbol grammar in any of them, and a
|
||||
bare symbol name is not injective (B7). The spec already pins a full
|
||||
coordinate, `spec.base` plus `path:line-end_line`, and git can carry that
|
||||
coordinate onto any later tree, the working tree included (B1, B5). This is
|
||||
the way Gerrit ports review comments across patch sets and GitHub marks a
|
||||
comment outdated: the anchor is stored where it was made, and diffs carry it
|
||||
forward. It is language-agnostic, needs only git, and fails loudly on every
|
||||
path that cannot be carried (base unreachable, path absent, range past EOF,
|
||||
file deleted). One anchor in seven needed carrying in practice (B4), and the
|
||||
`sed -n` orient step reads those wrong today (B13).
|
||||
|
||||
**Why the edit anchors are the v1 pack.** file_changes already hold the
|
||||
planner's localization at base, accurate when mapped (B3), which is
|
||||
Agentless's and ORACLE-SWE's edit-location handoff. The tool turns them into
|
||||
SWE-agent-shaped output: one status table first (lost-in-the-middle: the
|
||||
summary at the top), then windows of at most 100 lines (the SWE-agent ablation
|
||||
optimum; full-file views lost 5.3 points), then caller lists capped at 50
|
||||
lines with per-file counts beyond that (the iterative per-hit search lost 6
|
||||
points). An output cap keeps the pack from becoming the 20%-more-steps
|
||||
AGENTS.md overview (Gloaguen et al.). Re-expansion with `--since` answers the
|
||||
re-read finding (54%, 1,198 repeats with no edit in between): the edited
|
||||
windows come back fresh and nothing else is reprinted, as in SWE-agent's
|
||||
viewer auto-refresh and CORVUS's current-contents registry.
|
||||
|
||||
**Why read anchors and symbols are a question rather than a cut.** Three homes
|
||||
exist: a typed field (an additive `CodeLocation.symbol` and a `reads` list on
|
||||
cut_spec, three passes across Epiphany, Huginn plus a deploy, and Eureka, B12);
|
||||
a `Pack:` line convention in `first` (free, but structure carried in prose);
|
||||
or a sidecar pack file. The sidecar was rejected outright: it is a second store
|
||||
with its own lifecycle that goes stale the day a spec is revised. Which of the
|
||||
first two, and whether now or after measuring v1, decides schema work in the
|
||||
mind's own leaf. The question records options, evidence and a recommendation.
|
||||
Nothing in cuts context-pack-tool and context-pack-briefs depends on the
|
||||
answer.
|
||||
|
||||
**Base for the Eureka cuts.** Both cuts edit `tools/test-tools.sh` and
|
||||
`references/briefs.md`, which `hands/toolcall-relief` is changing (uncommitted
|
||||
in `C:\eureka-toolcalls`; its branch head equals main `0bb414d`). The specs pin
|
||||
`base 0bb414d` and anchor at it. Hands starts from main after that PR merges,
|
||||
and the first thing context-pack-briefs does is resolve its own briefs.md
|
||||
anchors through the tool that context-pack-tool lands (the +39 lines shift
|
||||
them). If the PR has not merged, Hands stops.
|
||||
|
||||
**Subtraction.** Removed: the Hands orient step's `sed -n` of frozen ranges
|
||||
(briefs.md:276-278) and the "reading a file twice is a smell" advice that the
|
||||
tool replaces. Imagination's prose drift notes ("the lines move with the
|
||||
merge", "re-take the anchor") are no longer needed and the map brief says so.
|
||||
Not added: a parser per language, a cache, a pack file, or a mind field.
|
||||
|
||||
## Read anchors and symbols in the schema (2026-10-08, imagination-read-anchors)
|
||||
|
||||
Imagination pass `imagination-read-anchors`, session `self-2026-10-08`, for
|
||||
operator ruling `eureka-substrate:ruling:context-pack-read-anchors`
|
||||
(typed-fields-now). Cuts: `leaf-read-anchors` (Epiphany), `huginn-read-anchors`
|
||||
(Huginn), `ops-read-anchors-upgrade` (gamecult-ops), `context-pack-reads`
|
||||
(Eureka). Pinned heads: Epiphany origin/main `ef9568655e75bb6cb362a038e2739a5ac5e777ee`
|
||||
(the rev Huginn pins; the local `F:\Projects\Epiphany` main is behind it at
|
||||
`2bf39eef`), Huginn main `6b496eba8c8cfde7b93bb8bc46b1961abca52fd4`,
|
||||
gamecult-ops main `7e233877dfb21f75d5bbe994641781f718098eac`, Eureka main
|
||||
`0bb414d92728db61d2d587d749c94970ed2e5582`. Probes ran in detached worktrees
|
||||
under this session's scratchpad `ra\`, removed afterwards.
|
||||
|
||||
### Body facts
|
||||
|
||||
B15. Stored payload encoding. `PipelineDocument::prepare` calls CultLib
|
||||
`prepare_entry_named` (cultcache-rs at `8fc74c7`, `lib.rs:2244-2259`), which is
|
||||
`rmp_serde::to_vec_named`: every value struct is a MessagePack map keyed by
|
||||
field name. `decode` is `rmp_serde::from_slice` (leaf `lib.rs:745-751`). No
|
||||
`deny_unknown_fields` exists in the leaf. Consequences: (a) an old document
|
||||
lacking a new key decodes when the field is `Option` or carries
|
||||
`#[serde(default)]`; (b) an old daemon reading a new document ignores the
|
||||
unknown key, so after a rollback it serves such documents without the field
|
||||
while the stored bytes keep it.
|
||||
|
||||
B16. Re-encoding is load-bearing. Admission prepares every write afresh
|
||||
(`admission.rs:143-157`) and the receipt digest is over those payloads
|
||||
(`receipt.rs:123-126`); A9 compares it with stored receipts to answer
|
||||
`AlreadyAdmitted` (`admission.rs:164-166`). So if a document without the new
|
||||
fields encoded differently after the change (for example `symbol: null` or
|
||||
`reads: []` written out), replaying any pre-upgrade batch would stop answering
|
||||
`AlreadyAdmitted`, and target invariant `stored-documents-valid` ("No change
|
||||
re-keys, re-encodes or invalidates a document already in the mind") would
|
||||
break. Hence `skip_serializing_if` on both fields, not only `serde(default)`.
|
||||
|
||||
B17. The macro. `value_types!` (`lib.rs:415-436`) emits a struct whose fields
|
||||
carry only an optional `#[schemars(extend("maxItems"))]`; it has no way to put
|
||||
a serde attribute on a field. `Bounded for Option<T>` exists (`lib.rs:79-83`);
|
||||
`Vec` is validated only through the `[max]` list form (`list`, `lib.rs:110`).
|
||||
`=> extra` is a struct-level validation hook (`campaign_repos_are_distinct`,
|
||||
`lib.rs:452-468`). Refusal variants are pinned at five by the schema test
|
||||
(`lib.rs:2717`), so new bounds must reuse `FieldBound` and `InvalidFormat`.
|
||||
|
||||
B18. Who constructs the changed structs. Epiphany: `CodeLocation {` 3 sites and
|
||||
`PipelineCutSpec {` 1 test sample, all in `lib.rs`; no other Epiphany crate
|
||||
builds them. Huginn: `CodeLocation {` in `huginn-mind/src/fixtures.rs:88`,
|
||||
`huginn-daemon/src/daemon.rs:360`, `eureka-state/tests/client.rs:59`;
|
||||
`PipelineCutSpec {` in `fixtures.rs:192`, `daemon.rs:361`, `client.rs:44`
|
||||
(`admission.rs:432` uses `..spec.clone()` and needs no edit). Published schemas
|
||||
that embed `CodeLocation`: Epiphany `schemas/cultnet/epiphany.pipeline.{cut_spec,cut_report,finding,follow_up}.v2.schema.json`;
|
||||
Huginn `schemas/cultnet/huginn.mind_{request,response}.v1.schema.json`, pinned
|
||||
byte for byte by `wire.rs:276-280`. The leaf's own check is
|
||||
`pipeline_published_schemas_match_derivation` (`lib.rs:2723`), which writes the
|
||||
derived copies to a temp dir on failure.
|
||||
|
||||
B19. Size calibration. `daemon.rs:349-356`'s `cut_spec` claims "every list the
|
||||
leaf bounds filled to its maximum"; `client.rs:220-236` calibrates `fits` (180
|
||||
file changes) under `MAX_RESPONSE_BYTES` and `wide` (256) over it. Filling the
|
||||
new fields in the daemon builder keeps its claim true; filling them in the
|
||||
client builder would move the calibration.
|
||||
|
||||
B20. Admission has no tree. Huginn holds no repository checkout; admission
|
||||
checks bounds, formats, keys and cross-document rules only. "The symbol is in
|
||||
the window at base" cannot be an admission rule. Its owner is the reader tool,
|
||||
run by Imagination at base after admitting (cut context-pack-briefs) and by
|
||||
Hands at its tree.
|
||||
|
||||
B21. Index text. `huginn-mind/src/index.rs:42-70` indexes a cut_spec's title,
|
||||
first, adds and keeps_moves only, not file_changes. Leaving `reads` out keeps
|
||||
the index text unchanged, so no reindex follows the upgrade.
|
||||
|
||||
B22. Deploy owner. Huginn is not an Idunn target: `runbooks/huginn-yggdrasil.md`
|
||||
(gamecult-ops) calls it "an interim deployment: a hand-installed systemd unit",
|
||||
retired by Idunn only in Huginn's 14-I, and says "No brake gates deployment of
|
||||
this unit". Target r2 names the same runbook as the deploy's canonical
|
||||
implementation. The live release is `releases/107552dc4b27b8856b043616ae74c2ebe7908b66`
|
||||
(read-only `readlink` on Yggdrasil, unit active); Huginn main since then changes
|
||||
docs only (`git diff --stat 107552dc..6b496eba -- crates Cargo.toml Cargo.lock`
|
||||
is empty). The client is `C:\Users\Meta\.eureka\bin\eureka-state.exe`, whose
|
||||
MCP `admit` input schema is derived at run time from the leaf types through
|
||||
schemars (`eureka-state/src/main.rs:73`), so a rebuilt client publishes the new
|
||||
fields with no hand edit; an agent session sees them only after it starts
|
||||
anew. The runbook's rollback paragraph (`:109-113`) is specific to the 64-byte
|
||||
key widening.
|
||||
|
||||
B23. The harvest. Target r2's canonical implementations put the leaf at Huginn
|
||||
`crates/eureka-pipeline`, and Huginn `docs/eureka-self-cut.md:435` (harvest H1)
|
||||
copies it there "from Epiphany head `4006b14b`", which is 5 commits behind
|
||||
`ef956865`. H1 has no cut_spec yet (eureka-body has only questions and
|
||||
rulings). If H1 copied from `4006b14b` after this change merges, it would drop
|
||||
both leaf-key-bound and the new fields.
|
||||
|
||||
### Rationale
|
||||
|
||||
**Where the fields land.** The leaf still lives in Epiphany and Huginn pins it
|
||||
by git rev, so the field goes into Epiphany's leaf, then Huginn re-pins, as the
|
||||
ruling's option text names. Waiting for H1 would make this one Huginn cut
|
||||
instead of two, but H1 is unscheduled. The operator accepted the three-pass
|
||||
cost in her words. Follow-up `leaf-harvest-copies-head` records the constraint
|
||||
on H1. If H1 merges before `leaf-read-anchors` starts, Self stops the cut and
|
||||
Imagination re-maps it onto `crates/eureka-pipeline` (one Huginn cut, no
|
||||
re-pin).
|
||||
|
||||
**Shape.** `CodeLocation.symbol: Option<Symbol>` everywhere a location is (file
|
||||
changes, findings, follow-ups, mutations). It means the same thing in every
|
||||
one: a name the location's lines must contain. `PipelineCutSpec.reads:
|
||||
Vec<ReadAnchor>[16]` with `ReadAnchor { location: CodeLocation, why: Short }`.
|
||||
It is a distinct type, not `FileChange`, because a read changes nothing and a
|
||||
field named `change` would lie. Reads are in the spec's repo at its base, like
|
||||
file_changes. A read in another repo stays prose in `first`, because a read
|
||||
cannot pin another repo's commit. `Symbol` is a new bounded text: 1-128 bytes,
|
||||
no whitespace or control character. It is new, so no stored document can fail
|
||||
it. A read's window is bounded by an `=> extra` hook on `ReadAnchor`: `line >=
|
||||
1`, `end_line >= line` (`InvalidFormat`), and span at most 100 lines
|
||||
(`FieldBound`, limit 100). 100 is the window cap the tool already uses. No new
|
||||
bound touches `CodeLocation`'s existing fields, because stored findings would
|
||||
then stop validating.
|
||||
|
||||
**The macro owns "additive".** `value_types!` gains a per-field marker written
|
||||
after the type and any list maximum, for example `symbol: Option<Symbol> =
|
||||
absent` and `reads: Vec<ReadAnchor>[16] = absent`. It emits
|
||||
`#[serde(default, skip_serializing_if = "Absent::absent")]`. Trait `Absent` is
|
||||
implemented for `Option<T>` and `Vec<T>` only, and the validate expansion
|
||||
names `<$ty as Absent>::$marker`, so a marker word other than `absent`, or the
|
||||
marker on any other type, is a compile error. The epoch doc and the schemas
|
||||
README then say this marker is how a field is added at v2. This replaces the
|
||||
hope that every future author remembers both attributes (B16).
|
||||
|
||||
**No admission rule in Huginn.** Bounds are the leaf's, and Huginn applies them
|
||||
through `validate` on every write. The symbol-in-window check needs a tree
|
||||
(B20) and belongs to `context-pack.py`, which exits nonzero on
|
||||
`SYMBOL_MISSING`.
|
||||
|
||||
**Deploy.** The owner is the gamecult-ops runbook's Upgrade section. It is not
|
||||
Idunn: Idunn does not own this unit, and no brake applies (B22). The ops cut
|
||||
generalises the rollback paragraph for additive fields and then executes the
|
||||
Upgrade steps. One addition: the read-back test also asserts that every stored
|
||||
document re-prepares to its stored payload bytes. That checks B16 on the live
|
||||
mind, not only in a unit test.
|
||||
|
||||
**Eureka.** One new cut after both v1 cuts and the deploy. The v1 specs stay as
|
||||
they are, because v1 must not wait on the deploy.
|
||||
|
||||
**Subtraction.** Removed: prose `path:line` read references in specs for the
|
||||
spec's own repo (224 today, B14), replaced by checked reads; Imagination's
|
||||
"re-take the anchor" notes; Hands' first-pass grep for callers of named
|
||||
symbols. Added: one trait, one text type, one struct, one macro marker, two
|
||||
fields, one tool section. Not added: an admission rule, a Huginn type, an
|
||||
index change, or a second store.
|
||||
|
||||
B24. The admit door drops unknown keys silently. The batch that admitted these
|
||||
specs had one file_change location with a stray `"symbol": null`. It was
|
||||
admitted as Committed (receipt `mind-commit-c528cc24...`), and a view of
|
||||
`cut-context-pack-reads.r1` shows that location without the key. This is B15(b)
|
||||
at the JSON door: a session that started before the client swap will drop
|
||||
`reads` and `symbol` and still report success. Follow-up
|
||||
`gap-admit-drops-unknown-keys` (owner: Huginn eureka-state). Meanwhile the ops
|
||||
cut makes agents restart, and context-pack-reads stops if its admit schema
|
||||
lacks `reads`.
|
||||
|
||||
Admitted (receipts `mind-commit-c528cc24...`, `mind-commit-5d97a6ad...`):
|
||||
`eureka-substrate:cut_spec:cut-leaf-read-anchors.r1`,
|
||||
`cut-huginn-read-anchors.r1`, `cut-ops-read-anchors-upgrade.r1`,
|
||||
`cut-context-pack-reads.r1`; follow-ups `leaf-harvest-copies-head` and
|
||||
`gap-admit-drops-unknown-keys`. Order: leaf, then Huginn, then ops (deploy),
|
||||
then Eureka. The Eureka cut also waits for both v1 cuts.
|
||||
Loading…
Reference in a new issue