@event4u/agent-config 16.1.0 → 16.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +98 -257
- package/README.md +14 -12
- package/dist/agent-src/commands/analyze/inbox.md +1 -1
- package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
- package/dist/agent-src/commands/bug/fix.md +17 -2
- package/dist/agent-src/commands/feature/plan.md +1 -1
- package/dist/agent-src/commands/feature/roadmap.md +1 -1
- package/dist/agent-src/commands/fix/ci.md +1 -1
- package/dist/agent-src/commands/implement-ticket.md +1 -1
- package/dist/agent-src/commands/jira-ticket.md +1 -1
- package/dist/agent-src/commands/roadmap/create.md +1 -1
- package/dist/agent-src/commands/roadmap/materialize.md +1 -1
- package/dist/agent-src/commands/roadmap/process-full.md +5 -5
- package/dist/agent-src/commands/roadmap/resolve-blockers.md +361 -0
- package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
- package/dist/agent-src/commands/roadmap.md +18 -4
- package/dist/agent-src/commands/tests/create.md +17 -3
- package/dist/agent-src/commands/tests/execute.md +22 -5
- package/dist/agent-src/commands/work.md +4 -0
- package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
- package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +6 -6
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +4 -8
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +32 -2
- package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
- package/dist/agent-src/contexts/execution/toolchain-resolver.md +101 -7
- package/dist/agent-src/rules/active-remediation.md +1 -1
- package/dist/agent-src/rules/autonomous-execution.md +1 -0
- package/dist/agent-src/rules/broken-access-control.md +1 -0
- package/dist/agent-src/rules/command-suggestion-policy.md +1 -0
- package/dist/agent-src/rules/context-hygiene.md +1 -1
- package/dist/agent-src/rules/decision-revisit-gate.md +16 -33
- package/dist/agent-src/rules/design-fidelity.md +13 -16
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -0
- package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -0
- package/dist/agent-src/rules/domain-safety-pii.md +1 -0
- package/dist/agent-src/rules/domain-safety-retention.md +1 -0
- package/dist/agent-src/rules/engineering-safety-floor.md +1 -0
- package/dist/agent-src/rules/evaluator-independence.md +3 -2
- package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -0
- package/dist/agent-src/rules/finance-safety-floor.md +1 -0
- package/dist/agent-src/rules/git-history-discipline.md +1 -0
- package/dist/agent-src/rules/image-likeness-and-rights.md +1 -0
- package/dist/agent-src/rules/legal-safety-floor.md +3 -2
- package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -0
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
- package/dist/agent-src/rules/media-governance-routing.md +14 -17
- package/dist/agent-src/rules/persona-governance.md +2 -2
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +1 -1
- package/dist/agent-src/rules/question-not-instruction.md +1 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
- package/dist/agent-src/rules/runtime-safety.md +1 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +1 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +3 -2
- package/dist/agent-src/rules/session-canary.md +8 -62
- package/dist/agent-src/rules/settings-ask-protocol.md +1 -0
- package/dist/agent-src/rules/source-confidentiality.md +1 -0
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -0
- package/dist/agent-src/rules/tool-safety.md +1 -0
- package/dist/agent-src/rules/ui-audit-gate.md +1 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +1 -0
- package/dist/agent-src/rules/user-interrupt-priority.md +1 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/dist/agent-src/scripts/deferral_carry.ts +339 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/dist/agent-src/skills/accessibility-auditor/data/aria-patterns.csv +1 -1
- package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +2 -2
- package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
- package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
- package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
- package/dist/agent-src/skills/design-review/SKILL.md +30 -4
- package/dist/agent-src/skills/design-review/references/verification-automation.md +32 -0
- package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +18 -3
- package/dist/agent-src/skills/existing-ui-audit/references/component-taxonomy-detection.md +56 -0
- package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
- package/dist/agent-src/skills/iconography/SKILL.md +1 -1
- package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
- package/dist/agent-src/skills/markitdown/SKILL.md +4 -0
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
- package/dist/agent-src/skills/playwright-testing/SKILL.md +30 -6
- package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
- package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
- package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
- package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
- package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +25 -2
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +30 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +302 -21
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/dist/agent-src/templates/scripts/work_engine/state.ts +57 -7
- package/dist/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
- package/dist/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
- package/dist/cli/python/knowledge_ingest.js +1 -1
- package/dist/cli/python/workspace_drive.js +1 -1
- package/dist/cli/registry.js +1 -1
- package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
- package/dist/cli-delegate/check_update_banner.js +12 -1
- package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
- package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
- package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
- package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-CQWX336L.js} +1 -1
- package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
- package/dist/cli-delegate/chunk-EEHDXSYD.js +2040 -0
- package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-GKE7ZVFA.js} +4 -4
- package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
- package/dist/cli-delegate/{chunk-UNCRJBT3.js → chunk-JQVYKIZA.js} +41 -0
- package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-JY2I2DXV.js} +12 -1
- package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
- package/dist/cli-delegate/{chunk-YUM5KURG.js → chunk-KR6EM23A.js} +235 -1455
- package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-LIYTLH6O.js} +1 -1
- package/dist/cli-delegate/chunk-NQ7WT43P.js +2729 -0
- package/dist/cli-delegate/chunk-NXEILF2K.js +2160 -0
- package/dist/cli-delegate/{chunk-5R7HOLAF.js → chunk-NYX3L2PZ.js} +1 -1
- package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
- package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
- package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-QLDHIPWR.js} +1 -1
- package/dist/cli-delegate/{chunk-HDVVGPQW.js → chunk-RQNNW7IF.js} +1405 -567
- package/dist/cli-delegate/{chunk-S3VFXMTM.js → chunk-S4UMZNES.js} +1 -1
- package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-S4YWNRKO.js} +24 -8
- package/dist/cli-delegate/{chunk-GJCBB2UG.js → chunk-TRI6DQZ6.js} +3054 -325
- package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
- package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
- package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
- package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +1862 -809
- package/dist/cli-delegate/cmd_doctor.js +13 -6
- package/dist/cli-delegate/cmd_doctor_neighbours.js +23 -0
- package/dist/cli-delegate/cmd_explain.js +5 -5
- package/dist/cli-delegate/cmd_export.js +11 -8
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_handoff.js +10 -7
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_memory_get.js +3 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +3 -3
- package/dist/cli-delegate/cmd_preflight.js +6 -6
- package/dist/cli-delegate/cmd_prune.js +11 -8
- package/dist/cli-delegate/cmd_refresh.js +2 -1
- package/dist/cli-delegate/cmd_route_audit.js +8 -6
- package/dist/cli-delegate/cmd_route_explain.js +4 -4
- package/dist/cli-delegate/cmd_session_recycle.js +4 -3
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +11 -8
- package/dist/cli-delegate/cmd_settings_set.js +4 -4
- package/dist/cli-delegate/cmd_sync.js +11 -8
- package/dist/cli-delegate/cmd_uninstall.js +11 -8
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +3 -2
- package/dist/cli-delegate/cmd_validate.js +11 -8
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/cli-delegate/deferral_carry.js +16 -0
- package/dist/cli-delegate/gate_execute.js +2 -2
- package/dist/cli-delegate/roadmap_gates.js +5 -5
- package/dist/cli-delegate/update_roadmap_progress.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +132 -80
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +7 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +6 -4
- package/dist/hooks/dispatch.js +7972 -5186
- package/dist/hooks/dispatch.sha256 +1 -0
- package/dist/install/claudePathsPlan.js +47 -6
- package/dist/install/claudeRuleRewrite.js +7 -0
- package/dist/install/emit_host_rules_cli.js +39 -36
- package/dist/install/globalRuleScope.js +87 -0
- package/dist/install/host_rule_ownership.js +160 -0
- package/dist/install/install.mjs +2226 -1055
- package/dist/install/installThinLayer.js +261 -0
- package/dist/install/installedRuleLinks.js +176 -0
- package/dist/install/wizard-plan.js +24 -0
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +40913 -34865
- package/dist/scripts/_lib/agent_settings.js +11 -0
- package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
- package/dist/scripts/_lib/installed_layer.js +378 -0
- package/dist/scripts/_lib/lean_projection_mode.js +218 -15
- package/dist/scripts/_lib/rule_consequence_class.js +45 -0
- package/dist/scripts/_lib/rule_injection.js +67 -10
- package/dist/scripts/_lib/rule_law_section.js +122 -0
- package/dist/scripts/_lib/thin_rules.js +458 -0
- package/dist/scripts/_lib/windsurf_render.js +60 -0
- package/dist/scripts/condense.js +14 -26
- package/dist/scripts/project_thin_rules.js +14 -294
- package/dist/server/schemas/settings.js +29 -0
- package/dist/shared/skillRanking.js +74 -13
- package/dist/ui/assets/index-Cwq4d0hX.js +23 -0
- package/dist/ui/assets/index-Cyjy8bWO.css +1 -0
- package/dist/ui/index.html +2 -2
- package/docs/contracts/settings-classes.md +10 -6
- package/package.json +4 -4
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/src/agent-src/scripts/deferral_carry.ts +339 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/src/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +302 -21
- package/src/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
- package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/src/agent-src/templates/scripts/work_engine/state.ts +57 -7
- package/src/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
- package/src/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
- package/src/config/agent-settings.template.yml +91 -22
- package/src/config/ci-local-parity.yml +18 -0
- package/src/config/continuity-surface.json +9 -2
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +327 -3
- package/src/config/gate-violation-baselines.json +21 -9
- package/src/config/hook-bundle-budget.json +25 -0
- package/src/config/hook-latency-budget.json +21 -0
- package/src/config/hook-token-budget.json +8 -3
- package/src/config/host-instruction-limits.json +33 -0
- package/src/config/metric-registry.yml +114 -0
- package/src/config/placeholder-drift-budget.json +10 -0
- package/src/config/routing-coverage-seed.json +38 -3
- package/src/config/rule-activation-census.json +7 -3
- package/src/config/rule-consequence-class.json +161 -0
- package/src/config/rule-law-ceilings.json +99 -0
- package/src/install/claudePathsPlan.ts +46 -4
- package/src/install/claudeRuleRewrite.ts +10 -1
- package/src/install/emit_host_rules_cli.ts +43 -34
- package/src/install/globalRuleScope.ts +109 -0
- package/src/install/host_rule_ownership.ts +170 -0
- package/src/install/installThinLayer.ts +312 -0
- package/src/install/installedRuleLinks.ts +220 -0
- package/src/install/wizard-plan.ts +24 -0
- package/src/scripts/_cli/cmd_doctor.ts +28 -90
- package/src/scripts/_cli/cmd_doctor_neighbours.ts +293 -0
- package/src/scripts/_cli/doctor_execution.ts +100 -17
- package/src/scripts/_cli/doctor_network_posture.ts +226 -0
- package/src/scripts/_dispatch.bash +16 -2
- package/src/scripts/_lib/agent_settings.ts +11 -0
- package/src/scripts/_lib/body_portable.ts +102 -0
- package/src/scripts/_lib/cc_transcript.ts +132 -1
- package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
- package/src/scripts/_lib/concern_sla_window.ts +200 -0
- package/src/scripts/_lib/estate_offsets.ts +241 -0
- package/src/scripts/_lib/exemption_shape.ts +143 -0
- package/src/scripts/_lib/fnv.ts +23 -0
- package/src/scripts/_lib/foreign_scan.ts +106 -0
- package/src/scripts/_lib/forge_protection.ts +114 -0
- package/src/scripts/_lib/forge_reader.ts +558 -0
- package/src/scripts/_lib/gitignore_block.ts +314 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +32 -0
- package/src/scripts/_lib/graph_feeder_record.ts +214 -0
- package/src/scripts/_lib/hook_settings.ts +73 -0
- package/src/scripts/_lib/host_capability.ts +40 -19
- package/src/scripts/_lib/host_env_write.ts +111 -0
- package/src/scripts/_lib/host_hook_merge.ts +165 -0
- package/src/scripts/_lib/installed_layer.ts +538 -0
- package/src/scripts/_lib/json_merge.ts +82 -0
- package/src/scripts/_lib/json_pointers.ts +93 -11
- package/src/scripts/_lib/lean_projection_mode.ts +275 -15
- package/src/scripts/_lib/llm_proposer_transport.ts +14 -4
- package/src/scripts/_lib/machine_wake.ts +16 -3
- package/src/scripts/_lib/neighbour_census.ts +760 -0
- package/src/scripts/_lib/neighbour_scan.ts +122 -0
- package/src/scripts/_lib/neighbour_tool_use.ts +189 -0
- package/src/scripts/_lib/obligations.ts +119 -8
- package/src/scripts/_lib/probe_inputs.ts +271 -0
- package/src/scripts/_lib/prompt_shape.ts +46 -0
- package/src/scripts/_lib/read_surface_scan.ts +322 -0
- package/src/scripts/_lib/release_highlights.ts +2 -1
- package/src/scripts/_lib/release_migration_gate.ts +19 -3
- package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
- package/src/scripts/_lib/retrieval_sanitize.ts +77 -16
- package/src/scripts/_lib/review_coverage.ts +134 -0
- package/src/scripts/_lib/rule_consequence_class.ts +71 -0
- package/src/scripts/_lib/rule_injection.ts +130 -10
- package/src/scripts/_lib/rule_law_section.ts +147 -0
- package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
- package/src/scripts/_lib/shell_write_shapes.ts +108 -0
- package/src/scripts/_lib/skill_origin.ts +254 -0
- package/src/scripts/_lib/structural_hiding.ts +622 -0
- package/src/scripts/_lib/structured_ask.ts +64 -21
- package/src/scripts/_lib/thin_rules.ts +540 -0
- package/src/scripts/_lib/touched_file_quality.ts +434 -0
- package/src/scripts/_lib/turn_end_refusals.ts +600 -4
- package/src/scripts/_lib/turn_end_transcript.ts +216 -0
- package/src/scripts/_lib/verification_command.ts +324 -0
- package/src/scripts/_lib/verification_evidence.ts +647 -0
- package/src/scripts/_lib/verify_clause.ts +280 -0
- package/src/scripts/_lib/windsurf_render.ts +63 -0
- package/src/scripts/ai_council/cli_call_budget.ts +13 -5
- package/src/scripts/ai_council/clients.ts +26 -57
- package/src/scripts/ai_council/config.ts +1 -1
- package/src/scripts/ai_council/vendor_defaults.ts +45 -0
- package/src/scripts/ai_team/team_dispatch.ts +4 -0
- package/src/scripts/audit_skill_overlap.ts +261 -0
- package/src/scripts/before_complete_hook.ts +573 -25
- package/src/scripts/bench_hook_latency.ts +412 -5
- package/src/scripts/bench_touched_file_quality.ts +238 -0
- package/src/scripts/cache_realization_report.ts +61 -1
- package/src/scripts/check_argument_hint.ts +287 -0
- package/src/scripts/check_claims.ts +125 -1
- package/src/scripts/check_enforcement_coverage.ts +38 -9
- package/src/scripts/check_enforcement_matrix.ts +621 -22
- package/src/scripts/check_estate_count.ts +130 -153
- package/src/scripts/check_finding_dispositions.ts +138 -7
- package/src/scripts/check_generator_sync.ts +71 -0
- package/src/scripts/check_hook_bundle_composition.ts +370 -0
- package/src/scripts/check_host_docs_digest.ts +786 -0
- package/src/scripts/check_host_format_column.ts +559 -0
- package/src/scripts/check_input_references.ts +228 -0
- package/src/scripts/check_inputs_parity.ts +235 -0
- package/src/scripts/check_kernel_edit_ratified.ts +89 -9
- package/src/scripts/check_kill_switch_table.ts +294 -0
- package/src/scripts/check_memory.ts +7 -1
- package/src/scripts/check_placeholder_drift.ts +221 -0
- package/src/scripts/check_read_surface_coverage.ts +515 -0
- package/src/scripts/check_release_highlights.ts +10 -0
- package/src/scripts/check_release_holds.ts +2 -1
- package/src/scripts/check_release_pr_shape.ts +38 -15
- package/src/scripts/check_routing_coverage.ts +378 -11
- package/src/scripts/check_standing_rule_delivery.ts +33 -13
- package/src/scripts/check_static_parity.ts +17 -0
- package/src/scripts/check_verify_expectation_delta.ts +521 -0
- package/src/scripts/ci_settle.ts +145 -19
- package/src/scripts/closure_scan.ts +115 -1
- package/src/scripts/code_graph/detect.ts +127 -7
- package/src/scripts/code_graph/foreign.ts +194 -0
- package/src/scripts/code_graph/query.ts +217 -4
- package/src/scripts/code_graph/types.ts +26 -2
- package/src/scripts/code_graph/validate.ts +3 -1
- package/src/scripts/code_graph/verbs.ts +103 -0
- package/src/scripts/compile_hook_manifest.ts +90 -14
- package/src/scripts/condense.ts +14 -27
- package/src/scripts/estate_exemption_shape.ts +202 -0
- package/src/scripts/external_sources_denylist.json +29 -4
- package/src/scripts/generate_host_cost_table.ts +1 -1
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +192 -14
- package/src/scripts/hooks/block_config_weakening.ts +294 -4
- package/src/scripts/hooks/block_kernel_rule_writes.ts +9 -78
- package/src/scripts/hooks/block_plumbing_writes.ts +342 -0
- package/src/scripts/hooks/bundle_integrity.ts +291 -0
- package/src/scripts/hooks/chain_nudge_hook.ts +1 -2
- package/src/scripts/hooks/code_graph_context_hook.ts +253 -25
- package/src/scripts/hooks/comment_discipline_hook.ts +1 -3
- package/src/scripts/hooks/concern_failure_policy.ts +280 -0
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/concern_timings.ts +94 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +1 -2
- package/src/scripts/hooks/design_pass_hook.ts +100 -9
- package/src/scripts/hooks/design_slop_hook.ts +1 -2
- package/src/scripts/hooks/dispatch_hook.ts +77 -71
- package/src/scripts/hooks/edit_shape_hook.ts +1 -2
- package/src/scripts/hooks/end_review_nudge_hook.ts +1 -1
- package/src/scripts/hooks/evidence_independence.ts +1 -2
- package/src/scripts/hooks/exit_codes.ts +129 -0
- package/src/scripts/hooks/host_lowering.json +1 -0
- package/src/scripts/hooks/host_lowering.ts +146 -3
- package/src/scripts/hooks/host_lowering.yaml +262 -46
- package/src/scripts/hooks/host_semantics.ts +30 -2
- package/src/scripts/hooks/injection_budget.ts +9 -2
- package/src/scripts/hooks/interruption_ledger_hook.ts +1 -2
- package/src/scripts/hooks/journal_record_hook.ts +1 -2
- package/src/scripts/hooks/memory_recall_hook.ts +1 -2
- package/src/scripts/hooks/obligation_settle_hook.ts +151 -5
- package/src/scripts/hooks/one_question_per_ask_hook.ts +43 -6
- package/src/scripts/hooks/orchestration_record_hook.ts +1 -2
- package/src/scripts/hooks/payload_stub.ts +10 -1
- package/src/scripts/hooks/permission_gate.ts +1 -2
- package/src/scripts/hooks/push_settle_hook.ts +1 -3
- package/src/scripts/hooks/replay_hook.ts +2 -1
- package/src/scripts/hooks/reread_guard_hook.ts +1 -2
- package/src/scripts/hooks/review_baseline_hook.ts +1 -2
- package/src/scripts/hooks/rtk_wrap_hook.ts +1 -2
- package/src/scripts/hooks/rule_inject_hook.ts +765 -68
- package/src/scripts/hooks/run_continuation_hook.ts +13 -15
- package/src/scripts/hooks/skill_route_hook.ts +1 -2
- package/src/scripts/hooks/source_first_gate_hook.ts +1 -2
- package/src/scripts/hooks/spawn_guard_shadow_hook.ts +1 -2
- package/src/scripts/hooks/subagent_ledger_hook.ts +1 -2
- package/src/scripts/hooks/suggestion_capture_hook.ts +1 -1
- package/src/scripts/hooks/table_fingerprint.ts +70 -0
- package/src/scripts/hooks/telemetry_flush_hook.ts +1 -2
- package/src/scripts/hooks/telemetry_usage_hook.ts +65 -10
- package/src/scripts/hooks/tool_result_bytes_hook.ts +93 -9
- package/src/scripts/hooks/turn_end_gate_hook.ts +421 -324
- package/src/scripts/hooks/ui_route_nudge_hook.ts +1 -2
- package/src/scripts/hooks_status.ts +112 -0
- package/src/scripts/injection_scan_hook.ts +7 -0
- package/src/scripts/install.ts +75 -189
- package/src/scripts/installed_layer_report.ts +103 -0
- package/src/scripts/language_mirror_hook.ts +15 -6
- package/src/scripts/learning_sidecar.ts +119 -8
- package/src/scripts/lint_deny_text.ts +419 -0
- package/src/scripts/lint_exit_codes.ts +262 -0
- package/src/scripts/lint_hook_manifest.ts +108 -0
- package/src/scripts/lint_major_migration_sections.ts +156 -26
- package/src/scripts/lint_pack_boundaries.ts +63 -5
- package/src/scripts/lint_roadmap_blockers.ts +78 -12
- package/src/scripts/lint_rule_law_section.ts +517 -0
- package/src/scripts/lint_skill_descriptions.ts +1 -1
- package/src/scripts/lint_skill_scripts_readonly.ts +1 -1
- package/src/scripts/lint_workflow_security.ts +161 -5
- package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
- package/src/scripts/mcp_server/graph_tools.ts +72 -3
- package/src/scripts/mcp_server/prompts.ts +142 -1
- package/src/scripts/measure_routing_signal.ts +54 -16
- package/src/scripts/measure_skill_ranker_baseline.ts +515 -53
- package/src/scripts/measure_turn_end_gate.ts +193 -0
- package/src/scripts/memory_learn_hook.ts +91 -6
- package/src/scripts/memory_lookup.ts +1 -1
- package/src/scripts/model_rule_injection.ts +52 -5
- package/src/scripts/prepack-check.mjs +53 -0
- package/src/scripts/project_thin_rules.ts +34 -327
- package/src/scripts/release_publication.ts +13 -1
- package/src/scripts/report_evidence_temperature.ts +657 -0
- package/src/scripts/report_installed_rule_links.ts +157 -0
- package/src/scripts/report_invocation_surface.ts +383 -0
- package/src/scripts/report_label_agreement.ts +233 -0
- package/src/scripts/report_obligation_carriers.ts +699 -0
- package/src/scripts/report_obligation_mechanism.ts +230 -0
- package/src/scripts/report_obligation_writer_split.ts +236 -0
- package/src/scripts/report_single_token_triggers.ts +277 -0
- package/src/scripts/report_skill_menu_census.ts +208 -0
- package/src/scripts/report_skill_ranker_confusion.ts +442 -0
- package/src/scripts/report_standing_payload_by_host.ts +188 -15
- package/src/scripts/report_verification_record_coverage.ts +306 -0
- package/src/scripts/roadmap_verify_share.ts +213 -0
- package/src/scripts/rule_activation_census.ts +5 -2
- package/src/scripts/rule_trigger_eval.ts +9 -9
- package/src/scripts/schemas/command.schema.json +44 -0
- package/src/scripts/schemas/review-findings.schema.json +7 -2
- package/src/scripts/schemas/rule.schema.json +5 -0
- package/src/scripts/schemas/skill.schema.json +44 -0
- package/src/scripts/self_review_gate.ts +421 -17
- package/src/scripts/semantic_parity_census.ts +314 -0
- package/src/scripts/session_eol_report.ts +54 -1
- package/src/scripts/skill_tools/score_skill_relevance.ts +290 -25
- package/src/scripts/sweep_dead_scan_roots.ts +1 -1
- package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
- package/src/scripts/sync_gitignore.ts +29 -235
- package/src/scripts/trigger_eval_grandfather.json +0 -7
- package/src/scripts/trigger_eval_rotation.ts +122 -27
- package/src/scripts/ui_conformance_probe.ts +156 -4
- package/src/scripts/update_prices.ts +85 -3
- package/src/scripts/write_bundle_digest.mjs +74 -0
- package/src/server/schemas/settings.ts +41 -0
- package/src/shared/skillRanking.ts +117 -11
- package/src/templates/consumer-settings/ONBOARDING.md +1 -0
- package/dist/cli-delegate/chunk-FXYUYU4N.js +0 -4416
- package/dist/cli-delegate/chunk-QJWAUMJW.js +0 -1072
- package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
- package/dist/ui/assets/index-DH1xc62v.js +0 -29
- package/dist/ui/assets/index-jSfMW8_t.css +0 -1
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* report_skill_ranker_confusion — why the ranker misses, before anything changes.
|
|
4
|
+
*
|
|
5
|
+
* `road-to-a-ranker-that-routes` 1.3. The baseline measurement says the ranker
|
|
6
|
+
* is wrong on four prompts in five; it does not say in what WAY it is wrong, and
|
|
7
|
+
* a signal chosen without that is a guess dressed as a fix. This report is the
|
|
8
|
+
* read that has to come first, and it is deliberately READ-ONLY: it changes no
|
|
9
|
+
* default, flips no flag, and its only output is markdown on stdout.
|
|
10
|
+
*
|
|
11
|
+
* IT READS THE TUNING SLICE, NEVER THE SEALED ONE. The partition lives in
|
|
12
|
+
* `measure_skill_ranker_baseline.sliceForId`. A confusion class read off the
|
|
13
|
+
* sealed rows would make every later "lift on held-out data" claim circular —
|
|
14
|
+
* the rows would have been looked at while choosing what to change. The script
|
|
15
|
+
* therefore takes `--slice` but defaults to `tuning`, and prints the slice it
|
|
16
|
+
* read in the artifact's own header so a reader never has to assume.
|
|
17
|
+
*
|
|
18
|
+
* WHAT IT MEASURES, and each is one of 1.3's five asks:
|
|
19
|
+
*
|
|
20
|
+
* 1. per-pack top-1 — where the misses concentrate;
|
|
21
|
+
* 2. the most frequent (expected, ranked-first) pairs — WHICH skill the
|
|
22
|
+
* ranker reaches for instead, which is the only form of this number a
|
|
23
|
+
* candidate signal can be derived from;
|
|
24
|
+
* 3. mean reciprocal rank — whether a miss is a near miss or a rout;
|
|
25
|
+
* 4. the share of misses whose expected skill is outside the top ten —
|
|
26
|
+
* the same question asked as a cliff rather than as an average;
|
|
27
|
+
* 5. false activation on the deliberate empties — how often a prompt a seat
|
|
28
|
+
* judged to have NO skill answer draws a top score as confident as a
|
|
29
|
+
* genuine hit's.
|
|
30
|
+
*
|
|
31
|
+
* Usage:
|
|
32
|
+
* ./scripts-run src/scripts/report_skill_ranker_confusion > out.md
|
|
33
|
+
* ./scripts-run src/scripts/report_skill_ranker_confusion --slice sealed
|
|
34
|
+
* ./scripts-run src/scripts/report_skill_ranker_confusion --ranker keyword-v2
|
|
35
|
+
* ./scripts-run src/scripts/report_skill_ranker_confusion --date 2026-10-01
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import * as path from 'node:path';
|
|
39
|
+
import { fileURLToPath } from 'node:url';
|
|
40
|
+
|
|
41
|
+
import { wilsonInterval } from './_lib/capture_rate.js';
|
|
42
|
+
import {
|
|
43
|
+
REPO,
|
|
44
|
+
SKILLS_DIR,
|
|
45
|
+
type LabelledPrompt,
|
|
46
|
+
type SliceName,
|
|
47
|
+
SLICE_NAMES,
|
|
48
|
+
packsForSkill,
|
|
49
|
+
parseFlagValue,
|
|
50
|
+
parseRanker,
|
|
51
|
+
partitionBySlice,
|
|
52
|
+
rankOptionsFor,
|
|
53
|
+
readMatrixCases,
|
|
54
|
+
readMatrixLabelledPrompts,
|
|
55
|
+
sliceForId,
|
|
56
|
+
sliceSizes,
|
|
57
|
+
} from './measure_skill_ranker_baseline.js';
|
|
58
|
+
import { _globSkillMd, rank, type RankRow } from './skill_tools/score_skill_relevance.js';
|
|
59
|
+
|
|
60
|
+
/** How deep "outside the top ten" is. 1.3's own number, not a derived one. */
|
|
61
|
+
export const DEEP_MISS_DEPTH = 10;
|
|
62
|
+
|
|
63
|
+
/** How many confusion pairs the table carries. 1.3's own number. */
|
|
64
|
+
export const CONFUSION_PAIRS = 20;
|
|
65
|
+
|
|
66
|
+
function round3(n: number): number {
|
|
67
|
+
return Math.round(n * 1000) / 1000;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function pct(n: number, d: number): string {
|
|
71
|
+
return d === 0 ? 'n/a' : `${(100 * (n / d)).toFixed(1)} %`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The 1-based position of the first expected skill, or 0 when the ranker never
|
|
76
|
+
* returns one at all.
|
|
77
|
+
*
|
|
78
|
+
* Zero rather than Infinity because the reciprocal of "absent" is 0, which is
|
|
79
|
+
* exactly what MRR wants, and because a sentinel that participates in
|
|
80
|
+
* arithmetic is how a rank-based metric quietly becomes a different metric.
|
|
81
|
+
*/
|
|
82
|
+
export function firstExpectedRank(rows: readonly RankRow[], expected: readonly string[]): number {
|
|
83
|
+
for (let i = 0; i < rows.length; i += 1) {
|
|
84
|
+
if (expected.includes(rows[i]![0])) return i + 1;
|
|
85
|
+
}
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface RowReading {
|
|
90
|
+
id: string;
|
|
91
|
+
expected: string[];
|
|
92
|
+
rankedFirst: string | null;
|
|
93
|
+
topScore: number;
|
|
94
|
+
rankOfExpected: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function readRows(
|
|
98
|
+
prompts: readonly LabelledPrompt[],
|
|
99
|
+
skillsDir: string,
|
|
100
|
+
ranker: string,
|
|
101
|
+
): RowReading[] {
|
|
102
|
+
const opts = rankOptionsFor(ranker);
|
|
103
|
+
return prompts.map((p) => {
|
|
104
|
+
const rows = rank(p.prompt, skillsDir, opts);
|
|
105
|
+
return {
|
|
106
|
+
id: p.id,
|
|
107
|
+
expected: p.expected,
|
|
108
|
+
rankedFirst: rows[0]?.[0] ?? null,
|
|
109
|
+
topScore: rows[0]?.[1] ?? 0,
|
|
110
|
+
rankOfExpected: firstExpectedRank(rows, p.expected),
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function meanReciprocalRank(readings: readonly RowReading[]): number {
|
|
116
|
+
if (readings.length === 0) return 0;
|
|
117
|
+
let sum = 0;
|
|
118
|
+
for (const r of readings) if (r.rankOfExpected > 0) sum += 1 / r.rankOfExpected;
|
|
119
|
+
return sum / readings.length;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface PackRow {
|
|
123
|
+
pack: string;
|
|
124
|
+
n: number;
|
|
125
|
+
top1: number;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function perPackTop1(
|
|
129
|
+
readings: readonly RowReading[],
|
|
130
|
+
skillsDir: string,
|
|
131
|
+
): PackRow[] {
|
|
132
|
+
const hit = new Map<string, number>();
|
|
133
|
+
const total = new Map<string, number>();
|
|
134
|
+
for (const r of readings) {
|
|
135
|
+
const packs = new Set<string>();
|
|
136
|
+
for (const s of r.expected) for (const p of packsForSkill(skillsDir, s)) packs.add(p);
|
|
137
|
+
const isHit = r.rankOfExpected === 1;
|
|
138
|
+
for (const p of packs) {
|
|
139
|
+
total.set(p, (total.get(p) ?? 0) + 1);
|
|
140
|
+
if (isHit) hit.set(p, (hit.get(p) ?? 0) + 1);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return [...total.keys()]
|
|
144
|
+
.map((pack) => ({
|
|
145
|
+
pack,
|
|
146
|
+
n: total.get(pack) ?? 0,
|
|
147
|
+
top1: round3((hit.get(pack) ?? 0) / Math.max(total.get(pack) ?? 1, 1)),
|
|
148
|
+
}))
|
|
149
|
+
// A TOTAL order, for the same reason `confusionPairs` below needs one:
|
|
150
|
+
// a comparator that never returns 0 leaves equal rows engine-ordered.
|
|
151
|
+
// Harmless here because `total` is a Map and its keys cannot collide —
|
|
152
|
+
// which is exactly why it would have stayed in place beside its own cure.
|
|
153
|
+
.sort((a, b) => a.top1 - b.top1 || b.n - a.n || (a.pack < b.pack ? -1 : a.pack > b.pack ? 1 : 0));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface ConfusionPair {
|
|
157
|
+
expected: string;
|
|
158
|
+
got: string;
|
|
159
|
+
count: number;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* The (expected, ranked-first) pairs, most frequent first.
|
|
164
|
+
*
|
|
165
|
+
* Keyed on the label's FIRST skill — the seat wrote it best-fit-first, so it is
|
|
166
|
+
* the one the pair is a claim about. Counting every skill in a three-slot label
|
|
167
|
+
* would inflate a single row into three confusions and make the frequency column
|
|
168
|
+
* a count of label widths rather than of errors.
|
|
169
|
+
*/
|
|
170
|
+
export function confusionPairs(readings: readonly RowReading[], limit = CONFUSION_PAIRS): ConfusionPair[] {
|
|
171
|
+
const counts = new Map<string, number>();
|
|
172
|
+
for (const r of readings) {
|
|
173
|
+
if (r.rankOfExpected === 1) continue;
|
|
174
|
+
const expected = r.expected[0] ?? '(none)';
|
|
175
|
+
const got = r.rankedFirst ?? '(nothing ranked)';
|
|
176
|
+
const key = `${expected}\u0000${got}`;
|
|
177
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
178
|
+
}
|
|
179
|
+
return (
|
|
180
|
+
[...counts.entries()]
|
|
181
|
+
.map(([key, count]) => {
|
|
182
|
+
const [expected, got] = key.split('\u0000');
|
|
183
|
+
return { expected: expected as string, got: got as string, count };
|
|
184
|
+
})
|
|
185
|
+
// A TOTAL order, so the table is reproducible. The earlier comparator
|
|
186
|
+
// tied on count and `expected` and then returned 1 for both argument
|
|
187
|
+
// orders — never 0 — which leaves equal rows in engine-defined order
|
|
188
|
+
// and quietly breaks the "regenerate every figure" claim this report
|
|
189
|
+
// opens with.
|
|
190
|
+
.sort(
|
|
191
|
+
(a, b) =>
|
|
192
|
+
b.count - a.count ||
|
|
193
|
+
(a.expected < b.expected ? -1 : a.expected > b.expected ? 1 : 0) ||
|
|
194
|
+
(a.got < b.got ? -1 : a.got > b.got ? 1 : 0),
|
|
195
|
+
)
|
|
196
|
+
.slice(0, limit)
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** The deliberate `expected_skills: []` rows, partitioned by the same seal. */
|
|
201
|
+
export function emptyRowIds(repo: string, slice: SliceName): { id: string; prompt: string }[] {
|
|
202
|
+
const out: { id: string; prompt: string }[] = [];
|
|
203
|
+
for (const c of readMatrixCases(repo)) {
|
|
204
|
+
if (c.expected?.length !== 0) continue;
|
|
205
|
+
const id = `${c.rule}#${c.section}[${String(c.ordinal)}]`;
|
|
206
|
+
if (slice !== 'all' && sliceForId(id) !== slice) continue;
|
|
207
|
+
out.push({ id, prompt: c.prompt });
|
|
208
|
+
}
|
|
209
|
+
return out;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface FalseActivation {
|
|
213
|
+
empties: number;
|
|
214
|
+
median_correct_hit_score: number;
|
|
215
|
+
at_or_above_median: number;
|
|
216
|
+
/** `null` when there is no threshold to compare against — see below. */
|
|
217
|
+
share: number | null;
|
|
218
|
+
correct_hits: number;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* How often a prompt with no skill answer draws a score as confident as a hit.
|
|
223
|
+
*
|
|
224
|
+
* The comparison point is the MEDIAN top score among rows the ranker got right,
|
|
225
|
+
* which is the only threshold available that the ranker itself defines. A fixed
|
|
226
|
+
* cutoff would be a number chosen here, and the question 1.3 asks is whether the
|
|
227
|
+
* ranker's own confidence separates the two populations at all.
|
|
228
|
+
*
|
|
229
|
+
* WITH ZERO CORRECT HITS there is no such threshold, and the share is `null`
|
|
230
|
+
* rather than a number. Falling back to a median of 0 would count every empty as
|
|
231
|
+
* at-or-above it — every score is ≥ 0 — and print a 100 % false-activation rate
|
|
232
|
+
* indistinguishable from a measured one.
|
|
233
|
+
*/
|
|
234
|
+
export function falseActivation(
|
|
235
|
+
labelled: readonly RowReading[],
|
|
236
|
+
emptyTopScores: readonly number[],
|
|
237
|
+
): FalseActivation {
|
|
238
|
+
const hits = labelled
|
|
239
|
+
.filter((r) => r.rankOfExpected === 1)
|
|
240
|
+
.map((r) => r.topScore)
|
|
241
|
+
.sort((a, b) => a - b);
|
|
242
|
+
if (hits.length === 0) {
|
|
243
|
+
return {
|
|
244
|
+
empties: emptyTopScores.length,
|
|
245
|
+
median_correct_hit_score: 0,
|
|
246
|
+
at_or_above_median: 0,
|
|
247
|
+
share: null,
|
|
248
|
+
correct_hits: 0,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
const median =
|
|
252
|
+
hits.length % 2 === 1
|
|
253
|
+
? (hits[(hits.length - 1) / 2] as number)
|
|
254
|
+
: ((hits[hits.length / 2 - 1] as number) + (hits[hits.length / 2] as number)) / 2;
|
|
255
|
+
const over = emptyTopScores.filter((s) => s >= median).length;
|
|
256
|
+
return {
|
|
257
|
+
empties: emptyTopScores.length,
|
|
258
|
+
median_correct_hit_score: median,
|
|
259
|
+
at_or_above_median: over,
|
|
260
|
+
share: emptyTopScores.length ? round3(over / emptyTopScores.length) : null,
|
|
261
|
+
correct_hits: hits.length,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function interval(successes: number, trials: number): string {
|
|
266
|
+
const raw = wilsonInterval(successes, trials);
|
|
267
|
+
return `${round3(raw.lower).toFixed(3)} – ${round3(raw.upper).toFixed(3)}`;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function renderReport(opts: {
|
|
271
|
+
repo: string;
|
|
272
|
+
skillsDir: string;
|
|
273
|
+
ranker: string;
|
|
274
|
+
slice: SliceName;
|
|
275
|
+
date: string;
|
|
276
|
+
}): string {
|
|
277
|
+
const whole = readMatrixLabelledPrompts(opts.repo);
|
|
278
|
+
const sizes = sliceSizes(whole);
|
|
279
|
+
const prompts = partitionBySlice(whole, opts.slice);
|
|
280
|
+
const readings = readRows(prompts, opts.skillsDir, opts.ranker);
|
|
281
|
+
|
|
282
|
+
const n = readings.length;
|
|
283
|
+
const top1 = readings.filter((r) => r.rankOfExpected === 1).length;
|
|
284
|
+
const top3 = readings.filter((r) => r.rankOfExpected >= 1 && r.rankOfExpected <= 3).length;
|
|
285
|
+
const unranked = readings.filter((r) => r.rankOfExpected === 0).length;
|
|
286
|
+
const misses = readings.filter((r) => r.rankOfExpected !== 1);
|
|
287
|
+
const deep = misses.filter((r) => r.rankOfExpected === 0 || r.rankOfExpected > DEEP_MISS_DEPTH).length;
|
|
288
|
+
const mrr = meanReciprocalRank(readings);
|
|
289
|
+
|
|
290
|
+
const empties = emptyRowIds(opts.repo, opts.slice);
|
|
291
|
+
const rankOpts = rankOptionsFor(opts.ranker);
|
|
292
|
+
const emptyScores = empties.map((e) => rank(e.prompt, opts.skillsDir, rankOpts)[0]?.[1] ?? 0);
|
|
293
|
+
const fa = falseActivation(readings, emptyScores);
|
|
294
|
+
|
|
295
|
+
const packs = perPackTop1(readings, opts.skillsDir);
|
|
296
|
+
const pairs = confusionPairs(readings);
|
|
297
|
+
|
|
298
|
+
const L: string[] = [];
|
|
299
|
+
L.push(`# Skill-ranker confusion report — ${opts.ranker}, ${opts.slice} slice`);
|
|
300
|
+
L.push('');
|
|
301
|
+
L.push('<!-- evidence-type: analysis -->');
|
|
302
|
+
L.push('');
|
|
303
|
+
L.push(`Produced by \`road-to-a-ranker-that-routes\` 1.3 on ${opts.date}. Read-only: this`);
|
|
304
|
+
L.push('report changes no default and flips no flag. Regenerate every measured figure');
|
|
305
|
+
L.push('below with');
|
|
306
|
+
L.push('');
|
|
307
|
+
L.push('```bash');
|
|
308
|
+
L.push(`./scripts-run src/scripts/report_skill_ranker_confusion --ranker ${opts.ranker} --slice ${opts.slice}`);
|
|
309
|
+
L.push('```');
|
|
310
|
+
L.push('');
|
|
311
|
+
L.push('## What was read');
|
|
312
|
+
L.push('');
|
|
313
|
+
L.push('| | |');
|
|
314
|
+
L.push('|---|---:|');
|
|
315
|
+
L.push(`| labelled rows in the routing matrix | ${String(sizes.all)} |`);
|
|
316
|
+
L.push(`| …in the tuning slice | ${String(sizes.tuning)} |`);
|
|
317
|
+
L.push(`| …in the sealed slice | ${String(sizes.sealed)} |`);
|
|
318
|
+
L.push(`| rows this report read (\`${opts.slice}\`) | ${String(n)} |`);
|
|
319
|
+
L.push(`| deliberate \`expected_skills: []\` rows in the same slice | ${String(empties.length)} |`);
|
|
320
|
+
// The LOADER's own glob, not a second one written here. This count is
|
|
321
|
+
// published as the population behind the document-frequency denominator, so
|
|
322
|
+
// a reimplementation that diverged would print a count of something the
|
|
323
|
+
// ranker did not index — and this one did diverge: it used `existsSync`
|
|
324
|
+
// where the loader uses `statSync().isDirectory()` and swallows errors, and
|
|
325
|
+
// it threw on an absent directory where `rank()` returns [].
|
|
326
|
+
L.push(`| skills indexed | ${String(_globSkillMd(opts.skillsDir).length)} |`);
|
|
327
|
+
L.push('');
|
|
328
|
+
if (opts.slice === 'tuning') {
|
|
329
|
+
L.push('The sealed slice is **not** read here. A confusion class derived from rows a');
|
|
330
|
+
L.push('later lift is measured on would make that lift circular, which is the one');
|
|
331
|
+
L.push('failure a held-out partition exists to prevent.');
|
|
332
|
+
} else if (opts.slice === 'sealed') {
|
|
333
|
+
L.push('**This run READ the sealed slice.** That is legitimate for reporting a result');
|
|
334
|
+
L.push('on held-out rows and is NOT legitimate as an input to choosing what to change:');
|
|
335
|
+
L.push('a confusion class derived from these rows would make every later lift measured');
|
|
336
|
+
L.push('on them circular. Derive from the `tuning` run.');
|
|
337
|
+
} else {
|
|
338
|
+
L.push('**This run read BOTH slices.** A confusion class derived from it therefore');
|
|
339
|
+
L.push('includes the sealed rows, so it may not be used to choose what to change —');
|
|
340
|
+
L.push('that is the `tuning` run, and the seal only means something if the choosing');
|
|
341
|
+
L.push('never sees the other half.');
|
|
342
|
+
}
|
|
343
|
+
L.push('');
|
|
344
|
+
L.push('## The headline on this slice');
|
|
345
|
+
L.push('');
|
|
346
|
+
L.push('| measure | value | 95 % CI |');
|
|
347
|
+
L.push('|---|---:|---|');
|
|
348
|
+
L.push(`| top-1 | ${round3(top1 / Math.max(n, 1)).toFixed(3)} | ${interval(top1, n)} |`);
|
|
349
|
+
L.push(`| top-3 | ${round3(top3 / Math.max(n, 1)).toFixed(3)} | ${interval(top3, n)} |`);
|
|
350
|
+
L.push(`| mean reciprocal rank | ${round3(mrr).toFixed(3)} | — |`);
|
|
351
|
+
L.push('');
|
|
352
|
+
L.push('MRR is the average of 1 / (position of the first expected skill), counting a row');
|
|
353
|
+
L.push('where no expected skill appears anywhere in the ranking as 0. It is the figure');
|
|
354
|
+
L.push('that separates "the right answer was second" from "the right answer was never');
|
|
355
|
+
L.push('returned", and top-1 alone cannot.');
|
|
356
|
+
L.push('');
|
|
357
|
+
L.push('## How deep the misses are');
|
|
358
|
+
L.push('');
|
|
359
|
+
L.push('| | count | share of misses |');
|
|
360
|
+
L.push('|---|---:|---:|');
|
|
361
|
+
L.push(`| top-1 misses | ${String(misses.length)} | — |`);
|
|
362
|
+
L.push(`| …expected skill outside the top ${String(DEEP_MISS_DEPTH)} | ${String(deep)} | ${pct(deep, misses.length)} |`);
|
|
363
|
+
L.push(`| …expected skill not ranked at all (score 0) | ${String(unranked)} | ${pct(unranked, misses.length)} |`);
|
|
364
|
+
L.push('');
|
|
365
|
+
L.push('A miss inside the top ten is a ranking problem — the right skill is in the');
|
|
366
|
+
L.push('candidate set and something else outscored it. A miss outside it, and above all');
|
|
367
|
+
L.push('a row where the expected skill scores zero, is a RECALL problem: no re-weighting');
|
|
368
|
+
L.push('of the existing signal can recover a skill the formula never surfaces. The two');
|
|
369
|
+
L.push('take different fixes, which is why the split is reported rather than an average.');
|
|
370
|
+
L.push('');
|
|
371
|
+
L.push('## False activation on the no-skill prompts');
|
|
372
|
+
L.push('');
|
|
373
|
+
L.push('| | |');
|
|
374
|
+
L.push('|---|---:|');
|
|
375
|
+
L.push(`| deliberate empties in this slice | ${String(fa.empties)} |`);
|
|
376
|
+
L.push(`| correct top-1 hits the median is taken over | ${String(fa.correct_hits)} |`);
|
|
377
|
+
L.push(`| median top score of a correct hit | ${String(fa.median_correct_hit_score)} |`);
|
|
378
|
+
L.push(`| empties whose top score reaches that median | ${String(fa.at_or_above_median)} |`);
|
|
379
|
+
// TWO causes produce a null share and they are not the same answer: no
|
|
380
|
+
// correct hit means there is no threshold to compare against, no empty row
|
|
381
|
+
// means there is nothing to compare. Printing one reason for both would
|
|
382
|
+
// state something the `correct_hits` row beside it contradicts.
|
|
383
|
+
const shareCell =
|
|
384
|
+
fa.share !== null
|
|
385
|
+
? pct(fa.at_or_above_median, fa.empties)
|
|
386
|
+
: fa.correct_hits === 0
|
|
387
|
+
? 'n/a — no correct top-1 hit, so no threshold'
|
|
388
|
+
: 'n/a — no deliberate empties in this slice, so no denominator';
|
|
389
|
+
L.push(`| share | ${shareCell} |`);
|
|
390
|
+
L.push('');
|
|
391
|
+
L.push('The threshold is the ranker\'s own median hit score rather than a cutoff chosen');
|
|
392
|
+
L.push('here, because the question is whether the ranker\'s confidence separates the two');
|
|
393
|
+
L.push('populations at all. A share near one half means it does not: a prompt a seat');
|
|
394
|
+
L.push('judged to have no skill answer is scored as confidently as a prompt it got right.');
|
|
395
|
+
L.push('');
|
|
396
|
+
L.push(`## Per-pack top-1, worst first`);
|
|
397
|
+
L.push('');
|
|
398
|
+
L.push('| pack | labelled rows | top-1 |');
|
|
399
|
+
L.push('|---|---:|---:|');
|
|
400
|
+
for (const p of packs) L.push(`| \`${p.pack}\` | ${String(p.n)} | ${p.top1.toFixed(3)} |`);
|
|
401
|
+
L.push('');
|
|
402
|
+
L.push('A row counts once per pack of each skill its label names, so the column sums');
|
|
403
|
+
L.push('above the row count — the same accounting the per-pack census uses.');
|
|
404
|
+
L.push('');
|
|
405
|
+
L.push(`## The ${String(CONFUSION_PAIRS)} most frequent (expected, ranked-first) pairs`);
|
|
406
|
+
L.push('');
|
|
407
|
+
L.push('| expected (label, best fit first) | ranked first instead | rows |');
|
|
408
|
+
L.push('|---|---|---:|');
|
|
409
|
+
for (const p of pairs) L.push(`| \`${p.expected}\` | \`${p.got}\` | ${String(p.count)} |`);
|
|
410
|
+
L.push('');
|
|
411
|
+
return `${L.join('\n')}\n`;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export function main(argv: readonly string[]): number {
|
|
415
|
+
let body: string;
|
|
416
|
+
try {
|
|
417
|
+
// Every flag through the shared parsers, inside one guard. A typo or a
|
|
418
|
+
// missing value must not reach the renderer: the label is printed in the
|
|
419
|
+
// report's own title and in the regenerate command beside it, and the
|
|
420
|
+
// date is printed in its header, so a swallowed next-flag would publish
|
|
421
|
+
// one configuration's number under another's name or stamp `--slice` as
|
|
422
|
+
// the date. `parseSlice` is not reused here only because this tool's
|
|
423
|
+
// default is `tuning` rather than `all`; the legal set is the one
|
|
424
|
+
// shared constant, so the two cannot disagree about what is valid.
|
|
425
|
+
const rawSlice = parseFlagValue(argv, '--slice', 'tuning');
|
|
426
|
+
if (!SLICE_NAMES.includes(rawSlice as SliceName)) {
|
|
427
|
+
throw new Error(`--slice expects one of ${SLICE_NAMES.join(' | ')}, got ${rawSlice}`);
|
|
428
|
+
}
|
|
429
|
+
const ranker = parseRanker(argv);
|
|
430
|
+
const date = parseFlagValue(argv, '--date', new Date().toISOString().slice(0, 10));
|
|
431
|
+
body = renderReport({ repo: REPO, skillsDir: SKILLS_DIR, ranker, slice: rawSlice as SliceName, date });
|
|
432
|
+
} catch (err) {
|
|
433
|
+
process.stderr.write(`${(err as Error).message}\n`);
|
|
434
|
+
return 2;
|
|
435
|
+
}
|
|
436
|
+
process.stdout.write(body);
|
|
437
|
+
return 0;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
|
|
441
|
+
process.exit(main(process.argv.slice(2)));
|
|
442
|
+
}
|