Repository navigation
Provider permissions: history redaction on model switch #168
Copy link
Copy link
Closed
Labels
afkImplement + merge unattendedImplement + merge unattended
Description
Important
Decision Surface
Problem: When switching from Model A (trusted) to Model B (limited), file contents already in the conversation history from directories denied by Model B's tier would leak to the new provider.
Approach: Implement redactHistory(messages, newModelId) — walks messages, checks each sourcePaths entry against the new model's tier, and replaces denied content with a placeholder at send-time. Does NOT mutate stored messages (filters a copy).
Scope: Redaction logic + integration at the model-switch point. Requires slices #2 (resolution) and #3 (source-path tagging).
Acceptance Criteria
-
redactHistory(messages, modelId)returns a filtered copy of messages with denied content replaced - Replacement text is:
[Content from {path} filtered — trust tier "{tierLabel}" does not have read access] - Messages with no
sourcePathsmetadata are passed through unchanged (not redacted) - Messages with sourcePaths in allowed directories are passed through unchanged
- The stored message history is NEVER mutated — redaction produces a new array for the API call
- If the model switches back to the original (trusted) model, the original content is visible again (because stored messages are untouched)
- Redaction is called automatically when the LLM runner detects a provider/model change
- Multiple sourcePaths in one message: redact only the portions from denied paths (if the message contains content from both allowed and denied dirs, keep the allowed portions)
Key Decisions
| # | Decision | Rationale |
|---|---|---|
| 1 | Non-mutating filter (copy on send) | Switching back to a trusted model should restore visibility; also preserves audit trail |
| 2 | Per-sourcePath granularity | A single tool result might reference multiple files; redact only the denied ones |
| 3 | Placeholder names the tier | User/debugging visibility into why content disappeared |
Testing Decisions
- Test message with denied sourcePath → content replaced with placeholder
- Test message with allowed sourcePath → unchanged
- Test message with no sourcePaths → unchanged
- Test original messages array is not mutated
- Test switch-back scenario: redact for model B, then re-send to model A without redaction
- Test mixed sourcePaths (one allowed, one denied) → partial redaction
- Extends Provider permissions: tier resolution engine #165 and Provider permissions: source-path tagging on tool results #166 test surface
Constraints & Invariants
- Redaction must be fast enough for large histories (linear scan, no re-resolution of already-computed tier lookups within one call)
- A message whose content is fully redacted still appears in history (as the placeholder) — never dropped entirely
Source
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
afkImplement + merge unattendedImplement + merge unattended
Activity