Skip to content

Release 0.65.0 — the retrieval is done long before the reply is - #19

Merged
JimmyWesley merged 9 commits into
mainfrom
develop
Aug 27, 2026
Merged

JimmyWesley merged 9 commits into
mainfrom
develop

Conversation

@JimmyWesley

Copy link
Copy Markdown
Owner

Release 0.65.0 — the retrieval is done long before the reply is

A hosted answer is two costs three orders of magnitude apart. The sweep's
retrieval is milliseconds — 19 on the 82-node fixture, 448 on a 1,902-node
forest cold — and the provider round trip is seconds. J.10.11 already keeps
the model off a reader lane and J.10.6 already publishes the two halves apart,
but the Station still answers once: the bundle exists as a value in the host
at millisecond 19 and leaves the building at second 10.

The Ask console spent that gap on a spinner.

What changed

The path panel (J.5.15). The console runs the sweep's retrieval itself, in
parallel with the answer, through the ordinary harvest — same question, same
k, same entry ranker, read-only and deterministic — so what it draws is what
the answer will see rather than a guess at it. It deposits no pheromone: heat is
the whisper's at the close of an answer (J.10.7), never a read's. The map is the
J.11 graph projection Explore already reads, already scoped and already
filtered.

Two of its rules are where the honest version and the flattering version part:

what a demo would draw what it draws
sweep a cited stage, "the model chose these" none — evidence is the whole bundle and the reply is prose that names nothing, so there is no selection to show
walk, entry stage filled from sources, to look complete zero — J.10.4 keeps only what carries text, and zero is what actually happened

The switch is deliberately separate from hops: a walk costs one model call
per hop and the drawing costs none, so one control over both would teach an
operator that the picture is what made the answer slow.

The panel prints the real millisecond figure off the Part D trace beside a
reveal that takes seconds. A console whose subject is that retrieval is cheap
must not leave an audience reading the animation's duration as the measurement.

A boundary under the shell. React 18 unmounts the whole tree on an uncaught
render throw, so one bad element below App left a blank page — no navigation,
no forest picker, no way back. Not hypothetical: a <Field> wrapping a
<Select> made React refuse an <input> with children (#137) and took the
Studio down every time a document was opened. That bug is fixed where it was
written; the boundary is the answer to the class. It sits below the Shell and
never above it — a boundary that also caught the navigation would leave nothing
to navigate with.

The reading console is a search. Each result is a real href, so middle
click and "copy link" work. Three honesty rules: the clock is the engine's
(Server-Timing: vine, with the round trip in the tooltip and no time at all
when the header is absent); the page is one page (locate has an 800-token
budget and no cursor, so the line says there are more matches instead of letting
ten look like all of them); and the search names the search it did not do
(locate reads curated metadata, never bodies — a silence here is a fact about
titles and summaries).

Not here

The walk's hops arriving one at a time, live. That needs the host to push, which
is a contract, and this version does not add one.

Engine

src/monkeyllm/ is untouched — the wheel's module code is identical to
0.64.0's. The number moves because it is the Station's identity, not the
engine's: package_version() feeds serverInfo.version (J.1.2 r3), the
station: field of forests() (r6, which the generated skill stamps and
teaches operators to compare), and /v1/health. A host change that does not
bump it leaves every deployment reporting a build it is no longer running.

Verification

  • Full suite green, both legs.
  • python -m build + twine check pass on the sdist and the wheel; the
    workflow's tag/version guard simulated OK against v0.65.0.
  • check-trail.mjs is F.137 and runs from tests/test_trail_panel.py, the same
    arrangement check-skill.mjs has.
  • de599e4 repairs a self-inflicted one: trailmap.js was first committed with
    NUL bytes, which made git treat it as a binary blob and cost the file its text
    diffs. tests/test_repo_hygiene.py now guards the class.

Known gap

The v0.65 changelog block in the spec carries the prose but not the closing
bullet list nor the Acceptance: F.137 line that every version since v0.54
ends with. F.137 itself is present in the body of the document.

A hosted `answer` is two costs three orders of magnitude apart. The sweep's
retrieval is milliseconds — 19 on the 82-node fixture, 448 on a 1,902-node
forest cold — and the provider round trip is seconds. J.10.11 already keeps
the model off a reader lane and J.10.6 already publishes the two halves apart,
but the Station still answers ONCE: the bundle exists as a value in the host at
millisecond 19 and leaves the building at second 10. The Ask console spent that
gap on a spinner.

J.5.15 is the panel that spends it on the truth instead. The console runs the
sweep's retrieval itself, in parallel with the answer, through the ordinary
`harvest` — same question, same k, same entry ranker, read-only and
deterministic — so what it draws is what the answer will see rather than a
guess at it, and it deposits no pheromone, because heat is the whisper's at the
close of an answer and never a read's. The map is the J.11 graph projection
Explore already reads, already scoped and already filtered.

Two of its rules exist because the honest version and the flattering version
differ, and the difference is exactly the kind a demo hides. On a sweep,
`evidence` is every id in the bundle — the reply is prose and names nothing —
so there is no "the model chose these" stage to draw, and drawing one would
show a selection that never happened. On a walk the entry `locate` marks
nothing, because J.10.4 keeps only what carries text: the stage reads zero,
which is true, instead of being filled from `sources` to look complete.

The panel states its own speed for the same reason. The reveal takes seconds
and the thing it depicts took milliseconds, so the real figure rides beside it
off the Part D trace — a console whose subject is that retrieval is cheap must
not leave an audience reading the animation's duration as the measurement.

Not here: the walk's hops arriving one at a time, live. That needs the host to
push, which is a contract, and this version does not add one.

Signed-off-by: Jimmy Wesley <rededown@hotmail.com>
The panel that fills the gap the spec measures. While the model writes, the
console runs the sweep's own retrieval beside it through `harvest` — same
question, same k, same entry ranker — and reveals the stages over the J.11
graph projection Explore already reads.

Its switch is deliberately separate from `hops`. A walk costs one model call
per hop and the drawing costs none; one control over both would teach an
operator that the picture is what made the answer slow, which is the opposite
of what the panel exists to show.

A trail carries `--graph-trail` and not `--graph-shortcut`. A
`discovered-shortcut` is a fact the forest holds and a trail is what one
question did to it — two different facts must not arrive in the same colour.
Segments follow `parent`, and only where BOTH ends are in the projection this
principal received, so the drawing cannot outline a region the scope hides.

`groupOf` and `step` become exports of `graph.jsx` rather than being copied
into `trailmap.js`: the layout the trail is drawn on has to be the layout
Explore draws, or the same forest would have two shapes.

The millisecond figure printed beside the stages is read off the Part D trace,
never timed around the reveal.

`check-trail.mjs` is F.137 and runs from `tests/test_trail_panel.py`, the same
arrangement `check-skill.mjs` has: it asserts that a stage is marked only from
material the host returned — a sweep produces no `cited` stage at all, an entry
stage appears only where `found_by` carries `locate`, and heat is unchanged by
the preview.

Signed-off-by: Jimmy Wesley <rededown@hotmail.com>
React 18 unmounts the whole tree on an uncaught render throw, so a single bad
element anywhere below `App` left a blank page — no navigation, no forest
picker, no way back, and an operator whose only repair was guessing that a
reload might help. That is not hypothetical: a `<Field>` wrapping a `<Select>`
made React refuse an `<input>` with children (#137) and took the entire Studio
down every time a document was opened.

The boundary is not the fix for that bug — that one is fixed where it was
written. It is the answer to the class: the shell survives, the address still
says where the operator is, and the failure is reported as one console's
failure rather than as the product ending.

It sits below the Shell and never above it. A boundary that also caught the
navigation would leave nothing to navigate WITH, which is the blank page again
wearing a message. It resets on `forest:view:node`, so moving somewhere else is
itself the retry, and a failure that belonged to a document the operator has
left does not poison every later navigation.

What it shows is the exception's `message`, truncated to one line, and nothing
below it. The stack and React's component info go to `console.error`, where a
front-end failure belongs: the console has no error sink of its own, and
inventing one would open a second, unaudited channel out of the operator's
browser — which is the premise J.5.13 is built on.

Signed-off-by: Jimmy Wesley <rededown@hotmail.com>
Two things in the reading console, one of which is the bug the boundary beside
it was built for.

The `<Field>` wrapping the share-window `<Select>` made React refuse an
`<input>` with children (#137) and threw on every render of the share panel,
which in React 18 unmounted the whole Studio. `Select` carries its own label,
so the wrapper was never needed; it is gone, and the crash with it. The
boundary is the answer to the class, this is the answer to the instance.

The finder is now shaped like a search engine rather than like a form, because
that is what somebody opening this console is doing. Each result is a real
`href` through the router's helper, so middle click, "copy link" and the status
bar all work — a list of buttons looks identical and answers none of them.

Three honesty rules, and each of them is a place where the easy version lies:

The clock is the engine's (J.10.6). `Server-Timing: vine` is the forest's own
figure and the round trip is the internet's, so the round trip rides in the
tooltip and never in the headline. When the header is absent — an older
Station, a proxy that dropped it — the line carries no time at all, because
printing the browser's stopwatch there is the exact claim J.10.6 forbids.

The page is one page. `locate` answers inside an 800-token budget (C.6) and has
no cursor, so ~10 entries is the whole of what one call can return whatever `k`
says, and there is no page two to offer. When the budget cut the list the line
SAYS there are more matches, instead of letting ten look like all of them.

And the search names the search it did not do. `locate` reads curated metadata
and never the bodies (C.6b), so `searched` reports how many documents that
covered and the empty state points at Explore, which runs both halves. A
silence here is a fact about titles and summaries, not about the forest.

Signed-off-by: Jimmy Wesley <rededown@hotmail.com>
Brand art for the company page and the personal cover, kept in `docs/` beside
`banner.png` and `social-preview.png` for the reason those are: the reasoning
about what a public surface claims belongs where the project keeps its
reasoning, and the images the README and the cards point at are absolute raw
URLs against this repository, so they have to live in it.

Five files because LinkedIn serves the page cover at more than one size and
crops it differently by viewport: `page-cover` and its `@2x`, a `-tall`
variant for the narrow crop, a `.jpg` for the upload paths that reject PNG,
and `cover` for the personal profile.

Signed-off-by: Jimmy Wesley <rededown@hotmail.com>
Signed-off-by: Jimmy Wesley <rededown@hotmail.com>
A literal NUL byte in the first 8000 bytes of a file causes Git to classify
it as binary, stripping away diff and blame functionality for the file. This
change removes such a byte from `apps/studio/src/trailmap.js` and adds a
hygiene test, `test_no_tracked_source_file_reads_as_binary`, to ensure no
tracked source files contain NUL bytes, maintaining readable history and
reviews.

Signed-off-by: Jimmy Wesley <rededown@hotmail.com>
Signed-off-by: Jimmy Wesley <rededown@hotmail.com>
Two duplications, measured on this repository's own history rather than
assumed.

A commit on `develop` that is also a pull request's head fired `tests` twice —
once for `push`, once for `pull_request` — and each run is a two-version
matrix, so ~20 runner-minutes answered one question. Neither run told anything
the other did not: same checkout, same suite, same matrix. `push` is now `main`
only. A required status check is matched by NAME against the head SHA whatever
event produced it, so the pull_request run satisfies the ruleset exactly as the
pair did.

The trade, stated rather than discovered later: a push to `develop` with no
pull request open is no longer tested until one is opened. That is not a new
hole so much as an old one made visible — the ruleset already requires a pull
request on `develop`, so such a push is a bypass of a rule this repository
already set.

The second duplication was in time rather than in events. Pushing three times
in a row left the first two suites running to produce an answer nobody would
read, because the third had already superseded them. `concurrency` keyed on the
ref cancels a superseded run.

Never for a tag. `release.yml` calls this file, and that run is the gate in
front of an upload PyPI will not let anyone take back: a push to `main` landing
while a release is mid-flight must not be able to cancel the thing standing
between a mistake and a permanent version. Hence the guard on the flag rather
than a bare `true`.

Not touched: the release re-running the suite at all. That one is the same file
and not a copy of it, on purpose — a release running a copy of the checks would
drift from the copy the branches enforce, and the drift would surface as a
published version nobody can reproduce. Five minutes before something permanent
is the one place repetition pays.

Signed-off-by: Jimmy Wesley <rededown@hotmail.com>
@JimmyWesley
JimmyWesley merged commit c13721a into main Aug 27, 2026
3 checks passed
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