- mitm-handler-base: hookBufferStart returns InterceptedRequest with
sanitized headers, extractSourceModel parses body.model, writeError
emits JSON with sanitized message (Hard Rule #12).
- mitm-handler-<id>: nine per-agent happy-path tests (antigravity,
kiro, copilot, codex, cursor, zed, claude-code, open-code) exercise
full intercept() with mocked fetch via _mitmHandlerHarness.ts;
asserts mapped model is forwarded and AgentBridge correlation
headers are present. Trae test confirms intercept() rejects with a
structured error.
- mitm-targets-resolve: ALL_TARGETS contains 9 entries; resolveTarget
is case-insensitive and returns null for unknown hosts.
- mitm-targets-route: bypass > target > passthrough precedence
validated against representative hostnames.
- mitm-detection: DETECTORS covers every AgentId; detectAgent never
throws and returns DetectionResult-shaped objects for all probes.
PRE-hook (before executor dispatch):
- Calls enforceQuotaShare via dynamic import (lazy load, fail-open).
- Returns 429 JSON via buildErrorBody() when decision.kind === 'block' (B25).
- Sets quotaSoftDeprioritize=true when decision.deprioritize=true (B17).
POST-hook (after successful response):
- Calls scheduleRecordConsumption for both streaming and non-streaming paths.
- Fire-and-forget via setImmediate; never blocks the client response (B29).
Both hooks use try/catch outer guards so any unexpected error fails open (B16).
scheduleRecordConsumption() wraps recordConsumption() in setImmediate so it
never adds latency to the client response path. Errors are caught and logged
via pino warn but NEVER propagated to the caller (B29 fail-open contract).
Implements the quota share enforcement gate and consumption recorder:
- enforceQuotaShare(): PRE-request check that returns allow/block/deprioritize
based on fair-share algorithm, saturation signals, and pool allocations.
- recordConsumption(): POST-response tracker that increments per-key counters
for each active plan dimension.
Both functions fail-open per B16/B29: any infra error → allow + warn log.
Adds 5 new settings route handlers for CLIs introduced by plan 14 that
declare configType:"custom" and need automated config file persistence:
forge (~/.forge/config.toml), jcode (~/.jcode/config.json),
deepseek-tui (~/.config/deepseek-tui/config.toml),
smelt (~/.smelt/config.json), pi (~/.pi/config.json).
Also registers the 5 tools in cliRuntime.ts path table so
getCliPrimaryConfigPath() resolves their config paths correctly.
Each handler follows the established pattern: requireCliToolsAuth guard on
every exported method, Zod body validation on POST, buildErrorBody/
sanitizeErrorMessage on all error paths (Hard Rule #12), fs/promises only
(no exec/spawn — Hard Rule #13), saveCliToolLastConfigured on success.
Integration tests: 7 subtests per handler (401 without auth, 200 GET,
400 missing-baseUrl, 400 missing-model, 200 POST writes file, 200 DELETE,
error sanitization + no exec/spawn static audit).
- compliance-tab-actor-filter.test.tsx: 4 tests verifying actor input
presence, initial fetch has no actor param, re-fetch with actor=X
after typing, and clearFilters does not throw.
- compression-log-namespace.test.tsx: 4 tests verifying that the logs
namespace is used (not settings), no _MISSING_ sentinels, and all 4
required keys are covered.
- compliance.actor / compliance.actorPlaceholder added to pt-BR + en
- logs.compressionLogTitle, logs.compressionLogEmpty, logs.tokens copied
from settings to logs namespace in both locales (original keys kept in
settings to avoid breaking other components)
The component was calling useTranslations("settings") which would cause
key misses once the settings namespace is reorganized. Keys used
(loading, compressionLogTitle, compressionLogEmpty, tokens) are now
sourced from the canonical "logs" namespace.
Adds state, fetch param, reset and input+datalist for filtering audit
entries by actor. The actor field is inserted between eventType and
severity in the filter grid. Filter value is sent as ?actor= to the
compliance audit-log API on every change.
Add tests for default branch paths (model/prompt/stream falsy), completions
params branch, search with model set, web.fetch depth=0, reversed markers
in parseImprovedContent. All new production files reach 100% branch coverage.
16 tests covering all 5 endpoints:
- GET /agent-skills: 42 total, category/area filters, invalid category → 400
- GET /agent-skills/[id]: found api+cli skills, unknown → 404
- GET /agent-skills/[id]/raw: unknown → 404, valid → 200/502/500 (network-tolerant)
- GET /agent-skills/coverage: SkillCoverage shape (api.total=22, cli.total=20)
- POST /generate: no auth → 401/403, invalid body → 400, no generator → 503
Hard Rule #12 verified explicitly in every error case: error.message must
not match /\bat \/|\bat file:\/\// (no stack trace exposure). Final test
collects all error paths and asserts sanitization in a single sweep.
Implements POST /api/agent-skills/generate (F4):
- Requires management auth via requireManagementAuth (same pattern as
usage/combo-health-dashboard and other management routes)
- Validates body via GenerateBodySchema (dryRun defaults true, prune
defaults false — safe preview mode)
- Dynamic import of @/lib/agentSkills/generator so the route coexists
before F3 (generator.ts) is merged; returns 503 if module unavailable
- Hard Rule #12: all error paths use buildErrorBody (400/401/403/503/500)
- Hard Rule #7: Zod validates both JSON parse and schema shape
Implements four read-only endpoints for the Agent Skills REST API (F4):
- GET /api/agent-skills — catalog with ?category= and ?area= filters,
returns { skills, count, coverage }
- GET /api/agent-skills/[id] — single skill by canonical ID (404 if absent)
- GET /api/agent-skills/[id]/raw — SKILL.md as text/markdown with
Cache-Control: public, max-age=3600; 502 on GitHub fallback failure
- GET /api/agent-skills/coverage — SkillCoverage (filesystem vs catalog)
All routes: export const dynamic = "force-dynamic" (filesystem reads),
error responses via buildErrorBody (Hard Rule #12), Zod input validation
(Hard Rule #7). coverage/route.ts force-added to git because .gitignore
matches the directory name "coverage/" — this is an API route, not a
report directory.
Adds 6 tests for executeListCapabilities (§3.7 shape, 42-skill IDs in markdown,
coverage bounds, ISO datetime, handler registration) and 5 tests for the Agent
Card route (6 skills total, list-capabilities presence + tags + examples, all
original 5 skills preserved). All 11 pass.
Adds "list-capabilities" entry to A2A_SKILL_HANDLERS in taskExecution.ts
(dynamic import pattern, consistent with the 5 existing skills) and adds
the 6th skill entry to /.well-known/agent.json with tags [discovery, capabilities]
and example questions for agent discovery.
Implements executeListCapabilities() which calls getCatalog() + computeCoverage()
from the agentSkills catalog (F1/F2) and returns a markdown table covering all
42 skills (22 API + 20 CLI) with ID, name, category, area, endpoints/commands,
and raw SKILL.md URL, matching the §3.7 result contract.