@event4u/agent-config 9.9.0 → 9.11.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-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +212 -194
- package/README.md +13 -16
- package/agents/templates/.ai-council.yml.example +481 -0
- package/agents/templates/.ai-video.xml.example +247 -0
- package/dist/agent-src/commands/agent-status.md +12 -11
- package/dist/agent-src/commands/agents/user/accept.md +115 -30
- package/dist/agent-src/commands/agents/user/delete.md +147 -0
- package/dist/agent-src/commands/agents/user/review.md +65 -28
- package/dist/agent-src/commands/agents/user/show.md +82 -29
- package/dist/agent-src/commands/agents/user/update.md +2 -2
- package/dist/agent-src/commands/agents/user.md +16 -3
- package/dist/agent-src/commands/check-current-md.md +0 -10
- package/dist/agent-src/commands/condense.md +28 -97
- package/dist/agent-src/commands/cost/report.md +7 -0
- package/dist/agent-src/commands/fix/portability.md +0 -8
- package/dist/agent-src/commands/fix/refs.md +0 -8
- package/dist/agent-src/commands/humanize.md +2 -2
- package/dist/agent-src/commands/jira-ticket.md +1 -1
- package/dist/agent-src/commands/memory/load.md +11 -0
- package/dist/agent-src/commands/optimize/skills.md +1 -1
- package/dist/agent-src/commands/pr/create.md +4 -4
- package/dist/agent-src/commands/profile/show.md +3 -3
- package/dist/agent-src/commands/rule-compliance-audit.md +5 -4
- package/dist/agent-src/commands/security-audit-config.md +1 -1
- package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
- package/dist/agent-src/commands/tdd.md +21 -0
- package/dist/agent-src/commands/team/delegate.md +2 -2
- package/dist/agent-src/commands/team-knowledge/bootstrap.md +9 -8
- package/dist/agent-src/commands/team-knowledge/consolidate.md +8 -7
- package/dist/agent-src/commands/team.md +4 -1
- package/dist/agent-src/commands/upstream-contribute.md +0 -1
- package/dist/agent-src/contexts/authority/commit-mechanics.md +7 -0
- package/dist/agent-src/contexts/authority/destructive-mechanics.md +16 -0
- package/dist/agent-src/contexts/authority/scope-mechanics.md +61 -0
- package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +20 -18
- package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/source-of-truth-mechanics.md +9 -10
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +11 -0
- package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +26 -15
- package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +3 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +67 -37
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
- package/dist/agent-src/contexts/execution/autonomy-examples.md +1 -1
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +7 -6
- package/dist/agent-src/contexts/execution/evidence-discipline.md +92 -77
- package/dist/agent-src/contexts/execution/orchestration-benchmark-gate.md +22 -21
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +24 -0
- package/dist/agent-src/contexts/execution/project-intelligence.md +122 -103
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +23 -21
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +5 -5
- package/dist/agent-src/contexts/execution/subagent-routing.md +11 -0
- package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +13 -13
- package/dist/agent-src/contexts/execution/subagent-steering.md +36 -34
- package/dist/agent-src/contexts/execution/toolchain-resolver.md +1 -1
- package/dist/agent-src/contexts/execution/user-memory-channels.md +189 -0
- package/dist/agent-src/contexts/execution/verification-mechanics.md +9 -0
- package/dist/agent-src/contexts/model-recommendations.md +3 -2
- package/dist/agent-src/contexts/subagent-configuration.md +3 -3
- package/dist/agent-src/ghostwriter/README.md +2 -2
- package/dist/agent-src/packs/README.md +1 -1
- package/dist/agent-src/personas/README.md +5 -5
- package/dist/agent-src/personas/_template-specialist/persona.md +3 -3
- package/dist/agent-src/personas/backend-architect.md +24 -23
- package/dist/agent-src/personas/eloquent-tamer.md +30 -30
- package/dist/agent-src/personas/frontend-engineer.md +30 -30
- package/dist/agent-src/personas/product-owner.md +41 -38
- package/dist/agent-src/personas/qa.md +13 -13
- package/dist/agent-src/personas/security-engineer.md +22 -22
- package/dist/agent-src/presets/README.md +3 -3
- package/dist/agent-src/profiles/README.md +3 -3
- package/dist/agent-src/rules/active-remediation.md +2 -2
- package/dist/agent-src/rules/artifact-engagement-recording.md +4 -4
- package/dist/agent-src/rules/ask-when-uncertain.md +0 -4
- package/dist/agent-src/rules/augment-edit-discipline.md +1 -1
- package/dist/agent-src/rules/broken-access-control.md +4 -4
- package/dist/agent-src/rules/code-comment-discipline.md +1 -1
- package/dist/agent-src/rules/code-provenance.md +2 -2
- package/dist/agent-src/rules/commit-policy.md +4 -9
- package/dist/agent-src/rules/communication-through-line.md +5 -5
- package/dist/agent-src/rules/decision-revisit-gate.md +1 -1
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
- package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +1 -1
- package/dist/agent-src/rules/external-code-graph-interop.md +1 -1
- package/dist/agent-src/rules/fast-path-marker-visibility.md +43 -7
- package/dist/agent-src/rules/finance-safety-floor.md +1 -1
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -3
- package/dist/agent-src/rules/history-discipline.md +1 -1
- package/dist/agent-src/rules/legal-safety-floor.md +1 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +5 -5
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +10 -8
- package/dist/agent-src/rules/media-governance-routing.md +13 -13
- package/dist/agent-src/rules/media-sync-ground-truth.md +29 -11
- package/dist/agent-src/rules/no-cheap-questions.md +7 -7
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +29 -18
- package/dist/agent-src/rules/non-destructive-by-default.md +5 -23
- package/dist/agent-src/rules/onboarding-gate.md +14 -4
- package/dist/agent-src/rules/persona-governance.md +2 -2
- package/dist/agent-src/rules/prefer-enums-over-literals.md +9 -9
- package/dist/agent-src/rules/preservation-guard.md +10 -2
- package/dist/agent-src/rules/question-not-instruction.md +1 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +6 -6
- package/dist/agent-src/rules/rule-type-governance.md +1 -1
- package/dist/agent-src/rules/scale-discipline.md +1 -1
- package/dist/agent-src/rules/scope-control.md +1 -1
- package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
- package/dist/agent-src/rules/security-sensitive-stop.md +17 -11
- package/dist/agent-src/rules/senior-engineering-discipline.md +17 -17
- package/dist/agent-src/rules/session-canary.md +1 -1
- package/dist/agent-src/rules/skill-quality.md +1 -1
- package/dist/agent-src/rules/source-confidentiality.md +21 -19
- package/dist/agent-src/rules/source-of-truth.md +6 -5
- package/dist/agent-src/rules/spreadsheet-source-quality.md +2 -2
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
- package/dist/agent-src/rules/think-before-action.md +5 -5
- package/dist/agent-src/rules/token-budget-discipline.md +5 -3
- package/dist/agent-src/rules/token-efficiency.md +2 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +4 -4
- package/dist/agent-src/rules/user-interaction.md +12 -0
- package/dist/agent-src/rules/verify-before-complete.md +4 -24
- package/dist/agent-src/skills/adversarial-review/SKILL.md +2 -2
- package/dist/agent-src/skills/agent-security-review/SKILL.md +52 -45
- package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +2 -2
- package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +20 -20
- package/dist/agent-src/skills/ai-council/SKILL.md +185 -128
- package/dist/agent-src/skills/analysis-skill-router/SKILL.md +3 -3
- package/dist/agent-src/skills/api-endpoint/SKILL.md +2 -2
- package/dist/agent-src/skills/artisan-commands/SKILL.md +2 -2
- package/dist/agent-src/skills/async-python-patterns/SKILL.md +8 -7
- package/dist/agent-src/skills/authz-review/SKILL.md +16 -15
- package/dist/agent-src/skills/aws-infrastructure/SKILL.md +5 -5
- package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +30 -12
- package/dist/agent-src/skills/code-intelligence/SKILL.md +0 -1
- package/dist/agent-src/skills/code-intelligence/evals/triggers.json +52 -0
- package/dist/agent-src/skills/code-review/SKILL.md +6 -6
- package/dist/agent-src/skills/command-routing/SKILL.md +5 -4
- package/dist/agent-src/skills/composer-packages/SKILL.md +2 -2
- package/dist/agent-src/skills/condense-memory/SKILL.md +43 -41
- package/dist/agent-src/skills/context-document/SKILL.md +23 -21
- package/dist/agent-src/skills/copilot-config/SKILL.md +6 -1
- package/dist/agent-src/skills/decision-record/SKILL.md +20 -18
- package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
- package/dist/agent-src/skills/design-review/SKILL.md +15 -14
- package/dist/agent-src/skills/design-system-capture/reference/design-system-json.md +28 -25
- package/dist/agent-src/skills/devcontainer/SKILL.md +2 -2
- package/dist/agent-src/skills/docker/SKILL.md +1 -1
- package/dist/agent-src/skills/docx-authoring/evals/triggers.json +52 -0
- package/dist/agent-src/skills/emit-tickets/SKILL.md +2 -2
- package/dist/agent-src/skills/error-handling-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +2 -2
- package/dist/agent-src/skills/evaluate-llm-feature/SKILL.md +0 -1
- package/dist/agent-src/skills/evaluate-llm-feature/evals/triggers.json +52 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +21 -7
- package/dist/agent-src/skills/fe-design/SKILL.md +10 -0
- package/dist/agent-src/skills/feature-planning/SKILL.md +2 -2
- package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +3 -3
- package/dist/agent-src/skills/flux/SKILL.md +1 -1
- package/dist/agent-src/skills/frontend-render-security/SKILL.md +13 -13
- package/dist/agent-src/skills/git-workflow/SKILL.md +33 -33
- package/dist/agent-src/skills/grafana/SKILL.md +5 -0
- package/dist/agent-src/skills/humanizer/SKILL.md +83 -66
- package/dist/agent-src/skills/humanizer/data/patterns.md +14 -14
- package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +4 -4
- package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +82 -37
- package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +17 -5
- package/dist/agent-src/skills/judge-injection-defense/SKILL.md +63 -25
- package/dist/agent-src/skills/judge-security-auditor/SKILL.md +2 -0
- package/dist/agent-src/skills/judge-synthesis/SKILL.md +72 -28
- package/dist/agent-src/skills/laravel-horizon/SKILL.md +5 -0
- package/dist/agent-src/skills/laravel-mail/SKILL.md +5 -4
- package/dist/agent-src/skills/laravel-middleware/SKILL.md +5 -4
- package/dist/agent-src/skills/laravel-notifications/SKILL.md +10 -9
- package/dist/agent-src/skills/laravel-pennant/SKILL.md +1 -1
- package/dist/agent-src/skills/laravel-pulse/SKILL.md +9 -8
- package/dist/agent-src/skills/laravel-reverb/SKILL.md +6 -5
- package/dist/agent-src/skills/laravel-scheduling/SKILL.md +6 -1
- package/dist/agent-src/skills/laravel-validation/SKILL.md +12 -0
- package/dist/agent-src/skills/launch-readiness/SKILL.md +1 -1
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +7 -7
- package/dist/agent-src/skills/learning-tutor/SKILL.md +44 -43
- package/dist/agent-src/skills/learning-tutor/evals/triggers.json +52 -0
- package/dist/agent-src/skills/license-compliance-audit/SKILL.md +7 -7
- package/dist/agent-src/skills/license-compliance-borrow-check/SKILL.md +3 -3
- package/dist/agent-src/skills/license-compliance-credits/SKILL.md +4 -4
- package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +0 -1
- package/dist/agent-src/skills/memory-consolidation/SKILL.md +69 -64
- package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -6
- package/dist/agent-src/skills/pdf-tools/evals/triggers.json +52 -0
- package/dist/agent-src/skills/performance-analysis/SKILL.md +7 -3
- package/dist/agent-src/skills/persona-improvement/SKILL.md +0 -2
- package/dist/agent-src/skills/persona-improvement/evals/triggers.json +52 -0
- package/dist/agent-src/skills/php-coder/SKILL.md +10 -0
- package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +129 -120
- package/dist/agent-src/skills/prediction-pool-optimizer/reference/ev-fixtures.md +36 -35
- package/dist/agent-src/skills/prediction-pool-optimizer/reference/odds-and-bonus.md +45 -41
- package/dist/agent-src/skills/project-analysis-core/SKILL.md +4 -4
- package/dist/agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +3 -3
- package/dist/agent-src/skills/project-analysis-react/SKILL.md +1 -1
- package/dist/agent-src/skills/project-analysis-symfony/SKILL.md +1 -1
- package/dist/agent-src/skills/project-analysis-zend-laminas/SKILL.md +2 -2
- package/dist/agent-src/skills/prompt-engineering-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/prompt-validator/SKILL.md +39 -39
- package/dist/agent-src/skills/quality-tools/SKILL.md +15 -15
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +55 -19
- package/dist/agent-src/skills/react-shadcn-ui/reference/registry.md +29 -27
- package/dist/agent-src/skills/readme-writing-package/SKILL.md +2 -2
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +25 -25
- package/dist/agent-src/skills/recursive-verification/SKILL.md +6 -5
- package/dist/agent-src/skills/refine-prompt/SKILL.md +1 -1
- package/dist/agent-src/skills/refine-ticket/SKILL.md +20 -2
- package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
- package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
- package/dist/agent-src/skills/roadmap-management/SKILL.md +80 -66
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +84 -77
- package/dist/agent-src/skills/rule-refactor/SKILL.md +1 -1
- package/dist/agent-src/skills/screenshot-hygiene/evals/triggers.json +52 -0
- package/dist/agent-src/skills/security-audit/SKILL.md +26 -9
- package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +38 -16
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +14 -11
- package/dist/agent-src/skills/skill-writing/SKILL.md +9 -8
- package/dist/agent-src/skills/song-to-script/SKILL.md +93 -85
- package/dist/agent-src/skills/sql-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +4 -3
- package/dist/agent-src/skills/standards-from-config/SKILL.md +61 -43
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +22 -8
- package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +28 -2
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +13 -13
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +22 -21
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
- package/dist/agent-src/skills/technical-specification/SKILL.md +5 -0
- package/dist/agent-src/skills/terraform/SKILL.md +2 -2
- package/dist/agent-src/skills/terragrunt/SKILL.md +8 -8
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +1 -1
- package/dist/agent-src/skills/threat-modeling/SKILL.md +19 -13
- package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +0 -1
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +9 -9
- package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -1
- package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +4 -6
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +67 -61
- package/dist/agent-src/skills/video-director/SKILL.md +7 -7
- package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -3
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/contexts/knowledge-pages.md +47 -45
- package/dist/agent-src/templates/contexts/lesson-card.md +2 -2
- package/dist/agent-src/templates/contexts/tenant-boundaries.md +2 -2
- package/dist/agent-src/templates/contexts.md +1 -1
- package/dist/agent-src/templates/features.md +1 -1
- package/dist/agent-src/templates/roadmaps.md +125 -116
- package/dist/agent-src/templates/rule.md +2 -1
- package/dist/agent-src/templates/scripts/pr_risk_review.ts +0 -0
- package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/dist/agent-src/templates/scripts/tier_usage_report.ts +2 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +22 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +21 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
- package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
- package/dist/agent-src/templates/scripts/work_engine/state.ts +21 -4
- package/dist/agent-src/user-types/README.md +8 -8
- package/dist/agent-src/user-types/galabau-field-crew.md +34 -33
- package/dist/agent-src/user-types/metalworking-shop.md +35 -34
- package/dist/agent-src/user-types/truck-driver.md +22 -20
- package/dist/cli/initRouting.js +74 -11
- package/dist/cli/initRouting.js.map +1 -1
- package/dist/cli/main.js +14 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/python/workspace_roles.js +2 -2
- package/dist/cli/python/workspace_roles.js.map +1 -1
- package/dist/cli-delegate/chunk-4SV3XGFA.js +6910 -0
- package/dist/cli-delegate/chunk-736JCWLM.js +1104 -0
- package/dist/cli-delegate/chunk-7DSAMZFU.js +356 -0
- package/dist/cli-delegate/chunk-7HQ52DHU.js +74 -0
- package/dist/cli-delegate/chunk-BJGXZNPM.js +266 -0
- package/dist/cli-delegate/chunk-FTAISGDQ.js +117 -0
- package/dist/cli-delegate/chunk-GME3Q44L.js +82 -0
- package/dist/cli-delegate/chunk-GRRPEPRN.js +336 -0
- package/dist/cli-delegate/chunk-HJ6DAJHR.js +502 -0
- package/dist/cli-delegate/chunk-IR7P7JWA.js +872 -0
- package/dist/cli-delegate/chunk-J55WI3RR.js +47 -0
- package/dist/cli-delegate/chunk-MCJYCQPF.js +35 -0
- package/dist/cli-delegate/chunk-NDJLNC6Q.js +169 -0
- package/dist/cli-delegate/chunk-OMIVVCG2.js +26 -0
- package/dist/cli-delegate/chunk-OY53J6II.js +7336 -0
- package/dist/cli-delegate/chunk-RDGRHAAB.js +259 -0
- package/dist/cli-delegate/chunk-TFG57JJM.js +1969 -0
- package/dist/cli-delegate/chunk-XX6TOPD7.js +715 -0
- package/dist/cli-delegate/chunk-YMFO6FDN.js +10603 -0
- package/dist/cli-delegate/cmd_analyze_session.js +294 -0
- package/dist/cli-delegate/cmd_conformance.js +646 -0
- package/dist/cli-delegate/cmd_converge.js +326 -0
- package/dist/cli-delegate/cmd_doctor.js +144 -0
- package/dist/cli-delegate/cmd_explain.js +2508 -0
- package/dist/cli-delegate/cmd_export.js +296 -0
- package/dist/cli-delegate/cmd_fleet.js +332 -0
- package/dist/cli-delegate/cmd_memory_get.js +3878 -0
- package/dist/cli-delegate/cmd_migrate.js +11 -0
- package/dist/cli-delegate/cmd_preflight.js +270 -0
- package/dist/cli-delegate/cmd_prune.js +444 -0
- package/dist/cli-delegate/cmd_refresh.js +28 -0
- package/dist/cli-delegate/cmd_settings_check.js +574 -0
- package/dist/cli-delegate/cmd_settings_migrate.js +223 -0
- package/dist/cli-delegate/cmd_sync.js +264 -0
- package/dist/cli-delegate/cmd_uninstall.js +656 -0
- package/dist/cli-delegate/cmd_update.js +425 -0
- package/dist/cli-delegate/cmd_upgrade.js +444 -0
- package/dist/cli-delegate/cmd_validate.js +305 -0
- package/dist/cli-delegate/cmd_versions.js +370 -0
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +100 -67
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +16 -10
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +7 -5
- package/dist/hooks/dispatch.js +186 -12
- package/dist/install/emit_host_rules_cli.js +2 -1
- package/dist/install/emit_host_rules_cli.js.map +1 -1
- package/dist/install/install.mjs +418 -378
- package/dist/install/rule_scope.js +5 -1
- package/dist/install/rule_scope.js.map +1 -1
- package/dist/install/toolDetection.js +40 -12
- package/dist/install/toolDetection.js.map +1 -1
- package/dist/install/wizard-plan.js +2 -2
- package/dist/install/wizard-plan.js.map +1 -1
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +2194 -1003
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/compile_time_toggles.js +48 -0
- package/dist/scripts/_lib/compile_time_toggles.js.map +1 -0
- package/dist/scripts/condense.js +234 -217
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +4 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/shared/userMd/utils.js +30 -0
- package/dist/shared/userMd/utils.js.map +1 -1
- package/dist/ui/assets/index-BpSQt5vm.js.map +1 -1
- package/docs/guidelines/agent-infra/api-cost-levers.md +56 -5
- package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +93 -33
- package/package.json +4 -2
- package/src/agent-src/templates/scripts/pr_risk_review.ts +0 -0
- package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/src/agent-src/templates/scripts/tier_usage_report.ts +2 -2
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
- package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
- package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +22 -2
- package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +21 -2
- package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
- package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
- package/src/agent-src/templates/scripts/work_engine/state.ts +21 -4
- package/src/config/agent-settings.template.yml +32 -2
- package/src/config/ci-local-parity.yml +142 -0
- package/src/config/discovery/packs.yml +7 -0
- package/src/config/evaluator-budgets.json +1 -1
- package/src/config/gate-coverage.yml +127 -0
- package/src/config/pack-size-budget.json +27 -0
- package/src/config/preamble-payload-budget.json +44 -0
- package/src/install/emit_host_rules_cli.ts +2 -1
- package/src/install/rule_scope.ts +5 -1
- package/src/install/toolDetection.ts +39 -8
- package/src/install/wizard-plan.ts +2 -2
- package/src/scripts/_cli/cmd_conformance.ts +2 -1
- package/src/scripts/_cli/cmd_converge.ts +2 -1
- package/src/scripts/_cli/cmd_doctor.ts +292 -15
- package/src/scripts/_cli/cmd_export.ts +2 -1
- package/src/scripts/_cli/cmd_fleet.ts +2 -1
- package/src/scripts/_cli/cmd_migrate.ts +2 -1
- package/src/scripts/_cli/cmd_preflight.ts +2 -1
- package/src/scripts/_cli/cmd_refresh.ts +2 -1
- package/src/scripts/_cli/cmd_update.ts +2 -1
- package/src/scripts/_cli/cmd_upgrade.ts +2 -1
- package/src/scripts/_cli/cmd_versions.ts +2 -1
- package/src/scripts/_cli/detection_report.ts +480 -0
- package/src/scripts/_dispatch.bash +52 -14
- package/src/scripts/_lib/agent_user_profile.ts +381 -0
- package/src/scripts/_lib/agents_overlay.ts +9 -0
- package/src/scripts/_lib/anchor_eval.ts +311 -0
- package/src/scripts/_lib/cc_transcript.ts +316 -0
- package/src/scripts/_lib/changelog_eras.ts +103 -9
- package/src/scripts/_lib/compile_time_toggles.ts +79 -0
- package/src/scripts/_lib/confusables.ts +101 -0
- package/src/scripts/_lib/duplicate_scope_census.ts +77 -0
- package/src/scripts/_lib/environment_detector.ts +441 -0
- package/src/scripts/_lib/managed_agents_folder.ts +181 -0
- package/src/scripts/_lib/package_root.ts +72 -0
- package/src/scripts/_lib/payload_hash_drift.ts +126 -0
- package/src/scripts/_lib/preservation_migration.ts +291 -0
- package/src/scripts/_lib/retrieval_sanitize.ts +166 -2
- package/src/scripts/_lib/scan_scope.ts +115 -0
- package/src/scripts/_lib/user_global_memory_audit.ts +187 -0
- package/src/scripts/_lib/user_global_observations.ts +830 -0
- package/src/scripts/_lib/user_global_revocations.ts +110 -0
- package/src/scripts/_lib/user_memory_gate_counters.ts +291 -0
- package/src/scripts/ai_council/blind_review.ts +0 -0
- package/src/scripts/ai_council/budget_guard.ts +90 -11
- package/src/scripts/ai_council/bundler.ts +2 -2
- package/src/scripts/ai_council/clients.ts +59 -3
- package/src/scripts/ai_council/config.ts +53 -7
- package/src/scripts/ai_council/modes.ts +68 -2
- package/src/scripts/ai_council/orchestrator.ts +54 -9
- package/src/scripts/ai_council/transport_resolver.ts +331 -0
- package/src/scripts/ai_team/team_dispatch.ts +17 -6
- package/src/scripts/anchor_eval_falsify.ts +198 -0
- package/src/scripts/anchor_scoring_run.ts +239 -0
- package/src/scripts/annotate_discovery.ts +1 -65
- package/src/scripts/bench_quality_run.ts +168 -4
- package/src/scripts/cache_realization_report.ts +782 -0
- package/src/scripts/check_artefact_count_messaging.ts +5 -1
- package/src/scripts/check_augment_description_cap.ts +15 -4
- package/src/scripts/check_bundle_path_leakage.ts +10 -4
- package/src/scripts/check_ci_local_parity.ts +317 -0
- package/src/scripts/check_condensation.ts +96 -191
- package/src/scripts/check_context_paths.ts +38 -9
- package/src/scripts/check_dependency_floors.ts +153 -0
- package/src/scripts/check_gate_coverage.ts +299 -0
- package/src/scripts/check_iron_law_prominence.ts +22 -1
- package/src/scripts/check_kernel_prefix_stability.ts +0 -0
- package/src/scripts/check_no_new_legacy_path.ts +16 -6
- package/src/scripts/check_no_roadmap_refs.ts +22 -9
- package/src/scripts/check_originality_freshness.ts +167 -0
- package/src/scripts/check_pack_size.ts +188 -0
- package/src/scripts/check_preamble_payload_budget.ts +130 -0
- package/src/scripts/check_proposal.ts +0 -0
- package/src/scripts/check_references.ts +0 -1
- package/src/scripts/check_safety_floor_untouched.ts +171 -24
- package/src/scripts/check_site_links.ts +62 -3
- package/src/scripts/ci_status.ts +0 -0
- package/src/scripts/cluster_near_miss_patterns.ts +0 -0
- package/src/scripts/code_graph/build.ts +0 -0
- package/src/scripts/command_suggester/types.ts +0 -0
- package/src/scripts/compile_router.ts +10 -14
- package/src/scripts/condense.sh +3 -4
- package/src/scripts/condense.ts +247 -228
- package/src/scripts/cost/track.mjs +168 -33
- package/src/scripts/cost_summary.ts +33 -1
- package/src/scripts/council_cli.ts +51 -5
- package/src/scripts/discovery_graph.ts +0 -0
- package/src/scripts/encoding_corpus.ts +500 -0
- package/src/scripts/encoding_corpus_report.ts +216 -0
- package/src/scripts/evaluator_umbrella.sh +34 -1
- package/src/scripts/generate_index.ts +19 -2
- package/src/scripts/install-hooks.sh +2 -2
- package/src/scripts/learning_sidecar.ts +0 -0
- package/src/scripts/lint_confusables.ts +10 -72
- package/src/scripts/lint_eval_fixture_citations.ts +113 -0
- package/src/scripts/lint_featured_skills.ts +0 -0
- package/src/scripts/lint_hidden_unicode.ts +208 -0
- package/src/scripts/lint_load_context.ts +17 -5
- package/src/scripts/lint_new_skill_gate.ts +9 -3
- package/src/scripts/lint_no_python_twin_rationale.ts +17 -2
- package/src/scripts/lint_originality.ts +1 -1
- package/src/scripts/lint_skill_originality.ts +1 -1
- package/src/scripts/lint_ticket_buildable.ts +1 -1
- package/src/scripts/lint_ui_stack_bundles.ts +170 -0
- package/src/scripts/mcp_server/tools.ts +4 -4
- package/src/scripts/measure_scope_dedup.ts +224 -0
- package/src/scripts/memory_lookup.ts +0 -0
- package/src/scripts/mine_session.ts +98 -0
- package/src/scripts/orchestration_payload_hash_drift.ts +145 -0
- package/src/scripts/preamble_byte_census.ts +574 -0
- package/src/scripts/probe_skill_registration.ts +2 -2
- package/src/scripts/redact_hook_capture.ts +13 -0
- package/src/scripts/release.ts +65 -10
- package/src/scripts/router_telemetry.ts +1 -1
- package/src/scripts/second_brain_retrieval.ts +14 -4
- package/src/scripts/skill_linter.ts +5 -0
- package/src/scripts/surface-tiers.yml +2 -0
- package/src/scripts/validate_pack_yaml.ts +0 -0
- package/src/server/schemas/settings.ts +8 -0
- package/src/shared/userMd/utils.ts +31 -0
- package/dist/agent-src/rules/telegraph-speak.md +0 -87
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The user-memory revocation ledger — Phase 4 of road-to-global-user-memory
|
|
3
|
+
* ("delete, revoke, audit").
|
|
4
|
+
*
|
|
5
|
+
* Reuses ADR-121's `.revocations.jsonl` tombstone-before-deletion pattern
|
|
6
|
+
* from `knowledge_global_promote.ts` (`append_tombstone` / `load_tombstones`)
|
|
7
|
+
* VERBATIM at the mechanism level: same filename, same single
|
|
8
|
+
* `fs.appendFileSync` per entry (never rewritten), same "the caller MUST
|
|
9
|
+
* call this BEFORE deleting the thing it documents" contract, same tolerant
|
|
10
|
+
* reader (a malformed line is skipped, never crashes the read), same
|
|
11
|
+
* per-domain ledger (this one lives under the `user/` root, exactly as
|
|
12
|
+
* ADR-121's lives under the knowledge store's own root — no line from one
|
|
13
|
+
* ledger is ever readable as a line of the other).
|
|
14
|
+
*
|
|
15
|
+
* The one adaptation ADR-121's shape cannot express unchanged: its
|
|
16
|
+
* `RevocationEntry.card_id` names a knowledge CARD, addressed by a stable,
|
|
17
|
+
* content-derived slug (`card_id_from`). Neither a buffered observation nor
|
|
18
|
+
* a `profile.md` field has an analogous natural id — the Phase 2/3 JSONL
|
|
19
|
+
* schema never added one, and a profile field is a YAML key, not a file
|
|
20
|
+
* with a stem. This module's entries therefore use `entity_id` in place of
|
|
21
|
+
* `card_id` — the generic name reflects that two different callers
|
|
22
|
+
* (`user_global_observations.ts`'s per-observation delete/purge,
|
|
23
|
+
* `agent_user_profile.ts`'s per-field revoke) share this ONE ledger rather
|
|
24
|
+
* than each inventing its own. Field order, the `{revoked_at, <id>, reason}`
|
|
25
|
+
* shape, and every operational guarantee are otherwise unchanged.
|
|
26
|
+
*/
|
|
27
|
+
import * as fs from 'node:fs';
|
|
28
|
+
import * as path from 'node:path';
|
|
29
|
+
|
|
30
|
+
import * as user_global_paths from './user_global_paths.js';
|
|
31
|
+
|
|
32
|
+
/** Relative-to-root path of the ledger — lives beside the profile/buffer it audits. */
|
|
33
|
+
export const REVOCATIONS_RELATIVE = path.join('user', '.revocations.jsonl');
|
|
34
|
+
|
|
35
|
+
/** One append-only tombstone line: what was revoked, when, and why. */
|
|
36
|
+
export interface RevocationEntry {
|
|
37
|
+
readonly revoked_at: string;
|
|
38
|
+
readonly entity_id: string;
|
|
39
|
+
readonly reason: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function _writeTarget(env: user_global_paths.EnvMap | null): string {
|
|
43
|
+
return user_global_paths.write_target(REVOCATIONS_RELATIVE, { env });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Append one tombstone line to the revocation ledger — the caller MUST call
|
|
48
|
+
* this BEFORE deleting the observation/field it documents. Append-only (a
|
|
49
|
+
* single `fs.appendFileSync`, never rewritten): no delete or purge call
|
|
50
|
+
* ever removes a prior tombstone, so the ledger stays a durable audit trail
|
|
51
|
+
* across every deletion path — mirroring `knowledge_global_promote.ts`'s
|
|
52
|
+
* `append_tombstone` exactly.
|
|
53
|
+
*/
|
|
54
|
+
export function appendTombstone(
|
|
55
|
+
entity_id: string,
|
|
56
|
+
reason: string,
|
|
57
|
+
options: { today?: string | undefined; env?: user_global_paths.EnvMap | null } = {},
|
|
58
|
+
): RevocationEntry {
|
|
59
|
+
const entry: RevocationEntry = {
|
|
60
|
+
revoked_at: options.today ?? new Date().toISOString().slice(0, 10),
|
|
61
|
+
entity_id,
|
|
62
|
+
reason: reason || 'no reason given',
|
|
63
|
+
};
|
|
64
|
+
const target = _writeTarget(options.env ?? null);
|
|
65
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
66
|
+
fs.appendFileSync(target, JSON.stringify(entry) + '\n', 'utf-8');
|
|
67
|
+
return entry;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Read the revocation ledger. Tolerant: missing file → []; malformed lines are skipped. */
|
|
71
|
+
export function loadTombstones(env?: user_global_paths.EnvMap | null): RevocationEntry[] {
|
|
72
|
+
const resolved = user_global_paths.resolve_with_fallback(REVOCATIONS_RELATIVE, {
|
|
73
|
+
env: env ?? null,
|
|
74
|
+
});
|
|
75
|
+
if (resolved === null) {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
let text: string;
|
|
79
|
+
try {
|
|
80
|
+
text = fs.readFileSync(resolved, 'utf-8');
|
|
81
|
+
} catch {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
const out: RevocationEntry[] = [];
|
|
85
|
+
for (const raw of text.split(/\r\n|\r|\n/)) {
|
|
86
|
+
const line = raw.trim();
|
|
87
|
+
if (!line) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const obj: unknown = JSON.parse(line);
|
|
92
|
+
if (
|
|
93
|
+
obj !== null &&
|
|
94
|
+
typeof obj === 'object' &&
|
|
95
|
+
!Array.isArray(obj) &&
|
|
96
|
+
typeof (obj as Record<string, unknown>)['entity_id'] === 'string'
|
|
97
|
+
) {
|
|
98
|
+
const rec = obj as Record<string, unknown>;
|
|
99
|
+
out.push({
|
|
100
|
+
revoked_at: String(rec['revoked_at'] ?? ''),
|
|
101
|
+
entity_id: rec['entity_id'] as string,
|
|
102
|
+
reason: String(rec['reason'] ?? ''),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
} catch {
|
|
106
|
+
// corrupt line — skip; never let one bad line crash the ledger read
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* The promotion-behaviour gate counters — road-to-global-user-memory Phase 5
|
|
4
|
+
* ("the gate that can actually fire").
|
|
5
|
+
*
|
|
6
|
+
* ADR-119 exists because a previous gate could never fire by construction:
|
|
7
|
+
* reuse could only accrue while the layer was ON, and ON was withheld pending
|
|
8
|
+
* reuse. ADR-138's Phase 5 gate is keyed to a different signal on purpose —
|
|
9
|
+
* **promotion behaviour**, which moves through human `/agents:user accept`
|
|
10
|
+
* decisions whether or not the global profile ever loads at session start.
|
|
11
|
+
* See `docs/decisions/ADR-138-global-user-profile-layer.md` § Promotion-
|
|
12
|
+
* behaviour gate for the kill-criterion this module's counters feed.
|
|
13
|
+
*
|
|
14
|
+
* Four counts, and nothing else:
|
|
15
|
+
*
|
|
16
|
+
* 1. `projects_with_ge_10_sessions` — how many projects reached the
|
|
17
|
+
* sessions floor the kill-criterion denominator needs.
|
|
18
|
+
* 2. `projects_with_promoted_observation` — how many of those (or any)
|
|
19
|
+
* projects have at least one promoted global observation.
|
|
20
|
+
* 3. `observations_proposed` — total candidates that reached
|
|
21
|
+
* the global buffer (Phase 2's `appendGlobalObservation` succeeding).
|
|
22
|
+
* 4. `observations_accepted` — total candidates a human
|
|
23
|
+
* confirmed via `/agents:user accept` (Phase 2's
|
|
24
|
+
* `applyObservationToGlobalProfile` writing the profile).
|
|
25
|
+
*
|
|
26
|
+
* PII-exclusion-by-construction (the same shape `orchestration-telemetry.md`
|
|
27
|
+
* and `artifact-engagement-recording.md` already use): the counter struct has
|
|
28
|
+
* **no field capable of holding free-form content** — every field is a
|
|
29
|
+
* non-negative integer count. There is no `payload`, `notes`, or `context`
|
|
30
|
+
* field to widen by accident, and `readGateCounters` drops any unknown key or
|
|
31
|
+
* non-numeric value on read rather than passing it through. Privacy is a
|
|
32
|
+
* property of the shape, not of a scrubbing pass that could fail.
|
|
33
|
+
*
|
|
34
|
+
* This module never decides WHEN a project crosses the ≥10-session floor or
|
|
35
|
+
* WHEN a project's first observation gets promoted — those are caller-side
|
|
36
|
+
* facts (a session-start counter, the `/agents:user accept` flow) that the
|
|
37
|
+
* caller already holds in memory at the moment it happens. This module only
|
|
38
|
+
* durably persists the four resulting counts. Honest boundary: a
|
|
39
|
+
* read-then-write race between two concurrent callers can under-count by one
|
|
40
|
+
* increment — acceptable for a single-user local CLI with no lock primitive
|
|
41
|
+
* elsewhere in this package (`_lib/installed_lock.ts` tracks installed files,
|
|
42
|
+
* not a mutex), and irrelevant to the gate's 90-day-window granularity.
|
|
43
|
+
*
|
|
44
|
+
* Path resolution mirrors every sibling global-root artefact
|
|
45
|
+
* (`user_global_observations.ts`, `agent_user_profile.ts`): honours
|
|
46
|
+
* `$EVENT4U_CONFIG_HOME`, falls back to `~/.event4u/agent-config/`, and reads
|
|
47
|
+
* the legacy `~/.config/agent-config/` location for pre-migration installs.
|
|
48
|
+
*/
|
|
49
|
+
import * as fs from 'node:fs';
|
|
50
|
+
import * as path from 'node:path';
|
|
51
|
+
|
|
52
|
+
import * as user_global_paths from './user_global_paths.js';
|
|
53
|
+
|
|
54
|
+
/** Relative-to-root path of the gate counters file. */
|
|
55
|
+
export const GATE_COUNTERS_RELATIVE = path.join('user', 'promotion-gate-counters.json');
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The gate's counter shape. Every field is a non-negative integer count —
|
|
59
|
+
* this interface can never carry a string, a path, an id, or an array; there
|
|
60
|
+
* is no field a caller could widen into free-form content without changing
|
|
61
|
+
* the type itself (verified by `tests/lib/user_memory_gate_counters.test.ts`'s
|
|
62
|
+
* shape test).
|
|
63
|
+
*/
|
|
64
|
+
/**
|
|
65
|
+
* The two project-level fields are **CANCELLED 2026-07-30** — kept in the struct
|
|
66
|
+
* so a reader finds the decision instead of the absence, never incremented. Both
|
|
67
|
+
* need a per-project record, and every primitive that can hold one either exposes
|
|
68
|
+
* the project set or, once coarsened past membership-testability, cannot resolve a
|
|
69
|
+
* 40% ratio at a cardinality in the tens. Reason + rejected candidates + the
|
|
70
|
+
* council review that forced the wording:
|
|
71
|
+
* agents/settings/contexts/promotion-gate-counting-primitive.md; the resulting
|
|
72
|
+
* narrowing of the kill criterion is recorded in ADR-138.
|
|
73
|
+
*/
|
|
74
|
+
export interface PromotionGateCounters {
|
|
75
|
+
readonly projects_with_ge_10_sessions: number;
|
|
76
|
+
readonly projects_with_promoted_observation: number;
|
|
77
|
+
readonly observations_proposed: number;
|
|
78
|
+
readonly observations_accepted: number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** The closed field set — anything else read from disk is dropped, never passed through. */
|
|
82
|
+
export const GATE_COUNTER_FIELDS = [
|
|
83
|
+
'projects_with_ge_10_sessions',
|
|
84
|
+
'projects_with_promoted_observation',
|
|
85
|
+
'observations_proposed',
|
|
86
|
+
'observations_accepted',
|
|
87
|
+
] as const satisfies readonly (keyof PromotionGateCounters)[];
|
|
88
|
+
|
|
89
|
+
/** All-zero starting state. */
|
|
90
|
+
export function zeroCounters(): PromotionGateCounters {
|
|
91
|
+
return {
|
|
92
|
+
projects_with_ge_10_sessions: 0,
|
|
93
|
+
projects_with_promoted_observation: 0,
|
|
94
|
+
observations_proposed: 0,
|
|
95
|
+
observations_accepted: 0,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** `true` iff `value` is a non-negative integer — the only shape a counter field may hold. */
|
|
100
|
+
function _isNonNegativeInteger(value: unknown): value is number {
|
|
101
|
+
return typeof value === 'number' && Number.isInteger(value) && value >= 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Coerce an arbitrary parsed-JSON value into a valid counters struct.
|
|
106
|
+
* Unknown keys are dropped; a field that is missing, non-numeric, negative,
|
|
107
|
+
* or non-integer falls back to `0` rather than throwing or passing the raw
|
|
108
|
+
* value through. This is the runtime half of the shape guarantee — the
|
|
109
|
+
* struct that comes out of a read can never carry anything the type doesn't
|
|
110
|
+
* already allow, even from a hand-edited or corrupted file on disk.
|
|
111
|
+
*/
|
|
112
|
+
export function coerceCounters(raw: unknown): PromotionGateCounters {
|
|
113
|
+
const rec =
|
|
114
|
+
raw !== null && typeof raw === 'object' && !Array.isArray(raw)
|
|
115
|
+
? (raw as Record<string, unknown>)
|
|
116
|
+
: {};
|
|
117
|
+
const zero = zeroCounters();
|
|
118
|
+
const out: Record<string, number> = { ...zero };
|
|
119
|
+
for (const field of GATE_COUNTER_FIELDS) {
|
|
120
|
+
const value = rec[field];
|
|
121
|
+
out[field] = _isNonNegativeInteger(value) ? value : 0;
|
|
122
|
+
}
|
|
123
|
+
return out as unknown as PromotionGateCounters;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// Path resolution — mirrors user_global_observations.ts / agent_user_profile.ts.
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
/** Canonical write target for the gate counters file. */
|
|
131
|
+
export function gateCountersWriteTarget(env?: user_global_paths.EnvMap | null): string {
|
|
132
|
+
return user_global_paths.write_target(GATE_COUNTERS_RELATIVE, { env: env ?? null });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Resolve the counters file's on-disk path — new namespace first, legacy fallback, `null` if neither exists. */
|
|
136
|
+
export function resolveGateCountersPath(env?: user_global_paths.EnvMap | null): string | null {
|
|
137
|
+
return user_global_paths.resolve_with_fallback(GATE_COUNTERS_RELATIVE, { env: env ?? null });
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
// Read / write
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
/** Read the current counters. Missing file, missing directory, or malformed JSON all resolve to `zeroCounters()` — never throws. */
|
|
145
|
+
export function readGateCounters(
|
|
146
|
+
options: { env?: user_global_paths.EnvMap | null } = {},
|
|
147
|
+
): PromotionGateCounters {
|
|
148
|
+
const target = resolveGateCountersPath(options.env ?? null);
|
|
149
|
+
if (target === null) {
|
|
150
|
+
return zeroCounters();
|
|
151
|
+
}
|
|
152
|
+
let raw: string;
|
|
153
|
+
try {
|
|
154
|
+
raw = fs.readFileSync(target, 'utf-8');
|
|
155
|
+
} catch {
|
|
156
|
+
return zeroCounters();
|
|
157
|
+
}
|
|
158
|
+
let parsed: unknown;
|
|
159
|
+
try {
|
|
160
|
+
parsed = JSON.parse(raw);
|
|
161
|
+
} catch {
|
|
162
|
+
return zeroCounters();
|
|
163
|
+
}
|
|
164
|
+
return coerceCounters(parsed);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Persist `counters` verbatim to the write target, creating the parent directory if needed. */
|
|
168
|
+
function _writeGateCounters(
|
|
169
|
+
counters: PromotionGateCounters,
|
|
170
|
+
options: { env?: user_global_paths.EnvMap | null } = {},
|
|
171
|
+
): void {
|
|
172
|
+
const target = gateCountersWriteTarget(options.env ?? null);
|
|
173
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
174
|
+
fs.writeFileSync(target, JSON.stringify(coerceCounters(counters)) + '\n', 'utf-8');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
// Pure increments — no disk access, easy to unit-test in isolation.
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
|
|
181
|
+
/** One project just crossed the ≥10-sessions floor. Caller dedupes per-project — this module holds no project identity. */
|
|
182
|
+
export function incrementProjectsWithTenSessions(
|
|
183
|
+
counters: PromotionGateCounters,
|
|
184
|
+
): PromotionGateCounters {
|
|
185
|
+
return { ...counters, projects_with_ge_10_sessions: counters.projects_with_ge_10_sessions + 1 };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** One project just got its FIRST promoted global observation. Caller dedupes per-project — this module holds no project identity. */
|
|
189
|
+
export function incrementProjectsWithPromotedObservation(
|
|
190
|
+
counters: PromotionGateCounters,
|
|
191
|
+
): PromotionGateCounters {
|
|
192
|
+
return {
|
|
193
|
+
...counters,
|
|
194
|
+
projects_with_promoted_observation: counters.projects_with_promoted_observation + 1,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** One observation candidate reached the global buffer (a Phase 2/3 `appendGlobalObservation` success). */
|
|
199
|
+
export function incrementObservationsProposed(
|
|
200
|
+
counters: PromotionGateCounters,
|
|
201
|
+
): PromotionGateCounters {
|
|
202
|
+
return { ...counters, observations_proposed: counters.observations_proposed + 1 };
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** One observation candidate was confirmed via `/agents:user accept` (a Phase 2 `applyObservationToGlobalProfile` write). */
|
|
206
|
+
export function incrementObservationsAccepted(
|
|
207
|
+
counters: PromotionGateCounters,
|
|
208
|
+
): PromotionGateCounters {
|
|
209
|
+
return { ...counters, observations_accepted: counters.observations_accepted + 1 };
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
// Disk-touching wrappers — read, increment, write, return the new value.
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
|
|
216
|
+
/** Record one project crossing the ≥10-sessions floor. */
|
|
217
|
+
export function recordProjectReachedTenSessions(
|
|
218
|
+
options: { env?: user_global_paths.EnvMap | null } = {},
|
|
219
|
+
): PromotionGateCounters {
|
|
220
|
+
const next = incrementProjectsWithTenSessions(readGateCounters(options));
|
|
221
|
+
_writeGateCounters(next, options);
|
|
222
|
+
return next;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Record one project's first promoted observation. */
|
|
226
|
+
export function recordProjectPromotedFirstObservation(
|
|
227
|
+
options: { env?: user_global_paths.EnvMap | null } = {},
|
|
228
|
+
): PromotionGateCounters {
|
|
229
|
+
const next = incrementProjectsWithPromotedObservation(readGateCounters(options));
|
|
230
|
+
_writeGateCounters(next, options);
|
|
231
|
+
return next;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/** Record one observation reaching the global buffer. */
|
|
235
|
+
export function recordObservationProposed(
|
|
236
|
+
options: { env?: user_global_paths.EnvMap | null } = {},
|
|
237
|
+
): PromotionGateCounters {
|
|
238
|
+
const next = incrementObservationsProposed(readGateCounters(options));
|
|
239
|
+
_writeGateCounters(next, options);
|
|
240
|
+
return next;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Record one observation confirmed via `/agents:user accept`. */
|
|
244
|
+
export function recordObservationAccepted(
|
|
245
|
+
options: { env?: user_global_paths.EnvMap | null } = {},
|
|
246
|
+
): PromotionGateCounters {
|
|
247
|
+
const next = incrementObservationsAccepted(readGateCounters(options));
|
|
248
|
+
_writeGateCounters(next, options);
|
|
249
|
+
return next;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ---------------------------------------------------------------------------
|
|
253
|
+
// Kill-criterion evaluation — see ADR-138 § Promotion-behaviour gate.
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
|
|
256
|
+
/** Human-confirmed floor: below this share of ≥10-session projects carrying a promotion, the teardown review is mandatory. */
|
|
257
|
+
export const PROJECT_PROMOTION_SHARE_FLOOR = 0.4;
|
|
258
|
+
|
|
259
|
+
/** Human-confirmed floor: below this review→accept rate, the teardown review is mandatory. */
|
|
260
|
+
export const REVIEW_ACCEPT_RATE_FLOOR = 0.3;
|
|
261
|
+
|
|
262
|
+
export interface KillCriterionResult {
|
|
263
|
+
/** `null` when `projects_with_ge_10_sessions` is `0` — the ratio is undefined, not zero, until there is a qualifying project. */
|
|
264
|
+
readonly project_promotion_share: number | null;
|
|
265
|
+
/** `null` when `observations_proposed` is `0` — same undefined-vs-zero distinction. */
|
|
266
|
+
readonly review_accept_rate: number | null;
|
|
267
|
+
/** `true` iff either floor is breached with a defined ratio — an undefined ratio never trips the gate on its own. */
|
|
268
|
+
readonly teardown_review_required: boolean;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Evaluate the two kill-criterion floors from ADR-138 § Promotion-behaviour
|
|
273
|
+
* gate against the current counters. A ratio with a zero denominator is
|
|
274
|
+
* reported as `null` (undefined), not `0` or `1` — an empty gate has not yet
|
|
275
|
+
* failed, it has not yet been exercised, and the ADR's window (90 days from
|
|
276
|
+
* release) is what turns "not yet exercised" into a real finding.
|
|
277
|
+
*/
|
|
278
|
+
export function evaluateKillCriterion(counters: PromotionGateCounters): KillCriterionResult {
|
|
279
|
+
const project_promotion_share =
|
|
280
|
+
counters.projects_with_ge_10_sessions > 0
|
|
281
|
+
? counters.projects_with_promoted_observation / counters.projects_with_ge_10_sessions
|
|
282
|
+
: null;
|
|
283
|
+
const review_accept_rate =
|
|
284
|
+
counters.observations_proposed > 0
|
|
285
|
+
? counters.observations_accepted / counters.observations_proposed
|
|
286
|
+
: null;
|
|
287
|
+
const teardown_review_required =
|
|
288
|
+
(project_promotion_share !== null && project_promotion_share < PROJECT_PROMOTION_SHARE_FLOOR) ||
|
|
289
|
+
(review_accept_rate !== null && review_accept_rate < REVIEW_ACCEPT_RATE_FLOOR);
|
|
290
|
+
return { project_promotion_share, review_accept_rate, teardown_review_required };
|
|
291
|
+
}
|
|
Binary file
|
|
@@ -12,9 +12,13 @@
|
|
|
12
12
|
* same permission discipline as the API keys). The legacy
|
|
13
13
|
* `~/.config/agent-config/council-spend.jsonl` is read as a fallback.
|
|
14
14
|
*
|
|
15
|
-
* Contract (verbatim from the Python module
|
|
15
|
+
* Contract (verbatim from the Python module, plus the additive TS-only
|
|
16
|
+
* cache extension below):
|
|
16
17
|
* - The ledger is **append-only**. Each line is `{"ts": ISO-8601 UTC,
|
|
17
|
-
* "usd": float, "provider": str, "model": str}
|
|
18
|
+
* "usd": float, "provider": str, "model": str}`, optionally followed by
|
|
19
|
+
* `"cache_read_input_tokens": int, "cache_creation_input_tokens": int,
|
|
20
|
+
* "cache_ttl": "5m"|"1h"` when the caller reports cache activity — absent
|
|
21
|
+
* on every entry recorded before this extension shipped.
|
|
18
22
|
* - `today_spend_usd()` sums entries within the last 24h from "now".
|
|
19
23
|
* - `would_exceed(limit_usd, next_call_usd)` returns true iff the next call
|
|
20
24
|
* would push the rolling window past the limit.
|
|
@@ -75,6 +79,12 @@ export interface SpendEntry {
|
|
|
75
79
|
usd: number;
|
|
76
80
|
provider: string;
|
|
77
81
|
model: string;
|
|
82
|
+
// Prompt-cache accounting (additive — absent on entries recorded before
|
|
83
|
+
// this field existed, and on calls with no cache activity to report).
|
|
84
|
+
cache_read_input_tokens?: number;
|
|
85
|
+
cache_creation_input_tokens?: number;
|
|
86
|
+
/** Write-multiplier TTL tier in effect when this entry was recorded. */
|
|
87
|
+
cache_ttl?: '5m' | '1h';
|
|
78
88
|
}
|
|
79
89
|
|
|
80
90
|
function _nowUtcMs(): number {
|
|
@@ -259,14 +269,37 @@ function _pyJsonString(s: string): string {
|
|
|
259
269
|
* `json.dumps({"ts": ts, "usd": round(usd, 6), "provider": provider,
|
|
260
270
|
* "model": model})` does: default separators (`", "`, `": "`), insertion
|
|
261
271
|
* order (NOT sorted). `usd` is a float (`pyFloatRepr`); the rest are strings.
|
|
272
|
+
*
|
|
273
|
+
* The three cache params are appended only when the CALLER passed them
|
|
274
|
+
* (`!== undefined`) — a call with none of the three reproduces the original
|
|
275
|
+
* 4-key line byte-for-byte, which is what keeps every pre-existing caller
|
|
276
|
+
* (and the python3 byte-parity test, which has no Python-side cache
|
|
277
|
+
* counterpart) unaffected by this additive extension.
|
|
262
278
|
*/
|
|
263
|
-
function _dumpEntry(
|
|
264
|
-
|
|
265
|
-
|
|
279
|
+
function _dumpEntry(
|
|
280
|
+
ts: string,
|
|
281
|
+
usd: number,
|
|
282
|
+
provider: string,
|
|
283
|
+
model: string,
|
|
284
|
+
cacheRead?: number,
|
|
285
|
+
cacheWrite?: number,
|
|
286
|
+
cacheTtl?: '5m' | '1h',
|
|
287
|
+
): string {
|
|
288
|
+
let body =
|
|
289
|
+
`${_pyJsonString('ts')}: ${_pyJsonString(ts)}, ` +
|
|
266
290
|
`${_pyJsonString('usd')}: ${pyFloatRepr(usd)}, ` +
|
|
267
291
|
`${_pyJsonString('provider')}: ${_pyJsonString(provider)}, ` +
|
|
268
|
-
`${_pyJsonString('model')}: ${_pyJsonString(model)}
|
|
269
|
-
)
|
|
292
|
+
`${_pyJsonString('model')}: ${_pyJsonString(model)}`;
|
|
293
|
+
if (cacheRead !== undefined) {
|
|
294
|
+
body += `, ${_pyJsonString('cache_read_input_tokens')}: ${Math.trunc(cacheRead)}`;
|
|
295
|
+
}
|
|
296
|
+
if (cacheWrite !== undefined) {
|
|
297
|
+
body += `, ${_pyJsonString('cache_creation_input_tokens')}: ${Math.trunc(cacheWrite)}`;
|
|
298
|
+
}
|
|
299
|
+
if (cacheTtl !== undefined) {
|
|
300
|
+
body += `, ${_pyJsonString('cache_ttl')}: ${_pyJsonString(cacheTtl)}`;
|
|
301
|
+
}
|
|
302
|
+
return `{${body}}`;
|
|
270
303
|
}
|
|
271
304
|
|
|
272
305
|
/** Coerce a parsed JSON value to a float like Python's `float(obj.get(...))`. */
|
|
@@ -366,16 +399,46 @@ export function read_entries(p: string | null = null): SpendEntry[] {
|
|
|
366
399
|
if (usd === null) {
|
|
367
400
|
continue;
|
|
368
401
|
}
|
|
369
|
-
|
|
402
|
+
const entry: SpendEntry = {
|
|
370
403
|
ts,
|
|
371
404
|
usd,
|
|
372
405
|
provider: _toStr(record.provider, ''),
|
|
373
406
|
model: _toStr(record.model, ''),
|
|
374
|
-
}
|
|
407
|
+
};
|
|
408
|
+
// exactOptionalPropertyTypes forbids `key: undefined` on an object
|
|
409
|
+
// literal — assign conditionally so a legacy (or cache-less) line
|
|
410
|
+
// leaves these keys absent rather than present-but-undefined.
|
|
411
|
+
const cacheRead = _toOptionalNonNegInt(record.cache_read_input_tokens);
|
|
412
|
+
if (cacheRead !== undefined) {
|
|
413
|
+
entry.cache_read_input_tokens = cacheRead;
|
|
414
|
+
}
|
|
415
|
+
const cacheWrite = _toOptionalNonNegInt(record.cache_creation_input_tokens);
|
|
416
|
+
if (cacheWrite !== undefined) {
|
|
417
|
+
entry.cache_creation_input_tokens = cacheWrite;
|
|
418
|
+
}
|
|
419
|
+
const cacheTtl = _toOptionalTtl(record.cache_ttl);
|
|
420
|
+
if (cacheTtl !== undefined) {
|
|
421
|
+
entry.cache_ttl = cacheTtl;
|
|
422
|
+
}
|
|
423
|
+
out.push(entry);
|
|
375
424
|
}
|
|
376
425
|
return out;
|
|
377
426
|
}
|
|
378
427
|
|
|
428
|
+
/** A non-negative finite number, or `undefined` when absent/malformed. */
|
|
429
|
+
function _toOptionalNonNegInt(v: unknown): number | undefined {
|
|
430
|
+
if (v === undefined || v === null) {
|
|
431
|
+
return undefined;
|
|
432
|
+
}
|
|
433
|
+
const n = _toFloat(v);
|
|
434
|
+
return n === null || n < 0 ? undefined : n;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/** `'5m' | '1h'`, or `undefined` for anything else (including absent). */
|
|
438
|
+
function _toOptionalTtl(v: unknown): '5m' | '1h' | undefined {
|
|
439
|
+
return v === '5m' || v === '1h' ? v : undefined;
|
|
440
|
+
}
|
|
441
|
+
|
|
379
442
|
/** `str(obj.get("ts", ""))` — the timestamp is read as a string before parsing. */
|
|
380
443
|
function _rawStr(v: unknown): string {
|
|
381
444
|
if (v === undefined) {
|
|
@@ -424,7 +487,15 @@ export function record_spend(
|
|
|
424
487
|
usd: number,
|
|
425
488
|
provider: string,
|
|
426
489
|
model: string,
|
|
427
|
-
options: {
|
|
490
|
+
options: {
|
|
491
|
+
path?: string | null;
|
|
492
|
+
now?: number | null;
|
|
493
|
+
// Additive prompt-cache accounting (Step B). Omitting all three
|
|
494
|
+
// reproduces the original 4-field ledger line exactly.
|
|
495
|
+
cache_read_input_tokens?: number;
|
|
496
|
+
cache_creation_input_tokens?: number;
|
|
497
|
+
cache_ttl?: '5m' | '1h';
|
|
498
|
+
} = {},
|
|
428
499
|
): boolean {
|
|
429
500
|
if (usd <= 0) {
|
|
430
501
|
return true; // zero-cost calls (manual mode) skip the ledger
|
|
@@ -435,7 +506,15 @@ export function record_spend(
|
|
|
435
506
|
}
|
|
436
507
|
const nowMs = options.now ?? _nowUtcMs();
|
|
437
508
|
const ts = nowUtcIso(nowMs);
|
|
438
|
-
const entry = `${_dumpEntry(
|
|
509
|
+
const entry = `${_dumpEntry(
|
|
510
|
+
ts,
|
|
511
|
+
_pyRound6(usd),
|
|
512
|
+
provider,
|
|
513
|
+
model,
|
|
514
|
+
options.cache_read_input_tokens,
|
|
515
|
+
options.cache_creation_input_tokens,
|
|
516
|
+
options.cache_ttl,
|
|
517
|
+
)}\n`;
|
|
439
518
|
try {
|
|
440
519
|
fs.appendFileSync(p, entry, { encoding: 'utf-8' });
|
|
441
520
|
} catch (exc) {
|
|
@@ -263,7 +263,7 @@ export function bundle_diff_with_context(
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
const root = cwd ? cwd : '.';
|
|
266
|
-
const seen = new Set<string>(); // `${file}
|
|
266
|
+
const seen = new Set<string>(); // `${file}\0${signature_line}`
|
|
267
267
|
// Preserve insertion order of first-seen files (Python dict order).
|
|
268
268
|
const byFile = new Map<string, Array<[number, string]>>();
|
|
269
269
|
|
|
@@ -279,7 +279,7 @@ export function bundle_diff_with_context(
|
|
|
279
279
|
if (sig === null) {
|
|
280
280
|
continue;
|
|
281
281
|
}
|
|
282
|
-
const key = `${filePath}
|
|
282
|
+
const key = `${filePath}\0${sig[0]}`;
|
|
283
283
|
if (seen.has(key)) {
|
|
284
284
|
continue;
|
|
285
285
|
}
|