@event4u/agent-config 16.1.0 → 16.2.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 +237 -248
- package/dist/agent-src/commands/roadmap/process-full.md +1 -1
- package/dist/agent-src/commands/work.md +4 -0
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +4 -8
- package/dist/agent-src/rules/ui-audit-gate.md +1 -2
- 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/design-review/SKILL.md +30 -4
- package/dist/agent-src/skills/design-review/references/verification-automation.md +32 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +16 -1
- package/dist/agent-src/skills/existing-ui-audit/references/component-taxonomy-detection.md +56 -0
- package/dist/agent-src/skills/markitdown/SKILL.md +4 -0
- package/dist/agent-src/skills/playwright-testing/SKILL.md +30 -6
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +23 -0
- 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 +260 -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/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-delegate/{chunk-S3VFXMTM.js → chunk-4XFP2Y3E.js} +1 -1
- package/dist/cli-delegate/{chunk-HDVVGPQW.js → chunk-7XGBX6ZH.js} +471 -387
- package/dist/cli-delegate/{chunk-GJCBB2UG.js → chunk-FP36SWJD.js} +432 -144
- package/dist/cli-delegate/{chunk-UNCRJBT3.js → chunk-IGD6ERX6.js} +31 -0
- package/dist/cli-delegate/{chunk-FXYUYU4N.js → chunk-JNMVLWLR.js} +42 -1
- package/dist/cli-delegate/{chunk-QJWAUMJW.js → chunk-YJ72UIAK.js} +730 -15
- package/dist/cli-delegate/cmd_conformance.js +902 -782
- package/dist/cli-delegate/cmd_doctor.js +2 -2
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +4 -4
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_route_audit.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +2 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +2 -2
- package/dist/cli-delegate/cmd_uninstall.js +2 -2
- package/dist/cli-delegate/cmd_validate.js +2 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +10 -10
- 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 +6666 -2581
- package/dist/hooks/dispatch.sha256 +1 -0
- package/dist/install/install.mjs +848 -733
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +2747 -1510
- package/dist/server/schemas/settings.js +23 -0
- 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 +6 -4
- package/package.json +4 -4
- 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 +260 -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/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 +29 -0
- package/src/config/ci-local-parity.yml +18 -0
- package/src/config/continuity-surface.json +2 -2
- package/src/config/gate-coverage.yml +234 -3
- package/src/config/gate-violation-baselines.json +7 -3
- package/src/config/hook-latency-budget.json +21 -0
- package/src/config/hook-token-budget.json +2 -2
- package/src/config/metric-registry.yml +114 -0
- package/src/config/placeholder-drift-budget.json +10 -0
- package/src/config/routing-coverage-seed.json +18 -4
- package/src/scripts/_cli/cmd_doctor.ts +5 -19
- package/src/scripts/_cli/doctor_execution.ts +100 -17
- package/src/scripts/_cli/doctor_network_posture.ts +226 -0
- package/src/scripts/_lib/body_portable.ts +102 -0
- package/src/scripts/_lib/cc_transcript.ts +132 -1
- package/src/scripts/_lib/concern_sla_window.ts +200 -0
- package/src/scripts/_lib/forge_protection.ts +114 -0
- package/src/scripts/_lib/forge_reader.ts +558 -0
- package/src/scripts/_lib/host_env_write.ts +111 -0
- package/src/scripts/_lib/llm_proposer_transport.ts +14 -4
- package/src/scripts/_lib/obligations.ts +119 -8
- package/src/scripts/_lib/probe_inputs.ts +271 -0
- package/src/scripts/_lib/read_surface_scan.ts +322 -0
- package/src/scripts/_lib/release_highlights.ts +2 -1
- package/src/scripts/_lib/retrieval_sanitize.ts +77 -16
- package/src/scripts/_lib/shell_write_shapes.ts +108 -0
- package/src/scripts/_lib/structural_hiding.ts +622 -0
- package/src/scripts/_lib/turn_end_refusals.ts +525 -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/ai_team/team_dispatch.ts +4 -0
- package/src/scripts/before_complete_hook.ts +340 -23
- package/src/scripts/bench_hook_latency.ts +412 -5
- 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 +245 -3
- package/src/scripts/check_finding_dispositions.ts +22 -3
- package/src/scripts/check_generator_sync.ts +71 -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 +47 -5
- package/src/scripts/check_kill_switch_table.ts +294 -0
- package/src/scripts/check_placeholder_drift.ts +221 -0
- package/src/scripts/check_read_surface_coverage.ts +515 -0
- package/src/scripts/check_release_holds.ts +2 -1
- package/src/scripts/check_routing_coverage.ts +378 -11
- package/src/scripts/check_static_parity.ts +17 -0
- package/src/scripts/ci_settle.ts +145 -19
- package/src/scripts/closure_scan.ts +115 -1
- package/src/scripts/compile_hook_manifest.ts +60 -16
- package/src/scripts/external_sources_denylist.json +29 -4
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +42 -5
- package/src/scripts/hooks/block_config_weakening.ts +229 -4
- package/src/scripts/hooks/block_kernel_rule_writes.ts +9 -78
- package/src/scripts/hooks/block_plumbing_writes.ts +314 -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 +1 -2
- package/src/scripts/hooks/comment_discipline_hook.ts +1 -3
- 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 +25 -19
- 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 +128 -0
- package/src/scripts/hooks/host_lowering.json +1 -0
- package/src/scripts/hooks/host_lowering.ts +128 -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 +25 -4
- package/src/scripts/hooks/orchestration_record_hook.ts +1 -2
- 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 +8 -5
- 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 +49 -0
- package/src/scripts/hooks/telemetry_flush_hook.ts +1 -2
- package/src/scripts/hooks/telemetry_usage_hook.ts +1 -2
- package/src/scripts/hooks/tool_result_bytes_hook.ts +93 -9
- package/src/scripts/hooks/turn_end_gate_hook.ts +337 -324
- package/src/scripts/hooks/ui_route_nudge_hook.ts +1 -2
- package/src/scripts/install.ts +3 -4
- 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 +55 -0
- package/src/scripts/lint_roadmap_blockers.ts +78 -12
- package/src/scripts/lint_skill_descriptions.ts +1 -1
- package/src/scripts/lint_skill_scripts_readonly.ts +1 -1
- package/src/scripts/mcp_server/prompts.ts +142 -1
- package/src/scripts/measure_skill_ranker_baseline.ts +305 -51
- package/src/scripts/measure_turn_end_gate.ts +193 -0
- package/src/scripts/memory_lookup.ts +1 -1
- package/src/scripts/prepack-check.mjs +53 -0
- package/src/scripts/release_publication.ts +13 -1
- package/src/scripts/report_invocation_surface.ts +383 -0
- package/src/scripts/report_obligation_carriers.ts +699 -0
- package/src/scripts/report_obligation_writer_split.ts +236 -0
- package/src/scripts/report_skill_menu_census.ts +208 -0
- package/src/scripts/report_standing_payload_by_host.ts +1 -1
- package/src/scripts/roadmap_verify_share.ts +213 -0
- package/src/scripts/schemas/command.schema.json +44 -0
- package/src/scripts/schemas/review-findings.schema.json +4 -0
- package/src/scripts/schemas/skill.schema.json +44 -0
- package/src/scripts/self_review_gate.ts +359 -10
- package/src/scripts/semantic_parity_census.ts +314 -0
- package/src/scripts/session_eol_report.ts +54 -1
- package/src/scripts/sweep_dead_scan_roots.ts +1 -1
- package/src/scripts/trigger_eval_grandfather.json +0 -2
- 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 +31 -0
- package/src/templates/consumer-settings/ONBOARDING.md +1 -0
- package/dist/ui/assets/index-DH1xc62v.js +0 -29
- package/dist/ui/assets/index-jSfMW8_t.css +0 -1
- /package/dist/cli-delegate/{chunk-YUM5KURG.js → chunk-7RQP4UDH.js} +0 -0
|
@@ -165,7 +165,7 @@ command is a claim; a layer with one is a check.
|
|
|
165
165
|
| 1 | A targeted local RED, then GREEN | the test runner filtered to the failing name — `npm run test:ts -- <file>`, never the suite |
|
|
166
166
|
| 2 | Quality scoped to the changed surface | the type-checker and linter over the diff — `npm run typecheck`, the linter on changed files |
|
|
167
167
|
| 3 | Per-phase fast CI | `roadmap.quality_cadence: per_phase` (Phase 0.2) at each phase boundary |
|
|
168
|
-
| 4 | The final full required CI | `./scripts-run src/scripts/ci_settle <PR> --timeout
|
|
168
|
+
| 4 | The final full required CI | `./scripts-run src/scripts/ci_settle <PR> --timeout-min 28`, run as a BACKGROUND job — its LAST OUTPUT LINE is the verdict |
|
|
169
169
|
| 5 | Forge branch protection | `agent-config doctor --json` → `forge_protection` (Phase 3.2), read from the forge |
|
|
170
170
|
| 6 | Final-head verification | `ci_settle`'s verdict line names the head; it must be the head that was pushed last |
|
|
171
171
|
|
|
@@ -9,6 +9,10 @@ visibility: visible
|
|
|
9
9
|
skills: [refine-prompt, command-routing]
|
|
10
10
|
description: Drive a free-form prompt end-to-end through refine → score → plan → implement → test → verify → report — Option-A loop over `work_engine`, confidence-band gated, no auto-git, test-first.
|
|
11
11
|
argument-hint: "[prompt]"
|
|
12
|
+
inputs:
|
|
13
|
+
- name: prompt
|
|
14
|
+
type: string
|
|
15
|
+
description: What to work on. Absent means resume the current task.
|
|
12
16
|
suggestion:
|
|
13
17
|
eligible: true
|
|
14
18
|
trigger_description: "build this, implement this, drive this end-to-end"
|
|
@@ -62,14 +62,10 @@ Ask.
|
|
|
62
62
|
|
|
63
63
|
Committing is governed by the canonical
|
|
64
64
|
[`commit-policy`](../../rules/commit-policy.md) rule, which applies
|
|
65
|
-
regardless of `personal.autonomy
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
authorizes it.
|
|
70
|
-
- NEVER ask about committing. The user invokes a command or says so.
|
|
71
|
-
- In autonomous mode, the **only** permitted commit-related question
|
|
72
|
-
is the one-shot pre-scan ask at the start of roadmap execution.
|
|
65
|
+
regardless of `personal.autonomy`. Its Iron Law, its four exceptions
|
|
66
|
+
and the never-ask clause live there; the mechanics — the Hard-Floor
|
|
67
|
+
diff triggers and the one-shot roadmap pre-scan ask — live in
|
|
68
|
+
[`commit-mechanics`](../authority/commit-mechanics.md).
|
|
73
69
|
|
|
74
70
|
Push, merge, rebase, branch creation, PR operations, and tags
|
|
75
71
|
remain permission-gated by
|
|
@@ -71,8 +71,7 @@ EXISTING-UI-AUDIT RUNS FIRST. ALWAYS.
|
|
|
71
71
|
`state.ui_audit` is a non-empty dict carrying at least one of:
|
|
72
72
|
|
|
73
73
|
- `components_found` — inventory entries from `existing-ui-audit`.
|
|
74
|
-
- `greenfield: true` plus `greenfield_decision` ∈
|
|
75
|
-
`{scaffold, bare, external_reference}`.
|
|
74
|
+
- `greenfield: true` plus a `greenfield_decision` ∈ `GREENFIELD_DECISIONS`.
|
|
76
75
|
- Legacy `components` alias — back-compat.
|
|
77
76
|
|
|
78
77
|
`null` or `{}` is **not** findings; empty dict is rejected on purpose.
|
|
@@ -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
|
}
|
|
@@ -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.
|
|
@@ -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.
|
|
@@ -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,6 +358,7 @@ 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
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# existing-ui-audit — component-taxonomy detection
|
|
2
|
+
|
|
3
|
+
> Section-level entry point of the `existing-ui-audit` skill (progressive
|
|
4
|
+
> disclosure). Load this file when § 1b of SKILL.md routes here — it carries
|
|
5
|
+
> the detection rules and the boundary the step must not cross.
|
|
6
|
+
|
|
7
|
+
## What the detector answers
|
|
8
|
+
|
|
9
|
+
The question is *"has this project already chosen a way to organize its
|
|
10
|
+
components by granularity, and if so what does it call the tiers?"* — never
|
|
11
|
+
*"which taxonomy should this project use?"*. The recorded value is the
|
|
12
|
+
project's **own** tier directory names, in the project's own order, joined
|
|
13
|
+
with `/`, or `none`. Nothing canonical is ever written: a project with three
|
|
14
|
+
tiers records three, and a project whose tiers are called
|
|
15
|
+
`primitives / patterns / features` records exactly that.
|
|
16
|
+
|
|
17
|
+
## Three properties, each pinned by a test
|
|
18
|
+
|
|
19
|
+
- **Declared outranks inferred.** A `## Component taxonomy` section in the
|
|
20
|
+
consumer project's own `DESIGN.md`, at its root or under `docs/`, listing
|
|
21
|
+
backticked directory names as list items wins, provided at least two of
|
|
22
|
+
those directories exist
|
|
23
|
+
under the component root. The name may be bolded — `- **\`atoms\`** — ...`
|
|
24
|
+
is read exactly like `` - `atoms` — ... ``. Grounding the declaration against
|
|
25
|
+
the tree keeps a stale doc from declaring a taxonomy the tree does not have,
|
|
26
|
+
and a backticked name in prose rather than in a list item is a mention, not a
|
|
27
|
+
declaration. This is how a project whose tiers appear in no vocabulary the
|
|
28
|
+
detector knows still gets conformance. The first doc that *qualifies* wins:
|
|
29
|
+
one with no section, or one naming fewer than two tiers that exist on disk,
|
|
30
|
+
falls through to the next.
|
|
31
|
+
|
|
32
|
+
- **A folder that merely sounds like a tier is a collision, not a convention.**
|
|
33
|
+
`components/{checkout,billing,molecules}` records `none`, and so does the
|
|
34
|
+
ordinary kind split `components/{layout,pages,forms}` — `layout`, `page`,
|
|
35
|
+
`block`, `element`, `part` and `cell` are all everyday folder names as well
|
|
36
|
+
as granularity words. Inference needs at least two tier-shaped buckets **and**
|
|
37
|
+
more than two thirds of the weighed ones; support folders (`hooks`, `utils`,
|
|
38
|
+
`types`, `lib`, `styles`, …) are left out of the denominator, so three
|
|
39
|
+
ordinary siblings cannot hide a taxonomy that is really there. Each floor has
|
|
40
|
+
its own fixture, because at one hit in three buckets either floor alone would
|
|
41
|
+
still refuse and neither would be tested.
|
|
42
|
+
|
|
43
|
+
- **`none` is a real answer, not a failure.** A flat tree, an unreadable tree,
|
|
44
|
+
a missing component folder, a permission error: all record `none`, and every
|
|
45
|
+
downstream step then behaves exactly as it did before this detection
|
|
46
|
+
existed. Detection never throws — degrading to `none` is the safe direction,
|
|
47
|
+
because `none` is precisely the value that leaves the project's own
|
|
48
|
+
structures untouched.
|
|
49
|
+
|
|
50
|
+
## The boundary
|
|
51
|
+
|
|
52
|
+
Never write a taxonomy the project does not evidence, and never "tidy" an
|
|
53
|
+
existing layout into one. Holding to the project's own structures is the
|
|
54
|
+
standing rule; this step exists to *find* that structure, not to supply one.
|
|
55
|
+
The single place a taxonomy is ever *offered* is the greenfield halt in § 7,
|
|
56
|
+
and a decline there is terminal.
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: markitdown
|
|
4
|
+
inputs:
|
|
5
|
+
- name: source
|
|
6
|
+
type: string
|
|
7
|
+
description: "URI of the document to convert — file:, https: or data: (http: is refused). Absent means the skill is being read for its scheme discipline rather than invoked."
|
|
4
8
|
description: "Convert PDF, DOCX, XLSX, PPTX, EPUB, images, or audio to Markdown via the markitdown-mcp server — 'extract this PDF', 'OCR this image', 'transcribe this audio'."
|
|
5
9
|
status: active
|
|
6
10
|
tier: senior
|
|
@@ -144,22 +144,46 @@ test('homepage visual regression', async ({ page }) => {
|
|
|
144
144
|
|
|
145
145
|
## Viewport testing
|
|
146
146
|
|
|
147
|
+
A viewport loop whose only assertion is an image proves that the page rendered,
|
|
148
|
+
not that the breakpoint did anything: the same picture comes back whether the
|
|
149
|
+
media query fired or silently did not. Assert the layout property the breakpoint
|
|
150
|
+
is supposed to change, then keep the capture and name it for the one thing it
|
|
151
|
+
proves.
|
|
152
|
+
|
|
147
153
|
```ts
|
|
148
154
|
test.describe('Responsive design', () => {
|
|
149
155
|
for (const viewport of [
|
|
150
|
-
{ width: 1440, height: 900, name: 'desktop' },
|
|
151
|
-
{ width: 768, height: 1024, name: 'tablet' },
|
|
152
|
-
{ width: 375, height: 812, name: 'mobile' },
|
|
156
|
+
{ width: 1440, height: 900, name: 'desktop', columns: '1fr 1fr 1fr' },
|
|
157
|
+
{ width: 768, height: 1024, name: 'tablet', columns: '1fr 1fr' },
|
|
158
|
+
{ width: 375, height: 812, name: 'mobile', columns: '1fr' },
|
|
153
159
|
]) {
|
|
154
|
-
test(`
|
|
155
|
-
await page.setViewportSize(viewport)
|
|
160
|
+
test(`lays out correctly on ${viewport.name}`, async ({ page }) => {
|
|
161
|
+
await page.setViewportSize({ width: viewport.width, height: viewport.height })
|
|
156
162
|
await page.goto('/')
|
|
157
|
-
|
|
163
|
+
// Behaviour: the declared breakpoint actually changed the layout.
|
|
164
|
+
await expect(page.locator('#grid')).toHaveCSS('grid-template-columns', viewport.columns)
|
|
165
|
+
// Appearance only: presence + sanity that nothing renders broken.
|
|
166
|
+
await expect(page).toHaveScreenshot(`appearance-${viewport.name}.png`)
|
|
158
167
|
})
|
|
159
168
|
}
|
|
160
169
|
})
|
|
161
170
|
```
|
|
162
171
|
|
|
172
|
+
**Read the probe artifact rather than re-deriving the matrix by hand.**
|
|
173
|
+
`agents/runtime/state/ui-conformance.json` — produced by
|
|
174
|
+
`ui_conformance_probe --target <file> --reference <file>` — carries a
|
|
175
|
+
`viewport_matrix` row per declared width, plus a not-applicable row with its
|
|
176
|
+
reason wherever the host could not cross the breakpoint. A width with no row is
|
|
177
|
+
missing evidence, not a pass, and no dimension reads zero findings because it did
|
|
178
|
+
not run.
|
|
179
|
+
|
|
180
|
+
**The capture above is appearance-only, and it stays mandatory.** It proves
|
|
181
|
+
presence and sanity — the surface rendered and nothing renders obviously broken —
|
|
182
|
+
and proves nothing about hover, focus, keyboard or a media-preference branch.
|
|
183
|
+
Demoting it from behavioral evidence does not narrow when it runs: it still runs
|
|
184
|
+
at every width in the matrix. Floor and division of labour:
|
|
185
|
+
[`design-review`](../design-review/SKILL.md) § Appearance verification.
|
|
186
|
+
|
|
163
187
|
## Debugging
|
|
164
188
|
|
|
165
189
|
```bash
|
|
@@ -69,6 +69,29 @@ still exists in the tree. Absent or empty → fall through to
|
|
|
69
69
|
Then review existing components in the codebase for the same
|
|
70
70
|
responsibility — extend rather than rebuild when a match is found.
|
|
71
71
|
|
|
72
|
+
**Read `state.ui_audit.component_taxonomy` before you decide where the
|
|
73
|
+
component goes.** The audit (§ 1b of
|
|
74
|
+
[`existing-ui-audit`](../existing-ui-audit/SKILL.md)) records the project's
|
|
75
|
+
**own** granularity tiers, joined with `/`, or `none`:
|
|
76
|
+
|
|
77
|
+
- **It names tiers** → record the chosen tier on the component's
|
|
78
|
+
`state.ui_design.components[]` entry as `tier` (the apply step reads that
|
|
79
|
+
field and nothing else writes it), then place the component inside it and say
|
|
80
|
+
which:
|
|
81
|
+
*"conforming to the project's `primitives/patterns/features` taxonomy —
|
|
82
|
+
`Checkout` goes under `src/components/features/`"*. Match the tier by name;
|
|
83
|
+
there is no rule here that computes a tier, and there must not be one.
|
|
84
|
+
- **A component fits no tier** → report it as a named conformance gap with the
|
|
85
|
+
reason, and leave it unplaced. Do not put it somewhere else quietly, and do
|
|
86
|
+
not invent a tier for it — picking one would need exactly the per-tier rule
|
|
87
|
+
the measurement below shows is not derivable.
|
|
88
|
+
- **`none`** → behave exactly as you would without this paragraph. A project
|
|
89
|
+
that organizes its components some other way must not be able to tell that
|
|
90
|
+
this step exists. Never propose a taxonomy to a project that has one you did
|
|
91
|
+
not recognise, and never propose one mid-task to a project that has none —
|
|
92
|
+
the single offer is made once, at the greenfield halt, and a decline there is
|
|
93
|
+
terminal.
|
|
94
|
+
|
|
72
95
|
**A new component's workshop is part of its design where the project has one —
|
|
73
96
|
size-conditional, never a generic mandate.** The boundary is
|
|
74
97
|
[`component-oriented-and-oop-development`](../../guidelines/component-oriented-and-oop-development.md)
|
|
@@ -39,7 +39,7 @@ schema_version: 1
|
|
|
39
39
|
# CI guard: a release bump of `package.json` must update this value
|
|
40
40
|
# in lockstep — see scripts/check_template_pin_drift.ts (road-to-
|
|
41
41
|
# portable-runtime-and-update-check P3.3).
|
|
42
|
-
agent_config_version: "16.
|
|
42
|
+
agent_config_version: "16.2.0"
|
|
43
43
|
|
|
44
44
|
# --- Project identity ---
|
|
45
45
|
project:
|
|
@@ -575,6 +575,36 @@ that was never a judgement call.
|
|
|
575
575
|
full CI pipeline — per `roadmap-ci-steps-policy` a `verify:` must not
|
|
576
576
|
be a full-suite gate.
|
|
577
577
|
|
|
578
|
+
**The expectation half — say what the command must produce.** A command
|
|
579
|
+
alone names no oracle. `` verify: `cat notes.md` `` is a conforming step
|
|
580
|
+
field that cannot say no, so the box gets flipped on a command that was
|
|
581
|
+
never able to fail. In practice the great majority of clauses in a
|
|
582
|
+
roadmap tree state no oracle at all — run the share command below on
|
|
583
|
+
your own tree rather than trusting a number written here. A clause
|
|
584
|
+
MAY therefore state what the command must produce, using the arrow
|
|
585
|
+
`exec:` evidence already carries — not a new symbol:
|
|
586
|
+
|
|
587
|
+
- `` verify: `<cmd>` -> 0 `` — the command must exit with that code.
|
|
588
|
+
- `` verify: `<cmd>` -> /regex/ `` — its output must match.
|
|
589
|
+
|
|
590
|
+
Prose after `verify:` stays legal and reads as MANUAL. Forbidding it
|
|
591
|
+
would invalidate most clauses already in the tree at a stroke, and a
|
|
592
|
+
grammar that reds every producer gets weakened until it finds nothing.
|
|
593
|
+
One parser reads the arrow (`src/scripts/_lib/verify_clause.ts`) and
|
|
594
|
+
nothing parses it a second time. `closure_scan`'s `unfalsifiable-verify`
|
|
595
|
+
family reports the clauses whose oracle cannot say no, and exits 0
|
|
596
|
+
unconditionally — it is a listing, never a gate. The share per roadmap
|
|
597
|
+
is `./scripts-run src/scripts/roadmap_verify_share`.
|
|
598
|
+
|
|
599
|
+
**An absence check names its positive control.** A `verify:` asserting
|
|
600
|
+
that something is *absent* — no match, no occurrence, an empty diff —
|
|
601
|
+
passes identically when the property holds, when the check itself is
|
|
602
|
+
broken, when the path moved, and when the corpus is empty. Such a clause
|
|
603
|
+
MUST name the input on which it does fire: the positive control. A
|
|
604
|
+
fixture that plants the thing, a prior commit that carried it, or a
|
|
605
|
+
sabotage the step records. Without one it is a check nobody has seen
|
|
606
|
+
working, and its green means only that nothing ran.
|
|
607
|
+
|
|
578
608
|
24. **Ready roadmaps carry a `## Risk Register` (Gate R1).** Every
|
|
579
609
|
ready (non-draft) roadmap ends with a schema-valid Risk Register —
|
|
580
610
|
marker line (`<!-- risk-review: v1 | reviewed: YYYY-MM-DD |
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
*
|
|
12
12
|
* The gate is **scoped to the greenfield-scaffold path only**. It acts only
|
|
13
13
|
* when `state.ui_audit` records `greenfield == True` and
|
|
14
|
-
* `greenfield_decision
|
|
15
|
-
* clean `SUCCESS` no-op, so those flows stay
|
|
14
|
+
* `greenfield_decision` ∈ `{scaffold, granularity_convention}`. Every other
|
|
15
|
+
* UI flow sees this slot as a clean `SUCCESS` no-op, so those flows stay
|
|
16
|
+
* byte-identical.
|
|
16
17
|
*/
|
|
17
18
|
import {
|
|
18
19
|
type Any,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
StepResult,
|
|
22
23
|
agent_directive,
|
|
23
24
|
} from '../../delivery_state.js';
|
|
25
|
+
import { GRANULARITY_CONVENTION } from '../../state.js';
|
|
24
26
|
|
|
25
27
|
/** Declared ambiguity surfaces for this step. */
|
|
26
28
|
export const AMBIGUITIES: ReadonlyArray<Record<string, string>> = [
|
|
@@ -112,14 +114,18 @@ export function run(state: DeliveryState): StepResult {
|
|
|
112
114
|
* The gate is inert for every other flow: improve-existing, the `bare` /
|
|
113
115
|
* `external_reference` greenfield picks, and the `diff` / `file` envelopes all
|
|
114
116
|
* leave `ui_audit` without the `greenfield == True` +
|
|
115
|
-
* `greenfield_decision
|
|
117
|
+
* `greenfield_decision` ∈ `{scaffold, granularity_convention}` pair.
|
|
116
118
|
*/
|
|
117
119
|
function _is_greenfield_scaffold(state: DeliveryState): boolean {
|
|
118
120
|
const audit = state.ui_audit;
|
|
119
121
|
if (!_isDict(audit)) return false;
|
|
122
|
+
// `granularity_convention` is option 4 — a scaffold that additionally
|
|
123
|
+
// organises what it creates under a named convention, so it takes the same
|
|
124
|
+
// grounding pass. Kept in step with the identical guard in `scaffold`.
|
|
120
125
|
return (
|
|
121
126
|
audit['greenfield'] === true &&
|
|
122
|
-
audit['greenfield_decision'] === 'scaffold'
|
|
127
|
+
(audit['greenfield_decision'] === 'scaffold' ||
|
|
128
|
+
audit['greenfield_decision'] === GRANULARITY_CONVENTION)
|
|
123
129
|
);
|
|
124
130
|
}
|
|
125
131
|
|