Skip to content

feat(save): generate the questions and names a context should be found by - #80

Merged
tanglearncode merged 1 commit into
mainfrom
routing-expansion-generate
Aug 8, 2026
Merged

tanglearncode merged 1 commit into
mainfrom
routing-expansion-generate

Conversation

@tanglearncode

Copy link
Copy Markdown
Contributor

#79 added the storage. Nothing filled it. This is the half that does.

Why at save time

No plugin process has a model. The session doing the saving does, and it has just read the material. Doing the language work once, where a model is already present and free, beats trying to do it on every question, where it is impossible. That asymmetry is the most useful property this architecture has.

What changes

Every host's save document now asks for two lists alongside the routing description:

  • routingQuestions — 10 to 15 questions this context should answer, in the words a user would type rather than the words the profile uses. Including the vague ones.
  • routingEntities — the names that appear in this work and rarely anywhere else: services, repos, ticket ids, error strings, commands, hosts.

Both documents state outright that neither list is ever shown. That matters: a list written for a reader is a materially worse list than one written to be matched against.

Omitting them on an update leaves the stored lists alone, so a save from a host — or a turn — that generated none cannot wipe what an earlier save wrote.

pi is the one host that takes a save as tool arguments rather than a capture file, so its tool schema and runtime carry the fields directly. Every other host passes the capture straight through, so no CLI change was needed.

Tests

A sweep over every host's save document, asserting both fields and both rules (never shown; omitting leaves stored lists alone). This is the guard that matters here: the storage is shared core and arrived everywhere at once, but this instruction is per host — and a host that forgot to ask would store contexts that are quietly harder to find than the same work saved from another host, with nothing failing anywhere to say so. It is the same shape of bug the command sweep already exists for.

Behavioural tests on pi's save path for both directions: supplied lists are stored, and a save that says nothing leaves them intact.

That second one is deliberate. Diff coverage reported these lines covered before I wrote it — if (x !== undefined) capture.x = x; counts as run when the condition is merely evaluated. Line coverage cannot tell that branch from the other one, so the assertion has to.

Diff coverage: 31 changed lines, 0 uncovered. Full suite 409 passing.

…d by

#79 added the storage; nothing filled it. This is the half that does the
work, and it does it at save time on purpose: no plugin process has a
model, but the session doing the saving does, and it has just read the
material. Doing the language work once, where it is free, beats doing it
on every question, where it is impossible.

Every host's save document now asks for two lists alongside the routing
description: the questions this context should answer, in the words a
user would type rather than the words the profile uses, and the names
that appear in this work and rarely anywhere else.

Both are matched against and never shown, which the documents say
outright — a list written for a reader is a worse list than one written
to be matched. Omitting them on an update leaves the stored lists alone,
so a save from a host or a turn that generated none cannot wipe what an
earlier one wrote.

pi takes a save as tool arguments rather than a capture file, so its
tool schema and runtime carry the fields directly.

A test sweeps every host's save document for both fields and both rules.
The storage was shared core and arrived everywhere at once; this
instruction is per host, and a host that forgot to ask would store
contexts that are quietly harder to find than the same work saved
elsewhere.
@tanglearncode
tanglearncode merged commit 2d27cf0 into main Aug 8, 2026
11 checks passed
tanglearncode added a commit that referenced this pull request Aug 8, 2026
The lists added in #79 travel inside the bundle, and the guidance in #80
told the model to fill them with "commands, hosts, people". Hostnames and
people mean nothing on anyone else's machine, and asking for people
contradicts the save command's own rule against writing unnecessary
personal information. A matching list is the easiest place for a context
to quietly stop being shareable: an absolute path looks like a usefully
rare term while it is written, and is worthless or revealing the moment
the bundle is handed over.

The hosts had also drifted apart — three asked for hosts and people, two
asked for neither — so the same work saved from different hosts produced
different bundles.

One wording everywhere now, asking for names that belong to the subject:
services, components, repositories, ticket ids and prefixes, error
strings, product and system names. Each document states that the lists
travel and must stay free of absolute paths, home directories,
usernames, personal names and email addresses.

If the work genuinely is about a particular environment, the profile is
where that belongs and is untouched. What changes is that the matching
index is not.

And a filter, so none of this rests on prose: entries carrying a drive
letter path, a UNC path, ~/, /home/, /Users/, /root/, or an email
address are dropped from both lists at save time. Ordinary domain terms
that merely look technical are kept, which the tests pin.
@tanglearncode tanglearncode mentioned this pull request Aug 9, 2026
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