@event4u/agent-config 14.12.0 → 14.14.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 +118 -155
- package/CONTRIBUTING.md +38 -0
- package/CREDITS.md +135 -0
- package/NOTICE +13 -0
- package/README.md +8 -6
- package/dist/agent-src/commands/analyze/inbox.md +145 -2
- package/dist/agent-src/commands/feature/dev.md +7 -2
- package/dist/agent-src/commands/ghostwriter/write.md +5 -1
- package/dist/agent-src/commands/implement-ticket.md +1 -1
- package/dist/agent-src/commands/mission/upgrade.md +1 -1
- package/dist/agent-src/commands/orchestrate.md +2 -2
- package/dist/agent-src/commands/post-as/me.md +5 -1
- package/dist/agent-src/commands/pr/merge.md +19 -6
- package/dist/agent-src/commands/roadmap/process-full.md +19 -5
- package/dist/agent-src/commands/tdd/red.md +12 -2
- package/dist/agent-src/commands/work.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
- package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
- package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
- package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
- package/dist/agent-src/rules/broken-access-control.md +4 -0
- package/dist/agent-src/rules/code-comment-discipline.md +6 -0
- package/dist/agent-src/rules/code-provenance.md +4 -0
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +4 -0
- package/dist/agent-src/rules/domain-safety-retention.md +4 -0
- package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
- package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
- package/dist/agent-src/rules/improve-before-implement.md +6 -8
- package/dist/agent-src/rules/laravel-routing.md +1 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
- package/dist/agent-src/rules/source-confidentiality.md +12 -34
- package/dist/agent-src/rules/symfony-routing.md +1 -1
- package/dist/agent-src/rules/token-efficiency.md +14 -0
- package/dist/agent-src/rules/tool-safety.md +4 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
- package/dist/agent-src/scripts/guarded_baseline.ts +343 -0
- package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/dist/agent-src/scripts/stub_queue.ts +82 -0
- package/dist/agent-src/scripts/stubs_due.ts +516 -0
- package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +16 -12
- package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
- package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
- package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
- package/dist/agent-src/skills/database/SKILL.md +8 -0
- package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
- package/dist/agent-src/skills/design-review/SKILL.md +1 -1
- package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
- package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
- package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
- package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
- package/dist/agent-src/skills/laravel/SKILL.md +35 -0
- package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
- package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
- package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
- package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
- package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +97 -3
- package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
- package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/dist/cli/commands/uiAudit.js +124 -5
- package/dist/cli/registry.js +2 -0
- package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
- package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
- package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
- package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
- package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
- package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
- package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
- package/dist/cli-delegate/cmd_adr_effective.js +102 -0
- package/dist/cli-delegate/cmd_conformance.js +80 -11
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +3 -2
- package/dist/cli-delegate/cmd_fleet.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +3 -2
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
- package/dist/cli-delegate/cmd_settings_set.js +2 -2
- package/dist/cli-delegate/cmd_sync.js +3 -2
- package/dist/cli-delegate/cmd_uninstall.js +3 -2
- package/dist/cli-delegate/cmd_validate.js +3 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +58 -58
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +2900 -1049
- package/dist/install/claudeRuleRewrite.js +254 -0
- package/dist/install/detect.js +29 -16
- package/dist/install/detect_php_shape.js +159 -0
- package/dist/install/install.mjs +634 -428
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +3 -3
- package/dist/mcp/server.mjs +4895 -2627
- package/dist/server/schemas/settings.js +3 -0
- package/dist/ui/assets/index-D0jaCRPM.js +29 -0
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +1 -1
- package/docs/THIRD-PARTY-NOTICES.md +25 -0
- package/docs/contracts/provider-lifecycle.md +1 -1
- package/docs/contracts/settings-classes.md +10 -4
- package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
- package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
- package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
- package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
- package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
- package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
- package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
- package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
- package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
- package/docs/guidelines/agent-infra/first-principles.md +2 -2
- package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
- package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
- package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
- package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
- package/docs/guidelines/agent-infra/layered-settings.md +10 -10
- package/docs/guidelines/agent-infra/memory-access.md +1 -1
- package/docs/guidelines/agent-infra/mental-models.md +3 -3
- package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
- package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
- package/docs/guidelines/agent-infra/role-contracts.md +2 -2
- package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
- package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
- package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
- package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
- package/docs/guidelines/agent-infra/six-hats.md +3 -3
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
- package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
- package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
- package/docs/guidelines/augment-portability-patterns.md +6 -4
- package/docs/guidelines/code-clarity.md +18 -0
- package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
- package/docs/guidelines/cross-role-handoff.md +2 -2
- package/docs/guidelines/design-fidelity-mechanics.md +1 -1
- package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
- package/docs/guidelines/php/database.md +90 -7
- package/docs/guidelines/prompt-templates.md +7 -7
- package/llms.txt +2 -2
- package/package.json +5 -2
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
- package/src/agent-src/scripts/guarded_baseline.ts +343 -0
- package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/src/agent-src/scripts/stub_queue.ts +82 -0
- package/src/agent-src/scripts/stubs_due.ts +516 -0
- package/src/agent-src/scripts/ticket_bundles.ts +84 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +16 -12
- package/src/agent-src/templates/scripts/check_memory.ts +258 -17
- package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/src/config/agent-settings.template.yml +32 -3
- package/src/config/assurance-capability-registry.json +21 -9
- package/src/config/canonical-terms.yml +119 -0
- package/src/config/capability-native-outcome-bars.json +81 -0
- package/src/config/ci-local-parity.yml +80 -0
- package/src/config/drafting-channels.yml +43 -0
- package/src/config/estate-count-budget.json +57 -36
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +729 -63
- package/src/config/gate-reachability-exemptions.json +21 -0
- package/src/config/gate-violation-baselines.json +42 -19
- package/src/config/harness-evolution-budget.json +25 -0
- package/src/config/lapsed-beta-baseline.json +96 -0
- package/src/config/memory-twin-verdicts.yml +129 -0
- package/src/config/metric-registry.yml +124 -0
- package/src/config/pack-size-budget.json +16 -15
- package/src/config/preamble-payload-budget.json +12 -4
- package/src/config/profiles/balanced.ini +27 -0
- package/src/config/profiles/full.ini +27 -0
- package/src/config/profiles/minimal.ini +27 -0
- package/src/config/publish-surface.json +9 -2
- package/src/config/routing-coverage-seed.json +16 -2
- package/src/config/rule-stub-ceilings.json +133 -112
- package/src/config/turnaround-budget.json +66 -0
- package/src/install/claudeRuleRewrite.ts +288 -0
- package/src/install/detect.ts +60 -17
- package/src/install/detect_php_shape.ts +191 -0
- package/src/scripts/_cli/cmd_doctor.ts +27 -112
- package/src/scripts/_dispatch.bash +23 -0
- package/src/scripts/_lib/activation_ladder.ts +255 -0
- package/src/scripts/_lib/activation_receipt_producer.ts +341 -0
- package/src/scripts/_lib/activation_states.ts +88 -0
- package/src/scripts/_lib/adherence_detectors.ts +143 -0
- package/src/scripts/_lib/adr_frontmatter.ts +26 -0
- package/src/scripts/_lib/arith_claims.ts +181 -0
- package/src/scripts/_lib/arm_ranking.ts +62 -0
- package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
- package/src/scripts/_lib/audit_field_provenance.ts +54 -0
- package/src/scripts/_lib/auto_dispatch.ts +32 -3
- package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
- package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
- package/src/scripts/_lib/candidate_pair_delta.ts +349 -0
- package/src/scripts/_lib/candidate_proposer.ts +402 -0
- package/src/scripts/_lib/candidate_record.ts +601 -0
- package/src/scripts/_lib/capture_rate.ts +319 -0
- package/src/scripts/_lib/carrier_status.ts +118 -0
- package/src/scripts/_lib/cascade_stage_enumeration.ts +92 -0
- package/src/scripts/_lib/collector_denominator.ts +771 -0
- package/src/scripts/_lib/collector_record.ts +340 -0
- package/src/scripts/_lib/collector_store.ts +664 -0
- package/src/scripts/_lib/collector_supervision.ts +827 -0
- package/src/scripts/_lib/concern_estate.ts +77 -0
- package/src/scripts/_lib/config_chain.ts +477 -0
- package/src/scripts/_lib/config_cost.ts +209 -0
- package/src/scripts/_lib/corpus_manifest.ts +726 -0
- package/src/scripts/_lib/council_settings_block.ts +6 -0
- package/src/scripts/_lib/curator_ops.ts +172 -0
- package/src/scripts/_lib/delivery_arm_experiment.ts +282 -0
- package/src/scripts/_lib/delivery_criticality.ts +126 -0
- package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
- package/src/scripts/_lib/empty_cycles.ts +88 -0
- package/src/scripts/_lib/estate_carrier_cases.ts +72 -0
- package/src/scripts/_lib/eval_publication.ts +354 -0
- package/src/scripts/_lib/evaluation_cascade.ts +452 -0
- package/src/scripts/_lib/evaluation_vector.ts +283 -0
- package/src/scripts/_lib/evaluator_promotion.ts +225 -0
- package/src/scripts/_lib/evidence_basis.ts +118 -0
- package/src/scripts/_lib/evolution_roi.ts +562 -0
- package/src/scripts/_lib/exec_evidence.ts +8 -0
- package/src/scripts/_lib/experience_card.ts +272 -0
- package/src/scripts/_lib/experience_report.ts +151 -0
- package/src/scripts/_lib/experiment_freeze.ts +112 -0
- package/src/scripts/_lib/generated_by.ts +66 -0
- package/src/scripts/_lib/harness_evolution_guards.ts +239 -0
- package/src/scripts/_lib/hook_effect_probe.ts +141 -0
- package/src/scripts/_lib/host_denominator.ts +687 -0
- package/src/scripts/_lib/host_projection_reach.ts +157 -0
- package/src/scripts/_lib/ignored_blocker.ts +148 -0
- package/src/scripts/_lib/install_reach_checks.ts +495 -0
- package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
- package/src/scripts/_lib/judge_hygiene.ts +228 -0
- package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
- package/src/scripts/_lib/lexical_shortlist.ts +215 -0
- package/src/scripts/_lib/llm_candidate_proposer.ts +461 -0
- package/src/scripts/_lib/llm_proposer_transport.ts +153 -0
- package/src/scripts/_lib/loop_guards.ts +299 -0
- package/src/scripts/_lib/loss_class.ts +129 -0
- package/src/scripts/_lib/machine_wake.ts +51 -0
- package/src/scripts/_lib/md_prose_lines.ts +177 -0
- package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
- package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
- package/src/scripts/_lib/orchestration_record.ts +253 -5
- package/src/scripts/_lib/outcome_envelope.ts +227 -0
- package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
- package/src/scripts/_lib/paired_stats.ts +245 -0
- package/src/scripts/_lib/paired_verdict.ts +226 -0
- package/src/scripts/_lib/pathology_archive.ts +393 -0
- package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
- package/src/scripts/_lib/privacy_class.ts +47 -0
- package/src/scripts/_lib/promotion_capability.ts +315 -0
- package/src/scripts/_lib/promotion_evidence.ts +414 -0
- package/src/scripts/_lib/promotion_review.ts +294 -0
- package/src/scripts/_lib/prompt_shape.ts +92 -0
- package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
- package/src/scripts/_lib/release_highlights.ts +70 -1
- package/src/scripts/_lib/release_material.ts +125 -2
- package/src/scripts/_lib/repeated_failure.ts +105 -0
- package/src/scripts/_lib/repo_root.ts +111 -0
- package/src/scripts/_lib/review_skipped_record.ts +37 -0
- package/src/scripts/_lib/role_split.ts +338 -0
- package/src/scripts/_lib/routing_corpus.ts +307 -0
- package/src/scripts/_lib/routing_index_input.ts +104 -0
- package/src/scripts/_lib/rule_injection.ts +22 -1
- package/src/scripts/_lib/runtime_journal.ts +1499 -0
- package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
- package/src/scripts/_lib/semantic_noop.ts +167 -0
- package/src/scripts/_lib/skill_catalogue.ts +11 -1
- package/src/scripts/_lib/source_digest.ts +200 -0
- package/src/scripts/_lib/source_redact.ts +260 -0
- package/src/scripts/_lib/source_shape.ts +502 -0
- package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
- package/src/scripts/_lib/strip_comments.d.mts +8 -0
- package/src/scripts/_lib/strip_comments.mjs +65 -0
- package/src/scripts/_lib/test_red_state.ts +154 -0
- package/src/scripts/_lib/trigger_shift.ts +144 -0
- package/src/scripts/_lib/untrusted_content.ts +82 -7
- package/src/scripts/activation_receipt.ts +258 -0
- package/src/scripts/adoption_report.ts +1 -1
- package/src/scripts/adr/evidence_census.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +26 -2
- package/src/scripts/adr_cite_check.ts +164 -1
- package/src/scripts/ai_council/blind_review.ts +11 -1
- package/src/scripts/ai_council/clients.ts +4 -0
- package/src/scripts/ai_council/config.ts +3 -0
- package/src/scripts/ai_council/consensus.ts +28 -8
- package/src/scripts/ai_council/consensus_round.ts +226 -0
- package/src/scripts/ai_council/cross_exam.ts +128 -0
- package/src/scripts/ai_council/disagreement_signal.ts +338 -0
- package/src/scripts/ai_council/explain_route.ts +157 -0
- package/src/scripts/ai_council/information_gain.ts +293 -0
- package/src/scripts/ai_council/inline_findings.ts +340 -0
- package/src/scripts/ai_council/judge_position_bias.ts +197 -0
- package/src/scripts/ai_council/leakage_corpus.ts +385 -0
- package/src/scripts/ai_council/leakage_patterns.ts +453 -0
- package/src/scripts/ai_council/minority_retention.ts +171 -0
- package/src/scripts/ai_council/orchestrator.ts +16 -203
- package/src/scripts/ai_council/orchestrator_results.ts +23 -3
- package/src/scripts/ai_council/pricing.ts +106 -0
- package/src/scripts/ai_council/prompts.ts +74 -7
- package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
- package/src/scripts/ai_council/py_format.ts +14 -3
- package/src/scripts/ai_council/recouncil_guard.ts +293 -0
- package/src/scripts/ai_council/recouncil_savings.ts +299 -0
- package/src/scripts/ai_council/replay_route.ts +223 -0
- package/src/scripts/ai_council/response_record.ts +50 -0
- package/src/scripts/ai_council/reviewer_assignment.ts +279 -0
- package/src/scripts/ai_council/routing_training_row.ts +197 -0
- package/src/scripts/ai_council/synthesis_strategy.ts +159 -0
- package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
- package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
- package/src/scripts/asset_delivery_ledger.ts +157 -0
- package/src/scripts/attest_artifact.ts +193 -0
- package/src/scripts/audit_auto_rules.ts +2 -1
- package/src/scripts/audit_command_surface.ts +1 -1
- package/src/scripts/audit_mcp_tools.ts +2 -2
- package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
- package/src/scripts/audit_user_type_axis.ts +2 -1
- package/src/scripts/bench_ab_clone.ts +215 -10
- package/src/scripts/bench_ab_integrity.ts +119 -5
- package/src/scripts/bench_ab_v2_stats.ts +40 -213
- package/src/scripts/build_archive_index.ts +1 -1
- package/src/scripts/build_linear_digest.ts +1 -1
- package/src/scripts/build_proof.ts +11 -4
- package/src/scripts/build_rule_trigger_matrix.ts +1 -1
- package/src/scripts/build_source_digests.ts +157 -0
- package/src/scripts/cache_realization_report.ts +103 -0
- package/src/scripts/check_adr_frontmatter.ts +131 -10
- package/src/scripts/check_benchmark_report_fields.ts +207 -0
- package/src/scripts/check_beta_review_markers.ts +235 -6
- package/src/scripts/check_bundle_path_leakage.ts +34 -1
- package/src/scripts/check_claims.ts +576 -6
- package/src/scripts/check_composite_arming.ts +35 -0
- package/src/scripts/check_concern_admissions.ts +365 -0
- package/src/scripts/check_enforcement_coverage.ts +28 -0
- package/src/scripts/check_estate_count.ts +347 -25
- package/src/scripts/check_gate_reachability.ts +383 -0
- package/src/scripts/check_host_loadability.ts +104 -0
- package/src/scripts/check_loss_class_declared.ts +308 -0
- package/src/scripts/check_md_language.ts +15 -98
- package/src/scripts/check_memory_proposal.ts +18 -11
- package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
- package/src/scripts/check_no_external_sources.ts +281 -6
- package/src/scripts/check_pack_conformance_fixture.ts +11 -1
- package/src/scripts/check_pack_size.ts +59 -2
- package/src/scripts/check_preamble_payload_budget.ts +114 -3
- package/src/scripts/check_prefix_stable_mutation.ts +372 -0
- package/src/scripts/check_publish_surface.ts +10 -1
- package/src/scripts/check_references.ts +24 -1
- package/src/scripts/check_release_highlights.ts +96 -13
- package/src/scripts/check_roadmap_trackable.ts +17 -2
- package/src/scripts/check_rule_evidence_declaration.ts +316 -0
- package/src/scripts/check_rule_projection_integrity.ts +14 -4
- package/src/scripts/check_score_contract.ts +26 -3
- package/src/scripts/check_static_parity.ts +285 -0
- package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
- package/src/scripts/check_suppression_hygiene.ts +15 -0
- package/src/scripts/ci_settle.ts +39 -2
- package/src/scripts/code_graph/build.ts +60 -3
- package/src/scripts/code_graph/extract.ts +44 -0
- package/src/scripts/code_graph/types.ts +24 -0
- package/src/scripts/collector_daemon.ts +714 -0
- package/src/scripts/config_cost_report.ts +302 -0
- package/src/scripts/consumer_matrix.ts +74 -1
- package/src/scripts/corpus_manifest.ts +235 -0
- package/src/scripts/cost/budget.mjs +10 -3
- package/src/scripts/cost/track.mjs +10 -3
- package/src/scripts/council_cli.ts +37 -54
- package/src/scripts/dispatch_r2_reviewer.ts +46 -5
- package/src/scripts/evolution_lab.ts +1153 -0
- package/src/scripts/external_sources_denylist.json +5 -18
- package/src/scripts/extract_audit_patterns.ts +21 -0
- package/src/scripts/fold_intake.ts +12 -1
- package/src/scripts/gen_discovery_baseline.ts +1 -1
- package/src/scripts/generate_capabilities_index.ts +12 -5
- package/src/scripts/generate_capability_matrix.ts +3 -3
- package/src/scripts/generate_command_flows.ts +2 -2
- package/src/scripts/generate_cookbook.ts +2 -2
- package/src/scripts/generate_index.ts +8 -1
- package/src/scripts/generate_knowledge_index.ts +2 -1
- package/src/scripts/generate_ownership_matrix.ts +2 -1
- package/src/scripts/generate_pack_manifests.ts +10 -2
- package/src/scripts/generate_role_experiences_catalog.ts +2 -2
- package/src/scripts/generate_settings_reference.ts +1 -1
- package/src/scripts/git_authorization_hook.ts +22 -1
- package/src/scripts/grade_target_readiness.ts +48 -5
- package/src/scripts/hook_effect_doctor.ts +261 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +125 -16
- package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
- package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
- package/src/scripts/hooks/comment_discipline_hook.ts +146 -0
- package/src/scripts/hooks/concern_registry.ts +6 -0
- package/src/scripts/hooks/dispatch_hook.ts +32 -0
- package/src/scripts/hooks/journal_record_hook.ts +345 -0
- package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
- package/src/scripts/hooks/run_continuation_hook.ts +44 -9
- package/src/scripts/hooks/shims/install.sh +61 -0
- package/src/scripts/hooks/shims/php +101 -0
- package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
- package/src/scripts/hooks/turn_end_gate_hook.ts +9 -1
- package/src/scripts/hot_context_hook.ts +16 -0
- package/src/scripts/install-hooks.sh +20 -5
- package/src/scripts/install.ts +17 -35
- package/src/scripts/inventory_frontmatter.ts +2 -1
- package/src/scripts/language_mirror_hook.ts +14 -2
- package/src/scripts/lint_adr_sweep_routing.ts +12 -0
- package/src/scripts/lint_canonical_terms.ts +604 -0
- package/src/scripts/lint_carrier_integrity.ts +820 -0
- package/src/scripts/lint_code_comments.ts +643 -0
- package/src/scripts/lint_composition_review.ts +619 -0
- package/src/scripts/lint_consolidation_lineage.ts +666 -0
- package/src/scripts/lint_eval_specs.ts +593 -0
- package/src/scripts/lint_hook_manifest.ts +19 -0
- package/src/scripts/lint_host_portability.ts +373 -0
- package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
- package/src/scripts/lint_memory_twin_parity.ts +335 -0
- package/src/scripts/lint_metric_consumers.ts +355 -0
- package/src/scripts/lint_plan_risk_register.ts +39 -19
- package/src/scripts/lint_promotion_paths.ts +779 -0
- package/src/scripts/lint_skill_descriptions.ts +18 -1
- package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
- package/src/scripts/lint_skill_link_reach.ts +252 -0
- package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
- package/src/scripts/lint_ticket_buildable.ts +17 -1
- package/src/scripts/llm_propose.ts +256 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
- package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
- package/src/scripts/measure_delivery_sets.ts +361 -0
- package/src/scripts/measure_docs_dead_links.ts +348 -0
- package/src/scripts/measure_host_capture.ts +461 -0
- package/src/scripts/measure_routing_signal.ts +307 -0
- package/src/scripts/migration_status.ts +3 -3
- package/src/scripts/model_rule_injection.ts +76 -0
- package/src/scripts/orchestration_record.ts +14 -0
- package/src/scripts/preamble_byte_census.ts +139 -10
- package/src/scripts/prepack-check.mjs +4 -1
- package/src/scripts/probe_council_retention.ts +495 -0
- package/src/scripts/probe_turnaround.ts +384 -0
- package/src/scripts/probe_unblocked_ask.ts +279 -0
- package/src/scripts/release.ts +21 -37
- package/src/scripts/release_drill.ts +143 -0
- package/src/scripts/release_env.ts +35 -0
- package/src/scripts/release_publication.ts +84 -0
- package/src/scripts/render_benchmark_md.ts +1 -1
- package/src/scripts/rule_activation_census.ts +70 -9
- package/src/scripts/rule_backlinks.ts +1 -1
- package/src/scripts/run_lifecycle_suite.ts +208 -0
- package/src/scripts/run_skill_evals.ts +40 -0
- package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
- package/src/scripts/schemas/drafting-channels.schema.json +43 -0
- package/src/scripts/schemas/evals.schema.json +24 -1
- package/src/scripts/schemas/rule.schema.json +52 -1
- package/src/scripts/schemas/skill.schema.json +17 -2
- package/src/scripts/skill_overlap.ts +7 -1
- package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
- package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
- package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
- package/src/scripts/skill_usage_report.ts +2 -1
- package/src/scripts/stubs_due.ts +211 -0
- package/src/scripts/sweep_source_surfaces.ts +678 -0
- package/src/scripts/sync_pr_branch.ts +3 -3
- package/src/scripts/trigger_eval_grandfather.json +202 -222
- package/src/scripts/utilization_report.ts +22 -2
- package/src/server/schemas/settings.ts +5 -0
- package/src/templates/marketing-copy.yml +1 -1
- package/dist/ui/assets/index-Cxgy63kz.js +0 -26
|
@@ -36,7 +36,8 @@ Use this skill when the user asks to create a database migration, add a column,
|
|
|
36
36
|
- Use `decimal` for money — never `float`.
|
|
37
37
|
- Add indexes for columns used in WHERE clauses and JOINs.
|
|
38
38
|
- Match existing column naming patterns in the same table or domain.
|
|
39
|
-
-
|
|
39
|
+
- Declare recovery: a reversible `down()`, or a roll-forward plan in the file
|
|
40
|
+
(see § The recovery contract below). Silence is the violation.
|
|
40
41
|
|
|
41
42
|
## Laravel projects
|
|
42
43
|
|
|
@@ -73,7 +74,10 @@ return new class extends Migration {
|
|
|
73
74
|
$table->foreign('customer_id')
|
|
74
75
|
->references('id')
|
|
75
76
|
->on('customers')
|
|
76
|
-
|
|
77
|
+
// Choose the referential action; never inherit it from a
|
|
78
|
+
// template. See "Referential action is a decision" below.
|
|
79
|
+
->onDelete('cascade'); // cascade: rows here are expendable
|
|
80
|
+
// WITHOUT their customer
|
|
77
81
|
|
|
78
82
|
$table->index('is_active');
|
|
79
83
|
});
|
|
@@ -143,6 +147,54 @@ php artisan migrate --env=testing # testing
|
|
|
143
147
|
1. Migration file with up() and down() methods
|
|
144
148
|
2. Model updates if columns or relationships changed
|
|
145
149
|
|
|
150
|
+
### The recovery contract — one obligation, two branches
|
|
151
|
+
|
|
152
|
+
Every migration declares **one** of these, and silence is the violation:
|
|
153
|
+
|
|
154
|
+
1. a `down()` that restores the prior state; **or**
|
|
155
|
+
2. a **roll-forward recovery plan, written in the migration file itself**, for
|
|
156
|
+
the cases where restoration is genuinely impossible — a completed
|
|
157
|
+
destructive backfill, a dropped column whose data is gone.
|
|
158
|
+
|
|
159
|
+
The second branch is not a lighter obligation. A migration taking it records, in
|
|
160
|
+
its own file comments, all three of:
|
|
161
|
+
|
|
162
|
+
1. **why restoration is impossible**, with the evidence — the data was checked
|
|
163
|
+
and is unrecoverable, not assumed to be;
|
|
164
|
+
2. **the ordered recovery procedure** — the steps, the inputs each needs, and
|
|
165
|
+
the criteria that say recovery succeeded;
|
|
166
|
+
3. **the responsible recovery owner**.
|
|
167
|
+
|
|
168
|
+
Vague intent or missing detail is the violation. The plan lives in the migration
|
|
169
|
+
file and lands in the same diff, because a plan documented "later" somewhere else
|
|
170
|
+
is a plan nobody can review at the moment it matters.
|
|
171
|
+
|
|
172
|
+
## Referential action is a decision
|
|
173
|
+
|
|
174
|
+
The template above labels its `onDelete('cascade')` as **one branch**, not a
|
|
175
|
+
default. Copying it unchanged is how a delete of one customer silently removes
|
|
176
|
+
records that had independent value.
|
|
177
|
+
|
|
178
|
+
| The child row, without its parent, is | Action | What happens |
|
|
179
|
+
|---|---|---|
|
|
180
|
+
| **expendable** — it only means something as part of the parent | `cascade` | deleted with the parent |
|
|
181
|
+
| **self-valued** — it is a record in its own right (an invoice, an audit row, a payment) | `restrict` (or `no action`) | the parent delete FAILS until the child is dealt with |
|
|
182
|
+
| **survivable** — it outlives the parent with the link removed | `set null` | the column is nulled; requires a nullable column |
|
|
183
|
+
|
|
184
|
+
Two consequences worth stating because they are the ones missed:
|
|
185
|
+
|
|
186
|
+
- `restrict` is the safe default for anything a finance, audit, or legal reader
|
|
187
|
+
would expect to still exist. A failed delete is a conversation; a cascaded
|
|
188
|
+
delete is a recovery.
|
|
189
|
+
- `set null` needs the foreign-key column to be nullable, and it needs the
|
|
190
|
+
application to handle the orphan state. Choosing it without both is choosing a
|
|
191
|
+
constraint error later.
|
|
192
|
+
|
|
193
|
+
Soft deletes do **not** interact with this: `onDelete` fires on a real `DELETE`,
|
|
194
|
+
so a soft-deleting parent never triggers it. If the model soft-deletes, the
|
|
195
|
+
referential action describes what happens on a force-delete or a purge, and that
|
|
196
|
+
is the case to decide against.
|
|
197
|
+
|
|
146
198
|
## Gotcha
|
|
147
199
|
|
|
148
200
|
- Always check if the table/column already exists before creating the migration — the model doesn't always check.
|
|
@@ -155,7 +207,9 @@ php artisan migrate --env=testing # testing
|
|
|
155
207
|
- Do NOT create migrations without specifying the correct connection when multiple databases exist.
|
|
156
208
|
- Do NOT create tables without checking the project's naming conventions (prefixes, casing).
|
|
157
209
|
- Do NOT use raw SQL in migrations when Schema builder works.
|
|
158
|
-
- Do NOT
|
|
210
|
+
- Do NOT leave recovery undeclared — ship a `down()` that restores the prior
|
|
211
|
+
state, or the three-part roll-forward plan in the migration file. Neither is
|
|
212
|
+
optional; choosing between them is.
|
|
159
213
|
- Do NOT use `float` for money — use `decimal`.
|
|
160
214
|
- Do NOT forget indexes on foreign keys and frequently filtered columns.
|
|
161
215
|
|
|
@@ -57,6 +57,24 @@ In precedence order, and report which one answered:
|
|
|
57
57
|
Globs are globs: `packages/*` means every direct child carrying a manifest, not
|
|
58
58
|
every directory.
|
|
59
59
|
|
|
60
|
+
### 2b. Catalogs — the version is declared once, not per member
|
|
61
|
+
|
|
62
|
+
When the workspace defines a **catalog**, a member's `catalog:` range is a
|
|
63
|
+
REFERENCE, not a declaration. Report the catalog as the version's home:
|
|
64
|
+
|
|
65
|
+
- A member range starting `catalog:` (bare, or `catalog:<name>`) resolves
|
|
66
|
+
against the workspace catalog definition. It does not resolve outside the
|
|
67
|
+
workspace at all — treat it exactly as `workspace:` for publishability.
|
|
68
|
+
- **An upgrade edits the catalog, not the member.** Editing a member that reads
|
|
69
|
+
`catalog:` is either a no-op or a silent divergence from the catalog, and the
|
|
70
|
+
catalog exists precisely so the version has one home.
|
|
71
|
+
- **A member carrying a version LITERAL for a dependency the catalog also
|
|
72
|
+
declares is reported, not gated** — see § Do NOT. Name the member, the
|
|
73
|
+
dependency, the literal range, the catalog name and the catalog range. Where
|
|
74
|
+
several catalogs declare the same dependency, list every candidate rather than
|
|
75
|
+
inventing an applicable one; nothing in the workspace definition says which
|
|
76
|
+
the literal intended to follow.
|
|
77
|
+
|
|
60
78
|
### 3. Task runner — ask the runner, do not read its config
|
|
61
79
|
|
|
62
80
|
When a runner is present, its own listing is the source of truth, because a
|
|
@@ -133,6 +151,14 @@ When the runner was absent, the last line reads
|
|
|
133
151
|
|
|
134
152
|
## Do NOT
|
|
135
153
|
|
|
154
|
+
- **Do NOT gate on a member version literal.** Whether a catalog repository
|
|
155
|
+
permits selective literals is that repository's convention, not this suite's
|
|
156
|
+
to impose. Report it as a structural observation — *"member literal overlaps
|
|
157
|
+
catalog entry"*, never *"invalid"* — and let the reader decide. An exact
|
|
158
|
+
mismatch between the literal and the catalog range is reported at higher
|
|
159
|
+
severity, and still does not gate.
|
|
160
|
+
|
|
161
|
+
|
|
136
162
|
- Read `project.json` by hand to enumerate Nx projects — `nx show projects` is
|
|
137
163
|
the source of truth and includes inferred targets.
|
|
138
164
|
- Install `turbo` or `nx` to answer a question. They are the consumer's
|
|
@@ -112,6 +112,33 @@ The derivation therefore unwraps a thin wrapper and records what it points at, a
|
|
|
112
112
|
confirm, and the file says which id failed. Downgrading is the honest outcome; writing
|
|
113
113
|
the stronger claim and hoping is the failure this skill exists to prevent.
|
|
114
114
|
|
|
115
|
+
## A confirmed canonical answer is a playbook — including the awkward one
|
|
116
|
+
|
|
117
|
+
A repository's answer to *"where does new code of this kind go"* is a playbook
|
|
118
|
+
once it has been **confirmed**, graded like any other: `configured` when every
|
|
119
|
+
cited id resolved, `observed` when one did not.
|
|
120
|
+
|
|
121
|
+
**The awkward case is the one worth writing down.** A public surface version and
|
|
122
|
+
an **implementation generation** are independent axes — a `v1` controller can
|
|
123
|
+
carry the current internal architecture while a `v2` one is half-migrated and
|
|
124
|
+
abandoned. So the canonical answer for a scope is frequently *"the
|
|
125
|
+
older-looking lane"*, and that is exactly the answer nobody records because it
|
|
126
|
+
reads as a mistake. **ADR-248** holds the evidence order that produces it: a live
|
|
127
|
+
decision record, then an executable architecture test, then a shared abstraction
|
|
128
|
+
in maintained code, then current tests and contracts, then several recent
|
|
129
|
+
analogous implementations, then migration docs, then git history, and **names and
|
|
130
|
+
paths last**.
|
|
131
|
+
|
|
132
|
+
Two bounds, both deliberate:
|
|
133
|
+
|
|
134
|
+
- **Per scope, never per artifact type.** A repository may legitimately have two
|
|
135
|
+
right answers in two modules. There is no single global exemplar, and a
|
|
136
|
+
playbook claiming one is over-reaching its own `scope`.
|
|
137
|
+
- **No second contract.** This is the ADR-244 playbook class unchanged — not a
|
|
138
|
+
conventions map, not a canonicality registry. A confirmed answer is a
|
|
139
|
+
playbook; an unconfirmed one is a hypothesis and belongs in the analysis that
|
|
140
|
+
produced it.
|
|
141
|
+
|
|
115
142
|
## Output format
|
|
116
143
|
|
|
117
144
|
1. One playbook per file in the playbook home, frontmatter first: `task`, `scope`, `grade`,
|
|
@@ -156,7 +183,7 @@ The derivation therefore unwraps a thin wrapper and records what it points at, a
|
|
|
156
183
|
|
|
157
184
|
## See also
|
|
158
185
|
|
|
159
|
-
- [ADR-244](../../../docs/decisions/ADR-244-playbook-is-a-sixth-context-type.md) — the
|
|
186
|
+
- [ADR-244](../../../docs/decisions/ADR-244-playbook-is-a-sixth-context-type.md) — the artifact class, its grades, its home, and the two deferred kinds.
|
|
160
187
|
- [`standards-from-config`](../standards-from-config/SKILL.md) — the Class-A rule this applies to procedure rather than to style.
|
|
161
188
|
- [`context-document`](../context-document/SKILL.md) — the contexts machinery a playbook reuses as its sixth type.
|
|
162
189
|
- [`command-writing`](../command-writing/SKILL.md) — the numbered-step shape the body follows.
|
|
@@ -258,7 +258,7 @@ rubric:
|
|
|
258
258
|
```
|
|
259
259
|
|
|
260
260
|
`contains` / `file_exists` grade deterministically. `rubric` items grade
|
|
261
|
-
via a fresh
|
|
261
|
+
via a fresh subagent reading the output against the criterion — keep
|
|
262
262
|
each criterion to one falsifiable sentence.
|
|
263
263
|
|
|
264
264
|
**Loop** (orchestrated by `scripts/run_skill_evals.ts`):
|
|
@@ -266,14 +266,14 @@ each criterion to one falsifiable sentence.
|
|
|
266
266
|
1. **Scaffold** — `./scripts-run src/scripts/run_skill_evals scaffold {skill}`
|
|
267
267
|
creates `runs/{timestamp}-{baseline,with-skill}/` and seeds each
|
|
268
268
|
scenario's `meta.json`.
|
|
269
|
-
2. **Baseline run** — spawn one
|
|
269
|
+
2. **Baseline run** — spawn one subagent per scenario **without** the
|
|
270
270
|
skill loaded. Capture stdout + any artifacts into
|
|
271
271
|
`runs/{timestamp}-baseline/{scenario-id}/`.
|
|
272
|
-
3. **With-skill run** — same scenarios, same
|
|
272
|
+
3. **With-skill run** — same scenarios, same subagent harness, **with**
|
|
273
273
|
the skill loaded. Capture into `runs/{timestamp}-with-skill/{scenario-id}/`.
|
|
274
274
|
4. **Grade** — for each scenario, write a `grade.json` file with
|
|
275
275
|
per-assertion pass/fail. Deterministic assertions auto-grade;
|
|
276
|
-
rubric assertions need a grader
|
|
276
|
+
rubric assertions need a grader subagent.
|
|
277
277
|
5. **Aggregate** — `./scripts-run src/scripts/run_skill_evals aggregate {skill}
|
|
278
278
|
--run {timestamp}` produces `runs/{timestamp}-benchmark.json` with
|
|
279
279
|
pass-rate, timing, token deltas baseline-vs-with-skill.
|
|
@@ -281,7 +281,7 @@ each criterion to one falsifiable sentence.
|
|
|
281
281
|
--run {timestamp}` prints the diff. Iterate on the skill body
|
|
282
282
|
until `with-skill` outperforms `baseline` on every scenario.
|
|
283
283
|
|
|
284
|
-
The script ships with
|
|
284
|
+
The script ships with subagent spawning **stubbed** — the orchestration
|
|
285
285
|
layer is per-environment (Claude Code, Augment, council). Implement
|
|
286
286
|
the spawn function once for your environment, the rest of the loop
|
|
287
287
|
(aggregate / report / scaffold) works out of the box.
|
|
@@ -30,7 +30,7 @@ Do NOT use when:
|
|
|
30
30
|
|
|
31
31
|
1. **Inspect call site & choose approach** — identify every dynamic value flowing into the query, then pick: query builder when possible. Raw SQL only when query builder can't express the query.
|
|
32
32
|
2. **Parameterize** — Every variable must use `?` binding or named `:param`. Never interpolate PHP variables into SQL strings.
|
|
33
|
-
3. **
|
|
33
|
+
3. **Read the engine, then choose the syntax** — check, in order: the project's DB config (`config/database.php` default connection, `DB_CONNECTION`), a `docker-compose.yml` service image, a migration using engine-specific syntax. MySQL and MariaDB share the query-syntax world this skill writes in; PostgreSQL and MSSQL do not. **If none of those declare an engine, say so and ask — do not assume one.** A query written for the wrong engine passes review and fails in production.
|
|
34
34
|
4. **Verify** — Run EXPLAIN on complex queries. Check that no PHP interpolation (`"$var"`, `'{$var}'`) appears in SQL.
|
|
35
35
|
|
|
36
36
|
```
|
|
@@ -66,6 +66,12 @@ DB::select("SELECT * FROM users WHERE email = '{$email}'");
|
|
|
66
66
|
|
|
67
67
|
## Gotcha
|
|
68
68
|
|
|
69
|
+
**MySQL and MariaDB share a query-syntax world. They never share a migration
|
|
70
|
+
one.** Same principle as `database`: one engine for writing a `SELECT`, two for
|
|
71
|
+
online-DDL semantics, lock behavior under `ALTER`, feature availability and
|
|
72
|
+
`EXPLAIN` output. Never carry a claim from the second group across the two
|
|
73
|
+
without naming the engine and version it was measured on.
|
|
74
|
+
|
|
69
75
|
- MariaDB and MySQL have subtle syntax differences.
|
|
70
76
|
- The model writes `$variable` in SQL strings instead of `?` placeholders.
|
|
71
77
|
- `GROUP BY` with `ONLY_FULL_GROUP_BY` requires all non-aggregated columns.
|
|
@@ -50,20 +50,43 @@ found", do not fabricate one).
|
|
|
50
50
|
- Python: `pyproject.toml` / `ruff.toml` (`[tool.ruff]`, `[tool.black]`),
|
|
51
51
|
`setup.cfg`.
|
|
52
52
|
- Ruby: `.rubocop.yml`. Go: `gofmt`/`golangci.yml`.
|
|
53
|
-
2. **
|
|
53
|
+
2. **Follow the chain before you digest, and pick the config NEAREST the edit.**
|
|
54
|
+
Read literally — one file, one parse — this procedure returns a null on a
|
|
55
|
+
repository whose root config is a single `extends`. A fourteen-line linter
|
|
56
|
+
config whose only load-bearing line points into a package in the same
|
|
57
|
+
workspace is not a project without standards; it is a project whose standards
|
|
58
|
+
are one hop away, and "no enforced standard found" there is a false negative
|
|
59
|
+
that reads exactly like a true one. `extends` is specified in TypeScript,
|
|
60
|
+
ESLint, Biome and Stylelint; `includes` plays the same role in PHPStan and
|
|
61
|
+
Rector; `workspace:` is documented in npm, yarn, pnpm and bun.
|
|
62
|
+
- **Precedence is nearest-first, and it is not a preference.** The config in
|
|
63
|
+
the edited path's own directory governs, then its parent, up to the
|
|
64
|
+
repository root. A per-package `tsconfig.json`, `.eslintrc`, `.env` or
|
|
65
|
+
deployment manifest is the one that package's build reads; a root file it
|
|
66
|
+
does not extend has no effect on it. Reading the root config for an edit
|
|
67
|
+
inside a package that carries its own is a **wrong** answer, not a coarse
|
|
68
|
+
one. Report the outranked root candidate too, so the precedence is visible.
|
|
69
|
+
- **An unresolvable hop is a named gap with a PARTIAL digest, never an
|
|
70
|
+
absence.** Say which hop failed and why. A partial digest naming its gap is
|
|
71
|
+
usable; a null that reads as "no standards" is a lie.
|
|
72
|
+
- **A hop that leaves the repository is labelled `external` and excluded from
|
|
73
|
+
the digest.** Presenting a third-party preset as the project's own standard
|
|
74
|
+
is worse than reporting nothing — the reader cannot tell which rules the
|
|
75
|
+
project chose. Report it with its path; do not merge it.
|
|
76
|
+
3. **Derive as pointer + digest, never a flattened claim.** Each standard is one
|
|
54
77
|
line: the **value**, the **config file it came from**, and the **scope** it
|
|
55
78
|
applies to. Write `ruff.toml → line-length = 88 (scope: src/**/*.py)`, NOT
|
|
56
79
|
"the project uses line length 88". The pointer makes the claim re-checkable
|
|
57
80
|
and the next agent can open the config to confirm.
|
|
58
|
-
|
|
81
|
+
4. **Preserve scope; surface conflicts, never flatten them.** If two configs (or
|
|
59
82
|
an inline / per-directory override) give two values, emit **two pointers with
|
|
60
83
|
two values + their scopes** — never one ambiguous merged claim. A visible
|
|
61
84
|
conflict is correct; a hidden flattened guess is the failure mode.
|
|
62
|
-
|
|
85
|
+
5. **Stamp staleness.** Record each source's `config_mtime` (or content hash).
|
|
63
86
|
The digest is stale when the config file's mtime/hash changes → re-derive. No
|
|
64
87
|
human gate is needed (Class A is deterministic) — the digest is **regenerated
|
|
65
88
|
from the config, never hand-edited**.
|
|
66
|
-
|
|
89
|
+
6. **Persist** as a Class-A context card under `agents/settings/contexts/` (see
|
|
67
90
|
Output format). Class A is high-trust *because* config-derived — it is read
|
|
68
91
|
for heuristics only and never bypasses a fresh structural read (the v1↔v2
|
|
69
92
|
isolation contract in `evidence-discipline`).
|
|
@@ -51,18 +51,25 @@ PIN IT, LOCK IT, CVE-SCAN IT. NEVER PIPE A REMOTE SCRIPT STRAIGHT TO A SHELL.
|
|
|
51
51
|
```
|
|
52
52
|
Non-existent, brand-new (published days ago), or near-zero-download → **stop**, treat as hallucination/slopsquat.
|
|
53
53
|
2. **Typo-adjacency** — is the name within 1–2 chars of a far-more-popular package (`python-dateutil` vs `dateutil`, `lodahs` vs `lodash`)? If so, you probably want the popular one — confirm before installing.
|
|
54
|
-
3. **Version
|
|
54
|
+
3. **Version source — look it up BEFORE you write a version, and report which outcome you got.** This is a precondition of step 4, not a note on it. Two outcomes, with opposite handling, and only the first is forbidden:
|
|
55
|
+
- **Invention** — writing a version string that **no source in the repository produced**. Always forbidden. A version that appeared from nowhere is unverifiable by anyone downstream, including you an hour later.
|
|
56
|
+
- **Lookup failure** — having searched the **declared version sources** and found none. Those sources are per ecosystem: a catalogue or a `workspace:` protocol entry, an existing manifest in the tree (`package.json`, `composer.json`, `pyproject.toml`, `go.mod`, `Cargo.toml`), and the lockfile. This is **not** a violation. Resolving it from the registry or from the user is the correct move; report it as *unresolved-then-resolved* with the source named.
|
|
57
|
+
|
|
58
|
+
**Silence is the failure, never the fallback.** Producing a version with no source and no report is the thing the rule forbids; reporting an unresolved lookup is the thing it asks for.
|
|
59
|
+
|
|
60
|
+
A manifest that already expresses a version through a protocol — `workspace:*`, a catalogue reference — is **left as it is**. Rewriting it to a literal discards the mechanism the repository chose and pins a value the workspace was resolving for you. `workspace:` is documented in npm, yarn, pnpm and bun; catalogued versions are a documented feature of pnpm and bun.
|
|
61
|
+
4. **Version safety** — the model's version pin may predate a CVE fix (training-cutoff reintroduction). Take the current patched release, then scan:
|
|
55
62
|
```bash
|
|
56
63
|
npm audit # block on high/critical
|
|
57
64
|
pip-audit
|
|
58
65
|
osv-scanner -r .
|
|
59
66
|
```
|
|
60
|
-
|
|
67
|
+
5. **Pin + lock** — install exact + commit the lockfile; reject floating ranges (`^`, `latest`, no lockfile) on production deps.
|
|
61
68
|
```bash
|
|
62
69
|
npm install --save-exact <pkg> && git add package-lock.json
|
|
63
70
|
```
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
6. **License** — confirm the license is compatible with the project's declared license before it lands.
|
|
72
|
+
7. **No pipe-to-shell** — never `curl … | bash` an install; download → inspect → execute over pinned HTTPS, or surface it to the user for confirmation.
|
|
66
73
|
|
|
67
74
|
## MCP-server intake — the dependency gate plus two extra checks
|
|
68
75
|
|
|
@@ -180,3 +180,38 @@ Then add these **Symfony-specific** checks:
|
|
|
180
180
|
- Messenger `failure_transport` is opt-in; without it, failures vanish.
|
|
181
181
|
- Compiled container changes need `cache:clear` in `prod` before debugging "config not applied".
|
|
182
182
|
- Symfony 7.x removed deprecated APIs — verify `composer.lock` before assuming 6.x patterns work.
|
|
183
|
+
|
|
184
|
+
## When NOT to use — components without the framework
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
A DEPENDENCY PROVES A LIBRARY IS AVAILABLE. ONLY THE ENTRY POINT AND THE
|
|
188
|
+
ROUTER PROVE WHICH APPLICATION SHAPE IS RUNNING.
|
|
189
|
+
`symfony/*` PACKAGES WITH NO SKELETON MARKER IS A THIRD STATE, AND THIS SKILL
|
|
190
|
+
DOES NOT APPLY TO IT.
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Symfony ships its ORM, container, collections and HTTP layer as
|
|
194
|
+
independently installable packages, usable with no framework present — a
|
|
195
|
+
published distribution model, not one consumer's arrangement. An application
|
|
196
|
+
built that way has a **custom entry point and a custom router**. Routing it here
|
|
197
|
+
offers a CLI that does not exist, a request-validation primitive that is not
|
|
198
|
+
wired, and a routes file that was never there: every suggestion confidently
|
|
199
|
+
wrong, and the reason visible only from the entry point.
|
|
200
|
+
|
|
201
|
+
**The probe set, and its cost.** A fixed set of filesystem existence checks plus
|
|
202
|
+
one manifest read — no directory walk, no content scan, and never re-derived per
|
|
203
|
+
session. Any ONE marker present means the framework is real:
|
|
204
|
+
|
|
205
|
+
| Probe | Meaning |
|
|
206
|
+
|---|---|
|
|
207
|
+
| `bin/console` | the console entry point the skeleton writes |
|
|
208
|
+
| `config/bundles.php` | the bundle registry |
|
|
209
|
+
| `config/services.yaml` | the DI service config |
|
|
210
|
+
|
|
211
|
+
`symfony/*` in `composer.json` with **none** of those markers is
|
|
212
|
+
*components-without-the-framework*. Say so and route away from this skill rather
|
|
213
|
+
than answering as though the framework were there.
|
|
214
|
+
|
|
215
|
+
Implemented deterministically in `src/install/detect_php_shape.ts`
|
|
216
|
+
(`detectPhpShape`), whose `PROBE_PATHS` is this table and whose verdict names
|
|
217
|
+
what a wrong route would have offered.
|
|
@@ -37,6 +37,91 @@ FLOOR PER BEHAVIOR: 1 HAPPY + 1 BOUNDARY + 1 ERROR (+1 ABUSE ON SECURITY PATHS).
|
|
|
37
37
|
CAP PER BEHAVIOR: 5–8 CASES — EACH MUST FAIL FOR A DISTINCT REASON.
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
## Does this change owe an executable behavior contract?
|
|
41
|
+
|
|
42
|
+
Cases and contracts are not the same artifact. A **case** is something you assert
|
|
43
|
+
in the project's unit runner. An **executable behavior contract** — a
|
|
44
|
+
specification written in the language of whoever asked for the change, and run
|
|
45
|
+
by a tool that reads it — is a heavier thing, and most changes do not owe one.
|
|
46
|
+
Ask for one everywhere and it degrades into a second, slower unit suite; ask for
|
|
47
|
+
one nowhere and behavior nobody can read stays unstated.
|
|
48
|
+
|
|
49
|
+
### The observable-behavior test
|
|
50
|
+
|
|
51
|
+
> **Does this change alter behavior someone outside the code can observe, and
|
|
52
|
+
> would that person describe it in their own words?**
|
|
53
|
+
|
|
54
|
+
Both halves have to hold: observable behavior with no outside audience is
|
|
55
|
+
still only a case. *Observable* rules out anything a caller cannot see. *In their own
|
|
56
|
+
words* rules out behavior that is real but has no audience outside the codebase —
|
|
57
|
+
if the only person who can state the rule is the person reading the
|
|
58
|
+
implementation, a case in the unit runner states it better and cheaper.
|
|
59
|
+
|
|
60
|
+
**Yes → a contract is owed.** A refund is issued when an order is cancelled
|
|
61
|
+
within 14 days; a member on a lapsed plan is denied the export; a rejected
|
|
62
|
+
upload tells the uploader which rule it broke.
|
|
63
|
+
|
|
64
|
+
**No → cases, not a contract.** At least these:
|
|
65
|
+
|
|
66
|
+
- **A refactor with no behavior change.** Nothing outside the code can observe
|
|
67
|
+
it, by definition. If something can, it was not a refactor.
|
|
68
|
+
- **An internal invariant with no external vocabulary.** Cache key derivation,
|
|
69
|
+
retry backoff, connection-pool sizing, a query plan. Real behavior, no
|
|
70
|
+
audience — the failure is stated as a case, not as a sentence somebody outside
|
|
71
|
+
the code would say.
|
|
72
|
+
- **A pure boundary or error path with no business reading.** Rejecting a
|
|
73
|
+
malformed UTF-8 sequence is a case; *"we do not accept expired coupons"* is a
|
|
74
|
+
contract.
|
|
75
|
+
- **A change whose only observer is another part of this system.** A consumer
|
|
76
|
+
written by the same team is a caller, not an audience. Contract tests between
|
|
77
|
+
services are a different tool and a different question.
|
|
78
|
+
|
|
79
|
+
When the answer is yes, the ordering is unchanged: the contract fails before the
|
|
80
|
+
implementation exists and passes after — see
|
|
81
|
+
[`test-driven-development`](../test-driven-development/SKILL.md). A contract
|
|
82
|
+
first seen green has the same unknown sensitivity as any other test never seen
|
|
83
|
+
red.
|
|
84
|
+
|
|
85
|
+
### The anti-script rule
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
A CONTRACT STEP NAMING A SELECTOR, A TIMEOUT, OR A KEYSTROKE IS A DEFECT
|
|
89
|
+
IN THE CONTRACT — NOT AN IMPLEMENTATION DETAIL THAT HAPPENS TO BE THERE.
|
|
90
|
+
WRITE WHAT IS TRUE, NEVER WHAT IS CLICKED.
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
A contract that scripts the interface is pinned to the interface: it goes red on
|
|
94
|
+
every redesign that changes nothing anyone cares about, and stays green through
|
|
95
|
+
the redesign that breaks the rule. It also stops being readable by the person
|
|
96
|
+
whose words it was supposed to be in — which was the only reason to pay for it.
|
|
97
|
+
|
|
98
|
+
**Wrong** — this is a click script wearing Given-When-Then:
|
|
99
|
+
|
|
100
|
+
```gherkin
|
|
101
|
+
Given I open "/cart?id=42"
|
|
102
|
+
When I click #apply-coupon
|
|
103
|
+
And I type "SUMMER" into input[name=code]
|
|
104
|
+
And I wait 2 seconds
|
|
105
|
+
Then .cart-total should contain "€45.00"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Every line is about the page. Change the button id and it fails; move the
|
|
109
|
+
discount rule and it passes.
|
|
110
|
+
|
|
111
|
+
**Right** — same behavior, stated as the rule it is:
|
|
112
|
+
|
|
113
|
+
```gherkin
|
|
114
|
+
Given a cart of €50
|
|
115
|
+
When the customer applies a valid 10% coupon
|
|
116
|
+
Then the order total is €45
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The rule survives the redesign, and the person who asked for it can read it.
|
|
120
|
+
|
|
121
|
+
**The test for a step:** could it still be true if the product were a CLI, an
|
|
122
|
+
API, and a web page? If not, it belongs in the implementation the contract calls
|
|
123
|
+
into, not in the contract.
|
|
124
|
+
|
|
40
125
|
## Procedure — the five-step funnel
|
|
41
126
|
|
|
42
127
|
### 1. Behavior inventory (30 seconds)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: test-driven-development
|
|
4
|
-
description: "
|
|
4
|
+
description: "Implementing a feature, fixing a bug, refactoring — failing test first, then the code. For a WRONG test, `testing-anti-patterns` wins."
|
|
5
5
|
domain: quality
|
|
6
6
|
workspaces:
|
|
7
7
|
- engineering
|
|
@@ -72,16 +72,28 @@ failed proves nothing about the code under test.
|
|
|
72
72
|
### Iron Law — delete-and-restart over keep-as-reference
|
|
73
73
|
|
|
74
74
|
```
|
|
75
|
-
|
|
75
|
+
UNTESTED CODE THIS TASK JUST WROTE, AND A TEST IS NEEDED — DELETE THE CODE,
|
|
76
76
|
WRITE THE TEST, REIMPLEMENT. NEVER KEEP IT "AS REFERENCE".
|
|
77
|
+
THIS LAW COVERS YOUR OWN UNTESTED OUTPUT. IT IS NOT A LICENCE TO DELETE
|
|
78
|
+
PRE-EXISTING CODE, AND NEVER OVERRIDES A REUSE VERDICT.
|
|
77
79
|
```
|
|
78
80
|
|
|
79
81
|
Reading the existing implementation while writing its test is
|
|
80
|
-
test-after-the-fact with extra steps.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
test-after-the-fact with extra steps. Which code that applies to has three
|
|
83
|
+
answers, and only the first is a deletion:
|
|
84
|
+
|
|
85
|
+
| The code is | Do |
|
|
86
|
+
|---|---|
|
|
87
|
+
| **untested, written by this task** | delete it, write the test, reimplement — the Iron Law above |
|
|
88
|
+
| **pre-existing and tested** | keep it. Its tests are the record of its behaviour; deleting it to re-derive the same thing discards evidence and contradicts the reuse verdict |
|
|
89
|
+
| **pre-existing and untested** | do NOT delete. Write a **characterization test** pinning the behaviour it has today — including the behaviour you think is wrong — then change it under that test |
|
|
90
|
+
|
|
91
|
+
The middle row is the one this law used to get wrong: unqualified, it read as
|
|
92
|
+
a standing instruction to delete tested legacy that a reuse verdict would
|
|
93
|
+
keep. Case detail, the characterization-test procedure, and the 12-row
|
|
94
|
+
anti-rationalization table are in
|
|
95
|
+
[`testing-anti-patterns/process-anti-patterns.md`](../testing-anti-patterns/process-anti-patterns.md),
|
|
96
|
+
which keeps this skill under the 400-line sunset trigger.
|
|
85
97
|
|
|
86
98
|
## Mode contracts — Goal / Activities / Forbidden / Output
|
|
87
99
|
|
|
@@ -91,10 +103,21 @@ checks it from the diff** — an unverifiable prohibition does not ship.
|
|
|
91
103
|
| Mode | Goal | Activities | Forbidden (diff check) | Output contract |
|
|
92
104
|
|---|---|---|---|---|
|
|
93
105
|
| **Design** | One-sentence behavior + enumerated cases | Steps 1–2 | **No production code** (diff touches no `src/**` production path) · no test bodies yet | Case list (happy/boundary/error) |
|
|
94
|
-
| **Test-Red** | A failing test that fails RIGHT | Steps 3–4 | **No production edits** (diff = `tests/**` only) ·
|
|
106
|
+
| **Test-Red** | A failing test that fails RIGHT | Steps 3–4 | **No production edits** (diff = `tests/**` only) · the failure must be **about the behaviour under test**. Valid: a failing **assertion** · a **missing target** — class-not-found, or a compile/type error naming the unimplemented symbol · a **contract failure** (wrong shape, wrong status, unmet interface). Invalid: a broken **fixture** · a **syntax error** in the test · a missing **unrelated dependency** · a **runner or environment** fault | Failing test + its observed failure, named as one of the three valid classes |
|
|
95
107
|
| **Implement** | Minimum code to green | Steps 5–6 | **No test edits** (no `tests/**` paths in Implement-phase diffs — changing the assertion to fit the code is the canonical violation; genuinely-wrong test → STOP and ask, never silently edit) · no scope beyond the one case | Green run output |
|
|
96
108
|
| **Debug** | Fix a defect found later | (re-enter at 3) | **No bugfix before a reproducing regression test exists** (the fix commit contains a `tests/**` addition that fails without the fix) | Regression test + fix, verified red→green |
|
|
97
109
|
|
|
110
|
+
#### What makes a RED valid — relevance, not the line number it fails on
|
|
111
|
+
|
|
112
|
+
The discriminator is **whether the failure is about the behaviour under test**,
|
|
113
|
+
never where in the run it surfaces. A class that does not exist yet can only
|
|
114
|
+
fail at load, so demanding an assertion would force a production stub before
|
|
115
|
+
the first test — the exact thing this skill forbids. The four invalid classes
|
|
116
|
+
are failures of the harness: they would fail identically with the behaviour
|
|
117
|
+
fully implemented, so they measure nothing about it. Unsure → re-read the
|
|
118
|
+
failure output and name which of the seven it is; an unclassified red is not a
|
|
119
|
+
RED.
|
|
120
|
+
|
|
98
121
|
### Mode inference on resume
|
|
99
122
|
|
|
100
123
|
Step 0 of any resume: if `agents/runtime/state/HANDOFF.md` exists, resume
|
|
@@ -107,7 +130,8 @@ assume Design:
|
|
|
107
130
|
| No test for the target behavior | Design |
|
|
108
131
|
| Test exists, currently failing at an assertion | Implement |
|
|
109
132
|
| Test exists + passing, defect reported | Debug |
|
|
110
|
-
| Test failing at
|
|
133
|
+
| Test failing at load because the target does not exist yet | Implement (that is a valid RED) |
|
|
134
|
+
| Test failing on a harness fault — fixture, syntax, unrelated dependency, runner | Test-Red (fix the test, not the code) |
|
|
111
135
|
|
|
112
136
|
At every mode transition, one consent-checkpoint sentence (per
|
|
113
137
|
`ask-when-uncertain` / `autonomous-execution` — no new mechanism): name the
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: testing-anti-patterns
|
|
4
|
-
description: "
|
|
4
|
+
description: "BEFORE writing/changing tests, mocks, or test-only methods on production classes — mocking-the-mock, production pollution, overfit assertions; for order, `test-driven-development` wins."
|
|
5
5
|
domain: quality
|
|
6
6
|
workspaces:
|
|
7
7
|
- engineering
|
|
@@ -17,11 +17,48 @@ is still mocking the mock.
|
|
|
17
17
|
```
|
|
18
18
|
WHEN YOU FIND YOURSELF KEEPING UNTESTED CODE "AS REFERENCE" WHILE WRITING
|
|
19
19
|
A TEST FOR IT — DELETE THE CODE. WRITE THE TEST. THEN REIMPLEMENT.
|
|
20
|
+
THE CODE IN QUESTION IS THE UNTESTED CODE THIS TASK JUST WROTE.
|
|
21
|
+
IT IS NOT PRE-EXISTING CODE, AND THE LAW NEVER OVERRIDES A REUSE VERDICT.
|
|
20
22
|
```
|
|
21
23
|
|
|
22
24
|
The cheap path is one extra round-trip. The expensive path is a test that
|
|
23
25
|
silently encodes the bug it was supposed to catch.
|
|
24
26
|
|
|
27
|
+
### The three cases — only one of them is a deletion
|
|
28
|
+
|
|
29
|
+
Unqualified, this law reads as a standing instruction to delete any untested
|
|
30
|
+
code in reach. That reading is wrong in two of the three cases, and the wrong
|
|
31
|
+
one is expensive: it discards working behavior a reuse verdict would keep.
|
|
32
|
+
|
|
33
|
+
| The code is | Do | Why |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| **untested, written by this task** | delete it, write the test, reimplement | Nothing is lost — you can rewrite what you wrote minutes ago, and the test is then written against the behavior you wanted rather than the code you happened to produce |
|
|
36
|
+
| **pre-existing and tested** | keep it | Its tests ARE the record of its behavior. Deleting it to re-derive the same thing throws away evidence you cannot cheaply rebuild, and directly contradicts a reuse / extend verdict |
|
|
37
|
+
| **pre-existing and untested** | write a characterization test first | Deleting it destroys the only remaining record of what it does. The test comes first, but it pins TODAY's behavior — not the behavior you wish it had |
|
|
38
|
+
|
|
39
|
+
### The characterization-test procedure
|
|
40
|
+
|
|
41
|
+
For the third case, in order:
|
|
42
|
+
|
|
43
|
+
1. **Observe, do not judge.** Run the code on real inputs and record what it
|
|
44
|
+
actually returns — including outputs you believe are wrong. Bug-compatible
|
|
45
|
+
is the point: the test's job is to detect *change*, not to assert *correctness*.
|
|
46
|
+
2. **Pin the observed values.** Assert them exactly. A characterization test
|
|
47
|
+
whose expected value is derived from the same code it tests is a tautology.
|
|
48
|
+
3. **Name it as one.** Prefix or tag the test (`characterizes_…`, a
|
|
49
|
+
`@characterization` marker) so a later reader does not mistake a pinned bug
|
|
50
|
+
for a desired behavior.
|
|
51
|
+
4. **Now change the behavior.** With the pin in place, the intended change is
|
|
52
|
+
an ordinary red-green cycle: the characterization test that must now change
|
|
53
|
+
is the blast radius, made visible.
|
|
54
|
+
5. **Update or delete the pin deliberately.** When the new behavior is
|
|
55
|
+
correct, the pinned assertion is edited *because the behavior changed* —
|
|
56
|
+
stated in the diff, never quietly.
|
|
57
|
+
|
|
58
|
+
**What this is NOT.** Not permission to skip TDD on new behavior — the pin
|
|
59
|
+
covers what exists, the new behavior still starts from a failing test. Not a
|
|
60
|
+
coverage exercise: pin the behavior the change will touch, not the whole file.
|
|
61
|
+
|
|
25
62
|
## 12-row anti-rationalization table
|
|
26
63
|
|
|
27
64
|
The urge to skip TDD is strongest on tasks where TDD matters most. Name
|