Release 0.79.0 — the walk knows what day it is - #22
Merged
Merged
Conversation
Spec v0.79. An operator asked a walk (J.10.5) for the two screenshots
they had uploaded that day. The forest held them: coverage counted two
media nodes in the walk's own first hop, with a date range ending on that
day. The walk then read the root, scanned it flat (zero), grepped every
body for the literal word "media" (four task documents, no picture) and
answered that the product is not a place for personal files. Every fact
it needed was one parameter away, and not one of those parameters was
written where the model reads.
- J.10.5: the menu MUST name what the tools take. since/until/date_field
on locate, sniff and scan have existed since v0.52 (C.13.1),
type_filter on locate and sniff, filter: {type} and recursive on scan,
and the loop forwards the model's arguments as they are, so all of them
would have worked. v0.67's sentence about tools now covers arguments:
a parameter the model is never told about is a parameter the whitelist
did not admit.
- J.10.5, C.13.3: calendar joins the whitelist, for the reason coverage
did. "Today", "this week", "in August" are questions about where the
material sits in time, and C.13.3 is the read built for that: counts
by period, no bodies, every number the policy's own.
- J.10.5 rule 3, J.10.7: the walk has a clock. No prompt stated the
date, so "today" was unresolvable even where a window was reachable.
The prompt states the host's date, the same clock that stamps created
on a node this host plants; the date enters the walk's key on HEAD's
terms, and only the walk's (a date in the sweep's key would expire
every stored answer nightly for nothing).
- J.10.5 rule 4: a kind of node is found by its filter, never by a sniff
for the type's name, which greps bodies for a word and returns every
document that mentions it.
- C.13.1 rule 7: the caller's window replaces whatever the model
authored, on every searching call and on calendar; the prompt says so.
- J.10.5: a hop names the argument that decided it. The record carried
query, terms, scope, parent_id, k and none of filter, type_filter,
since, until, date_field, recursive, granularity, so a console showed
"scan _index -> 0" and could not show the filter that made it zero.
- New J.5.19: the Ask console offers since/until, sent as C.13.1's own
parameters; read from the address beside q, never a browser preference
(v0.76's lesson); the answer is labelled by the response's window echo,
never the inputs, and the console never expands a coarse bound itself.
Acceptance F.173. CLAUDE.md points at v0.79 and carries the round.
Signed-off-by: Jimmy Wesley <[email protected]>
Implements spec v0.79 (J.10.5 rules 3/4, C.13.1 rule 7, C.13.3, J.10.7,
J.5.19), F.173.
Station (inference.py): FORAGE_TOOLS gains calendar; the menu names
since/until/date_field on locate, sniff and scan, type_filter on locate
and sniff, filter: {type} and recursive on scan, granularity on calendar,
and carries the two new rules (a period is a window resolved from the
stated date; a kind of node is its filter, never a sniff for its name).
host_today() is date.today(), the clock that stamps created and updated,
appended per call as FORAGE_CLOCK. The caller's bound is forced onto
calendar as onto the searching calls and lands last, so a model-authored
since is replaced, not merged, and the prompt says so. HOP_ARGS gains
filter, type_filter, since, until, date_field, recursive, granularity;
_outcome reports buckets for calendar.
Key (answer_store.py, app.py): build_key takes today, entering only when
set; the walk passes inference.host_today() and the sweep passes nothing,
so a sweep keys byte-identically. The walk store lookup is a closure that
had never imported inference, which a bare name there turned into a 400
on every walk; the import is local, like derive_terms beside it.
Studio (Ask.jsx, locales, check-ask-window.mjs): two date inputs, since
and until, read from the address at mount exactly as q is and never
through the preferences store; sent only when set, on the ask, the J.5.15
preview and the cURL; the answer badge reads the response's window echo;
the history badges a bounded run and restoring one restores its window.
Hop arguments that are objects render as compact JSON; a calendar hop
reports its buckets. The checker holds 34 criteria (17 fail against the
v0.78 view). The handbook's Ask section gains the paragraph in three
languages.
Tests: tests/test_v079_walk_window.py, eleven of them: the whitelist and
the served menu, the stated date, a model-authored window reaching the
engine, a type filter shown on the record, the caller's normalised bound
replacing the model's on scan and calendar with coverage left alone, only
what the model set on the record, the walk key moving with the date while
the sweep's does not, a walk stored yesterday not served today, and the
console's static criteria plus its locale keys.
Signed-off-by: Jimmy Wesley <[email protected]>
The walk's hops is not on the MCP answer tool, so v0.79's prompt changes
never reach an MCP client. The walk's failure does: an agent asked for
the pictures that sniffs for the word "media" gets every document that
mentions the word and not one picture.
The wire table (signatures.py) and C.6b's own signature carried
type_filter on sniff; the served MCP tool alone omitted it. Added, and
forwarded. The served locate, sniff and scan descriptions now say that a
kind of node (the pictures, the datasets, the decisions) is type_filter
on locate/sniff and filter: {"type": ...} on scan, that a flat scan of a
root lists its branches and recursive walks the subtree, and that
sniffing for a type's name is a search for a word (J.1.2 rule 7's
reason, applied to a parameter). The generated skill's sniff bullet
teaches the same, checked by check-skill.mjs; a served-description test
joins F.173 and calls the typed sniff through the MCP mount.
Signed-off-by: Jimmy Wesley <[email protected]>
One spec version since 0.78.0 (v0.79).
Behaviour changes worth reading before upgrading:
- The walk (answer with hops) is told what day it is. Its system prompt
now states the host's date, read off date.today(), the same clock that
stamps created and updated on every node the host writes. That date
enters the walk's answer-store key, so a walk stored yesterday is not
served today; every stored walk misses ONCE after the upgrade. The
sweep's key is unchanged and a sweep is served exactly as before.
- The walk's tool menu names since/until/date_field on locate, sniff and
scan, type_filter on locate and sniff, filter: {type} and recursive on
scan, and calendar joins its whitelist (metadata only, counts by the
policy, bounded by the caller's window like the searching calls). A
model that used to grep bodies for a type's name is told not to.
- A caller's since/until on a walk now also bounds calendar, and replaces
any window the model authors on the same call; the hop record shows the
bound normalised (2020 arrives as 2020-01-01), never the model's own.
- Hop records gain filter, type_filter, since, until, date_field,
recursive and granularity when the model set them. A consumer of a
record written before this version must read the absent field as not
set. calendar hops report out: {buckets: n}.
- The MCP sniff tool gains type_filter, which the wire table and C.6b's
signature already carried and the served tool alone omitted. The served
locate, sniff and scan descriptions and the generated skill now teach
that a kind of node (the pictures, the datasets) is a filter and never
a search for the type's name. Additive: a call without it is unchanged.
- Studio's Ask console offers a period (since/until) beside the question,
sent only when set; read from the address beside q and never kept as a
preference. A link carrying a coarse bound (?since=2026-08) is sent as
it is and shown by the answer's window badge, not by the date field.
Signed-off-by: Jimmy Wesley <[email protected]>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release 0.79.0 — the walk knows what day it is
One spec version, v0.79, and the package moves 0.78.0 → 0.79.0. It comes
from one screenshot: an operator asked a walk for the two screenshots I
uploaded today, on a 1,879-node forest that held exactly two
medianodes, and got told the product is not a place for personal files.
Nothing was missing on the wire.
since/until/date_fieldhave been onlocate,sniffandscansince v0.52;type_filter,filter: {type}and
recursiveexisted; the loop forwards the model's arguments verbatim.Three things were missing where the model reads: the menu named none of
those parameters,
calendarwas not on the whitelist, and no prompt saidwhat day it was. A model holding every window parameter there is can
write
sinceand has nothing to write in it.What changed
The menu names what the tools take (J.10.5). v0.67's rule about tools
— a tool the model is never told about is a tool the whitelist did not
admit — now covers arguments. Every searching call's window and filter
parameters are named,
scanis told that a flat scan of the root listsbranches and that
recursivewalks the subtree, and two prompt rules jointhe two of v0.67: a period in the question is a window resolved from the
stated date, and a kind of node is found by its filter, never by a
snifffor the type's name.
The walk has a clock (J.10.5 rule 3, J.10.7). The prompt states the
host's date, read off
date.today(), the same clock that stampscreatedand
updatedon every node the host writes, so "today" in the questionand "today" in the passports are one day. The date enters the walk's
store key on HEAD's terms, so a hunt asked on two days is two hunts and a
walk stored yesterday is not served today. Only the walk's: the sweep's
retrieval is the caller's, its bound is already stated, and a date in its
key would expire every stored answer nightly for nothing.
calendarjoins the whitelist (C.13.3). For the reasoncoveragedid: counts by period, no bodies, every number the policy's own — the one
read that turns "today" into a window instead of a guess. The caller's
bound is forced onto it as onto the searching calls, so the map the model
sees is the map of what it may reach.
The caller's window still wins (C.13.1 rule 7). It lands last on
every searching call and on
calendar, so a model-authoredsinceisreplaced, not merged, and the prompt says so. The record shows the bound
normalised (
2020arrives as2020-01-01), the two dates the searchactually used.
A hop names the argument that decided it. The record carried
query,terms,scope,parent_id,k— and none offilter,type_filter,since,until,date_field,recursive,granularity, the argumentsthat decide whether a listing is empty. Hop 3 above is why:
scan _index → 0read as an empty root. J.10.5 already required "the argumentsthe model chose"; this is the record catching up with its own rule. A
calendarhop reports{buckets: n}; objects render as compact JSON onthe console.
The question has a period on the console (new J.5.19). Two date
inputs beside the question, sent as C.13.1's own parameters only when
set; read from the address beside
q(a shared link asks the same boundedquestion) and never a browser preference — a window remembered from
yesterday is v0.76's lesson one console over. The answer is labelled by
the response's
windowecho, never by the inputs; the history badges abounded run and restoring one restores its window.
The MCP surface is taught the same filter. The walk's
hopsis noton the MCP
answertool, so the prompt changes never reach an MCP client— but the walk's failure does: an agent asked for the pictures that sniffs
for the word "media" gets four task documents. The wire table and C.6b's
signature carried
type_filteronsniff; the served tool alone omittedit, and no description named it. Now the served
locate,sniffandscandescriptions and the generated skill say that a kind of node is afilter, never a search for the type's name.
Found on the way
consult_walk_storeis a closure that had never importedinference;a bare name there was a 400 (
answer failed: name 'inference' is not defined) on every walk. Caught by the store suite before commit.addopts = "-q"plus a second-qon the command linehides pytest's summary line entirely. Count the dots, or drop the flag.
Known gaps, stated rather than discovered
(
?since=2026-08): it is sent as it is, the engine expands it, thebadge labels the answer, and the console deliberately does not
re-expand it — a second expansion is a second reading of C.13.1.
offline; F.173 asserts the harness (what is named, what is forwarded,
what is recorded, what is keyed).
bench/questions-locate-v1.json) is stillnot measured.
For existing callers
date). Sweeps are served exactly as before.
absent field as not set, never inferred from
out.since/untilon a walk now also boundscalendarandoverrides anything the model sends on the same call.
Acceptance
F.173. Full suite green locally (1687 passed, 6 skipped, Python 3.12) and running in CI on this PR;
python -m build+twine checkpassed.