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,2830 @@
|
|
|
1
|
+
# GENTYR Framework Changelog
|
|
2
|
+
|
|
3
|
+
## 2026-02-22 - npm CLI Package Migration
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
**`cli/` package — `npx gentyr` CLI** (`cli/index.js`, `cli/commands/*.js`, `cli/lib/*.js`):
|
|
8
|
+
- `gentyr init [--op-token <token>]` — first-time project setup; replaces `setup.sh --path . [--protect]`
|
|
9
|
+
- `gentyr sync` — force rebuild MCP servers, re-merge settings.json, regenerate .mcp.json, deploy staged hooks; also runs automatically on SessionStart when framework version or config hash changes
|
|
10
|
+
- `gentyr status` — print installation state (model, framework path, version, protection status)
|
|
11
|
+
- `gentyr protect` / `gentyr unprotect` — enable/disable root-owned file protection; replaces `setup.sh --protect-only` / `--unprotect-only`
|
|
12
|
+
- `gentyr uninstall` — full teardown; replaces `setup.sh --uninstall`
|
|
13
|
+
- `gentyr migrate` — convert legacy `.claude-framework` symlink installs to `node_modules/gentyr` npm model
|
|
14
|
+
- `gentyr scaffold <name>` — scaffold new project directory
|
|
15
|
+
|
|
16
|
+
**CLI lib modules** (`cli/lib/`):
|
|
17
|
+
- `resolve-framework.js` — resolves `node_modules/gentyr` (preferred) then `.claude-framework` (fallback)
|
|
18
|
+
- `symlinks.js` — creates directory, agent, and reporter symlinks from framework into target project
|
|
19
|
+
- `config-gen.js` — generates `.mcp.json`, merges `settings.json`, updates `CLAUDE.md`, updates `.gitignore`
|
|
20
|
+
- `state.js` — reads/writes `gentyr-state.json`; tracks installed version, config hash, install model
|
|
21
|
+
- `init.js` — shared init logic used by both `init` and `migrate` commands
|
|
22
|
+
|
|
23
|
+
**`packages/mcp-servers/src/shared/resolve-framework.ts`**:
|
|
24
|
+
- Shared TypeScript framework path resolver for MCP servers
|
|
25
|
+
- Exports `resolveFrameworkDir()`, `resolveFrameworkRelative()`, `detectInstallModel()`
|
|
26
|
+
- Prefers `node_modules/gentyr`, falls back to `.claude-framework`
|
|
27
|
+
- Used by MCP servers that need to reference the framework directory
|
|
28
|
+
|
|
29
|
+
**`scripts/hooks/gentyr-sync.js`** (staged hook):
|
|
30
|
+
- SessionStart hook; detects framework version or config template changes and auto-runs `npx gentyr sync`
|
|
31
|
+
- Fast path: under 5ms when nothing changed (compares two small JSON files)
|
|
32
|
+
- Registered in `settings.json.template` under `SessionStart`
|
|
33
|
+
|
|
34
|
+
**`scripts/hooks/playwright-cli-guard.js`** (staged hook):
|
|
35
|
+
- PreToolUse(Bash) hook; detects CLI-based Playwright invocations and warns agents to use MCP tools instead
|
|
36
|
+
- Non-blocking: emits `systemMessage` warning, never prevents execution
|
|
37
|
+
- Registered in `settings.json.template` under `PreToolUse > Bash`
|
|
38
|
+
- Tests: `.claude/hooks/__tests__/playwright-cli-guard.test.js` (23 tests, `node --test`)
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
**`package.json`**:
|
|
43
|
+
- Removed `"private": true`; package is now publishable
|
|
44
|
+
- Added `"bin": { "gentyr": "./cli/index.js" }` — enables `npx gentyr` and global install
|
|
45
|
+
- Added `"prepare": "npm run build:mcp"` — MCP servers build automatically on `npm install`
|
|
46
|
+
- Added `"build:mcp"` script — `cd packages/mcp-servers && npm install && npm run build`
|
|
47
|
+
- Version bumped to `1.3.0`
|
|
48
|
+
|
|
49
|
+
**`settings.json.template`**:
|
|
50
|
+
- Added `gentyr-sync.js` to SessionStart hooks
|
|
51
|
+
- Added `playwright-cli-guard.js` to PreToolUse(Bash) hooks
|
|
52
|
+
|
|
53
|
+
**34+ files updated** to reference `node_modules/gentyr` instead of `.claude-framework`:
|
|
54
|
+
- `CLAUDE.md`, `README.md` — install instructions rewritten for npm-based workflow
|
|
55
|
+
- `docs/AUTOMATION-SYSTEMS.md`, `docs/TESTING.md`, `docs/SETUP-GUIDE.md`, `docs/STACK.md`, `docs/shared/PROTECTION-SYSTEM.md`, `docs/shared/EPHEMERAL-STATE-FILES.md` — references updated
|
|
56
|
+
- Multiple `.claude/agents/`, `.claude/commands/`, `.claude/hooks/` files — path references updated
|
|
57
|
+
- `scripts/*.js`, `scripts/*.sh` — dual-path support (`node_modules/gentyr` + `.claude-framework` fallback)
|
|
58
|
+
|
|
59
|
+
### Fixed (Security — from code-reviewer)
|
|
60
|
+
|
|
61
|
+
**Command injection in `cli/commands/protect.js`**:
|
|
62
|
+
- `SUDO_USER` / `USER` environment variables were passed directly to `chown` via shell string interpolation
|
|
63
|
+
- Added `assertSafeName()` validator (`/^[a-z_][a-z0-9_-]{0,31}$/i`); throws on unsafe values
|
|
64
|
+
- Switched from `execSync` to `execFileSync` throughout
|
|
65
|
+
|
|
66
|
+
**Shell injection in `cli/commands/init.js`**:
|
|
67
|
+
- `--op-token` value was interpolated directly into a shell command
|
|
68
|
+
- Added `isValidOpToken()` validator (`/^[a-zA-Z0-9_-]{10,}$/`); rejects tokens with shell metacharacters
|
|
69
|
+
|
|
70
|
+
**Dead code removed in `cli/commands/init.js`**:
|
|
71
|
+
- `fs.symlinkSync().catch?.()` was unreachable — `symlinkSync` is synchronous and does not return a promise
|
|
72
|
+
- Removed the `.catch?.()` call
|
|
73
|
+
|
|
74
|
+
**`execSync` replaced with `execFileSync`** across all CLI command files:
|
|
75
|
+
- Zero remaining `execSync` calls in the CLI package
|
|
76
|
+
|
|
77
|
+
### Deprecated
|
|
78
|
+
|
|
79
|
+
`scripts/setup.sh` is now the legacy install path. The `--path` flag, `--protect`, `--unprotect`, `--protect-only`, `--unprotect-only`, and `--uninstall` modes are superseded by the `npx gentyr` CLI. `setup.sh` will be removed in v2.0.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 2026-02-22 - Security: SQL Injection Fix in Supabase MCP Server
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
**SQL injection vulnerability in Supabase MCP server** (`packages/mcp-servers/src/supabase/types.ts`, `packages/mcp-servers/src/supabase/server.ts`):
|
|
88
|
+
- Added shared `sqlIdentifier` Zod validator (`/^[a-zA-Z_][a-zA-Z0-9_]*$/`) to all 6 schemas that accept table or function names: `SelectArgsSchema`, `InsertArgsSchema`, `UpdateArgsSchema`, `DeleteArgsSchema`, `RpcArgsSchema`, and `DescribeTableArgsSchema`
|
|
89
|
+
- Table/function names were previously interpolated directly into SQL strings with no validation, allowing injection via malicious identifier strings
|
|
90
|
+
- `SqlArgsSchema` intentionally left unrestricted — it accepts raw SQL by design
|
|
91
|
+
- Defense-in-depth: `describeTable()` also adds single-quote escaping as a secondary guard
|
|
92
|
+
|
|
93
|
+
### Tests
|
|
94
|
+
|
|
95
|
+
**320 new vitest tests** (`packages/mcp-servers/src/supabase/__tests__/supabase-schemas.test.ts`):
|
|
96
|
+
- Coverage across all 6 affected schemas: valid identifiers, injection payloads (DROP, UNION, comment sequences), regex boundary cases, and edge cases (empty string, leading digits, special characters)
|
|
97
|
+
- Total: 1414 tests passing across 28 test files
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 2026-02-22 - OP_SERVICE_ACCOUNT_TOKEN Sync & Desync Detection
|
|
102
|
+
|
|
103
|
+
### Added
|
|
104
|
+
|
|
105
|
+
**OP token desync detection in `credential-health-check.js`** (`scripts/hooks/credential-health-check.js`, `.claude/hooks/credential-health-check.js`):
|
|
106
|
+
- At `SessionStart`, the hook now compares the shell `OP_SERVICE_ACCOUNT_TOKEN` environment variable against the value stored in `.mcp.json`
|
|
107
|
+
- If they differ, `opTokenDesync = true` is set; `process.env` is always overwritten with the `.mcp.json` value (source of truth)
|
|
108
|
+
- A `desyncPrefix` warning is prepended to any output message: "GENTYR: OP_SERVICE_ACCOUNT_TOKEN in shell differs from .mcp.json (source of truth). Run `npx gentyr sync` to re-sync."
|
|
109
|
+
- When all credentials are valid but a desync exists, the warning is emitted as the sole message rather than silent success
|
|
110
|
+
- Template copy (`scripts/hooks/credential-health-check.js`) synced to match the runtime copy; both files are now identical
|
|
111
|
+
|
|
112
|
+
**`setup.sh` section 3c — OP shell profile sync** (`scripts/setup.sh`):
|
|
113
|
+
- During install with `--op-token`, writes a `# BEGIN GENTYR OP` / `# END GENTYR OP` managed block to `~/.zshrc` (or `~/.bashrc`) containing `export OP_SERVICE_ACCOUNT_TOKEN=<token>`
|
|
114
|
+
- Idempotent: removes any existing managed block and any legacy unmanaged `export OP_SERVICE_ACCOUNT_TOKEN=` lines before writing
|
|
115
|
+
- During uninstall, removes the managed block from all detected shell profiles
|
|
116
|
+
|
|
117
|
+
**`validateShellSync()` in `setup-validate.js`** (`scripts/setup-validate.js`):
|
|
118
|
+
- New validator in the `SERVICE_VALIDATORS` registry (key: `shellSync`)
|
|
119
|
+
- Reads `.mcp.json` token as source of truth and compares against the `# BEGIN GENTYR OP` block in `~/.zshrc` / `~/.bashrc`
|
|
120
|
+
- Reports `fail` if: no managed block exists, legacy unmanaged export found, or tokens differ; reports `warn` if `.mcp.json` unreadable or no shell profile found
|
|
121
|
+
- Remediation message: "Run `npx gentyr sync` to re-sync shell profile with .mcp.json token"
|
|
122
|
+
|
|
123
|
+
### Tests
|
|
124
|
+
|
|
125
|
+
**11 new tests + 4 fixed assertions** (`.claude/hooks/__tests__/credential-health-check.test.js`):
|
|
126
|
+
- New `OP Token Desync Detection` describe block with 11 tests covering: desync warning when shell token differs from `.mcp.json`, silent success when tokens match, desync warning prepended to missing-credential messages, desync warning prepended to 1Password auth failure messages, `process.env` always overwritten with `.mcp.json` value, no desync when shell token is absent, and no token value exposure in output
|
|
127
|
+
- Fixed 4 existing test assertions that broke after desync changes (pattern updates for `desyncPrefix` and template literal matching)
|
|
128
|
+
- Total: 42 tests passing (was 31 before)
|
|
129
|
+
|
|
130
|
+
### Documentation
|
|
131
|
+
|
|
132
|
+
**Updated files**:
|
|
133
|
+
- `docs/AUTOMATION-SYSTEMS.md` — Hook Registration table updated to include `credential-health-check` at `SessionStart`; new "Credential Health Check Hook" section added
|
|
134
|
+
- `CLAUDE.md` — New "Credential Health Check Hook" bullet; uninstall description updated to mention shell profile block removal
|
|
135
|
+
- `docs/SETUP-GUIDE.md` — Phase 1 updated with shell profile sync behavior and managed block format
|
|
136
|
+
- `docs/CHANGELOG.md` — This entry
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 2026-02-22 - Bypass Security Hardening (Phase 2) + Fix Unknown Accounts
|
|
141
|
+
|
|
142
|
+
### Added
|
|
143
|
+
|
|
144
|
+
**HMAC verification in `executeBypass()`** (`packages/mcp-servers/src/deputy-cto/server.ts`):
|
|
145
|
+
- When the CTO types `APPROVE BYPASS <code>`, the UserPromptSubmit hook now writes an HMAC-SHA256 signature into `bypass-approval-token.json` over `code|request_id|expires_timestamp|bypass-approved`
|
|
146
|
+
- `execute_bypass` verifies this signature using the root-owned protection key before proceeding
|
|
147
|
+
- Forged token files are detected, deleted, and rejected with `FORGERY DETECTED: Invalid bypass approval token signature`
|
|
148
|
+
- Matches the verification pattern already used by `executeHotfixPromotion()`
|
|
149
|
+
|
|
150
|
+
**`pending_triage_count` in `get_pending_count` result** (`packages/mcp-servers/src/deputy-cto/server.ts`, `types.ts`):
|
|
151
|
+
- `GetPendingCountResult` now includes `pending_triage_count` alongside `pending_count`
|
|
152
|
+
- Lets the CTO see the split between pending questions and pending triage reports when `commits_blocked: true`
|
|
153
|
+
|
|
154
|
+
**Account profile resolution in `syncKeys()`** (`.claude/hooks/key-sync.js`, `.claude/hooks/api-key-watcher.js`):
|
|
155
|
+
- `fetchAccountProfile(accessToken)` exported from `key-sync.js`; calls `https://api.anthropic.com/api/oauth/profile` to resolve `account_uuid` and `email`
|
|
156
|
+
- `syncKeys()` now calls this for every active/exhausted key with `account_uuid === null` after the token refresh loop
|
|
157
|
+
- Fixes "unknown" accounts in the CTO notification status line caused by keys added by automation or token refresh paths that skipped the interactive SessionStart profile-resolution
|
|
158
|
+
- `api-key-watcher.js` now imports `fetchAccountProfile` from `key-sync.js` instead of maintaining a local copy
|
|
159
|
+
|
|
160
|
+
**Fingerprint cross-match in quota display hooks** (`.claude/hooks/cto-notification-hook.js`, `.claude/hooks/slash-command-prefetch.js`):
|
|
161
|
+
- Fallback deduplication for null-UUID keys: after building the account map, checks if any fingerprint-based entry (`fp:` prefix) matches a UUID-bearing entry by `seven_day + seven_day_sonnet` values
|
|
162
|
+
- Merges matches to prevent "unknown" appearing in the status line even when the profile API is temporarily unavailable
|
|
163
|
+
|
|
164
|
+
### Changed
|
|
165
|
+
|
|
166
|
+
**`requestBypass` rate limit** (`packages/mcp-servers/src/deputy-cto/server.ts`):
|
|
167
|
+
- Maximum 3 pending bypass-request questions allowed at a time
|
|
168
|
+
- `request_bypass` returns an error if the limit is reached, asking the agent to wait
|
|
169
|
+
|
|
170
|
+
**`reportToCto` rate limit** (`packages/mcp-servers/src/agent-reports/server.ts`):
|
|
171
|
+
- Maximum 5 untriaged reports per reporting agent allowed at a time
|
|
172
|
+
- `report_to_cto` returns an error if the limit is reached
|
|
173
|
+
|
|
174
|
+
### Removed
|
|
175
|
+
|
|
176
|
+
**`spawn_implementation_task` tool** (`packages/mcp-servers/src/deputy-cto/server.ts`, `types.ts`):
|
|
177
|
+
- Removed the tool that spawned background Claude instances directly from the deputy-cto server
|
|
178
|
+
- Task spawning is now exclusively managed by the agent-tracker MCP server and hourly automation
|
|
179
|
+
|
|
180
|
+
### Tests
|
|
181
|
+
|
|
182
|
+
**15 new vitest tests** (`packages/mcp-servers/src/deputy-cto/__tests__/deputy-cto.test.ts`, `packages/mcp-servers/src/agent-reports/__tests__/agent-reports.test.ts`):
|
|
183
|
+
- HMAC verification: forged token, missing HMAC, missing key, valid HMAC (4 tests)
|
|
184
|
+
- `get_pending_count` triage count (3 tests)
|
|
185
|
+
- `requestBypass` rate limiting (3 tests)
|
|
186
|
+
- `reportToCto` rate limiting (4 tests, in agent-reports test file)
|
|
187
|
+
- Total: 1093 tests passing across 27 test files
|
|
188
|
+
|
|
189
|
+
### Documentation
|
|
190
|
+
|
|
191
|
+
**Updated files**:
|
|
192
|
+
- `docs/AUTOMATION-SYSTEMS.md` — Deputy-CTO Security Guards section expanded with Phase 2 details; `syncKeys()` process updated with profile resolution step
|
|
193
|
+
- `docs/CHANGELOG.md` — This entry
|
|
194
|
+
- `CLAUDE.md` — Key Sync Module updated with `fetchAccountProfile` export and `syncKeys()` profile resolution step
|
|
195
|
+
- `plans/fix-unknown-accounts.md` — Removed (plan fully implemented)
|
|
196
|
+
- `plans/TRIAGE-COMMAND.md` — Removed (plan fully implemented in prior session)
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 2026-02-21 - Rotation Proxy E2E Validation + Triage Command
|
|
201
|
+
|
|
202
|
+
### Added
|
|
203
|
+
|
|
204
|
+
**`/triage` slash command** (`.claude/commands/triage.md`, `scripts/force-triage-reports.js`):
|
|
205
|
+
- On-demand force-spawn of the deputy-CTO triage cycle
|
|
206
|
+
- Bypasses hourly automation's triage check interval, automation-enabled flag, and CTO activity gate
|
|
207
|
+
- Prefetch handler in `slash-command-prefetch.js` injects pending report counts into the command
|
|
208
|
+
- Calls `force_triage_reports` on the agent-tracker MCP server
|
|
209
|
+
- Returns spawned session ID for `claude --resume` workflow
|
|
210
|
+
- Preserves concurrency guard, agent tracker registration, and per-item triage cooldown filtering
|
|
211
|
+
- Mirrors the `/spawn-tasks` pattern
|
|
212
|
+
|
|
213
|
+
**`force_triage_reports` MCP tool** (`packages/mcp-servers/src/agent-tracker/server.ts`, `types.ts`):
|
|
214
|
+
- New tool in agent-tracker server; calls `scripts/force-triage-reports.js` via execFileSync
|
|
215
|
+
- Returns `{ agentId, pid, sessionId, pendingReports }` result
|
|
216
|
+
|
|
217
|
+
**Deputy-CTO test coverage** (`packages/mcp-servers/src/deputy-cto/__tests__/deputy-cto.test.ts`):
|
|
218
|
+
- 284 lines of new vitest tests for deputy-cto server
|
|
219
|
+
|
|
220
|
+
### Fixed
|
|
221
|
+
|
|
222
|
+
**TLS CONNECT `head` buffer handling** (`scripts/rotation-proxy.js`):
|
|
223
|
+
- Added `clientSocket.unshift(head)` before wrapping CONNECT socket in TLSSocket
|
|
224
|
+
- The `head` parameter contains early client data (TLS ClientHello) sent before the 200 response arrives; dropping it caused intermittent ECONNRESET errors
|
|
225
|
+
- Success rate went from ~20% to 100% in controlled tests
|
|
226
|
+
- This is the textbook fix for Node.js HTTPS MITM proxies
|
|
227
|
+
|
|
228
|
+
### Tests
|
|
229
|
+
|
|
230
|
+
**`scripts/__tests__/rotation-proxy.test.js`** (NEW, 60 unit tests):
|
|
231
|
+
- Code structure: `head` buffer unshift in MITM CONNECT handler, transparent passthrough head forwarding
|
|
232
|
+
- Behavioral: `parseHttpRequest()`, `rebuildRequest()`, domain routing, log rotation threshold, `loadCerts()`, `getActiveToken()`, `rotateOnExhaustion()`, 429 retry cap
|
|
233
|
+
- Uses Node's built-in test runner (`node:test`)
|
|
234
|
+
- All 120 tests passing: 60 quota-monitor + 60 rotation-proxy
|
|
235
|
+
|
|
236
|
+
### Documentation
|
|
237
|
+
|
|
238
|
+
**Updated files**:
|
|
239
|
+
- `CLAUDE.md` — Added `/triage` command under Automation Service; added CONNECT head buffer handling note to Rotation Proxy section
|
|
240
|
+
- `docs/CHANGELOG.md` — This entry
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 2026-02-21 - Rotation Proxy (replaces binary patching for credential swap)
|
|
245
|
+
|
|
246
|
+
### Added
|
|
247
|
+
|
|
248
|
+
**Rotation proxy server** (`scripts/rotation-proxy.js`):
|
|
249
|
+
- Local MITM proxy on localhost:18080 that intercepts api.anthropic.com and mcp-proxy.anthropic.com
|
|
250
|
+
- Swaps Authorization header with active key from rotation state (`~/.claude/api-key-rotation.json`) on each request
|
|
251
|
+
- On 429 response: marks key exhausted, calls `selectActiveKey()`, retries request (max 2 retries)
|
|
252
|
+
- SSE streaming support for long-running API requests
|
|
253
|
+
- Health endpoint at `GET /__health` - returns active key ID, uptime, request count
|
|
254
|
+
- Structured JSON logging to `~/.claude/rotation-proxy.log` (1MB max with rotation)
|
|
255
|
+
- Runs as launchd KeepAlive service (`com.local.gentyr-rotation-proxy`) — auto-restarts on crash
|
|
256
|
+
|
|
257
|
+
**TLS certificate generation** (`scripts/generate-proxy-certs.sh`):
|
|
258
|
+
- One-time CA + server cert creation for MITM interception
|
|
259
|
+
- Trusts CA in macOS System Keychain automatically
|
|
260
|
+
- Idempotent: skips if certs already exist; `--remove` cleans up
|
|
261
|
+
|
|
262
|
+
**Proxy integration in launch points**:
|
|
263
|
+
- `scripts/setup-automation-service.sh`: provisions proxy launchd plist before automation plist; adds `HTTPS_PROXY/HTTP_PROXY/NO_PROXY` to automation environment
|
|
264
|
+
- `scripts/setup.sh`: cert generation in step 5c; shell profile integration (step 6d) with `BEGIN/END GENTYR PROXY` markers; cert removal + profile cleanup on uninstall
|
|
265
|
+
- `.claude/hooks/hourly-automation.js`: `checkProxyHealth()` before agent spawning; proxy env vars in `buildSpawnEnv()`
|
|
266
|
+
- `.claude/hooks/session-reviver.js`: proxy env vars in `buildSpawnEnv()`
|
|
267
|
+
|
|
268
|
+
### Changed
|
|
269
|
+
|
|
270
|
+
**Adoption tracking removed** (`.claude/hooks/quota-monitor.js`):
|
|
271
|
+
- Removed `pendingAudit.adopted`, `adoptionCheckCount`, `ADOPTION_CONFIRMED/TIMEOUT` logic (now handled at network layer by proxy)
|
|
272
|
+
- Simplified `pendingAudit` creation; rotation audit logging retained
|
|
273
|
+
|
|
274
|
+
**Binary patching archived** (`scripts/patch-credential-cache.js`, `scripts/watch-claude-version.js`):
|
|
275
|
+
- `patch-credential-cache.js`: deprecation banner added; no code changes; kept for reference
|
|
276
|
+
- `watch-claude-version.js`: all credential patch logic removed; now only handles Clawd mascot patch on binary updates
|
|
277
|
+
|
|
278
|
+
### Removed
|
|
279
|
+
|
|
280
|
+
**Adoption tracking tests** (`.claude/hooks/__tests__/quota-monitor-adoption-tracking.test.js`):
|
|
281
|
+
- Deleted: adoption tracking no longer exists in quota-monitor
|
|
282
|
+
|
|
283
|
+
### Tests
|
|
284
|
+
|
|
285
|
+
- Updated `quota-monitor-rotation-audit.test.js`: removed adoption tracking assertions
|
|
286
|
+
- All tests passing: quota-monitor (27), rotation-audit (33), adaptive (42) = 102 total
|
|
287
|
+
|
|
288
|
+
### Documentation
|
|
289
|
+
|
|
290
|
+
**Updated files**:
|
|
291
|
+
- `CLAUDE.md` - Rotation Proxy section added; Binary Patch Research marked ARCHIVED; quota-monitor adoption tracking notes removed
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## 2026-02-21 - Seamless Credential Rotation + Health Auditing
|
|
296
|
+
|
|
297
|
+
### Changed
|
|
298
|
+
|
|
299
|
+
**Seamless rotation for quota-based switches** (`.claude/hooks/quota-monitor.js`):
|
|
300
|
+
- Removed disruptive kill/restart paths (old lines 432-491): no more AppleScript terminal injection, no more orphaned process spawning
|
|
301
|
+
- Interactive sessions: now receive `continue: true` with system message explaining adoption timing (credentials written to Keychain, picked up at SRA or r6T, not immediate)
|
|
302
|
+
- Automated sessions: now receive `continue: false` with stopReason (clean stop for session-reviver to resume with fresh credentials from Keychain)
|
|
303
|
+
- Removed unused imports: `spawn`, `getClaudePid`, `detectTerminal`, `generateRestartScript`, `shellEscape`
|
|
304
|
+
- Updated doc comment to reflect seamless rotation behavior (version 2.0.0)
|
|
305
|
+
|
|
306
|
+
**Post-rotation health audit** (`.claude/hooks/quota-monitor.js`):
|
|
307
|
+
- Added `pendingAudit` field to throttle state
|
|
308
|
+
- Added `verifyPendingAudit()` function to verify rotation success
|
|
309
|
+
- Writes audit results to `rotation-audit.log`
|
|
310
|
+
- Imports `readKeychainCredentials` and `generateKeyId` from key-sync.js
|
|
311
|
+
|
|
312
|
+
**Shared keychain reader** (`.claude/hooks/key-sync.js`):
|
|
313
|
+
- New export: `readKeychainCredentials()` - reads and parses macOS Keychain credentials directly
|
|
314
|
+
- Used by quota-monitor for post-rotation auditing and by monitor-token-swap for state verification
|
|
315
|
+
|
|
316
|
+
**Rotation health monitoring** (`scripts/monitor-token-swap.mjs`):
|
|
317
|
+
- Added `--audit` flag: prints rotation health report (recent rotations, pending audits, current state, Keychain status, alerts)
|
|
318
|
+
- Refactored `readKeychainState()` to delegate to shared `readKeychainCredentials()` from key-sync.js
|
|
319
|
+
- Audit mode shows rotation success rate, credential sync status, and system health metrics
|
|
320
|
+
|
|
321
|
+
### Added
|
|
322
|
+
|
|
323
|
+
**Binary patch research** (`scripts/patch-credential-cache.py`):
|
|
324
|
+
- Dry-run only research script for Claude Code's `iB()` credential memoization
|
|
325
|
+
- Searches for 9 patterns in Bun SEA binary (all found on v2.1.34)
|
|
326
|
+
- Proposes Approach A: setInterval injection to periodically clear `iB.cache` (60-second TTL)
|
|
327
|
+
- Not production-ready; exists for future reference if immediate adoption needed for quota rotation
|
|
328
|
+
- Test coverage: `scripts/__tests__/patch-credential-cache.test.js` (37 tests)
|
|
329
|
+
|
|
330
|
+
### Tests
|
|
331
|
+
|
|
332
|
+
**Test updates**:
|
|
333
|
+
- Updated quota-monitor tests for seamless rotation paths (186 tests total, all passing)
|
|
334
|
+
- Added `readKeychainCredentials()` coverage in key-sync tests
|
|
335
|
+
- Added `--audit` flag tests for monitor-token-swap
|
|
336
|
+
- Created `patch-credential-cache.test.js` with 37 tests for binary patch research script
|
|
337
|
+
- Fixed `readKeychainState` test to match new delegation pattern
|
|
338
|
+
|
|
339
|
+
### Documentation
|
|
340
|
+
|
|
341
|
+
**Updated files**:
|
|
342
|
+
- `CLAUDE.md` - Seamless rotation behavior, rotation monitoring tools, binary patch research note
|
|
343
|
+
- `docs/AUTOMATION-SYSTEMS.md` - Updated session flow diagrams and quota-monitor steps
|
|
344
|
+
- `MEMORY.md` - Added seamless rotation pattern note
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## 2026-02-21 - Priority-Based Urgent Task Dispatch
|
|
349
|
+
|
|
350
|
+
### Added
|
|
351
|
+
|
|
352
|
+
**Priority field in TODO database** (`packages/mcp-servers/src/todo-db/`):
|
|
353
|
+
- New `priority` field in task schema with values `'normal' | 'urgent'`
|
|
354
|
+
- Exposed in `CreateTaskArgsSchema` with default value `'normal'`
|
|
355
|
+
- Exposed in `ListTasksArgsSchema` as optional filter parameter
|
|
356
|
+
- Auto-migration added: `ALTER TABLE tasks ADD COLUMN priority TEXT NOT NULL DEFAULT 'normal'` runs on server init if column missing
|
|
357
|
+
- Type exports: `TASK_PRIORITY` constant array, `TaskPriority` type from `shared/constants.ts`
|
|
358
|
+
|
|
359
|
+
**Urgent dispatcher in hourly automation** (`.claude/hooks/hourly-automation.js`):
|
|
360
|
+
- New `tryDispatchUrgentTasks()` step runs before task runner (bypasses 1-hour age filter)
|
|
361
|
+
- Urgent tasks are NOT age-gated — they dispatch immediately when spawned
|
|
362
|
+
- Concurrency limit enforced: urgent dispatcher respects global agent cap
|
|
363
|
+
- Queries for tasks with `status='pending' AND priority='urgent'`
|
|
364
|
+
- Uses same `spawnTaskAgent()` flow as regular task runner
|
|
365
|
+
|
|
366
|
+
**Governance routing for triage self-handle** (`packages/mcp-servers/src/deputy-cto/server.ts`):
|
|
367
|
+
- Triage self-handle path now routes through `create_task` with `priority: 'urgent'` instead of ungoverned `spawn_implementation_task`
|
|
368
|
+
- Ensures ALL task spawning goes through centralized governance (concurrency limits, tracking, recovery)
|
|
369
|
+
- Urgent priority ensures immediate dispatch without waiting for 1-hour age threshold
|
|
370
|
+
|
|
371
|
+
### Changed
|
|
372
|
+
|
|
373
|
+
**Force-spawn script** (`scripts/force-spawn-tasks.js`):
|
|
374
|
+
- Updated to support priority filter in task queries
|
|
375
|
+
- No behavioral changes (force-spawn bypasses priority entirely, spawns all matching tasks)
|
|
376
|
+
|
|
377
|
+
### Tests
|
|
378
|
+
|
|
379
|
+
**Test coverage**:
|
|
380
|
+
- 76 vitest tests (MCP servers) + 113 node:test tests (hooks) = 189 total tests
|
|
381
|
+
- All tests passing
|
|
382
|
+
- TypeScript build clean
|
|
383
|
+
- Coverage includes priority field validation, schema migration, urgent dispatcher logic
|
|
384
|
+
|
|
385
|
+
### Files Modified
|
|
386
|
+
|
|
387
|
+
**10 files across 3 areas**:
|
|
388
|
+
- MCP server: `shared/constants.ts`, `todo-db/types.ts`, `todo-db/server.ts`, `__testUtils__/schemas.ts`
|
|
389
|
+
- Hooks: `hourly-automation.js`
|
|
390
|
+
- Scripts: `force-spawn-tasks.js`
|
|
391
|
+
- Tests: `todo-db.test.ts`, `hourly-automation.test.js`
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## 2026-02-21 - Health Data Freshness Gate + Monitor Actuation Mode
|
|
396
|
+
|
|
397
|
+
### Added
|
|
398
|
+
|
|
399
|
+
**Health data freshness gate** (`.claude/hooks/key-sync.js`):
|
|
400
|
+
- New `HEALTH_DATA_MAX_AGE_MS` export (15 minutes) - usage data older than this is treated as unknown
|
|
401
|
+
- `selectActiveKey()` now nulls out usage data when `last_health_check` is older than 15 minutes
|
|
402
|
+
- Effect: prevents uninformed key switches when health data is stale
|
|
403
|
+
- Stale keys pass "usable" filter (not proven exhausted) but are excluded from comparison logic
|
|
404
|
+
- System stays put with current key rather than making blind decisions on outdated data
|
|
405
|
+
|
|
406
|
+
**Monitor actuation mode** (`scripts/monitor-token-swap.mjs`):
|
|
407
|
+
- New `--act` CLI flag enables actuation mode (default remains observation-only)
|
|
408
|
+
- DESYNC auto-fix: after 3 consecutive polls (~90s) with Keychain-vs-active desync, writes active key to Keychain automatically
|
|
409
|
+
- Actuation rotation: when `--act` enabled and active key >=90% usage, rotates to lower-usage alternative on different account with 5-min cooldown
|
|
410
|
+
- Stale-data health refresh (ALWAYS ON): deep checks now write fresh `last_health_check` and `last_usage` back to rotation state for ALL keys
|
|
411
|
+
- Email propagation: usage data propagates to all keys sharing same `account_email`
|
|
412
|
+
- New alert counters: `ACT_ROTATION`, `ACT_DESYNC_FIX`
|
|
413
|
+
|
|
414
|
+
**Test coverage** (`.claude/hooks/__tests__/health-data-freshness-gate.test.js`):
|
|
415
|
+
- 25 new tests covering `HEALTH_DATA_MAX_AGE_MS` constant and freshness gate behavior
|
|
416
|
+
- Code structure validation (8 tests): export check, value check, comment check, freshness loop placement
|
|
417
|
+
- Behavioral logic (9 tests): staleness detection, null-out logic, filter effects, comparison exclusion
|
|
418
|
+
- Integration scenarios (8 tests): no-switch with stale data, exhausted-current fallback to stale
|
|
419
|
+
|
|
420
|
+
### Changed
|
|
421
|
+
|
|
422
|
+
**Global hooks configuration** (`~/.claude/settings.json`):
|
|
423
|
+
- Added PostToolUse hook: `quota-monitor.js` with absolute path, timeout 10s (fires for ALL projects)
|
|
424
|
+
- Added Stop hook: `stop-continue-hook.js` with absolute path, timeout 5s (fires for ALL projects)
|
|
425
|
+
- Ensures quota monitoring works even in projects without their own hooks
|
|
426
|
+
|
|
427
|
+
### Fixed
|
|
428
|
+
|
|
429
|
+
**Usage optimizer maxKey computation** (`.claude/hooks/usage-optimizer.js`):
|
|
430
|
+
- Moved `maxKey5h`/`maxKey7d` computation to after exhausted key filtering
|
|
431
|
+
- Prevents exhausted keys from biasing effectiveUsage upward
|
|
432
|
+
|
|
433
|
+
### Tests
|
|
434
|
+
|
|
435
|
+
**Test results**:
|
|
436
|
+
- All 25 new freshness gate tests pass
|
|
437
|
+
- All existing key-sync tests pass (deduplication, expired-filter, proactive-refresh)
|
|
438
|
+
- All quota-monitor adaptive tests pass
|
|
439
|
+
- Code review verified all critical logic (freshness gate, actuation rotation, DESYNC fix, email propagation)
|
|
440
|
+
|
|
441
|
+
### Documentation
|
|
442
|
+
|
|
443
|
+
**Updated files**:
|
|
444
|
+
- `CLAUDE.md` - Added freshness gate documentation to Key Sync Module section
|
|
445
|
+
- `docs/CHANGELOG.md` - This entry
|
|
446
|
+
|
|
447
|
+
**Files modified (8 total)**:
|
|
448
|
+
- `.claude/hooks/key-sync.js` - Added `HEALTH_DATA_MAX_AGE_MS` constant + freshness gate in `selectActiveKey()`
|
|
449
|
+
- `scripts/monitor-token-swap.mjs` - Added `--act` actuation mode + DESYNC auto-fix + health refresh
|
|
450
|
+
- `~/.claude/settings.json` - Added global PostToolUse and Stop hooks
|
|
451
|
+
- `.claude/hooks/__tests__/health-data-freshness-gate.test.js` - New test suite (25 tests)
|
|
452
|
+
- `.claude/hooks/usage-optimizer.js` - Fixed maxKey computation timing
|
|
453
|
+
- `.claude/hooks/__tests__/usage-optimizer.test.js` - Updated tests
|
|
454
|
+
- `.claude/hooks/hourly-automation.js` - Updated tests
|
|
455
|
+
- `.claude/hooks/__tests__/hourly-automation.test.js` - Updated tests
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
## 2026-02-21 - Fix GENTYR Monitoring Gaps: Step 8 Violation Fixes
|
|
460
|
+
|
|
461
|
+
### Fixed
|
|
462
|
+
|
|
463
|
+
**3 security violations in hourly-automation hook** (`.claude/hooks/hourly-automation.js`):
|
|
464
|
+
|
|
465
|
+
1. **VIOLATION 1: Missing schema validation in readPersistentAlerts**
|
|
466
|
+
- Risk: Malformed persistent-alerts.json could cause type confusion or runtime errors
|
|
467
|
+
- Fix: Added comprehensive validation for top-level structure (`typeof`, null checks, `Array.isArray`)
|
|
468
|
+
- Fix: Alert entries missing required `severity` (string) or `resolved` (boolean) fields are now dropped
|
|
469
|
+
- Impact: Prevents injection or corruption attacks via malformed alert files
|
|
470
|
+
|
|
471
|
+
2. **VIOLATION 2: Missing API response validation in checkCiStatus**
|
|
472
|
+
- Risk: Unexpected GitHub API responses could cause null pointer exceptions
|
|
473
|
+
- Fix: Added `Array.isArray(runs)` validation before accessing runs array
|
|
474
|
+
- Fix: Added `typeof latestRun.conclusion !== 'string'` validation before comparing conclusion
|
|
475
|
+
- Impact: Graceful degradation when GitHub API returns unexpected data
|
|
476
|
+
|
|
477
|
+
3. **VIOLATION 3: Prompt injection risk in spawnAlertEscalation**
|
|
478
|
+
- Risk: Alert fields containing backticks, template literals, or newlines could inject arbitrary commands into agent prompt
|
|
479
|
+
- Fix: Created `sanitizeAlertField()` function (strips backticks, newlines, `${` syntax, truncates to 200 chars)
|
|
480
|
+
- Fix: Applied sanitization to ALL alert fields before prompt interpolation: title, key, severity, source, first_detected_at
|
|
481
|
+
- Fix: Moved sanitization before `registerSpawn` call to protect the description field
|
|
482
|
+
- Fix: Added `Number.isFinite` safety check on age calculation
|
|
483
|
+
- Impact: Prevents malicious alert data from executing arbitrary code in agent context
|
|
484
|
+
|
|
485
|
+
### Added
|
|
486
|
+
|
|
487
|
+
**Test coverage** (`.claude/hooks/__tests__/hourly-automation.test.js`):
|
|
488
|
+
- 4 structural tests for VIOLATION 1 (schema validation)
|
|
489
|
+
- 3 structural tests for VIOLATION 2 (CI API response validation)
|
|
490
|
+
- 8 structural tests for VIOLATION 3 (sanitization placement)
|
|
491
|
+
- 14 behavioral tests for `sanitizeAlertField` function
|
|
492
|
+
- 15 behavioral tests for `readPersistentAlerts` with file I/O
|
|
493
|
+
- Total: 44 new tests added
|
|
494
|
+
|
|
495
|
+
### Tests
|
|
496
|
+
|
|
497
|
+
**Test results**:
|
|
498
|
+
- All 102 hourly-automation tests pass (58 existing + 44 new)
|
|
499
|
+
- All 202 usage-optimizer tests pass
|
|
500
|
+
- Code review: All violations addressed, 2 follow-up fixes applied (sanitize in registerSpawn, safe age calculation)
|
|
501
|
+
|
|
502
|
+
### Context
|
|
503
|
+
|
|
504
|
+
This completes Step 8 (final step) of the "Fix GENTYR Monitoring Gaps" plan. GAPs 1-7 were implemented in a prior session. All monitoring gap fixes are now complete.
|
|
505
|
+
|
|
506
|
+
**Files modified (2 total)**:
|
|
507
|
+
- `.claude/hooks/hourly-automation.js` - 3 violation fixes + 2 follow-up improvements
|
|
508
|
+
- `.claude/hooks/__tests__/hourly-automation.test.js` - 44 new tests
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## 2026-02-21 - Usage Optimizer: 7 Cascading Bug Fixes + Trajectory Alignment
|
|
513
|
+
|
|
514
|
+
### Fixed
|
|
515
|
+
|
|
516
|
+
**7 interconnected bugs causing permanent over-throttling** (factor stuck at 0.099, automation +913% slower):
|
|
517
|
+
|
|
518
|
+
1. **Bug 1: Reset time selection picks last, not earliest** (`.claude/hooks/usage-optimizer.js`)
|
|
519
|
+
- When multiple keys have different reset times, the optimizer must use the earliest reset time to be conservative
|
|
520
|
+
- Previous: Used arbitrary last key's reset time (could be far in future)
|
|
521
|
+
- Fix: Changed `resetAt5h = k['5h_reset']` to `resetAt5h = k['5h_reset'] < resetAt5h`
|
|
522
|
+
|
|
523
|
+
2. **Bug 2: Exhausted accounts (7d >= 99.5%) pollute aggregate + EMA rate** (`.claude/hooks/usage-optimizer.js`)
|
|
524
|
+
- Exhausted keys should be filtered from both aggregate averaging AND trajectory rate calculation
|
|
525
|
+
- Previous: Filtered from aggregate but still included in EMA rate calculation
|
|
526
|
+
- Fix: Added `exhaustedKeyIds` Set, filter from both `calculateAggregate()` and `calculateTrajectory()`
|
|
527
|
+
|
|
528
|
+
3. **Bug 3: No tiered factor recovery from extreme throttling** (`.claude/hooks/usage-optimizer.js`)
|
|
529
|
+
- When factor hits MIN_FACTOR (0.05), 10% MAX_CHANGE_PER_CYCLE limit prevents recovery
|
|
530
|
+
- Fix: Two-tier recovery system:
|
|
531
|
+
- Tier 1 (hard reset): When factor <= 0.15 AND current usage < 63%, reset factor to 1.0 immediately
|
|
532
|
+
- Tier 2 (gradual boost): When factor < 0.5 AND current usage < target, apply 1.5x boost per cycle
|
|
533
|
+
|
|
534
|
+
4. **Bug 4: No per-key reset boundary detection** (`.claude/hooks/usage-optimizer.js`)
|
|
535
|
+
- Reset detection only looked at aggregate utilization drop, missing individual key resets
|
|
536
|
+
- Fix: Added PER_KEY_RESET_DROP_THRESHOLD (50pp) check — if ANY key's 5h drops >50pp between snapshots, reset factor to 1.0
|
|
537
|
+
|
|
538
|
+
5. **Bug 5: Key-count discontinuity causes spurious rate spikes** (`.claude/hooks/usage-optimizer.js`)
|
|
539
|
+
- When number of active keys changes between snapshots, rate calculation becomes invalid
|
|
540
|
+
- Fix: Added key-count validation — reject snapshot pairs where key counts differ
|
|
541
|
+
|
|
542
|
+
6. **Bug 6: Trajectory.ts not aligned with optimizer** (`packages/cto-dashboard/src/utils/trajectory.ts`)
|
|
543
|
+
- Dashboard trajectory calculation didn't filter exhausted accounts (inconsistent with optimizer)
|
|
544
|
+
- Fix: Added same exhausted account filtering (7d >= 0.995) to `getQuotaTrajectory()`
|
|
545
|
+
|
|
546
|
+
7. **Bug 7: maxKey computed from all keys including exhausted** (`.claude/hooks/usage-optimizer.js`)
|
|
547
|
+
- When computing effectiveUsage (max of average vs. maxKey), exhausted keys biased maxKey upward
|
|
548
|
+
- Fix: Moved maxKey5h/maxKey7d computation to after active key filtering
|
|
549
|
+
|
|
550
|
+
### Added
|
|
551
|
+
|
|
552
|
+
**Utility function** (`.claude/hooks/usage-optimizer.js`):
|
|
553
|
+
- `resetOptimizer()` export for manual cleanup after polluted data (clears snapshots, resets factor to 1.0)
|
|
554
|
+
|
|
555
|
+
**Test coverage** (`.claude/hooks/__tests__/usage-optimizer.test.js`):
|
|
556
|
+
- 13 new tests covering reset time selection, exhausted account filtering, tier-1/tier-2 recovery, per-key reset detection, key-count validation
|
|
557
|
+
- 3 new trajectory tests for exhausted account filtering (`packages/cto-dashboard/src/utils/__tests__/trajectory.test.ts`)
|
|
558
|
+
|
|
559
|
+
### Tests
|
|
560
|
+
|
|
561
|
+
**Test results**:
|
|
562
|
+
- All 202 usage-optimizer tests pass (189 existing + 13 new)
|
|
563
|
+
- All 23 trajectory tests pass (20 existing + 3 new)
|
|
564
|
+
- All 25 cto-report tests pass
|
|
565
|
+
- Code review: 1 minor concern addressed (maxKey bug fix added as Bug 7)
|
|
566
|
+
|
|
567
|
+
### Impact
|
|
568
|
+
|
|
569
|
+
**Before fixes**: Factor stuck at 0.099 (MIN_FACTOR), all automation throttled to +913% slower (essentially paused)
|
|
570
|
+
|
|
571
|
+
**After fixes**: Factor can reset to 1.0 on usage drop or key reset, tier-1 recovery provides immediate escape from extreme throttling, tier-2 recovery prevents gradual descent back to MIN_FACTOR
|
|
572
|
+
|
|
573
|
+
**Post-deploy action required**: Call `resetOptimizer()` on target project to clear polluted usage-snapshots.json and reset factor from 0.099 to 1.0
|
|
574
|
+
|
|
575
|
+
**Files modified (5 total)**:
|
|
576
|
+
- `.claude/hooks/usage-optimizer.js` - 7 bug fixes + resetOptimizer() export
|
|
577
|
+
- `packages/cto-dashboard/src/utils/trajectory.ts` - Exhausted account filtering alignment
|
|
578
|
+
- `.claude/hooks/__tests__/usage-optimizer.test.js` - 13 new tests
|
|
579
|
+
- `packages/cto-dashboard/src/utils/__tests__/trajectory.test.ts` - 3 new tests
|
|
580
|
+
- `.claude/hooks/hourly-automation.js` - Updated tests (not functionality)
|
|
581
|
+
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
## 2026-02-21 - Product Manager Agent & PMF Analysis System
|
|
585
|
+
|
|
586
|
+
### Added
|
|
587
|
+
|
|
588
|
+
**Product Manager MCP Server** (2 files):
|
|
589
|
+
- `packages/mcp-servers/src/product-manager/server.ts` - 13 MCP tools with SQLite DB, sequential section lock, markdown auto-generation
|
|
590
|
+
- `packages/mcp-servers/src/product-manager/types.ts` - Zod schemas for 6 analysis sections (market_space, buyer_personas, competitor_differentiation, pricing_models, niche_strengths, user_sentiment)
|
|
591
|
+
|
|
592
|
+
**Agent & Command Integration** (2 files):
|
|
593
|
+
- `.claude/agents/product-manager.md` - Opus model agent with read-only codebase access, WebSearch/WebFetch for research
|
|
594
|
+
- `.claude/commands/product-manager.md` - `/product-manager` slash command with status display and workflow options
|
|
595
|
+
|
|
596
|
+
**Dashboard Integration** (3 files):
|
|
597
|
+
- `packages/cto-dashboard/src/utils/product-manager-reader.ts` - Data reader for PMF analysis state
|
|
598
|
+
- `packages/cto-dashboard/src/components/ProductManagerSection.tsx` - Ink/React dashboard component
|
|
599
|
+
- Modified: `packages/cto-dashboard/src/App.tsx`, `index.tsx`, `components/index.ts`, `mock-data.ts`
|
|
600
|
+
|
|
601
|
+
**System Integration** (4 files):
|
|
602
|
+
- `packages/mcp-servers/src/shared/constants.ts` - Added PRODUCT-MANAGER to VALID_SECTIONS
|
|
603
|
+
- `packages/mcp-servers/src/todo-db/server.ts` - CHECK constraint + migration for PRODUCT-MANAGER section
|
|
604
|
+
- `.claude/hooks/agent-tracker.js` - New agent type registration
|
|
605
|
+
- `.claude/hooks/hourly-automation.js` - SECTION_AGENT_MAP entry
|
|
606
|
+
- `.claude/hooks/slash-command-prefetch.js` - Prefetch handler
|
|
607
|
+
|
|
608
|
+
**User Feedback Access Control** (2 files):
|
|
609
|
+
- `packages/mcp-servers/src/user-feedback/server.ts` - cto_protected migration + CTO-only access control for deletePersona
|
|
610
|
+
- `packages/mcp-servers/src/user-feedback/types.ts` - cto_protected + caller fields added to persona schema
|
|
611
|
+
|
|
612
|
+
**MCP Tools** (13 tools):
|
|
613
|
+
- `initiate_analysis` - Start PMF analysis (creates pending_approval state)
|
|
614
|
+
- `approve_analysis` - CTO approval to proceed
|
|
615
|
+
- `get_analysis_status` - Check overall progress
|
|
616
|
+
- `read_section` - Read content with prior context cascading
|
|
617
|
+
- `write_section` - Write single-content sections (1, 3, 4, 5)
|
|
618
|
+
- `add_entry` - Add list entries (sections 2, 6)
|
|
619
|
+
- `list_pain_points` - Query user_sentiment entries
|
|
620
|
+
- `map_pain_point_persona` - Link pain points to user-feedback personas
|
|
621
|
+
- `clear_and_respawn` - Wipe and rebuild analysis via task chain
|
|
622
|
+
- `get_compliance_report` - Persona mapping coverage stats
|
|
623
|
+
- `regenerate_md` - Export to `pmf-analysis.md`
|
|
624
|
+
- `delete_analysis` - Reset state
|
|
625
|
+
- `update_analysis_metadata` - Update timestamps and metadata
|
|
626
|
+
|
|
627
|
+
**Analysis Workflow**:
|
|
628
|
+
1. User/deputy-CTO calls `initiate_analysis` → state: pending_approval
|
|
629
|
+
2. Deputy-CTO approves → state: approved
|
|
630
|
+
3. Hourly automation spawns PRODUCT-MANAGER agent tasks for each section (sequential)
|
|
631
|
+
4. Agent researches via WebSearch/WebFetch, reads codebase, writes sections
|
|
632
|
+
5. After Section 6 completes, persona evaluation task maps pain points to user-feedback personas
|
|
633
|
+
6. `regenerate_md` exports full analysis to markdown
|
|
634
|
+
|
|
635
|
+
**Sequential Lock**:
|
|
636
|
+
- Each section requires all prior sections to be populated before writing
|
|
637
|
+
- Context cascading: `read_section` returns all previous sections as context
|
|
638
|
+
- Prevents fragmented or out-of-order analysis
|
|
639
|
+
|
|
640
|
+
### Tests
|
|
641
|
+
|
|
642
|
+
**New test files** (4 files):
|
|
643
|
+
- `packages/mcp-servers/src/product-manager/__tests__/product-manager.test.ts` - 32 tests covering all 13 MCP tools, state machine, sequential lock, persona mapping
|
|
644
|
+
- `.claude/hooks/__tests__/agent-tracker-product-manager.test.js` - 11 tests for agent type registration
|
|
645
|
+
- `.claude/hooks/__tests__/hourly-automation-product-manager.test.js` - 14 tests for task spawning
|
|
646
|
+
- `.claude/hooks/__tests__/slash-command-prefetch-product-manager.test.js` - 30 tests for command prefetch handler
|
|
647
|
+
|
|
648
|
+
**Test results**:
|
|
649
|
+
- All 1092 mcp-servers tests pass
|
|
650
|
+
- All 55 hook tests pass
|
|
651
|
+
- Clean TypeScript build for both packages/mcp-servers and packages/cto-dashboard
|
|
652
|
+
- Mock dashboard renders ProductManagerSection correctly
|
|
653
|
+
|
|
654
|
+
### Fixed
|
|
655
|
+
|
|
656
|
+
**Critical security/compliance issues** (identified during code review):
|
|
657
|
+
1. `deletePersona` missing CTO-protected access control - FIXED (requires deputy-CTO caller)
|
|
658
|
+
2. PRODUCT-MANAGER missing from spawn-tasks pending query - FIXED (added to slash-command-prefetch.js)
|
|
659
|
+
3. AddEntryArgsSchema.section not constrained to valid values (2, 6) - FIXED (Zod enum)
|
|
660
|
+
4. `clearAndRespawn` opens todo.db without WAL pragma - FIXED (added pragma)
|
|
661
|
+
5. `mapPainPointPersona` silently continues on persona verification failure - FIXED (throws error)
|
|
662
|
+
6. metadata field not validated as JSON - FIXED (Zod z.record)
|
|
663
|
+
|
|
664
|
+
### Impact
|
|
665
|
+
|
|
666
|
+
This session delivered the 11th agent (PRODUCT-MANAGER) and a complete PMF analysis system:
|
|
667
|
+
1. **Market research automation**: Agent uses WebSearch/WebFetch for competitive intelligence
|
|
668
|
+
2. **Codebase analysis**: Read-only access to understand product features
|
|
669
|
+
3. **Sequential workflow**: 6 sections populate in order with context cascading
|
|
670
|
+
4. **Persona integration**: Pain points map to user-feedback personas for automated testing
|
|
671
|
+
5. **CTO oversight**: Analysis requires approval before starting
|
|
672
|
+
6. **Dashboard visibility**: CTO sees PMF progress in main dashboard
|
|
673
|
+
|
|
674
|
+
All changes backward-compatible. New agent joins existing 10-agent ecosystem. Full integration with task runner, deputy-CTO triage, and hourly automation.
|
|
675
|
+
|
|
676
|
+
## 2026-02-21 - Dashboard Sections as Agent-Facing MCP Tools & Slash Commands
|
|
677
|
+
|
|
678
|
+
### Added
|
|
679
|
+
|
|
680
|
+
**Show MCP Server** (3 files):
|
|
681
|
+
- `packages/mcp-servers/src/show/types.ts` - Zod schemas and constants for 12 dashboard sections (`QUOTA`, `ACCOUNTS`, `DEPUTY_CTO`, `USAGE`, `AUTOMATIONS`, `TESTING`, `DEPLOYMENTS`, `WORKTREES`, `INFRA`, `LOGGING`, `TIMELINE`, `TASKS`)
|
|
682
|
+
- `packages/mcp-servers/src/show/server.ts` - 12 MCP tools generated from data-driven loop: `show_quota`, `show_accounts`, `show_deputy_cto`, etc. Each tool spawns the dashboard binary with `--section <name>` and optional `--limit <N>` flags
|
|
683
|
+
- `.mcp.json.template` - Registered `show` MCP server entry
|
|
684
|
+
|
|
685
|
+
**Slash Command Integration** (2 files):
|
|
686
|
+
- `.claude/commands/show.md` - New `/show` slash command reference page listing all 12 section tools with descriptions and usage examples
|
|
687
|
+
- `.claude/hooks/slash-command-prefetch.js` - Added `show` sentinel and lightweight `handleShow()` handler for instant command reference
|
|
688
|
+
|
|
689
|
+
**Dashboard CLI Enhancement** (1 file):
|
|
690
|
+
- `packages/cto-dashboard/src/index.tsx` - Added `--section <name>` and `--limit <N>` CLI flags with `renderSection()` function that renders individual dashboard sections. Includes exhaustiveness check, invalid section warning, and support for all 12 sections.
|
|
691
|
+
|
|
692
|
+
**Agent Guidance** (2 files):
|
|
693
|
+
- `CLAUDE.md.gentyr-section` - Added "Status Displays" section encouraging agents to use `mcp__show__*` tools before token-heavy operations, deployments, test runs, etc. Added `/show` to slash commands list.
|
|
694
|
+
- `.claude/agents/deputy-cto.md` - Added `mcp__show__*` to `allowedTools` and brief "Status Displays" usage guidance
|
|
695
|
+
|
|
696
|
+
**Use cases**:
|
|
697
|
+
- `mcp__show__show_quota()` before token-heavy operations
|
|
698
|
+
- `mcp__show__show_testing()` before writing or running tests
|
|
699
|
+
- `mcp__show__show_deployments()` before triggering deploys
|
|
700
|
+
- `mcp__show__show_tasks()` before creating tasks
|
|
701
|
+
- `mcp__show__show_worktrees()` before provisioning worktrees
|
|
702
|
+
- `mcp__show__show_automations()` before spawning agents
|
|
703
|
+
|
|
704
|
+
**Architecture**:
|
|
705
|
+
- Tools use `execFileSync` to spawn the dashboard binary (prevents shell injection)
|
|
706
|
+
- Pass `{ limit: N }` to expand the number of rows shown
|
|
707
|
+
- Renders rich terminal displays (Ink-based React components)
|
|
708
|
+
- Works with both `--mock` (development) and live MCP connections
|
|
709
|
+
|
|
710
|
+
### Tests
|
|
711
|
+
|
|
712
|
+
**Test results**:
|
|
713
|
+
- All 760 cto-dashboard tests pass
|
|
714
|
+
- All 1060 mcp-servers tests pass
|
|
715
|
+
- Both packages build cleanly
|
|
716
|
+
- All 12 sections verified working with `--mock` flag
|
|
717
|
+
|
|
718
|
+
### Documentation
|
|
719
|
+
|
|
720
|
+
**Updated documentation** (1 file):
|
|
721
|
+
- `CLAUDE.md.gentyr-section` - Added comprehensive "Status Displays" section with usage guidance and tool listings
|
|
722
|
+
|
|
723
|
+
### Impact
|
|
724
|
+
|
|
725
|
+
This session delivered agent-facing status displays:
|
|
726
|
+
1. **12 MCP tools**: Agents can now check individual dashboard sections on-demand without viewing the full CTO report
|
|
727
|
+
2. **Contextual usage**: Tools support passing `{ limit: N }` for expanded views
|
|
728
|
+
3. **Slash command**: `/show` provides quick reference for all available section tools
|
|
729
|
+
4. **Integration**: Works with both mock data (development) and live MCP connections (production)
|
|
730
|
+
|
|
731
|
+
All changes backward-compatible. Full dashboard (`/cto-report`) still available. New tools provide granular, on-demand access to specific metrics.
|
|
732
|
+
|
|
733
|
+
## 2026-02-21 - CTO Dashboard: Hotfix Pathway, Deployments Upgrade, Worktree Visualization
|
|
734
|
+
|
|
735
|
+
### Added
|
|
736
|
+
|
|
737
|
+
**CTO Emergency Hotfix Pathway** (4 files):
|
|
738
|
+
- `packages/mcp-servers/src/deputy-cto/types.ts` - Zod schemas for `RequestHotfixPromotionArgs`, `ExecuteHotfixPromotionArgs`, `HotfixRequest`
|
|
739
|
+
- `packages/mcp-servers/src/deputy-cto/server.ts` - `request_hotfix_promotion` and `execute_hotfix_promotion` MCP tools, `hotfix_requests` DB table
|
|
740
|
+
- `.claude/hooks/bypass-approval-hook.js` - APPROVE HOTFIX pattern matching, 6-char code validation, HMAC token writing to `hotfix-approval-token.json`
|
|
741
|
+
- `.claude/commands/hotfix.md` - New `/hotfix` slash command with CTO approval workflow
|
|
742
|
+
|
|
743
|
+
**Hotfix workflow**:
|
|
744
|
+
1. Agent calls `request_hotfix_promotion` → validates staging has unreleased commits → returns 6-char approval code
|
|
745
|
+
2. Agent presents code to user: `APPROVE HOTFIX <code>`
|
|
746
|
+
3. User types approval → bypass-approval-hook writes HMAC token (5-minute expiry)
|
|
747
|
+
4. Agent calls `execute_hotfix_promotion` with code → validates token → spawns staging→main promotion immediately (bypasses 24h stability window + midnight gate)
|
|
748
|
+
|
|
749
|
+
**DEPLOYMENTS Section Upgrade** (3 files):
|
|
750
|
+
- `packages/cto-dashboard/src/utils/deployments-reader.ts` - Added `localDevCount` (counts active worktrees), `stagingFreezeActive` (boolean flag) to pipeline data
|
|
751
|
+
- `packages/cto-dashboard/src/components/DeploymentsSection.tsx` - 4-column EnvironmentHealth (added Local Dev), PipelineDetail shows worktree count + freeze snowflake (❄)
|
|
752
|
+
- `packages/cto-dashboard/src/mock-data.ts` - Added preview deploys, `localDevCount`, `stagingFreezeActive`, `getMockWorktrees()` for realistic rendering
|
|
753
|
+
|
|
754
|
+
**Pipeline visualization**:
|
|
755
|
+
```
|
|
756
|
+
local dev (3) → preview ✓ → staging ✓ ❄ → production (24h gate) Last: 5h ago
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
**WORKTREES Section** (2 new files, 3 modified):
|
|
760
|
+
- `packages/cto-dashboard/src/utils/worktree-reader.ts` - Reads git worktree state, agent tracker DB, maps to pipeline stages
|
|
761
|
+
- `packages/cto-dashboard/src/components/WorktreeSection.tsx` - Full visualization: summary cards, worktree table (branch, agent, stage, stale flag, files), cleanup hints
|
|
762
|
+
- `packages/cto-dashboard/src/components/index.ts` - Added WorktreeSection export
|
|
763
|
+
- `packages/cto-dashboard/src/App.tsx` - Added worktrees prop, WorktreeSection rendering
|
|
764
|
+
- `packages/cto-dashboard/src/index.tsx` - Wired worktree data loading (mock + live paths)
|
|
765
|
+
|
|
766
|
+
**Worktree details displayed**:
|
|
767
|
+
- Branch name, agent ID, pipeline stage, creation time, modified files count
|
|
768
|
+
- Stale indicator for worktrees >3 days old
|
|
769
|
+
- Cleanup hints for merged branches
|
|
770
|
+
|
|
771
|
+
### Fixed
|
|
772
|
+
|
|
773
|
+
**Critical deputy-cto tool registration bug** (1 file):
|
|
774
|
+
- `packages/mcp-servers/src/deputy-cto/server.ts` - `request_hotfix_promotion` and `execute_hotfix_promotion` were defined as tool handlers but never added to the `tools` array
|
|
775
|
+
- Result: Tools were invisible to MCP clients (would have failed at runtime)
|
|
776
|
+
- Fix: Added both tools to the array before passing to `McpServer` constructor
|
|
777
|
+
|
|
778
|
+
### Tests
|
|
779
|
+
|
|
780
|
+
**New test files** (1 file):
|
|
781
|
+
- `.claude/hooks/__tests__/bypass-approval-hotfix.test.js` - 8 unit tests for APPROVE HOTFIX pattern matching, HMAC token generation, expiry, invalid code rejection
|
|
782
|
+
|
|
783
|
+
**Updated test files** (3 files):
|
|
784
|
+
- `packages/cto-dashboard/src/utils/__tests__/account-overview-reader.test.ts` - Added tests for worktree integration (schema changes)
|
|
785
|
+
- `packages/mcp-servers/src/deputy-cto/__tests__/deputy-cto.test.ts` - Tests for hotfix promotion tools (validation, DB writes, approval flow)
|
|
786
|
+
- Mock data validation tests for deployments-reader and worktree-reader
|
|
787
|
+
|
|
788
|
+
**Test results**:
|
|
789
|
+
- TypeScript build clean for both `cto-dashboard` and `mcp-servers`
|
|
790
|
+
- All existing tests pass
|
|
791
|
+
- Mock mode dashboard renders all 3 new features correctly
|
|
792
|
+
|
|
793
|
+
### Documentation
|
|
794
|
+
|
|
795
|
+
**Updated documentation** (2 files):
|
|
796
|
+
- `README.md` - Regenerated via `generate-readme.js` with new dashboard sections visible
|
|
797
|
+
- `docs/DEPLOYMENT-FLOW.md` - Added "Emergency Hotfix Pathway" section with workflow, prerequisites, safety measures; added `APPROVE HOTFIX` to CTO approval gates table
|
|
798
|
+
|
|
799
|
+
### Impact
|
|
800
|
+
|
|
801
|
+
This session delivered 3 major CTO dashboard enhancements:
|
|
802
|
+
1. **Emergency hotfix pathway**: CTO can approve immediate staging→main promotion when production is broken (bypasses 24h + midnight gates)
|
|
803
|
+
2. **Deployments visibility**: Pipeline now shows local dev worktrees and staging freeze status at a glance
|
|
804
|
+
3. **Worktree tracking**: CTO sees all active feature branches, agent assignments, stale work, and cleanup hints
|
|
805
|
+
|
|
806
|
+
All changes isolated to dashboard + deputy-CTO MCP server. No changes to core automation or promotion logic.
|
|
807
|
+
|
|
808
|
+
## 2026-02-21 - Chrome Bridge: Contextual Browser Automation Tips
|
|
809
|
+
|
|
810
|
+
### Added
|
|
811
|
+
|
|
812
|
+
**Contextual browser automation tips** (3 files):
|
|
813
|
+
- `packages/mcp-servers/src/chrome-bridge/browser-tips.ts` - BrowserTip interface, BrowserTipTracker class with session-scoped deduplication
|
|
814
|
+
- 14 contextual tips (5 general + 9 site-specific) sourced from docs/SETUP-GUIDE.md
|
|
815
|
+
- Tips are injected into chrome-bridge tool responses based on hostname and tool usage
|
|
816
|
+
- Each tip shown at most once per Claude Code session (MCP server lifetime)
|
|
817
|
+
- Domain boundary hostname matching (github.com matches *.github.com)
|
|
818
|
+
- Only shown on interactive tools: `navigate`, `computer`, `form_input`, `find`, `read_page`
|
|
819
|
+
- `packages/mcp-servers/src/chrome-bridge/server.ts` - Import BrowserTipTracker, cache URLs on navigate, appendTips method called at both return paths in executeTool
|
|
820
|
+
- `packages/mcp-servers/src/chrome-bridge/index.ts` - Re-export browser-tips module
|
|
821
|
+
|
|
822
|
+
**Site-specific tips included**:
|
|
823
|
+
- GitHub: Form input preference for special characters in token names
|
|
824
|
+
- 1Password: Field creation workflow (chevron + button + form_input + save verification)
|
|
825
|
+
- Render: One-time API key capture with get_page_text
|
|
826
|
+
- Vercel: One-time token capture, Team ID extraction
|
|
827
|
+
- Cloudflare: Zone ID extraction, multi-step wizard navigation
|
|
828
|
+
- Supabase: Reveal button for service_role key, multi-value extraction
|
|
829
|
+
- Elastic Cloud: Dev Tools Console API key creation (REST command preferred over UI)
|
|
830
|
+
- Resend: One-time API key capture, permission dropdown selection
|
|
831
|
+
- Codecov: GitHub OAuth disruption, manual login fallback, token extraction
|
|
832
|
+
|
|
833
|
+
### Tests
|
|
834
|
+
|
|
835
|
+
**New test files** (2 files):
|
|
836
|
+
- `packages/mcp-servers/src/chrome-bridge/__tests__/browser-tips.test.ts` - 38 unit tests for BrowserTipTracker (hostname matching, deduplication, tool filtering)
|
|
837
|
+
- `packages/mcp-servers/src/chrome-bridge/__tests__/appendTips.test.ts` - 24 integration tests for appendTips method (error exclusion, URL caching, anti-spam)
|
|
838
|
+
|
|
839
|
+
**Test results**:
|
|
840
|
+
- 93 chrome-bridge tests pass (31 existing + 62 new)
|
|
841
|
+
- TypeScript compilation clean (pre-existing deputy-cto unused variable warnings unrelated)
|
|
842
|
+
|
|
843
|
+
### Fixed
|
|
844
|
+
|
|
845
|
+
**Browser automation quirks** (2 files):
|
|
846
|
+
- Hostname matching: Changed from `endsWith(h)` to `hostname === h || hostname.endsWith('.' + h)` for proper domain boundary matching (prevents "github.com" from matching "notgithub.com")
|
|
847
|
+
- Tip text: Fixed reference to `zoom` as standalone tool when it's actually a `computer` action
|
|
848
|
+
|
|
849
|
+
### Design
|
|
850
|
+
|
|
851
|
+
**Anti-spam measures**:
|
|
852
|
+
- 5 interactive tools gate: Only `navigate`, `computer`, `form_input`, `find`, `read_page` trigger tips
|
|
853
|
+
- Per-tip Set deduplication: Each tip ID tracked, shown once per session
|
|
854
|
+
- Error exclusion: Tips never appended to error responses
|
|
855
|
+
- Session-scoped tracker: Tips reset on MCP server restart (new Claude Code session)
|
|
856
|
+
|
|
857
|
+
### Why This Feature
|
|
858
|
+
|
|
859
|
+
**Problem**: Agents using chrome-bridge MCP struggled with site-specific UI quirks. Browser automation tips existed only in docs/SETUP-GUIDE.md and were never shown to agents during actual browser automation.
|
|
860
|
+
|
|
861
|
+
**Solution**: Tips are now injected into chrome-bridge tool responses based on the site being visited. Agents see relevant guidance at the moment they need it.
|
|
862
|
+
|
|
863
|
+
## 2026-02-21 - CTO Dashboard: Per-Account Quota Bars in Usage Trajectory
|
|
864
|
+
|
|
865
|
+
### Added
|
|
866
|
+
|
|
867
|
+
**Per-account quota visualization** (4 files):
|
|
868
|
+
- `packages/cto-dashboard/src/components/UsageTrajectory.tsx` - Added `AccountQuotaBars` component showing per-account quota usage for 5-hour and 7-day windows
|
|
869
|
+
- Email-based deduplication: Multiple keys with the same `account_email` are merged to show one bar per account
|
|
870
|
+
- Invalid account filtering: Accounts with `status: 'invalid'` are excluded from display
|
|
871
|
+
- Truncated email labels: Shows first 20 chars + "..." for long email addresses
|
|
872
|
+
- Active account indicator: "*" suffix marks the currently active account
|
|
873
|
+
- `packages/cto-dashboard/src/App.tsx` - Passes `verifiedQuota` and `accountOverview` props to `UsageTrajectory`
|
|
874
|
+
- `packages/cto-dashboard/src/mock-data.ts` - Updated mock data to 3 distinct accounts for realistic quota bar rendering
|
|
875
|
+
|
|
876
|
+
### Fixed
|
|
877
|
+
|
|
878
|
+
**Zod schema bug in account-overview-reader** (1 file):
|
|
879
|
+
- `packages/cto-dashboard/src/utils/account-overview-reader.ts` - Fixed critical schema parsing bug
|
|
880
|
+
- Root cause: Strict Zod schema expected `resets_at` as string, but actual data includes Date objects (from active keys) and ISO strings (from exhausted keys)
|
|
881
|
+
- Schema also expected `account_uuid` and `account_email` as required strings, but some keys have null values
|
|
882
|
+
- Result: Entire parse failed with `hasData: false`, causing quota bars to never render in production
|
|
883
|
+
- Fix: Changed `resets_at` to `z.unknown()`, `account_uuid` and `account_email` to `.nullable().optional()`
|
|
884
|
+
- This was the root cause preventing quota bars from showing in production (entire parse was failing)
|
|
885
|
+
|
|
886
|
+
### Tests
|
|
887
|
+
|
|
888
|
+
**New test files** (2 files):
|
|
889
|
+
- `packages/cto-dashboard/src/components/__tests__/UsageTrajectory.test.tsx` - Updated for new props, added 7 new tests for deduplication and filtering (36 tests total, up from 29)
|
|
890
|
+
- `packages/cto-dashboard/src/utils/__tests__/account-overview-reader.test.ts` - New comprehensive test suite with 38 tests covering schema parsing, sorting, events, edge cases (96% statement coverage)
|
|
891
|
+
|
|
892
|
+
**Test results**:
|
|
893
|
+
- 760 tests pass across 22 test files (up from 719 across 21)
|
|
894
|
+
- Build passes (TypeScript compiles)
|
|
895
|
+
- Mock dashboard renders correctly with 3 accounts
|
|
896
|
+
- Live dashboard renders correctly with 4 real accounts (filtered from 32 keys)
|
|
897
|
+
- `generate-readme.js` successfully regenerates README with quota bars visible
|
|
898
|
+
|
|
899
|
+
### Documentation
|
|
900
|
+
|
|
901
|
+
- README.md updated via `generate-readme.js` to show per-account quota bars in USAGE TRAJECTORY section
|
|
902
|
+
- Bars display format: `Total`, then individual accounts with usage percentages and progress bars
|
|
903
|
+
|
|
904
|
+
## 2026-02-21 - Merge Chain Enforcement: Local Guards, Worktrees, and Stale Work Detection
|
|
905
|
+
|
|
906
|
+
### Added
|
|
907
|
+
|
|
908
|
+
**Local branch protection guards** (2 files):
|
|
909
|
+
- Pre-commit guard blocks direct commits to `main`, `staging`, `preview` - enforcement in `.claude/hooks/pre-commit-review.js`
|
|
910
|
+
- Pre-push guard blocks direct pushes to protected branches - enforcement in `templates/config/husky/pre-push.template`
|
|
911
|
+
- Both guards are unbypassable (cannot be disabled with `--no-verify`)
|
|
912
|
+
- Exception: Promotion pipeline agents with `GENTYR_PROMOTION_PIPELINE=true` environment variable
|
|
913
|
+
- Provides immediate local feedback before attempting forbidden operations
|
|
914
|
+
|
|
915
|
+
**Git worktrees for concurrent agents** (2 files):
|
|
916
|
+
- `.claude/hooks/lib/worktree-manager.js` - Worktree lifecycle management (create, provision, cleanup)
|
|
917
|
+
- `.claude/hooks/lib/feature-branch-helper.js` - Branch naming and protection checks
|
|
918
|
+
- Enables multiple agents to work concurrently on separate feature branches without checkout conflicts
|
|
919
|
+
- Each agent gets isolated working directory at `.claude/worktrees/<branch-name>/`
|
|
920
|
+
- Worktree provisioning: symlinks to `.claude/agents/`, `.claude/hooks/`, `.husky/`, generates worktree-specific `.mcp.json`
|
|
921
|
+
- State isolation: SQLite databases remain in main project, shared via `CLAUDE_PROJECT_DIR`
|
|
922
|
+
- Automatic cleanup after branch merged to preview (6-hour cycle)
|
|
923
|
+
|
|
924
|
+
**Stale work detection** (1 file):
|
|
925
|
+
- `.claude/hooks/stale-work-detector.js` - Detects uncommitted changes, unpushed commits, and stale feature branches (3+ days)
|
|
926
|
+
- Runs every 24 hours via hourly automation
|
|
927
|
+
- Reports to deputy-CTO with category `git-hygiene`
|
|
928
|
+
- Surfaced in `/deputy-cto` briefing under "Merge Chain Status"
|
|
929
|
+
|
|
930
|
+
**Deputy-CTO merge chain integration** (2 files):
|
|
931
|
+
- `packages/mcp-servers/src/deputy-cto/server.ts` - Added `get_merge_chain_status` MCP tool
|
|
932
|
+
- `.claude/commands/deputy-cto.md` - Updated briefing to include merge chain status (commits ahead, active branches, stale branches)
|
|
933
|
+
- Provides structured view of feature branches, promotion pipeline status, and stale work
|
|
934
|
+
|
|
935
|
+
**Template files for setup.sh** (2 files):
|
|
936
|
+
- `CLAUDE.md.gentyr-section` - GENTYR framework instructions template (includes Team Spawning section)
|
|
937
|
+
- `CLAUDE.md.makerkit-section` - Makerkit integration instructions template
|
|
938
|
+
- Used by `scripts/setup.sh` to inject framework and integration docs into project CLAUDE.md files
|
|
939
|
+
|
|
940
|
+
### Changed
|
|
941
|
+
|
|
942
|
+
**Agent spawning uses worktrees** (3 files):
|
|
943
|
+
- `.claude/hooks/hourly-automation.js` - Task agent spawning now creates worktrees and uses `cwd: worktreePath`
|
|
944
|
+
- `.claude/agents/code-writer.md` - Added feature branch workflow section (git workflow, PR creation, merge completion)
|
|
945
|
+
- `.claude/agents/test-writer.md` - Added worktree awareness and feature branch context
|
|
946
|
+
|
|
947
|
+
**Gitignore template** (1 file):
|
|
948
|
+
- `templates/config/gitignore.template` - Added `.claude/worktrees/` to prevent worktree tracking
|
|
949
|
+
|
|
950
|
+
### Documentation
|
|
951
|
+
|
|
952
|
+
**DEPLOYMENT-FLOW.md** (1 file):
|
|
953
|
+
- Added "Local Branch Protection" section documenting pre-commit and pre-push guards
|
|
954
|
+
- Added "Git Worktrees for Concurrent Agents" section documenting worktree architecture
|
|
955
|
+
- Added "Stale Work Detection" section documenting detection categories and integration
|
|
956
|
+
- Updated "Feature Branch Workflow" section to mention automated branch creation
|
|
957
|
+
|
|
958
|
+
**Implementation plan** (1 file):
|
|
959
|
+
- Created `/Users/jonathantodd/.claude/plans/sequential-sprouting-map.md` - Complete 3-phase implementation plan
|
|
960
|
+
- Phase 1: Local branch guards (pre-commit + pre-push)
|
|
961
|
+
- Phase 2: Worktrees + feature branch auto-creation
|
|
962
|
+
- Phase 3: Stale work detection + deputy-CTO integration
|
|
963
|
+
|
|
964
|
+
### Impact
|
|
965
|
+
|
|
966
|
+
This implementation makes the merge chain airtight with local enforcement, enables concurrent agent workflows via worktrees, and provides CTO visibility into stale work. All enforcement happens before remote operations, providing immediate feedback and preventing forbidden merges at the earliest possible point.
|
|
967
|
+
|
|
968
|
+
## 2026-02-20 - Slash Command Detection Fix
|
|
969
|
+
|
|
970
|
+
### Fixed
|
|
971
|
+
|
|
972
|
+
**Slash commands not being recognized by UserPromptSubmit hooks** (2 files):
|
|
973
|
+
- Root cause: Hooks receive JSON stdin like `{"prompt":"/restart-session",...}` but were only checking for HTML sentinel markers that exist in expanded .md content
|
|
974
|
+
- Impact: All 10 GENTYR slash commands were non-functional
|
|
975
|
+
- Fix: Added `extractPrompt()` to parse JSON stdin and extract raw prompt field
|
|
976
|
+
- Fix: Added `matchesCommand()` to check both bare `/command-name` and sentinel markers
|
|
977
|
+
- Files changed:
|
|
978
|
+
- `.claude/hooks/slash-command-prefetch.js` - Added JSON parsing for command detection (lines 66-90)
|
|
979
|
+
- `.claude/hooks/cto-notification-hook.js` - Updated slash command suppression logic (lines 507-519)
|
|
980
|
+
|
|
981
|
+
### Tests
|
|
982
|
+
|
|
983
|
+
- **slash-command-detection**: 30/30 pass (new test file validates extractPrompt and matchesCommand)
|
|
984
|
+
- **cto-notification-hook**: 26/26 pass (8 new tests for slash command suppression)
|
|
985
|
+
|
|
986
|
+
## 2026-02-20 - Credential File Guard: Tiered Blocking with CTO Approval
|
|
987
|
+
|
|
988
|
+
### Added
|
|
989
|
+
|
|
990
|
+
**CTO-approvable file access for credential-file-guard** (8 files):
|
|
991
|
+
- Split blocked credential files into two protection tiers:
|
|
992
|
+
1. **Always-blocked** - protection-key, approval tokens, .env files - hard deny with no escape hatch
|
|
993
|
+
2. **Approvable** - services.json, .mcp.json, api-key-rotation.json, credential-provider.json, vault-mappings.json - deny with CTO approval code
|
|
994
|
+
- Approval flow via approval-utils.js: create HMAC-signed request → deputy-CTO generates one-time code → user types code → hook validates HMAC + expiry
|
|
995
|
+
- Files changed:
|
|
996
|
+
- `.claude/hooks/credential-file-guard.js` - Core tiered blocking logic with approval flow integration
|
|
997
|
+
- `.claude/hooks/protected-actions.json` - Added `files` section with 5 approvable file configs
|
|
998
|
+
- `.claude/hooks/protected-action-approval-hook.js` - Updated `getValidPhrases()` to include file phrases
|
|
999
|
+
- `.claude/hooks/lib/approval-utils.js` - Updated `createRequest` to add HMAC signature, argsHash, approval_mode
|
|
1000
|
+
- `packages/mcp-servers/src/deputy-cto/server.ts` - Fixed HMAC argsHash bug in `approveProtectedAction`, added `files` field to TypeScript interface
|
|
1001
|
+
|
|
1002
|
+
### Fixed
|
|
1003
|
+
|
|
1004
|
+
**Deputy-CTO HMAC argsHash bug**:
|
|
1005
|
+
- `approveProtectedAction` was missing `argsHash` in HMAC computation (both verify and sign paths)
|
|
1006
|
+
- Would cause "FORGERY DETECTED" errors for gate-originated approval requests
|
|
1007
|
+
- Fixed by adding `argsHash` to `computeHmac(phrase, action, argsHash)` calls in verify and sign paths
|
|
1008
|
+
- Added 7 new test cases in `packages/mcp-servers/src/deputy-cto/__tests__/hmac-argshash.test.ts`
|
|
1009
|
+
|
|
1010
|
+
### Tests
|
|
1011
|
+
|
|
1012
|
+
- **credential-file-guard**: 117/117 pass (13 new tests for approval flow)
|
|
1013
|
+
- **approval-hook**: 18/18 pass (8 new tests in `protected-action-approval-hook-files.test.js`)
|
|
1014
|
+
- **MCP servers**: 939/939 pass (7 new HMAC argsHash tests)
|
|
1015
|
+
|
|
1016
|
+
### Known Follow-up Items
|
|
1017
|
+
|
|
1018
|
+
1. HIGH: `checkApproval()` in approval-utils.js lacks HMAC verification (mitigated by ALWAYS_BLOCKED_SUFFIXES on approval file)
|
|
1019
|
+
2. MEDIUM: Runtime files (.claude/hooks/.claude/) committed by prior checkpoint - need git rm --cached and .gitignore update (RESOLVED)
|
|
1020
|
+
3. MEDIUM: HMAC key handling inconsistency (raw Buffer vs base64 string) between createRequest and computeHmac
|
|
1021
|
+
4. MEDIUM: No HMAC integrity tests for credential-file-guard approval flow
|
|
1022
|
+
5. LOW: Grep/Glob tools don't support approval path (intentional hard-block only)
|
|
1023
|
+
|
|
1024
|
+
## 2026-02-20 - Protection System: Fix Token File EACCES Errors
|
|
1025
|
+
|
|
1026
|
+
### Fixed
|
|
1027
|
+
|
|
1028
|
+
**Token file handling under sticky-bit protection** (4 files):
|
|
1029
|
+
- Root cause: `commit-approval-token.json` was missing from pre-creation loop in `setup.sh`, and hooks used `fs.unlinkSync()` (delete semantics) to clear tokens, which fails under sticky-bit protection on `.claude/`
|
|
1030
|
+
- Changes:
|
|
1031
|
+
1. **`scripts/setup.sh`** - Added `commit-approval-token.json` to pre-creation loop (line 603)
|
|
1032
|
+
2. **`.claude/hooks/pre-commit-review.js`** - Changed 2 `unlinkSync` calls to `writeFileSync(path, '{}')` pattern, added empty-object early-exit check
|
|
1033
|
+
3. **`.claude/hooks/block-no-verify.js`** - Changed 7 `unlinkSync` calls to `clearToken()` helper using overwrite pattern, added empty-object early-exit check
|
|
1034
|
+
4. **`packages/mcp-servers/src/deputy-cto/server.ts`** - Changed 2 `unlinkSync` calls to `writeFileSync(path, '{}')`, added empty-object early-exit check
|
|
1035
|
+
- Result: All token files can now be safely written/cleared under sticky-bit protection without EACCES errors
|
|
1036
|
+
- Pattern: Pre-create file during setup → overwrite with data to activate → overwrite with `{}` to consume/clear → treat `{}` as "no token"
|
|
1037
|
+
|
|
1038
|
+
### Documentation
|
|
1039
|
+
|
|
1040
|
+
**Created `docs/shared/EPHEMERAL-STATE-FILES.md`**:
|
|
1041
|
+
- Comprehensive guide to the pre-create + overwrite pattern for ephemeral state files
|
|
1042
|
+
- Lists all 6 state files using this pattern with their writers/consumers
|
|
1043
|
+
- Step-by-step instructions for adding new state files
|
|
1044
|
+
- Common mistakes and how to avoid them
|
|
1045
|
+
- Critical for maintaining sticky-bit protection compatibility
|
|
1046
|
+
|
|
1047
|
+
### Validation
|
|
1048
|
+
|
|
1049
|
+
- Code review: CLEAN, no violations
|
|
1050
|
+
- Test writer: No test updates needed (existing tests don't test token clearing behavior directly)
|
|
1051
|
+
- Pre-existing test failures confirmed (unrelated to changes)
|
|
1052
|
+
- TypeScript compiles clean with project tsconfig
|
|
1053
|
+
- All JS files pass syntax check
|
|
1054
|
+
|
|
1055
|
+
## 2026-02-20 - Usage Optimizer: Per-Account Deduplication Fix
|
|
1056
|
+
|
|
1057
|
+
### Fixed
|
|
1058
|
+
|
|
1059
|
+
**Double-counting bug in usage optimizer and dashboard** (`.claude/hooks/usage-optimizer.js`, `packages/cto-dashboard/src/utils/data-reader.ts`):
|
|
1060
|
+
- Root cause: When the same Anthropic account was discovered through multiple sources (environment variable, rotation state, Keychain, credentials file), each discovery was treated as a separate key for quota calculations
|
|
1061
|
+
- Result: Usage projections were inflated, causing premature throttling and incorrect dashboard metrics
|
|
1062
|
+
- Fix: `getApiKeys()` now includes `accountId` field (from `account_uuid`) in all returned key objects
|
|
1063
|
+
- `collectSnapshot()` deduplicates keys by `accountId` before building snapshots, using fingerprint fallback (`fp:${five_hour}:${seven_day}`) when `accountId` is null
|
|
1064
|
+
- `getKeyRotationMetrics()` in dashboard reader performs same per-account deduplication for consistent metrics
|
|
1065
|
+
- Warning messages changed from "Key" to "Account" to reflect deduplication scope
|
|
1066
|
+
|
|
1067
|
+
### Tests
|
|
1068
|
+
|
|
1069
|
+
- **Updated 3 existing tests** in `.claude/hooks/__tests__/usage-optimizer.test.js`:
|
|
1070
|
+
- `getApiKeys()` structure test now asserts `accountId` field presence
|
|
1071
|
+
- `collectSnapshot()` tests updated for new `rawKeyData`/`keyLookup`/`accountMap` variables
|
|
1072
|
+
- Warning message assertions changed from "Key" to "Account"
|
|
1073
|
+
- **Added 6 new behavioral tests** in "Per-Account Deduplication" describe block:
|
|
1074
|
+
- Deduplication by `accountId` when present
|
|
1075
|
+
- Fingerprint fallback when `accountId` is null
|
|
1076
|
+
- `accountId` preference over fingerprint when both exist
|
|
1077
|
+
- `accountId` field presence in all key source objects (env, rotation state, keychain, credentials)
|
|
1078
|
+
- **Updated dashboard tests** in `packages/cto-dashboard/src/utils/__tests__/data-reader.test.ts`:
|
|
1079
|
+
- `getKeyRotationMetrics()` tests updated for account deduplication logic
|
|
1080
|
+
- All 173 optimizer tests passing (was 167)
|
|
1081
|
+
- All 662 dashboard tests passing
|
|
1082
|
+
|
|
1083
|
+
### Impact
|
|
1084
|
+
|
|
1085
|
+
This fix ensures accurate quota tracking when using multi-source credential discovery. Projects with the same account configured in both environment variables and rotation state will no longer show inflated usage projections or premature automation throttling.
|
|
1086
|
+
|
|
1087
|
+
---
|
|
1088
|
+
|
|
1089
|
+
## 2026-02-20 - macOS Compatibility: Setup Script Group Name Fix
|
|
1090
|
+
|
|
1091
|
+
### Fixed
|
|
1092
|
+
|
|
1093
|
+
**macOS "illegal group name" error in setup scripts** (`scripts/setup-automation-service.sh`, `scripts/protect-framework.sh`, `scripts/setup.sh`):
|
|
1094
|
+
- Root cause: macOS does not create a default group matching the username; commands like `chown $SUDO_USER:$SUDO_USER` fail with "illegal group name"
|
|
1095
|
+
- Fix: Replaced hardcoded `$SUDO_USER:$SUDO_USER` with `$SUDO_USER:$(id -gn "$SUDO_USER" 2>/dev/null || echo staff)` at 3 call sites (setup-automation-service.sh lines 181, 231; similar patterns in protect-framework.sh and setup.sh)
|
|
1096
|
+
- Hardened `get_original_group()` function with explicit empty-check and OS-aware fallback (staff on Darwin, username on Linux)
|
|
1097
|
+
- Lines affected: setup-automation-service.sh:181, 231; protect-framework.sh:118-127; setup.sh:170-179
|
|
1098
|
+
|
|
1099
|
+
### Added
|
|
1100
|
+
|
|
1101
|
+
**File Protection Error Handling documentation** (`.claude/agents/`, `CLAUDE.md.gentyr-section`):
|
|
1102
|
+
- Added "Permission Denied on Protected Files" section to 3 agent configs: code-writer.md, code-reviewer.md, project-manager.md
|
|
1103
|
+
- Added "File Protection Error Handling" section to CLAUDE.md.gentyr-section (deployed to target projects via setup.sh)
|
|
1104
|
+
- Instructs agents to use `mcp__setup-helper__gentyr_setup({ action: "unprotect" })` when encountering Permission denied errors on protected files
|
|
1105
|
+
- Prevents agents from attempting `chmod`/`chown` directly; enforces use of MCP tool for safe unprotect/protect workflow
|
|
1106
|
+
|
|
1107
|
+
**Protection System Documentation** (`docs/shared/PROTECTION-SYSTEM.md`):
|
|
1108
|
+
- Comprehensive guide to GENTYR's 7-layer protection architecture
|
|
1109
|
+
- Threat model, trust boundaries, and attack vectors prevented
|
|
1110
|
+
- Layer-by-layer breakdown: Root Ownership, Protected Action Gate, MCP Server Allowlist, Credential File Guard, Bash Command Filter, Secret Leak Detector, Deputy-CTO Commit Review
|
|
1111
|
+
- Fail-closed design principles and G001 compliance
|
|
1112
|
+
|
|
1113
|
+
### Impact
|
|
1114
|
+
|
|
1115
|
+
This fix enables GENTYR installation on macOS systems where the primary user does not have a matching group name (the default macOS configuration). Previously, `sudo scripts/setup.sh --protect` would fail with "chown: illegal group name" errors during systemd service setup and file protection operations.
|
|
1116
|
+
|
|
1117
|
+
---
|
|
1118
|
+
|
|
1119
|
+
## 2026-02-20 - Usage Optimizer: Remove Factor Caps for Aggressive Throttling
|
|
1120
|
+
|
|
1121
|
+
### Changed
|
|
1122
|
+
|
|
1123
|
+
**Usage optimizer factor range expansion** (`.claude/hooks/usage-optimizer.js`):
|
|
1124
|
+
- MAX_FACTOR: 2.0 to 20.0 (up to 20x speedup; MIN_EFFECTIVE_MINUTES=5 is the real ceiling)
|
|
1125
|
+
- MIN_FACTOR: 0.5 to 0.05 (up to 20x slowdown; sufficient to essentially pause automation)
|
|
1126
|
+
- Recovery threshold: `currentFactor <= MIN_FACTOR + 0.01` to `currentFactor <= 0.15` with explanatory comment (threshold now independent of MIN_FACTOR value)
|
|
1127
|
+
- MAX_CHANGE_PER_CYCLE: 0.10 unchanged (factor moves at most ±10% per cycle)
|
|
1128
|
+
- MIN_EFFECTIVE_MINUTES: 5 unchanged (no cooldown goes below 5 minutes)
|
|
1129
|
+
|
|
1130
|
+
**Rationale**: The previous 0.5-2.0 range limited the optimizer to only 2x slowdown/speedup. When aggressive throttling was needed (e.g., approaching quota ceiling), the factor hit the floor and couldn't go lower. The new 0.05-20.0 range provides 20x dynamic range in both directions while preserving safety invariants.
|
|
1131
|
+
|
|
1132
|
+
### Tests
|
|
1133
|
+
|
|
1134
|
+
- **Updated 6 existing assertions** in `.claude/hooks/__tests__/usage-optimizer.test.js`:
|
|
1135
|
+
- Constant value regexes for MIN_FACTOR (0.05), MAX_FACTOR (20.0)
|
|
1136
|
+
- Recovery threshold detection regex
|
|
1137
|
+
- Behavioral recovery test values
|
|
1138
|
+
- **Added 10 new boundary tests**:
|
|
1139
|
+
- 5 extreme factor boundary tests (MIN_EFFECTIVE_MINUTES floor enforcement, extreme slowdown scenarios)
|
|
1140
|
+
- 5 recovery threshold boundary tests (inclusive/exclusive boundary, independence from MIN_FACTOR)
|
|
1141
|
+
- All 166 tests passing (was 156 tests)
|
|
1142
|
+
|
|
1143
|
+
### Fixed
|
|
1144
|
+
|
|
1145
|
+
**Documentation alignment**:
|
|
1146
|
+
- Updated `docs/AUTOMATION-SYSTEMS.md` to reflect new 0.05-20.0 range (was 0.5-2.0)
|
|
1147
|
+
- Factor effects table now shows full dynamic range examples
|
|
1148
|
+
- Recovery threshold documentation updated to reflect 0.15 fixed value
|
|
1149
|
+
|
|
1150
|
+
### Impact
|
|
1151
|
+
|
|
1152
|
+
The usage optimizer can now throttle automation by up to 20x when approaching quota limits, preventing quota exhaustion in high-utilization scenarios. The 0.15 recovery threshold ensures the optimizer doesn't get trapped at extreme slowdown when usage drops far below target.
|
|
1153
|
+
|
|
1154
|
+
---
|
|
1155
|
+
|
|
1156
|
+
## 2026-02-20 - Secret-Sync MCP Server: Security Hardening
|
|
1157
|
+
|
|
1158
|
+
### Fixed
|
|
1159
|
+
|
|
1160
|
+
**HIGH: Path traversal vulnerability via confFile parameter** (`packages/mcp-servers/src/secret-sync/types.ts`, `packages/mcp-servers/src/secret-sync/server.ts`):
|
|
1161
|
+
- Schema-level defense: Added Zod regex `/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/` to `confFile` field in `ServicesConfigSchema` to reject path traversal attempts (line 56)
|
|
1162
|
+
- Runtime boundary check: Added `safeProjectPath()` helper function to verify resolved paths stay within project directory (defense-in-depth)
|
|
1163
|
+
- Updated both `confFile` construction sites in `syncSecrets` and `listMappings` tools to use `safeProjectPath()` instead of bare `path.join()`
|
|
1164
|
+
- Blocks 50+ attack vectors: null bytes, Unicode normalization tricks, symlink targets, URL-encoded traversal sequences, backslashes, etc.
|
|
1165
|
+
|
|
1166
|
+
**MEDIUM: Protected services.json from agent modification** (`.claude/hooks/credential-file-guard.js`, `scripts/protect-framework.sh`):
|
|
1167
|
+
- Added `.claude/config/services.json` to credential-file-guard BLOCKED_PATH_SUFFIXES array (prevents write/overwrite operations)
|
|
1168
|
+
- Added to protect-framework.sh PROTECTED_FILES array for root ownership enforcement when `--protect` flag is used
|
|
1169
|
+
|
|
1170
|
+
**MEDIUM: Removed "local" from "all" target expansion** (`packages/mcp-servers/src/secret-sync/server.ts`):
|
|
1171
|
+
- All three tool functions (`syncSecrets`, `listMappings`, `verifySecrets`) now expand "all" to 3 remote targets only: `['render-production', 'render-staging', 'vercel']`
|
|
1172
|
+
- Local file system operations now require explicit opt-in (`target: 'local'`)
|
|
1173
|
+
- Prevents accidental writes to project directory when agent uses `target: 'all'`
|
|
1174
|
+
|
|
1175
|
+
**LOW: Added op-secrets.conf to .gitignore** (`.gitignore`):
|
|
1176
|
+
- Prevents accidental commits of generated local secrets configuration file
|
|
1177
|
+
- Placed in "Generated secret config" section with clear comment
|
|
1178
|
+
|
|
1179
|
+
### Tests
|
|
1180
|
+
|
|
1181
|
+
- **New security defense tests**: `packages/mcp-servers/src/secret-sync/__tests__/secret-sync.test.ts` (12 new tests, 79 total in file)
|
|
1182
|
+
- Zod schema rejection tests: path traversal strings (`../../../etc/passwd`), absolute paths, empty strings, Unicode normalization attacks
|
|
1183
|
+
- `safeProjectPath` boundary check tests: symlink resolution, null byte injection, directory escape attempts
|
|
1184
|
+
- "all" target expansion verification: ensures local is excluded from remote batch operations
|
|
1185
|
+
- Attack vector coverage: 50+ malicious path patterns tested
|
|
1186
|
+
- All 873 tests passing (23 test files across MCP servers, hooks, and dashboard)
|
|
1187
|
+
- TypeScript build: clean
|
|
1188
|
+
- Code review: PASS (no violations)
|
|
1189
|
+
|
|
1190
|
+
### Changed
|
|
1191
|
+
|
|
1192
|
+
**Files modified (6 total):**
|
|
1193
|
+
- `packages/mcp-servers/src/secret-sync/types.ts` (added regex validation to confFile schema)
|
|
1194
|
+
- `packages/mcp-servers/src/secret-sync/server.ts` (added `safeProjectPath()` helper, updated 2 construction sites)
|
|
1195
|
+
- `.claude/hooks/credential-file-guard.js` (added services.json to blocked paths)
|
|
1196
|
+
- `scripts/protect-framework.sh` (added services.json to protected files)
|
|
1197
|
+
- `.gitignore` (added op-secrets.conf)
|
|
1198
|
+
- `packages/mcp-servers/src/secret-sync/__tests__/secret-sync.test.ts` (12 new security tests)
|
|
1199
|
+
|
|
1200
|
+
### Impact
|
|
1201
|
+
|
|
1202
|
+
This hardening eliminates path traversal vulnerabilities in the secret-sync MCP server's local file operations. The multi-layer defense (Zod schema + runtime boundary check) ensures agents cannot write outside the project directory or modify protected configuration files, even with sophisticated attack patterns.
|
|
1203
|
+
|
|
1204
|
+
---
|
|
1205
|
+
|
|
1206
|
+
## 2026-02-20 - CTO Dashboard: Readonly Database Fix for Protected Directories
|
|
1207
|
+
|
|
1208
|
+
### Fixed
|
|
1209
|
+
|
|
1210
|
+
**SQLite WAL-mode readonly access in root-owned directories** (`packages/cto-dashboard/src/utils/readonly-db.ts`, `packages/mcp-servers/src/shared/readonly-db.ts`, `packages/vscode-extension/src/extension/readonly-db.ts`):
|
|
1211
|
+
- Root cause: When `setup.sh --protect` makes `.claude/` root-owned, SQLite cannot create `-shm`/`-wal` files needed for WAL mode even with `{ readonly: true }` option
|
|
1212
|
+
- Fix: Created `openReadonlyDb()` helper function (3 identical implementations for dashboard, MCP servers, and VS Code extension)
|
|
1213
|
+
- Fallback strategy: On readonly directory error, copies database to `/tmp`, converts journal mode from WAL to DELETE, reopens as readonly, patches `close()` method to clean up temp file
|
|
1214
|
+
- Applied to 25 call sites across 12 files: replaced `new Database(path, { readonly: true })` with `openReadonlyDb(path)`
|
|
1215
|
+
|
|
1216
|
+
### Changed
|
|
1217
|
+
|
|
1218
|
+
**Files modified (12 total):**
|
|
1219
|
+
- `packages/cto-dashboard/src/utils/readonly-db.ts` (new, 56 lines)
|
|
1220
|
+
- `packages/cto-dashboard/src/utils/data-reader.ts` (4 call sites)
|
|
1221
|
+
- `packages/cto-dashboard/src/utils/deputy-cto-reader.ts` (1 call site)
|
|
1222
|
+
- `packages/cto-dashboard/src/utils/timeline-aggregator.ts` (2 call sites)
|
|
1223
|
+
- `packages/mcp-servers/src/shared/readonly-db.ts` (new, 51 lines)
|
|
1224
|
+
- `packages/mcp-servers/src/cto-report/server.ts` (3 call sites)
|
|
1225
|
+
- `packages/mcp-servers/src/deputy-cto/server.ts` (1 call site)
|
|
1226
|
+
- `packages/mcp-servers/src/feedback-explorer/server.ts` (3 call sites)
|
|
1227
|
+
- `packages/mcp-servers/src/user-feedback/server.ts` (1 call site)
|
|
1228
|
+
- `packages/vscode-extension/src/extension/readonly-db.ts` (new, 51 lines)
|
|
1229
|
+
- `packages/vscode-extension/src/extension/DataService.ts` (4 call sites)
|
|
1230
|
+
|
|
1231
|
+
### Tests
|
|
1232
|
+
|
|
1233
|
+
- **New test file**: `packages/cto-dashboard/src/utils/__tests__/readonly-db.test.ts` (20 tests, 418 lines)
|
|
1234
|
+
- Direct readonly open path (normal directories)
|
|
1235
|
+
- Fallback temp-copy path (readonly directories)
|
|
1236
|
+
- Temp file cleanup on `.close()`
|
|
1237
|
+
- Error propagation for non-readonly errors
|
|
1238
|
+
- All 632 dashboard tests + 847 MCP server tests + 20 new tests passing
|
|
1239
|
+
- TypeScript build: clean
|
|
1240
|
+
- Code review: PASS (no violations)
|
|
1241
|
+
|
|
1242
|
+
### Impact
|
|
1243
|
+
|
|
1244
|
+
This fix enables the CTO dashboard, MCP servers, and VS Code extension to read SQLite databases in protected GENTYR installations where `.claude/` directories are root-owned. Previously, all three components would fail with `SQLITE_READONLY_DIRECTORY` errors when attempting to open databases for reading.
|
|
1245
|
+
|
|
1246
|
+
---
|
|
1247
|
+
|
|
1248
|
+
## 2026-02-20 - Autonomous Restartless Credential Rotation
|
|
1249
|
+
|
|
1250
|
+
### Implemented
|
|
1251
|
+
|
|
1252
|
+
**Unified proactive refresh and pre-expiry swap** (`.claude/hooks/quota-monitor.js`, `.claude/hooks/key-sync.js`):
|
|
1253
|
+
- **Step 4b unified**: Combined expired-token refresh and approaching-expiry proactive refresh into single loop using `isExpired`/`isApproachingExpiry` variables
|
|
1254
|
+
- **Shared expiry constant**: `EXPIRY_BUFFER_MS` (10 min) exported from `key-sync.js`, imported by `quota-monitor.js` for consistent timing
|
|
1255
|
+
- **Proactive standby refresh**: Non-active tokens within 10 min of expiry are refreshed automatically to keep standby pool perpetually fresh
|
|
1256
|
+
- **Pre-expiry restartless swap**: When active key approaches expiry and valid standby exists, writes standby to Keychain; Claude Code's `SRA()` (5 min buffer) or `r6T()` (401 recovery) picks up new token seamlessly without restart
|
|
1257
|
+
- **Idle session coverage**: `key-sync.js` also performs proactive refresh and pre-expiry swap during `syncKeys()` runs (called every 10 min by launchd even when no Claude Code process is active)
|
|
1258
|
+
- **Date.now() consistency**: Cached into `now4b` variable to prevent time drift within execution (matches `key-sync.js` pattern)
|
|
1259
|
+
|
|
1260
|
+
### Tests
|
|
1261
|
+
|
|
1262
|
+
- **New test file**: `.claude/hooks/__tests__/proactive-refresh-and-swap.test.js` (35 tests, 592 lines)
|
|
1263
|
+
- Step 4b: `EXPIRY_BUFFER_MS` import verification, `isApproachingExpiry` variable presence, refresh loop behavior
|
|
1264
|
+
- Step 4c: Pre-expiry restartless swap trigger logic, standby selection, `updateActiveCredentials()` call verification
|
|
1265
|
+
- `key-sync.js`: proactive refresh in `syncKeys()`, pre-expiry swap logic, shared constant export
|
|
1266
|
+
- Coverage: all new autonomous rotation behaviors across both files
|
|
1267
|
+
- **Updated existing tests**: `.claude/hooks/__tests__/key-sync-expired-filter.test.js`, `.claude/hooks/__tests__/quota-monitor.test.js` (updated for new source patterns)
|
|
1268
|
+
- **Total**: 130 hook tests passing (92 existing + 35 new + 3 updated)
|
|
1269
|
+
|
|
1270
|
+
### Documentation
|
|
1271
|
+
|
|
1272
|
+
- **Implementation guide**: `docs/sessions/2026-02-20-credential-rotation-experiments.md` updated with detailed coverage matrix, autonomous rotation architecture, and `SRA()`/`r6T()` recovery path analysis
|
|
1273
|
+
- **CLAUDE.md**: Updated quota-monitor and key-sync sections with new proactive refresh and pre-expiry swap capabilities
|
|
1274
|
+
|
|
1275
|
+
### Research Findings
|
|
1276
|
+
|
|
1277
|
+
**Token expiry vs revocation behavior** (documented in `docs/sessions/2026-02-20-credential-rotation-experiments.md`):
|
|
1278
|
+
- Naturally expired OAuth tokens return HTTP **401** (`authentication_error`) — **recoverable** by Claude Code's built-in `r6T()` retry handler
|
|
1279
|
+
- Revoked tokens (via `refresh_token` grant) return HTTP **403** (`permission_error`) — **terminal**, no recovery
|
|
1280
|
+
- This means `refreshExpiredToken()` inadvertently causes unrecoverable 403 by revoking the old token, when waiting for natural expiry would yield a recoverable 401
|
|
1281
|
+
|
|
1282
|
+
**Claude Code token architecture**:
|
|
1283
|
+
- Uses `Authorization: Bearer <oauth-token>` with `anthropic-beta: oauth-2025-04-20` for `/v1/messages` calls
|
|
1284
|
+
- `SRA()` proactive refresh fires 5 minutes before `expiresAt`: clears credential cache → re-reads from disk → if new valid token found, adopts it seamlessly
|
|
1285
|
+
- `r6T()` fires on HTTP 401: clears cache → re-reads Keychain → retries with new credentials
|
|
1286
|
+
- The `org:create_api_key` scope and API key creation endpoint are optional; Bearer auth is the primary path
|
|
1287
|
+
|
|
1288
|
+
**Restartless rotation strategy identified**: Write new account's token to Keychain/file without refreshing the old one. When old token expires → `SRA()` or `r6T()` picks up new token from disk → seamless recovery, no restart needed.
|
|
1289
|
+
|
|
1290
|
+
### Bugs Found
|
|
1291
|
+
|
|
1292
|
+
**Missing process kill in automated rotation** (`.claude/hooks/quota-monitor.js:318-354`):
|
|
1293
|
+
- Automated session rotation spawns new `claude --resume` process but never kills the old one
|
|
1294
|
+
- Interactive sessions correctly kill via `generateRestartScript()` with `kill -TERM`/`kill -9`
|
|
1295
|
+
- Confirmed 33 orphaned processes consuming ~2GB total RAM
|
|
1296
|
+
|
|
1297
|
+
**Selective proxy routing in Bun** (informational):
|
|
1298
|
+
- `HTTPS_PROXY` routes eval, profile, and mcp_servers calls through proxy
|
|
1299
|
+
- `/v1/messages` (main SDK call) bypasses the proxy entirely
|
|
1300
|
+
- Proxy-based 401 injection is not viable for triggering credential recovery
|
|
1301
|
+
|
|
1302
|
+
## 2026-02-19 - Credential Lifecycle: invalid_grant Sentinel, Dead-Key Pruning, Secret Manager Agent
|
|
1303
|
+
|
|
1304
|
+
### Added
|
|
1305
|
+
|
|
1306
|
+
**invalid_grant sentinel in `refreshExpiredToken`** (`.claude/hooks/key-sync.js`):
|
|
1307
|
+
- `refreshExpiredToken` now returns the string `'invalid_grant'` (not `null`) when the OAuth server responds HTTP 400 + `{ error: 'invalid_grant' }`, distinguishing a permanently revoked refresh token from a transient network failure
|
|
1308
|
+
- All 4 callers updated atomically: `syncKeys()`, `api-key-watcher.js`, `quota-monitor.js`, `stop-continue-hook.js`
|
|
1309
|
+
- On `invalid_grant`: key status set to `'invalid'`, rotation log records `refresh_token_invalid_grant` reason, key excluded from all future rotation candidates
|
|
1310
|
+
|
|
1311
|
+
**`pruneDeadKeys()` garbage collection** (`.claude/hooks/key-sync.js`):
|
|
1312
|
+
- New exported function removes keys with `status === 'invalid'` where `last_health_check` (or `added_at`) is older than 7 days
|
|
1313
|
+
- Never prunes the currently active key
|
|
1314
|
+
- Removes orphaned `rotation_log` entries that reference pruned keys
|
|
1315
|
+
- Called automatically at the end of every `syncKeys()` run
|
|
1316
|
+
|
|
1317
|
+
**Dashboard event display** (`packages/cto-dashboard/src/utils/account-overview-reader.ts`):
|
|
1318
|
+
- Added `refresh_token_invalid_grant` reason mapping to human-readable description "Refresh token revoked for {key}"
|
|
1319
|
+
|
|
1320
|
+
**CTO report key status breakdown** (`packages/mcp-servers/src/cto-report/`):
|
|
1321
|
+
- `types.ts`: Added optional `expired_keys`, `invalid_keys`, `exhausted_keys` fields to `KeyRotationMetrics` interface
|
|
1322
|
+
- `server.ts`: `getKeyRotationMetrics()` counts and returns those three fields
|
|
1323
|
+
|
|
1324
|
+
**Secret Manager Agent** (`.claude/agents/secret-manager.md`):
|
|
1325
|
+
- New specialized agent for secret lifecycle management via GENTYR's 1Password-based system
|
|
1326
|
+
- Operations-only: uses MCP tools (`secret-sync`, `onepassword`, `todo-db`, `agent-reports`) without editing files
|
|
1327
|
+
- Handles: adding/rotating secrets, syncing to Render/Vercel, diagnosing missing runtime credentials, setting up local dev secrets
|
|
1328
|
+
- Creates TODO tasks for code-writer when `services.json` changes are needed
|
|
1329
|
+
- Reports security findings (shadow secrets, plain-type secrets, mismatched vault refs) to deputy-CTO
|
|
1330
|
+
|
|
1331
|
+
**`/setup-gentyr` Phase 2: Claude Account Inventory** (`.claude/commands/setup-gentyr.md`, `.claude/hooks/slash-command-prefetch.js`):
|
|
1332
|
+
- New `getAccountInventory()` function in `slash-command-prefetch.js` reads rotation state, deduplicates accounts by `account_uuid`, and injects data into prefetch payload
|
|
1333
|
+
- Phase 2 added to setup flow: displays current Claude account inventory (email, status, quota), offers guided login loop to add additional accounts for quota rotation
|
|
1334
|
+
- Existing phases renumbered 3–8 (was 2–7)
|
|
1335
|
+
|
|
1336
|
+
### Tests
|
|
1337
|
+
|
|
1338
|
+
- **New test file:** `.claude/hooks/__tests__/invalid-grant-and-prune.test.js` (43 tests)
|
|
1339
|
+
- `refreshExpiredToken` sentinel return value verification across all 4 caller files (static analysis)
|
|
1340
|
+
- `pruneDeadKeys` behavior: prunes keys older than 7 days, never prunes active key, removes orphaned log entries
|
|
1341
|
+
- `syncKeys` marks key `invalid` and logs `refresh_token_invalid_grant` on sentinel
|
|
1342
|
+
- All callers handle sentinel path by marking key `invalid`
|
|
1343
|
+
- All 135 hook tests passing (92 existing + 43 new)
|
|
1344
|
+
- TypeScript build: clean
|
|
1345
|
+
|
|
1346
|
+
### Verification
|
|
1347
|
+
|
|
1348
|
+
- Code review: PASS — no violations, no security issues, TypeScript compiles clean
|
|
1349
|
+
- Static analysis confirms sentinel string `'invalid_grant'` returned (not `null`) in HTTP 400 + error body path
|
|
1350
|
+
- `pruneDeadKeys` never touches active key in all test scenarios
|
|
1351
|
+
|
|
1352
|
+
**Total Changes:** 1 new agent, 1 new test file, 7 modified files, 43 new tests, 135 hook tests passing
|
|
1353
|
+
|
|
1354
|
+
---
|
|
1355
|
+
|
|
1356
|
+
## 2026-02-18 - Binary Patching: Clawd Mascot Customization
|
|
1357
|
+
|
|
1358
|
+
### Added
|
|
1359
|
+
|
|
1360
|
+
**Clawd Mascot Patcher** (`scripts/patch-clawd.py`, ~600 lines):
|
|
1361
|
+
- Version-agnostic binary patcher for Claude Code CLI mascot customization
|
|
1362
|
+
- Replaces stock Clawd with #29 Winged Eye design (sparkle wings, dark pupil, amber bases)
|
|
1363
|
+
- Structural pattern detection using regex instead of hardcoded offsets
|
|
1364
|
+
- Dynamic variable extraction for React createElement calls
|
|
1365
|
+
- Exact-length replacement with empty-string padding
|
|
1366
|
+
- 9 validation gates before and after writing
|
|
1367
|
+
- Atomic write via temp file + os.rename() to prevent corruption
|
|
1368
|
+
- Idempotent operation: detects already-patched binary and skips
|
|
1369
|
+
- CLI flags: --dry-run, --restore, --binary, --no-color
|
|
1370
|
+
- Automatic codesign and xattr quarantine clearing
|
|
1371
|
+
- Colored terminal output with detailed block analysis
|
|
1372
|
+
|
|
1373
|
+
**Binary Patching Documentation** (`docs/BINARY-PATCHING.md`):
|
|
1374
|
+
- Complete guide to customizing the Clawd mascot in Claude Code binary
|
|
1375
|
+
- Architecture explanation: Bun-compiled executable with embedded JS source
|
|
1376
|
+
- Mascot function locations and offset discovery methods
|
|
1377
|
+
- Theme color system and available color names
|
|
1378
|
+
- Byte-count compensation techniques (empty string padding, string adjustment)
|
|
1379
|
+
- Current design specification: #29 Winged Eye with unicode char reference
|
|
1380
|
+
- Automated patching workflow with safety gates
|
|
1381
|
+
- Manual patching fallback instructions
|
|
1382
|
+
- Rollback procedures
|
|
1383
|
+
- Technical lessons learned from binary patching experiments
|
|
1384
|
+
|
|
1385
|
+
### Fixed
|
|
1386
|
+
|
|
1387
|
+
**Code Review Fixes Applied:**
|
|
1388
|
+
- CRITICAL: Raw string bug in unicode escape sequences (lines 462, 475) - used r-prefix raw strings to preserve literal \u sequences
|
|
1389
|
+
- CRITICAL: Non-atomic write pattern - replaced direct file.write() with temp file + os.rename()
|
|
1390
|
+
- MEDIUM: Dead code removed - unused brace_depth variable in return block extraction
|
|
1391
|
+
- MEDIUM: Regex $ handling - fixed \w+ to [\w$]+ to match JavaScript identifiers with $
|
|
1392
|
+
- LOW: Missing verification - added binary execution check after codesign recovery
|
|
1393
|
+
- LOW: Incomplete mascot char list - added all quadrant block characters to detection set
|
|
1394
|
+
|
|
1395
|
+
### Tests
|
|
1396
|
+
|
|
1397
|
+
**Manual Testing:**
|
|
1398
|
+
- --dry-run on patched binary: detects 4 blocks, all "already patched"
|
|
1399
|
+
- --dry-run on stock binary: detects 4 blocks, builds correct replacements with exact byte match
|
|
1400
|
+
- Full patch cycle: detect → backup → patch → codesign → verify
|
|
1401
|
+
- Idempotency verified: re-run on patched binary does nothing
|
|
1402
|
+
- Visual verification: mascot displays correctly in terminal
|
|
1403
|
+
|
|
1404
|
+
### Technical Details
|
|
1405
|
+
|
|
1406
|
+
**Design #29 Winged Eye:**
|
|
1407
|
+
```
|
|
1408
|
+
▗▘ ✦ ▝▖ Row 1: wing tips + sparkle (penguinShimmer)
|
|
1409
|
+
▐▌ ● ▐▌ Row 2: wings + dark pupil (penguinShimmer wings, clawd_body eye)
|
|
1410
|
+
▀ ▀ Row 3: wing bases (chromeYellow)
|
|
1411
|
+
```
|
|
1412
|
+
|
|
1413
|
+
**Pattern Detection:**
|
|
1414
|
+
- Searches for flexDirection:"column",alignItems:"center" + clawd_body + mascot unicode chars
|
|
1415
|
+
- Extracts React import variable (e.g., x$, mB) dynamically
|
|
1416
|
+
- Extracts Flex and Text component variables dynamically
|
|
1417
|
+
- Builds replacement with exact byte count using empty-string padding (,"")
|
|
1418
|
+
|
|
1419
|
+
**Safety Mechanisms:**
|
|
1420
|
+
- Byte count verification before and after every replacement
|
|
1421
|
+
- Binary execution test after patching
|
|
1422
|
+
- Automatic backup creation before any write
|
|
1423
|
+
- Codesign restoration with verification
|
|
1424
|
+
- Idempotent operation prevents double-patching corruption
|
|
1425
|
+
|
|
1426
|
+
---
|
|
1427
|
+
|
|
1428
|
+
## 2026-02-18 - CTO Dashboard: Account Overview Section
|
|
1429
|
+
|
|
1430
|
+
### Added
|
|
1431
|
+
|
|
1432
|
+
**Account Overview Section** (`packages/cto-dashboard/`):
|
|
1433
|
+
- New `account-overview-reader.ts` data reader module (~226 lines)
|
|
1434
|
+
- Parses `~/.claude/api-key-rotation.json` for per-account details and rotation events
|
|
1435
|
+
- Reads key metadata: status, subscription type, email, expiry, usage quotas
|
|
1436
|
+
- Filters and formats rotation event log (last 24h, max 20 events, excludes noisy health_check events)
|
|
1437
|
+
- Account sorting: current key first, then by status (active → exhausted → expired → invalid), then by added date
|
|
1438
|
+
- New `AccountOverviewSection.tsx` component (~115 lines)
|
|
1439
|
+
- Per-account table with truncated key IDs, status indicators, subscription type, email, expiry date
|
|
1440
|
+
- Per-key quota bars: 5h, 7d, and conditional 7d-sonnet (only shown if >10pp difference from 7d)
|
|
1441
|
+
- Event history timeline (last 24h) with color-coded event types and timestamps
|
|
1442
|
+
- Title shows account count and 24h rotation count
|
|
1443
|
+
- Mock data integration in `mock-data.ts`
|
|
1444
|
+
- `getMockAccountOverview()` returns 3 mock accounts with realistic quota spreads
|
|
1445
|
+
- 8 mock rotation events covering all event types (key_added, key_switched, key_exhausted, key_removed)
|
|
1446
|
+
- Section wired into `App.tsx` between Quota & System Status and Deputy CTO sections
|
|
1447
|
+
- Barrel export added to `components/index.ts`
|
|
1448
|
+
|
|
1449
|
+
### Fixed
|
|
1450
|
+
|
|
1451
|
+
**Code Review Findings (all addressed):**
|
|
1452
|
+
- HIGH: React key collision risk — truncated 8-char key IDs used as React keys caused potential collisions
|
|
1453
|
+
- Fixed by adding index suffix: `key={`${account.keyId}-${idx}`}` for AccountRow components
|
|
1454
|
+
- MEDIUM: Dead fields removed — `fiveHourResetsAt` and `sevenDayResetsAt` were always null (reset times now stored in rotation state)
|
|
1455
|
+
- Removed from `AccountKeyDetail` interface
|
|
1456
|
+
- MEDIUM: Module-level constant prevents testability — `KEY_ROTATION_STATE_PATH` was a module-level constant
|
|
1457
|
+
- Refactored to lazy getter function `getKeyRotationStatePath()` for test isolation
|
|
1458
|
+
|
|
1459
|
+
### Tests
|
|
1460
|
+
|
|
1461
|
+
- **New test file:** `packages/cto-dashboard/src/components/__tests__/AccountOverviewSection.test.tsx` (30 tests)
|
|
1462
|
+
- Empty state rendering
|
|
1463
|
+
- Account table structure and ordering (current key first, then by status)
|
|
1464
|
+
- Quota bar rendering with conditional 7d-sonnet logic
|
|
1465
|
+
- Event history formatting and color coding
|
|
1466
|
+
- Edge cases: missing emails, no expiry dates, null usage data
|
|
1467
|
+
- **Modified:** `mock-data.ts` — added `getMockAccountOverview()` function
|
|
1468
|
+
- **Modified:** `account-overview-reader.ts` — fixed React key collision, removed dead fields, refactored path getter
|
|
1469
|
+
- All 632 tests passing across 18 test files (up from 602)
|
|
1470
|
+
- TypeScript build: clean
|
|
1471
|
+
- README generation: clean (Account Overview section renders in mock mode)
|
|
1472
|
+
|
|
1473
|
+
### Verification
|
|
1474
|
+
|
|
1475
|
+
**Live Mode Testing:**
|
|
1476
|
+
- Dashboard renders 12 real accounts from `~/.claude/api-key-rotation.json`
|
|
1477
|
+
- Event history shows 8 rotation events from last 24h
|
|
1478
|
+
- Quota bars display correct percentages from last_usage snapshots
|
|
1479
|
+
- Current key marked with `*` prefix and cyan color
|
|
1480
|
+
|
|
1481
|
+
**Mock Mode Testing:**
|
|
1482
|
+
- `npm run generate:readme` successfully regenerates README with Account Overview section
|
|
1483
|
+
- Mock data shows 3 accounts with varied statuses (active, exhausted) and quota spreads
|
|
1484
|
+
- Event timeline demonstrates all event type color coding
|
|
1485
|
+
|
|
1486
|
+
**Total Changes:** 2 new files, 4 modified files, 30 new tests, 632 total tests passing
|
|
1487
|
+
|
|
1488
|
+
---
|
|
1489
|
+
|
|
1490
|
+
## 2026-02-18 - Automatic Account Rotation & Session Recovery
|
|
1491
|
+
|
|
1492
|
+
### Added
|
|
1493
|
+
|
|
1494
|
+
**Quota Monitor Hook** (`.claude/hooks/quota-monitor.js`, ~230 lines):
|
|
1495
|
+
- PostToolUse hook that monitors API quota usage every 5 minutes
|
|
1496
|
+
- Triggers credential rotation at 95% utilization threshold
|
|
1497
|
+
- Interactive sessions: spawns auto-restart script with new credentials
|
|
1498
|
+
- Automated sessions: writes quota-interrupted state for session-reviver pickup
|
|
1499
|
+
- All-accounts-exhausted detection: writes paused-sessions.json with pause reason and timestamp
|
|
1500
|
+
- Cooldown protection: 10-minute rotation cooldown prevents rotation loops
|
|
1501
|
+
|
|
1502
|
+
**Session Reviver Hook** (`.claude/hooks/session-reviver.js`, ~320 lines):
|
|
1503
|
+
- Called from hourly-automation.js to recover interrupted automated sessions
|
|
1504
|
+
- Mode 1 (Quota-interrupted pickup): Reads quota-interrupted-sessions.json and re-spawns sessions with --resume after credential rotation
|
|
1505
|
+
- Mode 2 (Historical dead session recovery): Scans agent-tracker-history.json for unexpectedly dead agents (process_already_dead) within last 7 days and re-spawns pending TODOs
|
|
1506
|
+
- Mode 3 (Paused session resume): Reads paused-sessions.json and checks if any account has recovered, then resumes paused sessions
|
|
1507
|
+
- Limits: Max 3 revivals per cycle, 7-day historical window
|
|
1508
|
+
- TODO reconciliation integration with reap-completed-agents.js
|
|
1509
|
+
|
|
1510
|
+
**Recovery CLI Script** (`scripts/recover-interrupted-sessions.js`, ~200 lines):
|
|
1511
|
+
- One-time manual recovery tool for interrupted sessions
|
|
1512
|
+
- Accepts `--path`, `--dry-run`, `--max-concurrent` flags
|
|
1513
|
+
- Cross-references agent-tracker-history with TODO database
|
|
1514
|
+
- Identifies in_progress tasks with no corresponding live process
|
|
1515
|
+
- Re-spawns sessions with original task context
|
|
1516
|
+
|
|
1517
|
+
### Changed
|
|
1518
|
+
|
|
1519
|
+
**Key Sync Module** (`.claude/hooks/key-sync.js`):
|
|
1520
|
+
- Exported `checkKeyHealth()`, `selectActiveKey()`, `HIGH_USAGE_THRESHOLD` (80%), `EXHAUSTED_THRESHOLD` (95%) for reuse
|
|
1521
|
+
- Added 120 lines of public API functions for credential rotation workflows
|
|
1522
|
+
|
|
1523
|
+
**API Key Watcher** (`.claude/hooks/api-key-watcher.js`):
|
|
1524
|
+
- Refactored to use shared functions from key-sync.js (~100 lines removed, +10 added)
|
|
1525
|
+
- Moved `checkKeyHealth`, `selectActiveKey`, threshold constants to imports
|
|
1526
|
+
- Added local `ANTHROPIC_BETA_HEADER` constant for `fetchAccountProfile`
|
|
1527
|
+
|
|
1528
|
+
**Agent Tracker** (`.claude/hooks/agent-tracker.js`):
|
|
1529
|
+
- Added `SESSION_REVIVED` to `AGENT_TYPES`
|
|
1530
|
+
- Added `QUOTA_MONITOR` and `SESSION_REVIVER` to `HOOK_TYPES`
|
|
1531
|
+
|
|
1532
|
+
**Slash Command Prefetch** (`.claude/hooks/slash-command-prefetch.js`):
|
|
1533
|
+
- Made 6 utility functions into named exports: `getSessionDir`, `discoverSessionId`, `getClaudePid`, `detectTerminal`, `shellEscape`, `generateRestartScript`
|
|
1534
|
+
- Enables reuse in quota-monitor.js for restart script generation
|
|
1535
|
+
|
|
1536
|
+
**Settings Template** (`.claude/settings.json.template`):
|
|
1537
|
+
- Added PostToolUse section registering quota-monitor.js
|
|
1538
|
+
|
|
1539
|
+
**Stop-Continue Hook** (`.claude/hooks/stop-continue-hook.js`):
|
|
1540
|
+
- Added quota death detection: reads session JSONL for rate_limit errors
|
|
1541
|
+
- Attempts credential rotation on quota death
|
|
1542
|
+
- Writes recovery state to quota-interrupted-sessions.json for session-reviver pickup
|
|
1543
|
+
- Fixed full-file read replaced with head-only read (4KB) for performance
|
|
1544
|
+
|
|
1545
|
+
**Reap Completed Agents** (`scripts/reap-completed-agents.js`):
|
|
1546
|
+
- Added TODO reconciliation: marks completed or resets to pending based on reap reason
|
|
1547
|
+
- Added `todoReconciled` field to result object
|
|
1548
|
+
|
|
1549
|
+
**Hourly Automation** (`.claude/hooks/hourly-automation.js`):
|
|
1550
|
+
- Integrated session-reviver call after key-sync block with 10-minute cooldown
|
|
1551
|
+
|
|
1552
|
+
**Config Reader** (`.claude/hooks/config-reader.js`):
|
|
1553
|
+
- Added `session_reviver: 10` (minutes) to cooldown defaults
|
|
1554
|
+
|
|
1555
|
+
### Fixed
|
|
1556
|
+
|
|
1557
|
+
**Code Review Fixes Applied:**
|
|
1558
|
+
- CRITICAL: `ANTHROPIC_BETA_HEADER` undefined in api-key-watcher.js (now defined locally)
|
|
1559
|
+
- HIGH: Full transcript file read in stop-hook replaced with 4KB head-read for performance
|
|
1560
|
+
- MEDIUM: Changed `stdio: 'inherit'` to `'ignore'` in session-reviver.js to prevent stdio pollution
|
|
1561
|
+
- MEDIUM: Stored only `resets_at` timestamp from raw API instead of full response object
|
|
1562
|
+
- LOW: Default project path uses `process.cwd()` instead of hardcoded path
|
|
1563
|
+
- LOW: `isProcessAlive` handles EPERM consistently across platforms
|
|
1564
|
+
|
|
1565
|
+
### Known Technical Debt
|
|
1566
|
+
|
|
1567
|
+
**Pre-existing Architectural Patterns (not introduced by this change):**
|
|
1568
|
+
- Race condition on shared state files (no file locking) - systemic pattern across framework
|
|
1569
|
+
- Duplicate utility functions (readHead, readTail, etc.) across multiple modules - consolidation candidate
|
|
1570
|
+
- Inconsistent `getSessionDir` implementations across 4 files - should be unified
|
|
1571
|
+
|
|
1572
|
+
### Technical Details
|
|
1573
|
+
|
|
1574
|
+
**Recovery Workflow:**
|
|
1575
|
+
1. Session hits quota limit during execution
|
|
1576
|
+
2. Stop-continue-hook detects rate_limit error in JSONL tail
|
|
1577
|
+
3. Attempts credential rotation via key-sync
|
|
1578
|
+
4. Writes interrupted session state to quota-interrupted-sessions.json
|
|
1579
|
+
5. Session-reviver picks up interrupted state during next hourly automation cycle
|
|
1580
|
+
6. Re-spawns session with --resume flag and new credentials
|
|
1581
|
+
7. Agent continues from interruption point
|
|
1582
|
+
|
|
1583
|
+
**Paused Sessions Workflow:**
|
|
1584
|
+
1. Quota-monitor detects all accounts exhausted (all keys >= 95%)
|
|
1585
|
+
2. Writes paused-sessions.json with pause reason and timestamp
|
|
1586
|
+
3. Session-reviver checks paused state every hourly cycle
|
|
1587
|
+
4. When any account recovers below 95%, resumes paused sessions
|
|
1588
|
+
5. Logs recovery and clears paused state
|
|
1589
|
+
|
|
1590
|
+
**Files Created (3 total):**
|
|
1591
|
+
- `.claude/hooks/quota-monitor.js` (230 lines)
|
|
1592
|
+
- `.claude/hooks/session-reviver.js` (320 lines)
|
|
1593
|
+
- `scripts/recover-interrupted-sessions.js` (200 lines)
|
|
1594
|
+
|
|
1595
|
+
**Files Modified (9 total):**
|
|
1596
|
+
- `.claude/hooks/key-sync.js` (+120 lines)
|
|
1597
|
+
- `.claude/hooks/api-key-watcher.js` (-100/+10 lines)
|
|
1598
|
+
- `.claude/hooks/agent-tracker.js` (+3 lines)
|
|
1599
|
+
- `.claude/hooks/slash-command-prefetch.js` (+6 exports)
|
|
1600
|
+
- `.claude/settings.json.template` (+12 lines)
|
|
1601
|
+
- `.claude/hooks/stop-continue-hook.js` (+130 lines)
|
|
1602
|
+
- `scripts/reap-completed-agents.js` (+60 lines)
|
|
1603
|
+
- `.claude/hooks/hourly-automation.js` (+20 lines)
|
|
1604
|
+
- `.claude/hooks/config-reader.js` (+1 line)
|
|
1605
|
+
|
|
1606
|
+
**Total Changes:** +750 lines added across 12 files
|
|
1607
|
+
|
|
1608
|
+
---
|
|
1609
|
+
|
|
1610
|
+
## 2026-02-18 - Deputy-CTO Identity Injection and Investigator Session History
|
|
1611
|
+
|
|
1612
|
+
### Changed
|
|
1613
|
+
|
|
1614
|
+
**`/deputy-cto` command now fully assumes the deputy-CTO identity** by receiving the agent's complete knowledge base at session start, rather than operating as a generic assistant following session flow instructions.
|
|
1615
|
+
|
|
1616
|
+
**Prefetch hook — agent instructions injection** (`.claude/hooks/slash-command-prefetch.js`):
|
|
1617
|
+
- `handleDeputyCto()` now reads `.claude/agents/deputy-cto.md` at hook invocation time
|
|
1618
|
+
- Strips YAML frontmatter (between `---` markers) before injecting content
|
|
1619
|
+
- Injects the stripped markdown as `agentInstructions` in the prefetch output under `gathered.agentInstructions`
|
|
1620
|
+
- Non-fatal: if the agent file is missing, `agentInstructions` is set to `null` and the hook continues normally
|
|
1621
|
+
|
|
1622
|
+
**Deputy-CTO command — "Your Identity" section** (`.claude/commands/deputy-cto.md`):
|
|
1623
|
+
- Added a new "Your Identity" section before "Session Behavior"
|
|
1624
|
+
- Instructs Claude to locate the `agentInstructions` field injected by the prefetch hook and absorb it as its own identity
|
|
1625
|
+
- Clarifies interactive-session differences from autonomous mode (wait for CTO input, present options rather than deciding unilaterally, use `AskUserQuestion` for batch review)
|
|
1626
|
+
|
|
1627
|
+
**Investigator agent — mandatory session history search** (`.claude/agents/investigator.md`):
|
|
1628
|
+
- Added "Claude Session History (MANDATORY)" section with a table of `mcp__claude-sessions__*` tools (`search_sessions`, `list_sessions`, `read_session`)
|
|
1629
|
+
- Session history search is now step 1 in the Investigation Workflow (was previously absent); all subsequent steps shifted from 1-7 to 2-8
|
|
1630
|
+
- Prevents circular re-investigation of previously-explored issues and surfaces decisions not captured in code or docs
|
|
1631
|
+
|
|
1632
|
+
### Why This Matters
|
|
1633
|
+
|
|
1634
|
+
**Deputy-CTO identity**: Previously, `/deputy-cto` sessions ran Claude as a generic assistant following the command's session flow instructions. The deputy-cto agent's commit review criteria, decision framework, powers, and operating modes were only available in autonomous (pre-commit hook) contexts. Now both paths use the same identity and knowledge base, giving interactive CTO briefing sessions the full context they need to accurately represent the agent's standing policies and decision criteria.
|
|
1635
|
+
|
|
1636
|
+
**Investigator session history**: AI agents frequently re-investigate the same problems across sessions. The mandatory session history step surfaces prior work, failed approaches, and decisions before the agent spends time rediscovering them.
|
|
1637
|
+
|
|
1638
|
+
### Audit
|
|
1639
|
+
|
|
1640
|
+
All 10 slash commands were audited. The remaining 8 commands already follow their correct patterns and required no changes.
|
|
1641
|
+
|
|
1642
|
+
**Files Modified (3 total):**
|
|
1643
|
+
- `.claude/hooks/slash-command-prefetch.js` - ~12 lines added to `handleDeputyCto()`
|
|
1644
|
+
- `.claude/commands/deputy-cto.md` - ~8 lines added (new "Your Identity" section)
|
|
1645
|
+
- `.claude/agents/investigator.md` - ~25 lines added (mandatory session history section and workflow reorder)
|
|
1646
|
+
|
|
1647
|
+
---
|
|
1648
|
+
|
|
1649
|
+
## 2026-02-17 - CTO Dashboard: Elastic/Elasticsearch Integration Fixes
|
|
1650
|
+
|
|
1651
|
+
### Fixed
|
|
1652
|
+
|
|
1653
|
+
**Elasticsearch field mapping errors** (`packages/cto-dashboard/src/utils/logging-reader.ts`, `packages/cto-dashboard/src/utils/infra-reader.ts`):
|
|
1654
|
+
- Terms aggregations were failing with HTTP 400 errors because fields (`level`, `service`, `module`) are mapped as `text` type in the Elastic Serverless deployment and require the `.keyword` suffix for aggregations
|
|
1655
|
+
- Updated all terms aggregation fields: `level` -> `level.keyword`, `service` -> `service.keyword`, `module` -> `module.keyword`
|
|
1656
|
+
- Updated term filter fields in top-errors and top-warnings queries to use `level.keyword`
|
|
1657
|
+
|
|
1658
|
+
**Elasticsearch endpoint resolution** (`packages/cto-dashboard/src/utils/credentials.ts`):
|
|
1659
|
+
- Dashboard previously only looked for `ELASTIC_ENDPOINT`; Elastic Cloud hosted deployments use `ELASTIC_CLOUD_ID` (base64-encoded Cloud ID format) instead
|
|
1660
|
+
- Added `resolveElasticEndpoint()` helper: tries `ELASTIC_ENDPOINT` first, then decodes `ELASTIC_CLOUD_ID` (splits on `:`, base64-decodes the second segment, extracts the ES host from the `$`-delimited decoded string)
|
|
1661
|
+
- Both `logging-reader.ts` and `infra-reader.ts` updated to call `resolveElasticEndpoint()` instead of `resolveCredential('ELASTIC_ENDPOINT')` directly
|
|
1662
|
+
|
|
1663
|
+
**Storage estimation 403 fallback** (`packages/cto-dashboard/src/utils/logging-reader.ts`):
|
|
1664
|
+
- `queryStorage()` was calling `_cat/indices` which requires the `monitor` cluster privilege; the read-only API key returns 403
|
|
1665
|
+
- On a 403 response `queryStorage()` now falls back to doc-count estimation (total document count × estimated bytes-per-doc) instead of returning null storage data
|
|
1666
|
+
|
|
1667
|
+
### Added
|
|
1668
|
+
|
|
1669
|
+
**`ELASTIC_API_KEY_WRITE` vault mapping** (`vault-mappings.json`):
|
|
1670
|
+
- Added mapping for write-capable Elastic API key to support log ingestion use cases
|
|
1671
|
+
- Read-only key (`ELASTIC_API_KEY`) continues to be used by dashboard queries
|
|
1672
|
+
|
|
1673
|
+
**Sample log data seeding:**
|
|
1674
|
+
- Ingested 200 realistic sample log entries into the Elastic Serverless deployment covering multiple services, levels, and modules
|
|
1675
|
+
- Verified all dashboard queries (timeseries, level/service breakdowns, top errors/warnings) return correct data after seeding
|
|
1676
|
+
|
|
1677
|
+
### Tests
|
|
1678
|
+
|
|
1679
|
+
- 47 new tests in `packages/cto-dashboard/src/utils/__tests__/credentials.test.ts` covering:
|
|
1680
|
+
- `resolveElasticEndpoint()`: `ELASTIC_ENDPOINT` priority, `ELASTIC_CLOUD_ID` base64 decode path, malformed Cloud ID handling
|
|
1681
|
+
- `.keyword` field naming: all aggregation and filter fields use the `.keyword` suffix
|
|
1682
|
+
- Storage 403 fallback: `queryStorage()` returns doc-count estimate when `_cat/indices` is unauthorized
|
|
1683
|
+
- All 545 tests pass across 16 test files (up from 498)
|
|
1684
|
+
- TypeScript builds clean
|
|
1685
|
+
- Code review: PASS, no violations
|
|
1686
|
+
|
|
1687
|
+
**Total Changes:** 3 modified files, 1 vault-mappings.json update, 47 new tests, 545 total tests passing
|
|
1688
|
+
|
|
1689
|
+
---
|
|
1690
|
+
|
|
1691
|
+
## 2026-02-17 - CTO Dashboard: Layout Fixes, Environment-Based Deployments, Title-in-Border
|
|
1692
|
+
|
|
1693
|
+
### Changed
|
|
1694
|
+
|
|
1695
|
+
**Section Component — Title-in-Border Rendering** (`packages/cto-dashboard/src/components/Section.tsx`):
|
|
1696
|
+
- Sections now render titles inline in the top border: `╭─ TITLE ──────╮`
|
|
1697
|
+
- Uses `borderTop={false}` on the inner Box and a custom Text element for the top line
|
|
1698
|
+
- All sections across the dashboard use this style automatically when a title prop is provided
|
|
1699
|
+
|
|
1700
|
+
**Deployments Section Restructure** (`packages/cto-dashboard/src/components/DeploymentsSection.tsx`, `packages/cto-dashboard/src/utils/deployments-reader.ts`):
|
|
1701
|
+
- Added `DeployEnvironment` type (`preview | staging | production`) and `inferEnvironment()` function to `deployments-reader.ts`
|
|
1702
|
+
- `inferEnvironment()` classifies deploys by service name keywords (`staging`, `stg`, `preview`, `dev`) and Vercel `target` field, defaulting to `production`
|
|
1703
|
+
- Added `byEnvironment` grouping (`preview`, `staging`, `production` arrays, newest-first, up to 5 each) to `DeploymentsData`
|
|
1704
|
+
- Replaced old platform-based layout (ServiceList/Render/Vercel split) with per-environment layout:
|
|
1705
|
+
- `EnvironmentHealth` component: Production/Staging/Preview side-by-side with health dot, last deploy time, and deploy count
|
|
1706
|
+
- `PipelineDetail` component: 3-stage pipeline (preview → staging → production) with check timestamps
|
|
1707
|
+
- `EnvironmentDeploys` per-environment table: time, status dot, service (24w), platform (9w), status (10w), commit message (25w)
|
|
1708
|
+
- `DeployStats` footer: 24h total, success rate, failure count, frequency
|
|
1709
|
+
|
|
1710
|
+
**Infrastructure Section Layout Fix** (`packages/cto-dashboard/src/components/InfraSection.tsx`):
|
|
1711
|
+
- Restructured from 5-column card grid to clean tabular row layout
|
|
1712
|
+
- Aligned columns: Provider (16w) | Status (14w) | Detail (20w) | Extra
|
|
1713
|
+
- Each provider gets one row with consistent alignment and no wrapping
|
|
1714
|
+
|
|
1715
|
+
**Testing Section Chart Fix** (`packages/cto-dashboard/src/components/TestingSection.tsx`):
|
|
1716
|
+
- Changed `yDomain` minimum from `1` to `5` for better chart readability when data values are low
|
|
1717
|
+
|
|
1718
|
+
### Tests
|
|
1719
|
+
|
|
1720
|
+
- 53 new tests in `packages/cto-dashboard/src/utils/__tests__/deployments-reader.test.ts` covering `inferEnvironment`, `normalizeRenderStatus`, `normalizeVercelStatus`, `truncateMessage`, `byEnvironment` grouping, and `stats` computation
|
|
1721
|
+
- Fixed timing-sensitive `UsageTrends` test regex
|
|
1722
|
+
- All 498 tests pass across 15 test files
|
|
1723
|
+
- TypeScript builds clean
|
|
1724
|
+
|
|
1725
|
+
### Code Review
|
|
1726
|
+
|
|
1727
|
+
- All changes pass review with no violations
|
|
1728
|
+
- No mocked/placeholder code, no credential leaks, no security regressions
|
|
1729
|
+
- Pre-existing pattern noted: external API responses use TypeScript `as` casts rather than Zod validation (systemic, not a regression)
|
|
1730
|
+
|
|
1731
|
+
**Total Changes:** 4 modified files, 53 new tests, 498 total tests passing
|
|
1732
|
+
|
|
1733
|
+
---
|
|
1734
|
+
|
|
1735
|
+
## 2026-02-17 - Usage Optimizer and CTO Dashboard Bug Fixes
|
|
1736
|
+
|
|
1737
|
+
### Fixed
|
|
1738
|
+
|
|
1739
|
+
**Three interconnected bugs causing all automated instances to display "+100% slower":**
|
|
1740
|
+
|
|
1741
|
+
1. **Runaway 7-day projection** (`.claude/hooks/usage-optimizer.js`)
|
|
1742
|
+
- Linear rate extrapolation over long horizons (e.g. 155h remaining until 7d reset) was
|
|
1743
|
+
producing projections as high as 483%, which slammed the optimizer factor to MIN_FACTOR (0.5)
|
|
1744
|
+
and kept it there permanently — causing all automation cooldowns to double
|
|
1745
|
+
- Fix: Added `MAX_PROJECTION = 1.5` cap on both `projected5h` and `projected7d` to prevent
|
|
1746
|
+
linear extrapolation from producing nonsensical values
|
|
1747
|
+
|
|
1748
|
+
2. **No factor recovery** (`.claude/hooks/usage-optimizer.js`)
|
|
1749
|
+
- Once the factor reached MIN_FACTOR (0.5), the 10% MAX_CHANGE_PER_CYCLE limit prevented
|
|
1750
|
+
recovery as long as the inflated projection kept pushing the factor down each cycle
|
|
1751
|
+
- Fix: Added recovery clause — when factor is stuck at MIN_FACTOR AND current usage is below
|
|
1752
|
+
45% (half of the 90% target), the factor is reset to 1.0 and adjustment resumes normally
|
|
1753
|
+
|
|
1754
|
+
3. **Wrong display unit for projected_at_reset** (`packages/cto-dashboard/src/utils/automated-instances.ts`)
|
|
1755
|
+
- `projected_at_reset` is stored as a 0-1 fraction but was passed directly to the Footer
|
|
1756
|
+
component which expected a percentage integer — showing "5%" instead of "483%"
|
|
1757
|
+
- Fix: Multiply `projected_at_reset` by 100 when assigning to `currentProjected`
|
|
1758
|
+
|
|
1759
|
+
### Tests
|
|
1760
|
+
|
|
1761
|
+
- 11 new tests in `usage-optimizer.test.js` covering projection cap enforcement and factor recovery
|
|
1762
|
+
- 10 new tests in `automated-instances.test.ts` covering `currentProjected` unit conversion
|
|
1763
|
+
- All 54 automated-instances tests pass; all 132 usage-optimizer tests pass
|
|
1764
|
+
- Code review: all 3 changes approved with no violations
|
|
1765
|
+
|
|
1766
|
+
**Total Changes:** 2 files modified, 21 new tests
|
|
1767
|
+
|
|
1768
|
+
---
|
|
1769
|
+
|
|
1770
|
+
## 2026-02-17 - CTO Dashboard: Deployments, Infrastructure, and Logging Overhaul
|
|
1771
|
+
|
|
1772
|
+
### Added
|
|
1773
|
+
|
|
1774
|
+
**Deployments Section Overhaul** (`packages/cto-dashboard/src/components/DeploymentsSection.tsx`, `packages/cto-dashboard/src/utils/deployments-reader.ts`):
|
|
1775
|
+
- `PipelineDetail` component at the top showing a 3-stage pipeline (preview → staging → production) with timestamps
|
|
1776
|
+
- Per-platform deploy tables: Render and Vercel each display 5 most recent deploys with service name (width 20), status, age (width 9), and commit message (width 30, constrained)
|
|
1777
|
+
- `DeployStats` footer row: total deploy count, success rate, failure count, and deploy frequency
|
|
1778
|
+
- `deployments-reader.ts` enriched with `lastPreviewCheck`, `lastStagingCheck`, and stats computation from deploy history
|
|
1779
|
+
|
|
1780
|
+
**Infrastructure Section Overhaul** (`packages/cto-dashboard/src/components/InfraSection.tsx`, `packages/cto-dashboard/src/utils/infra-reader.ts`):
|
|
1781
|
+
- Per-platform event tables: Render deploy events and Vercel deployment events
|
|
1782
|
+
- Load metrics: Render `lastDeployAt`, Vercel `buildingCount`, Cloudflare `planName`
|
|
1783
|
+
- Cloudflare nameserver list added to display
|
|
1784
|
+
- Elasticsearch detail row removed from InfraSection (moved to dedicated LOGGING section)
|
|
1785
|
+
- `InfraSection` now accepts optional `deployments` prop to avoid duplicate Render/Vercel API calls
|
|
1786
|
+
- Credential bug fixed: `CF_API_TOKEN` corrected to `CLOUDFLARE_API_TOKEN` (line 145 of `infra-reader.ts`)
|
|
1787
|
+
|
|
1788
|
+
**New LOGGING Section** (`packages/cto-dashboard/src/utils/logging-reader.ts`, `packages/cto-dashboard/src/components/LoggingSection.tsx`):
|
|
1789
|
+
- `logging-reader.ts`: Elasticsearch queries for 24h volume timeseries (24 hourly buckets), level/service/source breakdowns, top 5 errors, top 5 warnings, storage estimates via `_cat/indices`, and source coverage assessment for 9 expected sources (api, worker, deployment, ci-cd, testing, database, cdn, auth, cron)
|
|
1790
|
+
- `LoggingSection.tsx`: Full section with LineGraph (volume timeseries), BarCharts (by level, by service), top errors/warnings tables, source coverage dot indicators (active/low-volume/missing), and storage footer
|
|
1791
|
+
- Wired into `index.tsx` via `getLoggingData` in `Promise.allSettled` parallel fetch block
|
|
1792
|
+
- Wired into `App.tsx` between `InfraSection` and `FeedbackPersonas`
|
|
1793
|
+
- Exported from `components/index.ts`
|
|
1794
|
+
|
|
1795
|
+
### Tests
|
|
1796
|
+
|
|
1797
|
+
- 45 new tests in `packages/cto-dashboard/src/utils/__tests__/logging-reader.test.ts` covering `parseSizeToBytes`, `assessSourceCoverage`, credential absence, storage estimation, `hasData` flag, and volumeTimeseries padding
|
|
1798
|
+
- New `packages/cto-dashboard/src/components/__tests__/AutomatedInstances.test.tsx` — 35 tests (created in preceding session)
|
|
1799
|
+
- All 445 tests pass across 14 test files
|
|
1800
|
+
- TypeScript build compiles clean
|
|
1801
|
+
|
|
1802
|
+
### Code Review Findings (informational, not blocking)
|
|
1803
|
+
|
|
1804
|
+
- Duplicated `truncate`/`statusColor` utilities across 3 component files — candidate for shared `formatters.ts` extraction
|
|
1805
|
+
- Render `updatedAt` used as proxy for `lastDeployAt` (documented with inline comment)
|
|
1806
|
+
- URL validation on trusted credential store values (informational)
|
|
1807
|
+
|
|
1808
|
+
**Total Changes:** 3 new files, 7 modified files, 445 tests passing
|
|
1809
|
+
|
|
1810
|
+
---
|
|
1811
|
+
|
|
1812
|
+
## 2026-02-17 - CTO Dashboard: Token Usage Bar Chart and Testing Section Fixes
|
|
1813
|
+
|
|
1814
|
+
### Added
|
|
1815
|
+
|
|
1816
|
+
**Automated Instances — Token Usage Bar Chart:**
|
|
1817
|
+
|
|
1818
|
+
1. **Token usage by automation type** (`packages/cto-dashboard/src/utils/automated-instances.ts`)
|
|
1819
|
+
- New `getAutomationTokenUsage()` async function reads session JSONL files from `~/.claude/projects/`
|
|
1820
|
+
- Extracts `[Task][agent-type]` prefix from the first user message to identify automation sessions
|
|
1821
|
+
- Sums all token usage fields (input, output, cache read, cache creation) per session
|
|
1822
|
+
- Rolls up raw agent types into INSTANCE_DEFINITIONS display names
|
|
1823
|
+
- Helper functions: `getSessionDir()`, `buildAgentTypeToDisplayName()`, `SessionEntry` interface
|
|
1824
|
+
- `tokensByType: Record<string, number>` field added to `AutomatedInstancesData` type
|
|
1825
|
+
|
|
1826
|
+
2. **Bar chart rendering** (`packages/cto-dashboard/src/components/AutomatedInstances.tsx`)
|
|
1827
|
+
- Horizontal bar chart (via `@pppp606/ink-chart` `BarChart`) rendered between Footer and Tip
|
|
1828
|
+
- Conditionally shown only when `tokensByType` has entries
|
|
1829
|
+
- Values sorted descending, formatted with `formatNumber()`
|
|
1830
|
+
- Title: "Token Usage by Automation (24h)"
|
|
1831
|
+
|
|
1832
|
+
3. **Async data integration** (`packages/cto-dashboard/src/index.tsx`)
|
|
1833
|
+
- `getAutomationTokenUsage` added to `Promise.allSettled` parallel fetch block
|
|
1834
|
+
- Result merged into `automatedInstances.tokensByType` on success
|
|
1835
|
+
|
|
1836
|
+
### Fixed
|
|
1837
|
+
|
|
1838
|
+
**Testing Section agent breakdown display** (`packages/cto-dashboard/src/components/TestingSection.tsx`):
|
|
1839
|
+
- Removed Jest from agent breakdown (not used by any agent type in testing-reader)
|
|
1840
|
+
- Expanded "PW" abbreviation to full "Playwright" label
|
|
1841
|
+
- Column width adjustments: COL_NAME 35→34, COL_AGE 9→10, COL_FW 9→11 for better alignment
|
|
1842
|
+
|
|
1843
|
+
### Tests
|
|
1844
|
+
|
|
1845
|
+
- **New:** `packages/cto-dashboard/src/components/__tests__/AutomatedInstances.test.tsx` — 35 tests covering empty state, table structure, footer, bar chart rendering, run counts, freq adjustments, until-next display, and render consistency
|
|
1846
|
+
- **Updated:** `automated-instances.test.ts` — added `tokensByType` shape validation, 2 new describe blocks (11 tests) for JSONL parsing logic
|
|
1847
|
+
- **Updated:** `TestingSection.test.tsx` — removed Jest assertions, uses "Playwright" label, updated zero-counts test data
|
|
1848
|
+
- All 390 tests pass across 13 test files (up from 343/12)
|
|
1849
|
+
- TypeScript build compiles clean
|
|
1850
|
+
|
|
1851
|
+
**Total Changes:** 1 new test file, 5 modified files, 390 tests passing
|
|
1852
|
+
|
|
1853
|
+
---
|
|
1854
|
+
|
|
1855
|
+
## 2026-02-17 - CTO Dashboard: Deployments, Infrastructure, and Testing Graph
|
|
1856
|
+
|
|
1857
|
+
### Added
|
|
1858
|
+
|
|
1859
|
+
**CTO Dashboard — New Sections and Shared Utilities:**
|
|
1860
|
+
|
|
1861
|
+
1. **Shared credential resolution module** (`packages/cto-dashboard/src/utils/credentials.ts`)
|
|
1862
|
+
- Common `resolveCredential()` function: env var → vault-mappings.json → `op read` chain
|
|
1863
|
+
- Shared `fetchWithTimeout()` helper used by all data readers
|
|
1864
|
+
- `loadOpTokenFromMcpJson()` for headless token resolution
|
|
1865
|
+
|
|
1866
|
+
2. **Deployments data reader** (`packages/cto-dashboard/src/utils/deployments-reader.ts`)
|
|
1867
|
+
- Fetches Render services and deploys, Vercel projects and deployments in parallel
|
|
1868
|
+
- All calls via `Promise.allSettled` with 10s timeouts (independently degradable)
|
|
1869
|
+
- Reads pipeline promotion state from local automation state file
|
|
1870
|
+
- Combines and sorts deploys from both platforms (newest first, up to 8)
|
|
1871
|
+
|
|
1872
|
+
3. **Infrastructure health reader** (`packages/cto-dashboard/src/utils/infra-reader.ts`)
|
|
1873
|
+
- 5-provider health queries: Render, Vercel, Supabase, Elasticsearch, Cloudflare
|
|
1874
|
+
- Each provider independently degradable — missing credentials or API failures return `{ available: false }`
|
|
1875
|
+
- Elasticsearch aggregation query returns 1h log totals, error/warn counts, top services
|
|
1876
|
+
|
|
1877
|
+
4. **DeploymentsSection component** (`packages/cto-dashboard/src/components/DeploymentsSection.tsx`)
|
|
1878
|
+
- Side-by-side Render service list and Vercel project list
|
|
1879
|
+
- Combined recent deploy timeline with platform badge and status color
|
|
1880
|
+
- Pipeline promotion state footer
|
|
1881
|
+
|
|
1882
|
+
5. **InfraSection component** (`packages/cto-dashboard/src/components/InfraSection.tsx`)
|
|
1883
|
+
- 5-provider health status row with colored dots
|
|
1884
|
+
- Elasticsearch logs detail row when available
|
|
1885
|
+
|
|
1886
|
+
### Modified
|
|
1887
|
+
|
|
1888
|
+
6. **TestingSection** (`packages/cto-dashboard/src/components/TestingSection.tsx`)
|
|
1889
|
+
- Replaced old 7-day sparkline with LineGraph using 42 x 4h buckets for higher resolution
|
|
1890
|
+
- Codecov sparkline retained
|
|
1891
|
+
|
|
1892
|
+
7. **testing-reader.ts** (`packages/cto-dashboard/src/utils/testing-reader.ts`)
|
|
1893
|
+
- Added `testActivityTimeseries` field (42 buckets, 4h resolution, ~7-day window)
|
|
1894
|
+
- Switched to shared credentials module
|
|
1895
|
+
|
|
1896
|
+
8. **App.tsx** — Renders DeploymentsSection and InfraSection between Testing and FeedbackPersonas
|
|
1897
|
+
|
|
1898
|
+
9. **index.tsx** — Fetches deployments and infra data in parallel at startup
|
|
1899
|
+
|
|
1900
|
+
10. **components/index.ts** — Added exports for DeploymentsSection and InfraSection
|
|
1901
|
+
|
|
1902
|
+
### Fixed
|
|
1903
|
+
|
|
1904
|
+
- **Vercel availability bug** (`infra-reader.ts`): `errorDeploys >= 0` always-true check replaced with `available: true` inside success path
|
|
1905
|
+
|
|
1906
|
+
### Tests
|
|
1907
|
+
|
|
1908
|
+
- Updated 3 test cases in `TestingSection.test.tsx` to match LineGraph (replaces sparkline)
|
|
1909
|
+
- All 343 tests pass across 12 test files
|
|
1910
|
+
- TypeScript build compiles clean
|
|
1911
|
+
|
|
1912
|
+
**Total Changes:** 5 new files, 5 modified files, 343 tests passing
|
|
1913
|
+
|
|
1914
|
+
---
|
|
1915
|
+
|
|
1916
|
+
## 2026-02-16 - CTO Dashboard Trajectory Forecast Graph
|
|
1917
|
+
|
|
1918
|
+
### Added
|
|
1919
|
+
|
|
1920
|
+
**Visual Trajectory Forecasting:**
|
|
1921
|
+
|
|
1922
|
+
1. **Trajectory Forecast Chart** (UsageTrends component)
|
|
1923
|
+
- Combined visualization showing historical usage transitioning to linear projections
|
|
1924
|
+
- 3 series: cyan 5h line, magenta 7d line, gray 90% target overlay
|
|
1925
|
+
- X-axis labels: "[timeAgo] → now → reset: Xh" to separate history from forecast
|
|
1926
|
+
- Projection point generation using linear extrapolation clamped to [0, 100]
|
|
1927
|
+
- Graceful degradation (only renders when projection data exists)
|
|
1928
|
+
|
|
1929
|
+
### Fixed
|
|
1930
|
+
|
|
1931
|
+
**Multi-Account Reset Time Bug:**
|
|
1932
|
+
- Previously: `trajectory.ts` arbitrarily took the last API key's reset time during iteration
|
|
1933
|
+
- Now: Picks the **earliest** reset time across all keys (most conservative estimate for aggregate quota tracking)
|
|
1934
|
+
|
|
1935
|
+
### Modified
|
|
1936
|
+
|
|
1937
|
+
**Files Changed (3 total):**
|
|
1938
|
+
- `packages/cto-dashboard/src/utils/trajectory.ts` (lines 174-175) - Fixed reset time selection logic
|
|
1939
|
+
- `packages/cto-dashboard/src/components/UsageTrends.tsx` - Added forecast chart with projection helpers
|
|
1940
|
+
- `packages/cto-dashboard/src/App.tsx` - Updated props from `{snapshots, hasData}` to `{trajectory: TrajectoryResult}`
|
|
1941
|
+
|
|
1942
|
+
**Tests Added (2 files, 48 tests):**
|
|
1943
|
+
- `packages/cto-dashboard/src/utils/__tests__/trajectory.test.ts` (21 tests)
|
|
1944
|
+
- `packages/cto-dashboard/src/components/__tests__/UsageTrends.test.tsx` (27 tests)
|
|
1945
|
+
|
|
1946
|
+
**Documentation:**
|
|
1947
|
+
- `docs/Executive.md` - Updated Usage Trends section to describe forecast chart and distinguish from text-based trajectory section
|
|
1948
|
+
|
|
1949
|
+
**Total Changes:** +165 lines added, 3 files modified, 48 tests added, 330 total tests passing
|
|
1950
|
+
|
|
1951
|
+
---
|
|
1952
|
+
|
|
1953
|
+
## 2026-02-16 - Multi-Layer Credential Detection
|
|
1954
|
+
|
|
1955
|
+
### Added
|
|
1956
|
+
|
|
1957
|
+
**4-Layer Credential Detection Architecture:**
|
|
1958
|
+
|
|
1959
|
+
1. **Shared Key Sync Module** (`key-sync.js`)
|
|
1960
|
+
- Multi-source credential reading (env var, macOS Keychain, credentials file)
|
|
1961
|
+
- User-level rotation state I/O at `~/.claude/api-key-rotation.json`
|
|
1962
|
+
- OAuth token refresh for expired credentials
|
|
1963
|
+
- Subscription tier detection (Free, Pro, Team)
|
|
1964
|
+
- Rate limit tier tracking (tier-1 through tier-5)
|
|
1965
|
+
|
|
1966
|
+
2. **Detection Layers**
|
|
1967
|
+
- Layer 1: launchd `WatchPaths` - instant file change detection on `~/.claude/.credentials.json`
|
|
1968
|
+
- Layer 2: 10-minute `StartInterval` - automation service key-sync calls
|
|
1969
|
+
- Layer 3: SessionStart hook (`api-key-watcher.js`) - full discovery on Claude Code start
|
|
1970
|
+
- Layer 4: PreToolUse hook (`credential-sync-hook.js`) - throttled mid-session checks (30-min)
|
|
1971
|
+
|
|
1972
|
+
3. **Key Features**
|
|
1973
|
+
- Aggregates credentials from all sources without short-circuiting
|
|
1974
|
+
- Shared rotation state registry across all projects (user-level)
|
|
1975
|
+
- Per-project rotation event logging
|
|
1976
|
+
- Automatic OAuth token refresh before expiration
|
|
1977
|
+
- Health checks and capacity alerts
|
|
1978
|
+
|
|
1979
|
+
**Files Created (2 total):**
|
|
1980
|
+
- `.claude/hooks/key-sync.js` (328 lines) - Shared credential detection module
|
|
1981
|
+
- `.claude/hooks/credential-sync-hook.js` (80 lines) - Throttled PreToolUse hook
|
|
1982
|
+
|
|
1983
|
+
**Files Modified (11 total):**
|
|
1984
|
+
- `.claude/hooks/api-key-watcher.js` - Refactored to thin wrapper around key-sync.js (v2.0.0)
|
|
1985
|
+
- `.claude/hooks/usage-optimizer.js` - Updated rotation state path to user-level
|
|
1986
|
+
- `.claude/hooks/cto-notification-hook.js` - Updated rotation state path
|
|
1987
|
+
- `.claude/hooks/credential-file-guard.js` - Added comment about user-level path coverage
|
|
1988
|
+
- `.claude/hooks/hourly-automation.js` - Added key-sync step after usage optimizer
|
|
1989
|
+
- `.claude/settings.json.template` - Added credential-sync-hook PreToolUse entry
|
|
1990
|
+
- `scripts/setup-automation-service.sh` - Added WatchPaths to launchd plist template
|
|
1991
|
+
- `packages/cto-dashboard/src/utils/data-reader.ts` - Updated rotation state path
|
|
1992
|
+
- `packages/mcp-servers/src/cto-report/server.ts` - Updated rotation state path
|
|
1993
|
+
- `.claude/hooks/__tests__/api-key-watcher.test.js` - Multiple test updates (75 tests passing)
|
|
1994
|
+
- `.claude/hooks/__tests__/usage-optimizer.test.js` - Updated assertion (107 tests passing)
|
|
1995
|
+
|
|
1996
|
+
**Documentation:**
|
|
1997
|
+
- `docs/CREDENTIAL-DETECTION.md` - Test coverage details for 4-layer architecture
|
|
1998
|
+
- `README.md` - Added Multi-Layer Credential Detection section
|
|
1999
|
+
- `CLAUDE.md` - (unchanged, no agent-facing updates needed)
|
|
2000
|
+
|
|
2001
|
+
**Total Changes:** +408 lines added, 11 files modified, 182 tests passing
|
|
2002
|
+
|
|
2003
|
+
### Code Review Findings
|
|
2004
|
+
|
|
2005
|
+
**9 Issues Identified:**
|
|
2006
|
+
|
|
2007
|
+
1. **CRITICAL**: Plaintext token aggregation without restrictive file permissions
|
|
2008
|
+
2. **HIGH**: Race condition on rotation state file (3 concurrent callers, no file locking)
|
|
2009
|
+
3. **HIGH**: Missing Zod validation on external API responses (OAuth token endpoint)
|
|
2010
|
+
4. **MEDIUM**: Timeout mismatch in credential-sync-hook (5s timeout but OAuth refresh can exceed)
|
|
2011
|
+
5. **MEDIUM**: Error swallowing in key-sync.js catch blocks (no telemetry)
|
|
2012
|
+
6. **MEDIUM**: No retry logic for transient Keychain failures
|
|
2013
|
+
7. **LOW**: Magic number for throttle cooldown (30 * 60 * 1000 should be constant)
|
|
2014
|
+
8. **LOW**: Missing JSDoc for public functions in key-sync.js
|
|
2015
|
+
9. **LOW**: No telemetry for credential source usage patterns
|
|
2016
|
+
|
|
2017
|
+
### Test Coverage
|
|
2018
|
+
|
|
2019
|
+
**Coverage Status:**
|
|
2020
|
+
- `api-key-watcher.js` - 75 tests passing (full coverage)
|
|
2021
|
+
- `usage-optimizer.js` - 107 tests passing (full coverage)
|
|
2022
|
+
- `key-sync.js` - 0% coverage (new module, tests recommended)
|
|
2023
|
+
- `credential-sync-hook.js` - 0% coverage (new hook, tests recommended)
|
|
2024
|
+
|
|
2025
|
+
**Coverage Gaps:**
|
|
2026
|
+
- `refreshExpiredToken()` - 0% coverage (security-critical OAuth flow)
|
|
2027
|
+
- `updateActiveCredentials()` - 0% behavioral coverage (dual-write to state)
|
|
2028
|
+
- `readCredentialSources()` - indirect coverage only
|
|
2029
|
+
- Recommendation: Create `.claude/hooks/__tests__/key-sync.test.js`
|
|
2030
|
+
|
|
2031
|
+
### Architecture Decisions
|
|
2032
|
+
|
|
2033
|
+
**Why user-level rotation state:**
|
|
2034
|
+
- Supports multi-project workflows (same API key across multiple repos)
|
|
2035
|
+
- Prevents state desync when same key used in multiple projects
|
|
2036
|
+
- Enables global key tracking and quota aggregation
|
|
2037
|
+
- Backward compatible with project-level fallback
|
|
2038
|
+
|
|
2039
|
+
**Why 4 detection layers:**
|
|
2040
|
+
- Layer 1 (WatchPaths): Instant response to file changes (macOS only)
|
|
2041
|
+
- Layer 2 (StartInterval): Cross-platform periodic checks
|
|
2042
|
+
- Layer 3 (SessionStart): Initial discovery on new sessions
|
|
2043
|
+
- Layer 4 (PreToolUse): Detects mid-session changes without restart
|
|
2044
|
+
|
|
2045
|
+
**Why shared key-sync module:**
|
|
2046
|
+
- DRY principle (single source of truth for credential logic)
|
|
2047
|
+
- Consistent behavior across all detection layers
|
|
2048
|
+
- Easier testing and maintenance
|
|
2049
|
+
- Supports future OAuth flow changes
|
|
2050
|
+
|
|
2051
|
+
---
|
|
2052
|
+
|
|
2053
|
+
## 2026-02-16 - Chrome Extension Bridge
|
|
2054
|
+
|
|
2055
|
+
### Added
|
|
2056
|
+
|
|
2057
|
+
**Chrome Bridge MCP Server:**
|
|
2058
|
+
|
|
2059
|
+
1. **Protocol Reverse Engineering**
|
|
2060
|
+
- Extracted Claude for Chrome extension protocol from Claude Desktop app.asar
|
|
2061
|
+
- Discovered Unix domain socket bridge at `/tmp/claude-mcp-browser-bridge-{username}/*.sock`
|
|
2062
|
+
- Binary framing protocol: 4-byte LE uint32 length prefix + UTF-8 JSON payload
|
|
2063
|
+
- Archived extraction to `~/Documents/archives/claude-desktop-app-extract-2026-02-16/`
|
|
2064
|
+
|
|
2065
|
+
2. **18 Chrome Extension Tools**
|
|
2066
|
+
- **Tab management** (4): `tabs_context_mcp`, `tabs_create_mcp`, `navigate`, `switch_browser`
|
|
2067
|
+
- **Page interaction** (6): `read_page`, `get_page_text`, `find`, `form_input`, `computer`, `javascript_tool`
|
|
2068
|
+
- **Debugging** (2): `read_console_messages`, `read_network_requests`
|
|
2069
|
+
- **Media** (3): `gif_creator`, `upload_image`, `resize_window`
|
|
2070
|
+
- **Workflows** (3): `shortcuts_list`, `shortcuts_execute`, `update_plan`
|
|
2071
|
+
|
|
2072
|
+
3. **Standalone MCP Server** (`chrome-bridge`)
|
|
2073
|
+
- Pure proxy architecture (no Zod validation, Chrome handles its own validation)
|
|
2074
|
+
- Multi-socket support (connects to all available Chrome instances)
|
|
2075
|
+
- Tab routing (remembers which socket owns which tab)
|
|
2076
|
+
- Connection resilience (exponential backoff, max 100 reconnect attempts)
|
|
2077
|
+
- Request serialization (per-socket queuing prevents response interleaving)
|
|
2078
|
+
- Proper timeout handling (2s for tabs_context_mcp, 120s for other tools)
|
|
2079
|
+
- Windows-compatible (null-safe `process.getuid` check)
|
|
2080
|
+
|
|
2081
|
+
4. **Integration**
|
|
2082
|
+
- Added to `.mcp.json.template` as direct server (no launcher needed)
|
|
2083
|
+
- Added `mcp-chrome-bridge` bin entry to package.json
|
|
2084
|
+
- Re-exported as ChromeBridge in packages/mcp-servers/src/index.ts
|
|
2085
|
+
|
|
2086
|
+
### Technical Details
|
|
2087
|
+
|
|
2088
|
+
**Files Created (3 total):**
|
|
2089
|
+
- `packages/mcp-servers/src/chrome-bridge/types.ts` (51 lines) - Protocol types
|
|
2090
|
+
- `packages/mcp-servers/src/chrome-bridge/server.ts` (997 lines) - Socket client + JSON-RPC server
|
|
2091
|
+
- `packages/mcp-servers/src/chrome-bridge/index.ts` (4 lines) - Re-exports
|
|
2092
|
+
|
|
2093
|
+
**Files Modified:**
|
|
2094
|
+
- `packages/mcp-servers/package.json` - Added bin entry
|
|
2095
|
+
- `.mcp.json.template` - Added chrome-bridge server config
|
|
2096
|
+
- `packages/mcp-servers/src/index.ts` - Added ChromeBridge export
|
|
2097
|
+
- `README.md` - Updated server count, directory structure, MCP server list, version history
|
|
2098
|
+
- `CLAUDE.md` - Added Chrome Browser Automation section
|
|
2099
|
+
|
|
2100
|
+
**Total Changes:** +1,052 lines added
|
|
2101
|
+
|
|
2102
|
+
### Testing
|
|
2103
|
+
|
|
2104
|
+
**Manual Testing:**
|
|
2105
|
+
- TypeScript compilation: Clean
|
|
2106
|
+
- MCP server initialization: Successful
|
|
2107
|
+
- Live connection test: Retrieved tab context from 9 Chrome tabs
|
|
2108
|
+
- Socket discovery: Detected Chrome extension socket
|
|
2109
|
+
- Tool execution: `tabs_context_mcp` returned complete tab list
|
|
2110
|
+
|
|
2111
|
+
### Architecture Decisions
|
|
2112
|
+
|
|
2113
|
+
**Why not use McpServer base class:**
|
|
2114
|
+
- Chrome extension handles its own validation (no need for Zod schemas)
|
|
2115
|
+
- Binary content support (screenshots) incompatible with text-only base class
|
|
2116
|
+
- Proxy pattern requires custom content normalization
|
|
2117
|
+
- Simpler to implement raw JSON-RPC for pure proxy use case
|
|
2118
|
+
|
|
2119
|
+
**Security:**
|
|
2120
|
+
- Socket ownership validation (only connects to user's own sockets via UID check)
|
|
2121
|
+
- No credential storage (local socket communication only)
|
|
2122
|
+
- Fail-safe reconnection logic (prevents infinite loops)
|
|
2123
|
+
|
|
2124
|
+
### Use Cases
|
|
2125
|
+
|
|
2126
|
+
**Example: Multi-Browser Testing**
|
|
2127
|
+
- Developer has Chrome instances on multiple displays
|
|
2128
|
+
- chrome-bridge discovers all sockets automatically
|
|
2129
|
+
- Routes tab operations to correct browser instance
|
|
2130
|
+
- Maintains tab-to-socket mapping for efficient targeting
|
|
2131
|
+
|
|
2132
|
+
**Example: Long-Running Automation**
|
|
2133
|
+
- Browser crashes mid-automation
|
|
2134
|
+
- Socket connection lost
|
|
2135
|
+
- chrome-bridge reconnects with exponential backoff
|
|
2136
|
+
- Automation resumes when browser restarts
|
|
2137
|
+
|
|
2138
|
+
### Requirements
|
|
2139
|
+
|
|
2140
|
+
- Claude for Chrome extension installed and running
|
|
2141
|
+
- Chrome browser with extension socket active
|
|
2142
|
+
- Unix-like OS with domain socket support (macOS, Linux)
|
|
2143
|
+
|
|
2144
|
+
---
|
|
2145
|
+
|
|
2146
|
+
## 2026-02-15 - MCP Server Thread-Safety Improvements
|
|
2147
|
+
|
|
2148
|
+
### Fixed
|
|
2149
|
+
|
|
2150
|
+
**Feedback System MCP Server Refactoring:**
|
|
2151
|
+
|
|
2152
|
+
1. **Thread-safety in McpServer base class**
|
|
2153
|
+
- Eliminated instance-level mutable state (`_captureMode`, `_capturedResponse`)
|
|
2154
|
+
- Refactored `handleRequest()` and `handleToolCall()` to return responses instead of using side-effect methods
|
|
2155
|
+
- Replaced `sendResponse`/`sendSuccess`/`sendError` with pure `createSuccessResponse`/`createErrorResponse`/`writeResponse`
|
|
2156
|
+
- Updated all 68 tests across server.test.ts and audited-server.test.ts
|
|
2157
|
+
|
|
2158
|
+
2. **Resource cleanup in factories**
|
|
2159
|
+
- Added `process.on('exit')` DB cleanup handler in `createUserFeedbackServer` factory
|
|
2160
|
+
- Removed signal handler leaks from `createFeedbackReporterServer` and `createPlaywrightFeedbackServer`
|
|
2161
|
+
- Moved SIGINT/SIGTERM handlers to auto-start guards only
|
|
2162
|
+
|
|
2163
|
+
3. **Verification**
|
|
2164
|
+
- TypeScript build: clean
|
|
2165
|
+
- Unit tests: 529 passed (16 files)
|
|
2166
|
+
- Integration tests: 21 passed (2 files)
|
|
2167
|
+
- Zero regressions
|
|
2168
|
+
|
|
2169
|
+
**Project Organization:**
|
|
2170
|
+
- Moved Executive.md, STUBBED-PROBLEM.md, and TESTING.md from root to `/docs`
|
|
2171
|
+
- Updated README.md reference to docs/TESTING.md
|
|
2172
|
+
- Root directory now contains only essential files (README, CLAUDE, LICENSE, package files, version.json, and CLAUDE.md.gentyr-section template)
|
|
2173
|
+
|
|
2174
|
+
## 2026-02-15 - AI User Feedback System
|
|
2175
|
+
|
|
2176
|
+
### Added
|
|
2177
|
+
|
|
2178
|
+
**AI User Feedback System (Phase 1-8 complete):**
|
|
2179
|
+
|
|
2180
|
+
1. **Data Layer** - `user-feedback` MCP server
|
|
2181
|
+
- 16 tools for persona/feature CRUD, persona-feature mapping, feedback run lifecycle, and session management
|
|
2182
|
+
- SQLite schema with personas, features, persona_features, feedback_runs, and feedback_sessions tables
|
|
2183
|
+
- Support for 4 consumption modes: gui, cli, api, sdk
|
|
2184
|
+
- Persona cooldown tracking and rate limiting (4h default, max 5 per run)
|
|
2185
|
+
- 43 unit tests passing
|
|
2186
|
+
|
|
2187
|
+
2. **Configuration Interface** - `/configure-personas` slash command
|
|
2188
|
+
- Interactive persona management (create, edit, delete)
|
|
2189
|
+
- Feature registration with file/URL glob patterns
|
|
2190
|
+
- Persona-feature mapping with priority and test scenarios
|
|
2191
|
+
- Dry run: `get_personas_for_changes` previews which personas would trigger
|
|
2192
|
+
|
|
2193
|
+
3. **GUI Testing** - `playwright-feedback` MCP server
|
|
2194
|
+
- 20 user-perspective-only tools (navigate, click, type, screenshot, read_text)
|
|
2195
|
+
- No developer tools (no evaluate_javascript, get_page_source, etc.)
|
|
2196
|
+
- Browser context isolation per session
|
|
2197
|
+
- 34 unit tests passing
|
|
2198
|
+
|
|
2199
|
+
4. **Programmatic Testing** - `programmatic-feedback` MCP server
|
|
2200
|
+
- CLI mode: execFile with shell injection prevention
|
|
2201
|
+
- API mode: HTTP fetch with base URL validation
|
|
2202
|
+
- SDK mode: worker thread sandbox with blocked dangerous modules
|
|
2203
|
+
- 12 tools supporting 3 testing modes
|
|
2204
|
+
- 47 unit tests passing
|
|
2205
|
+
|
|
2206
|
+
5. **Reporting Bridge** - `feedback-reporter` MCP server
|
|
2207
|
+
- Bridges findings from feedback sessions to agent-reports pipeline
|
|
2208
|
+
- Severity-to-priority mapping (critical→critical, high→high, medium→normal, low/info→low)
|
|
2209
|
+
- Persona-named reporting agents (e.g., "feedback-agent [power-user]")
|
|
2210
|
+
- Category: 'user-feedback' (added to REPORT_CATEGORIES)
|
|
2211
|
+
- 21 unit tests passing
|
|
2212
|
+
|
|
2213
|
+
6. **Feedback Agent** - `feedback-agent.md`
|
|
2214
|
+
- Restricted tool access: only playwright-feedback, programmatic-feedback, feedback-reporter
|
|
2215
|
+
- Disallowed: Read, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch, Task, NotebookEdit
|
|
2216
|
+
- Persona-driven instructions: stays in character, tests as real user
|
|
2217
|
+
- Reports findings via feedback-reporter tools
|
|
2218
|
+
|
|
2219
|
+
7. **Session Launcher** - `scripts/feedback-launcher.js`
|
|
2220
|
+
- Generates isolated .mcp.json configs for feedback sessions
|
|
2221
|
+
- Spawns Claude Code sessions with feedback-agent
|
|
2222
|
+
- Passes persona config and test scenarios via chat prompt
|
|
2223
|
+
- Detached process spawning for fire-and-forget execution
|
|
2224
|
+
|
|
2225
|
+
8. **Orchestration Pipeline** - `scripts/feedback-orchestrator.js`
|
|
2226
|
+
- Detects staging changes and matches affected features
|
|
2227
|
+
- Selects personas mapped to matched features
|
|
2228
|
+
- Respects 4h per-persona cooldown and max-5-per-run limit
|
|
2229
|
+
- Creates feedback_run and feedback_session records
|
|
2230
|
+
- Spawns feedback agents via feedback-launcher
|
|
2231
|
+
|
|
2232
|
+
**Testing Infrastructure:**
|
|
2233
|
+
|
|
2234
|
+
- Toy app (server.js, cli.js) with 5 intentional bugs for end-to-end testing
|
|
2235
|
+
- 9 integration tests covering full pipeline: persona CRUD → feature registration → change analysis → feedback run lifecycle → reporter bridge
|
|
2236
|
+
- Feedback agent stub for simulating sessions without spawning real Claude sessions
|
|
2237
|
+
- 475 MCP server unit tests: ALL PASSING
|
|
2238
|
+
- 9 integration tests: ALL PASSING
|
|
2239
|
+
|
|
2240
|
+
**Modified Files:**
|
|
2241
|
+
|
|
2242
|
+
- `.mcp.json.template` - Added user-feedback, playwright-feedback, programmatic-feedback, feedback-reporter servers
|
|
2243
|
+
- `packages/mcp-servers/src/agent-reports/types.ts` - Added 'user-feedback' category
|
|
2244
|
+
- `.claude/agents/feedback-agent.md` - New agent definition
|
|
2245
|
+
- `.claude/commands/configure-personas.md` - New slash command
|
|
2246
|
+
- `scripts/feedback-launcher.js` - New launcher script
|
|
2247
|
+
- `scripts/feedback-orchestrator.js` - New orchestration pipeline
|
|
2248
|
+
- `tests/README.md` - Documentation for feedback system tests
|
|
2249
|
+
- `tests/fixtures/toy-app/` - Toy application with intentional bugs
|
|
2250
|
+
- `tests/integration/feedback-pipeline.test.ts` - Integration tests
|
|
2251
|
+
- `tests/integration/mocks/feedback-agent-stub.ts` - Agent simulation stub
|
|
2252
|
+
|
|
2253
|
+
**Known Remaining Work (not in scope):**
|
|
2254
|
+
|
|
2255
|
+
- Move feedback-launcher.js and feedback-orchestrator.js to .claude/hooks/ after unprotect
|
|
2256
|
+
- Add feedback pipeline block to hourly-automation.js
|
|
2257
|
+
- Add `user_feedback: 120` cooldown default to config-reader.js
|
|
2258
|
+
|
|
2259
|
+
## 2026-02-15 - Usage Optimizer Improvements
|
|
2260
|
+
|
|
2261
|
+
### Enhanced
|
|
2262
|
+
|
|
2263
|
+
**Six behavioral improvements to usage-optimizer.js:**
|
|
2264
|
+
|
|
2265
|
+
1. **MIN_EFFECTIVE_MINUTES floor constant**
|
|
2266
|
+
- Added 2-minute floor to prevent cooldowns from going below practical minimums
|
|
2267
|
+
- `applyFactor()` clamps adjusted cooldowns to never go below 2 minutes
|
|
2268
|
+
- Prevents impractical sub-minute cooldowns that cause scheduler thrashing
|
|
2269
|
+
|
|
2270
|
+
2. **Reset-boundary detection**
|
|
2271
|
+
- New `RESET_BOUNDARY_DROP_THRESHOLD = 0.30` constant
|
|
2272
|
+
- Detects when 5-hour utilization drops >30pp between snapshots
|
|
2273
|
+
- Indicates quota reset occurred, clears trajectory data to start fresh
|
|
2274
|
+
- Prevents false trajectory calculations across reset boundaries
|
|
2275
|
+
|
|
2276
|
+
3. **EMA rate smoothing**
|
|
2277
|
+
- New `calculateEmaRate()` function with alpha=0.3
|
|
2278
|
+
- Exponential moving average smooths noisy utilization rates
|
|
2279
|
+
- Reduces overreaction to single anomalous snapshots
|
|
2280
|
+
- More stable cooldown adjustments over time
|
|
2281
|
+
|
|
2282
|
+
4. **Max-key awareness**
|
|
2283
|
+
- `calculateAggregate()` now tracks `maxKey5h` and `maxKey7d`
|
|
2284
|
+
- Uses highest utilization across all keys for trajectory projection
|
|
2285
|
+
- Prevents underutilization when one key is saturated
|
|
2286
|
+
- Ensures system doesn't spawn tasks on exhausted keys
|
|
2287
|
+
|
|
2288
|
+
5. **Per-key rate tracking**
|
|
2289
|
+
- New `perKeyUtilization` object tracks each key's 5h/7d rates
|
|
2290
|
+
- Logs warnings when any individual key exceeds 80% utilization
|
|
2291
|
+
- Helps identify single-key bottlenecks before hitting hard limits
|
|
2292
|
+
- Provides visibility into multi-key quota distribution
|
|
2293
|
+
|
|
2294
|
+
6. **Enhanced logging**
|
|
2295
|
+
- Direction tracking: "projected-at-reset falling behind target" messages
|
|
2296
|
+
- `hoursUntilReset` included in all adjustment logs and config writes
|
|
2297
|
+
- More context for understanding optimizer behavior in production
|
|
2298
|
+
|
|
2299
|
+
### Changed
|
|
2300
|
+
|
|
2301
|
+
**Modified Files:**
|
|
2302
|
+
- `.claude/hooks/usage-optimizer.js` - All 6 improvements implemented
|
|
2303
|
+
- `.claude/hooks/__tests__/usage-optimizer.test.js` - 27 new behavioral tests added
|
|
2304
|
+
|
|
2305
|
+
**Total Changes:** +412 lines added (including tests)
|
|
2306
|
+
|
|
2307
|
+
### Testing
|
|
2308
|
+
|
|
2309
|
+
**New Test Suite (27 behavioral tests):**
|
|
2310
|
+
- MIN_EFFECTIVE_MINUTES floor enforcement tests (4)
|
|
2311
|
+
- Reset-boundary detection tests (5)
|
|
2312
|
+
- EMA rate smoothing tests (5)
|
|
2313
|
+
- Max-key awareness tests (4)
|
|
2314
|
+
- Per-key utilization tracking tests (4)
|
|
2315
|
+
- Enhanced logging tests (5)
|
|
2316
|
+
|
|
2317
|
+
**Test Results:**
|
|
2318
|
+
- All 107 usage-optimizer tests passing (80 existing + 27 new)
|
|
2319
|
+
- Code review: No violations
|
|
2320
|
+
- TypeScript compilation: Passed
|
|
2321
|
+
|
|
2322
|
+
### Technical Details
|
|
2323
|
+
|
|
2324
|
+
**Behavioral Examples:**
|
|
2325
|
+
|
|
2326
|
+
**Floor Enforcement:**
|
|
2327
|
+
```
|
|
2328
|
+
Target: 1 min cooldown → Clamped to 2 min
|
|
2329
|
+
Target: 0.5 min cooldown → Clamped to 2 min
|
|
2330
|
+
Prevents scheduler thrashing
|
|
2331
|
+
```
|
|
2332
|
+
|
|
2333
|
+
**Reset Detection:**
|
|
2334
|
+
```
|
|
2335
|
+
Snapshot 1: 5h=0.75 (75%)
|
|
2336
|
+
Snapshot 2: 5h=0.40 (40%)
|
|
2337
|
+
Drop = 35pp > 30pp threshold → Reset detected
|
|
2338
|
+
Action: Clear trajectory, start fresh
|
|
2339
|
+
```
|
|
2340
|
+
|
|
2341
|
+
**EMA Smoothing:**
|
|
2342
|
+
```
|
|
2343
|
+
Snapshot 1: rate=8.0 (spike)
|
|
2344
|
+
Snapshot 2: rate=2.0 (normal)
|
|
2345
|
+
EMA rate = 0.3*8.0 + 0.7*2.0 = 3.8 (smoothed)
|
|
2346
|
+
Prevents overreaction to outliers
|
|
2347
|
+
```
|
|
2348
|
+
|
|
2349
|
+
**Max-Key Awareness:**
|
|
2350
|
+
```
|
|
2351
|
+
Key A: 5h=0.60, 7d=0.50
|
|
2352
|
+
Key B: 5h=0.85, 7d=0.70 (saturated)
|
|
2353
|
+
Aggregate uses maxKey: 5h=0.85, 7d=0.70
|
|
2354
|
+
Prevents spawning tasks on exhausted keys
|
|
2355
|
+
```
|
|
2356
|
+
|
|
2357
|
+
### Use Cases
|
|
2358
|
+
|
|
2359
|
+
**Example 1: Quota Reset Boundary**
|
|
2360
|
+
- System samples quota at 11:58 AM (75% used)
|
|
2361
|
+
- Quota resets at 12:00 PM
|
|
2362
|
+
- Next sample at 12:08 PM (5% used)
|
|
2363
|
+
- Reset detector triggers, clears trajectory
|
|
2364
|
+
- Prevents false "rate slowed dramatically" calculation
|
|
2365
|
+
|
|
2366
|
+
**Example 2: Single-Key Saturation**
|
|
2367
|
+
- Project has 3 API keys
|
|
2368
|
+
- Key #1 hits 90% utilization
|
|
2369
|
+
- Keys #2 and #3 at 40% utilization
|
|
2370
|
+
- Max-key tracking uses 90% for trajectory
|
|
2371
|
+
- System reduces spawn rate to avoid key exhaustion
|
|
2372
|
+
|
|
2373
|
+
**Example 3: Noisy Environment**
|
|
2374
|
+
- Network glitch causes one anomalous sample (spike)
|
|
2375
|
+
- EMA smoothing reduces impact of outlier
|
|
2376
|
+
- Cooldown adjustment remains stable
|
|
2377
|
+
- Prevents unnecessary spawn rate swings
|
|
2378
|
+
|
|
2379
|
+
### Backward Compatibility
|
|
2380
|
+
|
|
2381
|
+
Fully backward compatible:
|
|
2382
|
+
- All changes are internal to usage-optimizer.js
|
|
2383
|
+
- No config schema changes
|
|
2384
|
+
- No MCP tool changes
|
|
2385
|
+
- Existing snapshots remain valid
|
|
2386
|
+
- No breaking changes to hourly-automation.js integration
|
|
2387
|
+
|
|
2388
|
+
---
|
|
2389
|
+
|
|
2390
|
+
## 2026-02-15 - CTO Activity Gate for Autonomous Automation
|
|
2391
|
+
|
|
2392
|
+
### Added
|
|
2393
|
+
|
|
2394
|
+
**24-Hour CTO Activity Gate**
|
|
2395
|
+
- New fail-closed safety mechanism for autonomous automation system
|
|
2396
|
+
- All timer-based automations (task runner, health monitors, promotion pipelines, etc.) require CTO briefing within past 24 hours
|
|
2397
|
+
- `checkCtoActivityGate()` function validates CTO activity before running any automation
|
|
2398
|
+
- Prevents runaway automation when CTO is not actively engaged with the project
|
|
2399
|
+
|
|
2400
|
+
**Deputy-CTO MCP Tool**
|
|
2401
|
+
- `mcp__deputy-cto__record_cto_briefing` - Records timestamp when CTO runs `/deputy-cto`
|
|
2402
|
+
- Updates `lastCtoBriefing` in deputy-cto config database
|
|
2403
|
+
- Automatically refreshes the 24-hour automation window
|
|
2404
|
+
|
|
2405
|
+
**Configuration Schema Extension**
|
|
2406
|
+
- Added `lastCtoBriefing` field to deputy-cto config (ISO 8601 timestamp)
|
|
2407
|
+
- Persisted in `.claude/deputy-cto-config.db` SQLite database
|
|
2408
|
+
|
|
2409
|
+
**Status Reporting**
|
|
2410
|
+
- `mcp__deputy-cto__get_status` now includes gate status:
|
|
2411
|
+
- `activityGate.open` - Whether automation is currently allowed
|
|
2412
|
+
- `activityGate.hoursSinceLastBriefing` - Hours since last CTO activity
|
|
2413
|
+
- `activityGate.reason` - Human-readable explanation
|
|
2414
|
+
|
|
2415
|
+
### Changed
|
|
2416
|
+
|
|
2417
|
+
**Hourly Automation Service**
|
|
2418
|
+
- Modified `hourly-automation.js` main() to check CTO activity gate before running
|
|
2419
|
+
- If gate is closed, logs reason and exits gracefully (no automations run)
|
|
2420
|
+
- Gate check happens immediately after config load
|
|
2421
|
+
|
|
2422
|
+
**`/deputy-cto` Command**
|
|
2423
|
+
- Added `mcp__deputy-cto__record_cto_briefing()` as step 0 in opening briefing
|
|
2424
|
+
- CTO activity is automatically recorded at the start of every briefing session
|
|
2425
|
+
- Ensures automation window is refreshed each time CTO engages
|
|
2426
|
+
|
|
2427
|
+
### Security Features (G001 Compliance)
|
|
2428
|
+
|
|
2429
|
+
**Fail-Closed Design:**
|
|
2430
|
+
- Missing `lastCtoBriefing` field → automation gated
|
|
2431
|
+
- Invalid timestamp → automation gated
|
|
2432
|
+
- Parse errors → automation gated
|
|
2433
|
+
- Timestamp >24h old → automation gated
|
|
2434
|
+
|
|
2435
|
+
**Why This Matters:**
|
|
2436
|
+
- Prevents autonomous agents from running indefinitely without human oversight
|
|
2437
|
+
- Ensures CTO remains engaged with automated decision-making
|
|
2438
|
+
- Creates natural checkpoint for reviewing autonomous actions (daily)
|
|
2439
|
+
- Reduces risk of automation drift from project goals
|
|
2440
|
+
|
|
2441
|
+
### Technical Details
|
|
2442
|
+
|
|
2443
|
+
**Files Modified (5 total):**
|
|
2444
|
+
- `packages/mcp-servers/src/deputy-cto/types.ts` - Added lastCtoBriefing to config type, new tool schemas
|
|
2445
|
+
- `packages/mcp-servers/src/deputy-cto/server.ts` - Added recordCtoBriefing() function, registered tool
|
|
2446
|
+
- `.claude/hooks/hourly-automation.js` - Added checkCtoActivityGate() and gate check in main()
|
|
2447
|
+
- `.claude/commands/deputy-cto.md` - Added record_cto_briefing() as step 0
|
|
2448
|
+
- `packages/mcp-servers/src/deputy-cto/__tests__/deputy-cto.test.ts` - 12 new tests for gate feature
|
|
2449
|
+
|
|
2450
|
+
**Total Changes:** +203 lines added, -14 lines removed
|
|
2451
|
+
|
|
2452
|
+
### Testing
|
|
2453
|
+
|
|
2454
|
+
**New Test Suite (12 tests):**
|
|
2455
|
+
- `record_cto_briefing` tool functionality
|
|
2456
|
+
- `get_status` includes gate information
|
|
2457
|
+
- Gate opens when briefing is recent (<24h)
|
|
2458
|
+
- Gate closes when briefing is old (>24h)
|
|
2459
|
+
- Gate closes when briefing is missing
|
|
2460
|
+
- Gate closes on invalid timestamp
|
|
2461
|
+
- Fail-closed behavior on all error conditions
|
|
2462
|
+
|
|
2463
|
+
**Test Results:**
|
|
2464
|
+
- TypeScript compilation: ✓ Passed
|
|
2465
|
+
- All 330 tests passing (318 existing + 12 new)
|
|
2466
|
+
- Code review: ✓ No violations
|
|
2467
|
+
|
|
2468
|
+
### Use Cases
|
|
2469
|
+
|
|
2470
|
+
**Example 1: Fresh Installation**
|
|
2471
|
+
- User installs GENTYR, autonomous mode enabled by default
|
|
2472
|
+
- Hourly automation runs, checks gate → closed (no briefing yet)
|
|
2473
|
+
- User runs `/deputy-cto` → briefing recorded
|
|
2474
|
+
- Hourly automation runs, checks gate → open (briefing fresh)
|
|
2475
|
+
|
|
2476
|
+
**Example 2: Inactive Project**
|
|
2477
|
+
- User is away for 2 days
|
|
2478
|
+
- Hourly automation runs every hour → gate closed after 24h
|
|
2479
|
+
- No tasks spawned, no promotions, no health checks
|
|
2480
|
+
- User returns, runs `/deputy-cto` → automation resumes
|
|
2481
|
+
|
|
2482
|
+
**Example 3: Active Development**
|
|
2483
|
+
- User runs `/deputy-cto` daily as part of workflow
|
|
2484
|
+
- Gate always open, automation runs normally
|
|
2485
|
+
- Natural cadence of human oversight and automated execution
|
|
2486
|
+
|
|
2487
|
+
### Backward Compatibility
|
|
2488
|
+
|
|
2489
|
+
Fully backward compatible:
|
|
2490
|
+
- Existing deputy-cto config database migrates seamlessly (lastCtoBriefing defaults to null)
|
|
2491
|
+
- First run of `/deputy-cto` populates the field
|
|
2492
|
+
- Projects without deputy-cto installed are unaffected (no automation anyway)
|
|
2493
|
+
|
|
2494
|
+
---
|
|
2495
|
+
|
|
2496
|
+
## 2026-02-03 - CTO Approval System for MCP Actions
|
|
2497
|
+
|
|
2498
|
+
### Added
|
|
2499
|
+
|
|
2500
|
+
**Protected MCP Action Gate**
|
|
2501
|
+
- New PreToolUse hook: `protected-action-gate.js` - Blocks protected MCP actions until CTO approval
|
|
2502
|
+
- New UserPromptSubmit hook: `protected-action-approval-hook.js` - Processes CTO approval phrases
|
|
2503
|
+
- Configuration file: `protected-actions.json.template` - Maps approval phrases to MCP tools
|
|
2504
|
+
- Approval utilities library: `.claude/hooks/lib/approval-utils.js` - Encryption, code generation, validation
|
|
2505
|
+
|
|
2506
|
+
**CLI Utilities**
|
|
2507
|
+
- `scripts/encrypt-credential.js` - Encrypt credentials for protected-actions.json
|
|
2508
|
+
- `scripts/generate-protected-actions-spec.js` - Auto-generate spec file from config
|
|
2509
|
+
|
|
2510
|
+
**Deputy-CTO MCP Tools**
|
|
2511
|
+
- `mcp__deputy-cto__list_protections` - List all protected MCP actions and their approval phrases
|
|
2512
|
+
- `mcp__deputy-cto__get_protected_action_request` - Get details of pending approval request by code
|
|
2513
|
+
|
|
2514
|
+
**Setup Script Integration**
|
|
2515
|
+
- Added `--protect-mcp` flag to setup.sh for protecting MCP action config files
|
|
2516
|
+
- Protection includes: `protected-actions.json`, `protected-action-approvals.json`
|
|
2517
|
+
|
|
2518
|
+
**Agent Instructions**
|
|
2519
|
+
- Updated `CLAUDE.md.gentyr-section` with CTO-Protected Actions workflow section
|
|
2520
|
+
- Agents now instructed to stop and wait for CTO approval when actions are blocked
|
|
2521
|
+
|
|
2522
|
+
### Security Fixes
|
|
2523
|
+
|
|
2524
|
+
**G001 Fail-Closed Compliance**
|
|
2525
|
+
- Fixed fail-open vulnerability in protected-action-gate.js
|
|
2526
|
+
- Now properly fails closed when config is missing or invalid
|
|
2527
|
+
- Added explicit error handling for all edge cases
|
|
2528
|
+
|
|
2529
|
+
**Cryptographic Security**
|
|
2530
|
+
- Replaced weak RNG (Math.random) with crypto.randomBytes for approval code generation
|
|
2531
|
+
- 6-character codes now use cryptographically secure random values
|
|
2532
|
+
|
|
2533
|
+
**Protection Integrity**
|
|
2534
|
+
- Updated do_unprotect() to include new approval system files
|
|
2535
|
+
- Ensures uninstall properly removes all protected files
|
|
2536
|
+
|
|
2537
|
+
### Changed
|
|
2538
|
+
|
|
2539
|
+
**Hook Configuration**
|
|
2540
|
+
- `.claude/settings.json.template` updated with new hook registrations:
|
|
2541
|
+
- PreToolUse: protected-action-gate.js
|
|
2542
|
+
- UserPromptSubmit: protected-action-approval-hook.js
|
|
2543
|
+
|
|
2544
|
+
### Technical Details
|
|
2545
|
+
|
|
2546
|
+
**Approval Workflow:**
|
|
2547
|
+
1. Agent calls protected MCP action (e.g., production deployment tool)
|
|
2548
|
+
2. PreToolUse hook blocks the action, generates 6-character code
|
|
2549
|
+
3. Agent displays: "Action blocked. CTO must type: APPROVE PROD A7X9K2"
|
|
2550
|
+
4. CTO types approval phrase in chat
|
|
2551
|
+
5. UserPromptSubmit hook validates phrase and code, creates one-time approval token
|
|
2552
|
+
6. Agent retries action, PreToolUse hook allows it (one-time use, 5-minute expiry)
|
|
2553
|
+
|
|
2554
|
+
**Configuration Schema:**
|
|
2555
|
+
```json
|
|
2556
|
+
{
|
|
2557
|
+
"protections": [
|
|
2558
|
+
{
|
|
2559
|
+
"phrase": "APPROVE PROD",
|
|
2560
|
+
"encryptedCredential": "...",
|
|
2561
|
+
"tools": [
|
|
2562
|
+
{ "server": "mcp-server", "tool": "deploy_to_production" }
|
|
2563
|
+
]
|
|
2564
|
+
}
|
|
2565
|
+
]
|
|
2566
|
+
}
|
|
2567
|
+
```
|
|
2568
|
+
|
|
2569
|
+
**Files Created (13 total):**
|
|
2570
|
+
- `.claude/hooks/lib/approval-utils.js` (269 lines)
|
|
2571
|
+
- `.claude/hooks/protected-action-gate.js` (137 lines)
|
|
2572
|
+
- `.claude/hooks/protected-action-approval-hook.js` (120 lines)
|
|
2573
|
+
- `.claude/hooks/protected-actions.json.template` (52 lines)
|
|
2574
|
+
- `scripts/encrypt-credential.js` (85 lines)
|
|
2575
|
+
- `scripts/generate-protected-actions-spec.js` (116 lines)
|
|
2576
|
+
- `.claude/hooks/__tests__/approval-utils.test.js` (231 lines)
|
|
2577
|
+
- `.claude/hooks/__tests__/protected-action-gate.test.js` (189 lines)
|
|
2578
|
+
- `.claude/hooks/__tests__/protected-action-approval-hook.test.js` (192 lines)
|
|
2579
|
+
|
|
2580
|
+
**Files Modified:**
|
|
2581
|
+
- `.claude/settings.json.template` (+14 lines)
|
|
2582
|
+
- `CLAUDE.md.gentyr-section` (+7 lines)
|
|
2583
|
+
- `packages/mcp-servers/src/deputy-cto/server.ts` (+98 lines)
|
|
2584
|
+
- `packages/mcp-servers/src/deputy-cto/types.ts` (+23 lines)
|
|
2585
|
+
- `scripts/setup.sh` (+32 lines)
|
|
2586
|
+
|
|
2587
|
+
**Total Changes:** +1565 lines added
|
|
2588
|
+
|
|
2589
|
+
### Testing
|
|
2590
|
+
|
|
2591
|
+
All new components include comprehensive unit tests:
|
|
2592
|
+
- approval-utils.test.js: Encryption, code generation, validation
|
|
2593
|
+
- protected-action-gate.test.js: Hook blocking behavior, fail-closed compliance
|
|
2594
|
+
- protected-action-approval-hook.test.js: Approval phrase processing, token creation
|
|
2595
|
+
|
|
2596
|
+
### Use Cases
|
|
2597
|
+
|
|
2598
|
+
**Example 1: Production Deployment**
|
|
2599
|
+
Protect production deployment tools to require explicit CTO approval before execution.
|
|
2600
|
+
|
|
2601
|
+
**Example 2: Database Migrations**
|
|
2602
|
+
Prevent agents from running migrations without CTO review and approval.
|
|
2603
|
+
|
|
2604
|
+
**Example 3: API Key Rotation**
|
|
2605
|
+
Require CTO approval before rotating production API keys.
|
|
2606
|
+
|
|
2607
|
+
### Security Considerations
|
|
2608
|
+
|
|
2609
|
+
- Approval codes expire after 5 minutes
|
|
2610
|
+
- One-time use tokens (cannot be reused)
|
|
2611
|
+
- Fail-closed design (blocks on any error)
|
|
2612
|
+
- Credentials encrypted with AES-256-GCM
|
|
2613
|
+
- Cryptographically secure random code generation
|
|
2614
|
+
|
|
2615
|
+
---
|
|
2616
|
+
|
|
2617
|
+
## 2026-01-31 - Deputy CTO Task Assignment Feature
|
|
2618
|
+
|
|
2619
|
+
### Added
|
|
2620
|
+
|
|
2621
|
+
**Deputy CTO Agent: Task Assignment Capability**
|
|
2622
|
+
- Added `mcp__todo-db__create_task` to deputy-cto allowed tools
|
|
2623
|
+
- New "Task Assignment" section with urgency-based decision criteria
|
|
2624
|
+
- Reduces resource usage by queuing non-urgent tasks instead of immediate spawning
|
|
2625
|
+
|
|
2626
|
+
**Decision Framework:**
|
|
2627
|
+
- **Urgent tasks** (immediate spawning via `spawn_implementation_task`):
|
|
2628
|
+
- Security issues or vulnerabilities
|
|
2629
|
+
- Blocking issues preventing commits
|
|
2630
|
+
- Time-sensitive fixes
|
|
2631
|
+
- CTO explicitly requests immediate action
|
|
2632
|
+
- **Non-urgent tasks** (queued via `mcp__todo-db__create_task`):
|
|
2633
|
+
- Feature implementation from plans
|
|
2634
|
+
- Refactoring work
|
|
2635
|
+
- Documentation updates
|
|
2636
|
+
- General improvements
|
|
2637
|
+
|
|
2638
|
+
### Changed
|
|
2639
|
+
|
|
2640
|
+
**`.claude/agents/deputy-cto.md`**
|
|
2641
|
+
- Added `mcp__todo-db__create_task` to allowedTools
|
|
2642
|
+
- Updated "Your Powers" section to list both spawn and queue options
|
|
2643
|
+
- Added "Task Assignment" section with urgency criteria and code examples
|
|
2644
|
+
|
|
2645
|
+
**`.claude/commands/deputy-cto.md`**
|
|
2646
|
+
- Replaced "Spawning Implementation Tasks" section with "Task Assignment"
|
|
2647
|
+
- Added urgency-based decision criteria
|
|
2648
|
+
- Added code examples for both immediate spawning and queuing
|
|
2649
|
+
|
|
2650
|
+
### Technical Details
|
|
2651
|
+
|
|
2652
|
+
The deputy-cto agent now intelligently chooses between:
|
|
2653
|
+
1. **Immediate spawning** - Fire-and-forget Claude sessions for urgent work
|
|
2654
|
+
2. **Task queuing** - Adding tasks to todo.db for agent pickup during normal workflow
|
|
2655
|
+
|
|
2656
|
+
This reduces unnecessary resource consumption while maintaining responsiveness for critical issues.
|
|
2657
|
+
|
|
2658
|
+
### Files Modified
|
|
2659
|
+
|
|
2660
|
+
- `.claude/agents/deputy-cto.md` (configuration changes)
|
|
2661
|
+
- `.claude/commands/deputy-cto.md` (documentation changes)
|
|
2662
|
+
|
|
2663
|
+
### Review Status
|
|
2664
|
+
|
|
2665
|
+
- Code Reviewer: APPROVED - Changes well-structured, consistent, correct tool usage
|
|
2666
|
+
- Test Writer: N/A - Markdown configuration files, no executable code
|
|
2667
|
+
|
|
2668
|
+
---
|
|
2669
|
+
|
|
2670
|
+
## 2026-01-29 - CLAUDE.md Agent Instructions Feature
|
|
2671
|
+
|
|
2672
|
+
### Added
|
|
2673
|
+
|
|
2674
|
+
**Setup Script: CLAUDE.md Management**
|
|
2675
|
+
- Automatic injection of agent workflow instructions into target project CLAUDE.md files
|
|
2676
|
+
- Template file: `CLAUDE.md.gentyr-section` with golden rules and standard workflow
|
|
2677
|
+
- Smart append/replace logic:
|
|
2678
|
+
- Creates CLAUDE.md if it doesn't exist
|
|
2679
|
+
- Appends section to existing files
|
|
2680
|
+
- Replaces section on re-install (no duplicates)
|
|
2681
|
+
- Uses `<!-- GENTYR-FRAMEWORK-START/END -->` markers for idempotency
|
|
2682
|
+
|
|
2683
|
+
**Uninstall Cleanup**
|
|
2684
|
+
- Removes GENTYR section from CLAUDE.md
|
|
2685
|
+
- Deletes file if empty after removal
|
|
2686
|
+
- Preserves project-specific content
|
|
2687
|
+
|
|
2688
|
+
**Agent Workflow Documentation**
|
|
2689
|
+
- Golden rules: Never skip agents, always follow order, one agent per role
|
|
2690
|
+
- Standard sequence: INVESTIGATOR → CODE-WRITER → TEST-WRITER → CODE-REVIEWER → PROJECT-MANAGER → SUMMARY
|
|
2691
|
+
- CTO reporting guidelines for architecture, security, breaking changes, blockers
|
|
2692
|
+
- Slash command reference
|
|
2693
|
+
|
|
2694
|
+
### Changed
|
|
2695
|
+
|
|
2696
|
+
**scripts/setup.sh**
|
|
2697
|
+
- Added section 8: CLAUDE.md agent instructions injection
|
|
2698
|
+
- Added CLAUDE.md cleanup in uninstall section
|
|
2699
|
+
- Skip CLAUDE.md operations if file is write-protected
|
|
2700
|
+
|
|
2701
|
+
**README.md**
|
|
2702
|
+
- Expanded "Custom CLAUDE.md" section with installation behavior details
|
|
2703
|
+
- Documented template location and content
|
|
2704
|
+
- Added uninstall behavior explanation
|
|
2705
|
+
|
|
2706
|
+
### Files Modified
|
|
2707
|
+
|
|
2708
|
+
- `scripts/setup.sh` (+47 lines)
|
|
2709
|
+
- `CLAUDE.md` (new, 60 lines) - Framework's own CLAUDE.md
|
|
2710
|
+
- `CLAUDE.md.gentyr-section` (new, 34 lines) - Template for target projects
|
|
2711
|
+
- `README.md` (+20 lines)
|
|
2712
|
+
- `docs/CHANGELOG.md` (+35 lines, this entry)
|
|
2713
|
+
|
|
2714
|
+
### Technical Details
|
|
2715
|
+
|
|
2716
|
+
**Idempotency:**
|
|
2717
|
+
- Section markers ensure re-installs replace old section instead of appending duplicates
|
|
2718
|
+
- Sed-based removal using marker comments
|
|
2719
|
+
|
|
2720
|
+
**Protection Integration:**
|
|
2721
|
+
- Setup skips CLAUDE.md if write-protected (post-protection state)
|
|
2722
|
+
- Uninstall skips cleanup if write-protected
|
|
2723
|
+
|
|
2724
|
+
### Use Case
|
|
2725
|
+
|
|
2726
|
+
Before this feature, each project needed manual CLAUDE.md creation with agent workflow instructions. Now the framework automatically provides:
|
|
2727
|
+
- Consistent agent workflow across all projects
|
|
2728
|
+
- Up-to-date best practices for multi-agent coordination
|
|
2729
|
+
- Standardized CTO reporting conventions
|
|
2730
|
+
|
|
2731
|
+
Projects can still add custom instructions above/below the framework section.
|
|
2732
|
+
|
|
2733
|
+
---
|
|
2734
|
+
|
|
2735
|
+
## 2026-01-24 - Spec Suite System
|
|
2736
|
+
|
|
2737
|
+
### Added
|
|
2738
|
+
|
|
2739
|
+
**MCP Server: specs-browser**
|
|
2740
|
+
- 9 new MCP tools for spec and suite management:
|
|
2741
|
+
- `createSpec` - Create new specification files
|
|
2742
|
+
- `editSpec` - Edit existing specifications
|
|
2743
|
+
- `deleteSpec` - Delete specifications
|
|
2744
|
+
- `get_specs_for_file` - Get all applicable specs for a file (main + subspecs)
|
|
2745
|
+
- `listSuites` - List all configured spec suites
|
|
2746
|
+
- `getSuite` - Get suite configuration details
|
|
2747
|
+
- `createSuite` - Create new spec suite
|
|
2748
|
+
- `editSuite` - Modify suite configuration
|
|
2749
|
+
- `deleteSuite` - Remove spec suite
|
|
2750
|
+
|
|
2751
|
+
**Compliance Checker**
|
|
2752
|
+
- Suite-based enforcement system
|
|
2753
|
+
- Pattern matching for file scoping using glob patterns
|
|
2754
|
+
- `loadSuitesConfig()` - Load suite configuration
|
|
2755
|
+
- `getSuitesForFile()` - Determine applicable suites for a file
|
|
2756
|
+
- `getAllApplicableSpecs()` - Collect specs from matching suites (global)
|
|
2757
|
+
- `getAllExploratorySpecs()` - Collect specs from matching suites (local)
|
|
2758
|
+
- `matchesGlob()` - Simple glob pattern matcher
|
|
2759
|
+
|
|
2760
|
+
**Configuration**
|
|
2761
|
+
- New config file: `.claude/hooks/suites-config.json`
|
|
2762
|
+
- Suite schema with scope, priority, and enabled flags
|
|
2763
|
+
- Backward compatibility with legacy enforcement
|
|
2764
|
+
|
|
2765
|
+
**Documentation**
|
|
2766
|
+
- Comprehensive spec suites section in `.claude/hooks/README.md`
|
|
2767
|
+
- Session documentation: `docs/sessions/2026-01-24-spec-suite-implementation.md`
|
|
2768
|
+
- Updated README.md with spec suite examples
|
|
2769
|
+
|
|
2770
|
+
### Changed
|
|
2771
|
+
|
|
2772
|
+
**Compliance Prompts**
|
|
2773
|
+
- `spec-enforcement.md` - Added optional Suite Context section
|
|
2774
|
+
- `local-spec-enforcement.md` - Added Suite Context and Scope Constraint sections
|
|
2775
|
+
|
|
2776
|
+
**README.md**
|
|
2777
|
+
- Updated Specification Enforcement section with suite examples
|
|
2778
|
+
- Updated specs-browser description to include CRUD operations
|
|
2779
|
+
- Updated MCP tools examples
|
|
2780
|
+
|
|
2781
|
+
### Technical Details
|
|
2782
|
+
|
|
2783
|
+
**Files Modified (7 total):**
|
|
2784
|
+
- `.claude/hooks/README.md` (+89 lines)
|
|
2785
|
+
- `.claude/hooks/compliance-checker.js` (+382 lines major refactor)
|
|
2786
|
+
- `.claude/hooks/prompts/local-spec-enforcement.md` (+24 lines)
|
|
2787
|
+
- `.claude/hooks/prompts/spec-enforcement.md` (+9 lines)
|
|
2788
|
+
- `README.md` (+34 lines)
|
|
2789
|
+
- `packages/mcp-servers/src/specs-browser/server.ts` (+442 lines)
|
|
2790
|
+
- `packages/mcp-servers/src/specs-browser/types.ts` (+232 lines)
|
|
2791
|
+
|
|
2792
|
+
**Total Changes:** +1101 lines, -111 lines
|
|
2793
|
+
|
|
2794
|
+
### Verification
|
|
2795
|
+
|
|
2796
|
+
- TypeScript build: ✓ Passed
|
|
2797
|
+
- JavaScript syntax check: ✓ Passed
|
|
2798
|
+
- Code review: ✓ No violations
|
|
2799
|
+
- Vitest tests: ✓ 51 tests passing
|
|
2800
|
+
|
|
2801
|
+
### Testing
|
|
2802
|
+
|
|
2803
|
+
**specs-browser/__tests__/specs-browser.test.ts**
|
|
2804
|
+
- Fixed test cleanup issue in Suite Management describe block
|
|
2805
|
+
- Added `afterEach` to remove `.claude` directory created during tests
|
|
2806
|
+
- All 51 tests now pass consistently across test runs
|
|
2807
|
+
- Root cause: Missing cleanup caused directory persistence across runs
|
|
2808
|
+
|
|
2809
|
+
### Architecture
|
|
2810
|
+
|
|
2811
|
+
Spec suites allow projects to:
|
|
2812
|
+
1. Group related specifications (global + local)
|
|
2813
|
+
2. Scope specs to specific file patterns using glob syntax
|
|
2814
|
+
3. Reduce enforcement noise by checking only relevant specs
|
|
2815
|
+
4. Configure priority when multiple suites match
|
|
2816
|
+
|
|
2817
|
+
Example use case: Integration-specific specs only check integration files, not the entire codebase.
|
|
2818
|
+
|
|
2819
|
+
### Backward Compatibility
|
|
2820
|
+
|
|
2821
|
+
Fully backward compatible:
|
|
2822
|
+
- Legacy behavior if suites-config.json doesn't exist
|
|
2823
|
+
- Existing spec-file-mappings.json still supported
|
|
2824
|
+
- No breaking changes to existing workflows
|
|
2825
|
+
|
|
2826
|
+
---
|
|
2827
|
+
|
|
2828
|
+
## Previous Releases
|
|
2829
|
+
|
|
2830
|
+
See git history for pre-2026-01-24 changes.
|