TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/cad0p/pi-steering-hooks/llms.txt
Use this file to discover all available pages before exploring further.
work-item-plugin is the canonical reference for plugin authors. It is a domain-generic work-item tracker — the [PROJ-N] ticket format is a deliberate placeholder, not a real system — whose purpose is to demonstrate every v0.1.0 authoring pattern in one readable place. Reading the source top-to-bottom is the fastest path to understanding how to build a production plugin.
The plugin enforces three rules that together require the agent to do the work in a verifiable order: reference a ticket in every commit message, prove tests pass before pushing, and re-read its own commit description before committing a second time. Each rule demonstrates a distinct engine feature; none of the rules depend on domain knowledge specific to any real project.
Plugin structure
The three rules
commit-requires-work-item
Intercepts git commit ... -m <msg> and blocks unless the message carries a [PROJ-N] token. It uses the plugin-registered workItemFormat predicate under when.not — the predicate returns true when the work-item tag is present, and the not inversion means the rule fires when it is absent.
noOverride: false is explicit here — this is a workflow rule, not an inherently destructive action, so override comments are permitted when genuinely warranted.
push-requires-tests
Intercepts git push and blocks unless npm test has succeeded in the current agent loop and no subsequent git pull has staled that result. This rule combines three engine features:
noOverride: true is correct here — pushing without proof of green tests is treated as an inherently risky action.
commit-description-check
A self-marking reminder rule. The first git commit in an agent loop is blocked with a “re-read your description” message; the rule marks itself via onFire so the second git commit in the same loop is allowed. A new agent loop resets the reminder. This demonstrates the onFire side-effect hook (ADR §6) for rules that produce their own state rather than relying on a separate observer.
The npm-test-tracker observer
The observer follows the ADR §14 encapsulation convention: every observer file exports the event constant, a typed write helper, and the observer itself. This keeps the raw event string in exactly one place — downstream typos become compile errors.
writes: [TEST_PASSED_EVENT] declaration threads through to defineConfig’s compile-time cross-reference checking — rules that use happened: { event: TEST_PASSED_EVENT } are validated against the union of all declared writes across plugins and observers at authoring time.
The plugin export
as const satisfies Plugin pattern (ADR §7) preserves literal types — name: "work-item" stays a string literal, not string, and the writes tuples from rules and observers stay as typed tuple literals. This is what allows defineConfig to cross-reference when.happened.event values against the plugin’s declared writes at compile time. A bare : Plugin annotation would widen those types and disable the cross-reference check.
The &&-chain speculative allow
push-requires-tests blocks git push when TEST_PASSED_EVENT has not been written in the current agent loop. Without special handling, npm test && git push would hit the same block: the engine evaluates the full command before any of it runs, and TEST_PASSED_EVENT has not been written yet.
The engine resolves this through speculative allow. Because npmTestTracker declares writes: [TEST_PASSED_EVENT], and push-requires-tests gates on happened: { event: TEST_PASSED_EVENT }, the engine recognises that npm test — the && predecessor — would write the required event if it succeeds. The push is speculatively allowed pre-execution. If npm test fails, the && chain short-circuits and git push is never reached. If npm test succeeds, the observer fires, writes TEST_PASSED_EVENT, and the push proceeds.
This pattern breaks the “block → agent retries same chain → block” loop without weakening the guardrail for non-chained pushes — a plain git push with no preceding npm test in the same loop is still blocked.
Consuming the plugin
@examples/work-item-plugin with your own published plugin package following the same layout.
Running the tests
pretest script builds pi-steering first, so the example resolves the package through its emitted dist/ exports. Run pnpm -r test to execute all packages’ suites in one pass.