Skip to content

One door into the queue, and the dead promotion path deleted - #27

Open
leeovery wants to merge 5 commits into
fix3/e7-digestfrom
fix3/e8-admission
Open

One door into the queue, and the dead promotion path deleted#27
leeovery wants to merge 5 commits into
fix3/e7-digestfrom
fix3/e8-admission

Conversation

@leeovery

@leeovery leeovery commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Harvest is judgment; the machinery for judgment-free promotion goes.

  • Result.children, Child, _admit_children, via: "thread" deleted — no driver ever produced them; link promotion flows through enrich fetch, where a session applies the subject rule
  • Three admission paths collapsed into one (_Drain.admit: canonicalize → dedupe → provenance → caps → record); corpus seeding and enrich fetch supply only their policies
  • The depth cap is now actually enforced: enrich fetch refuses hop 5 with a stated reason; --force may exceed the URL cap, never depth (a hard bound by design)
  • Drift signal live: lint reads every standing non-forced cap fire (a session harvesting into a bound is over-promotion evidence); a --force'd fire is a deliberate override and excluded — discriminated by a typed forced field, never reason prose

🤖 Generated with Claude Code

leeovery and others added 5 commits August 23, 2026 19:38
`Result.children` and `_admit_children` were built as plumbing for a driver
that reports links to promote, then designed away: harvest is cognitive —
the subject rule is a reading of what an item is about, which no fetcher
can make — so `Child(` appears nowhere in src/ and never did. `via:
"thread"` goes with it: the walk-up writes its chain into one enrichment
file, so nothing was ever ledgered under it.

Migration 1's frozen copy of the provenance vocabulary tracks the
retirement, and must: a value it passes through that `LedgerEntry` no
longer accepts costs the whole line, where dropping the value costs a note.
No line it reads can carry `thread` anyway — the pre-rewrite engine had no
walk-up at all.

The tests that built `Child(...)` by hand to reach the caps are rewritten
against `enrich fetch`, the path that survives, because the caps stay.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Corpus seeding, `enrich fetch` and the deleted child path each admitted
work their own way, and they had drifted — which is how the depth cap came
to be enforced only in the one nothing called. `_Drain.admit` is the one
road in now: canonical identity keys the ledger, a hash the ledger already
holds is not re-admitted, provenance comes off the spawning entry, the caps
bound the re-entry, and the surviving line is recorded queued.

What a refusal MEANS stays with the caller, because the two answer to
different people. A capture batch has nobody to answer, so it parks its bad
seeds and seeds around them. `enrich fetch` answers whoever asked — the
cross-item report, the re-fetch in place, the stated refusal with its
route — and reads as that policy now, not as a second admission path.

Two things the collapse settles rather than carries: a cap-fire marker
records refused work, not an admitted unit, so it no longer blocks a later
admission of the same URL under any item; and the caps are asked of
re-entry alone, which is what they always bounded and what keeps an owner's
own twelve-URL capture out of the health check's harvest reading.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The depth bound lived only in the path nothing called, so `enrich fetch
--parent <deep-hash>` descended without limit — five hops, fifty, whatever
was typed. It fires where promotion actually happens now, recorded as a cap
fire exactly as the URL bound is.

`--force` does not reach past it. §10 gives the override to the URL cap by
name — "fetches count against the item's 12-URL cap; --force may exceed the
cap" — and §5's vocabulary spells `url-requested` as a fetch refused
without --force while depth has no such spelling. Depth bounds how far the
queue may walk from a shared URL, which is not a budget to spend; so the
refusal says "a hard bound, with no --force route" rather than naming a
route that would do nothing.

Driven the way a session drives one: fetch, promote, fetch under --parent,
four hops deep, and watch the fifth come back refused.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The health check diverted every `enrich fetch` refusal into a note, on the
reading that the owner naming a URL says nothing about the bounds. That
split does not survive the collapse: every promotion is a URL a session
named with `enrich fetch`, so "who typed it" separates nothing, and the
diversion was quietly emptying the drift signal it exists to feed.

What splits it is the override. A refusal that stood is drift to read,
whoever asked. A refusal answered with `--force` is a decision already
taken, so it leaves the reading — while the run report still answers the
asker with the route, unchanged.

`forced` is a schema field, not a reading of the reason text. §3 forbids
that route by name: the reason namespace holds session-authored free text
and must never be able to collide with a signal something routes on, and
the same bound worded two ways would split in two. Costless here — nothing
has shipped, so the field needs no migration; migration 1 tolerates it on
re-apply like every other current key.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The design still drew harvest promotions re-entering through the drain,
sketched `children` on the driver protocol, and listed `via: thread` in the
provenance vocabulary — three accounts of machinery that never ran. The
truth: drivers return content, media and metadata, promotion enters through
`enrich fetch`, and the caps bound it there.

§2's open question — `links` or `children` on the outcome union — is
answered by the deletion rather than decided: neither, because the union
carries no link-promotion field at all.

§1 gains what the two bounds now differ on, §5 the `forced` field, and §1 /
§11 / §12 the cap-surfacing rule as it now stands: the run report answers
the asker, the health check reads every fire nobody waived. The dex-lint
skill's claim that an owner-requested refusal "is no part of this reading"
was the sentence that just changed, so it says the new rule instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@leeovery leeovery changed the title fix3/e8 admission One door into the queue, and the dead promotion path deleted Aug 23, 2026
@leeovery
leeovery marked this pull request as ready for review August 23, 2026 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant