gentyr 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/antipattern-hunter.md +176 -0
- package/.claude/agents/code-reviewer.md +205 -0
- package/.claude/agents/code-writer.md +154 -0
- package/.claude/agents/deputy-cto.md +309 -0
- package/.claude/agents/feedback-agent.md +101 -0
- package/.claude/agents/investigator.md +136 -0
- package/.claude/agents/product-manager.md +97 -0
- package/.claude/agents/project-manager.md +116 -0
- package/.claude/agents/repo-hygiene-expert.md +626 -0
- package/.claude/agents/secret-manager.md +324 -0
- package/.claude/agents/test-writer.md +354 -0
- package/.claude/commands/configure-personas.md +144 -0
- package/.claude/commands/cto-report.md +36 -0
- package/.claude/commands/demo.md +89 -0
- package/.claude/commands/deputy-cto.md +345 -0
- package/.claude/commands/hotfix.md +31 -0
- package/.claude/commands/overdrive-gentyr.md +167 -0
- package/.claude/commands/product-manager.md +32 -0
- package/.claude/commands/push-migrations.md +86 -0
- package/.claude/commands/push-secrets.md +97 -0
- package/.claude/commands/services.json.example +30 -0
- package/.claude/commands/setup-gentyr.md +396 -0
- package/.claude/commands/show.md +42 -0
- package/.claude/commands/spawn-tasks.md +79 -0
- package/.claude/commands/toggle-automation-gentyr.md +75 -0
- package/.claude/commands/toggle-product-manager.md +19 -0
- package/.claude/commands/triage.md +69 -0
- package/.claude/hooks/README.md +686 -0
- package/.claude/hooks/__tests__/README.md +129 -0
- package/.claude/hooks/agent-tracker.js +434 -0
- package/.claude/hooks/antipattern-hunter-hook.js +401 -0
- package/.claude/hooks/api-key-watcher.js +289 -0
- package/.claude/hooks/block-no-verify.js +301 -0
- package/.claude/hooks/bypass-approval-hook.js +313 -0
- package/.claude/hooks/compliance-checker.js +1309 -0
- package/.claude/hooks/config-reader.js +143 -0
- package/.claude/hooks/credential-file-guard.js +1139 -0
- package/.claude/hooks/credential-health-check.js +168 -0
- package/.claude/hooks/credential-sync-hook.js +79 -0
- package/.claude/hooks/cto-notification-hook.js +656 -0
- package/.claude/hooks/feedback-launcher.js +424 -0
- package/.claude/hooks/feedback-orchestrator.js +367 -0
- package/.claude/hooks/gentyr-splash.js +47 -0
- package/.claude/hooks/gentyr-sync.js +389 -0
- package/.claude/hooks/hourly-automation.js +3340 -0
- package/.claude/hooks/key-sync.js +899 -0
- package/.claude/hooks/lib/approval-utils.js +731 -0
- package/.claude/hooks/lib/feature-branch-helper.js +102 -0
- package/.claude/hooks/lib/worktree-manager.js +330 -0
- package/.claude/hooks/mapping-validator.js +285 -0
- package/.claude/hooks/plan-executor.js +398 -0
- package/.claude/hooks/playwright-cli-guard.js +104 -0
- package/.claude/hooks/playwright-health-check.js +71 -0
- package/.claude/hooks/pre-commit-review.js +725 -0
- package/.claude/hooks/prompts/local-spec-enforcement.md +310 -0
- package/.claude/hooks/prompts/mapping-fix.md +92 -0
- package/.claude/hooks/prompts/mapping-review.md +140 -0
- package/.claude/hooks/prompts/schema-mapper.md +185 -0
- package/.claude/hooks/prompts/spec-enforcement.md +233 -0
- package/.claude/hooks/protected-action-approval-hook.js +336 -0
- package/.claude/hooks/protected-action-gate.js +562 -0
- package/.claude/hooks/protected-actions.json +208 -0
- package/.claude/hooks/protected-actions.json.template +122 -0
- package/.claude/hooks/quota-monitor.js +490 -0
- package/.claude/hooks/reporters/jest-failure-reporter.js +401 -0
- package/.claude/hooks/reporters/playwright-failure-reporter.js +446 -0
- package/.claude/hooks/reporters/vitest-failure-reporter.js +443 -0
- package/.claude/hooks/schema-mapper-hook.js +544 -0
- package/.claude/hooks/secret-leak-detector.js +216 -0
- package/.claude/hooks/session-reviver.js +514 -0
- package/.claude/hooks/slash-command-prefetch.js +1145 -0
- package/.claude/hooks/stale-work-detector.js +205 -0
- package/.claude/hooks/stop-continue-hook.js +414 -0
- package/.claude/hooks/todo-maintenance.js +522 -0
- package/.claude/hooks/todo-processing-prompt.md +75 -0
- package/.claude/hooks/usage-optimizer.js +791 -0
- package/.claude/mcp/README.md +246 -0
- package/.claude/settings.json.template +168 -0
- package/.mcp.json.template +207 -0
- package/CLAUDE.md +340 -0
- package/CLAUDE.md.gentyr-section +89 -0
- package/LICENSE +21 -0
- package/README.md +297 -0
- package/cli/commands/init.js +471 -0
- package/cli/commands/migrate.js +132 -0
- package/cli/commands/protect.js +271 -0
- package/cli/commands/scaffold.js +48 -0
- package/cli/commands/status.js +133 -0
- package/cli/commands/sync.js +101 -0
- package/cli/commands/uninstall.js +207 -0
- package/cli/index.js +111 -0
- package/cli/lib/config-gen.js +214 -0
- package/cli/lib/resolve-framework.js +97 -0
- package/cli/lib/state.js +140 -0
- package/cli/lib/symlinks.js +260 -0
- package/docs/AUTOMATION-SYSTEMS.md +484 -0
- package/docs/BINARY-PATCHING.md +212 -0
- package/docs/CHANGELOG.md +2830 -0
- package/docs/CREDENTIAL-DETECTION.md +151 -0
- package/docs/CTO-DASHBOARD.md +476 -0
- package/docs/DEPLOYMENT-FLOW.md +477 -0
- package/docs/DEVELOPER.md +116 -0
- package/docs/Executive.md +372 -0
- package/docs/SECRET-PATHS.md +77 -0
- package/docs/SETUP-GUIDE.md +419 -0
- package/docs/STACK.md +109 -0
- package/docs/TESTING.md +440 -0
- package/docs/assets/claude-logo.svg +3 -0
- package/docs/sessions/2026-01-24-spec-suite-implementation.md +190 -0
- package/docs/sessions/2026-02-15-feedback-e2e-audit.md +484 -0
- package/docs/sessions/2026-02-20-credential-rotation-experiments.md +340 -0
- package/docs/sessions/TEST-COVERAGE-REPORT-2026-02-20.md +168 -0
- package/docs/shared/EPHEMERAL-STATE-FILES.md +115 -0
- package/docs/shared/PROTECTION-SYSTEM.md +341 -0
- package/husky/post-commit +10 -0
- package/husky/pre-commit +40 -0
- package/husky/pre-push +94 -0
- package/package.json +43 -0
- package/packages/cto-dashboard/package-lock.json +3510 -0
- package/packages/cto-dashboard/package.json +41 -0
- package/packages/cto-dashboard/pnpm-lock.yaml +2168 -0
- package/packages/mcp-servers/dist/__testUtils__/fixtures.d.ts +220 -0
- package/packages/mcp-servers/dist/__testUtils__/fixtures.d.ts.map +1 -0
- package/packages/mcp-servers/dist/__testUtils__/fixtures.js +376 -0
- package/packages/mcp-servers/dist/__testUtils__/fixtures.js.map +1 -0
- package/packages/mcp-servers/dist/__testUtils__/index.d.ts +121 -0
- package/packages/mcp-servers/dist/__testUtils__/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/__testUtils__/index.js +180 -0
- package/packages/mcp-servers/dist/__testUtils__/index.js.map +1 -0
- package/packages/mcp-servers/dist/__testUtils__/schemas.d.ts +84 -0
- package/packages/mcp-servers/dist/__testUtils__/schemas.d.ts.map +1 -0
- package/packages/mcp-servers/dist/__testUtils__/schemas.js +309 -0
- package/packages/mcp-servers/dist/__testUtils__/schemas.js.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/index.d.ts +7 -0
- package/packages/mcp-servers/dist/agent-reports/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/index.js +8 -0
- package/packages/mcp-servers/dist/agent-reports/index.js.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/server.d.ts +22 -0
- package/packages/mcp-servers/dist/agent-reports/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/server.js +535 -0
- package/packages/mcp-servers/dist/agent-reports/server.js.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/types.d.ts +258 -0
- package/packages/mcp-servers/dist/agent-reports/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/types.js +81 -0
- package/packages/mcp-servers/dist/agent-reports/types.js.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/index.d.ts +5 -0
- package/packages/mcp-servers/dist/agent-tracker/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/index.js +5 -0
- package/packages/mcp-servers/dist/agent-tracker/index.js.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/server.d.ts +12 -0
- package/packages/mcp-servers/dist/agent-tracker/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/server.js +919 -0
- package/packages/mcp-servers/dist/agent-tracker/server.js.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/types.d.ts +328 -0
- package/packages/mcp-servers/dist/agent-tracker/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/types.js +128 -0
- package/packages/mcp-servers/dist/agent-tracker/types.js.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/browser-tips.d.ts +27 -0
- package/packages/mcp-servers/dist/chrome-bridge/browser-tips.d.ts.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/browser-tips.js +167 -0
- package/packages/mcp-servers/dist/chrome-bridge/browser-tips.js.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/index.d.ts +6 -0
- package/packages/mcp-servers/dist/chrome-bridge/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/index.js +6 -0
- package/packages/mcp-servers/dist/chrome-bridge/index.js.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/server.d.ts +13 -0
- package/packages/mcp-servers/dist/chrome-bridge/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/server.js +959 -0
- package/packages/mcp-servers/dist/chrome-bridge/server.js.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/types.d.ts +41 -0
- package/packages/mcp-servers/dist/chrome-bridge/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/types.js +8 -0
- package/packages/mcp-servers/dist/chrome-bridge/types.js.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/index.d.ts +8 -0
- package/packages/mcp-servers/dist/cloudflare/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/index.js +8 -0
- package/packages/mcp-servers/dist/cloudflare/index.js.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/server.d.ts +16 -0
- package/packages/mcp-servers/dist/cloudflare/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/server.js +253 -0
- package/packages/mcp-servers/dist/cloudflare/server.js.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/types.d.ts +141 -0
- package/packages/mcp-servers/dist/cloudflare/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/types.js +53 -0
- package/packages/mcp-servers/dist/cloudflare/types.js.map +1 -0
- package/packages/mcp-servers/dist/codecov/index.d.ts +7 -0
- package/packages/mcp-servers/dist/codecov/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/codecov/index.js +7 -0
- package/packages/mcp-servers/dist/codecov/index.js.map +1 -0
- package/packages/mcp-servers/dist/codecov/server.d.ts +21 -0
- package/packages/mcp-servers/dist/codecov/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/codecov/server.js +376 -0
- package/packages/mcp-servers/dist/codecov/server.js.map +1 -0
- package/packages/mcp-servers/dist/codecov/types.d.ts +269 -0
- package/packages/mcp-servers/dist/codecov/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/codecov/types.js +128 -0
- package/packages/mcp-servers/dist/codecov/types.js.map +1 -0
- package/packages/mcp-servers/dist/cto-report/index.d.ts +9 -0
- package/packages/mcp-servers/dist/cto-report/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-report/index.js +9 -0
- package/packages/mcp-servers/dist/cto-report/index.js.map +1 -0
- package/packages/mcp-servers/dist/cto-report/server.d.ts +14 -0
- package/packages/mcp-servers/dist/cto-report/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-report/server.js +859 -0
- package/packages/mcp-servers/dist/cto-report/server.js.map +1 -0
- package/packages/mcp-servers/dist/cto-report/types.d.ts +213 -0
- package/packages/mcp-servers/dist/cto-report/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-report/types.js +29 -0
- package/packages/mcp-servers/dist/cto-report/types.js.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/index.d.ts +7 -0
- package/packages/mcp-servers/dist/cto-reports/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/index.js +8 -0
- package/packages/mcp-servers/dist/cto-reports/index.js.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/server.d.ts +20 -0
- package/packages/mcp-servers/dist/cto-reports/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/server.js +538 -0
- package/packages/mcp-servers/dist/cto-reports/server.js.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/types.d.ts +236 -0
- package/packages/mcp-servers/dist/cto-reports/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/types.js +77 -0
- package/packages/mcp-servers/dist/cto-reports/types.js.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/index.d.ts +7 -0
- package/packages/mcp-servers/dist/deputy-cto/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/index.js +8 -0
- package/packages/mcp-servers/dist/deputy-cto/index.js.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/server.d.ts +23 -0
- package/packages/mcp-servers/dist/deputy-cto/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/server.js +1700 -0
- package/packages/mcp-servers/dist/deputy-cto/server.js.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/types.d.ts +439 -0
- package/packages/mcp-servers/dist/deputy-cto/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/types.js +102 -0
- package/packages/mcp-servers/dist/deputy-cto/types.js.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/index.d.ts +5 -0
- package/packages/mcp-servers/dist/elastic-logs/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/index.js +5 -0
- package/packages/mcp-servers/dist/elastic-logs/index.js.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/server.d.ts +18 -0
- package/packages/mcp-servers/dist/elastic-logs/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/server.js +259 -0
- package/packages/mcp-servers/dist/elastic-logs/server.js.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/types.d.ts +107 -0
- package/packages/mcp-servers/dist/elastic-logs/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/types.js +31 -0
- package/packages/mcp-servers/dist/elastic-logs/types.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/index.d.ts +2 -0
- package/packages/mcp-servers/dist/feedback-explorer/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/index.js +2 -0
- package/packages/mcp-servers/dist/feedback-explorer/index.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/server.d.ts +21 -0
- package/packages/mcp-servers/dist/feedback-explorer/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/server.js +580 -0
- package/packages/mcp-servers/dist/feedback-explorer/server.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/types.d.ts +331 -0
- package/packages/mcp-servers/dist/feedback-explorer/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/types.js +40 -0
- package/packages/mcp-servers/dist/feedback-explorer/types.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/index.d.ts +9 -0
- package/packages/mcp-servers/dist/feedback-reporter/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/index.js +9 -0
- package/packages/mcp-servers/dist/feedback-reporter/index.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/server.d.ts +36 -0
- package/packages/mcp-servers/dist/feedback-reporter/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/server.js +392 -0
- package/packages/mcp-servers/dist/feedback-reporter/server.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/types.d.ts +152 -0
- package/packages/mcp-servers/dist/feedback-reporter/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/types.js +67 -0
- package/packages/mcp-servers/dist/feedback-reporter/types.js.map +1 -0
- package/packages/mcp-servers/dist/github/index.d.ts +7 -0
- package/packages/mcp-servers/dist/github/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/github/index.js +7 -0
- package/packages/mcp-servers/dist/github/index.js.map +1 -0
- package/packages/mcp-servers/dist/github/server.d.ts +15 -0
- package/packages/mcp-servers/dist/github/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/github/server.js +686 -0
- package/packages/mcp-servers/dist/github/server.js.map +1 -0
- package/packages/mcp-servers/dist/github/types.d.ts +660 -0
- package/packages/mcp-servers/dist/github/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/github/types.js +209 -0
- package/packages/mcp-servers/dist/github/types.js.map +1 -0
- package/packages/mcp-servers/dist/index.d.ts +30 -0
- package/packages/mcp-servers/dist/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/index.js +32 -0
- package/packages/mcp-servers/dist/index.js.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/index.d.ts +5 -0
- package/packages/mcp-servers/dist/makerkit-docs/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/index.js +5 -0
- package/packages/mcp-servers/dist/makerkit-docs/index.js.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/server.d.ts +15 -0
- package/packages/mcp-servers/dist/makerkit-docs/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/server.js +252 -0
- package/packages/mcp-servers/dist/makerkit-docs/server.js.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/types.d.ts +74 -0
- package/packages/mcp-servers/dist/makerkit-docs/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/types.js +20 -0
- package/packages/mcp-servers/dist/makerkit-docs/types.js.map +1 -0
- package/packages/mcp-servers/dist/onepassword/index.d.ts +2 -0
- package/packages/mcp-servers/dist/onepassword/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/onepassword/index.js +2 -0
- package/packages/mcp-servers/dist/onepassword/index.js.map +1 -0
- package/packages/mcp-servers/dist/onepassword/server.d.ts +2 -0
- package/packages/mcp-servers/dist/onepassword/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/onepassword/server.js +159 -0
- package/packages/mcp-servers/dist/onepassword/server.js.map +1 -0
- package/packages/mcp-servers/dist/onepassword/types.d.ts +55 -0
- package/packages/mcp-servers/dist/onepassword/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/onepassword/types.js +22 -0
- package/packages/mcp-servers/dist/onepassword/types.js.map +1 -0
- package/packages/mcp-servers/dist/playwright/helpers.d.ts +20 -0
- package/packages/mcp-servers/dist/playwright/helpers.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright/helpers.js +31 -0
- package/packages/mcp-servers/dist/playwright/helpers.js.map +1 -0
- package/packages/mcp-servers/dist/playwright/index.d.ts +5 -0
- package/packages/mcp-servers/dist/playwright/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright/index.js +5 -0
- package/packages/mcp-servers/dist/playwright/index.js.map +1 -0
- package/packages/mcp-servers/dist/playwright/server.d.ts +13 -0
- package/packages/mcp-servers/dist/playwright/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright/server.js +1201 -0
- package/packages/mcp-servers/dist/playwright/server.js.map +1 -0
- package/packages/mcp-servers/dist/playwright/types.d.ts +216 -0
- package/packages/mcp-servers/dist/playwright/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright/types.js +172 -0
- package/packages/mcp-servers/dist/playwright/types.js.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/browser-manager.d.ts +39 -0
- package/packages/mcp-servers/dist/playwright-feedback/browser-manager.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/browser-manager.js +71 -0
- package/packages/mcp-servers/dist/playwright-feedback/browser-manager.js.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/index.d.ts +5 -0
- package/packages/mcp-servers/dist/playwright-feedback/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/index.js +5 -0
- package/packages/mcp-servers/dist/playwright-feedback/index.js.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/server.d.ts +34 -0
- package/packages/mcp-servers/dist/playwright-feedback/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/server.js +538 -0
- package/packages/mcp-servers/dist/playwright-feedback/server.js.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/types.d.ts +305 -0
- package/packages/mcp-servers/dist/playwright-feedback/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/types.js +123 -0
- package/packages/mcp-servers/dist/playwright-feedback/types.js.map +1 -0
- package/packages/mcp-servers/dist/product-manager/server.d.ts +17 -0
- package/packages/mcp-servers/dist/product-manager/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/product-manager/server.js +690 -0
- package/packages/mcp-servers/dist/product-manager/server.js.map +1 -0
- package/packages/mcp-servers/dist/product-manager/types.d.ts +286 -0
- package/packages/mcp-servers/dist/product-manager/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/product-manager/types.js +99 -0
- package/packages/mcp-servers/dist/product-manager/types.js.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/index.d.ts +7 -0
- package/packages/mcp-servers/dist/programmatic-feedback/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/index.js +7 -0
- package/packages/mcp-servers/dist/programmatic-feedback/index.js.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/sandbox.d.ts +19 -0
- package/packages/mcp-servers/dist/programmatic-feedback/sandbox.d.ts.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/sandbox.js +174 -0
- package/packages/mcp-servers/dist/programmatic-feedback/sandbox.js.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/server.d.ts +35 -0
- package/packages/mcp-servers/dist/programmatic-feedback/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/server.js +465 -0
- package/packages/mcp-servers/dist/programmatic-feedback/server.js.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/types.d.ts +127 -0
- package/packages/mcp-servers/dist/programmatic-feedback/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/types.js +80 -0
- package/packages/mcp-servers/dist/programmatic-feedback/types.js.map +1 -0
- package/packages/mcp-servers/dist/render/index.d.ts +8 -0
- package/packages/mcp-servers/dist/render/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/render/index.js +8 -0
- package/packages/mcp-servers/dist/render/index.js.map +1 -0
- package/packages/mcp-servers/dist/render/server.d.ts +15 -0
- package/packages/mcp-servers/dist/render/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/render/server.js +428 -0
- package/packages/mcp-servers/dist/render/server.js.map +1 -0
- package/packages/mcp-servers/dist/render/types.d.ts +273 -0
- package/packages/mcp-servers/dist/render/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/render/types.js +102 -0
- package/packages/mcp-servers/dist/render/types.js.map +1 -0
- package/packages/mcp-servers/dist/resend/index.d.ts +7 -0
- package/packages/mcp-servers/dist/resend/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/resend/index.js +7 -0
- package/packages/mcp-servers/dist/resend/index.js.map +1 -0
- package/packages/mcp-servers/dist/resend/server.d.ts +15 -0
- package/packages/mcp-servers/dist/resend/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/resend/server.js +298 -0
- package/packages/mcp-servers/dist/resend/server.js.map +1 -0
- package/packages/mcp-servers/dist/resend/types.d.ts +222 -0
- package/packages/mcp-servers/dist/resend/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/resend/types.js +58 -0
- package/packages/mcp-servers/dist/resend/types.js.map +1 -0
- package/packages/mcp-servers/dist/review-queue/index.d.ts +6 -0
- package/packages/mcp-servers/dist/review-queue/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/review-queue/index.js +6 -0
- package/packages/mcp-servers/dist/review-queue/index.js.map +1 -0
- package/packages/mcp-servers/dist/review-queue/server.d.ts +17 -0
- package/packages/mcp-servers/dist/review-queue/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/review-queue/server.js +348 -0
- package/packages/mcp-servers/dist/review-queue/server.js.map +1 -0
- package/packages/mcp-servers/dist/review-queue/types.d.ts +162 -0
- package/packages/mcp-servers/dist/review-queue/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/review-queue/types.js +56 -0
- package/packages/mcp-servers/dist/review-queue/types.js.map +1 -0
- package/packages/mcp-servers/dist/secret-sync/server.d.ts +19 -0
- package/packages/mcp-servers/dist/secret-sync/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/secret-sync/server.js +1139 -0
- package/packages/mcp-servers/dist/secret-sync/server.js.map +1 -0
- package/packages/mcp-servers/dist/secret-sync/types.d.ts +442 -0
- package/packages/mcp-servers/dist/secret-sync/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/secret-sync/types.js +113 -0
- package/packages/mcp-servers/dist/secret-sync/types.js.map +1 -0
- package/packages/mcp-servers/dist/session-events/index.d.ts +5 -0
- package/packages/mcp-servers/dist/session-events/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-events/index.js +5 -0
- package/packages/mcp-servers/dist/session-events/index.js.map +1 -0
- package/packages/mcp-servers/dist/session-events/server.d.ts +11 -0
- package/packages/mcp-servers/dist/session-events/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-events/server.js +290 -0
- package/packages/mcp-servers/dist/session-events/server.js.map +1 -0
- package/packages/mcp-servers/dist/session-events/types.d.ts +213 -0
- package/packages/mcp-servers/dist/session-events/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-events/types.js +69 -0
- package/packages/mcp-servers/dist/session-events/types.js.map +1 -0
- package/packages/mcp-servers/dist/session-restart/index.d.ts +9 -0
- package/packages/mcp-servers/dist/session-restart/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-restart/index.js +9 -0
- package/packages/mcp-servers/dist/session-restart/index.js.map +1 -0
- package/packages/mcp-servers/dist/session-restart/server.d.ts +20 -0
- package/packages/mcp-servers/dist/session-restart/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-restart/server.js +411 -0
- package/packages/mcp-servers/dist/session-restart/server.js.map +1 -0
- package/packages/mcp-servers/dist/session-restart/types.d.ts +26 -0
- package/packages/mcp-servers/dist/session-restart/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-restart/types.js +16 -0
- package/packages/mcp-servers/dist/session-restart/types.js.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/index.d.ts +5 -0
- package/packages/mcp-servers/dist/setup-helper/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/index.js +5 -0
- package/packages/mcp-servers/dist/setup-helper/index.js.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/server.d.ts +14 -0
- package/packages/mcp-servers/dist/setup-helper/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/server.js +454 -0
- package/packages/mcp-servers/dist/setup-helper/server.js.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/types.d.ts +81 -0
- package/packages/mcp-servers/dist/setup-helper/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/types.js +41 -0
- package/packages/mcp-servers/dist/setup-helper/types.js.map +1 -0
- package/packages/mcp-servers/dist/shared/audited-server.d.ts +31 -0
- package/packages/mcp-servers/dist/shared/audited-server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/audited-server.js +126 -0
- package/packages/mcp-servers/dist/shared/audited-server.js.map +1 -0
- package/packages/mcp-servers/dist/shared/constants.d.ts +26 -0
- package/packages/mcp-servers/dist/shared/constants.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/constants.js +41 -0
- package/packages/mcp-servers/dist/shared/constants.js.map +1 -0
- package/packages/mcp-servers/dist/shared/index.d.ts +6 -0
- package/packages/mcp-servers/dist/shared/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/index.js +6 -0
- package/packages/mcp-servers/dist/shared/index.js.map +1 -0
- package/packages/mcp-servers/dist/shared/readonly-db.d.ts +11 -0
- package/packages/mcp-servers/dist/shared/readonly-db.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/readonly-db.js +47 -0
- package/packages/mcp-servers/dist/shared/readonly-db.js.map +1 -0
- package/packages/mcp-servers/dist/shared/resolve-framework.d.ts +20 -0
- package/packages/mcp-servers/dist/shared/resolve-framework.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/resolve-framework.js +65 -0
- package/packages/mcp-servers/dist/shared/resolve-framework.js.map +1 -0
- package/packages/mcp-servers/dist/shared/server.d.ts +86 -0
- package/packages/mcp-servers/dist/shared/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/server.js +291 -0
- package/packages/mcp-servers/dist/shared/server.js.map +1 -0
- package/packages/mcp-servers/dist/shared/types.d.ts +113 -0
- package/packages/mcp-servers/dist/shared/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/types.js +36 -0
- package/packages/mcp-servers/dist/shared/types.js.map +1 -0
- package/packages/mcp-servers/dist/show/server.d.ts +12 -0
- package/packages/mcp-servers/dist/show/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/show/server.js +97 -0
- package/packages/mcp-servers/dist/show/server.js.map +1 -0
- package/packages/mcp-servers/dist/show/types.d.ts +19 -0
- package/packages/mcp-servers/dist/show/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/show/types.js +32 -0
- package/packages/mcp-servers/dist/show/types.js.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/index.d.ts +5 -0
- package/packages/mcp-servers/dist/specs-browser/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/index.js +5 -0
- package/packages/mcp-servers/dist/specs-browser/index.js.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/server.d.ts +13 -0
- package/packages/mcp-servers/dist/specs-browser/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/server.js +692 -0
- package/packages/mcp-servers/dist/specs-browser/server.js.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/types.d.ts +337 -0
- package/packages/mcp-servers/dist/specs-browser/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/types.js +134 -0
- package/packages/mcp-servers/dist/specs-browser/types.js.map +1 -0
- package/packages/mcp-servers/dist/supabase/index.d.ts +10 -0
- package/packages/mcp-servers/dist/supabase/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/supabase/index.js +10 -0
- package/packages/mcp-servers/dist/supabase/index.js.map +1 -0
- package/packages/mcp-servers/dist/supabase/server.d.ts +20 -0
- package/packages/mcp-servers/dist/supabase/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/supabase/server.js +451 -0
- package/packages/mcp-servers/dist/supabase/server.js.map +1 -0
- package/packages/mcp-servers/dist/supabase/types.d.ts +196 -0
- package/packages/mcp-servers/dist/supabase/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/supabase/types.js +76 -0
- package/packages/mcp-servers/dist/supabase/types.js.map +1 -0
- package/packages/mcp-servers/dist/todo-db/index.d.ts +5 -0
- package/packages/mcp-servers/dist/todo-db/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/todo-db/index.js +5 -0
- package/packages/mcp-servers/dist/todo-db/index.js.map +1 -0
- package/packages/mcp-servers/dist/todo-db/server.d.ts +13 -0
- package/packages/mcp-servers/dist/todo-db/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/todo-db/server.js +649 -0
- package/packages/mcp-servers/dist/todo-db/server.js.map +1 -0
- package/packages/mcp-servers/dist/todo-db/types.d.ts +225 -0
- package/packages/mcp-servers/dist/todo-db/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/todo-db/types.js +69 -0
- package/packages/mcp-servers/dist/todo-db/types.js.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/index.d.ts +7 -0
- package/packages/mcp-servers/dist/user-feedback/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/index.js +8 -0
- package/packages/mcp-servers/dist/user-feedback/index.js.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/server.d.ts +25 -0
- package/packages/mcp-servers/dist/user-feedback/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/server.js +914 -0
- package/packages/mcp-servers/dist/user-feedback/server.js.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/types.d.ts +415 -0
- package/packages/mcp-servers/dist/user-feedback/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/types.js +132 -0
- package/packages/mcp-servers/dist/user-feedback/types.js.map +1 -0
- package/packages/mcp-servers/dist/vercel/index.d.ts +9 -0
- package/packages/mcp-servers/dist/vercel/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/vercel/index.js +9 -0
- package/packages/mcp-servers/dist/vercel/index.js.map +1 -0
- package/packages/mcp-servers/dist/vercel/server.d.ts +17 -0
- package/packages/mcp-servers/dist/vercel/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/vercel/server.js +265 -0
- package/packages/mcp-servers/dist/vercel/server.js.map +1 -0
- package/packages/mcp-servers/dist/vercel/types.d.ts +189 -0
- package/packages/mcp-servers/dist/vercel/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/vercel/types.js +65 -0
- package/packages/mcp-servers/dist/vercel/types.js.map +1 -0
- package/packages/mcp-servers/package-lock.json +3765 -0
- package/packages/mcp-servers/package.json +64 -0
- package/packages/mcp-servers/test/reporters/test-failure-reporter.ts +372 -0
- package/packages/mcp-servers/vitest.config.ts +27 -0
- package/scripts/__tests__/README.md +163 -0
- package/scripts/apply-credential-hardening.sh +271 -0
- package/scripts/credential-providers/manual.js +56 -0
- package/scripts/credential-providers/onepassword.js +85 -0
- package/scripts/credential-providers/provider-interface.js +104 -0
- package/scripts/encrypt-credential.js +337 -0
- package/scripts/feedback-launcher.js +338 -0
- package/scripts/feedback-orchestrator.js +373 -0
- package/scripts/fix-mcp-launcher-issues.sh +97 -0
- package/scripts/force-spawn-tasks.js +651 -0
- package/scripts/force-triage-reports.js +560 -0
- package/scripts/generate-protected-actions-spec.js +142 -0
- package/scripts/generate-proxy-certs.sh +158 -0
- package/scripts/grant-chrome-ext-permissions.sh +242 -0
- package/scripts/mcp-launcher.js +125 -0
- package/scripts/merge-settings.cjs +167 -0
- package/scripts/patch-clawd.py +844 -0
- package/scripts/patch-credential-cache.py +313 -0
- package/scripts/patches/credential-file-guard-patched.mjs +573 -0
- package/scripts/patches/credential-file-guard.js.patched +573 -0
- package/scripts/patches/verify-tokenizer.mjs +132 -0
- package/scripts/protect-framework.sh +478 -0
- package/scripts/readme-chrome.template +12 -0
- package/scripts/reap-completed-agents.js +439 -0
- package/scripts/reinstall.sh +86 -0
- package/scripts/resign-node.sh +185 -0
- package/scripts/rotation-proxy.js +656 -0
- package/scripts/rotation-stress-monitor.mjs +862 -0
- package/scripts/setup-automation-service.sh +648 -0
- package/scripts/setup-check.js +251 -0
- package/scripts/watch-claude-version.js +142 -0
- package/specs/framework/CORE-INVARIANTS.md +161 -0
- package/specs/patterns/AGENT-PATTERNS.md +223 -0
- package/specs/patterns/HOOK-PATTERNS.md +242 -0
- package/specs/patterns/MCP-SERVER-PATTERNS.md +144 -0
- package/templates/config/gitignore.template +14 -0
- package/templates/config/merge-chain-check.yml.template +51 -0
- package/templates/config/package.json.template +18 -0
- package/templates/config/pnpm-workspace.yaml +5 -0
- package/templates/config/services.json.template +18 -0
- package/templates/config/tsconfig.base.json +17 -0
- package/templates/scaffold/integrations/_template/.gitkeep +0 -0
- package/templates/scaffold/packages/logger/package.json +17 -0
- package/templates/scaffold/packages/logger/src/logger.ts +44 -0
- package/templates/scaffold/packages/shared/package.json +17 -0
- package/templates/scaffold/packages/shared/src/errors.ts +43 -0
- package/templates/scaffold/products/_product/apps/backend/package.json +21 -0
- package/templates/scaffold/products/_product/apps/backend/src/index.ts +17 -0
- package/templates/scaffold/products/_product/apps/extension/.gitkeep +0 -0
- package/templates/scaffold/products/_product/apps/web/.gitkeep +0 -0
- package/templates/scaffold/specs/global/.gitkeep +0 -0
- package/templates/scaffold/specs/local/.gitkeep +0 -0
- package/templates/scaffold/specs/reference/.gitkeep +0 -0
- package/version.json +15 -0
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
# the automation layer
|
|
2
|
+
|
|
3
|
+
Automation is not a feature of GENTYR. It is the point.
|
|
4
|
+
|
|
5
|
+
Every ten minutes a background timer wakes up. It checks quota across multiple accounts. It refreshes expiring tokens. It spawns agents for pending tasks. It adjusts its own frequency based on how much API budget remains. No human triggers any of this. No human needs to.
|
|
6
|
+
|
|
7
|
+
The system has one goal: keep agents working at 90% of available capacity, indefinitely, without intervention. When quota runs low, it slows down. When quota resets, it speeds up.
|
|
8
|
+
|
|
9
|
+
This document describes how.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
GENTYR manages API quota across multiple Anthropic accounts through coordinated hooks that handle credential rotation, dynamic throughput adjustment, and session recovery. The system operates at four layers:
|
|
16
|
+
|
|
17
|
+
1. **Rotation proxy** - Transparent network-level credential swap (localhost:18080 MITM on api.anthropic.com)
|
|
18
|
+
2. **In-session hooks** - Monitor quota and rotate credentials during active Claude Code sessions
|
|
19
|
+
3. **Background automation** - Orchestrates task spawning and key syncing on a timer
|
|
20
|
+
4. **Dynamic optimization** - Adjusts all automation cooldowns based on projected quota utilization
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
launchd timer (10 min) ──> hourly-automation.js ──> CTO Activity Gate
|
|
24
|
+
|
|
|
25
|
+
|── runUsageOptimizer() -> adjust cooldown factor
|
|
26
|
+
|── syncKeys() -> refresh tokens, maintain standby pool
|
|
27
|
+
|── task runner -> spawn pending TODO tasks
|
|
28
|
+
|── feedback pipeline -> user persona testing
|
|
29
|
+
v
|
|
30
|
+
automation-config.json (factor scales all 18 cooldowns)
|
|
31
|
+
|
|
|
32
|
+
v
|
|
33
|
+
config-reader.js --> getCooldown(key, fallback)
|
|
34
|
+
|
|
|
35
|
+
v
|
|
36
|
+
All hooks read dynamic intervals
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Hook Registration
|
|
42
|
+
|
|
43
|
+
| Event | Hooks | Purpose |
|
|
44
|
+
|-------|-------|---------|
|
|
45
|
+
| **SessionStart** | gentyr-sync | Framework version/config change detection; auto-sync settings.json, .mcp.json, hooks, agents |
|
|
46
|
+
| **SessionStart** | api-key-watcher | Discover credentials, health-check, select optimal key |
|
|
47
|
+
| **SessionStart** | credential-health-check | Vault mapping validation, OP token desync detection |
|
|
48
|
+
| **PreToolUse(Bash)** | credential-sync-hook | Periodic credential sync (30-min throttle) |
|
|
49
|
+
| **PreToolUse(Bash)** | playwright-cli-guard | Warn agents against CLI-based Playwright test invocation (non-blocking) |
|
|
50
|
+
| **PostToolUse** | quota-monitor | Mid-session quota check (5-min throttle), rotate at 95% |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Credential Rotation
|
|
55
|
+
|
|
56
|
+
### Multi-Account Architecture
|
|
57
|
+
|
|
58
|
+
The system supports multiple Anthropic OAuth accounts. Each account can have multiple discovered keys (from environment, Keychain, and credentials file). Keys are tracked in a central rotation state file with lifecycle management.
|
|
59
|
+
|
|
60
|
+
### Key Lifecycle
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Discovered -> Active -> [High Usage 90%+] -> [Exhausted 100%] -> [Token Expires] -> Expired
|
|
64
|
+
|
|
|
65
|
+
[OAuth Refresh]
|
|
66
|
+
/ \
|
|
67
|
+
Success invalid_grant
|
|
68
|
+
| |
|
|
69
|
+
Active Invalid -> [7d] -> Pruned
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Key Selection Algorithm (`selectActiveKey`)
|
|
73
|
+
|
|
74
|
+
1. Filter to keys with `status === 'active'`
|
|
75
|
+
2. Exclude keys exhausted in any bucket (5h, 7d, or 7d_sonnet at 100%)
|
|
76
|
+
3. For each candidate, compute `maxUsage = max(five_hour, seven_day, seven_day_sonnet)`
|
|
77
|
+
4. Select key with lowest `maxUsage`
|
|
78
|
+
5. Ties broken by `last_used_at` (least recently used)
|
|
79
|
+
6. Only switch when current key hits >= 90% and an alternative exists below 90%
|
|
80
|
+
|
|
81
|
+
### Token Refresh
|
|
82
|
+
|
|
83
|
+
Multiple hooks can refresh tokens independently, all using `refreshExpiredToken()` from key-sync.js:
|
|
84
|
+
|
|
85
|
+
- **quota-monitor** Step 4b: Proactive refresh of standby tokens approaching expiry
|
|
86
|
+
- **syncKeys()**: Comprehensive refresh during periodic sync cycle
|
|
87
|
+
|
|
88
|
+
The refresh function returns three possible outcomes:
|
|
89
|
+
- `{ accessToken, refreshToken, expiresAt }` on success
|
|
90
|
+
- `'invalid_grant'` sentinel on permanent failure (HTTP 400) - callers mark key invalid
|
|
91
|
+
- `null` on transient failure - key stays in current status
|
|
92
|
+
|
|
93
|
+
### Restartless Token Swap
|
|
94
|
+
|
|
95
|
+
When the active key approaches expiry (within `EXPIRY_BUFFER_MS`):
|
|
96
|
+
|
|
97
|
+
1. Find a standby key with valid status and sufficient expiry window
|
|
98
|
+
2. Write standby token to macOS Keychain via `updateActiveCredentials()`
|
|
99
|
+
3. Update `active_key_id` in rotation state
|
|
100
|
+
4. Claude Code's built-in `SRA()` (fires 5 min before expiry) clears in-memory cache, re-reads Keychain, adopts new token
|
|
101
|
+
5. No restart needed - seamless credential handoff
|
|
102
|
+
|
|
103
|
+
This is safe because refreshing Account B's token does not revoke Account A's in-memory token.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Usage Optimizer
|
|
108
|
+
|
|
109
|
+
### Purpose
|
|
110
|
+
|
|
111
|
+
Targets 90% token budget utilization by dynamically scaling all 19 automation cooldowns through a single factor (0.05 to 20.0).
|
|
112
|
+
|
|
113
|
+
### Algorithm
|
|
114
|
+
|
|
115
|
+
1. **Collect snapshot**: Fetch usage from Anthropic API for all active keys. Store timestamped snapshot.
|
|
116
|
+
2. **Detect reset boundary**: If 5h usage drops > 30pp between consecutive snapshots, a quota reset just occurred. Skip adjustment.
|
|
117
|
+
3. **Calculate EMA rate**: Select time-based snapshots from a 2-hour window (minimum 5-min spacing). Apply Exponential Moving Average (alpha=0.3) to consecutive pairs to compute smoothed tokens-per-hour rate.
|
|
118
|
+
4. **Project utilization**: `projected = currentUsage + (rate * hoursUntilReset)`. Compare to 90% target.
|
|
119
|
+
5. **Adjust factor**: Compute desired rate ratio, apply conservative bounds (max +/-10% per cycle), clamp to 0.05-20.0.
|
|
120
|
+
6. **Write effective cooldowns**: `effective[key] = max(5, round(default / factor))`
|
|
121
|
+
|
|
122
|
+
### Factor Effects
|
|
123
|
+
|
|
124
|
+
| Factor | Effect | Example (60-min default) |
|
|
125
|
+
|--------|--------|--------------------------|
|
|
126
|
+
| 20.0 | 20x speed (cooldowns divided by 20) | 3 min effective (floor: 5 min) |
|
|
127
|
+
| 2.0 | 2x speed (half cooldowns) | 30 min effective |
|
|
128
|
+
| 1.0 | Normal (no adjustment) | 60 min effective |
|
|
129
|
+
| 0.5 | Half speed (double cooldowns) | 120 min effective |
|
|
130
|
+
| 0.05 | 20x slowdown (cooldowns multiplied by 20) | 1200 min effective |
|
|
131
|
+
|
|
132
|
+
### 18 Managed Cooldowns
|
|
133
|
+
|
|
134
|
+
All read via `getCooldown(key, fallback)` from config-reader.js:
|
|
135
|
+
|
|
136
|
+
| Category | Cooldowns |
|
|
137
|
+
|----------|-----------|
|
|
138
|
+
| Task management | hourly_tasks, task_runner, todo_maintenance |
|
|
139
|
+
| Triage | triage_check, triage_per_item |
|
|
140
|
+
| Code quality | lint_checker, antipattern_hunter, standalone_antipattern_hunter |
|
|
141
|
+
| Compliance | standalone_compliance_checker, compliance_checker_file, compliance_checker_spec |
|
|
142
|
+
| Deployment | preview_promotion, staging_promotion |
|
|
143
|
+
| Monitoring | staging_health_monitor, production_health_monitor |
|
|
144
|
+
| Other | user_feedback, test_failure_reporter, pre_commit_review |
|
|
145
|
+
|
|
146
|
+
### Edge Cases
|
|
147
|
+
|
|
148
|
+
- **Already at target**: If usage >= 90%, factor clamped to <= 1.0 (never speed up)
|
|
149
|
+
- **Zero rate**: Conservatively ramp toward MAX_FACTOR at 5% per cycle
|
|
150
|
+
- **Factor stuck at minimum**: If `currentFactor <= 0.15` and usage << 50% of target, reset factor to 1.0 (projection model unreliable)
|
|
151
|
+
- **Single key warning**: If any single key exceeds 80% in either bucket, bias effective usage upward
|
|
152
|
+
- **Overdrive mode**: Skips adjustment; reverts when overdrive expires
|
|
153
|
+
|
|
154
|
+
### Snapshot Quality
|
|
155
|
+
|
|
156
|
+
Snapshots are protected against rapid-fire contamination by three layers:
|
|
157
|
+
1. **Collection throttle**: Skip if last snapshot < 5 min old
|
|
158
|
+
2. **Time-based selection**: EMA uses snapshots >= 5 min apart within 2-hour window (not raw array tail)
|
|
159
|
+
3. **Interval floor**: EMA ignores any snapshot pair < 3 min apart
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Session Lifecycle
|
|
164
|
+
|
|
165
|
+
### Automated Session Flow
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
hourly-automation.js
|
|
169
|
+
|-- spawns: claude -p "[Task] ..." --dangerously-skip-permissions
|
|
170
|
+
|
|
|
171
|
+
v
|
|
172
|
+
Session runs task
|
|
173
|
+
|
|
|
174
|
+
|-- [PostToolUse] quota-monitor checks every 5 min
|
|
175
|
+
| |-- usage >= 95%? -> rotate key, write to Keychain, continue: true
|
|
176
|
+
| |-- token expiring? -> restartless swap via Keychain
|
|
177
|
+
|
|
|
178
|
+
v
|
|
179
|
+
Session ends
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Interactive Session Flow
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
User starts claude
|
|
186
|
+
|-- [SessionStart] api-key-watcher discovers keys, selects optimal
|
|
187
|
+
|
|
|
188
|
+
User works
|
|
189
|
+
|-- [PreToolUse:Bash] credential-sync-hook (30-min throttle)
|
|
190
|
+
|-- [PostToolUse] quota-monitor (5-min throttle)
|
|
191
|
+
| |-- usage >= 95%? -> rotate key, write to Keychain, continue (continue: true)
|
|
192
|
+
| | |-- credentials adopted at token expiry (SRA) or 401 (r6T)
|
|
193
|
+
| |-- token expiring? -> restartless Keychain swap
|
|
194
|
+
|
|
|
195
|
+
User or system stops session
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Concurrency Guards
|
|
199
|
+
|
|
200
|
+
- `MAX_CONCURRENT_AGENTS = 5` - total running agents across all types
|
|
201
|
+
- `MAX_TASKS_PER_CYCLE = 3` - new task spawns per automation cycle
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Rotation Proxy
|
|
206
|
+
|
|
207
|
+
Local MITM proxy (`scripts/rotation-proxy.js`) that handles immediate credential swap at the network layer.
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
Claude Code ──HTTPS_PROXY──> localhost:18080 ──TLS──> api.anthropic.com
|
|
211
|
+
|
|
|
212
|
+
reads api-key-rotation.json
|
|
213
|
+
|
|
|
214
|
+
on 429: rotate key, retry
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Intercepts** (TLS MITM + Authorization header swap):
|
|
218
|
+
- `api.anthropic.com` — main API
|
|
219
|
+
- `mcp-proxy.anthropic.com` — MCP proxy endpoint
|
|
220
|
+
|
|
221
|
+
**Passes through transparently** (CONNECT tunnel, no MITM):
|
|
222
|
+
- `platform.claude.com` — OAuth refresh
|
|
223
|
+
- Everything else
|
|
224
|
+
|
|
225
|
+
**Lifecycle**: KeepAlive launchd service (`com.local.gentyr-rotation-proxy`). Provisioned by `setup-automation-service.sh`. Starts before the automation service. Proxy env vars (`HTTPS_PROXY/HTTP_PROXY/NO_PROXY`) injected into all spawned agent environments.
|
|
226
|
+
|
|
227
|
+
**Relationship to hook-based rotation**: The proxy handles the actual HTTP-level token swap. Quota-monitor still detects usage thresholds and writes new `active_key_id` to rotation state. Key-sync still refreshes OAuth tokens and writes to Keychain. The proxy reads rotation state on every request, so token swap is immediate — no waiting for SRA or r6T.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Quota Monitor (PostToolUse)
|
|
232
|
+
|
|
233
|
+
Runs after every tool call, throttled to 5-minute intervals.
|
|
234
|
+
|
|
235
|
+
### Steps
|
|
236
|
+
|
|
237
|
+
1. **Throttle check**: Skip if last check < 5 min ago
|
|
238
|
+
2. **Anti-loop check**: Skip if rotated < 10 min ago
|
|
239
|
+
3. **Health check**: Query Anthropic usage API for active key
|
|
240
|
+
4. **Step 4b - Proactive refresh**: Refresh expired AND approaching-expiry standby tokens
|
|
241
|
+
5. **Step 4c - Pre-expiry swap**: If active key near expiry, write standby to Keychain (no restart)
|
|
242
|
+
6. **Rotation check**: If max usage >= 95%, select better key and rotate
|
|
243
|
+
7. **Seamless session handling**: write to Keychain, continue with `continue: true` for all sessions, credentials adopted at SRA/r6T
|
|
244
|
+
8. **Post-rotation audit**: Log rotation event to `rotation-audit.log` for health tracking
|
|
245
|
+
|
|
246
|
+
### Key Thresholds
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
PROACTIVE_THRESHOLD = 95% (trigger rotation)
|
|
250
|
+
HIGH_USAGE_THRESHOLD = 90% (from key-sync.js)
|
|
251
|
+
EXHAUSTED_THRESHOLD = 100% (from key-sync.js)
|
|
252
|
+
EXPIRY_BUFFER_MS = 600,000 (10 min - token pre-expiry window)
|
|
253
|
+
CHECK_INTERVAL_MS = 300,000 (5 min - throttle between checks)
|
|
254
|
+
ROTATION_COOLDOWN_MS = 600,000 (10 min - anti-loop after rotation)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Credential Health Check Hook (credential-health-check.js)
|
|
260
|
+
|
|
261
|
+
Runs at `SessionStart` for interactive sessions (skipped for spawned `[Task]` sessions). Validates that all required credential mappings are present and that the `OP_SERVICE_ACCOUNT_TOKEN` in the shell environment is in sync with `.mcp.json`.
|
|
262
|
+
|
|
263
|
+
### Validation Steps
|
|
264
|
+
|
|
265
|
+
1. **Load required keys**: Reads `protected-actions.json` to build the set of required credential keys
|
|
266
|
+
2. **Check vault mappings**: Reads `vault-mappings.json`; counts configured keys (both `op://` refs and direct values)
|
|
267
|
+
3. **Check `.mcp.json` env blocks**: Keys injected directly into `.mcp.json` (e.g. `OP_SERVICE_ACCOUNT_TOKEN`) count as configured even if absent from vault-mappings
|
|
268
|
+
4. **OP token desync detection**: Compares the shell `OP_SERVICE_ACCOUNT_TOKEN` environment variable against the value in `.mcp.json`; if they differ, sets `opTokenDesync = true` and always overwrites `process.env` with the `.mcp.json` value (source of truth)
|
|
269
|
+
5. **Alternative key resolution**: Removes keys from the missing list if a known alternative is already configured (e.g. `ELASTIC_CLOUD_ID` / `ELASTIC_ENDPOINT`)
|
|
270
|
+
6. **1Password connectivity**: If any `op://` refs are present, calls `op whoami` to verify the CLI is authenticated
|
|
271
|
+
|
|
272
|
+
### Output Behavior
|
|
273
|
+
|
|
274
|
+
| Condition | Output |
|
|
275
|
+
|-----------|--------|
|
|
276
|
+
| All configured, no desync | Silent (`suppressOutput: true`) |
|
|
277
|
+
| Token desync only | Warning prefix: "GENTYR: OP_SERVICE_ACCOUNT_TOKEN in shell differs from .mcp.json (source of truth). Run `npx gentyr sync` to re-sync." |
|
|
278
|
+
| Missing credentials | Error with count; prepended with desync warning if applicable |
|
|
279
|
+
| 1Password not authenticated | Error prompting to run setup with `--op-token`; prepended with desync warning if applicable |
|
|
280
|
+
|
|
281
|
+
### Deployment
|
|
282
|
+
|
|
283
|
+
The hook lives at `.claude/hooks/credential-health-check.js` and auto-propagates to target projects via the `.claude/hooks/` directory symlink (npm link model).
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Background Automation (hourly-automation.js)
|
|
288
|
+
|
|
289
|
+
Orchestrated by a launchd service running every 10 minutes.
|
|
290
|
+
|
|
291
|
+
### CTO Activity Gate
|
|
292
|
+
|
|
293
|
+
All automation is gated behind a recency check on the deputy-CTO briefing. If the last briefing is > 24 hours old, the automation exits immediately. This prevents rogue automation when the CTO is not actively monitoring.
|
|
294
|
+
|
|
295
|
+
### Execution Order
|
|
296
|
+
|
|
297
|
+
1. **Usage Optimizer** - Collect snapshot, adjust factor
|
|
298
|
+
2. **Key Sync** - Discover credentials, refresh tokens, prune dead keys
|
|
299
|
+
3. **Urgent Task Dispatcher** - Dispatch urgent priority tasks immediately (bypasses age filter)
|
|
300
|
+
4. **Task Runner** - Query todo.db for pending normal tasks (1-hour age filter), spawn agents up to concurrency limit
|
|
301
|
+
5. **Feedback Pipeline** - Trigger user persona testing on staging changes
|
|
302
|
+
|
|
303
|
+
### Task Orchestration
|
|
304
|
+
|
|
305
|
+
**Priority-Based Dispatch** (added 2026-02-21):
|
|
306
|
+
- Tasks in the TODO database have a `priority` field with values `'normal' | 'urgent'`
|
|
307
|
+
- **Urgent tasks** bypass the 1-hour age filter and dispatch immediately in Step 4
|
|
308
|
+
- **Normal tasks** require 1-hour age threshold before dispatch in Step 5
|
|
309
|
+
- Both urgent and normal dispatchers respect global concurrency limits
|
|
310
|
+
- All triage self-handle operations route through `create_task(priority: 'urgent')` for full governance
|
|
311
|
+
|
|
312
|
+
**Task Lifecycle**:
|
|
313
|
+
1. Created via `mcp__todo-db__create_task` (default `priority: 'normal'`)
|
|
314
|
+
2. If urgent: dispatched immediately by hourly automation Step 4
|
|
315
|
+
3. If normal: waits 1 hour, then dispatched by hourly automation Step 5
|
|
316
|
+
4. Agent spawned with task context, status → `in_progress`
|
|
317
|
+
5. On completion: status → `done`, followup tasks created if configured
|
|
318
|
+
6. Stale tasks (in_progress > 4 hours) escalated to project manager
|
|
319
|
+
|
|
320
|
+
**Concurrency Cap**:
|
|
321
|
+
- Default: 5 simultaneous task agents
|
|
322
|
+
- Configurable via `DEFAULT_MAX_CONCURRENT` in `agent-tracker.js`
|
|
323
|
+
- Urgent + normal combined count against single global limit
|
|
324
|
+
|
|
325
|
+
### Credential Cache
|
|
326
|
+
|
|
327
|
+
1Password credentials are lazily resolved on first agent spawn. Skipped in headless mode without `OP_SERVICE_ACCOUNT_TOKEN` to avoid macOS permission prompts. Results cached in memory only.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Key Sync Module (key-sync.js)
|
|
332
|
+
|
|
333
|
+
Shared library used by api-key-watcher, hourly-automation, credential-sync-hook, and quota-monitor.
|
|
334
|
+
|
|
335
|
+
### `syncKeys()` Process
|
|
336
|
+
|
|
337
|
+
1. Discover credentials from all sources (env, Keychain, credentials file)
|
|
338
|
+
2. Sync into rotation state (add new, update existing)
|
|
339
|
+
3. Refresh expired tokens AND proactively refresh non-active tokens approaching expiry
|
|
340
|
+
4. Resolve account profiles for keys with `account_uuid === null` — calls `fetchAccountProfile()` for each active/exhausted key missing a UUID; non-fatal, retried on next sync
|
|
341
|
+
5. Set initial `active_key_id` if not set
|
|
342
|
+
6. Pre-expiry restartless swap if active key near expiry
|
|
343
|
+
7. Prune dead keys (invalid > 7 days, never prunes active key)
|
|
344
|
+
8. Write state and return `{ keysAdded, keysUpdated, tokensRefreshed }`
|
|
345
|
+
|
|
346
|
+
### Credential Sources (priority order)
|
|
347
|
+
|
|
348
|
+
1. `CLAUDE_CODE_OAUTH_TOKEN` environment variable
|
|
349
|
+
2. macOS Keychain `Claude Code-credentials` entry
|
|
350
|
+
3. `~/.claude/.credentials.json` file
|
|
351
|
+
|
|
352
|
+
All sources are read (not short-circuited) and merged into rotation state.
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## Config Reader (config-reader.js)
|
|
357
|
+
|
|
358
|
+
Centralized dynamic cooldown configuration.
|
|
359
|
+
|
|
360
|
+
### `getCooldown(key, fallbackMinutes)`
|
|
361
|
+
|
|
362
|
+
Priority: `effective[key]` > `defaults[key]` > `fallbackMinutes`
|
|
363
|
+
|
|
364
|
+
The `effective` object is computed by the usage optimizer as `default * (1 / factor)`. Every hook and automation reads cooldowns through this function, making factor adjustment propagate system-wide.
|
|
365
|
+
|
|
366
|
+
### Configuration Structure
|
|
367
|
+
|
|
368
|
+
```json
|
|
369
|
+
{
|
|
370
|
+
"version": 1,
|
|
371
|
+
"defaults": { "task_runner": 60, "triage_check": 5, ... },
|
|
372
|
+
"effective": { "task_runner": 30, "triage_check": 3, ... },
|
|
373
|
+
"adjustment": {
|
|
374
|
+
"factor": 1.5,
|
|
375
|
+
"last_updated": "...",
|
|
376
|
+
"constraining_metric": "5h|7d",
|
|
377
|
+
"projected_at_reset": 0.89,
|
|
378
|
+
"direction": "ramping up|ramping down|stable",
|
|
379
|
+
"hours_until_reset": 3.5
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Pre-Commit Review Hook (pre-commit-review.js)
|
|
387
|
+
|
|
388
|
+
Runs as a Husky pre-commit hook on every `git commit` attempt.
|
|
389
|
+
|
|
390
|
+
### Commit Flow
|
|
391
|
+
|
|
392
|
+
```
|
|
393
|
+
git commit
|
|
394
|
+
|
|
|
395
|
+
v
|
|
396
|
+
pre-commit-review.js
|
|
397
|
+
|-- Verify git core.hooksPath hasn't been tampered (hook bypass detection)
|
|
398
|
+
|-- Check for valid emergency bypass token (from execute_bypass flow)
|
|
399
|
+
|-- Check for pending CTO items (G020 compliance)
|
|
400
|
+
| |-- Pending questions in deputy-cto.db?
|
|
401
|
+
| |-- Pending triage items in cto-reports.db?
|
|
402
|
+
| |-- Either present? -> BLOCK commit
|
|
403
|
+
|-- Check for valid approval token (from deputy-cto approve_commit)
|
|
404
|
+
| |-- Token exists + not expired (5 min) + hash matches staged files?
|
|
405
|
+
| |-- Yes -> ALLOW commit
|
|
406
|
+
|-- Spawn deputy-cto review in background
|
|
407
|
+
|-- BLOCK commit (await review)
|
|
408
|
+
|
|
|
409
|
+
v (after deputy-cto reviews and approves)
|
|
410
|
+
|
|
411
|
+
git commit (second attempt)
|
|
412
|
+
|-- Valid approval token found -> ALLOW commit
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Approval Token Lifecycle
|
|
416
|
+
|
|
417
|
+
1. Deputy-CTO reviews staged diff and calls `approve_commit`
|
|
418
|
+
2. `approve_commit` writes `.claude/commit-approval-token.json` with SHA-256 hash of staged diff + 5-minute expiry
|
|
419
|
+
3. Next commit attempt validates: token unexpired AND `diffHash` matches current staged changes
|
|
420
|
+
4. On match: commit proceeds; token consumed
|
|
421
|
+
|
|
422
|
+
### Emergency Bypass
|
|
423
|
+
|
|
424
|
+
A CTO-authorized emergency bypass writes a `commit_decisions` row with `rationale LIKE 'EMERGENCY BYPASS%'` and `question_id IS NOT NULL`. The hook detects this within a 5-minute window and allows the commit without requiring a deputy-CTO review cycle. The `question_id IS NOT NULL` constraint ensures only bypass decisions created via the `execute_bypass` MCP tool (which always links to the originating bypass-request question) are honored — bare `approve_commit` calls with "EMERGENCY BYPASS" prefix are blocked by the server-side guard.
|
|
425
|
+
|
|
426
|
+
### G020 Compliance Check
|
|
427
|
+
|
|
428
|
+
Before any approval path, the hook queries:
|
|
429
|
+
- `deputy-cto.db` questions table: `WHERE status = 'pending'`
|
|
430
|
+
- `cto-reports.db` reports table: `WHERE triage_status = 'pending'` (or `triaged_at IS NULL` as fallback)
|
|
431
|
+
|
|
432
|
+
If either count > 0, the commit is blocked regardless of token state. This ensures no code ships while the CTO has outstanding decisions.
|
|
433
|
+
|
|
434
|
+
### Fail-Closed Behavior
|
|
435
|
+
|
|
436
|
+
- `better-sqlite3` unavailable: skip CTO item check (permissive), approval token check still runs
|
|
437
|
+
- DB read error on triage count: assume 1 pending item (blocks commit)
|
|
438
|
+
- Hook path tampered (`core.hooksPath` changed): BLOCK with alert
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Deputy-CTO Server Security Guards (deputy-cto/server.ts)
|
|
443
|
+
|
|
444
|
+
Defense-in-depth guards implemented across the deputy-cto and agent-reports MCP servers to prevent bypass-route exploitation.
|
|
445
|
+
|
|
446
|
+
### Phase 1: Tool Handler Guards
|
|
447
|
+
|
|
448
|
+
Four `add_question` / `answer_question` / `clear_question` / `approve_commit` guards block agent-accessible loopholes:
|
|
449
|
+
|
|
450
|
+
**`add_question` Guard** — Blocks creation of `bypass-request` or `protected-action-request` question types via `add_question`. These types have dedicated creation paths (`request_bypass` tool, protected-action hook) that enforce the CTO verification code flow. An agent cannot self-create a bypass request and then self-answer it.
|
|
451
|
+
|
|
452
|
+
**`answer_question` Guard** — Blocks answering `bypass-request` questions via `answer_question`. The only valid answer path for bypass-requests is the CTO typing `APPROVE BYPASS <code>` in chat, which routes through the `execute_bypass` tool with cryptographic code verification.
|
|
453
|
+
|
|
454
|
+
**`clear_question` Guard** — Blocks clearing a pending `bypass-request` or `protected-action-request` question via `clear_question`. Pending requests of these types can only be resolved through their designated approval flows. This prevents an agent from clearing a pending bypass-request to make it appear resolved.
|
|
455
|
+
|
|
456
|
+
**`approve_commit` Guard** — Blocks any `approve_commit` call with a rationale beginning with `EMERGENCY BYPASS`. This prefix is reserved exclusively for the `execute_bypass` MCP tool, which validates a CTO-provided 6-character code before writing the bypass decision row. Direct use of this prefix via `approve_commit` would create a bypass-looking token without CTO verification.
|
|
457
|
+
|
|
458
|
+
The SQL fix in `pre-commit-review.js` (`AND question_id IS NOT NULL`) ensures the hook only honors bypass decisions that were created by `execute_bypass` — which always links `question_id` to the originating bypass-request question — not arbitrary `approve_commit` calls with the "EMERGENCY BYPASS" prefix.
|
|
459
|
+
|
|
460
|
+
### Phase 2: HMAC Verification and Rate Limits
|
|
461
|
+
|
|
462
|
+
**`executeBypass` HMAC verification** — When the CTO types `APPROVE BYPASS <code>`, the UserPromptSubmit hook writes a `bypass-approval-token.json` file containing an HMAC-SHA256 signature over `code|request_id|expires_timestamp|bypass-approved`. The `execute_bypass` tool recomputes the expected HMAC using the protection key (`loadProtectionKey()`) and rejects tokens that fail verification with `FORGERY DETECTED: Invalid bypass approval token signature. Token deleted.` This matches the pattern used by `executeHotfixPromotion()` and prevents an agent from writing a forged approval token file (the key is root-owned and unreadable by agent processes).
|
|
463
|
+
|
|
464
|
+
**`requestBypass` rate limit** — Maximum 3 pending bypass-request questions at a time. If the limit is reached, `request_bypass` returns an error asking the agent to wait for existing requests to be addressed. Prevents request flooding that could obscure legitimate bypass requests.
|
|
465
|
+
|
|
466
|
+
**`reportToCto` rate limit (agent-reports server)** — Maximum 5 untriaged reports per reporting agent at a time. If the limit is reached, `report_to_cto` returns an error message. Prevents a single agent from flooding the triage queue and hiding reports from other agents.
|
|
467
|
+
|
|
468
|
+
**`get_pending_count` exposes `pending_triage_count`** — The `GetPendingCountResult` type now includes `pending_triage_count` alongside `pending_count` and `commits_blocked`. This lets the CTO see the split between pending questions and pending triage reports when understanding why `commits_blocked: true`.
|
|
469
|
+
|
|
470
|
+
**`spawn_implementation_task` removed** — The `spawn_implementation_task` tool (which spawned background Claude instances directly from the deputy-cto server) was removed. Task spawning is now exclusively managed by the agent-tracker MCP server and hourly automation, which enforce concurrency limits, registration, and tracking.
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## State Files
|
|
475
|
+
|
|
476
|
+
| File | Scope | Written By | Read By |
|
|
477
|
+
|------|-------|-----------|---------|
|
|
478
|
+
| `~/.claude/api-key-rotation.json` | User | key-sync, quota-monitor, api-key-watcher | All rotation hooks, rotation-proxy |
|
|
479
|
+
| `~/.claude/.credentials.json` | User | Claude Code | key-sync |
|
|
480
|
+
| `~/.claude/rotation-proxy.log` | User | rotation-proxy | monitor-token-swap (--audit) |
|
|
481
|
+
| `.claude/state/automation-config.json` | Project | usage-optimizer | config-reader (all hooks) |
|
|
482
|
+
| `.claude/state/usage-snapshots.json` | Project | usage-optimizer | usage-optimizer, cto-dashboard |
|
|
483
|
+
| `.claude/state/quota-monitor-state.json` | Project | quota-monitor | quota-monitor |
|
|
484
|
+
| macOS Keychain `Claude Code-credentials` | System | key-sync, quota-monitor | Claude Code runtime |
|