diff --git a/openspec/changes/project-map-prompt-injection/design.md b/openspec/changes/project-map-prompt-injection/design.md new file mode 100644 index 0000000..ec1e8e5 --- /dev/null +++ b/openspec/changes/project-map-prompt-injection/design.md @@ -0,0 +1,235 @@ +# Design: Project Map Prompt Injection + +## Status + +| Field | Value | +|---|---| +| Phase | **Design** | +| Based on | [Spec](spec.md) | +| Next | Tasks | + +## Design summary + +This change adds a runtime guidance layer on top of the paired map/index artifact system. The implementation should not redesign map generation or retrieval. Instead, it should add a well-scoped injection pipeline that: +- emits honest startup hints before init, +- preloads the root pair after init, +- expands under a hybrid budget, +- avoids redundant reinjection by scanning real outgoing context, +- varies guidance strength through explicit modes, +- proves correctness with integration-heavy validation. + +## Affected areas + +### Source files likely to change +- `pi-extension.ts` +- shared config handling (`src/config.ts` or equivalent) +- runtime helpers for map/index discovery and injection selection +- tests covering extension lifecycle and per-turn behavior +- docs/runtime guidance surfaces if needed + +### New modules likely to appear +- `src/prompt-injection.ts` or equivalent runtime helper +- optional helper for canonical marker construction / detection +- optional helper for token-budget estimation across paired artifacts + +## Architecture changes + +### 1. Injection policy helper +Centralize prompt-injection logic in one helper rather than scattering it across hooks. + +Suggested responsibilities: +- determine current mode (`off` / `advisory` / `strong` / `strict`), +- detect whether artifacts exist, +- build pre-init startup hint, +- build post-init root-pair payload, +- estimate expansion budget, +- choose additional artifacts under the budget, +- construct a canonical injected marker/block, +- scan outgoing context or payload for that marker, +- decide whether reinjection is required. + +This helper is the main guard against drift between startup hints, context hooks, and strict-mode checks. + +### 2. Injection surfaces +Use different extension surfaces for different responsibilities. + +#### Pre-init / startup hint +Use `before_agent_start` for lightweight startup guidance before real artifacts exist. + +Required behavior: +- inject only a hint, +- tell the agent to run `project_map_init`, +- keep the hint visible and inspectable. + +#### Post-init root-pair preload +Use `before_agent_start` to guarantee the initial post-init root-pair preload for a prompt. + +Required behavior: +- inject root `.pi-map.index.md`, +- inject root `.pi-map.md`, +- optionally append brief protocol text only if needed by the selected mode. + +#### Relevant-turn reinjection +Use `context` for relevant-turn checks. + +Required behavior: +- inspect `event.messages`, +- decide whether the canonical block is already present, +- only add the root pair / budgeted expansion if absent, +- avoid rescanning on every trivial turn in `strong` mode. + +#### Payload fallback +Use `before_provider_request` only as a fallback or debugging surface when message-layer detection is insufficient. + +### 3. Canonical marker design +Deduplication depends on stable canonical detection. + +The implementation should stamp injected content with a canonical marker block. + +Recommended v1 shape: +- a deterministic wrapper such as `` / ``, +- normalized artifact identity lines for root `.pi-map.index.md` and root `.pi-map.md`, +- trust-boundary text within the same wrapped block when the active mode requires it. + +Marker rules: +- stable across turns, +- independent of provider formatting quirks, +- easy to scan in both `event.messages` and final provider payload, +- robust enough that root-pair presence can be detected without brittle full-text matching. + +### 4. Budgeting +Budgeting should be deterministic and layered. + +#### Context-window discovery and fallback +- Prefer active-model context-window metadata exposed by Pi runtime/model selection. +- If context-window metadata is unavailable, fall back to the configured absolute cap. +- The fallback path should be explicit in logs/debug behavior so budget decisions remain auditable. + +#### Required order +1. compute effective budget from relative percentage + optional absolute cap, +2. reserve the root pair first, +3. expand outward using a deterministic traversal order, +4. stop when the budget would be exceeded. + +#### Traversal strategy +The spec does not force exact traversal heuristics, but the design should prefer: +- root pair first, +- shallow structural coverage before deep leaves, +- predictable order over opaque scoring. + +This keeps automatic injection understandable and auditable. + +### 5. Mode control surface +Expose a config/runtime setting for the four modes. + +Because the current project config is loaded from flat JSON in `.pi-project-map.json`, v1 should prefer a flat compatible shape rather than forcing an immediate nested/YAML migration. + +Suggested v1 config shape: + +```json +{ + "promptInjectionMode": "strong", + "contextBudgetPercent": 15, + "contextBudgetMaxTokens": 100000 +} +``` + +Migration note: +- keep existing flat JSON loading in `src/config.ts`, +- treat these as new additive keys, +- decide explicitly whether existing `contextBudget` is deprecated, ignored for injection, or retained only for older LLM-analysis paths. + +Optional runtime UX may later mirror thinking-level controls, but v1 implementation can start with config-driven mode selection as long as the semantics are the same. + +### 6. Mode semantics +#### `off` +- no automatic artifact injection, +- no startup/init hint beyond existing tool/docs discovery. + +#### `advisory` +- startup/init hints enabled, +- optional root-pair preload, +- light reminders, +- weaker reinjection behavior. + +#### `strong` +- root-pair preload required, +- budgeted expansion required, +- relevant-turn reinjection checks required, +- reminders before edits and architecture-sensitive reasoning. + +#### `strict` +- everything in `strong`, plus: +- when protocol path is missing during sensitive actions, require explicit bypass justification. + +### 7. Relevant-turn detection +`strong` mode should not rescan on every turn. + +Relevant-turn triggers should be mapped to concrete runtime signals where possible: +- agent start, +- edit intent / edit tool preparation, +- architecture-sensitive planning prompts, +- compaction completion, +- root-pair artifact change detection. + +This will likely require some combination of: +- hook-local heuristics, +- observed tool calls, +- file timestamp/hash checks for root artifacts, +- compaction event handling. + +### 8. Visibility model +The design should preserve mixed visibility. + +- startup hints: visible and inspectable, +- raw injected artifact blocks: agent-visible by default, +- the fact that automatic injection exists should remain discoverable. + +The implementation may use hidden custom message types for artifact payloads, but should not make startup/init behavior opaque. + +### 9. Validation strategy +This change is validation-heavy. + +Unit tests alone are not enough, because the main risk is runtime interaction between hooks, message mutation, compaction, and reinjection. + +#### Integration focus areas +- startup before init, +- startup after init, +- root-pair marker insertion, +- reinjection suppression when marker already exists, +- reinjection after compaction, +- reinjection after artifact mutation, +- mode differences, +- strict-mode bypass path, +- mixed visibility expectations, +- synthetic event-sequence coverage for relevant-turn heuristics such as edit-intent, architecture-sensitive reasoning, compaction, and artifact invalidation. + +### 10. Documentation impact +Runtime guidance docs must align with the spec, but retrieval docs remain separate. + +Docs should teach: +- startup hint before init, +- root-pair automatic preload after init, +- trust boundary, +- mode ladder, +- relevant-turn reinjection behavior, +- integration-test importance. + +## Risks + +| Risk | Mitigation | +|---|---| +| Message-level scanning misses provider serialization quirks | Add payload fallback via `before_provider_request` | +| Root-pair marker becomes brittle | Use deterministic boundaries and normalized artifact identity lines | +| 15% + 100k is too aggressive in some fleets | Keep both knobs configurable and document the opinionated default | +| Relevant-turn detection becomes fuzzy | Centralize detection heuristics and prove them with integration tests | +| `strict` mode causes friction | Keep `strong` as default and isolate strict-only bypass behavior | + +## Settled defaults + +- Root pair is always guaranteed after init. +- Reinjection avoidance is based on canonical outgoing-context scanning. +- Retrieval remains out of scope. +- Mixed visibility is the intended baseline. +- Four modes exist, with `strong` as default. +- Default budget is 15% of active context window, capped at 100k tokens. diff --git a/openspec/changes/project-map-prompt-injection/proposal.md b/openspec/changes/project-map-prompt-injection/proposal.md new file mode 100644 index 0000000..e778bd1 --- /dev/null +++ b/openspec/changes/project-map-prompt-injection/proposal.md @@ -0,0 +1,88 @@ +# Proposal: Project Map Prompt Injection + +## Status + +| Field | Value | +|---|---| +| Phase | **Proposal** | +| Based on | Grill Me checkpoint + runtime/doc inspection | +| Next | Spec | + +## Problem + +`pi-project-map` currently provides strong generated artifacts and tool surfaces, but weak automatic runtime guidance. + +Today the repo has: +- a one-time `before_agent_start` hint, +- a `session_start` dirty-state UI notification, +- tool metadata and docs, +- generated `.pi-map.md` / `.pi-map.index.md` artifacts. + +But it lacks a clear spec for: +1. when maps/indexes should be injected automatically, +2. how much should be injected under a context budget, +3. how reinjection should avoid wasting prompt space, +4. how visible that guidance should be to the user, +5. how strong enforcement should be, +6. how to validate this behavior with integration tests. + +## Proposed change + +Adopt a runtime prompt-injection policy for project-map that: +- always injects the **root pair** after init, +- expands outward under a **hybrid context budget cap**, +- avoids redundant reinjection by scanning the actual outgoing context, +- keeps **retrieval guidance separate** from this spec, +- exposes **four configurable guidance modes** (`off`, `advisory`, `strong`, `strict`), +- uses **mixed visibility**: user-visible startup hints, agent-visible artifact injection, +- requires **extensive integration tests** for reinjection and context-scanning behavior. + +## In scope + +- [ ] Define pre-init startup hint behavior +- [ ] Define post-init automatic root-pair preload behavior +- [ ] Define hybrid budget defaults and config shape +- [ ] Define outgoing-context scanning for reinjection avoidance +- [ ] Define visibility model for hints vs injected artifacts +- [ ] Define configurable guidance-strength modes and default +- [ ] Define relevant-turn reinjection triggers for `strong` +- [ ] Define strict-mode bypass-justification behavior at the spec level +- [ ] Define validation and integration-test expectations +- [ ] Define implementation slices for runtime hooks/config/tests/docs + +## Out of scope + +- [ ] Redesign retrieval ranking or `project_map_context` +- [ ] Merge retrieval behavior into this policy spec +- [ ] Redesign paired artifact contents +- [ ] Introduce vector stores, Engram, or external retrieval backends +- [ ] Guarantee provider-agnostic perfect token counting beyond best-effort budgeting + +## Decisions from grilling + +| Topic | Decision | +|---|---| +| Change slug | `project-map-prompt-injection` | +| Scope split | Retrieval remains a separate spec | +| Pre-init | Inject only a lightweight `project_map_init` hint | +| Fake/synthetic maps before init | No | +| Guaranteed minimum | Always inject root `.pi-map.index.md` + root `.pi-map.md` | +| Budget model | Hybrid cap | +| Budget config | Relative percentage + optional absolute cap; smaller wins | +| Budget default | 15% of context window, capped at 100k tokens | +| Reinjection avoidance | Canonical marker scanning in actual outgoing context | +| Visibility | Mixed | +| Mode set | `off`, `advisory`, `strong`, `strict` | +| Default mode | `strong` | +| `strong` triggers | Relevant turns only | +| Validation | Extensive integration tests required | + +## Success criteria + +- [ ] The spec clearly defines what is injected before and after init +- [ ] The spec clearly defines how much is injected and how budgets are applied +- [ ] The spec clearly defines when reinjection checks happen and how duplicates are avoided +- [ ] The spec clearly defines mode semantics and the default mode +- [ ] The spec clearly separates runtime injection policy from retrieval behavior +- [ ] The implementation plan can be executed in narrow, reviewable slices +- [ ] The validation section makes integration coverage a first-class requirement diff --git a/openspec/changes/project-map-prompt-injection/spec.md b/openspec/changes/project-map-prompt-injection/spec.md new file mode 100644 index 0000000..326e83c --- /dev/null +++ b/openspec/changes/project-map-prompt-injection/spec.md @@ -0,0 +1,226 @@ +# Spec: Project Map Prompt Injection + +## Status + +| Field | Value | +|---|---| +| Phase | **Spec** | +| Based on | [Proposal](proposal.md) | +| Next | Design | + +## Overview + +`pi-project-map` must define a deliberate automatic runtime guidance model for map/index usage. After init, the system should preload the root pair, expand under a bounded context budget, avoid redundant reinjection by inspecting actual outgoing context, and scale enforcement through configurable guidance modes. + +This spec covers **automatic injection and maintenance guidance only**. Retrieval behavior remains covered by `map-context-retrieval`. + +## Decisions + +| # | Question | Answer | +|---|---|---| +| 1 | Retrieval included in this spec | No | +| 2 | Pre-init behavior | Lightweight init hint only | +| 3 | Synthetic map content before init | No | +| 4 | Guaranteed post-init minimum | Always inject root pair | +| 5 | Budget model | Hybrid cap | +| 6 | Budget knobs | Relative percentage + optional absolute cap | +| 7 | Budget default | 15% of context window, capped at 100k tokens | +| 8 | Reinjection avoidance | Canonical marker scan in outgoing context/payload | +| 9 | Visibility | Mixed | +| 10 | Mode set | `off`, `advisory`, `strong`, `strict` | +| 11 | Default mode | `strong` | +| 12 | `strong` reinjection cadence | Relevant turns only | +| 13 | Validation expectation | Extensive integration coverage | + +## Functional requirements + +### 1. Pre-init behavior +Before generated map/index artifacts exist, the extension must inject only a lightweight startup hint. + +#### Required behavior +- The hint must tell the agent that the project-map extension is active. +- The hint must instruct the agent to run `project_map_init`. +- The hint must not claim that real map/index artifacts already exist. +- The system must not inject synthetic or fake map content before real artifacts are generated. + +### 2. Post-init guaranteed preload +After real artifacts exist, the system must guarantee a minimum preload of the root pair: +- root `.pi-map.index.md` +- root `.pi-map.md` + +This root pair is the minimum automatic preload before budgeted expansion begins. + +### 3. Trust boundary +The runtime policy must encode the trust boundary: + +> **index routes, map orients, source decides** + +Required implications: +1. Indexes are navigation aids, not final authority. +2. Maps provide orientation and architectural context, not final authority. +3. Source must remain the final authority before edits or exact behavioral claims. +4. If injected artifacts and source disagree, source wins. + +### 4. Budget model +Automatic expansion beyond the root pair must use a hybrid context budget cap. + +#### Knobs +The system must support: +- a **relative context-budget percentage**, +- an **optional absolute token cap**. + +If both are configured, the smaller effective budget wins. + +#### Default budget +The default must be: +- **15%** of the active model context window, +- **100k tokens** absolute cap, +- use the smaller effective budget. + +#### Context-window discovery and fallback +- The runtime should derive the active model context window from Pi model metadata when available. +- If the active model context window is unavailable, the runtime must still honor the absolute cap. +- In that fallback case, implementations may skip the relative calculation and use the absolute cap as the effective budget. + +#### Expansion rules +- Root pair injection happens before budgeted expansion. +- Additional map/index artifacts are added only while the budget allows. +- The expansion strategy should prefer shallow, high-value structural coverage over deep indiscriminate expansion. +- The spec does not require exact provider-token parity; best-effort budgeting is acceptable if it is deterministic and auditable. + +### 5. Reinjection avoidance +The extension must avoid redundant reinjection once the root pair is already in active outgoing context. + +#### Required definition +"Already in context" must be defined by scanning the **actual outgoing context**, not only by session guesses. + +#### Required behavior +- Before reinjecting, scan per-turn `event.messages` for a stable canonical marker or normalized injected root-pair block. +- If message-layer evidence is insufficient, the runtime may additionally inspect the final provider payload. +- Inject only when the canonical root-pair marker/block is absent. +- The spec must allow implementation via explicit scanning logic even if Pi does not expose a convenience API. + +### 6. Visibility model +The system must use mixed visibility. + +#### Required behavior +- Lightweight startup/init hints should be user-visible and inspectable. +- Automatic artifact injection may remain agent-visible by default. +- The spec should preserve debuggability: implementations should make the presence of automatic guidance discoverable, even when raw artifact blocks are not fully dumped to the user on every turn. + +### 7. Guidance-strength modes +The system must support four named modes: +- `off` +- `advisory` +- `strong` +- `strict` + +#### Protocol path definition +For this spec, the **protocol path** is present when the current outgoing context contains: +1. the canonical injected root-pair block, or an equivalent canonical marker proving that root `.pi-map.index.md` and root `.pi-map.md` are already present, and +2. the trust-boundary instruction establishing that `index routes, map orients, source decides`. + +If either element is missing for a sensitive action, the protocol path is missing. + +#### Mode semantics +- **`off`** + - no automatic injection beyond tool/docs discovery. +- **`advisory`** + - inject startup/init hints, + - allow optional root-pair preload, + - use light reminders. +- **`strong`** + - inject root pair, + - expand under the configured budget, + - run reinjection checks on relevant turns, + - remind before edits or architecture-sensitive reasoning. +- **`strict`** + - same as `strong`, plus: + - require explicit bypass justification before sensitive edits or architectural claims when the protocol path is missing. + +#### Default mode +The default mode must be **`strong`**. + +### 8. `strong`-mode trigger timing +In `strong` mode, reinjection checks must happen on relevant turns only. + +Required triggers: +- agent start, +- before edits, +- before architecture-sensitive reasoning, +- after compaction, +- after root-pair artifact changes. + +Required non-trigger: +- do not rescan on every trivial turn. + +### 9. Implementation surfaces +The runtime may achieve this behavior through a combination of: +- startup hooks, +- per-turn context hooks, +- provider-payload hooks, +- prompt guidance, +- generated root artifacts. + +The spec intentionally does **not** require one exact implementation mechanism, but it does require the observable runtime behavior above. + +### 10. Validation requirements +The implementation must be proven with extensive integration coverage. + +At minimum, integration coverage must validate: +- pre-init hint behavior, +- post-init root-pair injection, +- budgeted expansion behavior, +- canonical-marker dedupe, +- reinjection after compaction, +- reinjection after root-pair artifact changes, +- mixed visibility behavior, +- guidance-mode differences, +- strict-mode bypass behavior where implemented. + +## Non-functional requirements + +- Keep the policy explicit and auditable. +- Keep retrieval out of scope for this spec. +- Prefer deterministic behavior over opaque heuristics where possible. +- Optimize for modern large-context models, while retaining a hard ceiling. +- Preserve source as final authority. + +## User flows + +### Flow 1: New repo, maps not initialized +1. Agent starts in a repo without project-map artifacts. +2. Runtime injects a lightweight visible startup hint. +3. Agent is instructed to run `project_map_init`. +4. No fake artifact content is injected. + +### Flow 2: Normal initialized repo in `strong` mode +1. Agent starts. +2. Runtime checks outgoing context for canonical root-pair marker. +3. If absent, inject root pair and budgeted expansion. +4. On relevant later turns, runtime rescans only when trigger conditions apply. +5. Before edits, agent is reminded to use injected context and then verify source. + +### Flow 3: Compaction or artifact invalidation +1. Context compacts or root-pair artifacts change. +2. Runtime treats that as a relevant reinjection trigger. +3. Runtime rescans outgoing context. +4. If canonical root-pair block is absent, inject again. + +### Flow 4: Strict-mode sensitive action +1. Agent approaches a sensitive edit or architectural claim. +2. Runtime checks whether the protocol path is present. +3. If not, runtime requires explicit bypass justification before proceeding. + +## Acceptance criteria + +- [ ] Pre-init behavior is hint-only and never injects fake map content +- [ ] Post-init behavior always guarantees root pair preload before budgeted expansion +- [ ] Budgeting supports both relative and absolute caps, with the smaller effective budget winning +- [ ] Default budget is 15% of active context window, capped at 100k tokens, with absolute-cap fallback when context-window metadata is unavailable +- [ ] Reinjection avoidance is based on actual outgoing-context scanning +- [ ] Mixed visibility is honored +- [ ] Four guidance modes exist with `strong` as default +- [ ] `strong` checks fire on relevant turns only +- [ ] `strict` adds bypass-justification semantics for missing protocol path on sensitive actions +- [ ] Extensive integration tests cover context scanning and reinjection behavior diff --git a/openspec/changes/project-map-prompt-injection/tasks.md b/openspec/changes/project-map-prompt-injection/tasks.md new file mode 100644 index 0000000..acbea66 --- /dev/null +++ b/openspec/changes/project-map-prompt-injection/tasks.md @@ -0,0 +1,90 @@ +# Tasks: Project Map Prompt Injection + +## Status + +| Field | Value | +|---|---| +| Phase | **Tasks** | +| Based on | [Design](design.md) | +| Next | Apply | + +## Delivery slices + +### Slice 1: Injection policy scaffold and config surface +**Scope**: mode/config scaffolding, pre-init hint behavior, canonical helper boundaries +**Review goal**: establish the policy control surface without yet wiring the full runtime pipeline + +**Tasks**: +1. [ ] Add a shared prompt-injection policy helper/module +2. [ ] Add config support for injection mode, context-budget percent, and absolute cap using additive flat JSON keys compatible with existing `.pi-project-map.json` loading +3. [ ] Decide and document how existing `contextBudget` interacts with the new injection-budget knobs +4. [ ] Implement pre-init startup-hint behavior with no synthetic artifact injection +5. [ ] Define canonical marker/block construction for injected root-pair content +6. [ ] Add/update tests for config loading and pre-init hint behavior + +### Slice 2: Root-pair preload and budgeted expansion +**Scope**: post-init preload, budget calculation, artifact selection under cap +**Review goal**: make automatic injection materially real after init + +**Tasks**: +1. [ ] Implement guaranteed root-pair preload after init +2. [ ] Implement effective-budget calculation using percent + absolute cap with smaller-wins semantics +3. [ ] Implement active-model context-window discovery and explicit absolute-cap fallback when metadata is unavailable +4. [ ] Implement deterministic budgeted expansion beyond the root pair +5. [ ] Keep retrieval explicitly out of this injection path +6. [ ] Add/update tests for root-pair guarantee, context-window fallback, and budget-capped expansion + +### Slice 3: Reinjection avoidance and relevant-turn checks +**Scope**: outgoing-context scanning, relevant-turn triggers, compaction/artifact invalidation +**Review goal**: avoid wasteful reinjection while preserving strong guidance + +**Tasks**: +1. [ ] Implement canonical marker scanning over `event.messages` +2. [ ] Add fallback inspection of final provider payload when needed +3. [ ] Implement relevant-turn reinjection triggers for `strong` mode +4. [ ] Reinject after compaction and after root-pair artifact changes +5. [ ] Add/update integration tests for dedupe, reinjection suppression, and reinjection after invalidation +6. [ ] Include synthetic event-sequence coverage for edit-intent, architecture-sensitive reasoning, compaction, and artifact-change heuristics + +### Slice 4: Mode semantics, visibility, and strict-path behavior +**Scope**: off/advisory/strong/strict semantics, mixed visibility, strict bypass behavior +**Review goal**: make the mode ladder operational and reviewable + +**Tasks**: +1. [ ] Implement mode-specific behavior for `off`, `advisory`, `strong`, and `strict` +2. [ ] Define and enforce the spec meaning of a missing `protocol path` during sensitive actions +3. [ ] Keep startup hints user-visible and artifact injection agent-visible by default +4. [ ] Implement strict-mode explicit bypass-justification behavior for sensitive edits/architectural claims +5. [ ] Add/update integration tests for visibility, protocol-path detection, and mode differences +6. [ ] Verify that `strong` remains the default behavior + +### Slice 5: Documentation and runtime alignment +**Scope**: docs, runtime guidance text, implementation notes +**Review goal**: align user-facing/runtime-facing guidance with the frozen spec + +**Tasks**: +1. [ ] Update runtime guidance strings to reflect init-hint behavior, root-pair preload, trust boundary, and mode ladder +2. [ ] Update docs/skill guidance for the prompt-injection policy +3. [ ] Keep retrieval guidance separate from these docs or clearly reference it as separate +4. [ ] Document the opinionated default budget and configurability +5. [ ] Summarize integration-test expectations and known risks + +## Acceptance checklist + +- [ ] Before init, only a lightweight `project_map_init` hint is injected +- [ ] No synthetic map/index artifact content is injected before init +- [ ] After init, root `.pi-map.index.md` and root `.pi-map.md` are always guaranteed before budgeted expansion +- [ ] Expansion uses a hybrid cap with both relative and absolute knobs, smaller effective budget wins +- [ ] Default budget is 15% of active context window, capped at 100k tokens +- [ ] Reinjection avoidance is based on canonical marker scanning in actual outgoing context +- [ ] `strong` checks only relevant turns, not every trivial turn +- [ ] Modes `off`, `advisory`, `strong`, and `strict` are implemented with the agreed semantics +- [ ] Mixed visibility behavior is preserved +- [ ] Retrieval behavior remains separate from this spec’s implementation scope +- [ ] Extensive integration tests validate context scanning and reinjection behavior +- [ ] `npm run typecheck` passes +- [ ] `npm test` passes +- [ ] `npm run lint` passes + +## Review workload note +This change mixes runtime hook behavior, prompt budgeting, context dedupe, visibility policy, and strict-mode enforcement. Keep delivery narrow and test-heavy. Avoid collapsing this into one oversized implementation slice.