@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,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-carry for the archival sweep: a finished roadmap whose only obstacle is
|
|
3
|
+
* bare `[~]` steps hands them to a follow-up roadmap and then archives.
|
|
4
|
+
*
|
|
5
|
+
* WHY. The dashboard renders a roadmap with zero open steps as 100 %, deferred
|
|
6
|
+
* steps included, while the sweep refused every bare `[~]` and waited for a
|
|
7
|
+
* human to write the `carried-to` annotation by hand. Nobody did: measured
|
|
8
|
+
* 2026-10-02, five roadmaps sat at 100 % in the active tree with fourteen
|
|
9
|
+
* unannotated deferrals between them, and `/roadmap:process-full` — which ends
|
|
10
|
+
* non-interactively — had no step that could resolve one. "Finished" and
|
|
11
|
+
* "archived" had silently come apart.
|
|
12
|
+
*
|
|
13
|
+
* The disposition this module executes is the one `roadmap-progress-sync`
|
|
14
|
+
* Iron Law 3 already routes to the council without the owner: carry the item
|
|
15
|
+
* AND its blocker into a named follow-up created in the SAME change. It keeps
|
|
16
|
+
* every criterion alive in the active estate, so it is the preserving branch of
|
|
17
|
+
* the preservation test, never a drop. The owner decided on 2026-10-02 that the
|
|
18
|
+
* sweep performs it automatically instead of waiting for a menu.
|
|
19
|
+
*
|
|
20
|
+
* What the carry does, so the archived parent and the live child agree:
|
|
21
|
+
*
|
|
22
|
+
* - every bare `[~]` block is copied verbatim into the child as an OPEN `[ ]`
|
|
23
|
+
* step — open, not `[~]`, because a child at 100 % on arrival would be
|
|
24
|
+
* carried again by the next sweep, forever;
|
|
25
|
+
* - the parent's step gets `<!-- deferred-resolution: carried-to=<child> -->`,
|
|
26
|
+
* and the child gets `parent_roadmap: <parent>`, which is the pair
|
|
27
|
+
* `deferralProblems` and `lint_deferral_integrity` validate from both ends;
|
|
28
|
+
* - every OPEN blocker a carried step names via `blocked-by: <id>` moves with
|
|
29
|
+
* it: copied verbatim into the child's `## Blockers`, and closed in the
|
|
30
|
+
* parent with a status line naming where it went. The open-blocker count is
|
|
31
|
+
* unchanged, it only changes file.
|
|
32
|
+
*
|
|
33
|
+
* NOT automatic when a moved blocker waits on the OWNER (owner decision
|
|
34
|
+
* 2026-10-02): the sweep then writes nothing and asks — archive with the steps
|
|
35
|
+
* parked in `later/` (`--owner-decision later`), or work them step by step with
|
|
36
|
+
* the first one on screen. The procedure lives in `roadmap-process-loop` § 6a.
|
|
37
|
+
*
|
|
38
|
+
* Refused, so nothing is written, when the parent would still not archive
|
|
39
|
+
* afterwards: an open blocker no carried step names is a decision the parent
|
|
40
|
+
* itself raised, and carrying around it would strand the child with steps that
|
|
41
|
+
* have no reason to exist apart from the parent. A human-written annotation
|
|
42
|
+
* that fails validation is also left alone — fixing someone's wrong carry is
|
|
43
|
+
* not this module's call.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
import * as fs from 'node:fs';
|
|
47
|
+
import * as path from 'node:path';
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* `<!-- deferred-resolution: carried-to=<slug> -->` — the resolved-deferral
|
|
51
|
+
* annotation. `merged-into=<slug>` is the second accepted form.
|
|
52
|
+
*/
|
|
53
|
+
export const DEFERRED_RESOLUTION_RE =
|
|
54
|
+
/<!--\s*deferred-resolution:\s*(carried-to|merged-into)\s*=\s*([A-Za-z0-9._-]+)\s*-->/;
|
|
55
|
+
|
|
56
|
+
/** `- [~] …` — a deferred step, at any indent, with `-` or `*`. */
|
|
57
|
+
export const DEFERRED_STEP_RE = /^[ \t]*[-*][ \t]+\[~\][ \t]*(.*)$/;
|
|
58
|
+
|
|
59
|
+
/** Any other checkbox, or a heading — where a step's block ends. */
|
|
60
|
+
export const BLOCK_END_RE = /^[ \t]*[-*][ \t]+\[[ xX~-]\]|^#{1,6}[ \t]/;
|
|
61
|
+
|
|
62
|
+
const BLOCKED_BY_RE = /blocked-by:\s*([A-Za-z0-9._-]+)/g;
|
|
63
|
+
const BLOCKER_HEAD_RE = /^###[ \t]+blocker:[ \t]*(.+?)[ \t]*$/i;
|
|
64
|
+
const STATUS_LINE_RE = /^([ \t]*-[ \t]+\*\*Status:\*\*[ \t]*)(.*)$/;
|
|
65
|
+
const AC_HEADING_RE = /^##[ \t]+acceptance/i;
|
|
66
|
+
const OWNER_LINE_RE = /^[ \t]*-[ \t]+\*\*Owner:\*\*[ \t]*`?([A-Za-z]+)/;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Blocker owners that are NOT the human owner. Everything else — `maintainer`,
|
|
70
|
+
* `user`, `owner`, and any value this list does not name — is owner-dependent:
|
|
71
|
+
* in doubt it is the owner's decision, so an unrecognised owner fails closed.
|
|
72
|
+
*/
|
|
73
|
+
const AGENT_SIDE_OWNERS: ReadonlySet<string> = new Set(['implementer', 'council', 'agent', 'ai']);
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* What happens to deferrals whose blockers wait on the owner.
|
|
77
|
+
*
|
|
78
|
+
* `ask` (default): nothing is written; the sweep reports the decision instead —
|
|
79
|
+
* archive with the steps parked in `later/`, or work them step by step.
|
|
80
|
+
* `later`: the owner chose to archive; the carry lands in `later/`.
|
|
81
|
+
*/
|
|
82
|
+
export type OwnerDecision = 'ask' | 'later';
|
|
83
|
+
|
|
84
|
+
/** The lightweight cap `lint_roadmap_complexity` enforces, with margin. */
|
|
85
|
+
const LIGHTWEIGHT_LINE_BUDGET = 500;
|
|
86
|
+
|
|
87
|
+
const DISPOSITION_DIRS: readonly string[] = ['', 'later', 'archive', 'skipped'];
|
|
88
|
+
|
|
89
|
+
interface BareStep {
|
|
90
|
+
/** Line index of the `[~]` line in the parent. */
|
|
91
|
+
line: number;
|
|
92
|
+
/** The step line plus its continuation block, dedented to the step. */
|
|
93
|
+
block: string[];
|
|
94
|
+
isAcceptance: boolean;
|
|
95
|
+
blockerIds: string[];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface BlockerSpan {
|
|
99
|
+
id: string;
|
|
100
|
+
start: number;
|
|
101
|
+
end: number;
|
|
102
|
+
open: boolean;
|
|
103
|
+
ownerDependent: boolean;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface CarryPlan {
|
|
107
|
+
destSlug: string;
|
|
108
|
+
destRel: string;
|
|
109
|
+
destText: string;
|
|
110
|
+
sourceText: string;
|
|
111
|
+
carried: number;
|
|
112
|
+
movedBlockers: string[];
|
|
113
|
+
/** Moved blockers only the owner can resolve. Non-empty ⇒ the owner decides. */
|
|
114
|
+
ownerBlockers: string[];
|
|
115
|
+
/** The first carried step, verbatim, for the step-by-step offer. */
|
|
116
|
+
firstStep: string;
|
|
117
|
+
/** True when the carry targets `later/` (owner chose to archive). */
|
|
118
|
+
parked: boolean;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export type CarryOutcome = { plan: CarryPlan } | { refused: string };
|
|
122
|
+
|
|
123
|
+
function _bareSteps(lines: readonly string[]): BareStep[] {
|
|
124
|
+
const out: BareStep[] = [];
|
|
125
|
+
let inAcceptance = false;
|
|
126
|
+
// No fence skipping, on purpose: `parseDeferredItems` does not skip fences
|
|
127
|
+
// either, and a step this module did not see but the sweep's validation does
|
|
128
|
+
// would be written, then refused.
|
|
129
|
+
for (let i = 0; i < lines.length; i++) {
|
|
130
|
+
const line = lines[i] as string;
|
|
131
|
+
if (/^##[ \t]/.test(line)) inAcceptance = AC_HEADING_RE.test(line);
|
|
132
|
+
const m = DEFERRED_STEP_RE.exec(line);
|
|
133
|
+
if (m === null) continue;
|
|
134
|
+
let end = i + 1;
|
|
135
|
+
while (end < lines.length && !BLOCK_END_RE.test(lines[end] as string)) end++;
|
|
136
|
+
const raw = lines.slice(i, end);
|
|
137
|
+
if (DEFERRED_RESOLUTION_RE.test(raw.join('\n'))) continue;
|
|
138
|
+
while (raw.length > 1 && (raw[raw.length - 1] as string).trim() === '') raw.pop();
|
|
139
|
+
const indent = (/^[ \t]*/.exec(line) as RegExpExecArray)[0].length;
|
|
140
|
+
const block = raw.map((l) => (l.slice(0, indent).trim() === '' ? l.slice(indent) : l));
|
|
141
|
+
const ids = new Set<string>();
|
|
142
|
+
for (const b of raw) for (const hit of b.matchAll(BLOCKED_BY_RE)) ids.add(hit[1] as string);
|
|
143
|
+
out.push({ line: i, block, isAcceptance: inAcceptance, blockerIds: [...ids] });
|
|
144
|
+
}
|
|
145
|
+
return out;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function _blockerSpans(lines: readonly string[]): BlockerSpan[] {
|
|
149
|
+
const start = lines.findIndex((l) => /^##[ \t]+Blockers[ \t]*$/i.test(l));
|
|
150
|
+
if (start === -1) return [];
|
|
151
|
+
let sectionEnd = lines.length;
|
|
152
|
+
for (let i = start + 1; i < lines.length; i++) {
|
|
153
|
+
if (/^##[ \t]+\S/.test(lines[i] as string)) {
|
|
154
|
+
sectionEnd = i;
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const spans: BlockerSpan[] = [];
|
|
159
|
+
for (let i = start + 1; i < sectionEnd; i++) {
|
|
160
|
+
const m = BLOCKER_HEAD_RE.exec(lines[i] as string);
|
|
161
|
+
if (m === null) continue;
|
|
162
|
+
let end = i + 1;
|
|
163
|
+
while (end < sectionEnd && !/^###?[ \t]/.test(lines[end] as string)) end++;
|
|
164
|
+
const status = lines
|
|
165
|
+
.slice(i, end)
|
|
166
|
+
.map((l) => STATUS_LINE_RE.exec(l))
|
|
167
|
+
.find((s) => s !== null);
|
|
168
|
+
const value = (status?.[2] ?? 'open').trim().toLowerCase();
|
|
169
|
+
const owner = lines
|
|
170
|
+
.slice(i, end)
|
|
171
|
+
.map((l) => OWNER_LINE_RE.exec(l))
|
|
172
|
+
.find((o) => o !== null);
|
|
173
|
+
spans.push({
|
|
174
|
+
id: (m[1] as string).trim(),
|
|
175
|
+
start: i,
|
|
176
|
+
end,
|
|
177
|
+
open: !/^resolved\b/.test(value),
|
|
178
|
+
ownerDependent: !AGENT_SIDE_OWNERS.has((owner?.[1] ?? '').toLowerCase()),
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return spans;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function _plusDays(date: string, days: number): string {
|
|
185
|
+
const d = new Date(`${date}T00:00:00Z`);
|
|
186
|
+
d.setUTCDate(d.getUTCDate() + days);
|
|
187
|
+
return d.toISOString().slice(0, 10);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** The first `<base>-carried[-N]` slug no roadmap directory already holds. */
|
|
191
|
+
export function nextCarrySlug(root: string, sourceSlug: string): string {
|
|
192
|
+
const base = sourceSlug.replace(/-carried(-\d+)?$/, '');
|
|
193
|
+
for (let n = 1; ; n++) {
|
|
194
|
+
const slug = n === 1 ? `${base}-carried` : `${base}-carried-${n}`;
|
|
195
|
+
const taken = DISPOSITION_DIRS.some((d) =>
|
|
196
|
+
fs.existsSync(path.join(root, 'agents', 'roadmaps', d, `${slug}.md`)),
|
|
197
|
+
);
|
|
198
|
+
if (!taken) return slug;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function _title(sourceText: string, sourceSlug: string): string {
|
|
203
|
+
const h1 = /^#[ \t]+(.+?)[ \t]*$/m.exec(sourceText.replace(/^---\n[\s\S]*?\n---\n/, ''));
|
|
204
|
+
return h1 !== null ? (h1[1] as string) : sourceSlug.replace(/-/g, ' ');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Plan the carry for one roadmap. Pure apart from reading which slugs exist, so
|
|
209
|
+
* the sweep can decide before it writes anything.
|
|
210
|
+
*
|
|
211
|
+
* @param openBlockerIds every OPEN blocker the parent carries, as `collect()`
|
|
212
|
+
* counts them — the source of truth for "would it archive afterwards".
|
|
213
|
+
*/
|
|
214
|
+
export function planCarry(
|
|
215
|
+
root: string,
|
|
216
|
+
rel: string,
|
|
217
|
+
text: string,
|
|
218
|
+
openBlockerIds: readonly string[],
|
|
219
|
+
date: string,
|
|
220
|
+
ownerDecision: OwnerDecision = 'ask',
|
|
221
|
+
): CarryOutcome {
|
|
222
|
+
const sourceSlug = rel.replace(/\.md$/, '');
|
|
223
|
+
const lines = text.split('\n');
|
|
224
|
+
const steps = _bareSteps(lines);
|
|
225
|
+
if (steps.length === 0) return { refused: 'no bare `[~]` step to carry' };
|
|
226
|
+
|
|
227
|
+
const named = new Set(steps.flatMap((s) => s.blockerIds));
|
|
228
|
+
const stranded = openBlockerIds.filter((id) => !named.has(id));
|
|
229
|
+
if (stranded.length > 0) {
|
|
230
|
+
return {
|
|
231
|
+
refused:
|
|
232
|
+
`open blocker(s) no deferred step names (${stranded.join(', ')}) — ` +
|
|
233
|
+
'carrying around them would not let this roadmap archive',
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
const moved = _blockerSpans(lines).filter((b) => b.open && named.has(b.id));
|
|
237
|
+
const ownerBlockers = moved.filter((b) => b.ownerDependent).map((b) => b.id);
|
|
238
|
+
const parked = ownerBlockers.length > 0 && ownerDecision === 'later';
|
|
239
|
+
|
|
240
|
+
const destSlug = nextCarrySlug(root, sourceSlug);
|
|
241
|
+
const annotation = `<!-- deferred-resolution: carried-to=${destSlug} -->`;
|
|
242
|
+
|
|
243
|
+
const out = [...lines];
|
|
244
|
+
for (const b of moved) {
|
|
245
|
+
for (let i = b.start; i < b.end; i++) {
|
|
246
|
+
const s = STATUS_LINE_RE.exec(out[i] as string);
|
|
247
|
+
if (s === null) continue;
|
|
248
|
+
out[i] =
|
|
249
|
+
`${s[1] as string}resolved — carried, still open, to \`${destSlug}\` ` +
|
|
250
|
+
`with the steps it blocks (was: ${(s[2] as string).trim()})`;
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
for (const s of steps) out[s.line] = `${out[s.line] as string} ${annotation}`;
|
|
255
|
+
|
|
256
|
+
const toOpen = (block: readonly string[]): string =>
|
|
257
|
+
block.map((l, i) => (i === 0 ? l.replace(/\[~\]/, '[ ]') : l)).join('\n');
|
|
258
|
+
const phaseSteps = steps.filter((s) => !s.isAcceptance).map((s) => toOpen(s.block));
|
|
259
|
+
const acSteps = steps.filter((s) => s.isAcceptance).map((s) => toOpen(s.block));
|
|
260
|
+
const phaseName = `Deferred steps carried from ${sourceSlug}`;
|
|
261
|
+
const blockerText = moved.map((b) => lines.slice(b.start, b.end).join('\n').trimEnd());
|
|
262
|
+
|
|
263
|
+
const body = [
|
|
264
|
+
`# ${_title(text, sourceSlug)} — carried`,
|
|
265
|
+
'',
|
|
266
|
+
`> **Source:** carried by the archival sweep on ${date} from`,
|
|
267
|
+
`> [\`${sourceSlug}\`](${parked ? '../' : ''}archive/${sourceSlug}.md), which closed every other step.`,
|
|
268
|
+
'> Each step below was `[~]` there and is restated verbatim as open work, so',
|
|
269
|
+
'> archiving the parent buried nothing. Blockers the steps name moved with them.',
|
|
270
|
+
'',
|
|
271
|
+
'## Goal',
|
|
272
|
+
'',
|
|
273
|
+
`Every step ${sourceSlug} deferred is either done here or explicitly disposed`,
|
|
274
|
+
'of — a step that still cannot run is re-deferred with its reason, never',
|
|
275
|
+
'left to read as finished.',
|
|
276
|
+
'',
|
|
277
|
+
`## Phase 1 — ${phaseName}`,
|
|
278
|
+
'',
|
|
279
|
+
phaseSteps.length > 0
|
|
280
|
+
? phaseSteps.join('\n')
|
|
281
|
+
: '- [ ] **1.1 Close the carried acceptance criteria below.** The parent deferred\n' +
|
|
282
|
+
' only acceptance criteria; this step is done when each is checked or disposed of.\n' +
|
|
283
|
+
' verify: every criterion under `## Acceptance Criteria` is `[x]` or `[-]`',
|
|
284
|
+
'',
|
|
285
|
+
...(blockerText.length > 0 ? ['## Blockers', '', blockerText.join('\n\n'), ''] : []),
|
|
286
|
+
'## Risk Register',
|
|
287
|
+
`<!-- risk-review: v1 | reviewed: ${date} | reviewer: archive-sweep/auto-carry -->`,
|
|
288
|
+
'',
|
|
289
|
+
'| Rank | Item | Risk type | Description | Mitigation | Anchored under |',
|
|
290
|
+
'|------|------|-----------|-------------|------------|----------------|',
|
|
291
|
+
'| 1 | Carried steps stay blocked indefinitely | implementation | A step deferred ' +
|
|
292
|
+
'once for elapsed time or a decision can sit here as long as it sat in the parent | ' +
|
|
293
|
+
'It now counts as open work in the dashboard instead of as 100 %, and its blocker ' +
|
|
294
|
+
`is listed where the estate gates count it | Phase 1 — ${phaseName} |`,
|
|
295
|
+
'',
|
|
296
|
+
'## Acceptance Criteria',
|
|
297
|
+
'',
|
|
298
|
+
acSteps.length > 0
|
|
299
|
+
? acSteps.join('\n')
|
|
300
|
+
: `- [ ] AC-1 — No step carried from \`${sourceSlug}\` is still \`[ ]\` without a recorded disposition.`,
|
|
301
|
+
'',
|
|
302
|
+
].join('\n');
|
|
303
|
+
const complexity = body.split('\n').length > LIGHTWEIGHT_LINE_BUDGET ? 'structural' : 'lightweight';
|
|
304
|
+
// Parked: `status: later` plus the three-part `entry_condition:` mapping
|
|
305
|
+
// `lint_roadmap_later_disposition` requires, and the growth claim the
|
|
306
|
+
// `later_roadmaps` count needs — a new file in `later/` is not a parking
|
|
307
|
+
// move, so no allowance covers it otherwise.
|
|
308
|
+
const ids = ownerBlockers.join(', ');
|
|
309
|
+
const parkedKeys = parked
|
|
310
|
+
? 'entry_condition:\n' +
|
|
311
|
+
` what: the owner resolves blocker(s) ${ids}\n` +
|
|
312
|
+
' when: whenever the owner takes the next step\n' +
|
|
313
|
+
' who: owner\n' +
|
|
314
|
+
// `lint_roadmap_later_disposition` rule C: a park with no review date
|
|
315
|
+
// reads exactly like an abandonment.
|
|
316
|
+
`review_by: ${_plusDays(date, 90)}\n` +
|
|
317
|
+
`estate_growth_exempt: >-\n Owner-chosen archive of ${sourceSlug}: its deferred steps wait on owner\n` +
|
|
318
|
+
` blocker(s) ${ids} and are parked here instead of left active. The parent\n` +
|
|
319
|
+
' is archived in the same change, so the active count drops by one.\n'
|
|
320
|
+
: '';
|
|
321
|
+
const destText =
|
|
322
|
+
`---\ncomplexity: ${complexity}\nstatus: ${parked ? 'later' : 'ready'}\nexecution:\n mode: phase-checkpoints\n` +
|
|
323
|
+
`parent_roadmap: ${sourceSlug}\n${parkedKeys}---\n${body}`;
|
|
324
|
+
const destRel = parked ? `agents/roadmaps/later/${destSlug}.md` : `agents/roadmaps/${destSlug}.md`;
|
|
325
|
+
|
|
326
|
+
return {
|
|
327
|
+
plan: {
|
|
328
|
+
destSlug,
|
|
329
|
+
destRel,
|
|
330
|
+
destText,
|
|
331
|
+
sourceText: out.join('\n'),
|
|
332
|
+
carried: steps.length,
|
|
333
|
+
movedBlockers: moved.map((b) => b.id),
|
|
334
|
+
ownerBlockers,
|
|
335
|
+
firstStep: (steps[0] as BareStep).block.join('\n'),
|
|
336
|
+
parked,
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
}
|
|
@@ -1351,7 +1351,10 @@ function main(argv?: readonly string[]): number {
|
|
|
1351
1351
|
// leaves behind rather than the one it found. `--check` never archives: a
|
|
1352
1352
|
// gate that mutates the tree it is checking cannot be trusted by CI.
|
|
1353
1353
|
let sweep_out = '';
|
|
1354
|
-
|
|
1354
|
+
// `pending_iron_law_3` too: a 100 % roadmap with bare `[~]` steps is what the
|
|
1355
|
+
// sweep's carry exists for, and gating on `deferred === 0` never spawned it.
|
|
1356
|
+
const before = collect(roadmap_root);
|
|
1357
|
+
if (!args.check && args.archive && unarchived_complete(before).length + pending_iron_law_3(before).length > 0) {
|
|
1355
1358
|
const swept = run_archival_sweep(repo_root);
|
|
1356
1359
|
sweep_out = swept.stdout;
|
|
1357
1360
|
if (swept.stderr) {
|
|
@@ -3,7 +3,7 @@ Modal dialog,modal dialog overlay popup confirm,dialog role + aria-modal,"role=d
|
|
|
3
3
|
Combobox / autocomplete,combobox autocomplete select search suggest dropdown,combobox + listbox popup,"role=combobox aria-expanded aria-controls aria-activedescendant; Down opens list, Enter selects, Esc closes; results announced via live region count","WCAG 4.1.2, 1.3.1",Re-implementing as div+onclick without keyboard model,https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
|
|
4
4
|
Tabs,tabs tabpanel tablist switch view,tablist/tab/tabpanel triad,"role=tablist/tab/tabpanel, aria-selected, tab order: one tabstop into list then Arrow keys; panel labelled by its tab","WCAG 2.1.1, 4.1.2",Each tab a separate Tab stop; panels not labelled,https://www.w3.org/WAI/ARIA/apg/patterns/tabs/
|
|
5
5
|
Accordion / disclosure,accordion disclosure expand collapse faq section,button + aria-expanded,Header is a real button with aria-expanded + aria-controls; content region labelled; Enter/Space toggle,"WCAG 4.1.2, 1.3.1",Heading-with-onclick; hiding content with display:none while aria-expanded=true,https://www.w3.org/WAI/ARIA/apg/patterns/accordion/
|
|
6
|
-
Menu / dropdown actions,menu dropdown actions kebab context,menu button + menu/menuitem,"
|
|
6
|
+
Menu / dropdown actions,menu dropdown actions kebab context menubutton menu-button,menu button + menu/menuitem,"menu button with aria-haspopup=menu aria-expanded; Arrow navigation, Esc closes and returns focus; menuitem (not links styled as menu)",WCAG 2.1.1,Using role=menu for site navigation (use nav+links),https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/
|
|
7
7
|
Toast / status message,toast notification snackbar status alert,status / alert live regions,"role=status (polite) for confirmations, role=alert (assertive) sparingly for errors; never move focus to a toast; pause on hover/focus; allow dismissal","WCAG 4.1.3, 2.2.1",Focus-stealing toasts; auto-dismiss with no persistence option for critical info,https://www.w3.org/WAI/ARIA/apg/patterns/alert/
|
|
8
8
|
Data table,table grid sortable data rows columns,table semantics + aria-sort,Native table elements with th scope; sortable headers are buttons inside th with aria-sort on the th; caption or aria-label names the table,WCAG 1.3.1,Div-grid for tabular data; sort state only as an icon,https://www.w3.org/WAI/ARIA/apg/patterns/table/
|
|
9
9
|
Form validation feedback,form error validation invalid message field,described-by + alert summary,aria-invalid + aria-describedby on the field; on submit failure move focus to first invalid field or an error-summary with anchor links; errors persist until fixed,"WCAG 3.3.1, 3.3.3, 2.4.3",Placeholder-only labels; toast-only errors,https://www.w3.org/WAI/tutorials/forms/notifications/
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"refresh_cadence": "quarterly",
|
|
29
29
|
"upstream": {
|
|
30
30
|
"repo": "derived: W3C ARIA Authoring Practices Guide + WCAG 2.2",
|
|
31
|
-
"sha": "
|
|
32
|
-
"last_checked": "2026-
|
|
31
|
+
"sha": "WCAG 2.2 W3C-REC-2024-12-12; APG continuously-published, menu-button canonical slug",
|
|
32
|
+
"last_checked": "2026-10-01"
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"refresh_cadence": "quarterly",
|
|
29
29
|
"upstream": {
|
|
30
30
|
"repo": "derived: RFC 9110/9457/7396/8288 + httpapi WG drafts",
|
|
31
|
-
"sha": "RFC 9110 (STD 97) / 9457 / 7396 / 8288 \u2014
|
|
32
|
-
"last_checked": "2026-
|
|
31
|
+
"sha": "RFC 9110 (STD 97, 2022-06) / 9457 (2023-07, obsoletes 7807) / 7396 (2014-10) / 8288 (2017-10) \u2014 all Standards Track",
|
|
32
|
+
"last_checked": "2026-10-04"
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -234,3 +234,20 @@ When a test fails, do not retry blindly with tweaked assertions until something
|
|
|
234
234
|
## Clarification guard — ambiguous contract → ask
|
|
235
235
|
|
|
236
236
|
If the endpoint contract is ambiguous (unclear status code, optional fields, error envelope shape), do not assume. Ask the user or check the OpenAPI spec / route definition before writing assertions — never guess the response shape from the route name.
|
|
237
|
+
|
|
238
|
+
## The HTTP-assertion idiom, per ecosystem
|
|
239
|
+
|
|
240
|
+
The examples above are Laravel's. The *shape* they teach — assert the status,
|
|
241
|
+
then the body contract, then the side effect, and keep one behavior per test —
|
|
242
|
+
transfers unchanged; the API does not. Resolve the runner with
|
|
243
|
+
`resolve_toolchain` and read its `ecosystems`:
|
|
244
|
+
|
|
245
|
+
| `ecosystems` | Request + assertion surface |
|
|
246
|
+
|---|---|
|
|
247
|
+
| `php` | `$this->getJson(...)` / `assertStatus` / `assertJsonPath` |
|
|
248
|
+
| `js` | `supertest` or the framework's own test client, with `expect(res.status)` |
|
|
249
|
+
| `python` | `httpx.AsyncClient` / framework `TestClient`; `assert res.status_code` |
|
|
250
|
+
| `go` | `httptest.NewServer` + `net/http`, or the router's own `ServeHTTP` |
|
|
251
|
+
|
|
252
|
+
Whatever the surface, the negative tests are not optional: unauthenticated,
|
|
253
|
+
not-owner and cross-tenant each get their own case, per `broken-access-control`.
|
|
@@ -245,14 +245,26 @@ paragraph claiming "the same five answers" directly after a list of four:
|
|
|
245
245
|
| `graph_dead` | `dead` |
|
|
246
246
|
| `graph_query` | `query` |
|
|
247
247
|
| `graph_path` | `path` |
|
|
248
|
+
| `graph_node` | no CLI verb — one symbol's location, in-edges, out-edges and degree |
|
|
248
249
|
|
|
249
250
|
`untested` has no tool of its own; it is a flag on `graph_impact`, because the
|
|
250
|
-
two answer the same question over the same diff and a
|
|
251
|
-
standing context for a boolean. `graph_impact` is the only one that is not
|
|
251
|
+
two answer the same question over the same diff and a separate tool would have
|
|
252
|
+
cost standing context for a boolean. `graph_impact` is the only one that is not
|
|
252
253
|
read-only — it runs `git diff --name-only` to resolve its rev — and
|
|
253
254
|
`graph_dead`'s refusal arrives as `status: "refused"`, never as `status: "ok"`
|
|
254
255
|
with an empty list.
|
|
255
256
|
|
|
257
|
+
`graph_node` is the one entry with no CLI verb behind it, and the one that
|
|
258
|
+
REFUSES a seed it cannot resolve exactly. Every other reader answers about a
|
|
259
|
+
neighbourhood or a set, where a best-guess seed costs the caller one wrong line
|
|
260
|
+
among several; a node view's every field — the location, the degree, both edge
|
|
261
|
+
lists — is a statement about ONE node, so a guess is wrong in all of them at
|
|
262
|
+
once. It resolves on the exact tiers of the same seed ladder (node id, then
|
|
263
|
+
label) and returns `status: "refused"` naming the candidates when a label is
|
|
264
|
+
ambiguous, rather than scoring free text — which is the retrieval class the
|
|
265
|
+
measured null covers (`docs/CLAIMS.md`, `code-graph-retrieval-null`). Use
|
|
266
|
+
`graph_query` when a best-guess match is what you want.
|
|
267
|
+
|
|
256
268
|
**No ordering claim is added here, and no measurement claim either.** These
|
|
257
269
|
verbs are cheaper than reconstructing the same relationship by hand — that is a
|
|
258
270
|
claim about the ALTERNATIVE being a manual reconstruction, not about grep.
|
|
@@ -44,7 +44,7 @@ A **live preview URL** is required for testing.
|
|
|
44
44
|
|
|
45
45
|
## Procedure: Design review
|
|
46
46
|
|
|
47
|
-
1. **Inspect the PR and preview** — Read the PR description, diff, and identify changed components/pages;
|
|
47
|
+
1. **Inspect the PR and preview** — Read the PR description, diff, and identify changed components/pages; read the probe artifact and run the appearance floor over the preview URL (Phase 0).
|
|
48
48
|
2. **Walk the interactions** — Run Phase 1; cover hover/focus/active/disabled, keyboard, loading, and form error states.
|
|
49
49
|
3. **Cover responsiveness, polish, a11y, robustness** — Run Phases 2–5 in order; record findings per phase.
|
|
50
50
|
4. **Audit code-health and content** — Run Phases 6–7; check tokens, dead styles, copy, console warnings.
|
|
@@ -55,7 +55,11 @@ A **live preview URL** is required for testing.
|
|
|
55
55
|
- Read PR description and git diff.
|
|
56
56
|
- Identify changed components and affected pages.
|
|
57
57
|
- Navigate to preview URL.
|
|
58
|
-
-
|
|
58
|
+
- **Read the probe artifact** `agents/runtime/state/ui-conformance.json`
|
|
59
|
+
(`ui_conformance_probe --target <file> --reference <file>`) — its per-dimension counters are the
|
|
60
|
+
behavioral evidence Phases 1–2 report against. Absent is absent, never clean; a dimension the host
|
|
61
|
+
could not exercise carries a not-applicable row with its reason rather than a zero.
|
|
62
|
+
- **Run the appearance floor** (§ Appearance verification) — mandatory on every review.
|
|
59
63
|
|
|
60
64
|
### Phase 1: Interaction
|
|
61
65
|
|
|
@@ -102,7 +106,9 @@ asserted floor outside the measured set is an assertion nobody checks; 375px
|
|
|
102
106
|
passing says nothing about 320px, which is where a two-column grid or a fixed
|
|
103
107
|
`min-width` actually breaks.
|
|
104
108
|
|
|
105
|
-
-
|
|
109
|
+
- **Read the probe artifact's `viewport_matrix` rows** — one per declared width, recording whether the
|
|
110
|
+
layout property that should change at that breakpoint did. A not-applicable row is missing evidence, not a pass.
|
|
111
|
+
- **Run the appearance floor** (§ Appearance verification) at every one of the four widths.
|
|
106
112
|
- **Scroll-driven surface** — read the `scroll_evidence` artefact
|
|
107
113
|
([`references/verification-automation.md`](references/verification-automation.md)
|
|
108
114
|
§ Scroll evidence) and report every sample whose asserted `state` and
|
|
@@ -156,6 +162,26 @@ passing says nothing about 320px, which is where a two-column grid or a fixed
|
|
|
156
162
|
- No placeholder text left in production.
|
|
157
163
|
- Check browser console for JavaScript errors or warnings.
|
|
158
164
|
|
|
165
|
+
## Appearance verification — mandatory, and explicitly appearance-only
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
APPEARANCE VERIFICATION IS MANDATORY WHEREVER APPEARANCE CAN BE AFFECTED.
|
|
169
|
+
THE PROBE DEMOTES THE IMAGE FROM PRIMARY EVIDENCE — IT DOES NOT MOVE THE FLOOR.
|
|
170
|
+
AN IMAGE IS NEVER EVIDENCE FOR HOVER, FOCUS, KEYBOARD, BREAKPOINT OR JS BEHAVIOR.
|
|
171
|
+
AN UNRUN APPEARANCE CHECK IS REPORTED AS UNRUN, NEVER AS PASSED.
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Trigger — identical to the two capture steps it replaces**, not merely as broad: Phase 0
|
|
175
|
+
unconditionally, Phase 2 once per width. Only what the image is evidence *for* narrowed.
|
|
176
|
+
**Two jobs, and the older one comes first:** (1) presence and sanity — *"presence + sanity
|
|
177
|
+
check that nothing renders broken. Not pixel-perfect regression"* — no blank frame, no
|
|
178
|
+
collapsed or overlapping layout, no missing region, no unstyled flash; **no probe dimension
|
|
179
|
+
covers it**, because a computed style can be correct on a node nobody can see; (2) pixel
|
|
180
|
+
comparison against a baseline where one exists, element-scoped, dynamic content masked. No
|
|
181
|
+
render capability → scope the verdict and say so per the gate at the top of this skill;
|
|
182
|
+
degrading is reported, never a pass. What a clean render does *not* answer:
|
|
183
|
+
[`references/verification-automation.md`](references/verification-automation.md) § Appearance verification.
|
|
184
|
+
|
|
159
185
|
## Reviewer posture
|
|
160
186
|
|
|
161
187
|
**Approval is earned, not assumed. Default to flagging.**
|
|
@@ -187,7 +213,7 @@ excessive copy, and redundant UI chrome.
|
|
|
187
213
|
Load the reference file whose sections the review needs — never all of them by default:
|
|
188
214
|
|
|
189
215
|
- [`references/review-communication.md`](references/review-communication.md) — Before / After / Why output format · Communication principles · Report structure · Design Review Summary
|
|
190
|
-
- [`references/verification-automation.md`](references/verification-automation.md) — Visual QA with browser automation · Async-verifier pattern (keep the main context clean)
|
|
216
|
+
- [`references/verification-automation.md`](references/verification-automation.md) — Visual QA with browser automation · Async-verifier pattern (keep the main context clean) · Appearance verification (what a clean render does not answer)
|
|
191
217
|
|
|
192
218
|
## Output format
|
|
193
219
|
|
|
@@ -122,3 +122,35 @@ the async verifier above, which captures the fan-out's main win without spinning
|
|
|
122
122
|
up four separate views. Reconsider only when `design-review` runs as a standalone
|
|
123
123
|
heavy batch over many *independent* surfaces, where per-surface
|
|
124
124
|
`do-in-parallel` genuinely pays.
|
|
125
|
+
|
|
126
|
+
## Appearance verification — what a clean render does not answer
|
|
127
|
+
|
|
128
|
+
The skill body carries the floor: appearance verification is mandatory wherever
|
|
129
|
+
appearance can be affected, its trigger is identical to the two capture steps it
|
|
130
|
+
replaces, and presence-and-sanity comes before pixel comparison. This section is
|
|
131
|
+
the part a reviewer looks up rather than obeys — the division of labour between a
|
|
132
|
+
render and the probe's four dimensions.
|
|
133
|
+
|
|
134
|
+
A render is a resting frame. It can only show what the surface looks like with
|
|
135
|
+
nothing driving it, which is why a clean one says nothing about:
|
|
136
|
+
|
|
137
|
+
| The question | Why the render cannot answer it | What does |
|
|
138
|
+
|---|---|---|
|
|
139
|
+
| Does hover / focus / active feedback exist? | the state is never entered | `interaction` |
|
|
140
|
+
| Does the keyboard reach it, and does the handler fire? | no input is delivered | `interaction` |
|
|
141
|
+
| Did the breakpoint change the layout, or did the media query silently not fire? | the same picture comes back either way | `viewport_matrix` |
|
|
142
|
+
| Is the resolved value the token intended, after cascade and fallback? | a wrong value can look plausible | `computed_style` |
|
|
143
|
+
| Is `prefers-reduced-motion` honoured, and with *what* instead? | the preference is never emulated | `media_emulation` |
|
|
144
|
+
|
|
145
|
+
Reading a clean render as though it covered a row of this table is the
|
|
146
|
+
substitution the appearance-only marking exists to prevent, and it is the reason
|
|
147
|
+
the floor lists its two jobs separately rather than as one "visual check": the
|
|
148
|
+
first job is the one no probe dimension replaces, and the second is the one the
|
|
149
|
+
probe supersedes for behavior.
|
|
150
|
+
|
|
151
|
+
**The converse holds and is the less obvious half.** No probe dimension covers
|
|
152
|
+
presence and sanity. A `computed_style` row can be green on a node that is
|
|
153
|
+
off-screen, transparent, zero-height or painted under an overlay — correct
|
|
154
|
+
resolved values on something nobody can see. That asymmetry is why demoting the
|
|
155
|
+
image from *primary evidence* is not the same as removing it, and why an unrun
|
|
156
|
+
appearance check is reported as unrun rather than folded into a probe verdict.
|
|
@@ -38,7 +38,7 @@ what this skill owns.
|
|
|
38
38
|
imported observation.
|
|
39
39
|
5. On the human's accept, persist the chosen fields into `DESIGN.md`. Where the
|
|
40
40
|
consumer wants a token source of truth, hand the mapped DTCG fields to
|
|
41
|
-
|
|
41
|
+
`brand-to-tokens` / `design-tokens` to
|
|
42
42
|
materialise `.tokens.json` — do not invent a parallel token format.
|
|
43
43
|
|
|
44
44
|
**Two sources, one shape:**
|
|
@@ -97,6 +97,14 @@ nobody can test is how the previous mismatch happened.
|
|
|
97
97
|
It reads zero in a JavaScript tree by construction, which is not the same as
|
|
98
98
|
unused.
|
|
99
99
|
|
|
100
|
+
### 1b. Detect the component-granularity taxonomy the project already chose
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npx tsx scripts/work_engine/taxonomy/detect.ts # or import detect_component_taxonomy(root)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Returns the project's **own** tier names joined with `/` — `atoms/molecules/organisms`, `primitives/patterns/features`, whatever it actually uses — or `none`. Record it as `state.ui_audit.component_taxonomy`, with `state.ui_audit.component_root` for where the components live. `none` is a real answer, and leaves every downstream step behaving exactly as it did before this detection existed. Never write a taxonomy the project does not evidence, and never "tidy" a layout into one — this step *finds* the project's structure, it never supplies one. Detection rules, the declared-beats-inferred precedence and the two collision floors: [`references/component-taxonomy-detection.md`](references/component-taxonomy-detection.md).
|
|
107
|
+
|
|
100
108
|
### 2. Identify the design system
|
|
101
109
|
|
|
102
110
|
Detect markers, in order. **Stop at the first match** — projects rarely run more than one design system.
|
|
@@ -220,7 +228,7 @@ this component satisfy the artifact"* — which is a different question with a
|
|
|
220
228
|
different answer, because a candidate can be an excellent name-and-props match
|
|
221
229
|
and still use the wrong type scale, the wrong control, or a colour the artifact
|
|
222
230
|
never states. Until this step existed nothing anywhere asked the second
|
|
223
|
-
question, while
|
|
231
|
+
question, while `ui-audit-gate` carried *"reuse
|
|
224
232
|
beats duplication"* as unqualified prose. Reused on an artifact port, an
|
|
225
233
|
unconforming candidate is a fidelity deviation dressed as good hygiene.
|
|
226
234
|
|
|
@@ -271,6 +279,9 @@ then set `state.ui_audit.greenfield = true` and emit a halt:
|
|
|
271
279
|
> before building (recommended for projects with >1 planned screen)
|
|
272
280
|
> 2. Proceed bare with Tailwind defaults (recommended for one-off prototypes)
|
|
273
281
|
> 3. Point me at an external design-system reference (URL or file)
|
|
282
|
+
> 4. Scaffold + a granularity convention — as 1, and new components go into
|
|
283
|
+
> named granularity folders you pick the names for; rename or drop it later
|
|
284
|
+
> and nothing here objects
|
|
274
285
|
|
|
275
286
|
**Recommendation: 1 — Scaffold tokens + primitives** — even one extra screen
|
|
276
287
|
benefits from a shared base; the scaffold cost is ~10 min and saves
|
|
@@ -278,7 +289,9 @@ re-doing every primitive on screen 2. Caveat: flip to 2 if this is a
|
|
|
278
289
|
demo or single-page prototype that will not grow.
|
|
279
290
|
```
|
|
280
291
|
|
|
281
|
-
|
|
292
|
+
Option 4 is an **offer**, and the only one made anywhere: a project that already exists is never asked (§ 1b reads what it chose), and a greenfield project picking any other number has declined terminally, because the halt is a no-op once any decision is recorded. It stays one more number in the same block rather than a second question — a single number still answers it, which is what the reply-shape rule requires.
|
|
293
|
+
|
|
294
|
+
Record the user's pick in `state.ui_audit.greenfield_decision` (`scaffold` | `bare` | `external_reference` | `granularity_convention`). Re-running the skill on the same state-file with `greenfield_decision` set is a no-op for the halt (audit findings stay). `granularity_convention` takes the same scaffold path as `scaffold` — it adds the convention, it does not replace the scaffolding.
|
|
282
295
|
|
|
283
296
|
### 8. (Optional) Capture an a11y baseline
|
|
284
297
|
|
|
@@ -332,6 +345,7 @@ violations will surface as new findings on every run.
|
|
|
332
345
|
Load on demand once the audit needs the pitfall catalog:
|
|
333
346
|
|
|
334
347
|
- [`references/anti-slop-cross-reference.md`](references/anti-slop-cross-reference.md) — Anti-slop cross-reference
|
|
348
|
+
- [`references/component-taxonomy-detection.md`](references/component-taxonomy-detection.md) — Component-taxonomy detection rules
|
|
335
349
|
|
|
336
350
|
- [`references/output-and-pitfalls.md`](references/output-and-pitfalls.md) — Output format · Gotcha · Anti-slop cross-reference
|
|
337
351
|
|
|
@@ -344,12 +358,13 @@ Load on demand once the audit needs the pitfall catalog:
|
|
|
344
358
|
5. **`state.ui_audit.patterns`** — object with forms, tables, modals, empty_states, navigation, data_display arrays
|
|
345
359
|
6. **`state.ui_audit.candidates`** — top-5 similarity matches for the current input (may be empty)
|
|
346
360
|
7. **`state.ui_audit.greenfield`** — boolean; when true, `greenfield_decision` MUST also be set before the dispatcher advances
|
|
361
|
+
7b. **`state.ui_audit.component_taxonomy`** / **`component_root`** — the project's own granularity tiers joined with `/` (or `none`), and where the components live relative to the project root. Never a canonical tier list — a project with three tiers records three; `none` is the value that leaves every downstream step unchanged.
|
|
347
362
|
8. **`state.ui_audit.a11y_baseline`** *(optional)* — array of `{rule, selector, severity?}` entries documenting pre-existing a11y violations the review gate should treat as informational. Omit the key entirely when no baseline applies; do not write `[]` for "I checked and there are none" — that disables the gate's filter for every future run.
|
|
348
363
|
|
|
349
364
|
**Design-system export (current-repo source):** when the goal is to seed
|
|
350
365
|
`DESIGN.md` from *this* repo, emit the inventory as a `design-system.json`
|
|
351
366
|
artifact (the import contract in
|
|
352
|
-
|
|
367
|
+
`design-system-capture`)
|
|
353
368
|
and hand it to `design-system-capture` — the same shape an external extraction
|
|
354
369
|
tool produces, so the import path is uniform.
|
|
355
370
|
|