@event4u/agent-config 7.0.2 → 7.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.
Files changed (140) hide show
  1. package/.claude-plugin/marketplace.json +9 -1
  2. package/CHANGELOG.md +117 -0
  3. package/README.md +4 -2
  4. package/dist/agent-src/commands/council/default.md +28 -20
  5. package/dist/agent-src/commands/evals/fix.json +5 -1
  6. package/dist/agent-src/commands/fix/comments.md +101 -0
  7. package/dist/agent-src/commands/fix.md +5 -2
  8. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +65 -0
  9. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +68 -0
  10. package/dist/agent-src/contexts/execution/host-capability-manifest.md +68 -0
  11. package/dist/agent-src/contexts/execution/orchestration-benchmark-gate.md +62 -0
  12. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +59 -0
  13. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +8 -3
  14. package/dist/agent-src/contexts/execution/subagent-response-contract.md +56 -0
  15. package/dist/agent-src/contexts/execution/subagent-routing.md +57 -0
  16. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +54 -0
  17. package/dist/agent-src/contexts/execution/subagent-steering.md +71 -0
  18. package/dist/agent-src/contexts/execution/verify-budget.md +50 -0
  19. package/dist/agent-src/rules/brand-source-of-truth.md +10 -0
  20. package/dist/agent-src/rules/delegation-policy.md +85 -0
  21. package/dist/agent-src/rules/design-fidelity.md +98 -0
  22. package/dist/agent-src/rules/domain-safety-pii.md +22 -0
  23. package/dist/agent-src/rules/legal-safety-floor.md +182 -0
  24. package/dist/agent-src/rules/lethal-trifecta-guard.md +25 -22
  25. package/dist/agent-src/rules/output-discipline.md +85 -0
  26. package/dist/agent-src/rules/telegraph-speak.md +4 -1
  27. package/dist/agent-src/rules/token-budget-discipline.md +94 -0
  28. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +102 -15
  29. package/dist/agent-src/scripts/update_roadmap_progress.ts +30 -3
  30. package/dist/agent-src/skills/accessibility-auditor/SKILL.md +20 -5
  31. package/dist/agent-src/skills/ai-council/SKILL.md +28 -1
  32. package/dist/agent-src/skills/blade-ui/SKILL.md +9 -0
  33. package/dist/agent-src/skills/contract-review/SKILL.md +125 -0
  34. package/dist/agent-src/skills/contract-review/evals/triggers.json +17 -0
  35. package/dist/agent-src/skills/dashboard-design/SKILL.md +21 -5
  36. package/dist/agent-src/skills/design-intelligence/SKILL.md +96 -0
  37. package/dist/agent-src/skills/design-review/SKILL.md +83 -0
  38. package/dist/agent-src/skills/design-system-capture/SKILL.md +234 -0
  39. package/dist/agent-src/skills/design-tokens/SKILL.md +1 -0
  40. package/dist/agent-src/skills/dpa-review/SKILL.md +130 -0
  41. package/dist/agent-src/skills/dpa-review/evals/triggers.json +17 -0
  42. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +15 -4
  43. package/dist/agent-src/skills/fe-design/SKILL.md +98 -16
  44. package/dist/agent-src/skills/flux/SKILL.md +8 -0
  45. package/dist/agent-src/skills/iconography/SKILL.md +1 -0
  46. package/dist/agent-src/skills/laravel/SKILL.md +1 -0
  47. package/dist/agent-src/skills/legal-intake-triage/SKILL.md +128 -0
  48. package/dist/agent-src/skills/legal-intake-triage/evals/triggers.json +17 -0
  49. package/dist/agent-src/skills/legal-practice-profile/SKILL.md +101 -0
  50. package/dist/agent-src/skills/legal-practice-profile/evals/triggers.json +17 -0
  51. package/dist/agent-src/skills/livewire/SKILL.md +8 -0
  52. package/dist/agent-src/skills/nda-triage/SKILL.md +114 -0
  53. package/dist/agent-src/skills/nda-triage/evals/triggers.json +17 -0
  54. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +21 -9
  55. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +3 -1
  56. package/dist/agent-src/skills/recursive-verification/SKILL.md +186 -0
  57. package/dist/agent-src/skills/roadmap-management/SKILL.md +17 -0
  58. package/dist/agent-src/skills/skill-writing/SKILL.md +18 -0
  59. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +11 -0
  60. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +17 -7
  61. package/dist/agent-src/skills/typography-system/SKILL.md +14 -0
  62. package/dist/agent-src/skills/ui-component-architect/SKILL.md +9 -0
  63. package/dist/agent-src/templates/agent-settings.md +64 -19
  64. package/dist/discovery/deprecation-report.md +1 -1
  65. package/dist/discovery/discovery-manifest.json +362 -43
  66. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  67. package/dist/discovery/discovery-manifest.summary.md +13 -5
  68. package/dist/discovery/orphan-report.md +1 -1
  69. package/dist/discovery/packs.json +56 -11
  70. package/dist/discovery/trust-report.md +7 -5
  71. package/dist/discovery/workspaces.json +38 -7
  72. package/dist/mcp/registry-manifest.json +3 -3
  73. package/dist/router.json +1 -1
  74. package/dist/server/routes/wizard.js +4 -3
  75. package/dist/server/routes/wizard.js.map +1 -1
  76. package/dist/server/schemas/settings.js +23 -0
  77. package/dist/server/schemas/settings.js.map +1 -1
  78. package/dist/ui/assets/{index-CoQo90sz.js → index-UjcTG_9O.js} +2 -2
  79. package/dist/ui/assets/index-UjcTG_9O.js.map +1 -0
  80. package/dist/ui/index.html +1 -1
  81. package/docs/RELEASE_STORY_TEMPLATE.md +37 -0
  82. package/docs/architecture.md +4 -4
  83. package/docs/benchmark.md +46 -0
  84. package/docs/catalog.md +18 -6
  85. package/docs/command-flows.md +7 -1
  86. package/docs/contracts/ai-council-config.md +17 -10
  87. package/docs/contracts/audit-log-v1.md +7 -0
  88. package/docs/contracts/auto-orchestration-v1.md +70 -0
  89. package/docs/contracts/capability-boundary.md +64 -0
  90. package/docs/contracts/command-clusters.md +1 -1
  91. package/docs/contracts/discovery-manifest.schema.json +2 -2
  92. package/docs/contracts/package-self-orientation.md +3 -0
  93. package/docs/contracts/subagent-boundary.md +54 -0
  94. package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +32 -0
  95. package/docs/decisions/ADR-020-global-only-consumer-scope.md +13 -6
  96. package/docs/decisions/ADR-049-configuration-trust-boundary.md +11 -1
  97. package/docs/decisions/ADR-093-ai-council-config-user-global.md +10 -4
  98. package/docs/decisions/ADR-104-ai-council-config-global-only.md +119 -0
  99. package/docs/decisions/ADR-105-automatic-subagent-orchestration.md +102 -0
  100. package/docs/decisions/ADR-106-recursive-verification-benchmark-gate.md +126 -0
  101. package/docs/decisions/ADR-107-legal-domain-pack-adoption.md +70 -0
  102. package/docs/decisions/ADR-108-open-source-forever-no-commercial-tier.md +46 -0
  103. package/docs/decisions/INDEX.md +5 -0
  104. package/docs/getting-started.md +2 -2
  105. package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +53 -0
  106. package/docs/guidelines/agent-infra/domain-pack-architecture.md +56 -0
  107. package/docs/guidelines/design-antipatterns-triggers.json +17 -0
  108. package/docs/guidelines/design-antipatterns.md +170 -0
  109. package/docs/guidelines/design-modes.md +97 -0
  110. package/package.json +1 -1
  111. package/src/config/agent-settings.template.yml +103 -3
  112. package/src/config/discovery/packs.yml +24 -0
  113. package/src/config/discovery/workspaces.yml +7 -0
  114. package/src/scripts/_lib/auto_dispatch.ts +95 -0
  115. package/src/scripts/_lib/host_capability.ts +59 -0
  116. package/src/scripts/_lib/orchestration_gate.ts +98 -0
  117. package/src/scripts/_lib/subagent_bundle.ts +154 -0
  118. package/src/scripts/_lib/subagent_response.ts +82 -0
  119. package/src/scripts/_lib/subagent_routing.ts +81 -0
  120. package/src/scripts/_lib/subagent_spawn.ts +97 -0
  121. package/src/scripts/_lib/subagent_steering.ts +64 -0
  122. package/src/scripts/_lib/verify_budget.ts +54 -0
  123. package/src/scripts/ai_council/advisors.ts +4 -2
  124. package/src/scripts/ai_council/clients.ts +7 -1
  125. package/src/scripts/ai_council/config.ts +22 -17
  126. package/src/scripts/bench_ab_v2_run.ts +127 -0
  127. package/src/scripts/bench_ab_v2_stats.ts +39 -0
  128. package/src/scripts/check_council_config_location.ts +6 -5
  129. package/src/scripts/check_trunk_drift.ts +67 -0
  130. package/src/scripts/lint_design_quality.ts +321 -0
  131. package/src/scripts/lint_discovery_vocabulary.ts +6 -0
  132. package/src/scripts/lint_framework_leakage_allowlist.json +21 -0
  133. package/src/scripts/lint_legal_pack.ts +197 -0
  134. package/src/scripts/lint_output_slop.ts +223 -0
  135. package/src/scripts/lint_pack_risk_class.ts +79 -0
  136. package/src/scripts/probe_projection_fidelity.ts +7 -1
  137. package/src/scripts/schemas/agent-settings.schema.json +23 -0
  138. package/src/scripts/schemas/skill.schema.json +5 -0
  139. package/src/scripts/skill_linter.ts +3 -0
  140. package/dist/ui/assets/index-CoQo90sz.js.map +0 -1
@@ -0,0 +1,56 @@
1
+ # Domain-pack architecture — a retrospective observation (NOT a design driver)
2
+
3
+ > **Status: retrospective hypothesis, N=1.** This documents the sequence the
4
+ > **legal** pack happened to follow. It is **not** a rule and **not** a template
5
+ > that future packs must fit. Validate it against a *second* domain before
6
+ > promoting any of it to a rule or building scaffolding tooling — per
7
+ > `domain-adoption-policy` and the `domain-pack-extraction-when-triggered` (N=2)
8
+ > roadmap. Designing a new pack to fit this speculative pattern would invert the
9
+ > lever: build the domain correctly on its own legs, then observe whether the
10
+ > pattern recurred.
11
+
12
+ ## The sequence legal followed
13
+
14
+ 1. **Safety floor first** — a domain `*-safety-floor` rule (Iron-Law-shaped,
15
+ ~100 lines) before any drafting skill. A drafting skill shipped before its
16
+ floor is the exact liability the floor prevents.
17
+ 2. **Enforcement teeth** — the floor's machine-checkable elements become a
18
+ deterministic linter (`lint_legal_pack`) wired into CI. Prompt rules are not
19
+ governance; lint rules are. This is the differentiator vs prompt-only suites.
20
+ 3. **Eval = regression harness, not a correctness oracle** — self-labeled
21
+ fixtures in the maintainer's genuine-competence sub-domain; the *objective*
22
+ eval (attorney-validated gold set, inter-annotator ≥0.7) is a separate,
23
+ demand-and-funding-gated track. See `domain-eval-anti-pattern.md`.
24
+ 4. **Skills = procedure + output template only** — no default domain positions;
25
+ positions live in a practice profile, so one skill set behaves
26
+ team-specifically and the pack stays portable.
27
+ 5. **Practice profile (the keystone)** — a cold-start interview writing a
28
+ plain-prose profile into `.agent-settings.yml` / the setup wizard; skills read
29
+ it and halt on unresolved placeholders.
30
+ 6. **Deferred by default** — personas, scheduled watchers, installer hubs, and
31
+ broader scope are recorded as rejected/gated, not built, until evidence pulls
32
+ them in.
33
+
34
+ ## Why it is NOT yet a rule
35
+
36
+ - **N=1.** Finance might need real-time-data evals; security might need red-team
37
+ evals; neither looks like "clause extraction + self-labeled fixtures." The
38
+ shape that fit legal may not fit them.
39
+ - **Premature tooling is the maintainer's enemy.** No `domain-pack:new`
40
+ scaffolding ships from this observation. Extraction waits for N=2, where a
41
+ second domain either confirms the sequence (promote to a rule) or diverges
42
+ (document the delta, keep both bespoke).
43
+
44
+ ## What to do at N=2
45
+
46
+ Build the second domain on its own merits. *Then* compare: which steps generalised,
47
+ which broke. If the sequence held twice, promote it to a rule and consider
48
+ scaffolding. If it diverged, this note records why a one-size pattern was wrong —
49
+ itself a useful result.
50
+
51
+ ## See also
52
+
53
+ - [Capability Boundary Matrix](../../contracts/capability-boundary.md) — per-pack safety posture (default-install / consent / council / disclaimer / eval / risk_class).
54
+ - [ADR-107 — Legal domain-pack adoption](../../decisions/ADR-107-legal-domain-pack-adoption.md)
55
+ - `domain-adoption-policy` (rule) — the three gates before opening any domain.
56
+ - `domain-eval-anti-pattern.md` — why the legal eval is a regression harness, not an objective gate.
@@ -0,0 +1,17 @@
1
+ {
2
+ "description": "Routing eval for design-antipatterns guideline: should an agent pull this catalog for a given task?",
3
+ "should_pull": [
4
+ "Design a landing page for a new SaaS product",
5
+ "Review this UI mockup for AI-slop patterns",
6
+ "Create a feature card section with icons and descriptions",
7
+ "Generate a hero section with a big metric and supporting stats",
8
+ "The design looks generic — how do I make it more distinctive?"
9
+ ],
10
+ "should_not_pull": [
11
+ "Fix the authentication bug in the login controller",
12
+ "Write a migration to add the user_id column to the orders table",
13
+ "Set up the CI pipeline for the monorepo",
14
+ "Draft a customer email reply for a billing issue",
15
+ "Analyze the test coverage for the payment module"
16
+ ]
17
+ }
@@ -0,0 +1,170 @@
1
+ # Design Anti-Patterns — AI-Slop Catalog
2
+
3
+ > Lazy-loaded reference guideline. Pull this before proposing, generating, or
4
+ > reviewing any UI. Used by `design-intelligence`, `fe-design`, `design-review`,
5
+ > `existing-ui-audit`.
6
+
7
+ This catalog enumerates patterns that make AI-generated UI **recognizably
8
+ AI-generated**. Every entry carries a concrete override condition — the goal is
9
+ not prohibition but deliberateness. A pattern on this list used *knowingly* for
10
+ a specific brief is a design decision; used *reflexively* from a default, it is
11
+ slop.
12
+
13
+ **How to use:** Before generating UI, scan the applicable category. Flag any
14
+ pattern you were about to reach for. Either (a) choose a different approach, or
15
+ (b) invoke the override condition and state the reason explicitly in the brief.
16
+
17
+ **Agent self-check principle:** These are guidance rules, not linter rules. The
18
+ agent reads the brief, checks its first impulse against this catalog, and adjusts
19
+ or overrides. The enforceable subset (contrast ratio, font-size, heading
20
+ hierarchy, reduced-motion, focus indicator) is in `lint_design_quality`
21
+ (Phase 5).
22
+
23
+ **Who owns what (boundary — avoid drift):**
24
+
25
+ | Layer | Owns | Artifact |
26
+ |---|---|---|
27
+ | **Guidance** | Subjective taste — Visual / Typography / Color / Layout / Copy patterns, override judgment, the originality self-test | this catalog |
28
+ | **Enforcement** | Objective floors — Q1–Q6 (WCAG contrast, font-size, line-length, reduced-motion, heading hierarchy, focus indicator) as exit-code-2 CI | `lint_design_quality` |
29
+ | **Audit method** | HOW to test WCAG (keyboard nav, ARIA, screen-reader procedures) | `accessibility-auditor` |
30
+ | **Stack manifestation** | Concrete Tailwind class / hex bans, shadcn defaults | `tailwind-engineer`, `react-shadcn-ui` (per `framework-neutrality-in-generic-skills`) |
31
+ | **Register** | Brand mode vs product mode — which patterns apply | `docs/guidelines/design-modes.md` |
32
+
33
+ This catalog is the canonical *index*; it states the pattern stack-agnostically.
34
+ The stack-specific bans live in the apply skills and link back here by entry ID.
35
+ The objective floors are cited from the linter, never re-eyeballed by an agent.
36
+
37
+ ---
38
+
39
+ ## Visual
40
+
41
+ | # | Pattern | Why it reads as AI-generated | Override condition |
42
+ |---|---|---|---|
43
+ | V1 | Side-stripe `border-left` or `border-right` > 1px as a colored accent | The single most recognizable AI-UI signature; every scaffold-default card uses it | Brand token explicitly defines a stripe; document the decision in the design brief |
44
+ | V2 | Glassmorphism as decoration (`backdrop-blur` + `bg-white/10`) with no functional depth hierarchy | Model defaults to it for "premium feel"; result looks like 2021 Material You clip-art | Element genuinely sits above a complex, blurred background layer; use sparingly and only for top-level floating surfaces |
45
+ | V3 | Ghost card: `border: 1px solid` + box-shadow ≥ 16px spread together | The combination creates visual noise — the ghost card signals no confident decision about depth | Choose either border OR shadow to indicate depth; never both on the same surface |
46
+ | V4 | Over-rounded small cards or badges: `border-radius` > 16px on elements < 200px wide | Excessive rounding on small surfaces looks toy-ish; standard cap is 12–16px | Pill shape (`border-radius: 9999px`) is intentional on single-line tags/chips only |
47
+ | V5 | Hand-drawn or illustrated SVG icons mixed with crisp icon-system icons | Visual register collision; instantly reads as "generated asset" | Intentional illustrative section (hero illustration, empty-state art); isolate from the icon system |
48
+ | V6 | Repeating diagonal stripes as a background texture | A cliché background default; reads as generated CSS art | Brand explicitly uses pattern backgrounds (e.g., a textile brand); document the stripe definition |
49
+ | V7 | Nested cards: a card inside a card inside a card | Depth hierarchy collapses; user cannot parse elevation intent | A truly three-level hierarchy (e.g., project → board → card); ensure each level has distinct visual weight |
50
+
51
+ ---
52
+
53
+ ## Typography
54
+
55
+ | # | Pattern | Why it reads as AI-generated | Override condition |
56
+ |---|---|---|---|
57
+ | T1 | Flat type hierarchy: body and headings use the same optical weight and nearly the same size | Type hierarchy is invisible; user cannot scan the page | Deliberately minimal aesthetic where all text is body-weight; must be an explicit brand decision |
58
+ | T2 | Oversized italic serif as the primary hero headline | The "AI startup landing page" template; seen on ~60% of AI-generated marketing pages | Brand adopts editorial-magazine aesthetic with a documented italic serif rationale |
59
+ | T3 | Icon tile (small rounded-square container) above heading | The universal AI feature-card template; reads as scaffold | Listed features genuinely benefit from visual-icon-then-title affordance AND the icons are custom, not library defaults |
60
+ | T4 | Eyebrow / ALL-CAPS label above every section heading | Overuse collapses the emphasis; maximum is 1 eyebrow per 3 sections (countable: grep tracking classes) | Used for genuine section-type differentiation with meaningful vocabulary (not just "FEATURES", "PRICING") |
61
+ | T5 | Repeated section kickers ("Our mission", "What we offer", "Why choose us") | Filler vocabulary; every AI-generated page has the same three section titles | Every kicker is substantive and uses brand-specific vocabulary, not generic marketing speak |
62
+ | T6 | Crushed letter-spacing on display text (`letter-spacing` < −0.04em) | Below −0.04em glyphs collide optically; reads as "designer-ish effect" with no grounding | Intentional tight display treatment with a documented minimum floor; verify at the actual render size |
63
+ | T7 | Overused fonts without a brand reason: Inter, Roboto, DM Sans, Geist, Space Grotesk, Instrument Serif | These are the default AI-coding-tool font picks; every generated UI uses one of them | Brand has explicitly adopted one of these AND there is a documented reason (e.g., Inter for its variable metrics in a data-dense dashboard) |
64
+ | T8 | Single typeface for everything | Missed typographic contrast opportunity; all-Inter reads as "I did not think about fonts" | Intentional mono-typeface aesthetic (e.g., terminal-inspired); must be stated in the brief |
65
+ | T9 | All-caps body paragraphs or field labels | Reduces legibility below WCAG AA for sustained reading; reads as flair over function | Short UI labels (e.g., button text in a brutalist layout); never for body paragraphs |
66
+ | T10 | Wide letter-spacing on body text (`letter-spacing` > 0.05em) | Reduces readability for sustained reading; reserved for display use | Display text (headlines, pull quotes) where intentional tracking is a brand element |
67
+
68
+ ---
69
+
70
+ ## Color
71
+
72
+ | # | Pattern | Why it reads as AI-generated | Override condition |
73
+ |---|---|---|---|
74
+ | C1 | Purple/violet + cyan-on-dark palette as the primary scheme | The most recognizable AI-UI color combination in 2024–2026; instantly signals "generated" | Brand color system genuinely defines a violet primary; must come from `brand-to-tokens`, not from model defaults |
75
+ | C2 | Gradient text via `background-clip: text` as a primary accent | Overused to the point of invisibility; also has rendering edge cases on some platforms | Headline treatment in a brand that explicitly uses gradient identity (e.g., a product whose logo is a gradient) |
76
+ | C3 | Glowing colored accents on dark mode (bright neon `box-shadow` or `text-shadow`) | Looks like a 2020 gaming UI; reads as an AI attempt at "moody" | Brand explicitly defines neon accents with a documented usage rule (e.g., error or alert states in a security product) |
77
+ | C4 | Gray text on colored background without WCAG AA check | Muted gray chosen for "elegance" often fails 4.5:1 contrast; the failure is invisible until audited | Any use — always verify the contrast ratio; if it fails, either darken the text or lighten/darken the background |
78
+ | C5 | Cream/sand body background (OKLCH L 0.84–0.97, C < 0.06) with brass/clay/oxblood accents | The 2025 "premium-consumer" AI palette; every generated "sophisticated" product uses this exact combination | Brand has an explicit warm-neutral design language documented in `brand-to-tokens`; the palette is first-party, not a default reach |
79
+
80
+ ---
81
+
82
+ ## Layout
83
+
84
+ | # | Pattern | Why it reads as AI-generated | Override condition |
85
+ |---|---|---|---|
86
+ | L1 | Hero metric template: giant number, small label, 3–4 stats in a row, gradient | The default SaaS dashboard hero; appears on ~70% of AI-generated dashboard screens | Data storytelling genuinely requires a primary metric with supporting context; must vary the arrangement |
87
+ | L2 | Three identical feature cards in a grid with the same visual weight | The scaffold-default; no visual rhythm, no hierarchy among features | Product genuinely has three equally weighted features; must still vary padding, or use a different composition |
88
+ | L3 | Monotonous spacing: one spacing value (usually 24px) used for everything | Spacing is rhythm; uniform spacing collapses the hierarchy of proximity | Intentional grid where every element has equal weight; must document the grid definition |
89
+ | L4 | Numbered section markers (01 / 02 / 03) as a primary section-order device | Universal AI-generated marketing page tell; seen on virtually every generated landing page | A genuinely numbered process or sequenced guide where the step number carries meaning beyond decoration |
90
+ | L5 | Line length > 80ch in body copy without column constraint | Reduces readability; WCAG recommends 45–75 characters; beyond 80 the eye struggles to track | Data-dense dashboards where column width is driven by tabular data, not narrative text |
91
+ | L6 | `position: absolute` dropdown inside `overflow: hidden` container | Dropdown clips; a common AI-generated layout bug | Refactor: use `<dialog>`, the Popover API, or `position: fixed` / portal to escape the stacking context |
92
+ | L7 | Content that overflows its container | Text truncation or reflow failures at non-default viewport widths; reads as untested | Never acceptable in production output; test at 320px, 768px, 1280px minimally |
93
+ | L8 | Z-index values of 99, 999, 9999 without a semantic z-index scale | Magic numbers; the first time two elements compete, the scale breaks | Establish a named semantic z-index scale (`--z-modal: 400`, `--z-toast: 500`, etc.) and use it |
94
+
95
+ ---
96
+
97
+ ## Motion
98
+
99
+ | # | Pattern | Why it reads as AI-generated | Override condition |
100
+ |---|---|---|---|
101
+ | M1 | Bounce or elastic easing curves on UI elements | Bounce draws attention to the animation itself; UI motion should serve the action, not perform | Intentional playful affordance (game UI, onboarding celebration state); must be brief and non-repeating |
102
+ | M2 | Animating layout properties (width, height, top, left, padding) | Triggers browser layout recalculation; janky on mid-range devices; always solvable with `transform` | Never — use `transform: scaleX()` for width-like effects, `transform: translateY()` for position |
103
+ | M3 | Animating `<img>` element on hover (scale, filter, transform) | Triggers composite + image decode; often causes content shift | Animate the card's background, border, or shadow instead; leave the image static |
104
+ | M4 | `transition: all` shorthand | Animates every property including layout, color, opacity simultaneously; unpredictable and expensive | Enumerate only the properties that should animate: `transition: transform 200ms ease-out, opacity 200ms` |
105
+ | M5 | Missing `@media (prefers-reduced-motion: reduce)` alternative for any animation | Accessibility violation; vestibular disorders make animated UI unusable | Never acceptable; always add a `prefers-reduced-motion` variant — gentler animation (reduced distance/opacity) is preferred over `display: none` |
106
+
107
+ ---
108
+
109
+ ## Copy
110
+
111
+ | # | Pattern | Why it reads as AI-generated | Override condition |
112
+ |---|---|---|---|
113
+ | CP1 | Em-dash (`—`) overuse | The #1 syntactic LLM signature; appears in AI copy at 3–5× the frequency of human editorial copy; maximum 2 per 500 words | Specific editorial voice that uses em-dashes deliberately; count them before shipping |
114
+ | CP2 | Marketing buzzwords: streamline, empower, supercharge, world-class, enterprise-grade, seamlessly, robust, leverage | These words carry no information; an AI-slop test: replace each with nothing — the sentence still communicates the same thing | No override; if a word can be deleted without loss, delete it |
115
+ | CP3 | Aphoristic manufactured contrast ("We don't do X. We do Y." / "Not just A, but B.") | A generated sentence rhythm that sounds like brand writing but carries no specificity | Aphoristic copy is legitimate when the contrast reveals a genuine product distinction; test by asking whether the Y side says something concrete |
116
+ | CP4 | "Theater" framing — copy that announces what the product does without saying how or why | "The platform for modern teams." communicates nothing; it is content-shaped noise | Every tagline must pass the "so what" test: can a skeptic follow it with "but how?" and get a concrete answer? |
117
+
118
+ ---
119
+
120
+ ## Quality floors — measurable thresholds
121
+
122
+ These are not stylistic — they are objective quality failures detectable without
123
+ aesthetic judgment. The `lint_design_quality` CI linter enforces a subset of
124
+ these. The rest are agent self-checks.
125
+
126
+ | # | Threshold | Measurement | CI-enforced? |
127
+ |---|---|---|---|
128
+ | Q1 | Text contrast ≥ 4.5:1 normal / ≥ 3:1 large text (WCAG AA) | `contrastRatio(text, bg) < threshold` | Yes (`lint_design_quality`) |
129
+ | Q2 | Body `font-size` ≥ 14px (floor); ≥ 16px strongly preferred | Computed `font-size` on `p`, `li`, `td` | Yes |
130
+ | Q3 | Line length ≤ 75 characters (prose) | Character count before soft wrap | Yes |
131
+ | Q4 | All `@keyframes` / `animation` have a `prefers-reduced-motion` alternative | CSS `@media` check | Yes |
132
+ | Q5 | Heading levels not skipped (h1→h3 direct, not h1→h4) | DOM heading sequence | Yes |
133
+ | Q6 | All interactive elements have a `:focus-visible` indicator | CSS rule check | Yes |
134
+ | Q7 | Display `letter-spacing` floor: ≥ −0.04em (tighter reads cramped) | Computed tracking | Agent self-check |
135
+ | Q8 | `line-height` ≥ 1.3 on body text | Computed `line-height` | Agent self-check |
136
+ | Q9 | Small-card `border-radius` cap: 12–16px (not 24px+) | Computed `border-radius` on elements < 200px | Agent self-check |
137
+ | Q10 | Body background: avoid OKLCH L 0.84–0.97, C < 0.06 (cream/sand) unless brand-defined | Color space calculation | Agent self-check |
138
+ | Q11 | Padding floors: ≥ 8px (inline elements), ≥ 16px (card/panel bodies) | Computed padding | Agent self-check |
139
+ | Q12 | Justified text only with CSS hyphenation (`hyphens: auto`) | Presence of `text-align: justify` without `hyphens` | Agent self-check |
140
+
141
+ ---
142
+
143
+ ## The AI-slop originality self-test
144
+
145
+ Before finalizing any UI design, run this two-tier check:
146
+
147
+ 1. **Category test:** Could someone guess the aesthetic from the product
148
+ category alone? (e.g., "SaaS → dark mode + purple gradient" /
149
+ "fintech → navy + gold" / "health → teal + rounded sans"). If yes,
150
+ rework the concept.
151
+
152
+ 2. **Anti-reference test:** Could someone still guess it after knowing the
153
+ category AND having seen 3 references you explicitly avoided? If yes,
154
+ dig deeper. A direction that is merely "not the worst cliché" is still
155
+ a cliché.
156
+
157
+ The bar: a visitor should ask "how was this made?", not "which AI made this?"
158
+
159
+ ---
160
+
161
+ ## See also
162
+
163
+ - `design-intelligence` — corpus-grounded style/color/typography selection
164
+ - `fe-design` — stack-agnostic heuristics (form, table, responsive, a11y)
165
+ - `design-review` — structured UI/UX review methodology
166
+ - `existing-ui-audit` — mandatory pre-step: inventory before designing
167
+ - `motion-choreographer` — animation heuristics (should-it, which-easing, how-much)
168
+ - `typography-system` — modular-scale construction and pairing
169
+ - `accessibility-auditor` — WCAG audit method
170
+ - `brand-to-tokens` — first-party brand token extraction (the legitimate override source for most anti-patterns above)
@@ -0,0 +1,97 @@
1
+ # Design Modes — Brand vs Product
2
+
3
+ > Reference doc. Pull this when deciding which design skills to prioritize
4
+ > or when the brief is ambiguous about the design register.
5
+
6
+ ## The two registers
7
+
8
+ Every design task operates in one of two registers. Getting the register
9
+ wrong is the root cause of most AI-generated design failures:
10
+
11
+ | | Brand mode | Product mode |
12
+ |---|---|---|
13
+ | **Core thesis** | The impression IS the product | Design serves the task |
14
+ | **Primary failure** | Flatness / genericness — looks like every other AI startup | Strangeness without purpose — "clever" choices that obscure the tool |
15
+ | **The user's question** | "How was this made?" (genuine curiosity) | "Where do I click?" (the tool disappears into the task) |
16
+ | **Key skill cluster** | `brand-identity`, `iconography`, `fe-design § Aesthetic direction`, `design-intelligence` | `accessibility-auditor`, `ui-component-architect`, `fe-design § Table/Form Design` |
17
+ | **Typography strategy** | Distinctive pairing — two contrasting families, deliberate tracking | One reliable family — Inter or equivalent; predictable hierarchy |
18
+ | **Color strategy** | Brand identity — often unexpected; the palette IS the differentiator | Semantic function — primary/danger/success/neutral; predictable meaning |
19
+ | **Motion strategy** | Expressive — motion reinforces the brand's personality | Utilitarian — motion confirms state changes; nothing decorative |
20
+ | **Spacing strategy** | Breathing room; generous whitespace as a brand signal | Dense/efficient; optimize for information density |
21
+ | **Success criterion** | Originality test: a skeptic can't guess "which AI made this?" | Earned familiarity: the tool disappears; users focus on their task |
22
+
23
+ ## How to determine the register
24
+
25
+ Ask: **What is the output of this UI being used for?**
26
+
27
+ - A consumer-facing surface where the FIRST impression determines whether the
28
+ user trusts/buys → **Brand mode**. The product has 3 seconds; every pixel
29
+ contributes to the brand's identity.
30
+
31
+ - An internal tool, dashboard, admin panel, or workflow-critical surface where
32
+ users return dozens of times per day → **Product mode**. Strangeness wastes
33
+ their time; predictability builds trust.
34
+
35
+ - A marketing landing page → **Brand mode**. It has one job: create desire.
36
+
37
+ - A data entry form → **Product mode**. It has one job: accept correct data.
38
+
39
+ **Ambiguous cases:** many products have both (a brand-heavy landing page +
40
+ a product-mode dashboard). The register applies per-surface, not per-product.
41
+ When unclear: ask — *"Is the user here to be impressed, or to accomplish a
42
+ task?"*
43
+
44
+ ## Brand-mode failure modes
45
+
46
+ - **Genericness:** Choosing the safe AI-slop palette (cream + brass, purple/violet gradient, three equal cards). The product is invisible in its category. Cross-check with `docs/guidelines/design-antipatterns.md` § Color and Visual.
47
+ - **Inconsistency:** Brand direction picked for the hero, abandoned for the body. The page reads as two different products.
48
+ - **Aesthetics-without-function:** Beautiful but confusing navigation, stunning hero with no CTA clarity.
49
+
50
+ ## Product-mode failure modes
51
+
52
+ - **Strangeness-without-purpose:** A clever typographic choice that makes the CTA harder to scan. A gradient background on a data table. An animated page transition in an admin panel.
53
+ - **Premature originality:** Reinventing a standard UI pattern (data table, form validation, dropdown) when the standard is what users expect.
54
+ - **Over-engineering:** Five different card elevations in a dashboard that needs two.
55
+
56
+ ## The AI-slop originality self-test (applies to brand mode primarily)
57
+
58
+ Run BOTH tiers before approving a brand-mode design direction:
59
+
60
+ **Tier 1 — Category test:**
61
+ Would a designer seeing 20 AI-generated [product category] UIs recognize this
62
+ aesthetic as part of that category's default? (e.g., "SaaS → dark mode + purple
63
+ gradient"; "health app → teal + rounded sans serif + white space").
64
+ - If YES: rework the concept. The design is invisible in its category.
65
+ - If NO: proceed to Tier 2.
66
+
67
+ **Tier 2 — Anti-reference test:**
68
+ Given the category AND three explicit aesthetics you've avoided — could a
69
+ skeptic still guess the direction? (e.g., "fintech that's not navy-and-gold,
70
+ not minimal white, not brutalist → everyone picks terminal dark").
71
+ - If YES: dig deeper. "Avoiding the worst cliché" is not differentiation.
72
+ - If NO: the direction is genuinely distinctive.
73
+
74
+ **The bar:** a visitor should ask "how was this made?" not "which AI made this?"
75
+
76
+ ## Routing to skills by mode
77
+
78
+ **Brand mode brief:**
79
+ 1. `design-intelligence` (grounded style/palette/typography selection — run the corpus first)
80
+ 2. `brand-identity` (archetype → token system)
81
+ 3. `iconography` (icon system selection for brand expression)
82
+ 4. `fe-design § Aesthetic direction` (direction → composition → typography → color)
83
+
84
+ **Product mode brief:**
85
+ 1. `existing-ui-audit` (mandatory — inventory first)
86
+ 2. `accessibility-auditor` (WCAG compliance from the start)
87
+ 3. `ui-component-architect` (reuse existing primitives)
88
+ 4. `fe-design § Component Architecture, Form Design, Table Design` (standard patterns)
89
+
90
+ **Both modes:** `design-antipatterns` (always pull), `design-review` (with anti-slop check)
91
+
92
+ ## See also
93
+
94
+ - `docs/guidelines/design-antipatterns.md` — the slop-tell catalog; brand mode especially needs this
95
+ - `brand-source-of-truth` — when a registered brand profile is present, it governs
96
+ - `brand-consistency` — validates emitted artifacts against the brand profile
97
+ - `design-system-capture` — DESIGN.md/PRODUCT.md capture the mode's decisions for cross-task consistency
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
- "version": "7.0.2",
3
+ "version": "7.2.0",
4
4
  "description": "Universal AI Agent OS — audited skills, governance rules, commands, and templates for AI coding tools (Claude Code, Cursor, Windsurf, Copilot).",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -84,6 +84,24 @@ rule_loading_tier: __RULE_LOADING_TIER__
84
84
  lean_projection:
85
85
  mode: eager-all
86
86
 
87
+ # --- Token-rich skills governance ---
88
+ #
89
+ # Skills marked `token_budget_class: rich` in their frontmatter are exempt
90
+ # from telegraph-speak condensation and thin-projector trimming. They load
91
+ # their full content (examples, tables, code blocks) to maximize design-output
92
+ # quality. This setting controls whether that extra spend is allowed globally.
93
+ #
94
+ # Values:
95
+ # on — rich skills load in full (default; recommended for design-intensive workflows)
96
+ # off — rich skills fall back to standard condensed behavior
97
+ # ask — before loading a rich skill, the agent surfaces an estimated token
98
+ # delta (≈ file size in chars / 4, reported in tokens not dollars) and
99
+ # asks the user once; the answer is cached for the session
100
+ #
101
+ # Configurable in the browser setup wizard (Setup → Skills → Token budget).
102
+ tokens:
103
+ rich_skills: on
104
+
87
105
  # --- Cost tracking + budget enforcement ---
88
106
  #
89
107
  # USD budgets evaluated against `agents/cost-tracking/sessions.jsonl` by
@@ -393,12 +411,81 @@ quality:
393
411
  # themselves (default — saves agent runtime and tokens)
394
412
  wait_for_remote_ci: false
395
413
 
414
+ # --- Design fidelity ---
415
+ #
416
+ # Controls how strictly the agent must follow a user-provided, finished
417
+ # design — a prototype, mockup, screenshot, or design-system file. Consumed
418
+ # by the `design-fidelity` rule. The provided design is the spec, not a
419
+ # starting point for the agent's own taste.
420
+ design:
421
+ # strict | structural | hard-floor (default: strict)
422
+ #
423
+ # strict = build it 1:1. EVERY visible deviation (font, control type,
424
+ # component, layout, spacing, colour, an omitted/added element)
425
+ # needs explicit confirmation. A "better" idea is surfaced as a
426
+ # numbered option, never executed.
427
+ # structural = structure is locked (fonts, control types, component set,
428
+ # layout, no omissions still need confirmation). Where the spec
429
+ # is genuinely silent (hover / empty / error states), the agent
430
+ # may fill the gap in the spec's style and MUST state the
431
+ # assumption.
432
+ # hard-floor = any deviation is a Hard-Floor action (never autonomous; no
433
+ # autonomy setting, roadmap, or standing instruction lifts it).
434
+ fidelity_mode: strict
435
+
396
436
  # --- Subagent orchestration ---
397
437
  #
398
- # Controls model selection and parallelism for subagent-based workflows
399
- # (/do-and-judge, /do-in-steps, /judge). Empty values fall back to the
400
- # runtime defaults described in .augment/contexts/subagent-configuration.md.
438
+ # Controls model selection, parallelism, and AUTOMATIC orchestration for
439
+ # subagent-based workflows (/do-and-judge, /do-in-steps, /judge, and the
440
+ # auto-dispatch layer). Empty values fall back to the runtime defaults
441
+ # described in .augment/contexts/subagent-configuration.md and
442
+ # .augment/contexts/execution/auto-orchestration-activation.md.
401
443
  subagents:
444
+ # Global master switch for the whole subagent layer.
445
+ # true (default) = the layer is available; false = fully disabled, the
446
+ # canonical kill-switch (no auto-dispatch, no model routing, in-session only).
447
+ enabled: true
448
+
449
+ # Automatic-dispatch mode: off | ask | on
450
+ #
451
+ # off = never auto-dispatch; subagents only via an explicit command.
452
+ # ask = classify the task; when delegable, ask once before dispatching.
453
+ # on = auto-dispatch delegable tasks without asking (surface the choice
454
+ # in one line).
455
+ #
456
+ # Initial SHIPPED default is `ask` on hosts whose capability manifest reports
457
+ # `subagent_spawn: true`, and `off` on hosts without a subagent primitive.
458
+ # The shipped default flips toward `on` (host-gated) only behind the Phase-6
459
+ # benchmark gate of road-to-auto-subagent-orchestration.md — never on an
460
+ # unmeasured claim. Auto-dispatch is also a no-op wherever the host manifest
461
+ # reports `subagent_spawn: false`, regardless of this value.
462
+ auto: ask
463
+
464
+ # Route delegable sub-tasks to the lowest-capable model tier (cost + speed
465
+ # via model downshift). true (default) = downshift per declared model_tier;
466
+ # false = every subagent runs on the session tier.
467
+ downshift: true
468
+
469
+ # Prefer a separate-quota-pool model for delegable sub-tasks WHERE the host
470
+ # manifest reports `separate_quota_pool: true` (e.g. a subscription whose
471
+ # Sonnet allowance is distinct from Opus). Optional bonus only — behaviour is
472
+ # identical (minus the quota win) where unsupported. Never load-bearing.
473
+ quota_arbitrage: true
474
+
475
+ # Optional per-tier model map for downshift routing. Empty value = use the
476
+ # tier's runtime default (see model-recommendations.md). Keys are the
477
+ # vendor-neutral capability bands.
478
+ model_map:
479
+ lite: ""
480
+ medium: ""
481
+ high: ""
482
+
483
+ # Optional host-capability override (see
484
+ # .augment/contexts/execution/host-capability-manifest.md). Any field set
485
+ # here wins; any field omitted falls back to the all-false safe default.
486
+ # Leave empty to let the agent resolve the manifest from host knowledge.
487
+ host_capabilities: {}
488
+
402
489
  # Model for implementer subagents (empty = same tier as the session model)
403
490
  implementer_model: ""
404
491
 
@@ -716,6 +803,19 @@ update_check:
716
803
  explain:
717
804
  enable_last: true
718
805
 
806
+ # ─── legal-review-prep consent gate ──────────────────────────────────────────
807
+ # The legal-review-prep pack is high-risk (EU/DE legal review-prep, NOT legal
808
+ # advice). It stays inactive until you acknowledge it is not legal advice — set
809
+ # by the setup wizard's consent checkbox, or here by hand. The legal-safety-floor
810
+ # rule refuses every legal-review-prep skill until `acknowledged: true`.
811
+ legal_review_prep:
812
+ acknowledged: false
813
+ consented_at: ""
814
+ # Gate legal work-product behind a multi-model council / deep-research pass
815
+ # (defense-in-depth + audit trail; fail-closed). Off lets single-model legal
816
+ # output through — not recommended for this high-risk pack.
817
+ require_council: true
818
+
719
819
  # ─── secrets ────────────────────────────────────────────────────────────────
720
820
  # Local-only secret material. This whole file is gitignored, so the key never
721
821
  # enters the tracked tree.
@@ -167,6 +167,7 @@
167
167
  workspaces: [finance, founder]
168
168
  trust_level_default: professional
169
169
  domain: finance
170
+ risk_class: medium # advisory (finance-safety-floor): not-financial-advice disclaimer
170
171
  size_class: medium
171
172
  onboarding:
172
173
  first_win_doc: FIRST_WIN.md
@@ -180,6 +181,7 @@
180
181
  requires: [finance-basic]
181
182
  trust_level_default: core
182
183
  domain: finance
184
+ risk_class: medium # advisory (finance-safety-floor)
183
185
  size_class: medium
184
186
 
185
187
  - id: gtm-sales
@@ -223,6 +225,7 @@
223
225
  trust_level_default: core
224
226
  domain: founder
225
227
  size_class: medium
228
+ risk_class: medium # advisory (strategy-safety-floor)
226
229
  onboarding:
227
230
  first_win_doc: FIRST_WIN.md
228
231
  example_workflow: vision-articulation
@@ -240,6 +243,27 @@
240
243
  workspaces: [construction]
241
244
  trust_level_default: professional
242
245
 
246
+ - id: legal-review-prep
247
+ label: Legal Review Prep
248
+ description: "NOT LEGAL ADVICE — a research/drafting aid to PREPARE for attorney review, not a substitute for a lawyer. EU/DE-scoped contract/NDA/DPA review and triage, procedure-only (no default legal positions); general information + templates only, never individual-case examination; every output a draft for attorney review. Opt-in + council-gated. See LEGAL_NOTICE.md."
249
+ workspaces: [legal-review-prep]
250
+ trust_level_default: experimental
251
+ surface_tier: lab
252
+ domain: legal
253
+ size_class: medium
254
+ # High-risk posture (road-to-legal-review-prep Phase 4). Documentation-first;
255
+ # enforcement lives in the legal-safety-floor rule + consent gate + lint.
256
+ risk_class: high
257
+ risk_profile: rdg_regulated_eu_de
258
+ requires_explicit_consent: true
259
+ requires_council: true
260
+ default_install: false
261
+ promotion_gate: attorney_framing_review
262
+ onboarding:
263
+ first_win_doc: FIRST_WIN.md
264
+ example_workflow: dpa-review
265
+ time_to_first_value_minutes: 8
266
+
243
267
  - id: ai-video
244
268
  label: AI Video
245
269
  description: AI video pipeline.
@@ -64,6 +64,13 @@
64
64
  default_packs: [construction]
65
65
  optional_packs: []
66
66
 
67
+ - id: legal-review-prep
68
+ label: Legal Review Prep
69
+ description: In-house legal review-prep — EU/DE-scoped contract/NDA/DPA review and triage to PREPARE for attorney review. Not legal advice; opt-in + council-gated.
70
+ example_roles: [In-house Counsel, DPO, Legal Ops]
71
+ default_packs: [legal-review-prep]
72
+ optional_packs: []
73
+
67
74
  - id: agent-config-maintainer
68
75
  label: Maintainer
69
76
  description: Skills/rules/commands that maintain this package.
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Auto-dispatch classification (v1 — deterministic).
3
+ *
4
+ * Pure, no-I/O encoding of the rule-based classifier described in
5
+ * `src/agent-src/contexts/execution/auto-dispatch-classification.md`.
6
+ *
7
+ * Decides whether a task is delegable to subagents and which
8
+ * `subagent-orchestration` mode fits — with NO per-turn LLM meta-call.
9
+ *
10
+ * Contract highlights:
11
+ * - A task is delegable only on an enumerated structural signal.
12
+ * - Trivial tasks below the size floor never delegate.
13
+ * - Ambiguity → `ask` (when `auto == 'ask'`) or in-session, never speculative
14
+ * spawn.
15
+ * - The activation gate (`enabled`, `auto != off`, `subagent_spawn`) runs
16
+ * first; any failure short-circuits to in-session.
17
+ */
18
+
19
+ /** Minimum task-size estimate (exclusive) below which a task never delegates. */
20
+ export const SIZE_FLOOR = 1;
21
+
22
+ export type AutoMode = 'off' | 'ask' | 'on';
23
+ export type DispatchMode = 'do-in-steps' | 'do-in-parallel';
24
+ export type DispatchAction = 'dispatch' | 'ask' | 'in-session';
25
+
26
+ /** Task descriptor — structural signals only, no task body. */
27
+ export interface TaskSignals {
28
+ /** Frontmatter `parallelizable:` value of the skill/command in play, if any. */
29
+ parallelizable?: 'steps' | 'files' | 'independent' | null;
30
+ /** Task is an explicit ordered plan (numbered steps / phase / checklist). */
31
+ ordered_plan?: boolean;
32
+ /** Count of independent same-shape targets (e.g. 5 files to review). */
33
+ independent_slices?: number;
34
+ /** Orchestrator's pre-dispatch size estimate (abstract units). */
35
+ size_estimate: number;
36
+ }
37
+
38
+ /** Activation inputs resolved from settings + the host-capability manifest. */
39
+ export interface ActivationInputs {
40
+ enabled: boolean;
41
+ auto: AutoMode;
42
+ subagent_spawn: boolean;
43
+ }
44
+
45
+ export interface Classification {
46
+ delegable: boolean;
47
+ action: DispatchAction;
48
+ mode: DispatchMode | null;
49
+ reason: string;
50
+ }
51
+
52
+ function inSession(reason: string): Classification {
53
+ return { delegable: false, action: 'in-session', mode: null, reason };
54
+ }
55
+
56
+ /**
57
+ * Classify a task for auto-dispatch. Activation gate first, then the
58
+ * deterministic delegable-signal rules.
59
+ */
60
+ export function classifyTask(signals: TaskSignals, activation: ActivationInputs): Classification {
61
+ // ── Activation gate — any failure short-circuits to in-session ──
62
+ if (!activation.enabled) return inSession('subagents.enabled is false');
63
+ if (activation.auto === 'off') return inSession('subagents.auto is off');
64
+ if (!activation.subagent_spawn) return inSession('host has no subagent_spawn primitive');
65
+
66
+ // ── Size floor — trivial tasks never delegate ──
67
+ if (!(signals.size_estimate > SIZE_FLOOR)) {
68
+ return inSession(`task below size floor (${signals.size_estimate} <= ${SIZE_FLOOR})`);
69
+ }
70
+
71
+ // ── Delegable-signal rules (enumerated; ambiguity never spawns) ──
72
+ const slices = signals.independent_slices ?? 0;
73
+ let mode: DispatchMode | null = null;
74
+ let reason = '';
75
+
76
+ if (signals.parallelizable === 'steps' || signals.ordered_plan === true) {
77
+ mode = 'do-in-steps';
78
+ reason = signals.parallelizable === 'steps' ? 'declared parallelizable: steps' : 'ordered-plan structure';
79
+ } else if (signals.parallelizable === 'files' || signals.parallelizable === 'independent' || slices >= 2) {
80
+ mode = 'do-in-parallel';
81
+ reason = signals.parallelizable ? `declared parallelizable: ${signals.parallelizable}` : `independent slices (${slices})`;
82
+ }
83
+
84
+ if (mode === null) {
85
+ // No enumerated signal matched → ambiguous. Ask under `ask`, else in-session.
86
+ if (activation.auto === 'ask') {
87
+ return { delegable: false, action: 'ask', mode: null, reason: 'no delegable signal — borderline, ask' };
88
+ }
89
+ return inSession('no enumerated delegable signal matched');
90
+ }
91
+
92
+ // Matched a signal. Dispatch under `on`, ask under `ask`.
93
+ const action: DispatchAction = activation.auto === 'on' ? 'dispatch' : 'ask';
94
+ return { delegable: true, action, mode, reason };
95
+ }