Five commits, all green on dev (last run 7396, 66e21a6).
#4364: auto-inject retrieves on the conversation, not just the typed words
574b27a: the prompt hook sends the tail of the last assistant reply as ctx. The notes and rule arms append it to prompts of 280 chars or less, prompt first, capped at 600 chars. It uses no model tokens.
20227eb: fixes the context cap (counted a trailing space) and the empty-transcript exit status.
bb632c4: menu lines are now #id [kind · System] "name" (score) plus the whole matched passage. A seen repeat is a one-line pointer. This applies to both the prompt and write-path menus.
eb00554: the startup hook reports a timeout, unreachable instance, refused key or HTTP code, with elapsed time. It retries once only where a retry helps, and the fallback starts with enter_project(<id>).
Milestone 427: a snippet's and lesson's stored title is its name
66e21a6: embeddings.document_title joins the trigger from data at embed time, idempotently. The embedded text is unchanged, so there is no re-embed.
Migration 0108 rewrites existing titles on an exact own-trigger suffix, leaving updated_at alone. The downgrade recomposes. CI ran it on an empty schema only; spot-check snippet and lesson titles after deploy.
Five commits, all green on dev (last run 7396, 66e21a6).
**#4364: auto-inject retrieves on the conversation, not just the typed words**
- `574b27a`: the prompt hook sends the tail of the last assistant reply as `ctx`. The notes and rule arms append it to prompts of 280 chars or less, prompt first, capped at 600 chars. It uses no model tokens.
- `20227eb`: fixes the context cap (counted a trailing space) and the empty-transcript exit status.
- `bb632c4`: menu lines are now `#id [kind · System] "name" (score)` plus the whole matched passage. A `seen` repeat is a one-line pointer. This applies to both the prompt and write-path menus.
**#4366: SessionStart names its failure**
- `eb00554`: the startup hook reports a timeout, unreachable instance, refused key or HTTP code, with elapsed time. It retries once only where a retry helps, and the fallback starts with `enter_project(<id>)`.
**Milestone 427: a snippet's and lesson's stored title is its name**
- `66e21a6`: `embeddings.document_title` joins the trigger from `data` at embed time, idempotently. The embedded text is unchanged, so there is no re-embed.
- **Migration 0108** rewrites existing titles on an exact own-trigger suffix, leaving `updated_at` alone. The downgrade recomposes. CI ran it on an empty schema only; spot-check snippet and lesson titles after deploy.
Plugin version: `2026.09.23.2008`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The prompt hook sent only the operator's message, so a mid-session
follow-up ("yes do that") named nothing a note, lesson or rule could
match. The hook now reads the tail of the last assistant reply from the
transcript and sends it as `ctx`; the notes and rule arms append it to a
short prompt (<= 280 chars), prompt first, capped at 600 chars. No model
tokens: it is embedding input, and the injected menu's budget is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The context fetch folded a timeout, an HTTP error and a refused key into
one sentence that ended "enter_project() as needed" -- read as optional,
so a session could start with no recent milestones or open tasks and no
way to know what prior work existed. The fetch now names the cause and
the elapsed time, retries once (6s) only where a retry can change the
answer, and the fallback states enter_project as the first step, with
the marker's project id when there is one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The trailing newline became a space before the 600-char cut, so the cap
kept 599 characters of text; and under pipefail a grep that matched no
reply made the helper exit 1. Trim before cutting; return 0 explicitly.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Injected lines rendered a snippet's or lesson's title, which carries its
whole trigger by construction (the embedding shape) and ran past 1,500
characters -- again on every `seen` repeat. The passage under a line was
cut to 200 chars from the middle, keeping its head (the title again) and
losing where the match was.
Now, on both the prompt menu and the write-path prior-art menu:
- the line shows the record's NAME (snippet data.name / lesson subject),
with its kind and System (`[issue (done) · Plugin & hooks]`);
- the passage is the whole matched chunk, title prefix stripped, on one
line so the blockquote holds; a title-only match hands over the trigger;
- a `seen` record is a one-line pointer to what is already in context.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The title was `subject — trigger` because the stored title WAS the
embedded one, and the join is what makes these kinds rank on the
situation they apply to (#2485). Every surface that shows a title then
showed the trigger too -- menus, lists and search rows ran to kilobytes.
- embeddings.document_title(title, note_type, data, body) joins the
trigger from `data` (body fallback) at embed time. Idempotent: an
un-migrated composed title comes out the same, never doubled. The
embed path, the startup backfill and the dedup gate's semantic signal
all use it, so the embedded text -- and every vector -- is unchanged.
- Writers store the subject: snippet create/update (service, REST, MCP)
and lesson_document. Both compose_title helpers are removed.
- Readers: dedup takes `data`; the menus strip the embedded title from a
passage; list rows project `when_to_use`, which SnippetListView reads.
- 0108 rewrites existing rows on an exact `' — ' || <own trigger>`
suffix with raw SQL, leaving updated_at alone so the backfill does not
re-embed the corpus for identical vectors. Downgrade recomposes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Five commits, all green on dev (last run 7396,
66e21a6).#4364: auto-inject retrieves on the conversation, not just the typed words
574b27a: the prompt hook sends the tail of the last assistant reply asctx. The notes and rule arms append it to prompts of 280 chars or less, prompt first, capped at 600 chars. It uses no model tokens.20227eb: fixes the context cap (counted a trailing space) and the empty-transcript exit status.bb632c4: menu lines are now#id [kind · System] "name" (score)plus the whole matched passage. Aseenrepeat is a one-line pointer. This applies to both the prompt and write-path menus.#4366: SessionStart names its failure
eb00554: the startup hook reports a timeout, unreachable instance, refused key or HTTP code, with elapsed time. It retries once only where a retry helps, and the fallback starts withenter_project(<id>).Milestone 427: a snippet's and lesson's stored title is its name
66e21a6:embeddings.document_titlejoins the trigger fromdataat embed time, idempotently. The embedded text is unchanged, so there is no re-embed.updated_atalone. The downgrade recomposes. CI ran it on an empty schema only; spot-check snippet and lesson titles after deploy.Plugin version:
2026.09.23.2008.🤖 Generated with Claude Code
The prompt hook sent only the operator's message, so a mid-session follow-up ("yes do that") named nothing a note, lesson or rule could match. The hook now reads the tail of the last assistant reply from the transcript and sends it as `ctx`; the notes and rule arms append it to a short prompt (<= 280 chars), prompt first, capped at 600 chars. No model tokens: it is embedding input, and the injected menu's budget is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>