mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-08-28 16:45:22 +00:00
feat: vendor permission system source
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
---
|
||||
issue: 54
|
||||
issue_title: "Verify doom_loop detection fires end-to-end"
|
||||
---
|
||||
|
||||
# Deprecate `doom_loop` special permission key
|
||||
|
||||
## Problem Statement
|
||||
|
||||
The `doom_loop` key is declared as a `SpecialPermissionName`, accepted in config under `special.doom_loop`, and resolved through `checkPermission()`.
|
||||
However, nothing in this extension or in Pi's core ever calls `checkPermission("doom_loop", ...)` at runtime.
|
||||
|
||||
Investigation of Pi's source (`~/development/pi/pi-mono/packages/coding-agent/src/`) confirms: Pi has **no doom_loop detection**.
|
||||
The `tool_call` event only fires for actual tool names (`bash`, `read`, `edit`, etc.) — there is no repeated-tool-call tracking or synthetic `doom_loop` event.
|
||||
|
||||
In OpenCode, doom_loop detection lives in the **session processor** (core runtime), not in the permission extension.
|
||||
The permission system only resolves the policy gate when the core fires the check.
|
||||
Implementing detection inside a permission extension would be a layering violation — mixing condition detection with policy enforcement.
|
||||
|
||||
Per AGENTS.md: "Treat any declared config field not read at runtime as a maintenance trap."
|
||||
The key is dead code and should be deprecated.
|
||||
|
||||
## Goals
|
||||
|
||||
- Deprecate `special.doom_loop` with a config-issue warning (same pattern as `tool_call_limit`).
|
||||
- Remove `doom_loop` from the TypeScript types, JSON schema allowed properties, example config, and README.
|
||||
- Keep the config loader tolerant: accept the legacy key, emit a single non-fatal warning, discard the value.
|
||||
- File a Pi upstream issue requesting core-level doom_loop detection (out of scope for this change, tracked as a follow-up).
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Implementing doom_loop detection in this extension (layering violation — detection belongs in Pi core).
|
||||
- Changing `external_directory` or any other special key.
|
||||
- Touching the `SpecialPermissionName` union beyond removing `doom_loop` (if `external_directory` is the only remaining member, keep the type for extensibility).
|
||||
|
||||
## Background
|
||||
|
||||
### Permission surface
|
||||
|
||||
`special` — reserved permission checks for runtime behaviors that are not tied to a specific tool.
|
||||
|
||||
### Relevant modules
|
||||
|
||||
| File | Role |
|
||||
| --------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| `src/types.ts` | `SpecialPermissionName` type union includes `"doom_loop"` |
|
||||
| `src/permission-manager.ts` | `SPECIAL_PERMISSION_KEYS` set includes `"doom_loop"`; `checkPermission()` routes it to the special surface |
|
||||
| `src/config-loader.ts` | `SPECIAL_PERMISSION_KEYS` set (duplicate) includes `"doom_loop"` |
|
||||
| `src/extension-config.ts` | `PERMISSION_POLICY_KEYS` set includes `"doom_loop"` for misplaced-key detection |
|
||||
| `schemas/permissions.schema.json` | `special.doom_loop` property definition |
|
||||
| `config/config.example.json` | `"doom_loop": "deny"` example entry |
|
||||
| `README.md` | Documents `doom_loop` in the special permissions table |
|
||||
|
||||
### Precedent
|
||||
|
||||
`tool_call_limit` was deprecated in the same pattern: added to `DEPRECATED_SPECIAL_KEYS` in `permission-manager.ts`, stripped from normalized output, config issue emitted, removed from schema/types/docs.
|
||||
|
||||
## Design Overview
|
||||
|
||||
Follow the exact `tool_call_limit` deprecation pattern:
|
||||
|
||||
1. Add `"doom_loop"` to `DEPRECATED_SPECIAL_KEYS` in `src/permission-manager.ts`.
|
||||
2. Remove `"doom_loop"` from `SPECIAL_PERMISSION_KEYS` in both `src/permission-manager.ts` and `src/config-loader.ts`.
|
||||
3. Remove `"doom_loop"` from the `SpecialPermissionName` type union in `src/types.ts`.
|
||||
4. Remove `"doom_loop"` from `PERMISSION_POLICY_KEYS` in `src/extension-config.ts` (it is no longer a valid policy key to detect as misplaced).
|
||||
5. Remove the `doom_loop` property from `special` in the JSON schema.
|
||||
6. Remove `doom_loop` from the example config and README.
|
||||
7. Existing configs with `doom_loop` get a deprecation warning and the value is silently discarded — no crash, no behavior change.
|
||||
|
||||
### Type change
|
||||
|
||||
```typescript
|
||||
// Before
|
||||
export type SpecialPermissionName = "doom_loop" | "external_directory";
|
||||
|
||||
// After
|
||||
export type SpecialPermissionName = "external_directory";
|
||||
```
|
||||
|
||||
### Schema change
|
||||
|
||||
Remove the `doom_loop` property from `special.properties`.
|
||||
Add a deprecated note if desired, or simply remove (the loader tolerance handles on-disk configs).
|
||||
|
||||
## Module-Level Changes
|
||||
|
||||
| File | Change |
|
||||
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `src/types.ts` | Remove `"doom_loop"` from `SpecialPermissionName` union |
|
||||
| `src/permission-manager.ts` | Move `"doom_loop"` from `SPECIAL_PERMISSION_KEYS` to `DEPRECATED_SPECIAL_KEYS` |
|
||||
| `src/config-loader.ts` | Remove `"doom_loop"` from `SPECIAL_PERMISSION_KEYS` |
|
||||
| `src/extension-config.ts` | Remove `"doom_loop"` from `PERMISSION_POLICY_KEYS` |
|
||||
| `schemas/permissions.schema.json` | Remove `doom_loop` property from `special`; update `special` description to mention only `external_directory` |
|
||||
| `config/config.example.json` | Remove `"doom_loop": "deny"` line |
|
||||
| `README.md` | Remove `doom_loop` row from special permissions table; update description text |
|
||||
| `docs/architecture/current-architecture.md` | Update example config snippet if it references `doom_loop` |
|
||||
| `tests/permission-system.test.ts` | Update tests: doom_loop should now emit a deprecation warning and be stripped; existing doom_loop resolution tests become deprecation-behavior tests |
|
||||
| `tests/config-loader.test.ts` | Update test that checks `special: { doom_loop: "deny" }` normalization |
|
||||
| `tests/extension-config.test.ts` | Remove `doom_loop` from misplaced-key test expectations |
|
||||
|
||||
## TDD Order
|
||||
|
||||
1. **Red**: test that `normalizeRawPermission({ special: { doom_loop: "ask" } })` returns `configIssues` containing a deprecation message and `permissions.special` does not contain `doom_loop`.
|
||||
Commit: `test: doom_loop deprecation warning from normalizeRawPermission`
|
||||
|
||||
2. **Green**: add `"doom_loop"` to `DEPRECATED_SPECIAL_KEYS`, remove from `SPECIAL_PERMISSION_KEYS` in `permission-manager.ts`.
|
||||
Commit: `feat: deprecate doom_loop special permission key`
|
||||
|
||||
3. **Red**: test that `checkPermission("doom_loop", {})` falls through to `defaultPolicy.special` (no longer matches as a special key — returns default).
|
||||
Commit: `test: doom_loop checkPermission falls through to default`
|
||||
|
||||
4. **Green**: remove `"doom_loop"` from `SPECIAL_PERMISSION_KEYS` in `config-loader.ts`, remove from `SpecialPermissionName` type.
|
||||
Commit: `feat: remove doom_loop from type union and config-loader`
|
||||
|
||||
5. **Update existing tests**: fix tests that assert `doom_loop` resolution, `doom_loop` in normalized output, or `doom_loop` in misplaced-key detection.
|
||||
Commit: `test: update doom_loop assertions for deprecation`
|
||||
|
||||
6. **Docs + schema + example**: remove `doom_loop` from schema, example config, README, and architecture docs.
|
||||
Commit: `docs: remove doom_loop from schema, example, and README`
|
||||
|
||||
## Risks and Mitigations
|
||||
|
||||
| Risk | Mitigation |
|
||||
| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Users with `doom_loop` in config see a new warning | Warning is non-fatal and actionable ("remove it from your policy file"). Same UX as `tool_call_limit` deprecation. |
|
||||
| Could this silently weaken a permission? | No — the key was already dead code. No runtime check ever fired `checkPermission("doom_loop")`, so removing it changes zero runtime decisions. |
|
||||
| Future Pi core doom_loop detection breaks | If Pi adds native detection that fires `checkPermission("doom_loop")`, we re-add the key. The deprecation warning tells users to remove it, so re-adding is non-breaking. |
|
||||
| `defaultPolicy.special` description references doom_loop | Update schema and README description text to mention only `external_directory`. |
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Should we file a Pi upstream issue requesting core-level doom_loop detection?
|
||||
Deferred to a follow-up after this change lands.
|
||||
- If `external_directory` becomes the only special key, should the `special` surface be reconsidered?
|
||||
Deferred to #56 (unify Rule type), which determines the long-term shape of surfaces.
|
||||
Reference in New Issue
Block a user