Files
AirCoding/packages/contracts/src/permission.ts
AirCoding a773bac28c P0-P8: Full V1.0.0 Alpha implementation + audit reports
Implements 123 tasks across 9 phases (T-001..T-809) totaling 146 source files.

Monorepo (P0):
- 7-package Bun + Turborepo + TypeScript monorepo
- dependency-cruiser enforcing 7 forbidden edges + 5 deep-import rules

Contracts (P0):
- 16 type files (ids/error/event/runtime/ipc/task/worker-result/tool/artifact/evidence/project/provider/permission/ui/capability/platform)

Storage & Events (P1):
- DatabaseManager + MigrationRunner (19 tables, 22 indexes, 5 schema_meta seeds)
- 16 repositories (Repository<T,I,U> pattern, INV-1 status columns via EventStore.project only)
- EventSchemaRegistry (54 durable + 7 ephemeral), EventStore, EventBus, EventIngestor
- Project/Session/Artifact/Evidence stores + 8-step Recovery

Tools & Permission (P2):
- PathClassifier (8 categories), CommandRiskAnalyzer (10 categories), SecretRedactor
- PermissionEngine 6-layer evaluation (capability→profile→task_scope→risk→credential→user_prompt)
- ToolRegistry with 20+ tools across fs/shell/git/project/artifact/context/permission/doctor
- CapabilityManifestValidator + CapabilityRegistry

LLM & Context (P3):
- ModelConfigLoader, CapabilityMatrix, AnthropicCanonicalConverter
- AnthropicAdapter + OpenAICompatibleAdapter
- ProviderManager facade
- PromptLayerLoader (L0/L1/L3/L5), CompactionPolicy, ContextAssembler

Worker IPC & Scheduler (P4):
- WorkerProtocol (NDJSON), WorkerProcess (exit codes 0-5), WorkerManager (spawn/handshake)
- WorkerRuntime (INV-3: IPC only, no direct fs/shell/SQLite)
- 5 worker roles (Executor/Reviewer/Debugger/Compactor/ExperienceMiner)
- TaskGraph, WavePlanner, RetryPlanner, AgentMonitor, WorkspaceManager
- Scheduler (state machine), 8-step Recovery

C++ Toolchain (P5):
- DiagnosticParser, CppProjectDetector, CMakeConfigurator, CppBuilder
- CppTestRunner, CppcheckRunner, ClangdClient
- CppToolRegistrar + capability manifest

Projection & TUI (P6):
- ProjectionStore (hydrate/apply/snapshot/subscribe)
- TuiApp + 8 components (Session/Task/Agent/Tool/Diff/Evidence/Permission/Blocker/Hud)
- ProjectionClient in-process ref

Agents & Knowledge (P7):
- MainAgent, ArchitectureDesigner
- DebugKnowledgeStore + LearnedMemoryStore (single-writer, outbox model)
- Role integration wiring

CLI & Doctor & Release (P8):
- Logger + DeveloperLogEncryptor (AES-256-GCM)
- DoctorService (self_bootstrap first)
- RuntimeApp + ServiceRegistry
- 11 CLI commands: run/init/doctor/provider/resume/compact/history/session/restore/e2e/release
- CliEntrypoint + air<TODO>

Audit (in AirPlan/docs/):
- Deepseek开发阶段审计.md (97 findings)
- Opus开发阶段审计.md (140+ findings, 18 P0 blockers)
- MiniMaxM3开发阶段审计.md (18 P0 blockers, focuses on executability)
- AirPlan/TODO.md (technical debt + 42 TODOs by phase)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 19:19:55 +08:00

124 lines
4.3 KiB
TypeScript
Executable File

// contracts §13 — Permission Contracts
// File: permission.ts — PathPolicy, PermissionRequestContext, PermissionAction,
// PermissionGrantScope, PermissionDecision, PermissionRecordResult, PermissionEngine
import type { SessionID, TaskID, AgentID, EvidenceRefID } from './ids.js'
import type { AirError } from './error.js'
// Re-export PathPolicy and ToolPermissionSpec from tool.ts so they are also
// available from this module per the DD §3 file map (PathPolicy canonical
// assignment: permission.ts) and downstream import expectations.
export type { PathPolicy, ToolPermissionSpec } from './tool.js'
// =============================================================================
// §13 — Permission Contracts
// =============================================================================
/**
* Context provided when the ToolRegistry requests a permission evaluation.
* Constructed from ToolExecutionContext + ToolDefinition.permissions + input
* paths/commands per DD §9.1.
*/
export interface PermissionRequestContext {
session_id: SessionID
task_id?: TaskID
agent_id?: AgentID
tool_name?: string
command?: string
paths?: string[]
network?: boolean
requested_action: string
reason: string
}
/**
* Actions the PermissionEngine can return.
* ToolRegistry.call branches on these per DD §9.3:
*
* allow — execute; create backup first if backup_required
* announce_then_run — emit visible notice, then execute unless interrupted;
* bounded by grant_scope
* ask_user — suspend; emit permission.prompt.requested;
* resume on permission.prompt.resolved
* deny — do not execute; return ToolResultEnvelope{status:"error"};
* caller may pick safe path
* block — return blocked outcome → task.blocked upstream
* refuse — return AirError{kind:"policy_error"}; no execution
*/
export type PermissionAction =
| 'allow'
| 'announce_then_run'
| 'ask_user'
| 'deny'
| 'block'
| 'refuse'
/**
* Scope of a permission grant. Determines how long the granted action
* remains valid before re-evaluation is required.
*
* none — no grant (decision is informational only)
* once — valid for this single invocation
* session — valid for the remainder of the session
* project — valid across sessions for this project
* global — valid across all projects for this user
*/
export type PermissionGrantScope =
| 'none'
| 'once'
| 'session'
| 'project'
| 'global'
/**
* Risk levels assigned by the PermissionEngine during evaluation.
* Used by downstream branching logic and UI presentation.
*/
export type PermissionRiskLevel = 'low' | 'medium' | 'high' | 'critical'
/**
* Decision returned by PermissionEngine.evaluate.
* Matches DD §22.1 specification and DD §9.3 branching table.
*
* Layered evaluation order (contracts §13, runtime-semantics §8, overview §12):
* 1. tool capability declaration
* 2. permission profile (permission_template)
* 3. TaskSpec scope allowed/denied paths
* 4. path/command/network risk classification (PathClassifier + CommandRiskAnalyzer)
* 5. credential/system-sensitive override
* 6. user prompt workflow if required
*/
export interface PermissionDecision {
action: PermissionAction
grant_scope: PermissionGrantScope
risk_level: PermissionRiskLevel
reason: string
required_confirmation?: boolean
backup_required?: boolean
evidence_ref_ids?: EvidenceRefID[]
}
/**
* Result of recording a permission decision.
* PermissionEngine.record writes a permission.decision.recorded durable event
* and returns this result; on write failure it returns {ok:false, error}.
*/
export interface PermissionRecordResult {
ok: boolean
error?: AirError
}
/**
* Core permission evaluation engine interface.
* Implements contracts §13, referenced by ToolRegistry (DD §9.1, §9.3).
*
* Invariants (DD §9.2):
* - project-level allow never overrides task scope
* - credential/system-sensitive overrides broad allows
* - paths normalized via realpath before prefix checks
* - .git/ internals protected
*/
export interface PermissionEngine {
evaluate(context: PermissionRequestContext): Promise<PermissionDecision>
record(decision: PermissionDecision, context: PermissionRequestContext): Promise<PermissionRecordResult>
}