spec(prompt): add project map prompt injection change set
This commit is contained in:
@@ -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 `<!-- PI_MAP_ROOT_PAIR_START -->` / `<!-- PI_MAP_ROOT_PAIR_END -->`,
|
||||
- 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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user