claude-flow-novice 2.15.2 → 2.15.4
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/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
- package/.claude/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
- package/.claude/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
- package/.claude/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
- package/.claude/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
- package/.claude/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
- package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
- package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
- package/.claude/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
- package/.claude/commands/cfn-loop-cli.md +16 -2
- package/.claude/commands/switch-api.md +31 -10
- package/.claude/hooks/cfn-BACKUP_USAGE.md +243 -243
- package/.claude/hooks/cfn-invoke-security-validation.sh +69 -69
- package/.claude/hooks/cfn-lint-sql-injection.sh +61 -0
- package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +109 -78
- package/.claude/hooks/cfn-post-edit.config.json +44 -44
- package/.claude/hooks/cfn-pre-edit-security-warning.sh +40 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
- package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
- package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
- package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
- package/.claude/skills/cfn-hybrid-routing/check-dependencies.sh +51 -51
- package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
- package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
- package/.claude/skills/cfn-loop-orchestration/security_utils.sh +24 -0
- package/.claude/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
- package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -252
- package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
- package/.claude/skills/cfn-redis-coordination/agent-log.sh +4 -0
- package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
- package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +74 -74
- package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
- package/.claude/skills/cfn-redis-coordination/get-context.sh +145 -112
- package/.claude/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
- package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
- package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/.claude/skills/cfn-redis-coordination/redis-functions.sh +33 -0
- package/.claude/skills/cfn-redis-coordination/report-completion.sh +24 -31
- package/.claude/skills/cfn-redis-coordination/store-context.sh +4 -0
- package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
- package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
- package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
- package/.claude/skills/cfn-transparency-middleware/middleware-config.sh +28 -28
- package/.claude/skills/cfn-transparency-middleware/performance-benchmark.sh +78 -78
- package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
- package/.claude/skills/cfn-transparency-middleware/test-integration.sh +161 -161
- package/.claude/skills/cfn-transparency-middleware/test-transparency-skill.sh +367 -367
- package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +107 -92
- package/.claude/skills/cfn-transparency-middleware/wrap-agent.sh +131 -131
- package/README.md +116 -475
- package/claude-assets/agents/cfn-dev-team/README.md +103 -0
- package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +1 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +77 -15
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +355 -6
- package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +82 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +82 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +77 -15
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +99 -12
- package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +1 -1
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +97 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +20 -1
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +97 -0
- package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +110 -13
- package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +106 -15
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +115 -11
- package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +94 -7
- package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +87 -9
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +85 -7
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +160 -28
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +101 -19
- package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +108 -14
- package/claude-assets/agents/cfn-dev-team/reviewers/{reviewer.md → code-reviewer.md} +95 -8
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +107 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +98 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +95 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +136 -9
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +108 -1
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +107 -13
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +737 -0
- package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +828 -0
- package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +106 -7
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +77 -0
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +684 -0
- package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +110 -1
- package/claude-assets/agents/cfn-dev-team/testers/tester.md +94 -7
- package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +1 -3
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +87 -13
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +103 -7
- package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -3
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +94 -7
- package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +46 -0
- package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
- package/claude-assets/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
- package/claude-assets/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
- package/claude-assets/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
- package/claude-assets/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
- package/claude-assets/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
- package/claude-assets/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
- package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
- package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
- package/claude-assets/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
- package/claude-assets/commands/cfn-loop-cli.md +16 -2
- package/claude-assets/commands/switch-api.md +31 -10
- package/claude-assets/hooks/cfn-BACKUP_USAGE.md +243 -243
- package/claude-assets/hooks/cfn-invoke-security-validation.sh +69 -69
- package/claude-assets/hooks/cfn-lint-sql-injection.sh +61 -0
- package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +109 -78
- package/claude-assets/hooks/cfn-post-edit.config.json +44 -44
- package/claude-assets/hooks/cfn-post-execution/memory-cleanup.sh +19 -19
- package/claude-assets/hooks/cfn-pre-edit-security-warning.sh +40 -0
- package/claude-assets/hooks/cfn-pre-execution/memory-check.sh +19 -19
- package/claude-assets/hooks/detect-hardcoded-credentials.sh +212 -0
- package/claude-assets/skills/SKILL_TEMPLATE.md +774 -0
- package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +543 -572
- package/claude-assets/skills/agent-lifecycle/simple-audit.sh +57 -30
- package/claude-assets/skills/agent-template-generator/SKILL.md +440 -0
- package/claude-assets/skills/agent-template-generator/generate-agent.sh +405 -0
- package/claude-assets/skills/agent-validation-linter/SKILL.md +589 -0
- package/claude-assets/skills/agent-validation-linter/lint-agents.sh +271 -0
- package/claude-assets/skills/bootstrap/bash-fundamentals.md +786 -0
- package/claude-assets/skills/bootstrap/database-connection.md +464 -0
- package/claude-assets/skills/bootstrap/error-handling.md +580 -0
- package/claude-assets/skills/bootstrap/file-operations.md +699 -0
- package/claude-assets/skills/bootstrap/skill-loader.md +616 -0
- package/claude-assets/skills/bootstrap/sqlite-params.sh +287 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
- package/claude-assets/skills/cfn-automatic-memory-persistence/persist-agent-output.sh +48 -48
- package/claude-assets/skills/cfn-automatic-memory-persistence/query-agent-history.sh +34 -34
- package/claude-assets/skills/cfn-automatic-memory-persistence/test-memory-persistence.sh +17 -16
- package/claude-assets/skills/cfn-deliverable-validation/confidence-calculator.sh +261 -261
- package/claude-assets/skills/cfn-deployment/SKILL.md +293 -0
- package/claude-assets/skills/cfn-deployment/execute.sh +21 -0
- package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
- package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
- package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
- package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +38 -0
- package/claude-assets/skills/cfn-error-batching-strategy/lib/core-functions.sh +47 -47
- package/claude-assets/skills/cfn-expert-update/update-expert.sh +345 -345
- package/claude-assets/skills/cfn-file-operations/SKILL.md +290 -0
- package/claude-assets/skills/cfn-file-operations/execute.sh +129 -0
- package/claude-assets/skills/cfn-file-operations/lib/atomic-write.sh +294 -0
- package/claude-assets/skills/cfn-file-operations/lib/lock.sh +361 -0
- package/claude-assets/skills/cfn-file-operations/test.sh +369 -0
- package/claude-assets/skills/cfn-hybrid-routing/check-dependencies.sh +51 -51
- package/claude-assets/skills/cfn-intervention-detector/detect-intervention.sh +110 -110
- package/claude-assets/skills/cfn-intervention-orchestrator/execute-intervention.sh +58 -58
- package/claude-assets/skills/cfn-log-operations/SKILL.md +308 -0
- package/claude-assets/skills/cfn-log-operations/execute.sh +420 -0
- package/claude-assets/skills/cfn-log-operations/lib/rotate.sh +406 -0
- package/claude-assets/skills/cfn-log-operations/lib/search.sh +448 -0
- package/claude-assets/skills/cfn-log-operations/test.sh +394 -0
- package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
- package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
- package/claude-assets/skills/cfn-loop-orchestration/security_utils.sh +24 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
- package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -252
- package/claude-assets/skills/cfn-loop2-output-processing/process-validator-output.sh +275 -275
- package/claude-assets/skills/cfn-memory-management/check-memory.sh +159 -159
- package/claude-assets/skills/cfn-memory-management/cleanup-memory.sh +196 -196
- package/claude-assets/skills/cfn-node-heap-sizer/task-mode-heap-limiter.sh +325 -325
- package/claude-assets/skills/cfn-parameterized-queries/SKILL.md +339 -0
- package/claude-assets/skills/cfn-playbook/query-playbook.sh +19 -15
- package/claude-assets/skills/cfn-playbook/update-playbook.sh +25 -14
- package/claude-assets/skills/cfn-playbook-auto-update/auto-update-playbook.sh +85 -85
- package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +44 -0
- package/claude-assets/skills/cfn-promotion/SKILL.md +305 -0
- package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh +4 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +74 -74
- package/claude-assets/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
- package/claude-assets/skills/cfn-redis-coordination/get-context.sh +145 -112
- package/claude-assets/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
- package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
- package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +33 -0
- package/claude-assets/skills/cfn-redis-coordination/report-completion.sh +24 -31
- package/claude-assets/skills/cfn-redis-coordination/store-context.sh +4 -0
- package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
- package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
- package/claude-assets/skills/cfn-scope-simplifier/simplify-scope.sh +67 -67
- package/claude-assets/skills/cfn-skill-loader/SKILL.md +466 -0
- package/claude-assets/skills/cfn-skill-loader/execute.sh +344 -0
- package/claude-assets/skills/cfn-specialist-injection/recommend-specialist.sh +56 -56
- package/claude-assets/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
- package/claude-assets/skills/cfn-standardized-error-handling/capture-agent-error.sh +86 -86
- package/claude-assets/skills/cfn-standardized-error-handling/test-error-handling.sh +165 -165
- package/claude-assets/skills/cfn-task-audit/get-audit-data.sh +42 -21
- package/claude-assets/skills/cfn-task-audit/store-task-audit.sh +17 -10
- package/claude-assets/skills/cfn-task-config-init/initialize-config.sh +264 -264
- package/claude-assets/skills/cfn-task-decomposition/task-decomposer.sh +278 -278
- package/claude-assets/skills/cfn-test-runner/detect-regressions.sh +17 -14
- package/claude-assets/skills/cfn-test-runner/detect-regressions.sh.backup-1763392821 +55 -0
- package/claude-assets/skills/cfn-test-runner/store-benchmarks.sh +17 -19
- package/claude-assets/skills/cfn-transparency-middleware/middleware-config.sh +28 -28
- package/claude-assets/skills/cfn-transparency-middleware/performance-benchmark.sh +78 -78
- package/claude-assets/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
- package/claude-assets/skills/cfn-transparency-middleware/test-integration.sh +161 -161
- package/claude-assets/skills/cfn-transparency-middleware/test-transparency-skill.sh +367 -367
- package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +107 -92
- package/claude-assets/skills/cfn-transparency-middleware/wrap-agent.sh +131 -131
- package/claude-assets/skills/cfn-utilities/SKILL.md +237 -0
- package/claude-assets/skills/cfn-utilities/execute.sh +32 -0
- package/claude-assets/skills/cfn-utilities/lib/errors.sh +56 -0
- package/claude-assets/skills/cfn-utilities/lib/file-ops.sh +164 -0
- package/claude-assets/skills/cfn-utilities/lib/logging.sh +77 -0
- package/claude-assets/skills/cfn-utilities/lib/retry.sh +127 -0
- package/claude-assets/skills/cfn-utilities/test.sh +317 -0
- package/claude-assets/skills/docker-build/SKILL.md +96 -203
- package/claude-assets/skills/docker-build/build.sh +73 -73
- package/claude-assets/skills/integration/agent-handoff.sh +492 -0
- package/claude-assets/skills/integration/file-operations.sh +414 -0
- package/claude-assets/skills/json-validation/SKILL.md +431 -0
- package/claude-assets/skills/json-validation/test-validate-success-criteria.sh +421 -0
- package/claude-assets/skills/json-validation/validate-success-criteria.sh +197 -0
- package/claude-assets/skills/redis-coordination/validate-parameters.sh +34 -0
- package/claude-assets/skills/workflow-codification/APPROVAL_WORKFLOW.md +806 -0
- package/claude-assets/skills/workflow-codification/COST_TRACKING.md +637 -0
- package/claude-assets/skills/workflow-codification/DEPLOY_QUICK_REFERENCE.md +106 -0
- package/claude-assets/skills/workflow-codification/EDGE_CASE_TRACKING.md +404 -0
- package/claude-assets/skills/workflow-codification/PROPAGATE_UPDATE_QUICK_REFERENCE.md +366 -0
- package/claude-assets/skills/workflow-codification/README_PHASE4.md +457 -0
- package/claude-assets/skills/workflow-codification/SKILL.md +110 -0
- package/claude-assets/skills/workflow-codification/analyze-patterns.sh +899 -0
- package/claude-assets/skills/workflow-codification/approval-workflow.sh +514 -0
- package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh +481 -0
- package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh.backup-1763392820 +512 -0
- package/claude-assets/skills/workflow-codification/generate-skill-update.sh +525 -0
- package/claude-assets/skills/workflow-codification/lib/security-utils.sh +204 -0
- package/claude-assets/skills/workflow-codification/propagate-skill-update.sh +648 -0
- package/claude-assets/skills/workflow-codification/propagate-skill-update.sh.backup-1763392820 +664 -0
- package/claude-assets/skills/workflow-codification/review-skill.sh +643 -0
- package/claude-assets/skills/workflow-codification/templates/email-notification.txt +114 -0
- package/claude-assets/skills/workflow-codification/templates/slack-notification.md +85 -0
- package/claude-assets/skills/workflow-codification/test-integration.sh +296 -0
- package/claude-assets/skills/workflow-codification/test-metadata-update.sh +350 -0
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh +486 -0
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh.backup-1763392821 +445 -0
- package/claude-assets/skills/workflow-codification/track-edge-case.sh +290 -0
- package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
- package/dist/ace/ace-curator.js +10 -2
- package/dist/ace/ace-curator.js.map +1 -1
- package/dist/ace/ace-generator.js +4 -0
- package/dist/ace/ace-generator.js.map +1 -1
- package/dist/ace/ace-reflector.js +1 -1
- package/dist/ace/ace-reflector.js.map +1 -1
- package/dist/ace/context-injection.js +24 -2
- package/dist/ace/context-injection.js.map +1 -1
- package/dist/agents/agent-loader.js +146 -165
- package/dist/agents/agent-loader.js.map +1 -1
- package/dist/agents/task-agent-integration.js +1 -1
- package/dist/agents/task-agent-integration.js.map +1 -1
- package/dist/api/health-endpoints.js +390 -0
- package/dist/api/health-endpoints.js.map +1 -0
- package/dist/cli/agent-executor.js +4 -1
- package/dist/cli/agent-executor.js.map +1 -1
- package/dist/cli/agent-prompt-builder.js +89 -1
- package/dist/cli/agent-prompt-builder.js.map +1 -1
- package/dist/cli/agent-spawn.js +130 -37
- package/dist/cli/agent-spawn.js.map +1 -1
- package/dist/cli/config-manager.js +91 -109
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/cli/skill-cache-validator.js +412 -0
- package/dist/cli/skill-cache-validator.js.map +1 -0
- package/dist/cli/skill-cli.js +991 -0
- package/dist/cli/skill-cli.js.map +1 -0
- package/dist/cli/skill-execution-logger.js +284 -0
- package/dist/cli/skill-execution-logger.js.map +1 -0
- package/dist/cli/skill-loader.js +457 -0
- package/dist/cli/skill-loader.js.map +1 -0
- package/dist/coordination/event-bus.js +2 -2
- package/dist/coordination/event-bus.js.map +1 -1
- package/dist/coordination/fleet-manager.js +1 -1
- package/dist/coordination/fleet-manager.js.map +1 -1
- package/dist/coordination/index.js +23 -9
- package/dist/coordination/index.js.map +1 -1
- package/dist/coordination/types/fleet-manager.types.js.map +1 -1
- package/dist/db/migration-manager.js +483 -0
- package/dist/db/migration-manager.js.map +1 -0
- package/dist/db/skills-query.js +535 -0
- package/dist/db/skills-query.js.map +1 -0
- package/dist/integration/DatabaseHandoff.js +507 -0
- package/dist/integration/DatabaseHandoff.js.map +1 -0
- package/dist/integration/StandardAdapter.js +291 -0
- package/dist/integration/StandardAdapter.js.map +1 -0
- package/dist/jobs/edge-case-analyzer.js +367 -0
- package/dist/jobs/edge-case-analyzer.js.map +1 -0
- package/dist/jobs/promotion-sla-enforcer.js +288 -0
- package/dist/jobs/promotion-sla-enforcer.js.map +1 -0
- package/dist/lib/agent-output-parser.js +518 -0
- package/dist/lib/agent-output-parser.js.map +1 -0
- package/dist/lib/agent-output-validator.js +950 -0
- package/dist/lib/agent-output-validator.js.map +1 -0
- package/dist/lib/agent-workspace.js +281 -0
- package/dist/lib/agent-workspace.js.map +1 -0
- package/dist/lib/artifact-registry.js +443 -0
- package/dist/lib/artifact-registry.js.map +1 -0
- package/dist/lib/atomic-file-writer.js +377 -0
- package/dist/lib/atomic-file-writer.js.map +1 -0
- package/dist/lib/backup-manager.js +779 -0
- package/dist/lib/backup-manager.js.map +1 -0
- package/dist/lib/checkpoint-manager.js +837 -0
- package/dist/lib/checkpoint-manager.js.map +1 -0
- package/dist/lib/circuit-breaker.js +340 -0
- package/dist/lib/circuit-breaker.js.map +1 -0
- package/dist/lib/completion-signal-handler.js +243 -0
- package/dist/lib/completion-signal-handler.js.map +1 -0
- package/dist/lib/config-manager.js +312 -0
- package/dist/lib/config-manager.js.map +1 -0
- package/dist/lib/config-migrator.js +386 -0
- package/dist/lib/config-migrator.js.map +1 -0
- package/dist/lib/config-validator.js +687 -0
- package/dist/lib/config-validator.js.map +1 -0
- package/dist/lib/correlation-cache.js +311 -0
- package/dist/lib/correlation-cache.js.map +1 -0
- package/dist/lib/correlation.js +263 -0
- package/dist/lib/correlation.js.map +1 -0
- package/dist/lib/database-service/connection-pool-manager.js +520 -0
- package/dist/lib/database-service/connection-pool-manager.js.map +1 -0
- package/dist/lib/database-service/correlation.js +329 -0
- package/dist/lib/database-service/correlation.js.map +1 -0
- package/dist/lib/database-service/errors.js +120 -0
- package/dist/lib/database-service/errors.js.map +1 -0
- package/dist/lib/database-service/index.js +168 -0
- package/dist/lib/database-service/index.js.map +1 -0
- package/dist/lib/database-service/postgres-adapter.js +526 -0
- package/dist/lib/database-service/postgres-adapter.js.map +1 -0
- package/dist/lib/database-service/redis-adapter.js +360 -0
- package/dist/lib/database-service/redis-adapter.js.map +1 -0
- package/dist/lib/database-service/sqlite-adapter.js +544 -0
- package/dist/lib/database-service/sqlite-adapter.js.map +1 -0
- package/dist/lib/database-service/transaction-manager.js +773 -0
- package/dist/lib/database-service/transaction-manager.js.map +1 -0
- package/dist/lib/database-service/types.js +23 -0
- package/dist/lib/database-service/types.js.map +1 -0
- package/dist/lib/deadlock-resolver.js +292 -0
- package/dist/lib/deadlock-resolver.js.map +1 -0
- package/dist/lib/distributed-lock.js +451 -0
- package/dist/lib/distributed-lock.js.map +1 -0
- package/dist/lib/edge-case-deduplicator.js +227 -0
- package/dist/lib/edge-case-deduplicator.js.map +1 -0
- package/dist/lib/encryption-manager.js +322 -0
- package/dist/lib/encryption-manager.js.map +1 -0
- package/dist/lib/error-aggregator.js +234 -0
- package/dist/lib/error-aggregator.js.map +1 -0
- package/dist/lib/errors.js +287 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/file-lock-manager.js +578 -0
- package/dist/lib/file-lock-manager.js.map +1 -0
- package/dist/lib/file-operations.js +367 -0
- package/dist/lib/file-operations.js.map +1 -0
- package/dist/lib/idempotent-write.js +237 -0
- package/dist/lib/idempotent-write.js.map +1 -0
- package/dist/lib/integration-schema-validator.js +522 -0
- package/dist/lib/integration-schema-validator.js.map +1 -0
- package/dist/lib/lock-health-monitor.js +298 -0
- package/dist/lib/lock-health-monitor.js.map +1 -0
- package/dist/lib/log-shipper.js +422 -0
- package/dist/lib/log-shipper.js.map +1 -0
- package/dist/lib/logging.js +146 -0
- package/dist/lib/logging.js.map +1 -0
- package/dist/lib/message-deduplicator.js +439 -0
- package/dist/lib/message-deduplicator.js.map +1 -0
- package/dist/lib/multi-system-query.js +604 -0
- package/dist/lib/multi-system-query.js.map +1 -0
- package/dist/lib/orphan-detector.js +332 -0
- package/dist/lib/orphan-detector.js.map +1 -0
- package/dist/lib/password-generator.js +166 -0
- package/dist/lib/password-generator.js.map +1 -0
- package/dist/lib/path-validator.js +429 -0
- package/dist/lib/path-validator.js.map +1 -0
- package/dist/lib/query-translator.js +905 -0
- package/dist/lib/query-translator.js.map +1 -0
- package/dist/lib/queue-recovery.js +469 -0
- package/dist/lib/queue-recovery.js.map +1 -0
- package/dist/lib/redis-queue-manager.js +512 -0
- package/dist/lib/redis-queue-manager.js.map +1 -0
- package/dist/lib/reflection-archiver.js +272 -0
- package/dist/lib/reflection-archiver.js.map +1 -0
- package/dist/lib/retry-manager.js +453 -0
- package/dist/lib/retry-manager.js.map +1 -0
- package/dist/lib/retry.js +262 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/lib/schema-transform.js +695 -0
- package/dist/lib/schema-transform.js.map +1 -0
- package/dist/lib/schema-validator.js +491 -0
- package/dist/lib/schema-validator.js.map +1 -0
- package/dist/lib/skill-cache.js +297 -0
- package/dist/lib/skill-cache.js.map +1 -0
- package/dist/lib/skill-content-manager.js +337 -0
- package/dist/lib/skill-content-manager.js.map +1 -0
- package/dist/lib/skill-frontmatter-parser.js +237 -0
- package/dist/lib/skill-frontmatter-parser.js.map +1 -0
- package/dist/lib/skill-git-integration.js +275 -0
- package/dist/lib/skill-git-integration.js.map +1 -0
- package/dist/lib/skill-markdown-validator.js +396 -0
- package/dist/lib/skill-markdown-validator.js.map +1 -0
- package/dist/lib/skill-output-parser.js +312 -0
- package/dist/lib/skill-output-parser.js.map +1 -0
- package/dist/lib/unified-query-api.js +467 -0
- package/dist/lib/unified-query-api.js.map +1 -0
- package/dist/middleware/auth-middleware.js +350 -0
- package/dist/middleware/auth-middleware.js.map +1 -0
- package/dist/middleware/schema-validation.js +347 -0
- package/dist/middleware/schema-validation.js.map +1 -0
- package/dist/providers/anthropic-provider.js +1 -1
- package/dist/providers/anthropic-provider.js.map +1 -1
- package/dist/providers/provider-factory.js +2 -2
- package/dist/providers/provider-factory.js.map +1 -1
- package/dist/services/edge-case-analyzer.js +321 -0
- package/dist/services/edge-case-analyzer.js.map +1 -0
- package/dist/services/edge-case-deduplicator.js +266 -0
- package/dist/services/edge-case-deduplicator.js.map +1 -0
- package/dist/services/edge-case-detector.js +337 -0
- package/dist/services/edge-case-detector.js.map +1 -0
- package/dist/services/edge-case-tracker.js +547 -0
- package/dist/services/edge-case-tracker.js.map +1 -0
- package/dist/services/health-check-system.js +586 -0
- package/dist/services/health-check-system.js.map +1 -0
- package/dist/services/metrics-logger.js +412 -0
- package/dist/services/metrics-logger.js.map +1 -0
- package/dist/services/patch-generator.js +378 -0
- package/dist/services/patch-generator.js.map +1 -0
- package/dist/services/patch-validator.js +337 -0
- package/dist/services/patch-validator.js.map +1 -0
- package/dist/services/performance-monitor.js +811 -0
- package/dist/services/performance-monitor.js.map +1 -0
- package/dist/services/promotion-pipeline.js +918 -0
- package/dist/services/promotion-pipeline.js.map +1 -0
- package/dist/services/promotion-validator.js +394 -0
- package/dist/services/promotion-validator.js.map +1 -0
- package/dist/services/reflection-logger.js +388 -0
- package/dist/services/reflection-logger.js.map +1 -0
- package/dist/services/skill-deployment.js +472 -0
- package/dist/services/skill-deployment.js.map +1 -0
- package/dist/services/skill-loader.js +427 -0
- package/dist/services/skill-loader.js.map +1 -0
- package/dist/services/skill-promotion.js +372 -0
- package/dist/services/skill-promotion.js.map +1 -0
- package/dist/services/skill-validator.js +454 -0
- package/dist/services/skill-validator.js.map +1 -0
- package/dist/services/skill-versioning.js +244 -0
- package/dist/services/skill-versioning.js.map +1 -0
- package/dist/services/workspace-supervisor.js +597 -0
- package/dist/services/workspace-supervisor.js.map +1 -0
- package/dist/types/agent-output.js +44 -0
- package/dist/types/agent-output.js.map +1 -0
- package/dist/types/config.js +28 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/edge-case.js +45 -0
- package/dist/types/edge-case.js.map +1 -0
- package/package.json +201 -176
- package/readme/README.md +19 -4
- package/scripts/artifact-cleanup.sh +392 -0
- package/scripts/backup-cleanup.sh +627 -0
- package/scripts/cleanup-workspaces.sh +412 -0
- package/scripts/cleanup-yaml-configs.sh +141 -0
- package/scripts/deploy-approved-skills.sh +263 -0
- package/scripts/deploy-production.sh +355 -355
- package/scripts/docker-playwright-fix.sh +311 -311
- package/scripts/docker-rebuild-all-agents.sh +127 -127
- package/scripts/health-check.sh +447 -0
- package/scripts/log-aggregator.sh +554 -0
- package/scripts/log-monitor.sh +629 -0
- package/scripts/manage-agent-workspaces.sh +434 -0
- package/scripts/memory-leak-prevention.sh +305 -305
- package/scripts/migrate-artifacts.sh +563 -0
- package/scripts/migrate-schema.sh +533 -0
- package/scripts/migrate-yaml-to-json.sh +465 -0
- package/scripts/promote-staged-skills.sh +423 -0
- package/scripts/run-marketing-tests.sh +42 -42
- package/scripts/update_paths.sh +46 -46
- package/scripts/verify-no-secrets.sh +88 -35
- package/.claude/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
- package/.claude/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
- package/.claude/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
- package/README.md.backup_before_replace +0 -781
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reflection Logger Service
|
|
3
|
+
* Task 5.3: ACE Reflection Persistence Standardization
|
|
4
|
+
*
|
|
5
|
+
* Manages reflection data flow: PostgreSQL → Redis (24h TTL) with automatic archival
|
|
6
|
+
*
|
|
7
|
+
* Performance targets:
|
|
8
|
+
* - Write to Redis: <100ms
|
|
9
|
+
* - Query spanning both: <200ms
|
|
10
|
+
* - Archive to PostgreSQL: <500ms (background)
|
|
11
|
+
*/ import { StandardError, ErrorCode } from '../lib/errors.js';
|
|
12
|
+
import { logger } from '../lib/logging.js';
|
|
13
|
+
const REDIS_TTL_SECONDS = 86400; // 24 hours
|
|
14
|
+
const ARCHIVE_THRESHOLD_SECONDS = 3600; // Archive when TTL < 1 hour
|
|
15
|
+
export class ReflectionLogger {
|
|
16
|
+
dbService;
|
|
17
|
+
redisAvailable = true;
|
|
18
|
+
reflectionLossCount = 0;
|
|
19
|
+
constructor(dbService){
|
|
20
|
+
this.dbService = dbService;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Log a reflection to Redis with 24h TTL and PostgreSQL for persistence
|
|
24
|
+
* Performance target: <100ms
|
|
25
|
+
*/ async logReflection(reflection) {
|
|
26
|
+
const startTime = Date.now();
|
|
27
|
+
// Validate reflection schema
|
|
28
|
+
this.validateReflection(reflection);
|
|
29
|
+
// Ensure timestamp is set
|
|
30
|
+
const reflectionWithTimestamp = {
|
|
31
|
+
...reflection,
|
|
32
|
+
timestamp: reflection.timestamp || new Date()
|
|
33
|
+
};
|
|
34
|
+
// Generate Redis key
|
|
35
|
+
const redisKey = this.buildRedisKey(reflectionWithTimestamp.agent_id, reflectionWithTimestamp.timestamp);
|
|
36
|
+
// Serialize reflection
|
|
37
|
+
const serialized = JSON.stringify(reflectionWithTimestamp);
|
|
38
|
+
try {
|
|
39
|
+
// Write to Redis with TTL
|
|
40
|
+
const redisAdapter = this.dbService.getAdapter('redis');
|
|
41
|
+
await redisAdapter.setex(redisKey, REDIS_TTL_SECONDS, serialized);
|
|
42
|
+
logger.debug('Reflection logged to Redis', {
|
|
43
|
+
agent_id: reflectionWithTimestamp.agent_id,
|
|
44
|
+
task_id: reflectionWithTimestamp.task_id,
|
|
45
|
+
key: redisKey,
|
|
46
|
+
ttl: REDIS_TTL_SECONDS
|
|
47
|
+
});
|
|
48
|
+
this.redisAvailable = true;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
// Graceful degradation: Redis unavailable
|
|
51
|
+
this.redisAvailable = false;
|
|
52
|
+
this.reflectionLossCount++;
|
|
53
|
+
logger.warn('Redis unavailable, falling back to PostgreSQL only', {
|
|
54
|
+
error: error instanceof Error ? error.message : String(error),
|
|
55
|
+
reflection_loss_count: this.reflectionLossCount
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// Always write to PostgreSQL for long-term persistence
|
|
59
|
+
try {
|
|
60
|
+
await this.writeToPostgreSQL(reflectionWithTimestamp);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
throw new StandardError(ErrorCode.DATABASE_ERROR, 'Failed to persist reflection to PostgreSQL', {
|
|
63
|
+
reflection,
|
|
64
|
+
error: error instanceof Error ? error.message : String(error)
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const duration = Date.now() - startTime;
|
|
68
|
+
logger.debug('Reflection logged', {
|
|
69
|
+
agent_id: reflectionWithTimestamp.agent_id,
|
|
70
|
+
duration_ms: duration,
|
|
71
|
+
redis_available: this.redisAvailable
|
|
72
|
+
});
|
|
73
|
+
if (duration >= 100) {
|
|
74
|
+
logger.warn('Reflection write exceeded performance target', {
|
|
75
|
+
duration_ms: duration,
|
|
76
|
+
target_ms: 100
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Query reflections spanning both Redis (recent) and PostgreSQL (archived)
|
|
82
|
+
* Performance target: <200ms
|
|
83
|
+
*/ async queryReflections(query) {
|
|
84
|
+
const startTime = Date.now();
|
|
85
|
+
const results = [];
|
|
86
|
+
// Query Redis for recent reflections
|
|
87
|
+
if (this.redisAvailable) {
|
|
88
|
+
try {
|
|
89
|
+
const redisResults = await this.queryRedis(query);
|
|
90
|
+
results.push(...redisResults);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
logger.warn('Redis query failed, using PostgreSQL only', {
|
|
93
|
+
error: error instanceof Error ? error.message : String(error)
|
|
94
|
+
});
|
|
95
|
+
this.redisAvailable = false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Query PostgreSQL for archived reflections
|
|
99
|
+
try {
|
|
100
|
+
const pgResults = await this.queryPostgreSQL(query);
|
|
101
|
+
results.push(...pgResults);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
logger.error('PostgreSQL query failed', {
|
|
104
|
+
error: error instanceof Error ? error.message : String(error)
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// Remove duplicates (prefer Redis version for recent data)
|
|
108
|
+
const uniqueResults = this.deduplicateResults(results);
|
|
109
|
+
// Sort by timestamp descending
|
|
110
|
+
uniqueResults.sort((a, b)=>{
|
|
111
|
+
const timeA = a.timestamp?.getTime() || 0;
|
|
112
|
+
const timeB = b.timestamp?.getTime() || 0;
|
|
113
|
+
return timeB - timeA;
|
|
114
|
+
});
|
|
115
|
+
const duration = Date.now() - startTime;
|
|
116
|
+
logger.debug('Reflections queried', {
|
|
117
|
+
count: uniqueResults.length,
|
|
118
|
+
duration_ms: duration
|
|
119
|
+
});
|
|
120
|
+
if (duration >= 200) {
|
|
121
|
+
logger.warn('Reflection query exceeded performance target', {
|
|
122
|
+
duration_ms: duration,
|
|
123
|
+
target_ms: 200
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return uniqueResults;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get aggregate statistics for reflections
|
|
130
|
+
*/ async getReflectionStats(agentId) {
|
|
131
|
+
const query = agentId ? {
|
|
132
|
+
agent_id: agentId
|
|
133
|
+
} : {};
|
|
134
|
+
const reflections = await this.queryReflections(query);
|
|
135
|
+
if (reflections.length === 0) {
|
|
136
|
+
return {
|
|
137
|
+
total_count: 0,
|
|
138
|
+
average_confidence: 0,
|
|
139
|
+
min_confidence: 0,
|
|
140
|
+
max_confidence: 0
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const confidences = reflections.map((r)=>r.confidence);
|
|
144
|
+
const sum = confidences.reduce((a, b)=>a + b, 0);
|
|
145
|
+
const byType = {};
|
|
146
|
+
reflections.forEach((r)=>{
|
|
147
|
+
byType[r.reflection_type] = (byType[r.reflection_type] || 0) + 1;
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
total_count: reflections.length,
|
|
151
|
+
average_confidence: sum / reflections.length,
|
|
152
|
+
min_confidence: Math.min(...confidences),
|
|
153
|
+
max_confidence: Math.max(...confidences),
|
|
154
|
+
by_type: byType
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Archive reflections approaching TTL expiration to PostgreSQL
|
|
159
|
+
* Runs as background task
|
|
160
|
+
* Performance target: <500ms per reflection
|
|
161
|
+
*/ async archiveExpiredReflections() {
|
|
162
|
+
if (!this.redisAvailable) {
|
|
163
|
+
logger.debug('Redis unavailable, skipping archive check');
|
|
164
|
+
return 0;
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
const redisAdapter = this.dbService.getAdapter('redis');
|
|
168
|
+
// Get all reflection keys
|
|
169
|
+
const keys = await redisAdapter.keys('reflection:*');
|
|
170
|
+
let archivedCount = 0;
|
|
171
|
+
for (const key of keys){
|
|
172
|
+
try {
|
|
173
|
+
// Check TTL
|
|
174
|
+
const ttl = await redisAdapter.ttl(key);
|
|
175
|
+
// Archive if TTL is approaching expiration
|
|
176
|
+
if (ttl > 0 && ttl < ARCHIVE_THRESHOLD_SECONDS) {
|
|
177
|
+
const data = await redisAdapter.get(key);
|
|
178
|
+
if (data) {
|
|
179
|
+
const reflection = JSON.parse(data);
|
|
180
|
+
// Ensure it's in PostgreSQL (idempotent)
|
|
181
|
+
await this.writeToPostgreSQL(reflection);
|
|
182
|
+
archivedCount++;
|
|
183
|
+
logger.debug('Reflection archived before expiration', {
|
|
184
|
+
key,
|
|
185
|
+
ttl,
|
|
186
|
+
agent_id: reflection.agent_id
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
} catch (error) {
|
|
191
|
+
logger.error('Failed to archive reflection', {
|
|
192
|
+
key,
|
|
193
|
+
error: error instanceof Error ? error.message : String(error)
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return archivedCount;
|
|
198
|
+
} catch (error) {
|
|
199
|
+
logger.error('Archive scan failed', {
|
|
200
|
+
error: error instanceof Error ? error.message : String(error)
|
|
201
|
+
});
|
|
202
|
+
return 0;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get reflection loss monitoring metrics
|
|
207
|
+
*/ getMonitoringMetrics() {
|
|
208
|
+
return {
|
|
209
|
+
redis_available: this.redisAvailable,
|
|
210
|
+
reflection_loss_count: this.reflectionLossCount
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// ========== Private Methods ==========
|
|
214
|
+
validateReflection(reflection) {
|
|
215
|
+
const errors = [];
|
|
216
|
+
if (!reflection.agent_id || reflection.agent_id.trim() === '') {
|
|
217
|
+
errors.push('agent_id is required and must not be empty');
|
|
218
|
+
}
|
|
219
|
+
if (!reflection.task_id || reflection.task_id.trim() === '') {
|
|
220
|
+
errors.push('task_id is required and must not be empty');
|
|
221
|
+
}
|
|
222
|
+
if (![
|
|
223
|
+
'confidence',
|
|
224
|
+
'status',
|
|
225
|
+
'progress',
|
|
226
|
+
'error',
|
|
227
|
+
'decision'
|
|
228
|
+
].includes(reflection.reflection_type)) {
|
|
229
|
+
errors.push('reflection_type must be one of: confidence, status, progress, error, decision');
|
|
230
|
+
}
|
|
231
|
+
if (typeof reflection.confidence !== 'number' || reflection.confidence < 0 || reflection.confidence > 1) {
|
|
232
|
+
errors.push('confidence must be a number between 0 and 1');
|
|
233
|
+
}
|
|
234
|
+
if (!reflection.payload || typeof reflection.payload !== 'object') {
|
|
235
|
+
errors.push('payload must be an object');
|
|
236
|
+
}
|
|
237
|
+
if (errors.length > 0) {
|
|
238
|
+
throw new StandardError(ErrorCode.VALIDATION_ERROR, 'Reflection validation failed', {
|
|
239
|
+
errors,
|
|
240
|
+
reflection
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
buildRedisKey(agentId, timestamp) {
|
|
245
|
+
const isoTimestamp = timestamp.toISOString();
|
|
246
|
+
return `reflection:${agentId}:${isoTimestamp}`;
|
|
247
|
+
}
|
|
248
|
+
async writeToPostgreSQL(reflection) {
|
|
249
|
+
const pgAdapter = this.dbService.getAdapter('postgres');
|
|
250
|
+
const query = `
|
|
251
|
+
INSERT INTO reflections (
|
|
252
|
+
agent_id,
|
|
253
|
+
task_id,
|
|
254
|
+
reflection_type,
|
|
255
|
+
confidence,
|
|
256
|
+
payload,
|
|
257
|
+
timestamp
|
|
258
|
+
) VALUES ($1, $2, $3, $4, $5, $6)
|
|
259
|
+
ON CONFLICT (agent_id, task_id, timestamp)
|
|
260
|
+
DO UPDATE SET
|
|
261
|
+
reflection_type = EXCLUDED.reflection_type,
|
|
262
|
+
confidence = EXCLUDED.confidence,
|
|
263
|
+
payload = EXCLUDED.payload
|
|
264
|
+
`;
|
|
265
|
+
const params = [
|
|
266
|
+
reflection.agent_id,
|
|
267
|
+
reflection.task_id,
|
|
268
|
+
reflection.reflection_type,
|
|
269
|
+
reflection.confidence,
|
|
270
|
+
JSON.stringify(reflection.payload),
|
|
271
|
+
reflection.timestamp || new Date()
|
|
272
|
+
];
|
|
273
|
+
await pgAdapter.execute(query, params);
|
|
274
|
+
}
|
|
275
|
+
async queryRedis(query) {
|
|
276
|
+
const redisAdapter = this.dbService.getAdapter('redis');
|
|
277
|
+
// Build Redis key pattern
|
|
278
|
+
let pattern = 'reflection:';
|
|
279
|
+
if (query.agent_id) {
|
|
280
|
+
pattern += `${query.agent_id}:`;
|
|
281
|
+
} else {
|
|
282
|
+
pattern += '*:';
|
|
283
|
+
}
|
|
284
|
+
pattern += '*';
|
|
285
|
+
const keys = await redisAdapter.keys(pattern);
|
|
286
|
+
const results = [];
|
|
287
|
+
for (const key of keys){
|
|
288
|
+
try {
|
|
289
|
+
const data = await redisAdapter.get(key);
|
|
290
|
+
if (data) {
|
|
291
|
+
const reflection = JSON.parse(data);
|
|
292
|
+
// Apply filters
|
|
293
|
+
if (this.matchesQuery(reflection, query)) {
|
|
294
|
+
results.push(reflection);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
} catch (error) {
|
|
298
|
+
logger.warn('Failed to parse Redis reflection', {
|
|
299
|
+
key,
|
|
300
|
+
error: error instanceof Error ? error.message : String(error)
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return results;
|
|
305
|
+
}
|
|
306
|
+
async queryPostgreSQL(query) {
|
|
307
|
+
const pgAdapter = this.dbService.getAdapter('postgres');
|
|
308
|
+
const conditions = [];
|
|
309
|
+
const params = [];
|
|
310
|
+
let paramIndex = 1;
|
|
311
|
+
if (query.agent_id) {
|
|
312
|
+
conditions.push(`agent_id = $${paramIndex++}`);
|
|
313
|
+
params.push(query.agent_id);
|
|
314
|
+
}
|
|
315
|
+
if (query.task_id) {
|
|
316
|
+
conditions.push(`task_id = $${paramIndex++}`);
|
|
317
|
+
params.push(query.task_id);
|
|
318
|
+
}
|
|
319
|
+
if (query.reflection_type) {
|
|
320
|
+
conditions.push(`reflection_type = $${paramIndex++}`);
|
|
321
|
+
params.push(query.reflection_type);
|
|
322
|
+
}
|
|
323
|
+
if (query.start_date) {
|
|
324
|
+
conditions.push(`timestamp >= $${paramIndex++}`);
|
|
325
|
+
params.push(query.start_date);
|
|
326
|
+
}
|
|
327
|
+
if (query.end_date) {
|
|
328
|
+
conditions.push(`timestamp <= $${paramIndex++}`);
|
|
329
|
+
params.push(query.end_date);
|
|
330
|
+
}
|
|
331
|
+
if (query.min_confidence !== undefined) {
|
|
332
|
+
conditions.push(`confidence >= $${paramIndex++}`);
|
|
333
|
+
params.push(query.min_confidence);
|
|
334
|
+
}
|
|
335
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
336
|
+
const sql = `
|
|
337
|
+
SELECT
|
|
338
|
+
agent_id,
|
|
339
|
+
task_id,
|
|
340
|
+
reflection_type,
|
|
341
|
+
confidence,
|
|
342
|
+
payload,
|
|
343
|
+
timestamp
|
|
344
|
+
FROM reflections
|
|
345
|
+
${whereClause}
|
|
346
|
+
ORDER BY timestamp DESC
|
|
347
|
+
`;
|
|
348
|
+
const result = await pgAdapter.query(sql, params);
|
|
349
|
+
return result.rows.map((row)=>({
|
|
350
|
+
agent_id: row.agent_id,
|
|
351
|
+
task_id: row.task_id,
|
|
352
|
+
reflection_type: row.reflection_type,
|
|
353
|
+
confidence: row.confidence,
|
|
354
|
+
payload: typeof row.payload === 'string' ? JSON.parse(row.payload) : row.payload,
|
|
355
|
+
timestamp: new Date(row.timestamp)
|
|
356
|
+
}));
|
|
357
|
+
}
|
|
358
|
+
matchesQuery(reflection, query) {
|
|
359
|
+
if (query.task_id && reflection.task_id !== query.task_id) {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
if (query.reflection_type && reflection.reflection_type !== query.reflection_type) {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
if (query.min_confidence !== undefined && reflection.confidence < query.min_confidence) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
if (query.start_date && reflection.timestamp && reflection.timestamp < query.start_date) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
if (query.end_date && reflection.timestamp && reflection.timestamp > query.end_date) {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
return true;
|
|
375
|
+
}
|
|
376
|
+
deduplicateResults(results) {
|
|
377
|
+
const seen = new Map();
|
|
378
|
+
for (const reflection of results){
|
|
379
|
+
const key = `${reflection.agent_id}:${reflection.task_id}:${reflection.timestamp?.toISOString()}`;
|
|
380
|
+
if (!seen.has(key)) {
|
|
381
|
+
seen.set(key, reflection);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return Array.from(seen.values());
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
//# sourceMappingURL=reflection-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/services/reflection-logger.ts"],"sourcesContent":["/**\r\n * Reflection Logger Service\r\n * Task 5.3: ACE Reflection Persistence Standardization\r\n *\r\n * Manages reflection data flow: PostgreSQL → Redis (24h TTL) with automatic archival\r\n *\r\n * Performance targets:\r\n * - Write to Redis: <100ms\r\n * - Query spanning both: <200ms\r\n * - Archive to PostgreSQL: <500ms (background)\r\n */\r\n\r\nimport { DatabaseService } from '../lib/database-service.js';\r\nimport { StandardError, ErrorCode } from '../lib/errors.js';\r\nimport { logger } from '../lib/logging.js';\r\n\r\nexport interface Reflection {\r\n agent_id: string;\r\n task_id: string;\r\n reflection_type: 'confidence' | 'status' | 'progress' | 'error' | 'decision';\r\n confidence: number;\r\n payload: Record<string, any>;\r\n timestamp?: Date;\r\n}\r\n\r\nexport interface ReflectionQuery {\r\n agent_id?: string;\r\n task_id?: string;\r\n reflection_type?: string;\r\n start_date?: Date;\r\n end_date?: Date;\r\n min_confidence?: number;\r\n}\r\n\r\nexport interface ReflectionStats {\r\n total_count: number;\r\n average_confidence: number;\r\n min_confidence: number;\r\n max_confidence: number;\r\n by_type?: Record<string, number>;\r\n}\r\n\r\nconst REDIS_TTL_SECONDS = 86400; // 24 hours\r\nconst ARCHIVE_THRESHOLD_SECONDS = 3600; // Archive when TTL < 1 hour\r\n\r\nexport class ReflectionLogger {\r\n private dbService: DatabaseService;\r\n private redisAvailable: boolean = true;\r\n private reflectionLossCount: number = 0;\r\n\r\n constructor(dbService: DatabaseService) {\r\n this.dbService = dbService;\r\n }\r\n\r\n /**\r\n * Log a reflection to Redis with 24h TTL and PostgreSQL for persistence\r\n * Performance target: <100ms\r\n */\r\n async logReflection(reflection: Reflection): Promise<void> {\r\n const startTime = Date.now();\r\n\r\n // Validate reflection schema\r\n this.validateReflection(reflection);\r\n\r\n // Ensure timestamp is set\r\n const reflectionWithTimestamp: Reflection = {\r\n ...reflection,\r\n timestamp: reflection.timestamp || new Date(),\r\n };\r\n\r\n // Generate Redis key\r\n const redisKey = this.buildRedisKey(\r\n reflectionWithTimestamp.agent_id,\r\n reflectionWithTimestamp.timestamp!\r\n );\r\n\r\n // Serialize reflection\r\n const serialized = JSON.stringify(reflectionWithTimestamp);\r\n\r\n try {\r\n // Write to Redis with TTL\r\n const redisAdapter = this.dbService.getAdapter('redis');\r\n await redisAdapter.setex(redisKey, REDIS_TTL_SECONDS, serialized);\r\n\r\n logger.debug('Reflection logged to Redis', {\r\n agent_id: reflectionWithTimestamp.agent_id,\r\n task_id: reflectionWithTimestamp.task_id,\r\n key: redisKey,\r\n ttl: REDIS_TTL_SECONDS,\r\n });\r\n\r\n this.redisAvailable = true;\r\n } catch (error) {\r\n // Graceful degradation: Redis unavailable\r\n this.redisAvailable = false;\r\n this.reflectionLossCount++;\r\n\r\n logger.warn('Redis unavailable, falling back to PostgreSQL only', {\r\n error: error instanceof Error ? error.message : String(error),\r\n reflection_loss_count: this.reflectionLossCount,\r\n });\r\n }\r\n\r\n // Always write to PostgreSQL for long-term persistence\r\n try {\r\n await this.writeToPostgreSQL(reflectionWithTimestamp);\r\n } catch (error) {\r\n throw new StandardError(\r\n ErrorCode.DATABASE_ERROR,\r\n 'Failed to persist reflection to PostgreSQL',\r\n { reflection, error: error instanceof Error ? error.message : String(error) }\r\n );\r\n }\r\n\r\n const duration = Date.now() - startTime;\r\n logger.debug('Reflection logged', {\r\n agent_id: reflectionWithTimestamp.agent_id,\r\n duration_ms: duration,\r\n redis_available: this.redisAvailable,\r\n });\r\n\r\n if (duration >= 100) {\r\n logger.warn('Reflection write exceeded performance target', {\r\n duration_ms: duration,\r\n target_ms: 100,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Query reflections spanning both Redis (recent) and PostgreSQL (archived)\r\n * Performance target: <200ms\r\n */\r\n async queryReflections(query: ReflectionQuery): Promise<Reflection[]> {\r\n const startTime = Date.now();\r\n\r\n const results: Reflection[] = [];\r\n\r\n // Query Redis for recent reflections\r\n if (this.redisAvailable) {\r\n try {\r\n const redisResults = await this.queryRedis(query);\r\n results.push(...redisResults);\r\n } catch (error) {\r\n logger.warn('Redis query failed, using PostgreSQL only', {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n this.redisAvailable = false;\r\n }\r\n }\r\n\r\n // Query PostgreSQL for archived reflections\r\n try {\r\n const pgResults = await this.queryPostgreSQL(query);\r\n results.push(...pgResults);\r\n } catch (error) {\r\n logger.error('PostgreSQL query failed', {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n }\r\n\r\n // Remove duplicates (prefer Redis version for recent data)\r\n const uniqueResults = this.deduplicateResults(results);\r\n\r\n // Sort by timestamp descending\r\n uniqueResults.sort((a, b) => {\r\n const timeA = a.timestamp?.getTime() || 0;\r\n const timeB = b.timestamp?.getTime() || 0;\r\n return timeB - timeA;\r\n });\r\n\r\n const duration = Date.now() - startTime;\r\n logger.debug('Reflections queried', {\r\n count: uniqueResults.length,\r\n duration_ms: duration,\r\n });\r\n\r\n if (duration >= 200) {\r\n logger.warn('Reflection query exceeded performance target', {\r\n duration_ms: duration,\r\n target_ms: 200,\r\n });\r\n }\r\n\r\n return uniqueResults;\r\n }\r\n\r\n /**\r\n * Get aggregate statistics for reflections\r\n */\r\n async getReflectionStats(agentId?: string): Promise<ReflectionStats> {\r\n const query: ReflectionQuery = agentId ? { agent_id: agentId } : {};\r\n const reflections = await this.queryReflections(query);\r\n\r\n if (reflections.length === 0) {\r\n return {\r\n total_count: 0,\r\n average_confidence: 0,\r\n min_confidence: 0,\r\n max_confidence: 0,\r\n };\r\n }\r\n\r\n const confidences = reflections.map(r => r.confidence);\r\n const sum = confidences.reduce((a, b) => a + b, 0);\r\n\r\n const byType: Record<string, number> = {};\r\n reflections.forEach(r => {\r\n byType[r.reflection_type] = (byType[r.reflection_type] || 0) + 1;\r\n });\r\n\r\n return {\r\n total_count: reflections.length,\r\n average_confidence: sum / reflections.length,\r\n min_confidence: Math.min(...confidences),\r\n max_confidence: Math.max(...confidences),\r\n by_type: byType,\r\n };\r\n }\r\n\r\n /**\r\n * Archive reflections approaching TTL expiration to PostgreSQL\r\n * Runs as background task\r\n * Performance target: <500ms per reflection\r\n */\r\n async archiveExpiredReflections(): Promise<number> {\r\n if (!this.redisAvailable) {\r\n logger.debug('Redis unavailable, skipping archive check');\r\n return 0;\r\n }\r\n\r\n try {\r\n const redisAdapter = this.dbService.getAdapter('redis');\r\n\r\n // Get all reflection keys\r\n const keys = await redisAdapter.keys('reflection:*');\r\n\r\n let archivedCount = 0;\r\n\r\n for (const key of keys) {\r\n try {\r\n // Check TTL\r\n const ttl = await redisAdapter.ttl(key);\r\n\r\n // Archive if TTL is approaching expiration\r\n if (ttl > 0 && ttl < ARCHIVE_THRESHOLD_SECONDS) {\r\n const data = await redisAdapter.get(key);\r\n\r\n if (data) {\r\n const reflection: Reflection = JSON.parse(data);\r\n\r\n // Ensure it's in PostgreSQL (idempotent)\r\n await this.writeToPostgreSQL(reflection);\r\n\r\n archivedCount++;\r\n\r\n logger.debug('Reflection archived before expiration', {\r\n key,\r\n ttl,\r\n agent_id: reflection.agent_id,\r\n });\r\n }\r\n }\r\n } catch (error) {\r\n logger.error('Failed to archive reflection', {\r\n key,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n }\r\n }\r\n\r\n return archivedCount;\r\n } catch (error) {\r\n logger.error('Archive scan failed', {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n return 0;\r\n }\r\n }\r\n\r\n /**\r\n * Get reflection loss monitoring metrics\r\n */\r\n getMonitoringMetrics(): { redis_available: boolean; reflection_loss_count: number } {\r\n return {\r\n redis_available: this.redisAvailable,\r\n reflection_loss_count: this.reflectionLossCount,\r\n };\r\n }\r\n\r\n // ========== Private Methods ==========\r\n\r\n private validateReflection(reflection: Reflection): void {\r\n const errors: string[] = [];\r\n\r\n if (!reflection.agent_id || reflection.agent_id.trim() === '') {\r\n errors.push('agent_id is required and must not be empty');\r\n }\r\n\r\n if (!reflection.task_id || reflection.task_id.trim() === '') {\r\n errors.push('task_id is required and must not be empty');\r\n }\r\n\r\n if (!['confidence', 'status', 'progress', 'error', 'decision'].includes(reflection.reflection_type)) {\r\n errors.push('reflection_type must be one of: confidence, status, progress, error, decision');\r\n }\r\n\r\n if (typeof reflection.confidence !== 'number' || reflection.confidence < 0 || reflection.confidence > 1) {\r\n errors.push('confidence must be a number between 0 and 1');\r\n }\r\n\r\n if (!reflection.payload || typeof reflection.payload !== 'object') {\r\n errors.push('payload must be an object');\r\n }\r\n\r\n if (errors.length > 0) {\r\n throw new StandardError(\r\n ErrorCode.VALIDATION_ERROR,\r\n 'Reflection validation failed',\r\n { errors, reflection }\r\n );\r\n }\r\n }\r\n\r\n private buildRedisKey(agentId: string, timestamp: Date): string {\r\n const isoTimestamp = timestamp.toISOString();\r\n return `reflection:${agentId}:${isoTimestamp}`;\r\n }\r\n\r\n private async writeToPostgreSQL(reflection: Reflection): Promise<void> {\r\n const pgAdapter = this.dbService.getAdapter('postgres');\r\n\r\n const query = `\r\n INSERT INTO reflections (\r\n agent_id,\r\n task_id,\r\n reflection_type,\r\n confidence,\r\n payload,\r\n timestamp\r\n ) VALUES ($1, $2, $3, $4, $5, $6)\r\n ON CONFLICT (agent_id, task_id, timestamp)\r\n DO UPDATE SET\r\n reflection_type = EXCLUDED.reflection_type,\r\n confidence = EXCLUDED.confidence,\r\n payload = EXCLUDED.payload\r\n `;\r\n\r\n const params = [\r\n reflection.agent_id,\r\n reflection.task_id,\r\n reflection.reflection_type,\r\n reflection.confidence,\r\n JSON.stringify(reflection.payload),\r\n reflection.timestamp || new Date(),\r\n ];\r\n\r\n await pgAdapter.execute(query, params);\r\n }\r\n\r\n private async queryRedis(query: ReflectionQuery): Promise<Reflection[]> {\r\n const redisAdapter = this.dbService.getAdapter('redis');\r\n\r\n // Build Redis key pattern\r\n let pattern = 'reflection:';\r\n\r\n if (query.agent_id) {\r\n pattern += `${query.agent_id}:`;\r\n } else {\r\n pattern += '*:';\r\n }\r\n\r\n pattern += '*';\r\n\r\n const keys = await redisAdapter.keys(pattern);\r\n\r\n const results: Reflection[] = [];\r\n\r\n for (const key of keys) {\r\n try {\r\n const data = await redisAdapter.get(key);\r\n\r\n if (data) {\r\n const reflection: Reflection = JSON.parse(data);\r\n\r\n // Apply filters\r\n if (this.matchesQuery(reflection, query)) {\r\n results.push(reflection);\r\n }\r\n }\r\n } catch (error) {\r\n logger.warn('Failed to parse Redis reflection', {\r\n key,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n }\r\n }\r\n\r\n return results;\r\n }\r\n\r\n private async queryPostgreSQL(query: ReflectionQuery): Promise<Reflection[]> {\r\n const pgAdapter = this.dbService.getAdapter('postgres');\r\n\r\n const conditions: string[] = [];\r\n const params: any[] = [];\r\n let paramIndex = 1;\r\n\r\n if (query.agent_id) {\r\n conditions.push(`agent_id = $${paramIndex++}`);\r\n params.push(query.agent_id);\r\n }\r\n\r\n if (query.task_id) {\r\n conditions.push(`task_id = $${paramIndex++}`);\r\n params.push(query.task_id);\r\n }\r\n\r\n if (query.reflection_type) {\r\n conditions.push(`reflection_type = $${paramIndex++}`);\r\n params.push(query.reflection_type);\r\n }\r\n\r\n if (query.start_date) {\r\n conditions.push(`timestamp >= $${paramIndex++}`);\r\n params.push(query.start_date);\r\n }\r\n\r\n if (query.end_date) {\r\n conditions.push(`timestamp <= $${paramIndex++}`);\r\n params.push(query.end_date);\r\n }\r\n\r\n if (query.min_confidence !== undefined) {\r\n conditions.push(`confidence >= $${paramIndex++}`);\r\n params.push(query.min_confidence);\r\n }\r\n\r\n const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\r\n\r\n const sql = `\r\n SELECT\r\n agent_id,\r\n task_id,\r\n reflection_type,\r\n confidence,\r\n payload,\r\n timestamp\r\n FROM reflections\r\n ${whereClause}\r\n ORDER BY timestamp DESC\r\n `;\r\n\r\n const result = await pgAdapter.query(sql, params);\r\n\r\n return result.rows.map(row => ({\r\n agent_id: row.agent_id,\r\n task_id: row.task_id,\r\n reflection_type: row.reflection_type,\r\n confidence: row.confidence,\r\n payload: typeof row.payload === 'string' ? JSON.parse(row.payload) : row.payload,\r\n timestamp: new Date(row.timestamp),\r\n }));\r\n }\r\n\r\n private matchesQuery(reflection: Reflection, query: ReflectionQuery): boolean {\r\n if (query.task_id && reflection.task_id !== query.task_id) {\r\n return false;\r\n }\r\n\r\n if (query.reflection_type && reflection.reflection_type !== query.reflection_type) {\r\n return false;\r\n }\r\n\r\n if (query.min_confidence !== undefined && reflection.confidence < query.min_confidence) {\r\n return false;\r\n }\r\n\r\n if (query.start_date && reflection.timestamp && reflection.timestamp < query.start_date) {\r\n return false;\r\n }\r\n\r\n if (query.end_date && reflection.timestamp && reflection.timestamp > query.end_date) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private deduplicateResults(results: Reflection[]): Reflection[] {\r\n const seen = new Map<string, Reflection>();\r\n\r\n for (const reflection of results) {\r\n const key = `${reflection.agent_id}:${reflection.task_id}:${reflection.timestamp?.toISOString()}`;\r\n\r\n if (!seen.has(key)) {\r\n seen.set(key, reflection);\r\n }\r\n }\r\n\r\n return Array.from(seen.values());\r\n }\r\n}\r\n"],"names":["StandardError","ErrorCode","logger","REDIS_TTL_SECONDS","ARCHIVE_THRESHOLD_SECONDS","ReflectionLogger","dbService","redisAvailable","reflectionLossCount","logReflection","reflection","startTime","Date","now","validateReflection","reflectionWithTimestamp","timestamp","redisKey","buildRedisKey","agent_id","serialized","JSON","stringify","redisAdapter","getAdapter","setex","debug","task_id","key","ttl","error","warn","Error","message","String","reflection_loss_count","writeToPostgreSQL","DATABASE_ERROR","duration","duration_ms","redis_available","target_ms","queryReflections","query","results","redisResults","queryRedis","push","pgResults","queryPostgreSQL","uniqueResults","deduplicateResults","sort","a","b","timeA","getTime","timeB","count","length","getReflectionStats","agentId","reflections","total_count","average_confidence","min_confidence","max_confidence","confidences","map","r","confidence","sum","reduce","byType","forEach","reflection_type","Math","min","max","by_type","archiveExpiredReflections","keys","archivedCount","data","get","parse","getMonitoringMetrics","errors","trim","includes","payload","VALIDATION_ERROR","isoTimestamp","toISOString","pgAdapter","params","execute","pattern","matchesQuery","conditions","paramIndex","start_date","end_date","undefined","whereClause","join","sql","result","rows","row","seen","Map","has","set","Array","from","values"],"mappings":"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"}
|