Skip to content

sec-default: the system prompt's sections continue past the user tier - #97241

Merged
poteat merged 4 commits into
mainfrom
sec-default-prompt-compose
Sep 29, 2026
Merged

poteat merged 4 commits into
mainfrom
sec-default-prompt-compose

Conversation

@poteat

@poteat poteat commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary

TLDR: where an organization seats sec-default, a person's plugins no longer shape the system prompt's sections.

prompt.compose, whose hooks answer the system prompt as an ordered list of sections, joins the rows that continue past the user tier (next.to(e, "append")).

Notes

  • re why: every other event that shapes what the model is told (prompt.section, prompt.context) already continues past the user tier here; this one's chain ends in the engine's own composition. Without this row a person's plugin could drop, reorder or rewrite a section, change the facts the list is composed from, or answer a list of its own, on a machine its organization manages.
  • Only the user tier is passed over, by the tier the CLI pins on each plugin; a plugin passed over is not run for this event at all. Where no organization seats sec-default nothing changes, and a person's plugins keep prompt.submit everywhere.
  • Cost: the engine raises this event only when a loaded plugin hooks it, so where sec-default is seated every render of the system prompt runs the chain.
  • The declarations gain prompt.compose as the CLI declares it, and nothing else.
  • The test check is red for now, by construction: it installs the published CLI, and a CLI that does not know the event refuses a hooks module that names it ("prompt.compose" is not an event), so sec-default's suite fails there while the other mods pass. It turns green with the first published CLI that carries the event; the tests are not loosened.
  • Merge order with the sibling sec-default PR (deny rules hold): either. Both merge cleanly both ways; this one inserts one README row and one name on the first line of "What it hooks".
  • Release order: a CLI build whose engine does not know the event refuses to link this mod, loudly, at build time, so a build of an older engine compiles a mods commit from before this one.
  • Follow-up, not here: sec-default passes every event it does not list; a test that fails on a prompt-shaping event with no row would catch the next one.

Test Plan

  • With managed settings, claude --plugin-dir on a mod whose prompt.compose hook drops a section, rewords one, or answers a list of its own: the request is unchanged.
  • With no managed settings, the same mods change the prompt as before.
  • claude plugin test mods/sec-default is green on a CLI that carries the event.

Checked on a CLI built with the event: the three mods above leave the request byte-identical to the one with no mod; with the row removed and the CLI rebuilt, the section is gone, the rewording lands and the third mod's text is the composed prompt.

Revert-proof: 2 new tests fail on base with the fix reverted (claude plugin test mods/sec-default with the row removed: 26 pass, 2 fail; 28 of 28 with it back)

Changelog

@poteat
poteat enabled auto-merge (squash) September 29, 2026 19:05

@bhosmer-ant bhosmer-ant left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hook line mirrors the prompt.section one, and the declarations match what the CLI generates. One note: this and #97334 both add tests/fixtures/rewording.ts with different contents, so the second to merge will conflict.

@poteat
poteat merged commit 684800b into main Sep 29, 2026
1 of 2 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.

2 participants