@event4u/agent-config 6.1.0 → 7.0.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 +35 -3
- package/AGENTS.md +8 -7
- package/CHANGELOG.md +408 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +17 -15
- package/dist/agent-src/commands/agent-status.md +2 -2
- package/dist/agent-src/commands/agents/audit.md +3 -3
- package/dist/agent-src/commands/agents/init.md +1 -1
- package/dist/agent-src/commands/agents/optimize.md +4 -4
- package/dist/agent-src/commands/analyze/decision.md +108 -0
- package/dist/agent-src/commands/analyze/incident.md +120 -0
- package/dist/agent-src/commands/analyze/near-miss.md +113 -0
- package/dist/agent-src/commands/analyze/postmortem.md +130 -0
- package/dist/agent-src/commands/analyze/premortem.md +104 -0
- package/dist/agent-src/commands/analyze.md +124 -0
- package/dist/agent-src/commands/brand/identity.md +27 -0
- package/dist/agent-src/commands/brand/review.md +27 -0
- package/dist/agent-src/commands/brand/strategy.md +27 -0
- package/dist/agent-src/commands/brand/tokens.md +28 -0
- package/dist/agent-src/commands/brand/voice.md +27 -0
- package/dist/agent-src/commands/brand.md +58 -0
- package/dist/agent-src/commands/check-current-md.md +3 -3
- package/dist/agent-src/commands/condense.md +2 -2
- package/dist/agent-src/commands/council/debate.md +2 -2
- package/dist/agent-src/commands/council/default.md +45 -18
- package/dist/agent-src/commands/fix/portability.md +3 -3
- package/dist/agent-src/commands/fix/refs.md +3 -3
- package/dist/agent-src/commands/implement-ticket.md +36 -6
- package/dist/agent-src/commands/knowledge/cross-repo.md +1 -1
- package/dist/agent-src/commands/memory/add.md +1 -1
- package/dist/agent-src/commands/mission/upgrade.md +182 -0
- package/dist/agent-src/commands/optimize/skills.md +2 -2
- package/dist/agent-src/commands/orchestrate.md +1 -1
- package/dist/agent-src/commands/pr/create.md +6 -4
- package/dist/agent-src/commands/review-changes.md +8 -0
- package/dist/agent-src/commands/roadmap/materialize.md +73 -0
- package/dist/agent-src/commands/skill/preview.md +1 -1
- package/dist/agent-src/commands/skills/discover.md +1 -1
- package/dist/agent-src/commands/threat-model.md +4 -4
- package/dist/agent-src/commands/upstream-contribute.md +3 -3
- package/dist/agent-src/commands/video/from-script.md +2 -2
- package/dist/agent-src/commands/video/from-song.md +3 -3
- package/dist/agent-src/commands/video/scene.md +1 -1
- package/dist/agent-src/commands/video/storyboard.md +1 -1
- package/dist/agent-src/commands/video.md +3 -3
- package/dist/agent-src/contexts/communication/rules-auto/source-of-truth-mechanics.md +3 -3
- package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +1 -1
- package/dist/agent-src/contexts/execution/evidence-discipline.md +153 -0
- package/dist/agent-src/contexts/execution/project-intelligence.md +264 -0
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +2 -1
- package/dist/agent-src/personas/ai-video-technical-director.md +1 -1
- package/dist/agent-src/personas/brand-strategist.md +74 -0
- package/dist/agent-src/personas/design-director.md +74 -0
- package/dist/agent-src/rules/brand-consistency.md +77 -0
- package/dist/agent-src/rules/brand-source-of-truth.md +57 -0
- package/dist/agent-src/rules/direct-answers.md +2 -0
- package/dist/agent-src/rules/domain-safety-disclaimer.md +2 -0
- package/dist/agent-src/rules/git-history-discipline.md +1 -0
- package/dist/agent-src/rules/icon-consistency.md +53 -0
- package/dist/agent-src/rules/image-likeness-and-rights.md +67 -0
- package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -1
- package/dist/agent-src/rules/persona-governance.md +2 -2
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +10 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +9 -3
- package/dist/agent-src/rules/size-enforcement.md +1 -1
- package/dist/agent-src/rules/source-confidentiality.md +3 -3
- package/dist/agent-src/rules/source-discovery-gate.md +98 -0
- package/dist/agent-src/rules/think-before-action.md +1 -0
- package/dist/agent-src/rules/ui-audit-gate.md +2 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +1 -1
- package/dist/agent-src/rules/user-interaction.md +1 -1
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +392 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +824 -0
- package/dist/agent-src/skills/adr-create/SKILL.md +5 -5
- package/dist/agent-src/skills/agent-security-review/evals/triggers.json +1 -0
- package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +1 -1
- package/dist/agent-src/skills/ai-council/SKILL.md +1 -1
- package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +9 -13
- package/dist/agent-src/skills/blade-ui/SKILL.md +12 -5
- package/dist/agent-src/skills/blameless-post-mortem/SKILL.md +199 -0
- package/dist/agent-src/skills/brand/ATTRIBUTION.md +38 -0
- package/dist/agent-src/skills/brand/SKILL.md +115 -0
- package/dist/agent-src/skills/brand/data/archetypes.csv +13 -0
- package/dist/agent-src/skills/brand/data/color-psychology.csv +14 -0
- package/dist/agent-src/skills/brand/data/logo-style-fit.csv +13 -0
- package/dist/agent-src/skills/brand/data/manifest.json +226 -0
- package/dist/agent-src/skills/brand/data/messaging-frameworks.csv +13 -0
- package/dist/agent-src/skills/brand/data/naming-patterns.csv +13 -0
- package/dist/agent-src/skills/brand/data/typography-principles.csv +13 -0
- package/dist/agent-src/skills/brand/data/voice-tone.csv +13 -0
- package/dist/agent-src/skills/brand/evals/triggers.json +17 -0
- package/dist/agent-src/skills/brand-asset-generation/SKILL.md +89 -0
- package/dist/agent-src/skills/brand-asset-generation/evals/triggers.json +17 -0
- package/dist/agent-src/skills/brand-audit/SKILL.md +67 -0
- package/dist/agent-src/skills/brand-audit/evals/triggers.json +17 -0
- package/dist/agent-src/skills/brand-identity/SKILL.md +101 -0
- package/dist/agent-src/skills/brand-identity/evals/triggers.json +17 -0
- package/dist/agent-src/skills/brand-strategy/SKILL.md +83 -0
- package/dist/agent-src/skills/brand-strategy/evals/triggers.json +17 -0
- package/dist/agent-src/skills/brand-to-tokens/SKILL.md +102 -0
- package/dist/agent-src/skills/brand-to-tokens/evals/triggers.json +17 -0
- package/dist/agent-src/skills/brand-to-tokens/templates/marp-brand-deck.md.example +46 -0
- package/dist/agent-src/skills/brand-to-tokens/templates/reveal-brand-deck.yaml +32 -0
- package/dist/agent-src/skills/canvas-design/evals/triggers.json +1 -0
- package/dist/agent-src/skills/check-refs/SKILL.md +5 -5
- package/dist/agent-src/skills/code-review/SKILL.md +6 -15
- package/dist/agent-src/skills/command-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/complexity-first-planning/evals/triggers.json +1 -0
- package/dist/agent-src/skills/context-authoring/SKILL.md +2 -2
- package/dist/agent-src/skills/context-document/SKILL.md +35 -2
- package/dist/agent-src/skills/corpus-grounding/evals/triggers.json +1 -0
- package/dist/agent-src/skills/corpus-grounding/scripts/bm25_search.ts +482 -0
- package/dist/agent-src/skills/corpus-grounding/scripts/decision_engine.ts +803 -0
- package/dist/agent-src/skills/corpus-grounding/scripts/ground.ts +541 -0
- package/dist/agent-src/skills/corpus-grounding/scripts/schema_validator.ts +309 -0
- package/dist/agent-src/skills/database/SKILL.md +26 -4
- package/dist/agent-src/skills/decision-record/SKILL.md +1 -1
- package/dist/agent-src/skills/decision-record/evals/triggers.json +17 -0
- package/dist/agent-src/skills/decision-review/SKILL.md +179 -0
- package/dist/agent-src/skills/description-assist/SKILL.md +1 -1
- package/dist/agent-src/skills/design-intelligence/SKILL.md +1 -1
- package/dist/agent-src/skills/design-intelligence/data/manifest.json +23 -6
- package/dist/agent-src/skills/design-intelligence/evals/triggers.json +1 -0
- package/dist/agent-src/skills/design-tokens/evals/triggers.json +1 -0
- package/dist/agent-src/skills/design-tokens/scripts/tokens.ts +888 -0
- package/dist/agent-src/skills/doc-coauthoring/evals/triggers.json +1 -0
- package/dist/agent-src/skills/eloquent/evals/triggers.json +1 -0
- package/dist/agent-src/skills/emit-tickets/SKILL.md +198 -0
- package/dist/agent-src/skills/estimate-ticket/evals/triggers.json +1 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +33 -0
- package/dist/agent-src/skills/guideline-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/iconography/SKILL.md +88 -0
- package/dist/agent-src/skills/iconography/evals/triggers.json +17 -0
- package/dist/agent-src/skills/image-analyser/evals/triggers.json +1 -0
- package/dist/agent-src/skills/image-creator/evals/triggers.json +1 -0
- package/dist/agent-src/skills/image-editing/SKILL.md +100 -0
- package/dist/agent-src/skills/image-editing/evals/triggers.json +17 -0
- package/dist/agent-src/skills/image-generation/SKILL.md +95 -0
- package/dist/agent-src/skills/image-generation/evals/triggers.json +17 -0
- package/dist/agent-src/skills/image-provider-routing/SKILL.md +96 -0
- package/dist/agent-src/skills/image-provider-routing/evals/triggers.json +17 -0
- package/dist/agent-src/skills/launch-readiness/SKILL.md +21 -0
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +12 -8
- package/dist/agent-src/skills/lint-skills/SKILL.md +5 -5
- package/dist/agent-src/skills/logo-generation/SKILL.md +98 -0
- package/dist/agent-src/skills/logo-generation/evals/triggers.json +17 -0
- package/dist/agent-src/skills/markitdown/SKILL.md +1 -1
- package/dist/agent-src/skills/md-language-check/SKILL.md +1 -1
- package/dist/agent-src/skills/motion-choreographer/SKILL.md +1 -1
- package/dist/agent-src/skills/php-coder/evals/triggers.json +1 -0
- package/dist/agent-src/skills/prediction-pool-optimizer/evals/triggers.json +1 -0
- package/dist/agent-src/skills/premortem/SKILL.md +137 -0
- package/dist/agent-src/skills/prompt-engineering-image/SKILL.md +115 -0
- package/dist/agent-src/skills/prompt-engineering-image/evals/triggers.json +17 -0
- package/dist/agent-src/skills/prompt-validator/evals/triggers.json +1 -0
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +12 -5
- package/dist/agent-src/skills/react-shadcn-ui/scripts/shadcn_add.ts +388 -0
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +1 -1
- package/dist/agent-src/skills/reasoning-orchestrator/evals/triggers.json +1 -0
- package/dist/agent-src/skills/refine-ticket/evals/triggers.json +1 -0
- package/dist/agent-src/skills/roadmap-management/SKILL.md +16 -3
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +76 -0
- package/dist/agent-src/skills/root-cause-frameworks/SKILL.md +146 -0
- package/dist/agent-src/skills/rule-refactor/SKILL.md +9 -9
- package/dist/agent-src/skills/rule-writing/SKILL.md +7 -7
- package/dist/agent-src/skills/script-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/security-audit/SKILL.md +5 -0
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +19 -3
- package/dist/agent-src/skills/skill-management/SKILL.md +3 -3
- package/dist/agent-src/skills/skill-reviewer/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-writing/SKILL.md +5 -5
- package/dist/agent-src/skills/skill-writing/evals/triggers.json +1 -0
- package/dist/agent-src/skills/source-discovery/SKILL.md +182 -0
- package/dist/agent-src/skills/standards-from-config/SKILL.md +93 -0
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +7 -0
- package/dist/agent-src/skills/tailwind-engineer/scripts/tailwind_config_gen.ts +561 -0
- package/dist/agent-src/skills/threat-modeling/SKILL.md +1 -0
- package/dist/agent-src/skills/typography-system/SKILL.md +138 -0
- package/dist/agent-src/skills/typography-system/evals/triggers.json +17 -0
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +3 -3
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +209 -0
- package/dist/agent-src/skills/verify-repair-loop/evals/output-schema.yml +20 -0
- package/dist/agent-src/skills/verify-repair-loop/evals/triggers.json +17 -0
- package/dist/agent-src/templates/agent-settings.md +7 -0
- package/dist/agent-src/templates/contexts/knowledge-card.md +69 -0
- package/dist/agent-src/templates/contexts/lesson-card.md +73 -0
- package/dist/agent-src/templates/roadmaps.md +29 -1
- package/dist/agent-src/templates/scripts/README.md +6 -6
- package/dist/agent-src/templates/scripts/check_memory.ts +640 -0
- package/dist/agent-src/templates/scripts/check_memory_proposal.ts +351 -0
- package/dist/agent-src/templates/scripts/implement_ticket/__main__.ts +27 -0
- package/dist/agent-src/templates/scripts/memory_hash.ts +333 -0
- package/dist/agent-src/templates/scripts/memory_lookup.ts +1067 -0
- package/dist/agent-src/templates/scripts/memory_report.ts +846 -0
- package/dist/agent-src/templates/scripts/memory_signal.ts +422 -0
- package/dist/agent-src/templates/scripts/memory_status.ts +191 -0
- package/dist/agent-src/templates/scripts/pr_review_routing.ts +523 -0
- 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/telemetry/boundary.ts +164 -0
- package/dist/agent-src/templates/scripts/telemetry/engagement.ts +479 -0
- package/dist/agent-src/templates/scripts/telemetry/report_renderer.ts +394 -0
- package/dist/agent-src/templates/scripts/telemetry/settings.ts +210 -0
- package/dist/agent-src/templates/scripts/telemetry_record.ts +255 -0
- package/dist/agent-src/templates/scripts/telemetry_report.ts +189 -0
- package/dist/agent-src/templates/scripts/telemetry_status.ts +312 -0
- package/dist/agent-src/templates/scripts/tier_usage_report.ts +597 -0
- package/dist/agent-src/templates/scripts/work_engine/__main__.ts +14 -0
- package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +1118 -0
- package/dist/agent-src/templates/scripts/work_engine/_lib/user_global_paths.ts +329 -0
- package/dist/agent-src/templates/scripts/work_engine/cli.ts +206 -0
- package/dist/agent-src/templates/scripts/work_engine/cli_args.ts +249 -0
- package/dist/agent-src/templates/scripts/work_engine/delivery_state.ts +225 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/analyze.ts +125 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +189 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +94 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/memory.ts +193 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/plan.ts +267 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/refine.ts +518 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/report.ts +379 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +268 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +258 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/index.ts +32 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/contract.ts +243 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/index.ts +108 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +259 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/ui.ts +216 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/_passthrough.ts +40 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +241 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +216 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +506 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +325 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/index.ts +102 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +462 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +474 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +352 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/_skipped.ts +33 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/apply.ts +213 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/index.ts +111 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/refine.ts +126 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/report.ts +112 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/test.ts +164 -0
- package/dist/agent-src/templates/scripts/work_engine/dispatcher.ts +515 -0
- package/dist/agent-src/templates/scripts/work_engine/emitters.ts +119 -0
- package/dist/agent-src/templates/scripts/work_engine/errors.ts +24 -0
- package/dist/agent-src/templates/scripts/work_engine/hook_bootstrap.ts +104 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/_chat_history_base.ts +176 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_append.ts +41 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_halt_append.ts +89 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_gate.ts +193 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +304 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/directive_set_guard.ts +110 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/halt_surface_audit.ts +118 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/index.ts +17 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +161 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/state_shape_validation.ts +45 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/trace.ts +134 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/context.ts +94 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/events.ts +58 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/exceptions.ts +85 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/index.ts +27 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/registry.ts +66 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/runner.ts +90 -0
- package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +260 -0
- package/dist/agent-src/templates/scripts/work_engine/input_builders.ts +260 -0
- package/dist/agent-src/templates/scripts/work_engine/intent/classify.ts +466 -0
- package/dist/agent-src/templates/scripts/work_engine/migration/v0_to_v1.ts +531 -0
- package/dist/agent-src/templates/scripts/work_engine/orchestration.ts +366 -0
- package/dist/agent-src/templates/scripts/work_engine/persona_policy.ts +97 -0
- package/dist/agent-src/templates/scripts/work_engine/resolvers/diff.ts +135 -0
- package/dist/agent-src/templates/scripts/work_engine/resolvers/file.ts +175 -0
- package/dist/agent-src/templates/scripts/work_engine/resolvers/prompt.ts +115 -0
- package/dist/agent-src/templates/scripts/work_engine/scoring/confidence.ts +415 -0
- package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +466 -0
- package/dist/agent-src/templates/scripts/work_engine/scoring/decision_trace.ts +298 -0
- package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +444 -0
- package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +252 -0
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +745 -0
- package/dist/agent-src/templates/scripts/work_engine/state.ts +1151 -0
- package/dist/agent-src/templates/scripts/work_engine/state_io.ts +413 -0
- package/dist/agent-src/templates/tickets.md +120 -0
- package/dist/cli/commands/commands.js +2 -2
- package/dist/cli/commands/commands.js.map +1 -1
- package/dist/cli/commands/doctorShell.js +4 -22
- package/dist/cli/commands/doctorShell.js.map +1 -1
- package/dist/cli/commands/packs.js +1 -1
- package/dist/cli/commands/packs.js.map +1 -1
- package/dist/cli/commands/recordTriggerEval.js +179 -0
- package/dist/cli/commands/recordTriggerEval.js.map +1 -0
- package/dist/cli/commands/recordTriggerEval.test.js +113 -0
- package/dist/cli/commands/recordTriggerEval.test.js.map +1 -0
- package/dist/cli/commands/workspaces.js +1 -1
- package/dist/cli/commands/workspaces.js.map +1 -1
- package/dist/cli/main.js +22 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/python/knowledge_ingest.js +1048 -0
- package/dist/cli/python/knowledge_ingest.js.map +1 -0
- package/dist/cli/python/workspace_analytics.js +1085 -0
- package/dist/cli/python/workspace_analytics.js.map +1 -0
- package/dist/cli/python/workspace_crypto.js +544 -0
- package/dist/cli/python/workspace_crypto.js.map +1 -0
- package/dist/cli/python/workspace_documents.js +1216 -0
- package/dist/cli/python/workspace_documents.js.map +1 -0
- package/dist/cli/python/workspace_drive.js +574 -0
- package/dist/cli/python/workspace_drive.js.map +1 -0
- package/dist/cli/python/workspace_drive_health.js +628 -0
- package/dist/cli/python/workspace_drive_health.js.map +1 -0
- package/dist/cli/python/workspace_explain.js +765 -0
- package/dist/cli/python/workspace_explain.js.map +1 -0
- package/dist/cli/python/workspace_hosts.js +349 -0
- package/dist/cli/python/workspace_hosts.js.map +1 -0
- package/dist/cli/python/workspace_inbox.js +692 -0
- package/dist/cli/python/workspace_inbox.js.map +1 -0
- package/dist/cli/python/workspace_render.js +816 -0
- package/dist/cli/python/workspace_render.js.map +1 -0
- package/dist/cli/python/workspace_roles.js +487 -0
- package/dist/cli/python/workspace_roles.js.map +1 -0
- package/dist/cli/python/workspace_secrets.js +180 -0
- package/dist/cli/python/workspace_secrets.js.map +1 -0
- package/dist/cli/python/workspace_sessions.js +1079 -0
- package/dist/cli/python/workspace_sessions.js.map +1 -0
- package/dist/cli/python/workspace_skills.js +417 -0
- package/dist/cli/python/workspace_skills.js.map +1 -0
- package/dist/cli/registry.js +2 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +1174 -123
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +9 -6
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +163 -15
- package/dist/discovery/trust-report.md +4 -4
- package/dist/discovery/workspaces.json +73 -12
- package/dist/install/install.mjs +13934 -0
- package/dist/mcp/registry-manifest.json +4 -4
- package/dist/router.json +1 -1
- package/dist/server/routes/wizard.js +50 -21
- package/dist/server/routes/wizard.js.map +1 -1
- package/dist/server/routes/workspace.js +44 -25
- package/dist/server/routes/workspace.js.map +1 -1
- package/dist/server/schemas/settings.js +15 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/SKILL_CENSUS.md +344 -0
- package/docs/architecture/augment-projection.md +1 -1
- package/docs/architecture/multi-tool-projection.md +3 -3
- package/docs/architecture.md +37 -6
- package/docs/benchmark.md +24 -27
- package/docs/capability-matrix.md +32 -0
- package/docs/catalog.md +50 -9
- package/docs/command-naming-audit.md +60 -0
- package/docs/contracts/STABILITY.md +32 -0
- package/docs/contracts/agents-md-tech-stack.md +1 -1
- package/docs/contracts/ai-council-config.md +22 -22
- package/docs/contracts/analysis-memory-loop.md +149 -0
- package/docs/contracts/benchmark-ab-contract.md +3 -3
- package/docs/contracts/branch-protection-policy.md +27 -0
- package/docs/contracts/brand-token-consumption.md +69 -0
- package/docs/contracts/command-clusters.md +2 -1
- package/docs/contracts/command-surface-tiers.md +13 -0
- package/docs/contracts/discovery-manifest.schema.json +24 -5
- package/docs/contracts/implement-ticket-flow.md +9 -9
- package/docs/contracts/install-layout.md +249 -0
- package/docs/contracts/kernel-membership.md +1 -1
- package/docs/contracts/linear-ai-rules-inclusion.md +2 -2
- package/docs/contracts/linter-structural-model.md +1 -1
- package/docs/contracts/mcp-discovery-phase-notice.md +1 -1
- package/docs/contracts/multi-tool-projection-fidelity.md +1 -1
- package/docs/contracts/namespace.md +2 -2
- package/docs/contracts/no-runtime-boundary.md +56 -0
- package/docs/contracts/package-self-orientation.md +24 -0
- package/docs/contracts/provider-lifecycle.md +3 -3
- package/docs/contracts/reasoning-discipline-protocol.md +83 -0
- package/docs/contracts/rule-classification.md +3 -3
- package/docs/contracts/skill-domains.md +1 -1
- package/docs/contracts/smoke-contracts.md +1 -1
- package/docs/contracts/surface-tiers.md +81 -0
- package/docs/contracts/ticket-bundle-format.md +228 -0
- package/docs/cookbook.md +152 -0
- package/docs/customization.md +12 -1
- package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +16 -0
- package/docs/decisions/ADR-056-unvalidated-video-adapters-disposition.md +1 -1
- package/docs/decisions/ADR-059-render-resume-filesystem-as-state.md +1 -1
- package/docs/decisions/ADR-060-comfyui-sandbox-model.md +1 -1
- package/docs/decisions/ADR-061-corpus-grounding-layer.md +48 -1
- package/docs/decisions/ADR-096-analysis-workbench.md +110 -0
- package/docs/decisions/ADR-097-mission-recipe-privilege-boundary.md +121 -0
- package/docs/decisions/ADR-098-evidence-first-structure-discovery.md +154 -0
- package/docs/decisions/ADR-099-file-first-pattern-library.md +87 -0
- package/docs/decisions/ADR-100-global-knowledge-card-sharing.md +133 -0
- package/docs/decisions/ADR-101-ticket-bundle-emission.md +109 -0
- package/docs/decisions/ADR-102-ticket-handoff-paste-and-mcp.md +72 -0
- package/docs/decisions/ADR-103-global-knowledge-default-off-until-measured.md +92 -0
- package/docs/decisions/ADR-200-python-to-typescript-migration.md +193 -0
- package/docs/decisions/INDEX.md +9 -0
- package/docs/distribution/mcp-submission-checklist.md +3 -3
- package/docs/featured-commands.md +1 -1
- package/docs/featured-skills.md +1 -1
- package/docs/getting-started-by-role.md +2 -0
- package/docs/getting-started.md +2 -2
- package/docs/guidelines/agent-infra/failure-signatures.md +35 -0
- package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +5 -0
- package/docs/guidelines/agent-infra/size-and-scope.md +17 -0
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +2 -2
- package/docs/guides/frontend-design-corpus-refresh.md +83 -0
- package/docs/guides/skill-preview.md +1 -1
- package/docs/hook-payload-capture.md +4 -4
- package/docs/mcp.md +1 -1
- package/docs/migration/consumer-template-consumption-model.md +145 -0
- package/docs/migration/divergences/README.md +55 -0
- package/docs/migration/divergences/_template.md +50 -0
- package/docs/migration/divergences/bench-stats-float-precision.md +72 -0
- package/docs/migration/divergences/mcp-telemetry-node-sqlite.md +61 -0
- package/docs/migration/divergences/pack-mcp-content-gzip-body.md +53 -0
- package/docs/migration/divergences/src-scripts-build_cloud_bundle.md +63 -0
- package/docs/migration/divergences/src-scripts-check_memory.md +91 -0
- package/docs/migration/divergences/src-scripts-inventory_abstraction_budget.md +65 -0
- package/docs/migration/divergences/src-scripts-lint_marketplace.md +57 -0
- package/docs/migration/divergences/src-scripts-lint_mcp_registry_manifest.md +70 -0
- package/docs/migration/divergences/src-scripts-spotcheck_thin_root.md +60 -0
- package/docs/migration/divergences/src-scripts-validate_agent_settings.md +58 -0
- package/docs/migration/node-floor.md +86 -0
- package/docs/migration/yaml-roundtrip-spike.md +163 -0
- package/docs/personas.md +6 -1
- package/docs/role-experiences.md +19 -0
- package/docs/setup/per-ide/windsurf.md +1 -1
- package/docs/skills-catalog.md +24 -3
- package/docs/threat-model.md +28 -0
- package/llms.txt +23 -2
- package/package.json +10 -15
- package/src/config/agent-settings.template.yml +64 -1
- package/src/config/discovery/packs.yml +31 -0
- package/src/config/discovery/unassigned-artefacts.yml +6 -0
- package/src/config/discovery/workspaces.yml +2 -2
- package/src/config/gitignore-block.txt +7 -0
- package/src/scripts/_cli/cmd_doctor.ts +2306 -0
- package/src/scripts/_cli/cmd_explain.ts +748 -0
- package/src/scripts/_cli/cmd_export.ts +375 -0
- package/src/scripts/_cli/cmd_migrate.ts +951 -0
- package/src/scripts/_cli/cmd_prune.ts +610 -0
- package/src/scripts/_cli/cmd_refresh.ts +530 -0
- package/src/scripts/_cli/cmd_settings_check.ts +407 -0
- package/src/scripts/_cli/cmd_settings_migrate.ts +344 -0
- package/src/scripts/_cli/cmd_sync.ts +381 -0
- package/src/scripts/_cli/cmd_uninstall.ts +833 -0
- package/src/scripts/_cli/cmd_update.ts +585 -0
- package/src/scripts/_cli/cmd_upgrade.ts +390 -0
- package/src/scripts/_cli/cmd_validate.ts +394 -0
- package/src/scripts/_cli/cmd_versions.ts +492 -0
- package/src/scripts/_cli/explain_last/assumptions.ts +114 -0
- package/src/scripts/_cli/explain_last/council.ts +197 -0
- package/src/scripts/_cli/explain_last/halt.ts +73 -0
- package/src/scripts/_cli/explain_last/index.ts +155 -0
- package/src/scripts/_cli/explain_last/inputs.ts +211 -0
- package/src/scripts/_cli/explain_last/memory.ts +231 -0
- package/src/scripts/_cli/explain_last/provider.ts +82 -0
- package/src/scripts/_cli/explain_last/render.ts +54 -0
- package/src/scripts/_cli/explain_last/route.ts +70 -0
- package/src/scripts/_cli/explain_last/scrubber.ts +138 -0
- package/src/scripts/_cli/explain_last/sections/assumptions.ts +51 -0
- package/src/scripts/_cli/explain_last/sections/council.ts +56 -0
- package/src/scripts/_cli/explain_last/sections/halt.ts +60 -0
- package/src/scripts/_cli/explain_last/sections/header.ts +50 -0
- package/src/scripts/_cli/explain_last/sections/index.ts +21 -0
- package/src/scripts/_cli/explain_last/sections/inputs.ts +63 -0
- package/src/scripts/_cli/explain_last/sections/memory.ts +124 -0
- package/src/scripts/_cli/explain_last/sections/pack.ts +42 -0
- package/src/scripts/_cli/explain_last/sections/provider.ts +51 -0
- package/src/scripts/_cli/explain_last/sections/route.ts +48 -0
- package/src/scripts/_cli/explain_last/state_loader.ts +119 -0
- package/src/scripts/_dispatch.bash +179 -163
- package/src/scripts/_lib/agent_settings.ts +1123 -0
- package/src/scripts/_lib/agent_src.ts +654 -0
- package/src/scripts/_lib/agents_overlay.ts +183 -0
- package/src/scripts/_lib/bench_ab_cache.ts +399 -0
- package/src/scripts/_lib/bench_ab_scoring.ts +352 -0
- package/src/scripts/_lib/bench_ab_scoring_v2.ts +751 -0
- package/src/scripts/_lib/bench_cost.ts +396 -0
- package/src/scripts/_lib/bench_quality.ts +237 -0
- package/src/scripts/_lib/bench_report.ts +255 -0
- package/src/scripts/_lib/bench_telegraph.ts +516 -0
- package/src/scripts/_lib/bench_telegraph_report.ts +272 -0
- package/src/scripts/_lib/changelog_eras.ts +398 -0
- package/src/scripts/_lib/claude_desktop_bundler.ts +324 -0
- package/src/scripts/_lib/cli_wrapper.ts +89 -0
- package/src/scripts/_lib/fs_atomic.ts +172 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +639 -0
- package/src/scripts/_lib/install_layout.ts +87 -0
- package/src/scripts/_lib/install_regenerator.ts +157 -0
- package/src/scripts/_lib/installed_lock.ts +451 -0
- package/src/scripts/_lib/installed_tools.ts +518 -0
- package/src/scripts/_lib/json_pointers.ts +388 -0
- package/src/scripts/_lib/knowledge_global.ts +770 -0
- package/src/scripts/_lib/knowledge_global_promote.ts +453 -0
- package/src/scripts/_lib/knowledge_global_redaction.ts +448 -0
- package/src/scripts/_lib/link_crypto.ts +325 -0
- package/src/scripts/_lib/linked_projects.ts +613 -0
- package/src/scripts/_lib/model_tier.ts +65 -0
- package/src/scripts/_lib/module_detection.ts +275 -0
- package/src/scripts/_lib/node_sqlite.d.ts +32 -0
- package/src/scripts/_lib/pin_resolver.ts +264 -0
- package/src/scripts/_lib/py_random.ts +212 -0
- package/src/scripts/_lib/script_output.ts +147 -0
- package/src/scripts/_lib/security_lint.ts +623 -0
- package/src/scripts/_lib/surface_tiers.ts +127 -0
- package/src/scripts/_lib/token_count.ts +126 -0
- package/src/scripts/_lib/update_check.ts +297 -0
- package/src/scripts/_lib/user_global_paths.ts +329 -0
- package/src/scripts/_lib/value_ladder.ts +882 -0
- package/src/scripts/_lib/value_report.ts +617 -0
- package/src/scripts/_lib/zip_min.ts +175 -0
- package/src/scripts/adoption_report.ts +357 -0
- package/src/scripts/adoption_snapshot.ts +392 -0
- package/src/scripts/adoption_status.ts +424 -0
- package/src/scripts/adr/regenerate_index.ts +257 -0
- package/src/scripts/ai-image/adapters/flux.sh +45 -0
- package/src/scripts/ai-image/adapters/gemini-image.sh +45 -0
- package/src/scripts/ai-image/adapters/ideogram.sh +45 -0
- package/src/scripts/ai-image/adapters/recraft.sh +47 -0
- package/src/scripts/ai-video/adapters/comfyui.sh +3 -3
- package/src/scripts/ai-video/adapters/fal.sh +3 -3
- package/src/scripts/ai-video/adapters/gemini-veo.sh +3 -3
- package/src/scripts/ai-video/adapters/higgsfield.sh +3 -3
- package/src/scripts/ai-video/adapters/kling.sh +3 -3
- package/src/scripts/ai-video/adapters/musetalk.sh +2 -2
- package/src/scripts/ai-video/adapters/openai-images.sh +3 -3
- package/src/scripts/ai-video/adapters/replicate.sh +3 -3
- package/src/scripts/ai-video/adapters/sora.sh +3 -3
- package/src/scripts/ai-video/adapters/syncso.sh +3 -3
- package/src/scripts/ai-video/audio-adapters/allin1.sh +2 -2
- package/src/scripts/ai-video/audio-adapters/whisperx.sh +2 -2
- package/src/scripts/ai-video/lib/audio-adapter-contract.md +1 -1
- package/src/scripts/ai-video/lib/embed-provenance.sh +2 -2
- package/src/scripts/ai-video/lib/ingest-song.sh +2 -2
- package/src/scripts/ai-video/lib/parse-blueprint.sh +1 -1
- package/src/scripts/ai-video/lib/resume-scan.sh +2 -2
- package/src/scripts/ai-video/smoke-trace.sh +16 -7
- package/src/scripts/ai-video/stitch.sh +2 -2
- package/src/scripts/ai_council/_default_prices.ts +73 -0
- package/src/scripts/ai_council/advisors.ts +244 -0
- package/src/scripts/ai_council/airgap.ts +249 -0
- package/src/scripts/ai_council/budget_guard.ts +492 -0
- package/src/scripts/ai_council/bundler.ts +376 -0
- package/src/scripts/ai_council/cli_hints.ts +120 -0
- package/src/scripts/ai_council/clients.ts +2214 -0
- package/src/scripts/ai_council/compile_corpus.ts +681 -0
- package/src/scripts/ai_council/confidence_gate.ts +230 -0
- package/src/scripts/ai_council/config.ts +1729 -0
- package/src/scripts/ai_council/consensus.ts +551 -0
- package/src/scripts/ai_council/events_log.ts +327 -0
- package/src/scripts/ai_council/learn_low_impact_preview.ts +317 -0
- package/src/scripts/ai_council/low_impact.ts +1069 -0
- package/src/scripts/ai_council/low_impact_corpus.ts +662 -0
- package/src/scripts/ai_council/low_impact_intake.ts +222 -0
- package/src/scripts/ai_council/modes.ts +169 -0
- package/src/scripts/ai_council/necessity.ts +933 -0
- package/src/scripts/ai_council/orchestrator.ts +1689 -0
- package/src/scripts/ai_council/pricing.ts +267 -0
- package/src/scripts/ai_council/probation_gate.ts +282 -0
- package/src/scripts/ai_council/project_context.ts +308 -0
- package/src/scripts/ai_council/prompts.ts +600 -0
- package/src/scripts/ai_council/redact_low_impact_entry.ts +291 -0
- package/src/scripts/ai_council/replay.ts +314 -0
- package/src/scripts/ai_council/session.ts +558 -0
- package/src/scripts/ai_council/shadow_dispatch.ts +509 -0
- package/src/scripts/ai_council/solo_dispatch.ts +281 -0
- package/src/scripts/analysis_freshness.ts +343 -0
- package/src/scripts/annotate_discovery.ts +288 -0
- package/src/scripts/apply_modules_config.ts +537 -0
- package/src/scripts/audit_adr_coverage.ts +357 -0
- package/src/scripts/audit_auto_rules.ts +415 -0
- package/src/scripts/audit_cloud_compatibility.ts +608 -0
- package/src/scripts/audit_command_surface.ts +1227 -0
- package/src/scripts/audit_initial_context.ts +694 -0
- package/src/scripts/audit_likelihood.ts +434 -0
- package/src/scripts/audit_mcp_tools.ts +252 -0
- package/src/scripts/audit_overlap.ts +421 -0
- package/src/scripts/audit_skill_descriptions.ts +402 -0
- package/src/scripts/audit_skill_overlap.ts +576 -0
- package/src/scripts/audit_user_type_axis.ts +264 -0
- package/src/scripts/backfill_model_tier.ts +349 -0
- package/src/scripts/bench_ab_cache_dispatch.ts +126 -0
- package/src/scripts/bench_ab_clone.ts +610 -0
- package/src/scripts/bench_ab_diff.ts +609 -0
- package/src/scripts/bench_ab_integrity.ts +261 -0
- package/src/scripts/bench_ab_run.ts +417 -0
- package/src/scripts/bench_ab_task_runner.ts +1382 -0
- package/src/scripts/bench_ab_tracka_run.ts +436 -0
- package/src/scripts/bench_ab_v2_run.ts +585 -0
- package/src/scripts/bench_ab_v2_stats.ts +1018 -0
- package/src/scripts/bench_baseline_ready.ts +326 -0
- package/src/scripts/bench_condense_memory.ts +479 -0
- package/src/scripts/bench_drift_check.ts +503 -0
- package/src/scripts/bench_per_tool.ts +591 -0
- package/src/scripts/bench_rtk_savings.ts +710 -0
- package/src/scripts/bench_run.ts +509 -0
- package/src/scripts/bench_runner.ts +519 -0
- package/src/scripts/build_cloud_bundle.ts +692 -0
- package/src/scripts/build_discovery_manifest.ts +1371 -0
- package/src/scripts/build_linear_digest.ts +368 -0
- package/src/scripts/build_mcp_registry_manifest.ts +351 -0
- package/src/scripts/build_rule_trigger_matrix.ts +469 -0
- package/src/scripts/capture_showcase_session.ts +735 -0
- package/src/scripts/chat_history.ts +2301 -0
- package/src/scripts/check_always_budget.ts +694 -0
- package/src/scripts/check_artefact_checksums.ts +281 -0
- package/src/scripts/check_augment_description_cap.ts +133 -0
- package/src/scripts/check_augmentignore.ts +108 -0
- package/src/scripts/check_beta_review_markers.ts +234 -0
- package/src/scripts/check_bite_sized_granularity.ts +116 -0
- package/src/scripts/check_cluster_patterns.ts +285 -0
- package/src/scripts/check_command_count_messaging.ts +224 -0
- package/src/scripts/check_condensation.ts +900 -0
- package/src/scripts/check_condensed_paths.ts +414 -0
- package/src/scripts/check_context_paths.ts +388 -0
- package/src/scripts/check_council_config_location.ts +260 -0
- package/src/scripts/check_council_layout.ts +180 -0
- package/src/scripts/check_council_references.ts +345 -0
- package/src/scripts/check_discovery_determinism.ts +124 -0
- package/src/scripts/check_gate_paths.ts +230 -0
- package/src/scripts/check_iron_law_prominence.ts +298 -0
- package/src/scripts/check_kernel_rule_bundle.ts +242 -0
- package/src/scripts/check_knowledge_cards.ts +759 -0
- package/src/scripts/check_md_language.ts +291 -0
- package/src/scripts/check_memory.ts +845 -0
- package/src/scripts/check_memory_proposal.ts +351 -0
- package/src/scripts/check_module_management_neutral.ts +238 -0
- package/src/scripts/check_no_conflict_markers.ts +298 -0
- package/src/scripts/check_no_conflict_markers_allowlist.json +4 -0
- package/src/scripts/check_no_external_sources.ts +351 -0
- package/src/scripts/check_no_local_settings_committed.ts +69 -0
- package/src/scripts/check_no_new_legacy_path.ts +188 -0
- package/src/scripts/check_no_roadmap_refs.ts +304 -0
- package/src/scripts/check_one_off_location.ts +165 -0
- package/src/scripts/check_overlay_cascade_subdirs.ts +188 -0
- package/src/scripts/check_portability.ts +860 -0
- package/src/scripts/check_proposal.ts +0 -0
- package/src/scripts/check_public_catalog_links.ts +204 -0
- package/src/scripts/check_public_links.ts +357 -0
- package/src/scripts/check_references.ts +963 -0
- package/src/scripts/check_release_includes_discovery.ts +94 -0
- package/src/scripts/check_release_pr_shape.ts +222 -0
- package/src/scripts/check_release_published.ts +235 -0
- package/src/scripts/check_release_trunk_sync.ts +203 -0
- package/src/scripts/check_reply_consistency.ts +359 -0
- package/src/scripts/check_roadmap_trackable.ts +268 -0
- package/src/scripts/check_role_doc_links.ts +187 -0
- package/src/scripts/check_safety_floor_untouched.ts +160 -0
- package/src/scripts/check_skill_requires.ts +205 -0
- package/src/scripts/check_structural_breaking.ts +170 -0
- package/src/scripts/check_surface_tiers.ts +567 -0
- package/src/scripts/check_template_pin_drift.ts +222 -0
- package/src/scripts/check_test_coverage_diff.ts +235 -0
- package/src/scripts/check_token_optimizer_freshness.ts +183 -0
- package/src/scripts/check_trigger_evals.ts +375 -0
- package/src/scripts/check_update_banner.ts +143 -0
- package/src/scripts/ci_status.ts +0 -0
- package/src/scripts/ci_summary.ts +235 -0
- package/src/scripts/ci_time_ratio.ts +526 -0
- package/src/scripts/command_suggester/cooldown.ts +176 -0
- package/src/scripts/command_suggester/index.ts +41 -0
- package/src/scripts/command_suggester/loader.ts +205 -0
- package/src/scripts/command_suggester/match.ts +294 -0
- package/src/scripts/command_suggester/rank.ts +201 -0
- package/src/scripts/command_suggester/render.ts +122 -0
- package/src/scripts/command_suggester/sanitize.ts +114 -0
- package/src/scripts/command_suggester/settings.ts +186 -0
- package/src/scripts/command_suggester/types.ts +0 -0
- package/src/scripts/compile_router.ts +297 -0
- package/src/scripts/condense.sh +7 -1
- package/src/scripts/condense.ts +2035 -0
- package/src/scripts/condense_memory.ts +334 -0
- package/src/scripts/config/index.ts +15 -0
- package/src/scripts/config/packs.ts +310 -0
- package/src/scripts/config/presets.ts +369 -0
- package/src/scripts/config/profile_explain.ts +114 -0
- package/src/scripts/config/profiles.ts +277 -0
- package/src/scripts/config/session_profiles.ts +1064 -0
- package/src/scripts/context_hygiene_hook.ts +272 -0
- package/src/scripts/cost_by_conversation.ts +444 -0
- package/src/scripts/cost_summary.ts +407 -0
- package/src/scripts/council_cli.ts +2827 -0
- package/src/scripts/council_prune.ts +153 -0
- package/src/scripts/cross_repo_retrieve.ts +694 -0
- package/src/scripts/discovery_stats.ts +218 -0
- package/src/scripts/evidence_report.ts +580 -0
- package/src/scripts/external_sources_denylist.json +1 -0
- package/src/scripts/extract_audit_patterns.ts +394 -0
- package/src/scripts/first_run_gate_hook.ts +246 -0
- package/src/scripts/gen_discovery_baseline.ts +297 -0
- package/src/scripts/generate_capabilities_index.ts +496 -0
- package/src/scripts/generate_capability_matrix.ts +430 -0
- package/src/scripts/generate_catalog.ts +178 -0
- package/src/scripts/generate_command_flows.ts +316 -0
- package/src/scripts/generate_cookbook.ts +302 -0
- package/src/scripts/generate_index.ts +500 -0
- package/src/scripts/generate_ownership_matrix.ts +646 -0
- package/src/scripts/generate_pack_manifests.ts +1025 -0
- package/src/scripts/generate_role_experiences_catalog.ts +265 -0
- package/src/scripts/hermetic-install.sh +22 -11
- package/src/scripts/hook_manifest.yaml +24 -10
- package/src/scripts/hooks/augment-chat-history.sh +3 -10
- package/src/scripts/hooks/augment-context-hygiene.sh +3 -10
- package/src/scripts/hooks/augment-dispatcher.sh +3 -10
- package/src/scripts/hooks/augment-onboarding-gate.sh +3 -10
- package/src/scripts/hooks/augment-roadmap-progress.sh +3 -10
- package/src/scripts/hooks/block_no_verify.ts +413 -0
- package/src/scripts/hooks/cline-dispatcher.sh +3 -10
- package/src/scripts/hooks/cowork-dispatcher.sh +3 -14
- package/src/scripts/hooks/cursor-dispatcher.sh +3 -10
- package/src/scripts/hooks/dispatch_hook.ts +851 -0
- package/src/scripts/hooks/dispatch_issues.ts +226 -0
- package/src/scripts/hooks/envelope.ts +140 -0
- package/src/scripts/hooks/gemini-dispatcher.sh +3 -8
- package/src/scripts/hooks/replay_hook.ts +364 -0
- package/src/scripts/hooks/state_io.ts +293 -0
- package/src/scripts/hooks/windsurf-dispatcher.sh +3 -9
- package/src/scripts/hooks_doctor.ts +418 -0
- package/src/scripts/hooks_status.ts +292 -0
- package/src/scripts/injection_scan_hook.ts +285 -0
- package/src/scripts/install +36 -22
- package/src/scripts/install-hooks.sh +20 -14
- package/src/scripts/install.sh +38 -14
- package/src/scripts/install.ts +4515 -0
- package/src/scripts/inventory_abstraction_budget.ts +1104 -0
- package/src/scripts/inventory_frontmatter.ts +320 -0
- package/src/scripts/inventory_meta_layers.ts +516 -0
- package/src/scripts/iron_law_sha.ts +233 -0
- package/src/scripts/knowledge_global_cli.ts +1105 -0
- package/src/scripts/linked_projects_list.ts +310 -0
- package/src/scripts/lint_agent_security.ts +224 -0
- package/src/scripts/lint_agent_skill_names.ts +241 -0
- package/src/scripts/lint_agents_layout.ts +205 -0
- package/src/scripts/lint_agents_md.ts +294 -0
- package/src/scripts/lint_archived_skills.ts +309 -0
- package/src/scripts/lint_artefact_frontmatter.ts +359 -0
- package/src/scripts/lint_bench_ab.ts +319 -0
- package/src/scripts/lint_bench_corpus.ts +421 -0
- package/src/scripts/lint_command_flow_coverage.ts +231 -0
- package/src/scripts/lint_command_routing.ts +377 -0
- package/src/scripts/lint_command_tiers.ts +345 -0
- package/src/scripts/lint_command_verbs.ts +379 -0
- package/src/scripts/lint_commit_subjects.ts +243 -0
- package/src/scripts/lint_context_spine_usage.ts +198 -0
- package/src/scripts/lint_discovery_manifest.ts +540 -0
- package/src/scripts/lint_discovery_vocabulary.ts +393 -0
- package/src/scripts/lint_empty_roadmaps.ts +147 -0
- package/src/scripts/lint_eval_freshness.ts +335 -0
- package/src/scripts/lint_examples.ts +183 -0
- package/src/scripts/lint_explain_trace.ts +381 -0
- package/src/scripts/lint_featured_skills.ts +0 -0
- package/src/scripts/lint_flows.ts +701 -0
- package/src/scripts/lint_framework_leakage.ts +497 -0
- package/src/scripts/lint_framework_leakage_allowlist.json +8 -1
- package/src/scripts/lint_frontmatter_boilerplate.ts +356 -0
- package/src/scripts/lint_ghostwriter_source.ts +389 -0
- package/src/scripts/lint_global_paths.ts +420 -0
- package/src/scripts/lint_handoffs.ts +362 -0
- package/src/scripts/lint_hidden_unicode.ts +350 -0
- package/src/scripts/lint_hook_concern_budget.ts +319 -0
- package/src/scripts/lint_hook_manifest.ts +354 -0
- package/src/scripts/lint_instruction_smuggling.ts +173 -0
- package/src/scripts/lint_load_context.ts +371 -0
- package/src/scripts/lint_marketplace.ts +286 -0
- package/src/scripts/lint_marketplace_install_completeness.ts +309 -0
- package/src/scripts/lint_mcp_config_security.ts +225 -0
- package/src/scripts/lint_mcp_registry_manifest.ts +350 -0
- package/src/scripts/lint_media_policy_linkage.ts +224 -0
- package/src/scripts/lint_missions.ts +774 -0
- package/src/scripts/lint_model_tier_coverage.ts +151 -0
- package/src/scripts/lint_namespace.ts +295 -0
- package/src/scripts/lint_namespace_collisions.ts +203 -0
- package/src/scripts/lint_new_skill_gate.ts +462 -0
- package/src/scripts/lint_no_new_atomic_commands.ts +342 -0
- package/src/scripts/lint_one_off_age.ts +348 -0
- package/src/scripts/lint_orchestration_dsl.ts +377 -0
- package/src/scripts/lint_orchestrator_auto_detect.ts +177 -0
- package/src/scripts/lint_pack_boundaries.ts +366 -0
- package/src/scripts/lint_pack_dependencies.ts +541 -0
- package/src/scripts/lint_pack_first_win.ts +202 -0
- package/src/scripts/lint_persona_governance.ts +292 -0
- package/src/scripts/lint_positioning.ts +257 -0
- package/src/scripts/lint_profile_overlay_set_only.ts +324 -0
- package/src/scripts/lint_readme_jargon.ts +189 -0
- package/src/scripts/lint_readme_size.ts +73 -0
- package/src/scripts/lint_regression.ts +497 -0
- package/src/scripts/lint_roadmap_ci_steps.ts +252 -0
- package/src/scripts/lint_roadmap_complexity.ts +295 -0
- package/src/scripts/lint_roadmap_later_disposition.ts +357 -0
- package/src/scripts/lint_role_experiences.ts +410 -0
- package/src/scripts/lint_rule_interactions.ts +281 -0
- package/src/scripts/lint_rule_tiers.ts +169 -0
- package/src/scripts/lint_showcase_sessions.ts +254 -0
- package/src/scripts/lint_skill_frontmatter_safety.ts +279 -0
- package/src/scripts/lint_skill_originality.ts +586 -0
- package/src/scripts/lint_skill_originality_allowlist.json +20 -0
- package/src/scripts/lint_skill_tools.ts +320 -0
- package/src/scripts/lint_ticket_buildable.ts +1027 -0
- package/src/scripts/lint_topics_yaml.ts +203 -0
- package/src/scripts/lint_trust_coherence.ts +377 -0
- package/src/scripts/lint_value_dashboard.ts +314 -0
- package/src/scripts/lint_workflow_security.ts +637 -0
- package/src/scripts/lint_workflow_security_allowlist.json +20 -0
- package/src/scripts/lint_workspace_boundary.ts +248 -0
- package/src/scripts/mcp_parity_smoke.ts +638 -0
- package/src/scripts/mcp_render.ts +346 -0
- package/src/scripts/mcp_server/__main__.ts +28 -0
- package/src/scripts/mcp_server/catalog.ts +154 -0
- package/src/scripts/mcp_server/index.ts +24 -0
- package/src/scripts/mcp_server/metadata.ts +83 -0
- package/src/scripts/mcp_server/prompts.ts +711 -0
- package/src/scripts/mcp_server/resources.ts +343 -0
- package/src/scripts/mcp_server/server.ts +439 -0
- package/src/scripts/mcp_server/telemetry.ts +154 -0
- package/src/scripts/mcp_server/tools.ts +1031 -0
- package/src/scripts/mcp_setup.sh +25 -52
- package/src/scripts/mcp_telemetry_health.ts +362 -0
- package/src/scripts/mcp_telemetry_query.ts +371 -0
- package/src/scripts/mcp_telemetry_store.ts +422 -0
- package/src/scripts/measure_augment_budget.ts +453 -0
- package/src/scripts/measure_density.ts +618 -0
- package/src/scripts/measure_frugality_savings.ts +353 -0
- package/src/scripts/measure_markitdown_lift.ts +299 -0
- package/src/scripts/measure_patterns.ts +682 -0
- package/src/scripts/measure_projection_bytes.ts +425 -0
- package/src/scripts/measure_rule_budget.ts +627 -0
- package/src/scripts/measure_skill_reduction.ts +442 -0
- package/src/scripts/media/lib/adapter-common.sh +247 -0
- package/src/scripts/media/lib/adapter-contract.md +329 -0
- package/src/scripts/media/lib/fixtures/comfyui/result.json +1 -0
- package/src/scripts/media/lib/fixtures/fal/result.json +1 -0
- package/src/scripts/media/lib/fixtures/flux/asset-0001.png +0 -0
- package/src/scripts/media/lib/fixtures/flux/result.json +1 -0
- package/src/scripts/media/lib/fixtures/gemini-image/asset-0001.png +0 -0
- package/src/scripts/media/lib/fixtures/gemini-image/result.json +1 -0
- package/src/scripts/media/lib/fixtures/gemini-veo/result.json +1 -0
- package/src/scripts/media/lib/fixtures/higgsfield/result.json +1 -0
- package/src/scripts/media/lib/fixtures/ideogram/asset-0001.png +0 -0
- package/src/scripts/media/lib/fixtures/ideogram/result.json +1 -0
- package/src/scripts/media/lib/fixtures/kling/result.json +1 -0
- package/src/scripts/media/lib/fixtures/musetalk/result.json +1 -0
- package/src/scripts/media/lib/fixtures/openai-images/result.json +1 -0
- package/src/scripts/media/lib/fixtures/recraft/asset-0001.svg +1 -0
- package/src/scripts/media/lib/fixtures/recraft/result.json +1 -0
- package/src/scripts/media/lib/fixtures/replicate/result.json +1 -0
- package/src/scripts/media/lib/fixtures/sora/result.json +1 -0
- package/src/scripts/media/lib/fixtures/syncso/result.json +1 -0
- package/src/scripts/media/lib/load-config.sh +180 -0
- package/src/scripts/media/lib/redact.sh +85 -0
- package/src/scripts/memory_hash.ts +331 -0
- package/src/scripts/memory_lookup.ts +1278 -0
- package/src/scripts/memory_report.ts +845 -0
- package/src/scripts/memory_signal.ts +417 -0
- package/src/scripts/memory_status.ts +189 -0
- package/src/scripts/migrate_command_suggestions.ts +341 -0
- package/src/scripts/migrate_frontmatter_defaults.ts +539 -0
- package/src/scripts/migration_status.ts +301 -0
- package/src/scripts/mine_session.ts +645 -0
- package/src/scripts/minimal_safe_diff_hook.ts +355 -0
- package/src/scripts/move_artefact.ts +869 -0
- package/src/scripts/new_skill.ts +404 -0
- package/src/scripts/onboarding_gate_hook.ts +224 -0
- package/src/scripts/pack_dependency_allowlist.json +1 -1
- package/src/scripts/pack_mcp_content.ts +552 -0
- package/src/scripts/parity/README.md +140 -0
- package/src/scripts/parity/compare.ts +189 -0
- package/src/scripts/parity/coverage_diff.ts +199 -0
- package/src/scripts/parity/phase-manifest.json +93 -0
- package/src/scripts/parity/phase_gate.ts +270 -0
- package/src/scripts/parity/replay.ts +320 -0
- package/src/scripts/pattern_share.ts +363 -0
- package/src/scripts/plan_physical_move.ts +605 -0
- package/src/scripts/prediction-pool/poisson_sim.ts +537 -0
- package/src/scripts/prediction-pool/pool_winsim.ts +677 -0
- package/src/scripts/prediction-pool/score_ev.ts +546 -0
- package/src/scripts/print_required_checks.ts +249 -0
- package/src/scripts/probe_projection_fidelity.ts +468 -0
- package/src/scripts/probe_skill_registration.ts +787 -0
- package/src/scripts/profile_staleness_hook.ts +169 -0
- package/src/scripts/profile_use.ts +227 -0
- package/src/scripts/project_thin_rules.ts +387 -0
- package/src/scripts/propose_modules_config.ts +311 -0
- package/src/scripts/prototype_lint_contradictions.ts +414 -0
- package/src/scripts/prove_pack_extractable.ts +388 -0
- package/src/scripts/readme_linter.ts +913 -0
- package/src/scripts/redact_hook_capture.ts +325 -0
- package/src/scripts/refine_ticket_detect.ts +703 -0
- package/src/scripts/release.ts +1697 -0
- package/src/scripts/render_benchmark_md.ts +664 -0
- package/src/scripts/render_value_md.ts +506 -0
- package/src/scripts/repro/repro_marketplace_install_gap.sh +1 -1
- package/src/scripts/roadmap_progress_hook.ts +410 -0
- package/src/scripts/router_telemetry.ts +972 -0
- package/src/scripts/run.ts +98 -0
- package/src/scripts/run_skill_evals.ts +477 -0
- package/src/scripts/runtime_dispatcher.ts +586 -0
- package/src/scripts/runtime_handler.ts +231 -0
- package/src/scripts/runtime_registry.ts +394 -0
- package/src/scripts/schemas/command.schema.json +3 -2
- package/src/scripts/schemas/mission-catalog.schema.json +112 -0
- package/src/scripts/schemas/mission.schema.json +87 -0
- package/src/scripts/schemas/pack.schema.json +6 -0
- package/src/scripts/schemas/rule.schema.json +1 -0
- package/src/scripts/schemas/skill.schema.json +1 -0
- package/src/scripts/schemas/ticket-manifest.schema.json +35 -0
- package/src/scripts/schemas/ticket.schema.json +60 -0
- package/src/scripts/score_skill_selection.ts +570 -0
- package/src/scripts/security_audit_config.ts +423 -0
- package/src/scripts/skill_collision_clusters.ts +448 -0
- package/src/scripts/skill_discovery.ts +690 -0
- package/src/scripts/skill_linter.ts +4276 -0
- package/src/scripts/skill_overlap.ts +414 -0
- package/src/scripts/skill_preview.ts +548 -0
- package/src/scripts/skill_tools/audit_persona_coverage.ts +427 -0
- package/src/scripts/skill_tools/audit_user_type_coverage.ts +507 -0
- package/src/scripts/skill_tools/index.ts +28 -0
- package/src/scripts/skill_tools/run_block_d_eval.ts +373 -0
- package/src/scripts/skill_tools/score_skill_relevance.ts +475 -0
- package/src/scripts/skill_tools/suggest_skill_for_task.ts +288 -0
- package/src/scripts/skill_trigger_eval.ts +1046 -0
- package/src/scripts/skill_usage_collect.ts +465 -0
- package/src/scripts/skill_usage_report.ts +364 -0
- package/src/scripts/smoke/kernel.sh +4 -5
- package/src/scripts/smoke/router.sh +76 -76
- package/src/scripts/smoke/schema.sh +2 -2
- package/src/scripts/smoke/skills.sh +73 -52
- package/src/scripts/smoke_path_resolution.ts +194 -0
- package/src/scripts/smoke_quickstart.ts +224 -0
- package/src/scripts/snapshot_agent_outputs.ts +375 -0
- package/src/scripts/spotcheck_thin_root.ts +247 -0
- package/src/scripts/surface-tiers.yml +68 -0
- package/src/scripts/sync_agent_settings.ts +763 -0
- package/src/scripts/sync_github_metadata.ts +550 -0
- package/src/scripts/sync_gitignore.ts +630 -0
- package/src/scripts/sync_yaml_rt.ts +910 -0
- package/src/scripts/telegraph_stats.ts +447 -0
- package/src/scripts/tool_registry.ts +330 -0
- package/src/scripts/tools/adapter_errors.ts +93 -0
- package/src/scripts/tools/base_adapter.ts +147 -0
- package/src/scripts/tools/github_adapter.ts +229 -0
- package/src/scripts/tools/jira_adapter.ts +196 -0
- package/src/scripts/trigger_coverage.ts +251 -0
- package/src/scripts/update_counts.ts +284 -0
- package/src/scripts/update_prices.ts +219 -0
- package/src/scripts/validate_agent_settings.ts +265 -0
- package/src/scripts/validate_decision_engine.ts +366 -0
- package/src/scripts/validate_discovery_manifest.ts +160 -0
- package/src/scripts/validate_frontmatter.ts +1030 -0
- package/src/scripts/validate_pack_yaml.ts +0 -0
- package/src/scripts/validate_safe_paths.ts +164 -0
- package/src/scripts/validate_telegraph_carveouts.ts +485 -0
- package/src/scripts/verify_before_complete_hook.ts +306 -0
- package/src/scripts/verify_physical_move.ts +411 -0
- package/src/scripts/wrapper_freshness_hook.ts +179 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.py +0 -171
- package/dist/agent-src/scripts/update_roadmap_progress.py +0 -537
- package/dist/agent-src/skills/corpus-grounding/scripts/bm25_search.py +0 -212
- package/dist/agent-src/skills/corpus-grounding/scripts/decision_engine.py +0 -438
- package/dist/agent-src/skills/corpus-grounding/scripts/ground.py +0 -166
- package/dist/agent-src/skills/corpus-grounding/scripts/schema_validator.py +0 -160
- package/dist/agent-src/skills/design-tokens/scripts/tokens.py +0 -296
- package/dist/agent-src/skills/react-shadcn-ui/scripts/shadcn_add.py +0 -299
- package/dist/agent-src/skills/tailwind-engineer/scripts/tailwind_config_gen.py +0 -463
- package/dist/agent-src/templates/scripts/check_memory.py +0 -282
- package/dist/agent-src/templates/scripts/check_memory_proposal.py +0 -180
- package/dist/agent-src/templates/scripts/implement_ticket/__init__.py +0 -94
- package/dist/agent-src/templates/scripts/implement_ticket/__main__.py +0 -15
- package/dist/agent-src/templates/scripts/memory_hash.py +0 -75
- package/dist/agent-src/templates/scripts/memory_lookup.py +0 -436
- package/dist/agent-src/templates/scripts/memory_report.py +0 -314
- package/dist/agent-src/templates/scripts/memory_signal.py +0 -165
- package/dist/agent-src/templates/scripts/memory_status.py +0 -76
- package/dist/agent-src/templates/scripts/pr_review_routing.py +0 -340
- package/dist/agent-src/templates/scripts/pr_risk_review.py +0 -211
- package/dist/agent-src/templates/scripts/telemetry/__init__.py +0 -42
- package/dist/agent-src/templates/scripts/telemetry/aggregator.py +0 -169
- package/dist/agent-src/templates/scripts/telemetry/boundary.py +0 -171
- package/dist/agent-src/templates/scripts/telemetry/engagement.py +0 -297
- package/dist/agent-src/templates/scripts/telemetry/report_renderer.py +0 -197
- package/dist/agent-src/templates/scripts/telemetry/settings.py +0 -177
- package/dist/agent-src/templates/scripts/telemetry_record.py +0 -179
- package/dist/agent-src/templates/scripts/telemetry_report.py +0 -161
- package/dist/agent-src/templates/scripts/telemetry_status.py +0 -142
- package/dist/agent-src/templates/scripts/tier_usage_report.py +0 -183
- package/dist/agent-src/templates/scripts/work_engine/__init__.py +0 -58
- package/dist/agent-src/templates/scripts/work_engine/__main__.py +0 -9
- package/dist/agent-src/templates/scripts/work_engine/_lib/__init__.py +0 -7
- package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.py +0 -840
- package/dist/agent-src/templates/scripts/work_engine/_lib/user_global_paths.py +0 -249
- package/dist/agent-src/templates/scripts/work_engine/cli.py +0 -195
- package/dist/agent-src/templates/scripts/work_engine/cli_args.py +0 -116
- package/dist/agent-src/templates/scripts/work_engine/delivery_state.py +0 -137
- package/dist/agent-src/templates/scripts/work_engine/directives/__init__.py +0 -33
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/__init__.py +0 -98
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/analyze.py +0 -98
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.py +0 -145
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/memory.py +0 -136
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/plan.py +0 -175
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/refine.py +0 -396
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/report.py +0 -227
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.py +0 -180
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.py +0 -170
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/__init__.py +0 -116
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/contract.py +0 -254
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.py +0 -229
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/ui.py +0 -231
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/__init__.py +0 -113
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/_passthrough.py +0 -44
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.py +0 -241
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/audit.py +0 -414
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.py +0 -335
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.py +0 -513
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.py +0 -471
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/__init__.py +0 -119
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/_skipped.py +0 -37
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/apply.py +0 -165
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/refine.py +0 -66
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/report.py +0 -62
- package/dist/agent-src/templates/scripts/work_engine/directives/ui_trivial/test.py +0 -115
- package/dist/agent-src/templates/scripts/work_engine/dispatcher.py +0 -331
- package/dist/agent-src/templates/scripts/work_engine/emitters.py +0 -68
- package/dist/agent-src/templates/scripts/work_engine/errors.py +0 -19
- package/dist/agent-src/templates/scripts/work_engine/hook_bootstrap.py +0 -91
- package/dist/agent-src/templates/scripts/work_engine/hooks/__init__.py +0 -54
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/__init__.py +0 -35
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/_chat_history_base.py +0 -59
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_append.py +0 -43
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_halt_append.py +0 -41
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_gate.py +0 -162
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.py +0 -163
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/directive_set_guard.py +0 -53
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/halt_surface_audit.py +0 -50
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.py +0 -141
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/state_shape_validation.py +0 -52
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/trace.py +0 -84
- package/dist/agent-src/templates/scripts/work_engine/hooks/context.py +0 -66
- package/dist/agent-src/templates/scripts/work_engine/hooks/events.py +0 -44
- package/dist/agent-src/templates/scripts/work_engine/hooks/exceptions.py +0 -79
- package/dist/agent-src/templates/scripts/work_engine/hooks/registry.py +0 -60
- package/dist/agent-src/templates/scripts/work_engine/hooks/runner.py +0 -73
- package/dist/agent-src/templates/scripts/work_engine/hooks/settings.py +0 -196
- package/dist/agent-src/templates/scripts/work_engine/input_builders.py +0 -163
- package/dist/agent-src/templates/scripts/work_engine/intent/__init__.py +0 -47
- package/dist/agent-src/templates/scripts/work_engine/intent/classify.py +0 -280
- package/dist/agent-src/templates/scripts/work_engine/migration/__init__.py +0 -8
- package/dist/agent-src/templates/scripts/work_engine/migration/v0_to_v1.py +0 -231
- package/dist/agent-src/templates/scripts/work_engine/orchestration.py +0 -193
- package/dist/agent-src/templates/scripts/work_engine/persona_policy.py +0 -85
- package/dist/agent-src/templates/scripts/work_engine/resolvers/__init__.py +0 -22
- package/dist/agent-src/templates/scripts/work_engine/resolvers/diff.py +0 -106
- package/dist/agent-src/templates/scripts/work_engine/resolvers/file.py +0 -113
- package/dist/agent-src/templates/scripts/work_engine/resolvers/prompt.py +0 -90
- package/dist/agent-src/templates/scripts/work_engine/scoring/__init__.py +0 -14
- package/dist/agent-src/templates/scripts/work_engine/scoring/confidence.py +0 -300
- package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.py +0 -351
- package/dist/agent-src/templates/scripts/work_engine/scoring/decision_trace.py +0 -141
- package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.py +0 -283
- package/dist/agent-src/templates/scripts/work_engine/stack/__init__.py +0 -31
- package/dist/agent-src/templates/scripts/work_engine/stack/detect.py +0 -187
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.py +0 -481
- package/dist/agent-src/templates/scripts/work_engine/state.py +0 -694
- package/dist/agent-src/templates/scripts/work_engine/state_io.py +0 -202
- package/dist/cli/python/resolvePython.js +0 -38
- package/dist/cli/python/resolvePython.js.map +0 -1
- package/src/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
- package/src/scripts/_archive/_backfill_skill_domains.py +0 -140
- package/src/scripts/_archive/_bootstrap_tier_frontmatter.py +0 -151
- package/src/scripts/_archive/_p43_bodies.py +0 -235
- package/src/scripts/_archive/_p43_condense.py +0 -118
- package/src/scripts/_archive/_p4_migrate.py +0 -199
- package/src/scripts/_archive/_phase2_shim_helper.py +0 -109
- package/src/scripts/_archive/_pilot_council_question.py +0 -57
- package/src/scripts/_cli/__init__.py +0 -0
- package/src/scripts/_cli/cmd_doctor.py +0 -1669
- package/src/scripts/_cli/cmd_explain.py +0 -355
- package/src/scripts/_cli/cmd_export.py +0 -157
- package/src/scripts/_cli/cmd_migrate.py +0 -524
- package/src/scripts/_cli/cmd_prune.py +0 -322
- package/src/scripts/_cli/cmd_refresh.py +0 -179
- package/src/scripts/_cli/cmd_settings_check.py +0 -171
- package/src/scripts/_cli/cmd_settings_migrate.py +0 -147
- package/src/scripts/_cli/cmd_sync.py +0 -166
- package/src/scripts/_cli/cmd_uninstall.py +0 -476
- package/src/scripts/_cli/cmd_update.py +0 -279
- package/src/scripts/_cli/cmd_upgrade.py +0 -172
- package/src/scripts/_cli/cmd_validate.py +0 -177
- package/src/scripts/_cli/cmd_versions.py +0 -160
- package/src/scripts/_cli/explain_last/__init__.py +0 -122
- package/src/scripts/_cli/explain_last/assumptions.py +0 -59
- package/src/scripts/_cli/explain_last/council.py +0 -105
- package/src/scripts/_cli/explain_last/halt.py +0 -44
- package/src/scripts/_cli/explain_last/inputs.py +0 -128
- package/src/scripts/_cli/explain_last/memory.py +0 -94
- package/src/scripts/_cli/explain_last/provider.py +0 -52
- package/src/scripts/_cli/explain_last/render.py +0 -52
- package/src/scripts/_cli/explain_last/route.py +0 -59
- package/src/scripts/_cli/explain_last/scrubber.py +0 -105
- package/src/scripts/_cli/explain_last/sections/__init__.py +0 -35
- package/src/scripts/_cli/explain_last/sections/assumptions.py +0 -21
- package/src/scripts/_cli/explain_last/sections/council.py +0 -27
- package/src/scripts/_cli/explain_last/sections/halt.py +0 -31
- package/src/scripts/_cli/explain_last/sections/header.py +0 -24
- package/src/scripts/_cli/explain_last/sections/inputs.py +0 -27
- package/src/scripts/_cli/explain_last/sections/memory.py +0 -21
- package/src/scripts/_cli/explain_last/sections/pack.py +0 -16
- package/src/scripts/_cli/explain_last/sections/provider.py +0 -26
- package/src/scripts/_cli/explain_last/sections/route.py +0 -22
- package/src/scripts/_cli/explain_last/state_loader.py +0 -76
- package/src/scripts/_emit_domain_table.py +0 -35
- package/src/scripts/_lib/__init__.py +0 -5
- package/src/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
- package/src/scripts/_lib/agent_settings.py +0 -840
- package/src/scripts/_lib/agent_src.py +0 -491
- package/src/scripts/_lib/agents_overlay.py +0 -120
- package/src/scripts/_lib/bench_ab_cache.py +0 -162
- package/src/scripts/_lib/bench_ab_scoring.py +0 -209
- package/src/scripts/_lib/bench_ab_scoring_v2.py +0 -227
- package/src/scripts/_lib/bench_cost.py +0 -138
- package/src/scripts/_lib/bench_quality.py +0 -118
- package/src/scripts/_lib/bench_report.py +0 -149
- package/src/scripts/_lib/bench_telegraph.py +0 -273
- package/src/scripts/_lib/bench_telegraph_report.py +0 -151
- package/src/scripts/_lib/changelog_eras.py +0 -330
- package/src/scripts/_lib/claude_desktop_bundler.py +0 -238
- package/src/scripts/_lib/cli_wrapper.py +0 -64
- package/src/scripts/_lib/fs_atomic.py +0 -116
- package/src/scripts/_lib/global_deploy_inventory.py +0 -312
- package/src/scripts/_lib/install_regenerator.py +0 -134
- package/src/scripts/_lib/installed_lock.py +0 -256
- package/src/scripts/_lib/installed_tools.py +0 -381
- package/src/scripts/_lib/json_pointers.py +0 -260
- package/src/scripts/_lib/link_crypto.py +0 -206
- package/src/scripts/_lib/linked_projects.py +0 -238
- package/src/scripts/_lib/model_tier.py +0 -52
- package/src/scripts/_lib/module_detection.py +0 -223
- package/src/scripts/_lib/pin_resolver.py +0 -152
- package/src/scripts/_lib/script_output.py +0 -144
- package/src/scripts/_lib/security_lint.py +0 -228
- package/src/scripts/_lib/token_count.py +0 -95
- package/src/scripts/_lib/update_check.py +0 -207
- package/src/scripts/_lib/user_global_paths.py +0 -249
- package/src/scripts/_lib/value_ladder.py +0 -696
- package/src/scripts/_lib/value_report.py +0 -455
- package/src/scripts/_phase4_bucket.py +0 -210
- package/src/scripts/_pilot_measure.py +0 -53
- package/src/scripts/_tmp_scan_framework_leakage.py +0 -119
- package/src/scripts/adoption_report.py +0 -195
- package/src/scripts/adoption_snapshot.py +0 -219
- package/src/scripts/adoption_status.py +0 -166
- package/src/scripts/adr/regenerate_index.py +0 -79
- package/src/scripts/ai-video/lib/adapter-common.sh +0 -231
- package/src/scripts/ai-video/lib/adapter-contract.md +0 -329
- package/src/scripts/ai-video/lib/fixtures/comfyui/result.json +0 -1
- package/src/scripts/ai-video/lib/fixtures/fal/result.json +0 -1
- package/src/scripts/ai-video/lib/fixtures/gemini-veo/result.json +0 -1
- package/src/scripts/ai-video/lib/fixtures/higgsfield/result.json +0 -1
- package/src/scripts/ai-video/lib/fixtures/kling/result.json +0 -1
- package/src/scripts/ai-video/lib/fixtures/musetalk/result.json +0 -1
- package/src/scripts/ai-video/lib/fixtures/openai-images/result.json +0 -1
- package/src/scripts/ai-video/lib/fixtures/replicate/result.json +0 -1
- package/src/scripts/ai-video/lib/fixtures/sora/result.json +0 -1
- package/src/scripts/ai-video/lib/fixtures/syncso/result.json +0 -1
- package/src/scripts/ai-video/lib/load-config.sh +0 -180
- package/src/scripts/ai-video/lib/redact.sh +0 -85
- package/src/scripts/ai_council/__init__.py +0 -40
- package/src/scripts/ai_council/_default_prices.py +0 -50
- package/src/scripts/ai_council/advisors.py +0 -148
- package/src/scripts/ai_council/airgap.py +0 -165
- package/src/scripts/ai_council/budget_guard.py +0 -202
- package/src/scripts/ai_council/bundler.py +0 -263
- package/src/scripts/ai_council/cli_hints.py +0 -123
- package/src/scripts/ai_council/clients.py +0 -1385
- package/src/scripts/ai_council/compile_corpus.py +0 -179
- package/src/scripts/ai_council/confidence_gate.py +0 -156
- package/src/scripts/ai_council/config.py +0 -1419
- package/src/scripts/ai_council/consensus.py +0 -329
- package/src/scripts/ai_council/events_log.py +0 -141
- package/src/scripts/ai_council/learn_low_impact_preview.py +0 -252
- package/src/scripts/ai_council/low_impact.py +0 -714
- package/src/scripts/ai_council/low_impact_corpus.py +0 -466
- package/src/scripts/ai_council/low_impact_intake.py +0 -163
- package/src/scripts/ai_council/modes.py +0 -131
- package/src/scripts/ai_council/necessity.py +0 -782
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_2a4_acceptance.py +0 -208
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_add_quiet.py +0 -149
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_budget_v2_audit.py +0 -206
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_context_layer_v1_estimate.py +0 -67
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_context_layer_v1_review.py +0 -292
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_followups_review.py +0 -259
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_inject_quiet_flag.py +0 -33
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_measure_v2.sh +0 -36
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_measure_verbosity.sh +0 -26
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_nondestructive_inline_audit.py +0 -209
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_per_task.sh +0 -41
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_phase4_dispatch_latency.py +0 -108
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_phase6_trigger_jaccard.py +0 -92
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_phase_2a_budget_rebalance.py +0 -257
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_phase_2a_post_revert.py +0 -197
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_rebalancing_audit.py +0 -149
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_roundtrip.py +0 -111
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_rule_hardening_v1.py +0 -251
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_silent_taskfiles.py +0 -98
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_structural_open_questions.py +0 -232
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_structural_optimization.py +0 -144
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_structural_v3_gaps.py +0 -252
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_structural_v3_review.py +0 -240
- package/src/scripts/ai_council/one_off_archive/2026-05/_one_off_tier_retrofit.py +0 -180
- package/src/scripts/ai_council/orchestrator.py +0 -1206
- package/src/scripts/ai_council/pricing.py +0 -215
- package/src/scripts/ai_council/probation_gate.py +0 -152
- package/src/scripts/ai_council/project_context.py +0 -159
- package/src/scripts/ai_council/prompts.py +0 -567
- package/src/scripts/ai_council/redact_low_impact_entry.py +0 -155
- package/src/scripts/ai_council/replay.py +0 -155
- package/src/scripts/ai_council/session.py +0 -366
- package/src/scripts/ai_council/shadow_dispatch.py +0 -235
- package/src/scripts/ai_council/solo_dispatch.py +0 -226
- package/src/scripts/annotate_discovery.py +0 -149
- package/src/scripts/apply_modules_config.py +0 -290
- package/src/scripts/audit_adr_coverage.py +0 -173
- package/src/scripts/audit_auto_rules.py +0 -175
- package/src/scripts/audit_cloud_compatibility.py +0 -362
- package/src/scripts/audit_command_surface.py +0 -682
- package/src/scripts/audit_initial_context.py +0 -237
- package/src/scripts/audit_likelihood.py +0 -148
- package/src/scripts/audit_mcp_tools.py +0 -146
- package/src/scripts/audit_overlap.py +0 -145
- package/src/scripts/audit_skill_descriptions.py +0 -180
- package/src/scripts/audit_skill_overlap.py +0 -207
- package/src/scripts/audit_user_type_axis.py +0 -140
- package/src/scripts/backfill_model_tier.py +0 -184
- package/src/scripts/bench_ab_cache_dispatch.py +0 -68
- package/src/scripts/bench_ab_clone.py +0 -220
- package/src/scripts/bench_ab_diff.py +0 -220
- package/src/scripts/bench_ab_integrity.py +0 -143
- package/src/scripts/bench_ab_run.py +0 -235
- package/src/scripts/bench_ab_task_runner.py +0 -814
- package/src/scripts/bench_ab_tracka_run.py +0 -202
- package/src/scripts/bench_ab_v2_run.py +0 -247
- package/src/scripts/bench_ab_v2_stats.py +0 -347
- package/src/scripts/bench_baseline_ready.py +0 -108
- package/src/scripts/bench_condense_memory.py +0 -168
- package/src/scripts/bench_drift_check.py +0 -151
- package/src/scripts/bench_per_tool.py +0 -216
- package/src/scripts/bench_rtk_savings.py +0 -320
- package/src/scripts/bench_run.py +0 -272
- package/src/scripts/bench_runner.py +0 -158
- package/src/scripts/build_cloud_bundle.py +0 -458
- package/src/scripts/build_discovery_manifest.py +0 -757
- package/src/scripts/build_linear_digest.py +0 -260
- package/src/scripts/build_mcp_registry_manifest.py +0 -181
- package/src/scripts/build_rule_trigger_matrix.py +0 -350
- package/src/scripts/capture_showcase_session.py +0 -361
- package/src/scripts/chat_history.py +0 -1799
- package/src/scripts/check_always_budget.py +0 -532
- package/src/scripts/check_artefact_checksums.py +0 -111
- package/src/scripts/check_augment_description_cap.py +0 -79
- package/src/scripts/check_augmentignore.py +0 -72
- package/src/scripts/check_beta_review_markers.py +0 -127
- package/src/scripts/check_bite_sized_granularity.py +0 -98
- package/src/scripts/check_cluster_patterns.py +0 -206
- package/src/scripts/check_command_count_messaging.py +0 -152
- package/src/scripts/check_condensation.py +0 -375
- package/src/scripts/check_condensed_paths.py +0 -231
- package/src/scripts/check_context_paths.py +0 -202
- package/src/scripts/check_council_layout.py +0 -125
- package/src/scripts/check_council_references.py +0 -228
- package/src/scripts/check_discovery_determinism.py +0 -70
- package/src/scripts/check_gate_paths.py +0 -128
- package/src/scripts/check_iron_law_prominence.py +0 -145
- package/src/scripts/check_kernel_rule_bundle.py +0 -151
- package/src/scripts/check_md_language.py +0 -161
- package/src/scripts/check_memory.py +0 -429
- package/src/scripts/check_memory_proposal.py +0 -182
- package/src/scripts/check_module_management_neutral.py +0 -147
- package/src/scripts/check_no_external_sources.py +0 -101
- package/src/scripts/check_no_local_settings_committed.py +0 -51
- package/src/scripts/check_no_new_legacy_path.py +0 -100
- package/src/scripts/check_no_roadmap_refs.py +0 -155
- package/src/scripts/check_one_off_location.py +0 -81
- package/src/scripts/check_overlay_cascade_subdirs.py +0 -129
- package/src/scripts/check_portability.py +0 -574
- package/src/scripts/check_proposal.py +0 -269
- package/src/scripts/check_public_catalog_links.py +0 -125
- package/src/scripts/check_public_links.py +0 -185
- package/src/scripts/check_references.py +0 -559
- package/src/scripts/check_release_includes_discovery.py +0 -61
- package/src/scripts/check_release_pr_shape.py +0 -123
- package/src/scripts/check_release_published.py +0 -145
- package/src/scripts/check_release_trunk_sync.py +0 -152
- package/src/scripts/check_reply_consistency.py +0 -169
- package/src/scripts/check_roadmap_trackable.py +0 -114
- package/src/scripts/check_role_doc_links.py +0 -110
- package/src/scripts/check_safety_floor_untouched.py +0 -125
- package/src/scripts/check_skill_requires.py +0 -147
- package/src/scripts/check_template_pin_drift.py +0 -129
- package/src/scripts/check_test_coverage_diff.py +0 -180
- package/src/scripts/check_token_optimizer_freshness.py +0 -146
- package/src/scripts/check_update_banner.py +0 -86
- package/src/scripts/ci_status.py +0 -301
- package/src/scripts/ci_summary.py +0 -131
- package/src/scripts/ci_time_ratio.py +0 -168
- package/src/scripts/command_suggester/__init__.py +0 -51
- package/src/scripts/command_suggester/cooldown.py +0 -132
- package/src/scripts/command_suggester/loader.py +0 -73
- package/src/scripts/command_suggester/match.py +0 -180
- package/src/scripts/command_suggester/rank.py +0 -120
- package/src/scripts/command_suggester/render.py +0 -86
- package/src/scripts/command_suggester/sanitize.py +0 -113
- package/src/scripts/command_suggester/settings.py +0 -127
- package/src/scripts/command_suggester/types.py +0 -78
- package/src/scripts/compile_router.py +0 -232
- package/src/scripts/condense.py +0 -1919
- package/src/scripts/condense_memory.py +0 -178
- package/src/scripts/config/__init__.py +0 -9
- package/src/scripts/config/packs.py +0 -157
- package/src/scripts/config/presets.py +0 -224
- package/src/scripts/config/profile_explain.py +0 -89
- package/src/scripts/config/profiles.py +0 -191
- package/src/scripts/config/session_profiles.py +0 -542
- package/src/scripts/context_hygiene_hook.py +0 -181
- package/src/scripts/cost_by_conversation.py +0 -78
- package/src/scripts/cost_summary.py +0 -97
- package/src/scripts/council_cli.py +0 -2571
- package/src/scripts/council_prune.py +0 -81
- package/src/scripts/cross_repo_retrieve.py +0 -172
- package/src/scripts/discovery_stats.py +0 -70
- package/src/scripts/extract_audit_patterns.py +0 -202
- package/src/scripts/first_run_gate_hook.py +0 -179
- package/src/scripts/gen_discovery_baseline.py +0 -127
- package/src/scripts/generate_catalog.py +0 -116
- package/src/scripts/generate_command_flows.py +0 -191
- package/src/scripts/generate_index.py +0 -303
- package/src/scripts/generate_ownership_matrix.py +0 -378
- package/src/scripts/generate_pack_manifests.py +0 -340
- package/src/scripts/hooks/__init__.py +0 -1
- package/src/scripts/hooks/dispatch_hook.py +0 -461
- package/src/scripts/hooks/dispatch_issues.py +0 -136
- package/src/scripts/hooks/envelope.py +0 -98
- package/src/scripts/hooks/replay_hook.py +0 -144
- package/src/scripts/hooks/state_io.py +0 -145
- package/src/scripts/hooks_doctor.py +0 -223
- package/src/scripts/hooks_status.py +0 -157
- package/src/scripts/injection_scan_hook.py +0 -145
- package/src/scripts/install.py +0 -5258
- package/src/scripts/inventory_abstraction_budget.py +0 -622
- package/src/scripts/inventory_frontmatter.py +0 -164
- package/src/scripts/inventory_meta_layers.py +0 -288
- package/src/scripts/iron_law_sha.py +0 -107
- package/src/scripts/linked_projects_list.py +0 -91
- package/src/scripts/lint_agent_security.py +0 -112
- package/src/scripts/lint_agent_skill_names.py +0 -150
- package/src/scripts/lint_agents_layout.py +0 -197
- package/src/scripts/lint_agents_md.py +0 -210
- package/src/scripts/lint_archived_skills.py +0 -159
- package/src/scripts/lint_artefact_frontmatter.py +0 -188
- package/src/scripts/lint_bench_ab.py +0 -173
- package/src/scripts/lint_bench_corpus.py +0 -255
- package/src/scripts/lint_command_flow_coverage.py +0 -132
- package/src/scripts/lint_command_routing.py +0 -160
- package/src/scripts/lint_command_tiers.py +0 -216
- package/src/scripts/lint_command_verbs.py +0 -206
- package/src/scripts/lint_commit_subjects.py +0 -139
- package/src/scripts/lint_context_spine_usage.py +0 -137
- package/src/scripts/lint_discovery_manifest.py +0 -176
- package/src/scripts/lint_discovery_vocabulary.py +0 -222
- package/src/scripts/lint_empty_roadmaps.py +0 -80
- package/src/scripts/lint_examples.py +0 -102
- package/src/scripts/lint_explain_trace.py +0 -80
- package/src/scripts/lint_featured_skills.py +0 -144
- package/src/scripts/lint_flows.py +0 -215
- package/src/scripts/lint_framework_leakage.py +0 -375
- package/src/scripts/lint_frontmatter_boilerplate.py +0 -77
- package/src/scripts/lint_ghostwriter_source.py +0 -242
- package/src/scripts/lint_global_paths.py +0 -148
- package/src/scripts/lint_handoffs.py +0 -217
- package/src/scripts/lint_hidden_unicode.py +0 -132
- package/src/scripts/lint_hook_concern_budget.py +0 -207
- package/src/scripts/lint_hook_manifest.py +0 -217
- package/src/scripts/lint_instruction_smuggling.py +0 -107
- package/src/scripts/lint_load_context.py +0 -196
- package/src/scripts/lint_marketplace.py +0 -180
- package/src/scripts/lint_marketplace_install_completeness.py +0 -198
- package/src/scripts/lint_mcp_config_security.py +0 -124
- package/src/scripts/lint_mcp_registry_manifest.py +0 -69
- package/src/scripts/lint_media_policy_linkage.py +0 -140
- package/src/scripts/lint_model_tier_coverage.py +0 -73
- package/src/scripts/lint_namespace.py +0 -135
- package/src/scripts/lint_namespace_collisions.py +0 -103
- package/src/scripts/lint_new_skill_gate.py +0 -144
- package/src/scripts/lint_no_new_atomic_commands.py +0 -180
- package/src/scripts/lint_one_off_age.py +0 -184
- package/src/scripts/lint_orchestration_dsl.py +0 -217
- package/src/scripts/lint_orchestrator_auto_detect.py +0 -111
- package/src/scripts/lint_pack_boundaries.py +0 -147
- package/src/scripts/lint_pack_dependencies.py +0 -137
- package/src/scripts/lint_pack_first_win.py +0 -121
- package/src/scripts/lint_persona_governance.py +0 -164
- package/src/scripts/lint_positioning.py +0 -143
- package/src/scripts/lint_profile_overlay_set_only.py +0 -179
- package/src/scripts/lint_readme_jargon.py +0 -131
- package/src/scripts/lint_readme_size.py +0 -33
- package/src/scripts/lint_regression.py +0 -251
- package/src/scripts/lint_roadmap_ci_steps.py +0 -186
- package/src/scripts/lint_roadmap_complexity.py +0 -220
- package/src/scripts/lint_role_experiences.py +0 -255
- package/src/scripts/lint_rule_interactions.py +0 -170
- package/src/scripts/lint_rule_tiers.py +0 -90
- package/src/scripts/lint_showcase_sessions.py +0 -148
- package/src/scripts/lint_skill_frontmatter_safety.py +0 -144
- package/src/scripts/lint_skill_tools.py +0 -168
- package/src/scripts/lint_topics_yaml.py +0 -89
- package/src/scripts/lint_trust_coherence.py +0 -212
- package/src/scripts/lint_value_dashboard.py +0 -218
- package/src/scripts/lint_workspace_boundary.py +0 -122
- package/src/scripts/mcp_parity_smoke.py +0 -316
- package/src/scripts/mcp_render.py +0 -173
- package/src/scripts/mcp_server/__init__.py +0 -19
- package/src/scripts/mcp_server/__main__.py +0 -12
- package/src/scripts/mcp_server/catalog.py +0 -125
- package/src/scripts/mcp_server/metadata.py +0 -75
- package/src/scripts/mcp_server/prompts.py +0 -442
- package/src/scripts/mcp_server/requirements.txt +0 -4
- package/src/scripts/mcp_server/resources.py +0 -201
- package/src/scripts/mcp_server/server.py +0 -270
- package/src/scripts/mcp_server/telemetry.py +0 -128
- package/src/scripts/mcp_server/tools.py +0 -926
- package/src/scripts/mcp_telemetry_health.py +0 -214
- package/src/scripts/mcp_telemetry_query.py +0 -203
- package/src/scripts/mcp_telemetry_store.py +0 -211
- package/src/scripts/measure_augment_budget.py +0 -214
- package/src/scripts/measure_density.py +0 -232
- package/src/scripts/measure_frugality_savings.py +0 -164
- package/src/scripts/measure_markitdown_lift.py +0 -127
- package/src/scripts/measure_patterns.py +0 -376
- package/src/scripts/measure_projection_bytes.py +0 -159
- package/src/scripts/measure_rule_budget.py +0 -347
- package/src/scripts/measure_skill_reduction.py +0 -102
- package/src/scripts/memory_hash.py +0 -75
- package/src/scripts/memory_lookup.py +0 -436
- package/src/scripts/memory_report.py +0 -314
- package/src/scripts/memory_signal.py +0 -165
- package/src/scripts/memory_status.py +0 -76
- package/src/scripts/migrate_command_suggestions.py +0 -151
- package/src/scripts/migrate_frontmatter_defaults.py +0 -245
- package/src/scripts/mine_session.py +0 -356
- package/src/scripts/minimal_safe_diff_hook.py +0 -245
- package/src/scripts/move_artefact.py +0 -143
- package/src/scripts/new_skill.py +0 -148
- package/src/scripts/onboarding_gate_hook.py +0 -142
- package/src/scripts/pack_mcp_content.py +0 -293
- package/src/scripts/plan_physical_move.py +0 -353
- package/src/scripts/prediction-pool/poisson_sim.py +0 -167
- package/src/scripts/prediction-pool/pool_winsim.py +0 -236
- package/src/scripts/prediction-pool/score_ev.py +0 -188
- package/src/scripts/print_required_checks.py +0 -196
- package/src/scripts/probe_projection_fidelity.py +0 -202
- package/src/scripts/probe_skill_registration.py +0 -413
- package/src/scripts/profile_staleness_hook.py +0 -69
- package/src/scripts/profile_use.py +0 -164
- package/src/scripts/project_thin_rules.py +0 -168
- package/src/scripts/propose_modules_config.py +0 -145
- package/src/scripts/prototype_lint_contradictions.py +0 -150
- package/src/scripts/prove_pack_extractable.py +0 -187
- package/src/scripts/readme_linter.py +0 -589
- package/src/scripts/redact_hook_capture.py +0 -148
- package/src/scripts/refine_ticket_detect.py +0 -646
- package/src/scripts/release.py +0 -1091
- package/src/scripts/render_benchmark_md.py +0 -401
- package/src/scripts/render_value_md.py +0 -347
- package/src/scripts/requirements-evals.txt +0 -8
- package/src/scripts/roadmap_progress_hook.py +0 -274
- package/src/scripts/router_telemetry.py +0 -470
- package/src/scripts/run_skill_evals.py +0 -185
- package/src/scripts/runtime_dispatcher.py +0 -276
- package/src/scripts/runtime_handler.py +0 -148
- package/src/scripts/runtime_registry.py +0 -166
- package/src/scripts/score_skill_selection.py +0 -198
- package/src/scripts/security_audit_config.py +0 -153
- package/src/scripts/setup_eval_venv.sh +0 -58
- package/src/scripts/skill_collision_clusters.py +0 -162
- package/src/scripts/skill_discovery.py +0 -254
- package/src/scripts/skill_linter.py +0 -3694
- package/src/scripts/skill_overlap.py +0 -204
- package/src/scripts/skill_preview.py +0 -179
- package/src/scripts/skill_tools/__init__.py +0 -22
- package/src/scripts/skill_tools/audit_persona_coverage.py +0 -147
- package/src/scripts/skill_tools/audit_user_type_coverage.py +0 -148
- package/src/scripts/skill_tools/run_block_d_eval.py +0 -129
- package/src/scripts/skill_tools/score_skill_relevance.py +0 -169
- package/src/scripts/skill_tools/suggest_skill_for_task.py +0 -113
- package/src/scripts/skill_trigger_eval.py +0 -682
- package/src/scripts/skill_usage_collect.py +0 -191
- package/src/scripts/skill_usage_report.py +0 -162
- package/src/scripts/smoke_path_resolution.py +0 -93
- package/src/scripts/smoke_quickstart.py +0 -144
- package/src/scripts/snapshot_agent_outputs.py +0 -144
- package/src/scripts/spotcheck_thin_root.py +0 -134
- package/src/scripts/sync_agent_settings.py +0 -180
- package/src/scripts/sync_github_metadata.py +0 -147
- package/src/scripts/sync_gitignore.py +0 -291
- package/src/scripts/sync_yaml_rt.py +0 -734
- package/src/scripts/telegraph_stats.py +0 -119
- package/src/scripts/tool_registry.py +0 -146
- package/src/scripts/tools/__init__.py +0 -1
- package/src/scripts/tools/adapter_errors.py +0 -63
- package/src/scripts/tools/base_adapter.py +0 -91
- package/src/scripts/tools/github_adapter.py +0 -128
- package/src/scripts/tools/jira_adapter.py +0 -115
- package/src/scripts/trigger_coverage.py +0 -129
- package/src/scripts/update_counts.py +0 -199
- package/src/scripts/update_prices.py +0 -125
- package/src/scripts/validate_agent_settings.py +0 -124
- package/src/scripts/validate_decision_engine.py +0 -136
- package/src/scripts/validate_discovery_manifest.py +0 -94
- package/src/scripts/validate_frontmatter.py +0 -647
- package/src/scripts/validate_pack_yaml.py +0 -179
- package/src/scripts/validate_safe_paths.py +0 -118
- package/src/scripts/validate_telegraph_carveouts.py +0 -129
- package/src/scripts/verify_before_complete_hook.py +0 -216
- package/src/scripts/verify_physical_move.py +0 -185
- package/src/scripts/wrapper_freshness_hook.py +0 -86
- /package/dist/agent-src/skills/design-intelligence/data/{typography.csv → font-pairings-reference.csv} +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/allin1/analysis.json +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/comfyui/scene-0001.mp4 +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/fal/scene-0001.mp4 +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/gemini-veo/scene-0001.mp4 +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/higgsfield/scene-0001.mp4 +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/kling/scene-0001.mp4 +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/musetalk/lipsync-0001.mp4 +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/openai-images/scene-0001.png +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/replicate/scene-0001.mp4 +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/sora/scene-0001.mp4 +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/syncso/lipsync-0001.mp4 +0 -0
- /package/src/scripts/{ai-video → media}/lib/fixtures/whisperx/transcript.json +0 -0
- /package/src/scripts/{ai-video → media}/lib/telemetry.sh +0 -0
|
@@ -0,0 +1,1689 @@
|
|
|
1
|
+
// Council orchestrator — fan out one question to multiple members.
|
|
2
|
+
//
|
|
3
|
+
// py2ts twin of orchestrator.py (ADR-200). Byte-for-byte parity with the
|
|
4
|
+
// Python original: member dispatch order, sequential cost gating, the overrun
|
|
5
|
+
// callback contract, multi-round debate / peer-review / consensus passes, and
|
|
6
|
+
// the Markdown render assembly are all mirrored exactly.
|
|
7
|
+
//
|
|
8
|
+
// v2 contract (sequential + interactive overrun prompt):
|
|
9
|
+
//
|
|
10
|
+
// - Members are called **sequentially** in input order. The previous
|
|
11
|
+
// parallel ThreadPoolExecutor was traded for predictable mid-flow
|
|
12
|
+
// user prompts; with 2-3 council members the latency cost is small.
|
|
13
|
+
// - `estimate(question, members, table)` returns a pre-call cost preview
|
|
14
|
+
// (input tokens + max-output ceiling + USD per member). The host
|
|
15
|
+
// agent shows this before invoking `consult()`.
|
|
16
|
+
// - `consult(..., on_overrun=...)` invokes the callback BEFORE each
|
|
17
|
+
// member's actual API call when the projected total cost would push
|
|
18
|
+
// past the cost budget. The callback decides whether to proceed for
|
|
19
|
+
// this single member; the next member triggers the callback again.
|
|
20
|
+
//
|
|
21
|
+
// Failure normalisation (one member's exception → `error`-set
|
|
22
|
+
// CouncilResponse, never raise) is unchanged.
|
|
23
|
+
|
|
24
|
+
import {
|
|
25
|
+
record_spend as _record_daily_spend,
|
|
26
|
+
today_spend_usd as _today_spend_usd,
|
|
27
|
+
would_exceed as _would_exceed_daily,
|
|
28
|
+
} from './budget_guard.js';
|
|
29
|
+
import type {
|
|
30
|
+
ExternalAIClient} from './clients.js';
|
|
31
|
+
import {
|
|
32
|
+
DEFAULT_MAX_TOKENS,
|
|
33
|
+
CouncilResponse
|
|
34
|
+
} from './clients.js';
|
|
35
|
+
import type {
|
|
36
|
+
ConsensusMetadata,
|
|
37
|
+
Finding} from './consensus.js';
|
|
38
|
+
import {
|
|
39
|
+
ConsensusBucket,
|
|
40
|
+
FindingScore,
|
|
41
|
+
aggregate_scores,
|
|
42
|
+
anonymize_findings,
|
|
43
|
+
anonymize_responses,
|
|
44
|
+
bucket_by_threshold,
|
|
45
|
+
parse_findings_response,
|
|
46
|
+
parse_scores_response,
|
|
47
|
+
} from './consensus.js';
|
|
48
|
+
import type {
|
|
49
|
+
CostEstimate,
|
|
50
|
+
PriceTable} from './pricing.js';
|
|
51
|
+
import {
|
|
52
|
+
estimate_cost,
|
|
53
|
+
estimate_input_tokens,
|
|
54
|
+
} from './pricing.js';
|
|
55
|
+
import type { ProjectContext } from './project_context.js';
|
|
56
|
+
import type { AdvisorPlan } from './advisors.js';
|
|
57
|
+
import {
|
|
58
|
+
advisor_system_prompt,
|
|
59
|
+
build_extraction_user_prompt,
|
|
60
|
+
build_peer_review_user_prompt,
|
|
61
|
+
build_scoring_user_prompt,
|
|
62
|
+
peer_review_synthesis_addendum,
|
|
63
|
+
synthesis_template,
|
|
64
|
+
system_prompt_for,
|
|
65
|
+
} from './prompts.js';
|
|
66
|
+
|
|
67
|
+
// ── Python-format / stdlib parity helpers ────────────────────────────────
|
|
68
|
+
//
|
|
69
|
+
// The orchestrator formats USD / scores / strengths via Python f-string
|
|
70
|
+
// specs (`:.4f`, `:.2f`, `:.1f`) which round half-to-even on the decimal
|
|
71
|
+
// representation. JS `toFixed` rounds half away from zero, so the spec
|
|
72
|
+
// formatting is reimplemented to stay byte-exact with the Python original.
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Format `x` to `ndigits` decimals using round-half-to-even, matching
|
|
76
|
+
* CPython's `format(x, ".<ndigits>f")`.
|
|
77
|
+
*/
|
|
78
|
+
function _pyFixed(x: number, ndigits: number): string {
|
|
79
|
+
if (!Number.isFinite(x)) {
|
|
80
|
+
return String(x);
|
|
81
|
+
}
|
|
82
|
+
const neg = x < 0 || Object.is(x, -0);
|
|
83
|
+
const abs = Math.abs(x);
|
|
84
|
+
const factor = Math.pow(10, ndigits);
|
|
85
|
+
const scaled = abs * factor;
|
|
86
|
+
const floor = Math.floor(scaled);
|
|
87
|
+
const frac = scaled - floor;
|
|
88
|
+
const tol = Math.max(Math.abs(scaled), 1) * 2 ** -40;
|
|
89
|
+
let rounded: number;
|
|
90
|
+
if (Math.abs(frac - 0.5) <= tol) {
|
|
91
|
+
rounded = floor % 2 === 0 ? floor : floor + 1;
|
|
92
|
+
} else {
|
|
93
|
+
rounded = Math.round(scaled);
|
|
94
|
+
}
|
|
95
|
+
let intStr = String(rounded);
|
|
96
|
+
let result: string;
|
|
97
|
+
if (ndigits === 0) {
|
|
98
|
+
result = intStr;
|
|
99
|
+
} else {
|
|
100
|
+
if (intStr.length <= ndigits) {
|
|
101
|
+
intStr = '0'.repeat(ndigits - intStr.length + 1) + intStr;
|
|
102
|
+
}
|
|
103
|
+
const whole = intStr.slice(0, intStr.length - ndigits);
|
|
104
|
+
const dec = intStr.slice(intStr.length - ndigits);
|
|
105
|
+
result = `${whole}.${dec}`;
|
|
106
|
+
}
|
|
107
|
+
return neg ? `-${result}` : result;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Mirror Python `str.strip()` (no-arg). Sibling-twin convention uses trim(). */
|
|
111
|
+
function _pyStrip(s: string): string {
|
|
112
|
+
return s.trim();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Mirror Python `str.split()` (no separator) — split on runs of whitespace,
|
|
117
|
+
* dropping leading / trailing whitespace (no empty tokens).
|
|
118
|
+
*/
|
|
119
|
+
function _pySplitWhitespace(s: string): string[] {
|
|
120
|
+
const trimmed = s.trim();
|
|
121
|
+
if (trimmed === '') {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
return trimmed.split(/\s+/);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Mirror Python `getattr(obj, name, fallback)` for the duck-typed member
|
|
129
|
+
* objects (real clients + test mocks). Returns the attribute value or the
|
|
130
|
+
* fallback when the attribute is absent / object is null.
|
|
131
|
+
*/
|
|
132
|
+
function _getattr(obj: unknown, name: string, fallback: unknown): unknown {
|
|
133
|
+
if (obj === null || obj === undefined) {
|
|
134
|
+
return fallback;
|
|
135
|
+
}
|
|
136
|
+
if (typeof obj === 'object' || typeof obj === 'function') {
|
|
137
|
+
const val = (obj as Record<string, unknown>)[name];
|
|
138
|
+
if (val !== undefined) {
|
|
139
|
+
return val;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return fallback;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Mirror Python `chr(ord("A") + idx)` — reviewer label letters. */
|
|
146
|
+
function _label(idx: number): string {
|
|
147
|
+
return String.fromCharCode('A'.charCodeAt(0) + idx);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ── dataclasses ───────────────────────────────────────────────────────
|
|
151
|
+
|
|
152
|
+
export class CostBudget {
|
|
153
|
+
max_input_tokens: number;
|
|
154
|
+
max_output_tokens: number;
|
|
155
|
+
max_calls: number;
|
|
156
|
+
max_total_usd: number; // 0 = USD ceiling disabled (token caps still apply)
|
|
157
|
+
daily_limit_usd: number; // 0 = rolling 24h cap disabled (D3)
|
|
158
|
+
|
|
159
|
+
constructor(
|
|
160
|
+
args: {
|
|
161
|
+
max_input_tokens?: number;
|
|
162
|
+
max_output_tokens?: number;
|
|
163
|
+
max_calls?: number;
|
|
164
|
+
max_total_usd?: number;
|
|
165
|
+
daily_limit_usd?: number;
|
|
166
|
+
} = {},
|
|
167
|
+
) {
|
|
168
|
+
this.max_input_tokens = args.max_input_tokens ?? 50_000;
|
|
169
|
+
this.max_output_tokens = args.max_output_tokens ?? 20_000;
|
|
170
|
+
this.max_calls = args.max_calls ?? 10;
|
|
171
|
+
this.max_total_usd = args.max_total_usd ?? 0.0;
|
|
172
|
+
this.daily_limit_usd = args.daily_limit_usd ?? 0.0;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export class CouncilQuestion {
|
|
177
|
+
mode: string; // one of: prompt, roadmap, diff, files
|
|
178
|
+
user_prompt: string; // bundled artefact text
|
|
179
|
+
max_tokens: number;
|
|
180
|
+
|
|
181
|
+
constructor(args: { mode: string; user_prompt: string; max_tokens?: number }) {
|
|
182
|
+
this.mode = args.mode;
|
|
183
|
+
this.user_prompt = args.user_prompt;
|
|
184
|
+
this.max_tokens = args.max_tokens ?? DEFAULT_MAX_TOKENS;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Passed to `on_overrun` when projected spend exceeds the budget. */
|
|
189
|
+
export class OverrunEvent {
|
|
190
|
+
member_index: number;
|
|
191
|
+
member: ExternalAIClient;
|
|
192
|
+
next_estimate: CostEstimate; // this member's projected cost
|
|
193
|
+
spent_input_tokens: number; // already-billed totals BEFORE this member
|
|
194
|
+
spent_output_tokens: number;
|
|
195
|
+
spent_usd: number;
|
|
196
|
+
projected_total_usd: number; // spent_usd + next_estimate.total_usd
|
|
197
|
+
daily_spent_usd: number; // rolling 24h spend BEFORE this member (D3)
|
|
198
|
+
daily_limit_usd: number; // the configured daily cap (0 = disabled)
|
|
199
|
+
breach_kind: string; // "session" | "daily" | "tokens"
|
|
200
|
+
|
|
201
|
+
constructor(args: {
|
|
202
|
+
member_index: number;
|
|
203
|
+
member: ExternalAIClient;
|
|
204
|
+
next_estimate: CostEstimate;
|
|
205
|
+
spent_input_tokens: number;
|
|
206
|
+
spent_output_tokens: number;
|
|
207
|
+
spent_usd: number;
|
|
208
|
+
projected_total_usd: number;
|
|
209
|
+
daily_spent_usd?: number;
|
|
210
|
+
daily_limit_usd?: number;
|
|
211
|
+
breach_kind?: string;
|
|
212
|
+
}) {
|
|
213
|
+
this.member_index = args.member_index;
|
|
214
|
+
this.member = args.member;
|
|
215
|
+
this.next_estimate = args.next_estimate;
|
|
216
|
+
this.spent_input_tokens = args.spent_input_tokens;
|
|
217
|
+
this.spent_output_tokens = args.spent_output_tokens;
|
|
218
|
+
this.spent_usd = args.spent_usd;
|
|
219
|
+
this.projected_total_usd = args.projected_total_usd;
|
|
220
|
+
this.daily_spent_usd = args.daily_spent_usd ?? 0.0;
|
|
221
|
+
this.daily_limit_usd = args.daily_limit_usd ?? 0.0;
|
|
222
|
+
this.breach_kind = args.breach_kind ?? 'session';
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Callback signature: receive event → return True (proceed) or False (skip + tag error).
|
|
227
|
+
export type OnOverrunCallback = (event: OverrunEvent) => boolean;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Pre-flight debate cost summary (Phase 8).
|
|
231
|
+
*
|
|
232
|
+
* `low_usd` / `expected_usd` / `high_usd` are the rolled-up spend bounds
|
|
233
|
+
* across every billable member × `rounds`. The expected estimate matches
|
|
234
|
+
* the per-round `estimate()` total multiplied by rounds (worst-case
|
|
235
|
+
* `max_output_tokens`). `low_usd` discounts output to 25% of the ceiling —
|
|
236
|
+
* most members do not hit their token budget. `high_usd` adds a 20%
|
|
237
|
+
* over-run buffer per the roadmap's ±20% accuracy target.
|
|
238
|
+
*
|
|
239
|
+
* `per_member` carries one entry per billable member with the same bound
|
|
240
|
+
* triple, plus the member's transport label (api / cli / manual).
|
|
241
|
+
* `subscription_members` lists non-billable members so the disclosure
|
|
242
|
+
* block can call out the "covered by subscription" rows without summing
|
|
243
|
+
* them into USD totals.
|
|
244
|
+
*/
|
|
245
|
+
export class DebateCostEstimate {
|
|
246
|
+
readonly rounds: number;
|
|
247
|
+
readonly low_usd: number;
|
|
248
|
+
readonly expected_usd: number;
|
|
249
|
+
readonly high_usd: number;
|
|
250
|
+
readonly per_member: Array<Record<string, unknown>>;
|
|
251
|
+
readonly subscription_members: Array<Record<string, string>>;
|
|
252
|
+
|
|
253
|
+
constructor(args: {
|
|
254
|
+
rounds: number;
|
|
255
|
+
low_usd: number;
|
|
256
|
+
expected_usd: number;
|
|
257
|
+
high_usd: number;
|
|
258
|
+
per_member: Array<Record<string, unknown>>;
|
|
259
|
+
subscription_members: Array<Record<string, string>>;
|
|
260
|
+
}) {
|
|
261
|
+
this.rounds = args.rounds;
|
|
262
|
+
this.low_usd = args.low_usd;
|
|
263
|
+
this.expected_usd = args.expected_usd;
|
|
264
|
+
this.high_usd = args.high_usd;
|
|
265
|
+
this.per_member = args.per_member;
|
|
266
|
+
this.subscription_members = args.subscription_members;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export interface EstimateOptions {
|
|
271
|
+
project?: ProjectContext | null;
|
|
272
|
+
original_ask?: string;
|
|
273
|
+
advisor_plans?: Map<string, AdvisorPlan> | null;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface EstimateDebateCostOptions extends EstimateOptions {
|
|
277
|
+
rounds: number;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Project total spend for an N-round debate across all members.
|
|
282
|
+
*
|
|
283
|
+
* Mirrors `estimate()` per-member, then multiplies by `rounds` to account
|
|
284
|
+
* for the per-round preamble + critique pass. CLI / manual members
|
|
285
|
+
* (`billable=false`) are excluded from USD totals and surfaced separately
|
|
286
|
+
* in `subscription_members` so the disclosure block can label them as
|
|
287
|
+
* covered by the user's flat-rate plan.
|
|
288
|
+
*/
|
|
289
|
+
export function estimate_debate_cost(
|
|
290
|
+
question: CouncilQuestion,
|
|
291
|
+
members: ExternalAIClient[],
|
|
292
|
+
table: PriceTable,
|
|
293
|
+
opts: EstimateDebateCostOptions,
|
|
294
|
+
): DebateCostEstimate {
|
|
295
|
+
const rounds = opts.rounds;
|
|
296
|
+
const project = opts.project ?? null;
|
|
297
|
+
const original_ask = opts.original_ask ?? '';
|
|
298
|
+
const advisor_plans = opts.advisor_plans ?? null;
|
|
299
|
+
if (rounds < 1) {
|
|
300
|
+
throw new Error(`rounds must be >= 1 (got ${_pyReprInt(rounds)}).`);
|
|
301
|
+
}
|
|
302
|
+
const billable_members = members.filter(
|
|
303
|
+
(m) => _getattr(m, 'billable', true) as boolean,
|
|
304
|
+
);
|
|
305
|
+
const sub_members: Array<Record<string, string>> = members
|
|
306
|
+
.filter((m) => !(_getattr(m, 'billable', true) as boolean))
|
|
307
|
+
.map((m) => ({
|
|
308
|
+
name: m.name,
|
|
309
|
+
model: m.model,
|
|
310
|
+
transport: _getattr(m, 'transport', 'api') as string,
|
|
311
|
+
subscription_label: _getattr(m, 'subscription_label', '') as string,
|
|
312
|
+
}));
|
|
313
|
+
const per_round = estimate(question, billable_members, table, {
|
|
314
|
+
project,
|
|
315
|
+
original_ask,
|
|
316
|
+
advisor_plans,
|
|
317
|
+
});
|
|
318
|
+
const expected =
|
|
319
|
+
per_round.reduce((acc, e) => acc + _total_usd(e), 0) * rounds;
|
|
320
|
+
// Low bound: output tokens rarely reach `max_output_tokens` ceiling.
|
|
321
|
+
// Use input-only cost + 25% of the output ceiling — empirical floor
|
|
322
|
+
// from manual debate traces.
|
|
323
|
+
const low =
|
|
324
|
+
per_round.reduce((acc, e) => acc + e.input_usd + 0.25 * e.output_usd, 0) *
|
|
325
|
+
rounds;
|
|
326
|
+
// High bound: +20% over-run buffer (roadmap ±20% accuracy target).
|
|
327
|
+
const high = expected * 1.2;
|
|
328
|
+
const per_member: Array<Record<string, unknown>> = [];
|
|
329
|
+
for (let i = 0; i < billable_members.length; i++) {
|
|
330
|
+
const member = billable_members[i] as ExternalAIClient;
|
|
331
|
+
const est = per_round[i] as CostEstimate;
|
|
332
|
+
const member_expected = _total_usd(est) * rounds;
|
|
333
|
+
per_member.push({
|
|
334
|
+
name: member.name,
|
|
335
|
+
model: member.model,
|
|
336
|
+
transport: _getattr(member, 'transport', 'api') as string,
|
|
337
|
+
low_usd: (est.input_usd + 0.25 * est.output_usd) * rounds,
|
|
338
|
+
expected_usd: member_expected,
|
|
339
|
+
high_usd: member_expected * 1.2,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
return new DebateCostEstimate({
|
|
343
|
+
rounds,
|
|
344
|
+
low_usd: low,
|
|
345
|
+
expected_usd: expected,
|
|
346
|
+
high_usd: high,
|
|
347
|
+
per_member,
|
|
348
|
+
subscription_members: sub_members,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** Mirror the Python `CostEstimate.total_usd` property. */
|
|
353
|
+
function _total_usd(e: CostEstimate): number {
|
|
354
|
+
return e.input_usd + e.output_usd;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Return a pre-call cost estimate per member, in input order.
|
|
359
|
+
*
|
|
360
|
+
* `project` and `original_ask` are passed through to `system_prompt_for()`
|
|
361
|
+
* so the estimate covers the handoff preamble bytes too. Both default to
|
|
362
|
+
* v1-shape (no preamble extension).
|
|
363
|
+
*
|
|
364
|
+
* `advisor_plans` (Phase 6) — when a member's name has a plan, the estimate
|
|
365
|
+
* uses the advisor persona system prompt (typically larger than the bare
|
|
366
|
+
* mode addendum). The cost estimator must mirror `_run_round` exactly so the
|
|
367
|
+
* pre-call preview never under-states the advisor-mode bill.
|
|
368
|
+
*/
|
|
369
|
+
export function estimate(
|
|
370
|
+
question: CouncilQuestion,
|
|
371
|
+
members: ExternalAIClient[],
|
|
372
|
+
table: PriceTable,
|
|
373
|
+
opts: EstimateOptions = {},
|
|
374
|
+
): CostEstimate[] {
|
|
375
|
+
const project = opts.project ?? null;
|
|
376
|
+
const original_ask = opts.original_ask ?? '';
|
|
377
|
+
const plans = opts.advisor_plans ?? new Map<string, AdvisorPlan>();
|
|
378
|
+
const base_user_tokens = estimate_input_tokens(question.user_prompt);
|
|
379
|
+
const base_sys = system_prompt_for(question.mode, { project, original_ask });
|
|
380
|
+
const base_sys_tokens = estimate_input_tokens(base_sys);
|
|
381
|
+
const estimates: CostEstimate[] = [];
|
|
382
|
+
for (const m of members) {
|
|
383
|
+
const plan = plans.get(m.name);
|
|
384
|
+
let sys_tokens: number;
|
|
385
|
+
if (plan === undefined) {
|
|
386
|
+
sys_tokens = base_sys_tokens;
|
|
387
|
+
} else {
|
|
388
|
+
const sys_prompt = advisor_system_prompt(plan.persona_text, {
|
|
389
|
+
project,
|
|
390
|
+
original_ask,
|
|
391
|
+
});
|
|
392
|
+
sys_tokens = estimate_input_tokens(sys_prompt);
|
|
393
|
+
}
|
|
394
|
+
const input_tokens = base_user_tokens + sys_tokens;
|
|
395
|
+
estimates.push(
|
|
396
|
+
estimate_cost(m.name, m.model, input_tokens, question.max_tokens, table),
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
return estimates;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export interface ConsultOptions {
|
|
403
|
+
table?: PriceTable | null;
|
|
404
|
+
on_overrun?: OnOverrunCallback | null;
|
|
405
|
+
project?: ProjectContext | null;
|
|
406
|
+
original_ask?: string;
|
|
407
|
+
rounds?: number;
|
|
408
|
+
on_round_complete?:
|
|
409
|
+
| ((round_idx: number, responses: CouncilResponse[]) => void)
|
|
410
|
+
| null;
|
|
411
|
+
advisor_plans?: Map<string, AdvisorPlan> | null;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Sequentially fan out `question` to every enabled member.
|
|
416
|
+
*
|
|
417
|
+
* - If `table` is provided, USD spend is tracked against
|
|
418
|
+
* `budget.max_total_usd` (when > 0). Without `table`, only the
|
|
419
|
+
* token caps apply (back-compat with v1 callers).
|
|
420
|
+
* - When the projected next-member spend would breach any cap,
|
|
421
|
+
* `on_overrun` is consulted. Returning False marks that member as
|
|
422
|
+
* `cost_budget_exceeded`; True proceeds with the call.
|
|
423
|
+
* - Without `on_overrun`, breaching caps short-circuits remaining
|
|
424
|
+
* members with `cost_budget_exceeded` (v1 behaviour preserved).
|
|
425
|
+
* - `project` + `original_ask` flow into `handoff_preamble()` so the
|
|
426
|
+
* council member receives a neutral context-handoff alongside the
|
|
427
|
+
* artefact. Both default to v1 shape (no preamble extension).
|
|
428
|
+
* - `rounds >= 2` enables multi-round debate (D1). Each subsequent
|
|
429
|
+
* round augments the user prompt with anonymised prior-round
|
|
430
|
+
* responses (provider/model identity stripped). Token + USD caps
|
|
431
|
+
* accumulate across rounds. Returns the FINAL round's responses;
|
|
432
|
+
* use `on_round_complete(round_idx, responses)` to capture
|
|
433
|
+
* intermediate rounds.
|
|
434
|
+
* - `advisor_plans` (Phase 6) keyed by provider name swaps the
|
|
435
|
+
* member's system prompt for the advisor persona via
|
|
436
|
+
* `advisor_system_prompt()`. Replace-mode: no extra calls.
|
|
437
|
+
*/
|
|
438
|
+
export function consult(
|
|
439
|
+
members: ExternalAIClient[],
|
|
440
|
+
question: CouncilQuestion,
|
|
441
|
+
budget: CostBudget | null = null,
|
|
442
|
+
opts: ConsultOptions = {},
|
|
443
|
+
): CouncilResponse[] {
|
|
444
|
+
const table = opts.table ?? null;
|
|
445
|
+
const on_overrun = opts.on_overrun ?? null;
|
|
446
|
+
const project = opts.project ?? null;
|
|
447
|
+
const original_ask = opts.original_ask ?? '';
|
|
448
|
+
const rounds = opts.rounds ?? 1;
|
|
449
|
+
const on_round_complete = opts.on_round_complete ?? null;
|
|
450
|
+
const advisor_plans = opts.advisor_plans ?? null;
|
|
451
|
+
|
|
452
|
+
if (rounds < 1) {
|
|
453
|
+
throw new Error(`rounds must be >= 1 (got ${rounds})`);
|
|
454
|
+
}
|
|
455
|
+
if (members.length === 0) {
|
|
456
|
+
return [];
|
|
457
|
+
}
|
|
458
|
+
const resolvedBudget = budget ?? new CostBudget();
|
|
459
|
+
if (members.length > resolvedBudget.max_calls) {
|
|
460
|
+
throw new Error(
|
|
461
|
+
`Council has ${members.length} members but budget caps at ` +
|
|
462
|
+
`${resolvedBudget.max_calls} calls.`,
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const spent: Spent = { input: 0, output: 0, usd: 0.0 };
|
|
467
|
+
let last_results: CouncilResponse[] = [];
|
|
468
|
+
let current_user_prompt = question.user_prompt;
|
|
469
|
+
|
|
470
|
+
for (let round_idx = 0; round_idx < rounds; round_idx++) {
|
|
471
|
+
const round_question =
|
|
472
|
+
round_idx === 0
|
|
473
|
+
? question
|
|
474
|
+
: new CouncilQuestion({
|
|
475
|
+
mode: question.mode,
|
|
476
|
+
user_prompt: current_user_prompt,
|
|
477
|
+
max_tokens: question.max_tokens,
|
|
478
|
+
});
|
|
479
|
+
last_results = _run_round(members, round_question, resolvedBudget, spent, {
|
|
480
|
+
table,
|
|
481
|
+
on_overrun,
|
|
482
|
+
project,
|
|
483
|
+
original_ask,
|
|
484
|
+
advisor_plans,
|
|
485
|
+
});
|
|
486
|
+
if (on_round_complete !== null) {
|
|
487
|
+
on_round_complete(round_idx, last_results);
|
|
488
|
+
}
|
|
489
|
+
if (round_idx + 1 < rounds) {
|
|
490
|
+
current_user_prompt = _augment_for_next_round(
|
|
491
|
+
question.user_prompt,
|
|
492
|
+
last_results,
|
|
493
|
+
round_idx + 2,
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return last_results;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
interface Spent {
|
|
502
|
+
input: number;
|
|
503
|
+
output: number;
|
|
504
|
+
usd: number;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
interface RunRoundOptions {
|
|
508
|
+
table: PriceTable | null;
|
|
509
|
+
on_overrun: OnOverrunCallback | null;
|
|
510
|
+
project: ProjectContext | null;
|
|
511
|
+
original_ask: string;
|
|
512
|
+
advisor_plans?: Map<string, AdvisorPlan> | null;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/** Run a single round; mutate `spent` with cumulative totals. */
|
|
516
|
+
function _run_round(
|
|
517
|
+
members: ExternalAIClient[],
|
|
518
|
+
question: CouncilQuestion,
|
|
519
|
+
budget: CostBudget,
|
|
520
|
+
spent: Spent,
|
|
521
|
+
opts: RunRoundOptions,
|
|
522
|
+
): CouncilResponse[] {
|
|
523
|
+
const table = opts.table;
|
|
524
|
+
const on_overrun = opts.on_overrun;
|
|
525
|
+
const project = opts.project;
|
|
526
|
+
const original_ask = opts.original_ask;
|
|
527
|
+
const plans = opts.advisor_plans ?? new Map<string, AdvisorPlan>();
|
|
528
|
+
const base_system_prompt = system_prompt_for(question.mode, {
|
|
529
|
+
project,
|
|
530
|
+
original_ask,
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
const _system_prompt_for_member = (m: ExternalAIClient): string => {
|
|
534
|
+
const plan = plans.get(m.name);
|
|
535
|
+
if (plan === undefined) {
|
|
536
|
+
return base_system_prompt;
|
|
537
|
+
}
|
|
538
|
+
return advisor_system_prompt(plan.persona_text, { project, original_ask });
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
const results: CouncilResponse[] = [];
|
|
542
|
+
const estimates: CostEstimate[] | null =
|
|
543
|
+
table !== null
|
|
544
|
+
? estimate(question, members, table, {
|
|
545
|
+
project,
|
|
546
|
+
original_ask,
|
|
547
|
+
advisor_plans: opts.advisor_plans ?? null,
|
|
548
|
+
})
|
|
549
|
+
: null;
|
|
550
|
+
|
|
551
|
+
for (let idx = 0; idx < members.length; idx++) {
|
|
552
|
+
const member = members[idx] as ExternalAIClient;
|
|
553
|
+
// ── non-billable members skip the cost gate entirely ─────────
|
|
554
|
+
// ManualClient (and future PlaywrightClient) cost us $0; their
|
|
555
|
+
// token counts are still tracked from the response below for
|
|
556
|
+
// observability, but no projection / budget breach can apply.
|
|
557
|
+
if (!(_getattr(member, 'billable', true) as boolean)) {
|
|
558
|
+
let response: CouncilResponse;
|
|
559
|
+
try {
|
|
560
|
+
response = member.ask(
|
|
561
|
+
_system_prompt_for_member(member),
|
|
562
|
+
question.user_prompt,
|
|
563
|
+
question.max_tokens,
|
|
564
|
+
);
|
|
565
|
+
} catch (exc) {
|
|
566
|
+
response = new CouncilResponse({
|
|
567
|
+
provider: member.name,
|
|
568
|
+
model: member.model,
|
|
569
|
+
text: '',
|
|
570
|
+
error: _excTag(exc),
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
_stamp_transport_metadata(response, member);
|
|
574
|
+
results.push(response);
|
|
575
|
+
spent.input += response.input_tokens;
|
|
576
|
+
spent.output += response.output_tokens;
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// ── projected spend check ────────────────────────────────────
|
|
581
|
+
const est = estimates ? (estimates[idx] as CostEstimate) : null;
|
|
582
|
+
const proj_input = spent.input + (est ? est.input_tokens : 0);
|
|
583
|
+
const proj_output = spent.output + (est ? est.output_tokens : 0);
|
|
584
|
+
const proj_usd = spent.usd + (est ? _total_usd(est) : 0.0);
|
|
585
|
+
const next_call_usd = est ? _total_usd(est) : 0.0;
|
|
586
|
+
|
|
587
|
+
const breaches_tokens =
|
|
588
|
+
proj_input > budget.max_input_tokens ||
|
|
589
|
+
proj_output > budget.max_output_tokens;
|
|
590
|
+
const breaches_usd =
|
|
591
|
+
budget.max_total_usd > 0 && proj_usd > budget.max_total_usd;
|
|
592
|
+
const breaches_daily =
|
|
593
|
+
budget.daily_limit_usd > 0 &&
|
|
594
|
+
_would_exceed_daily(budget.daily_limit_usd, next_call_usd);
|
|
595
|
+
|
|
596
|
+
if (breaches_tokens || breaches_usd || breaches_daily) {
|
|
597
|
+
const breach_kind = breaches_tokens
|
|
598
|
+
? 'tokens'
|
|
599
|
+
: breaches_daily
|
|
600
|
+
? 'daily'
|
|
601
|
+
: 'session';
|
|
602
|
+
const error_tag =
|
|
603
|
+
breach_kind === 'daily'
|
|
604
|
+
? 'daily_budget_exceeded'
|
|
605
|
+
: 'cost_budget_exceeded';
|
|
606
|
+
if (on_overrun !== null && estimates !== null) {
|
|
607
|
+
const event = new OverrunEvent({
|
|
608
|
+
member_index: idx,
|
|
609
|
+
member,
|
|
610
|
+
next_estimate: estimates[idx] as CostEstimate,
|
|
611
|
+
spent_input_tokens: _pyInt(spent.input),
|
|
612
|
+
spent_output_tokens: _pyInt(spent.output),
|
|
613
|
+
spent_usd: spent.usd,
|
|
614
|
+
projected_total_usd: proj_usd,
|
|
615
|
+
daily_spent_usd:
|
|
616
|
+
budget.daily_limit_usd > 0 ? _today_spend_usd() : 0.0,
|
|
617
|
+
daily_limit_usd: budget.daily_limit_usd,
|
|
618
|
+
breach_kind,
|
|
619
|
+
});
|
|
620
|
+
if (!on_overrun(event)) {
|
|
621
|
+
results.push(_aborted(member, error_tag));
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
} else {
|
|
625
|
+
// v1 behaviour: short-circuit all remaining members.
|
|
626
|
+
for (const left of members.slice(idx)) {
|
|
627
|
+
results.push(_aborted(left, error_tag));
|
|
628
|
+
}
|
|
629
|
+
return results;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// ── actual call ──────────────────────────────────────────────
|
|
634
|
+
let response: CouncilResponse;
|
|
635
|
+
try {
|
|
636
|
+
response = member.ask(
|
|
637
|
+
_system_prompt_for_member(member),
|
|
638
|
+
question.user_prompt,
|
|
639
|
+
question.max_tokens,
|
|
640
|
+
);
|
|
641
|
+
} catch (exc) {
|
|
642
|
+
response = new CouncilResponse({
|
|
643
|
+
provider: member.name,
|
|
644
|
+
model: member.model,
|
|
645
|
+
text: '',
|
|
646
|
+
error: _excTag(exc),
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
results.push(response);
|
|
650
|
+
spent.input += response.input_tokens;
|
|
651
|
+
spent.output += response.output_tokens;
|
|
652
|
+
let actual_usd: number | null = null;
|
|
653
|
+
if (estimates !== null && table !== null) {
|
|
654
|
+
// Bill the actual output against the budget using the
|
|
655
|
+
// member's per-1M output rate. Re-use estimate_cost with
|
|
656
|
+
// the *real* token count.
|
|
657
|
+
const actual = estimate_cost(
|
|
658
|
+
member.name,
|
|
659
|
+
member.model,
|
|
660
|
+
response.input_tokens,
|
|
661
|
+
response.output_tokens,
|
|
662
|
+
table,
|
|
663
|
+
);
|
|
664
|
+
actual_usd = _total_usd(actual);
|
|
665
|
+
spent.usd += _total_usd(actual);
|
|
666
|
+
// Persist to the rolling 24h ledger when the daily cap is
|
|
667
|
+
// active. Errors are swallowed inside record_spend.
|
|
668
|
+
if (budget.daily_limit_usd > 0 && !response.error) {
|
|
669
|
+
_record_daily_spend(_total_usd(actual), member.name, member.model);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
_stamp_transport_metadata(response, member, actual_usd);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
return results;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
function _aborted(member: ExternalAIClient, reason: string): CouncilResponse {
|
|
679
|
+
const response = new CouncilResponse({
|
|
680
|
+
provider: member.name,
|
|
681
|
+
model: member.model,
|
|
682
|
+
text: '',
|
|
683
|
+
error: reason,
|
|
684
|
+
});
|
|
685
|
+
_stamp_transport_metadata(response, member);
|
|
686
|
+
return response;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Annotate `response.metadata` with transport / billable / cost info.
|
|
691
|
+
*
|
|
692
|
+
* Phase 5 / Step 1 — the session writer and orchestrator renderer key
|
|
693
|
+
* off these fields to format the cost line as either
|
|
694
|
+
* `cost: subscription (claude-pro)` (non-billable vendor CLI) or
|
|
695
|
+
* `cost: $0.NNNN (… in / … out)` (billable api or community CLI).
|
|
696
|
+
* Stamped here (and not in each client) so the writer stays decoupled
|
|
697
|
+
* from the client class hierarchy.
|
|
698
|
+
*/
|
|
699
|
+
function _stamp_transport_metadata(
|
|
700
|
+
response: CouncilResponse,
|
|
701
|
+
member: ExternalAIClient,
|
|
702
|
+
cost_usd: number | null = null,
|
|
703
|
+
): void {
|
|
704
|
+
const meta: Record<string, unknown> = { ...(response.metadata ?? {}) };
|
|
705
|
+
const transport = _getattr(member, 'transport', 'api') as string;
|
|
706
|
+
_setdefault(meta, 'transport', transport);
|
|
707
|
+
_setdefault(meta, 'billable', Boolean(_getattr(member, 'billable', true)));
|
|
708
|
+
const label = (_getattr(member, 'subscription_label', '') as string) || '';
|
|
709
|
+
if (label && !(_metaGet(meta, 'billable', true) as boolean)) {
|
|
710
|
+
_setdefault(meta, 'subscription_label', label);
|
|
711
|
+
}
|
|
712
|
+
if (cost_usd !== null) {
|
|
713
|
+
meta['cost_usd'] = Number(cost_usd);
|
|
714
|
+
}
|
|
715
|
+
response.metadata = meta;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Build the round-N user prompt: original artefact + anonymised prior round.
|
|
720
|
+
*
|
|
721
|
+
* Provider/model identifiers are stripped (Iron Law of Neutrality §
|
|
722
|
+
* multi-round). Reviewers are labelled "Reviewer A / B / C…" in the
|
|
723
|
+
* order they appeared. Errors are skipped — they reveal nothing
|
|
724
|
+
* useful and can leak provider error formats.
|
|
725
|
+
*/
|
|
726
|
+
function _augment_for_next_round(
|
|
727
|
+
original_prompt: string,
|
|
728
|
+
prior_responses: CouncilResponse[],
|
|
729
|
+
next_round_number: number,
|
|
730
|
+
): string {
|
|
731
|
+
const blocks: string[] = [];
|
|
732
|
+
let label_idx = 0;
|
|
733
|
+
for (const r of prior_responses) {
|
|
734
|
+
if (r.error || !_pyStrip(r.text)) {
|
|
735
|
+
continue;
|
|
736
|
+
}
|
|
737
|
+
const label = _label(label_idx);
|
|
738
|
+
label_idx += 1;
|
|
739
|
+
blocks.push(`### Reviewer ${label}\n\n${_pyStrip(r.text)}`);
|
|
740
|
+
}
|
|
741
|
+
if (blocks.length === 0) {
|
|
742
|
+
return original_prompt;
|
|
743
|
+
}
|
|
744
|
+
const prior_block = blocks.join('\n\n');
|
|
745
|
+
return (
|
|
746
|
+
`${original_prompt}\n\n` +
|
|
747
|
+
`---\n\n` +
|
|
748
|
+
`## Prior round critiques (round ${next_round_number - 1})\n\n` +
|
|
749
|
+
`You are now in round ${next_round_number}. Below are anonymised\n` +
|
|
750
|
+
`critiques from independent reviewers in the previous round.\n` +
|
|
751
|
+
`You do NOT know which model produced which critique. Read them,\n` +
|
|
752
|
+
`then respond with:\n\n` +
|
|
753
|
+
`1. Which prior points you agree with (cite reviewer label).\n` +
|
|
754
|
+
`2. Which you disagree with and why.\n` +
|
|
755
|
+
`3. New points or refinements not raised in round 1.\n\n` +
|
|
756
|
+
`${prior_block}`
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Snapshot passed to the continue-prompt callback between rounds.
|
|
762
|
+
*
|
|
763
|
+
* Phase 7 progressive-disclosure contract — the orchestrator pauses
|
|
764
|
+
* after each completed round, builds this checkpoint, and asks the
|
|
765
|
+
* caller whether to continue. Returning False stops the debate
|
|
766
|
+
* gracefully (caller receives every completed round).
|
|
767
|
+
*/
|
|
768
|
+
export class DebateCheckpoint {
|
|
769
|
+
completed_round: number; // 1-based index of the round just finished
|
|
770
|
+
total_planned_rounds: number;
|
|
771
|
+
cost_so_far_usd: number;
|
|
772
|
+
next_round_estimate_usd: number;
|
|
773
|
+
last_round_responses: CouncilResponse[];
|
|
774
|
+
|
|
775
|
+
constructor(args: {
|
|
776
|
+
completed_round: number;
|
|
777
|
+
total_planned_rounds: number;
|
|
778
|
+
cost_so_far_usd: number;
|
|
779
|
+
next_round_estimate_usd: number;
|
|
780
|
+
last_round_responses: CouncilResponse[];
|
|
781
|
+
}) {
|
|
782
|
+
this.completed_round = args.completed_round;
|
|
783
|
+
this.total_planned_rounds = args.total_planned_rounds;
|
|
784
|
+
this.cost_so_far_usd = args.cost_so_far_usd;
|
|
785
|
+
this.next_round_estimate_usd = args.next_round_estimate_usd;
|
|
786
|
+
this.last_round_responses = args.last_round_responses;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* Raised when projected next-round spend would breach the budget cap.
|
|
792
|
+
*
|
|
793
|
+
* The CLI catches this *after* writing the partial artefact, so the
|
|
794
|
+
* user always has a recoverable trail of the rounds that completed
|
|
795
|
+
* before the cap fired.
|
|
796
|
+
*/
|
|
797
|
+
export class DebateCapExceeded extends Error {
|
|
798
|
+
completed_round: number;
|
|
799
|
+
cost_so_far: number;
|
|
800
|
+
next_estimate: number;
|
|
801
|
+
cap: number;
|
|
802
|
+
|
|
803
|
+
constructor(args: {
|
|
804
|
+
completed_round: number;
|
|
805
|
+
cost_so_far: number;
|
|
806
|
+
next_estimate: number;
|
|
807
|
+
cap: number;
|
|
808
|
+
}) {
|
|
809
|
+
super(
|
|
810
|
+
`Debate hard-cap: round ${args.completed_round + 1} would push spend ` +
|
|
811
|
+
`to $${_pyFixed(args.cost_so_far + args.next_estimate, 4)} ` +
|
|
812
|
+
`(cap=$${_pyFixed(args.cap, 4)}); ` +
|
|
813
|
+
`stopping after round ${args.completed_round}.`,
|
|
814
|
+
);
|
|
815
|
+
this.name = 'DebateCapExceeded';
|
|
816
|
+
this.completed_round = args.completed_round;
|
|
817
|
+
this.cost_so_far = args.cost_so_far;
|
|
818
|
+
this.next_estimate = args.next_estimate;
|
|
819
|
+
this.cap = args.cap;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// Continue-prompt callback. Receives a DebateCheckpoint, returns True to
|
|
824
|
+
// proceed with the next round, False to stop gracefully.
|
|
825
|
+
export type DebateContinuePrompt = (checkpoint: DebateCheckpoint) => boolean;
|
|
826
|
+
|
|
827
|
+
/**
|
|
828
|
+
* Build the round-N user prompt for a debate — rebuttal framing.
|
|
829
|
+
*
|
|
830
|
+
* Same anonymisation rules as `_augment_for_next_round` (Iron Law of
|
|
831
|
+
* Neutrality § multi-round): provider/model identifiers stripped,
|
|
832
|
+
* "Reviewer A / B / C…" labels assigned in input order, errors
|
|
833
|
+
* skipped. The instruction block is debate-specific: each reviewer
|
|
834
|
+
* is asked to identify the strongest opposing position and write a
|
|
835
|
+
* rebuttal, NOT to find common ground.
|
|
836
|
+
*/
|
|
837
|
+
function _augment_for_debate_round(
|
|
838
|
+
original_prompt: string,
|
|
839
|
+
prior_responses: CouncilResponse[],
|
|
840
|
+
next_round_number: number,
|
|
841
|
+
): string {
|
|
842
|
+
const blocks: string[] = [];
|
|
843
|
+
let label_idx = 0;
|
|
844
|
+
for (const r of prior_responses) {
|
|
845
|
+
if (r.error || !_pyStrip(r.text)) {
|
|
846
|
+
continue;
|
|
847
|
+
}
|
|
848
|
+
const label = _label(label_idx);
|
|
849
|
+
label_idx += 1;
|
|
850
|
+
blocks.push(`### Reviewer ${label}\n\n${_pyStrip(r.text)}`);
|
|
851
|
+
}
|
|
852
|
+
if (blocks.length === 0) {
|
|
853
|
+
return original_prompt;
|
|
854
|
+
}
|
|
855
|
+
const prior_block = blocks.join('\n\n');
|
|
856
|
+
return (
|
|
857
|
+
`${original_prompt}\n\n` +
|
|
858
|
+
`---\n\n` +
|
|
859
|
+
`## Prior round positions (round ${next_round_number - 1})\n\n` +
|
|
860
|
+
`You are now in round ${next_round_number} of a structured\n` +
|
|
861
|
+
`debate. Below are anonymised positions from independent\n` +
|
|
862
|
+
`reviewers in the previous round. You do NOT know which model\n` +
|
|
863
|
+
`produced which position.\n\n` +
|
|
864
|
+
`Identify the SINGLE strongest opposing position and write a\n` +
|
|
865
|
+
`rebuttal addressed at its strongest steel-manned form. Do NOT\n` +
|
|
866
|
+
`search for common ground — name the load-bearing flaw the\n` +
|
|
867
|
+
`opposing reviewer missed and state the evidence behind your\n` +
|
|
868
|
+
`counter-position.\n\n` +
|
|
869
|
+
`${prior_block}`
|
|
870
|
+
);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
export interface RunDebateOptions {
|
|
874
|
+
budget?: CostBudget | null;
|
|
875
|
+
table?: PriceTable | null;
|
|
876
|
+
on_overrun?: OnOverrunCallback | null;
|
|
877
|
+
project?: ProjectContext | null;
|
|
878
|
+
original_ask?: string;
|
|
879
|
+
max_rounds?: number;
|
|
880
|
+
on_round_complete?:
|
|
881
|
+
| ((round_number: number, responses: CouncilResponse[]) => void)
|
|
882
|
+
| null;
|
|
883
|
+
on_continue?: DebateContinuePrompt | null;
|
|
884
|
+
advisor_plans?: Map<string, AdvisorPlan> | null;
|
|
885
|
+
seed_round_1?: CouncilResponse[] | null;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* Run a structured multi-round debate with progressive disclosure.
|
|
890
|
+
*
|
|
891
|
+
* Returns every completed round in order — caller persists each
|
|
892
|
+
* round incrementally via `on_round_complete` for crash safety.
|
|
893
|
+
*
|
|
894
|
+
* Round 1: each member produces an initial position. When
|
|
895
|
+
* `seed_round_1` is provided, it is reused verbatim (no calls) so
|
|
896
|
+
* `/council debate --continue-as-debate` can pivot from an existing
|
|
897
|
+
* `/council default` session.
|
|
898
|
+
*
|
|
899
|
+
* Round 2+: `_augment_for_debate_round` wraps the original prompt
|
|
900
|
+
* with anonymised prior positions and asks each member for a
|
|
901
|
+
* rebuttal addressed at the strongest opposing view.
|
|
902
|
+
*
|
|
903
|
+
* Between rounds: `on_continue(checkpoint)` is consulted. Returning
|
|
904
|
+
* False stops the debate; the caller receives every completed round.
|
|
905
|
+
* `None` (the default) auto-continues — the CLI wires its
|
|
906
|
+
* interactive y/N prompt here, `--auto-continue` passes `None`.
|
|
907
|
+
*
|
|
908
|
+
* Hard cap: before kicking off round N+1, the orchestrator compares
|
|
909
|
+
* `spent_usd + next_round_estimate` to `budget.max_total_usd`. A
|
|
910
|
+
* projected breach raises `DebateCapExceeded`; the CLI catches it
|
|
911
|
+
* after persisting the partial debate.
|
|
912
|
+
*/
|
|
913
|
+
export function run_debate(
|
|
914
|
+
members: ExternalAIClient[],
|
|
915
|
+
question: CouncilQuestion,
|
|
916
|
+
opts: RunDebateOptions = {},
|
|
917
|
+
): CouncilResponse[][] {
|
|
918
|
+
const budget0 = opts.budget ?? null;
|
|
919
|
+
const table = opts.table ?? null;
|
|
920
|
+
const on_overrun = opts.on_overrun ?? null;
|
|
921
|
+
const project = opts.project ?? null;
|
|
922
|
+
const original_ask = opts.original_ask ?? '';
|
|
923
|
+
const max_rounds = opts.max_rounds ?? 2;
|
|
924
|
+
const on_round_complete = opts.on_round_complete ?? null;
|
|
925
|
+
const on_continue = opts.on_continue ?? null;
|
|
926
|
+
const advisor_plans = opts.advisor_plans ?? null;
|
|
927
|
+
const seed_round_1 = opts.seed_round_1 ?? null;
|
|
928
|
+
|
|
929
|
+
if (max_rounds < 1) {
|
|
930
|
+
throw new Error(`max_rounds must be >= 1 (got ${max_rounds})`);
|
|
931
|
+
}
|
|
932
|
+
if (members.length === 0) {
|
|
933
|
+
return [];
|
|
934
|
+
}
|
|
935
|
+
const budget = budget0 ?? new CostBudget();
|
|
936
|
+
if (members.length > budget.max_calls) {
|
|
937
|
+
throw new Error(
|
|
938
|
+
`Debate has ${members.length} members but budget caps at ` +
|
|
939
|
+
`${budget.max_calls} calls.`,
|
|
940
|
+
);
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
const spent: Spent = { input: 0, output: 0, usd: 0.0 };
|
|
944
|
+
const all_rounds: CouncilResponse[][] = [];
|
|
945
|
+
let current_user_prompt = question.user_prompt;
|
|
946
|
+
|
|
947
|
+
for (let round_idx = 0; round_idx < max_rounds; round_idx++) {
|
|
948
|
+
const round_number = round_idx + 1;
|
|
949
|
+
let results: CouncilResponse[];
|
|
950
|
+
if (round_idx === 0 && seed_round_1 !== null) {
|
|
951
|
+
// Pivot from /council default — reuse the existing round 1
|
|
952
|
+
// verbatim. No calls billed; spend stays at $0 until round 2.
|
|
953
|
+
results = [...seed_round_1];
|
|
954
|
+
} else {
|
|
955
|
+
const round_question =
|
|
956
|
+
round_idx === 0
|
|
957
|
+
? question
|
|
958
|
+
: new CouncilQuestion({
|
|
959
|
+
mode: question.mode,
|
|
960
|
+
user_prompt: current_user_prompt,
|
|
961
|
+
max_tokens: question.max_tokens,
|
|
962
|
+
});
|
|
963
|
+
results = _run_round(members, round_question, budget, spent, {
|
|
964
|
+
table,
|
|
965
|
+
on_overrun,
|
|
966
|
+
project,
|
|
967
|
+
original_ask,
|
|
968
|
+
advisor_plans,
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
all_rounds.push(results);
|
|
973
|
+
if (on_round_complete !== null) {
|
|
974
|
+
on_round_complete(round_number, results);
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// Prep the user-prompt for the next round so the cost estimate
|
|
978
|
+
// below covers the augmented bytes.
|
|
979
|
+
if (round_idx + 1 < max_rounds) {
|
|
980
|
+
current_user_prompt = _augment_for_debate_round(
|
|
981
|
+
question.user_prompt,
|
|
982
|
+
results,
|
|
983
|
+
round_number + 1,
|
|
984
|
+
);
|
|
985
|
+
// Hard-cap + continue-prompt gating before kicking off N+1.
|
|
986
|
+
let next_round_usd: number;
|
|
987
|
+
if (table !== null) {
|
|
988
|
+
const next_question = new CouncilQuestion({
|
|
989
|
+
mode: question.mode,
|
|
990
|
+
user_prompt: current_user_prompt,
|
|
991
|
+
max_tokens: question.max_tokens,
|
|
992
|
+
});
|
|
993
|
+
const next_estimates = estimate(next_question, members, table, {
|
|
994
|
+
project,
|
|
995
|
+
original_ask,
|
|
996
|
+
advisor_plans,
|
|
997
|
+
});
|
|
998
|
+
next_round_usd = next_estimates.reduce(
|
|
999
|
+
(acc, e) => acc + _total_usd(e),
|
|
1000
|
+
0,
|
|
1001
|
+
);
|
|
1002
|
+
} else {
|
|
1003
|
+
next_round_usd = 0.0;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
if (
|
|
1007
|
+
budget.max_total_usd > 0 &&
|
|
1008
|
+
spent.usd + next_round_usd > budget.max_total_usd
|
|
1009
|
+
) {
|
|
1010
|
+
throw new DebateCapExceeded({
|
|
1011
|
+
completed_round: round_number,
|
|
1012
|
+
cost_so_far: spent.usd,
|
|
1013
|
+
next_estimate: next_round_usd,
|
|
1014
|
+
cap: budget.max_total_usd,
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
if (on_continue !== null) {
|
|
1019
|
+
const checkpoint = new DebateCheckpoint({
|
|
1020
|
+
completed_round: round_number,
|
|
1021
|
+
total_planned_rounds: max_rounds,
|
|
1022
|
+
cost_so_far_usd: spent.usd,
|
|
1023
|
+
next_round_estimate_usd: next_round_usd,
|
|
1024
|
+
last_round_responses: results,
|
|
1025
|
+
});
|
|
1026
|
+
if (!on_continue(checkpoint)) {
|
|
1027
|
+
return all_rounds;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
return all_rounds;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* Bundle returned by `run_peer_review()` (Phase 5 / F1).
|
|
1038
|
+
*
|
|
1039
|
+
* `responses` carries the per-reviewer critiques. `label_to_source`
|
|
1040
|
+
* is the anonymisation map captured server-side so the audit-trail
|
|
1041
|
+
* JSON can rehydrate it without leaking provider identity to the
|
|
1042
|
+
* member at prompt time.
|
|
1043
|
+
*
|
|
1044
|
+
* `persona_labels` is the (optional) Phase 6 / Step 3a wiring: when
|
|
1045
|
+
* the deliberation was an advisor-mode run, the source → persona
|
|
1046
|
+
* map flows through to the renderer so peer-review output can render
|
|
1047
|
+
* as `Response A (Contrarian)`. Plain-member runs leave it empty.
|
|
1048
|
+
*/
|
|
1049
|
+
export class PeerReviewResult {
|
|
1050
|
+
responses: CouncilResponse[];
|
|
1051
|
+
label_to_source: Map<string, string>;
|
|
1052
|
+
persona_labels: Map<string, string>;
|
|
1053
|
+
|
|
1054
|
+
constructor(args: {
|
|
1055
|
+
responses: CouncilResponse[];
|
|
1056
|
+
label_to_source: Map<string, string>;
|
|
1057
|
+
persona_labels: Map<string, string>;
|
|
1058
|
+
}) {
|
|
1059
|
+
this.responses = args.responses;
|
|
1060
|
+
this.label_to_source = args.label_to_source;
|
|
1061
|
+
this.persona_labels = args.persona_labels;
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
export interface RunPeerReviewOptions {
|
|
1066
|
+
budget?: CostBudget | null;
|
|
1067
|
+
table?: PriceTable | null;
|
|
1068
|
+
on_overrun?: OnOverrunCallback | null;
|
|
1069
|
+
project?: ProjectContext | null;
|
|
1070
|
+
original_ask?: string;
|
|
1071
|
+
max_tokens?: number;
|
|
1072
|
+
persona_labels?: Map<string, string> | null;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/**
|
|
1076
|
+
* Karpathy peer-review pass (Phase 5 / F1).
|
|
1077
|
+
*
|
|
1078
|
+
* After the final deliberation round, each member sees the OTHER
|
|
1079
|
+
* members' deliberation outputs under neutral `Response-A` labels
|
|
1080
|
+
* (provider identity stripped; advisor persona labels preserved per
|
|
1081
|
+
* Phase 6 Step 3a) and emits a Karpathy-style critique:
|
|
1082
|
+
* strongest / weakest blind spot / what all missed / refinement.
|
|
1083
|
+
*
|
|
1084
|
+
* Members never see their own response — the orchestrator filters
|
|
1085
|
+
* self before building the anonymised prompt. Errors in one member's
|
|
1086
|
+
* pass tag that member but never abort the round.
|
|
1087
|
+
*
|
|
1088
|
+
* Cost gates flow through `consult([member], ...)`, so the same
|
|
1089
|
+
* budget + daily-ledger semantics as deliberation apply.
|
|
1090
|
+
*/
|
|
1091
|
+
export function run_peer_review(
|
|
1092
|
+
members: ExternalAIClient[],
|
|
1093
|
+
deliberation_responses: CouncilResponse[],
|
|
1094
|
+
opts: RunPeerReviewOptions = {},
|
|
1095
|
+
): PeerReviewResult {
|
|
1096
|
+
const budget = opts.budget ?? null;
|
|
1097
|
+
const table = opts.table ?? null;
|
|
1098
|
+
const on_overrun = opts.on_overrun ?? null;
|
|
1099
|
+
const project = opts.project ?? null;
|
|
1100
|
+
const original_ask = opts.original_ask ?? '';
|
|
1101
|
+
const max_tokens = opts.max_tokens ?? DEFAULT_MAX_TOKENS;
|
|
1102
|
+
|
|
1103
|
+
if (members.length === 0 || deliberation_responses.length === 0) {
|
|
1104
|
+
return new PeerReviewResult({
|
|
1105
|
+
responses: [],
|
|
1106
|
+
label_to_source: new Map(),
|
|
1107
|
+
persona_labels: new Map(),
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
const member_by_name = new Map<string, ExternalAIClient>();
|
|
1112
|
+
for (const m of members) {
|
|
1113
|
+
member_by_name.set(m.name, m);
|
|
1114
|
+
}
|
|
1115
|
+
// ── source map: deliberation responses keyed by `provider:model` ─
|
|
1116
|
+
// Errors and empty bodies are skipped — they leak nothing useful
|
|
1117
|
+
// and would clutter the anonymised prompt with blanks.
|
|
1118
|
+
const by_source = new Map<string, CouncilResponse>();
|
|
1119
|
+
for (const r of deliberation_responses) {
|
|
1120
|
+
if (r.error || !_pyStrip(r.text)) {
|
|
1121
|
+
continue;
|
|
1122
|
+
}
|
|
1123
|
+
const source = `${r.provider}:${r.model}`;
|
|
1124
|
+
by_source.set(source, r);
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
if (by_source.size < 2) {
|
|
1128
|
+
// Peer-review needs ≥ 2 distinct deliberation outputs (a
|
|
1129
|
+
// reviewer with nothing else to review is a no-op).
|
|
1130
|
+
return new PeerReviewResult({
|
|
1131
|
+
responses: [],
|
|
1132
|
+
label_to_source: new Map(),
|
|
1133
|
+
persona_labels: new Map(),
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
const persona_labels = new Map<string, string>(opts.persona_labels ?? []);
|
|
1138
|
+
const review_responses: CouncilResponse[] = [];
|
|
1139
|
+
// ── final label_to_source map captured from the LAST member call
|
|
1140
|
+
// so the renderer / JSON dump has the deterministic A/B mapping.
|
|
1141
|
+
// Each member sees a different N-1 subset (self filtered), but the
|
|
1142
|
+
// ordering of `by_source` stays stable, so the label assignment is
|
|
1143
|
+
// deterministic per artefact run.
|
|
1144
|
+
let last_label_to_source = new Map<string, string>();
|
|
1145
|
+
|
|
1146
|
+
for (const reviewer of members) {
|
|
1147
|
+
const scorer = `${reviewer.name}:${reviewer.model}`;
|
|
1148
|
+
if (!member_by_name.has(reviewer.name)) {
|
|
1149
|
+
continue;
|
|
1150
|
+
}
|
|
1151
|
+
const others_pairs: Array<[string, string]> = [];
|
|
1152
|
+
for (const [src, resp] of by_source) {
|
|
1153
|
+
if (src !== scorer) {
|
|
1154
|
+
others_pairs.push([src, resp.text]);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
if (others_pairs.length === 0) {
|
|
1158
|
+
continue;
|
|
1159
|
+
}
|
|
1160
|
+
const [anon_text, label_to_source] = anonymize_responses(others_pairs, {
|
|
1161
|
+
persona_labels,
|
|
1162
|
+
});
|
|
1163
|
+
if (anon_text.size === 0) {
|
|
1164
|
+
continue;
|
|
1165
|
+
}
|
|
1166
|
+
last_label_to_source = label_to_source;
|
|
1167
|
+
const question = new CouncilQuestion({
|
|
1168
|
+
mode: 'prompt',
|
|
1169
|
+
user_prompt: build_peer_review_user_prompt(anon_text),
|
|
1170
|
+
max_tokens,
|
|
1171
|
+
});
|
|
1172
|
+
const reviewed = consult([reviewer], question, budget, {
|
|
1173
|
+
table,
|
|
1174
|
+
on_overrun,
|
|
1175
|
+
project,
|
|
1176
|
+
original_ask,
|
|
1177
|
+
});
|
|
1178
|
+
review_responses.push(...reviewed);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
return new PeerReviewResult({
|
|
1182
|
+
responses: review_responses,
|
|
1183
|
+
label_to_source: last_label_to_source,
|
|
1184
|
+
persona_labels,
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
/**
|
|
1189
|
+
* Bundle returned by `run_consensus_scoring()`.
|
|
1190
|
+
*
|
|
1191
|
+
* `bucket` is renderer-ready; `findings`, `scores`, and `metadata`
|
|
1192
|
+
* are kept for audit-trail JSON (council-sessions/*.json).
|
|
1193
|
+
*/
|
|
1194
|
+
export class ConsensusResult {
|
|
1195
|
+
bucket: ConsensusBucket;
|
|
1196
|
+
findings: Finding[];
|
|
1197
|
+
scores: FindingScore[];
|
|
1198
|
+
metadata: Map<string, ConsensusMetadata>;
|
|
1199
|
+
extraction_responses: CouncilResponse[];
|
|
1200
|
+
scoring_responses: CouncilResponse[];
|
|
1201
|
+
|
|
1202
|
+
constructor(args: {
|
|
1203
|
+
bucket: ConsensusBucket;
|
|
1204
|
+
findings: Finding[];
|
|
1205
|
+
scores: FindingScore[];
|
|
1206
|
+
metadata: Map<string, ConsensusMetadata>;
|
|
1207
|
+
extraction_responses: CouncilResponse[];
|
|
1208
|
+
scoring_responses: CouncilResponse[];
|
|
1209
|
+
}) {
|
|
1210
|
+
this.bucket = args.bucket;
|
|
1211
|
+
this.findings = args.findings;
|
|
1212
|
+
this.scores = args.scores;
|
|
1213
|
+
this.metadata = args.metadata;
|
|
1214
|
+
this.extraction_responses = args.extraction_responses;
|
|
1215
|
+
this.scoring_responses = args.scoring_responses;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
export interface RunConsensusScoringOptions {
|
|
1220
|
+
budget?: CostBudget | null;
|
|
1221
|
+
table?: PriceTable | null;
|
|
1222
|
+
on_overrun?: OnOverrunCallback | null;
|
|
1223
|
+
project?: ProjectContext | null;
|
|
1224
|
+
original_ask?: string;
|
|
1225
|
+
max_tokens?: number;
|
|
1226
|
+
strong_threshold?: number;
|
|
1227
|
+
minority_threshold?: number;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
/**
|
|
1231
|
+
* Two-pass consensus round (Phase 4 / F3).
|
|
1232
|
+
*
|
|
1233
|
+
* Pass 1 — extraction: each member re-emits its own deliberation as
|
|
1234
|
+
* a JSON array of `{id, text}` findings. Pass 2 — scoring: each
|
|
1235
|
+
* member sees the *other* members' findings under anonymous labels
|
|
1236
|
+
* and rates them 1-10 + agree/disagree + reason.
|
|
1237
|
+
*
|
|
1238
|
+
* The cost budget is shared across both passes; the daily ledger
|
|
1239
|
+
* receives both. Errors in one member's extraction or scoring tag
|
|
1240
|
+
* that member but never abort the round.
|
|
1241
|
+
*/
|
|
1242
|
+
export function run_consensus_scoring(
|
|
1243
|
+
members: ExternalAIClient[],
|
|
1244
|
+
deliberation_responses: CouncilResponse[],
|
|
1245
|
+
opts: RunConsensusScoringOptions = {},
|
|
1246
|
+
): ConsensusResult {
|
|
1247
|
+
const budget = opts.budget ?? null;
|
|
1248
|
+
const table = opts.table ?? null;
|
|
1249
|
+
const on_overrun = opts.on_overrun ?? null;
|
|
1250
|
+
const project = opts.project ?? null;
|
|
1251
|
+
const original_ask = opts.original_ask ?? '';
|
|
1252
|
+
const max_tokens = opts.max_tokens ?? DEFAULT_MAX_TOKENS;
|
|
1253
|
+
const strong_threshold = opts.strong_threshold ?? 0.7;
|
|
1254
|
+
const minority_threshold = opts.minority_threshold ?? 0.4;
|
|
1255
|
+
|
|
1256
|
+
if (members.length === 0 || deliberation_responses.length === 0) {
|
|
1257
|
+
return new ConsensusResult({
|
|
1258
|
+
bucket: new ConsensusBucket(),
|
|
1259
|
+
findings: [],
|
|
1260
|
+
scores: [],
|
|
1261
|
+
metadata: new Map(),
|
|
1262
|
+
extraction_responses: [],
|
|
1263
|
+
scoring_responses: [],
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
// ── Pass 1: extraction ──────────────────────────────────────────
|
|
1268
|
+
const member_by_name = new Map<string, ExternalAIClient>();
|
|
1269
|
+
for (const m of members) {
|
|
1270
|
+
member_by_name.set(m.name, m);
|
|
1271
|
+
}
|
|
1272
|
+
const extraction_responses: CouncilResponse[] = [];
|
|
1273
|
+
const all_findings: Finding[] = [];
|
|
1274
|
+
for (const resp of deliberation_responses) {
|
|
1275
|
+
const member = member_by_name.get(resp.provider);
|
|
1276
|
+
if (member === undefined || resp.error || !_pyStrip(resp.text)) {
|
|
1277
|
+
continue;
|
|
1278
|
+
}
|
|
1279
|
+
const question = new CouncilQuestion({
|
|
1280
|
+
mode: 'prompt',
|
|
1281
|
+
user_prompt: build_extraction_user_prompt(resp.text),
|
|
1282
|
+
max_tokens,
|
|
1283
|
+
});
|
|
1284
|
+
const extracted = consult([member], question, budget, {
|
|
1285
|
+
table,
|
|
1286
|
+
on_overrun,
|
|
1287
|
+
project,
|
|
1288
|
+
original_ask,
|
|
1289
|
+
});
|
|
1290
|
+
extraction_responses.push(...extracted);
|
|
1291
|
+
if (extracted.length === 0 || extracted[0]!.error) {
|
|
1292
|
+
continue;
|
|
1293
|
+
}
|
|
1294
|
+
const source = `${member.name}:${member.model}`;
|
|
1295
|
+
all_findings.push(
|
|
1296
|
+
...parse_findings_response(extracted[0]!.text, { source }),
|
|
1297
|
+
);
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
if (all_findings.length === 0) {
|
|
1301
|
+
return new ConsensusResult({
|
|
1302
|
+
bucket: new ConsensusBucket(),
|
|
1303
|
+
findings: [],
|
|
1304
|
+
scores: [],
|
|
1305
|
+
metadata: new Map(),
|
|
1306
|
+
extraction_responses,
|
|
1307
|
+
scoring_responses: [],
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
// ── Pass 2: scoring (each member rates the OTHERS' findings) ────
|
|
1312
|
+
const scoring_responses: CouncilResponse[] = [];
|
|
1313
|
+
const all_scores: FindingScore[] = [];
|
|
1314
|
+
for (const member of members) {
|
|
1315
|
+
const scorer = `${member.name}:${member.model}`;
|
|
1316
|
+
const others = all_findings.filter((f) => f.source !== scorer);
|
|
1317
|
+
if (others.length === 0) {
|
|
1318
|
+
continue;
|
|
1319
|
+
}
|
|
1320
|
+
const anon = anonymize_findings(others);
|
|
1321
|
+
const label_to_id = new Map<string, string>();
|
|
1322
|
+
const anon_text = new Map<string, string>();
|
|
1323
|
+
for (const [label, f] of anon) {
|
|
1324
|
+
label_to_id.set(label, f.id);
|
|
1325
|
+
anon_text.set(label, f.text);
|
|
1326
|
+
}
|
|
1327
|
+
const question = new CouncilQuestion({
|
|
1328
|
+
mode: 'prompt',
|
|
1329
|
+
user_prompt: build_scoring_user_prompt(anon_text),
|
|
1330
|
+
max_tokens,
|
|
1331
|
+
});
|
|
1332
|
+
const scored = consult([member], question, budget, {
|
|
1333
|
+
table,
|
|
1334
|
+
on_overrun,
|
|
1335
|
+
project,
|
|
1336
|
+
original_ask,
|
|
1337
|
+
});
|
|
1338
|
+
scoring_responses.push(...scored);
|
|
1339
|
+
if (scored.length === 0 || scored[0]!.error) {
|
|
1340
|
+
continue;
|
|
1341
|
+
}
|
|
1342
|
+
for (const s of parse_scores_response(scored[0]!.text, { scorer })) {
|
|
1343
|
+
const real_id = label_to_id.get(s.finding_id);
|
|
1344
|
+
if (real_id === undefined) {
|
|
1345
|
+
continue;
|
|
1346
|
+
}
|
|
1347
|
+
all_scores.push(
|
|
1348
|
+
new FindingScore(real_id, s.scorer, s.score, s.agree, s.reason),
|
|
1349
|
+
);
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
const metadata = aggregate_scores(all_findings, all_scores);
|
|
1354
|
+
const bucket = bucket_by_threshold(all_findings, metadata, {
|
|
1355
|
+
strong: strong_threshold,
|
|
1356
|
+
minority: minority_threshold,
|
|
1357
|
+
});
|
|
1358
|
+
return new ConsensusResult({
|
|
1359
|
+
bucket,
|
|
1360
|
+
findings: all_findings,
|
|
1361
|
+
scores: all_scores,
|
|
1362
|
+
metadata,
|
|
1363
|
+
extraction_responses,
|
|
1364
|
+
scoring_responses,
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
/**
|
|
1369
|
+
* Format the per-member meta line — tokens, cost (or subscription), latency.
|
|
1370
|
+
*
|
|
1371
|
+
* Phase 5 / Step 1 — non-billable vendor-CLI calls render
|
|
1372
|
+
* `cost: subscription (<label>)` with no token detail (the local
|
|
1373
|
+
* session counted them but the user is on a flat rate). Billable
|
|
1374
|
+
* calls (api or community CLI) render `cost: $X.XXXX` plus tokens.
|
|
1375
|
+
* Tokens marked `estimated=True` get a `~` prefix so the audit
|
|
1376
|
+
* trail flags heuristic counts.
|
|
1377
|
+
*/
|
|
1378
|
+
function _render_response_meta(r: CouncilResponse): string {
|
|
1379
|
+
const meta_dict: Record<string, unknown> = r.metadata ?? {};
|
|
1380
|
+
const billable = Boolean(_metaGet(meta_dict, 'billable', true));
|
|
1381
|
+
const estimated = Boolean(_metaGet(meta_dict, 'tokens_estimated', false));
|
|
1382
|
+
const parts: string[] = [];
|
|
1383
|
+
if (!billable) {
|
|
1384
|
+
const label = (_metaGet(meta_dict, 'subscription_label', null) ||
|
|
1385
|
+
'flat-rate') as string;
|
|
1386
|
+
parts.push(`cost: subscription (${label})`);
|
|
1387
|
+
} else {
|
|
1388
|
+
const cost_usd = _metaGet(meta_dict, 'cost_usd', undefined);
|
|
1389
|
+
if (typeof cost_usd === 'number' && !(typeof cost_usd === 'boolean')) {
|
|
1390
|
+
parts.push(`cost: $${_pyFixed(cost_usd, 4)}`);
|
|
1391
|
+
}
|
|
1392
|
+
const prefix = estimated ? '~' : '';
|
|
1393
|
+
parts.push(
|
|
1394
|
+
`tokens: ${prefix}${r.input_tokens} in / ${prefix}${r.output_tokens} out`,
|
|
1395
|
+
);
|
|
1396
|
+
}
|
|
1397
|
+
parts.push(`${r.latency_ms} ms`);
|
|
1398
|
+
return `*${parts.join(' · ')}*`;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
// Lens defaults for the Phase 9 confidence-explanation badge. The PR
|
|
1402
|
+
// lens stays terse so the existing "Must-fix / Nice-to-have" structure
|
|
1403
|
+
// isn't drowned in scorer prose; every other decision lens shows the
|
|
1404
|
+
// explanation by default. Creative lenses (design/optimize) never reach
|
|
1405
|
+
// this code path because they skip consensus scoring entirely.
|
|
1406
|
+
const _DEFAULT_EXPLAIN_LENSES: ReadonlySet<string> = new Set([
|
|
1407
|
+
'default',
|
|
1408
|
+
'analysis',
|
|
1409
|
+
'debate',
|
|
1410
|
+
'prompt',
|
|
1411
|
+
'roadmap',
|
|
1412
|
+
'diff',
|
|
1413
|
+
'files',
|
|
1414
|
+
]);
|
|
1415
|
+
|
|
1416
|
+
/**
|
|
1417
|
+
* Decide whether the confidence-explanation badge fires by default.
|
|
1418
|
+
*
|
|
1419
|
+
* Pulled into a helper so the CLI `--explain-confidence` /
|
|
1420
|
+
* `--no-explain-confidence` flags and the lens override path share
|
|
1421
|
+
* one truth source.
|
|
1422
|
+
*/
|
|
1423
|
+
function _default_explain_confidence(mode: string | null): boolean {
|
|
1424
|
+
if (mode === null) {
|
|
1425
|
+
return true;
|
|
1426
|
+
}
|
|
1427
|
+
return _DEFAULT_EXPLAIN_LENSES.has(mode);
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
export interface RenderOptions {
|
|
1431
|
+
mode?: string | null;
|
|
1432
|
+
prose_synthesis?: boolean | null;
|
|
1433
|
+
consensus?: ConsensusResult | null;
|
|
1434
|
+
peer_review?: PeerReviewResult | null;
|
|
1435
|
+
explain_confidence?: boolean | null;
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
/**
|
|
1439
|
+
* Render stacked sections + a lens-aware synthesis prompt slot.
|
|
1440
|
+
*
|
|
1441
|
+
* `mode` selects the synthesis template from `prompts.synthesis_template`.
|
|
1442
|
+
* `None` collapses to the default decision-lens template (back-compat).
|
|
1443
|
+
*
|
|
1444
|
+
* `prose_synthesis` is the R4 Q4 escape hatch:
|
|
1445
|
+
* - `True` → force creative-lens passthrough (bare slot) regardless of mode
|
|
1446
|
+
* - `False` → force decision-lens default template even on creative lenses
|
|
1447
|
+
* - `None` → honour the lens default from the table
|
|
1448
|
+
*
|
|
1449
|
+
* `consensus` (Phase 4 / F3) prepends Strong Consensus / Findings /
|
|
1450
|
+
* Minority Views sections when the analysis lens scored its findings.
|
|
1451
|
+
*
|
|
1452
|
+
* `peer_review` (Phase 5 / F1) appends a Peer-Review block listing
|
|
1453
|
+
* each member's critique (under Reviewer-A / Reviewer-B labels, in
|
|
1454
|
+
* member input order so the audit trail is deterministic) and
|
|
1455
|
+
* extends the synthesis template with the
|
|
1456
|
+
* `Peer-Review-Surfaced Blind Spots` addendum.
|
|
1457
|
+
*/
|
|
1458
|
+
export function render(responses: CouncilResponse[], opts: RenderOptions = {}): string {
|
|
1459
|
+
const mode = opts.mode ?? null;
|
|
1460
|
+
const prose_synthesis = opts.prose_synthesis ?? null;
|
|
1461
|
+
const consensus = opts.consensus ?? null;
|
|
1462
|
+
const peer_review = opts.peer_review ?? null;
|
|
1463
|
+
const explain_confidence = opts.explain_confidence ?? null;
|
|
1464
|
+
|
|
1465
|
+
const blocks: string[] = [];
|
|
1466
|
+
const explain =
|
|
1467
|
+
explain_confidence !== null
|
|
1468
|
+
? explain_confidence
|
|
1469
|
+
: _default_explain_confidence(mode);
|
|
1470
|
+
if (
|
|
1471
|
+
consensus !== null &&
|
|
1472
|
+
(consensus.bucket.strong.length > 0 ||
|
|
1473
|
+
consensus.bucket.findings.length > 0 ||
|
|
1474
|
+
consensus.bucket.minority.length > 0)
|
|
1475
|
+
) {
|
|
1476
|
+
blocks.push(_render_consensus(consensus.bucket, explain));
|
|
1477
|
+
}
|
|
1478
|
+
for (const r of responses) {
|
|
1479
|
+
const header = `## ${r.provider} · ${r.model}`;
|
|
1480
|
+
if (r.error) {
|
|
1481
|
+
blocks.push(`${header}\n\n*ERROR:* \`${r.error}\``);
|
|
1482
|
+
continue;
|
|
1483
|
+
}
|
|
1484
|
+
const meta = _render_response_meta(r);
|
|
1485
|
+
blocks.push(`${header}\n\n${meta}\n\n${r.text}`);
|
|
1486
|
+
}
|
|
1487
|
+
if (peer_review !== null && peer_review.responses.length > 0) {
|
|
1488
|
+
blocks.push(_render_peer_review(peer_review));
|
|
1489
|
+
}
|
|
1490
|
+
let template: string;
|
|
1491
|
+
if (prose_synthesis === true) {
|
|
1492
|
+
template = '';
|
|
1493
|
+
} else if (prose_synthesis === false) {
|
|
1494
|
+
template = synthesis_template('default');
|
|
1495
|
+
} else {
|
|
1496
|
+
template = synthesis_template(mode);
|
|
1497
|
+
}
|
|
1498
|
+
if (peer_review !== null && peer_review.responses.length > 0) {
|
|
1499
|
+
const addendum = peer_review_synthesis_addendum();
|
|
1500
|
+
template = template ? `${template}\n${addendum}` : _pyLStrip(addendum);
|
|
1501
|
+
}
|
|
1502
|
+
let body: string;
|
|
1503
|
+
if (template) {
|
|
1504
|
+
body = template;
|
|
1505
|
+
} else {
|
|
1506
|
+
body = '*to be summarised by the host agent*';
|
|
1507
|
+
}
|
|
1508
|
+
blocks.push(`## Convergence / Divergence\n\n${body}`);
|
|
1509
|
+
return blocks.join('\n\n---\n\n');
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
/**
|
|
1513
|
+
* Render the peer-review block under deterministic Reviewer labels.
|
|
1514
|
+
*
|
|
1515
|
+
* Each successful reviewer gets a `### Reviewer X` sub-section. Errors
|
|
1516
|
+
* keep their slot (so the audit trail still surfaces the breach) but
|
|
1517
|
+
* render `ERROR: <tag>` instead of the prompt body.
|
|
1518
|
+
*/
|
|
1519
|
+
function _render_peer_review(peer_review: PeerReviewResult): string {
|
|
1520
|
+
const lines: string[] = ['## Peer-Review (Karpathy)'];
|
|
1521
|
+
let label_idx = 0;
|
|
1522
|
+
for (const r of peer_review.responses) {
|
|
1523
|
+
const label = _label(label_idx);
|
|
1524
|
+
label_idx += 1;
|
|
1525
|
+
if (r.error) {
|
|
1526
|
+
lines.push(`### Reviewer ${label}\n\n*ERROR:* \`${r.error}\``);
|
|
1527
|
+
continue;
|
|
1528
|
+
}
|
|
1529
|
+
lines.push(`### Reviewer ${label}\n\n${_pyStrip(r.text)}`);
|
|
1530
|
+
}
|
|
1531
|
+
return lines.join('\n\n');
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
/**
|
|
1535
|
+
* Render Strong / Findings / Minority sections in renderer order.
|
|
1536
|
+
*
|
|
1537
|
+
* `explain` toggles the Phase 9 confidence-explanation badge — when
|
|
1538
|
+
* `False` the renderer falls back to the terse Phase 4 badge so the
|
|
1539
|
+
* PR lens (and any caller passing `--no-explain-confidence`) keeps
|
|
1540
|
+
* its compact output.
|
|
1541
|
+
*/
|
|
1542
|
+
function _render_consensus(bucket: ConsensusBucket, explain = true): string {
|
|
1543
|
+
const parts: string[] = [];
|
|
1544
|
+
if (bucket.strong.length > 0) {
|
|
1545
|
+
parts.push(
|
|
1546
|
+
'## Strong Consensus\n\n' + _render_bucket(bucket.strong, explain),
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1549
|
+
if (bucket.findings.length > 0) {
|
|
1550
|
+
parts.push('## Findings\n\n' + _render_bucket(bucket.findings, explain));
|
|
1551
|
+
}
|
|
1552
|
+
if (bucket.minority.length > 0) {
|
|
1553
|
+
parts.push(
|
|
1554
|
+
'## Minority Views\n\n' +
|
|
1555
|
+
'*Sub-threshold by consensus; kept for audit trail.*\n\n' +
|
|
1556
|
+
_render_bucket(bucket.minority, explain),
|
|
1557
|
+
);
|
|
1558
|
+
}
|
|
1559
|
+
return parts.join('\n\n');
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
/**
|
|
1563
|
+
* Collapse a multi-line scorer reason to a single ≤`limit`-char line.
|
|
1564
|
+
*
|
|
1565
|
+
* Phase 9 — the dissent summary must fit on one line; we keep the
|
|
1566
|
+
* first sentence-ish chunk and add an ellipsis when truncating. Empty
|
|
1567
|
+
* reasons render as `no rationale`.
|
|
1568
|
+
*/
|
|
1569
|
+
function _truncate_reason(reason: string, limit = 120): string {
|
|
1570
|
+
const flat = reason ? _pySplitWhitespace(reason).join(' ') : '';
|
|
1571
|
+
if (!flat) {
|
|
1572
|
+
return 'no rationale';
|
|
1573
|
+
}
|
|
1574
|
+
if (_pyLen(flat) <= limit) {
|
|
1575
|
+
return flat;
|
|
1576
|
+
}
|
|
1577
|
+
return _pyRStrip(_pySlice(flat, 0, limit - 1)) + '…';
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
/**
|
|
1581
|
+
* Render one bucket of (finding, metadata) tuples.
|
|
1582
|
+
*
|
|
1583
|
+
* The Phase 4 terse badge (`strength · mean · scorers · dissent`)
|
|
1584
|
+
* is preserved on the first line. Phase 9 adds a second
|
|
1585
|
+
* confidence-explanation line whenever `explain` is true *and* at
|
|
1586
|
+
* least one scorer rated the finding — the explanation needs scorer
|
|
1587
|
+
* data to be meaningful.
|
|
1588
|
+
*/
|
|
1589
|
+
function _render_bucket(
|
|
1590
|
+
items: Array<[Finding, ConsensusMetadata]>,
|
|
1591
|
+
explain = true,
|
|
1592
|
+
): string {
|
|
1593
|
+
const lines: string[] = [];
|
|
1594
|
+
for (const [f, m] of items) {
|
|
1595
|
+
const terse_badge =
|
|
1596
|
+
`strength ${_pyFixed(m.consensus_strength, 2)} · ` +
|
|
1597
|
+
`mean ${_pyFixed(m.mean_score, 1)}/10 · ` +
|
|
1598
|
+
`${m.scorers.length} scorers · ` +
|
|
1599
|
+
`${m.dissent_count} dissent`;
|
|
1600
|
+
let block = `- **${f.id}** — ${f.text} \n _${terse_badge}_`;
|
|
1601
|
+
if (explain && m.scorers.length > 0) {
|
|
1602
|
+
let total = m.concur_count + m.dissent_count;
|
|
1603
|
+
if (total <= 0) {
|
|
1604
|
+
total = m.scorers.length;
|
|
1605
|
+
}
|
|
1606
|
+
const parts: string[] = [`${m.concur_count}/${total} members concur`];
|
|
1607
|
+
if (m.dissent_reasons.length > 0) {
|
|
1608
|
+
const first = m.dissent_reasons[0] as readonly [string, string];
|
|
1609
|
+
parts.push(
|
|
1610
|
+
`${first[0]} dissented citing ` + `${_truncate_reason(first[1])}`,
|
|
1611
|
+
);
|
|
1612
|
+
const extra = m.dissent_reasons.length - 1;
|
|
1613
|
+
if (extra > 0) {
|
|
1614
|
+
parts.push(`${extra} other dissent(s)`);
|
|
1615
|
+
}
|
|
1616
|
+
} else {
|
|
1617
|
+
parts.push('no dissent');
|
|
1618
|
+
}
|
|
1619
|
+
parts.push(`mean evidence-quality ${m.evidence_quality}`);
|
|
1620
|
+
block += ' \n _' + parts.join('; ') + '_';
|
|
1621
|
+
}
|
|
1622
|
+
lines.push(block);
|
|
1623
|
+
}
|
|
1624
|
+
return lines.join('\n');
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
// ── small stdlib parity helpers ───────────────────────────────────────
|
|
1628
|
+
|
|
1629
|
+
/** Mirror Python `int(x)` truncation-toward-zero on a float total. */
|
|
1630
|
+
function _pyInt(x: number): number {
|
|
1631
|
+
return Math.trunc(x);
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
/** Mirror Python `repr(int)` for the error message in estimate_debate_cost. */
|
|
1635
|
+
function _pyReprInt(x: number): string {
|
|
1636
|
+
return String(x);
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
/** Mirror `type(exc).__name__ + ": " + str(exc)`. */
|
|
1640
|
+
function _excTag(exc: unknown): string {
|
|
1641
|
+
if (exc instanceof Error) {
|
|
1642
|
+
return `${exc.name}: ${exc.message}`;
|
|
1643
|
+
}
|
|
1644
|
+
return `Error: ${String(exc)}`;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
/** dict.setdefault(key, value) — only set when key absent. */
|
|
1648
|
+
function _setdefault(
|
|
1649
|
+
obj: Record<string, unknown>,
|
|
1650
|
+
key: string,
|
|
1651
|
+
value: unknown,
|
|
1652
|
+
): void {
|
|
1653
|
+
if (!(key in obj)) {
|
|
1654
|
+
obj[key] = value;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1658
|
+
/** dict.get(key, default). */
|
|
1659
|
+
function _metaGet(
|
|
1660
|
+
obj: Record<string, unknown>,
|
|
1661
|
+
key: string,
|
|
1662
|
+
fallback: unknown,
|
|
1663
|
+
): unknown {
|
|
1664
|
+
return key in obj ? obj[key] : fallback;
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
/** Python `str.lstrip()` (no-arg) — strip leading whitespace. */
|
|
1668
|
+
function _pyLStrip(s: string): string {
|
|
1669
|
+
return s.replace(/^\s+/, '');
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
/** Python `str.rstrip()` (no-arg) — strip trailing whitespace. */
|
|
1673
|
+
function _pyRStrip(s: string): string {
|
|
1674
|
+
return s.replace(/\s+$/, '');
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
/** Python `len(str)` — code-point count, not UTF-16 unit count. */
|
|
1678
|
+
function _pyLen(s: string): number {
|
|
1679
|
+
let n = 0;
|
|
1680
|
+
for (const _ of s) {
|
|
1681
|
+
n += 1;
|
|
1682
|
+
}
|
|
1683
|
+
return n;
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
/** Python `s[start:end]` — code-point slicing. */
|
|
1687
|
+
function _pySlice(s: string, start: number, end: number): string {
|
|
1688
|
+
return [...s].slice(start, end).join('');
|
|
1689
|
+
}
|