mandrel 1.92.0 → 1.94.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 (144) hide show
  1. package/.agents/agents/acceptance-critic.md +129 -0
  2. package/.agents/agents/retro.md +42 -0
  3. package/.agents/agents/story-worker.md +162 -0
  4. package/.agents/docs/configuration.md +7 -1
  5. package/.agents/docs/execution-reference.md +27 -2
  6. package/.agents/instructions.md +43 -33
  7. package/.agents/personas/engineer.md +26 -112
  8. package/.agents/personas/security-engineer.md +1 -2
  9. package/.agents/rules/git-conventions-reference.md +225 -0
  10. package/.agents/rules/git-conventions.md +25 -200
  11. package/.agents/rules/security-baseline.md +5 -0
  12. package/.agents/rules/testing-standards.md +106 -13
  13. package/.agents/schemas/agentrc.schema.json +31 -1
  14. package/.agents/schemas/lifecycle/slice.end.schema.json +21 -0
  15. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +20 -0
  16. package/.agents/schemas/lifecycle/slice.start.schema.json +17 -0
  17. package/.agents/scripts/acceptance-eval.js +62 -18
  18. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  19. package/.agents/scripts/bookkeeping-reconcile.js +117 -0
  20. package/.agents/scripts/check-context-budget.js +62 -5
  21. package/.agents/scripts/diagnose-friction.js +0 -6
  22. package/.agents/scripts/epic-deliver-prepare.js +272 -10
  23. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +56 -18
  24. package/.agents/scripts/lib/close-validation/gates.js +159 -21
  25. package/.agents/scripts/lib/config/acceptance-eval.js +52 -5
  26. package/.agents/scripts/lib/config/delivery-routing.js +87 -0
  27. package/.agents/scripts/lib/config/explain.js +2 -0
  28. package/.agents/scripts/lib/config-resolver.js +1 -1
  29. package/.agents/scripts/lib/config-settings-schema-delivery.js +37 -3
  30. package/.agents/scripts/lib/config-settings-schema-quality.js +9 -0
  31. package/.agents/scripts/lib/doc-tiers.js +37 -2
  32. package/.agents/scripts/lib/observability/active-story-env.js +111 -2
  33. package/.agents/scripts/lib/observability/hook-heartbeat.js +219 -0
  34. package/.agents/scripts/lib/observability/tool-trace-hook.js +15 -4
  35. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +111 -0
  36. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +32 -4
  37. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +270 -0
  38. package/.agents/scripts/lib/orchestration/ceremony-routing.js +141 -0
  39. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +3 -124
  40. package/.agents/scripts/lib/orchestration/deliver-route.js +173 -0
  41. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +1 -1
  42. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +233 -0
  43. package/.agents/scripts/lib/orchestration/file-assumptions.js +68 -7
  44. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +270 -0
  45. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +83 -2
  46. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +6 -0
  47. package/.agents/scripts/lib/orchestration/plan-context.js +189 -3
  48. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +3 -2
  49. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +99 -0
  50. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +38 -1
  51. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +16 -1
  52. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +1 -0
  53. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +1 -0
  54. package/.agents/scripts/lib/orchestration/ticket-validator.js +19 -2
  55. package/.agents/scripts/lib/provider-factory.js +1 -1
  56. package/.agents/scripts/lib/templates/decomposer-prompts.js +1 -1
  57. package/.agents/scripts/plan-context.js +28 -10
  58. package/.agents/scripts/post-structured-comment.js +38 -0
  59. package/.agents/scripts/slice-phase.js +361 -0
  60. package/.agents/scripts/sync-claude-agents.js +165 -0
  61. package/.agents/scripts/update-ticket-state.js +31 -0
  62. package/.agents/scripts/wave-tick.js +138 -9
  63. package/.agents/skills/core/api-and-interface-design/SKILL.md +5 -3
  64. package/.agents/skills/core/code-review-and-quality/SKILL.md +63 -7
  65. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +1 -1
  66. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +5 -5
  67. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +8 -8
  68. package/.agents/skills/core/epic-plan-premortem/SKILL.md +4 -4
  69. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +26 -56
  70. package/.agents/skills/core/gates-and-baselines/SKILL.md +149 -0
  71. package/.agents/skills/core/idea-refinement/SKILL.md +2 -8
  72. package/.agents/skills/core/qa-coverage-mapping/SKILL.md +7 -7
  73. package/.agents/skills/skills.index.json +11 -381
  74. package/.agents/workflows/deliver.md +47 -4
  75. package/.agents/workflows/helpers/acceptance-self-eval.md +38 -13
  76. package/.agents/workflows/helpers/deliver-epic-reference.md +18 -5
  77. package/.agents/workflows/helpers/deliver-epic-single.md +331 -0
  78. package/.agents/workflows/helpers/deliver-epic.md +51 -8
  79. package/.agents/workflows/helpers/deliver-stories.md +15 -5
  80. package/.agents/workflows/helpers/epic-deliver-story.md +12 -3
  81. package/.agents/workflows/helpers/mandrel-sync-config.md +1 -1
  82. package/.agents/workflows/helpers/plan-epic-reference.md +19 -8
  83. package/.agents/workflows/helpers/plan-epic.md +95 -27
  84. package/.agents/workflows/helpers/scope-triage-gate.md +9 -0
  85. package/.agents/workflows/mandrel-update.md +1 -1
  86. package/.agents/workflows/plan.md +16 -4
  87. package/docs/CHANGELOG.md +23 -0
  88. package/lib/cli/registry.js +95 -0
  89. package/package.json +4 -2
  90. package/.agents/personas/engineer-mobile.md +0 -120
  91. package/.agents/personas/engineer-web.md +0 -111
  92. package/.agents/personas/product.md +0 -94
  93. package/.agents/personas/refactorer.md +0 -113
  94. package/.agents/personas/sre.md +0 -86
  95. package/.agents/personas/ux-designer.md +0 -95
  96. package/.agents/scripts/epic-plan-decompose.js +0 -54
  97. package/.agents/scripts/epic-plan-spec.js +0 -64
  98. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +0 -109
  99. package/.agents/scripts/plan-critics.js +0 -227
  100. package/.agents/skills/core/baseline-refresh/SKILL.md +0 -181
  101. package/.agents/skills/core/ci-cd-and-automation/SKILL.md +0 -274
  102. package/.agents/skills/core/ci-cd-and-automation/examples.md +0 -211
  103. package/.agents/skills/core/code-simplification/SKILL.md +0 -389
  104. package/.agents/skills/core/context-engineering/SKILL.md +0 -309
  105. package/.agents/skills/core/context-engineering/examples.md +0 -58
  106. package/.agents/skills/core/deprecation-and-migration/SKILL.md +0 -250
  107. package/.agents/skills/core/frontend-ui-engineering/SKILL.md +0 -357
  108. package/.agents/skills/core/hydrate-context/SKILL.md +0 -123
  109. package/.agents/skills/core/idea-refinement/examples.md +0 -437
  110. package/.agents/skills/core/idea-refinement/frameworks.md +0 -135
  111. package/.agents/skills/core/incremental-implementation/SKILL.md +0 -271
  112. package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +0 -213
  113. package/.agents/skills/core/knowledge-transfer/SKILL.md +0 -180
  114. package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +0 -117
  115. package/.agents/skills/core/performance-optimization/SKILL.md +0 -314
  116. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +0 -277
  117. package/.agents/skills/core/property-based-testing/SKILL.md +0 -148
  118. package/.agents/skills/core/refactoring-discipline/SKILL.md +0 -111
  119. package/.agents/skills/core/shipping-and-launch/SKILL.md +0 -328
  120. package/.agents/skills/core/spec-driven-development/SKILL.md +0 -252
  121. package/.agents/skills/core/test-driven-development/SKILL.md +0 -475
  122. package/.agents/skills/core/using-agent-skills/SKILL.md +0 -232
  123. package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +0 -31
  124. package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +0 -51
  125. package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +0 -76
  126. package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +0 -31
  127. package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +0 -33
  128. package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +0 -31
  129. package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +0 -51
  130. package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +0 -54
  131. package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +0 -29
  132. package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +0 -30
  133. package/.agents/skills/stack/backend/stripe-integration/SKILL.md +0 -57
  134. package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +0 -9
  135. package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +0 -48
  136. package/.agents/skills/stack/frontend/astro/SKILL.md +0 -62
  137. package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +0 -30
  138. package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +0 -29
  139. package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +0 -50
  140. package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +0 -58
  141. package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +0 -34
  142. package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +0 -51
  143. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +0 -199
  144. package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +0 -68
@@ -1,357 +0,0 @@
1
- ---
2
- name: frontend-ui-engineering
3
- description:
4
- Builds production-quality UIs. Use when building or modifying user-facing
5
- interfaces. Use when creating components, implementing layouts, managing
6
- state, or when the output needs to look and feel production-quality rather
7
- than AI-generated.
8
- ---
9
-
10
- # Frontend UI Engineering
11
-
12
- ## Policy Capsule
13
-
14
- - Build UI that meets WCAG 2.1 AA: every interactive element keyboard-accessible, ARIA labels on icon-only controls, focus moved when content changes, color never the sole indicator of state.
15
- - Adhere to the project's design system — use semantic tokens (`text-primary`, `bg-surface`) and the spacing scale (no arbitrary pixel values, no inline styles).
16
- - Avoid the "AI aesthetic": no default purple/indigo palettes, gratuitous gradients, blanket `rounded-2xl`, oversized padding, or shadow-heavy layering.
17
- - Prefer composition over configuration; keep components focused (split anything past ~200 lines) and separate data-fetching containers from presentation components.
18
- - Choose the simplest state mechanism that works: local `useState` → lifted state → context (read-heavy) → URL state → server-state library → global store; do not prop-drill past three levels.
19
- - Render meaningful loading, empty, and error states for every async surface — skeletons for content (not spinners), and explicit empty-state copy + CTA.
20
- - Design mobile-first and verify at 320 / 768 / 1024 / 1440 px breakpoints before claiming responsive.
21
- - Respect the heading hierarchy (one `h1` per page, no skipped levels) and never re-purpose heading styles for non-heading content.
22
- - Verify accessibility tooling (axe-core / dev-tools warnings) is clean and a screen reader can convey the page structure before marking the work done.
23
-
24
- ## Overview
25
-
26
- Build production-quality user interfaces that are accessible, performant, and
27
- visually polished. The goal is UI that looks like it was built by a design-aware
28
- engineer at a top company — not like it was generated by an AI. This means real
29
- design system adherence, proper accessibility, thoughtful interaction patterns,
30
- and no generic "AI aesthetic."
31
-
32
- ## When to Use
33
-
34
- - Building new UI components or pages
35
- - Modifying existing user-facing interfaces
36
- - Implementing responsive layouts
37
- - Adding interactivity or state management
38
- - Fixing visual or UX issues
39
-
40
- ## Component Architecture
41
-
42
- ### File Structure
43
-
44
- Colocate everything related to a component:
45
-
46
- ```text
47
- src/components/
48
- TaskList/
49
- TaskList.tsx # Component implementation
50
- TaskList.test.tsx # Tests
51
- TaskList.stories.tsx # Storybook stories (if using)
52
- use-task-list.ts # Custom hook (if complex state)
53
- types.ts # Component-specific types (if needed)
54
- ```
55
-
56
- ### Component Patterns
57
-
58
- **Prefer composition over configuration:**
59
-
60
- ```tsx
61
- // Good: Composable
62
- <Card>
63
- <CardHeader>
64
- <CardTitle>Tasks</CardTitle>
65
- </CardHeader>
66
- <CardBody>
67
- <TaskList tasks={tasks} />
68
- </CardBody>
69
- </Card>
70
-
71
- // Avoid: Over-configured
72
- <Card
73
- title="Tasks"
74
- headerVariant="large"
75
- bodyPadding="md"
76
- content={<TaskList tasks={tasks} />}
77
- />
78
- ```
79
-
80
- **Keep components focused:**
81
-
82
- ```tsx
83
- // Good: Does one thing
84
- export function TaskItem({ task, onToggle, onDelete }: TaskItemProps) {
85
- return (
86
- <li className="flex items-center gap-3 p-3">
87
- <Checkbox checked={task.done} onChange={() => onToggle(task.id)} />
88
- <span className={task.done ? 'line-through text-muted' : ''}>
89
- {task.title}
90
- </span>
91
- <Button variant="ghost" size="sm" onClick={() => onDelete(task.id)}>
92
- <TrashIcon />
93
- </Button>
94
- </li>
95
- );
96
- }
97
- ```
98
-
99
- **Separate data fetching from presentation:**
100
-
101
- ```tsx
102
- // Container: handles data
103
- export function TaskListContainer() {
104
- const { tasks, isLoading, error } = useTasks();
105
-
106
- if (isLoading) return <TaskListSkeleton />;
107
- if (error)
108
- return <ErrorState message="Failed to load tasks" retry={refetch} />;
109
- if (tasks.length === 0) return <EmptyState message="No tasks yet" />;
110
-
111
- return <TaskList tasks={tasks} />;
112
- }
113
-
114
- // Presentation: handles rendering
115
- export function TaskList({ tasks }: { tasks: Task[] }) {
116
- return (
117
- <ul role="list" className="divide-y">
118
- {tasks.map((task) => (
119
- <TaskItem key={task.id} task={task} />
120
- ))}
121
- </ul>
122
- );
123
- }
124
- ```
125
-
126
- ## State Management
127
-
128
- **Choose the simplest approach that works:**
129
-
130
- ```text
131
- Local state (useState) → Component-specific UI state
132
- Lifted state → Shared between 2-3 sibling components
133
- Context → Theme, auth, locale (read-heavy, write-rare)
134
- URL state (searchParams) → Filters, pagination, shareable UI state
135
- Server state (React Query, SWR) → Remote data with caching
136
- Global store (Zustand, Redux) → Complex client state shared app-wide
137
- ```
138
-
139
- **Avoid prop drilling deeper than 3 levels.** If you're passing props through
140
- components that don't use them, introduce context or restructure the component
141
- tree.
142
-
143
- ## Design System Adherence
144
-
145
- ### Avoid the AI Aesthetic
146
-
147
- AI-generated UI has recognizable patterns. Avoid all of them:
148
-
149
- | AI Default | Why It Is a Problem | Production Quality |
150
- | -------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
151
- | Purple/indigo everything | Models default to visually "safe" palettes, making every app look identical | Use the project's actual color palette |
152
- | Excessive gradients | Gradients add visual noise and clash with most design systems | Flat or subtle gradients matching the design system |
153
- | Rounded everything (rounded-2xl) | Maximum rounding signals "friendly" but ignores the hierarchy of corner radii in real designs | Consistent border-radius from the design system |
154
- | Generic hero sections | Template-driven layout with no connection to the actual content or user need | Content-first layouts |
155
- | Lorem ipsum-style copy | Placeholder text hides layout problems that real content reveals (length, wrapping, overflow) | Realistic placeholder content |
156
- | Oversized padding everywhere | Equal generous padding destroys visual hierarchy and wastes screen space | Consistent spacing scale |
157
- | Stock card grids | Uniform grids are a layout shortcut that ignores information priority and scanning patterns | Purpose-driven layouts |
158
- | Shadow-heavy design | Layered shadows add depth that competes with content and slows rendering on low-end devices | Subtle or no shadows unless the design system specifies |
159
-
160
- ### Spacing and Layout
161
-
162
- Use a consistent spacing scale. Don't invent values:
163
-
164
- ```css
165
- /* Use the scale: 0.25rem increments (or whatever the project uses) */
166
- /* Good */
167
- padding: 1rem; /* 16px */
168
- /* Good */
169
- gap: 0.75rem; /* 12px */
170
- /* Bad */
171
- padding: 13px; /* Not on any scale */
172
- /* Bad */
173
- margin-top: 2.3rem; /* Not on any scale */
174
- ```
175
-
176
- ### Typography
177
-
178
- Respect the type hierarchy:
179
-
180
- ```text
181
- h1 → Page title (one per page)
182
- h2 → Section title
183
- h3 → Subsection title
184
- body → Default text
185
- small → Secondary/helper text
186
- ```
187
-
188
- Don't skip heading levels. Don't use heading styles for non-heading content.
189
-
190
- ### Color
191
-
192
- - Use semantic color tokens: `text-primary`, `bg-surface`, `border-default` —
193
- not raw hex values
194
- - Ensure sufficient contrast (4.5:1 for normal text, 3:1 for large text)
195
- - Don't rely solely on color to convey information (use icons, text, or patterns
196
- too)
197
-
198
- ## Accessibility (WCAG 2.1 AA)
199
-
200
- Every component must meet these standards:
201
-
202
- ### Keyboard Navigation
203
-
204
- ```tsx
205
- // Every interactive element must be keyboard accessible
206
- <button onClick={handleClick}>Click me</button> // ✓ Focusable by default
207
- <div onClick={handleClick}>Click me</div> // ✗ Not focusable
208
- <div role="button" tabIndex={0} onClick={handleClick} // ✓ But prefer <button>
209
- onKeyDown={e => e.key === 'Enter' && handleClick()}>
210
- Click me
211
- </div>
212
- ```
213
-
214
- ### ARIA Labels
215
-
216
- ```tsx
217
- // Label interactive elements that lack visible text
218
- <button aria-label="Close dialog"><XIcon /></button>
219
-
220
- // Label form inputs
221
- <label htmlFor="email">Email</label>
222
- <input id="email" type="email" />
223
-
224
- // Or use aria-label when no visible label exists
225
- <input aria-label="Search tasks" type="search" />
226
- ```
227
-
228
- ### Focus Management
229
-
230
- ```tsx
231
- // Move focus when content changes
232
- function Dialog({ isOpen, onClose }: DialogProps) {
233
- const closeRef = useRef<HTMLButtonElement>(null);
234
-
235
- useEffect(() => {
236
- if (isOpen) closeRef.current?.focus();
237
- }, [isOpen]);
238
-
239
- // Trap focus inside dialog when open
240
- return (
241
- <dialog open={isOpen}>
242
- <button ref={closeRef} onClick={onClose}>
243
- Close
244
- </button>
245
- {/* dialog content */}
246
- </dialog>
247
- );
248
- }
249
- ```
250
-
251
- ### Meaningful Empty and Error States
252
-
253
- ```tsx
254
- // Don't show blank screens
255
- function TaskList({ tasks }: { tasks: Task[] }) {
256
- if (tasks.length === 0) {
257
- return (
258
- <div role="status" className="text-center py-12">
259
- <TasksEmptyIcon className="mx-auto h-12 w-12 text-muted" />
260
- <h3 className="mt-2 text-sm font-medium">No tasks</h3>
261
- <p className="mt-1 text-sm text-muted">
262
- Get started by creating a new task.
263
- </p>
264
- <Button className="mt-4" onClick={onCreateTask}>
265
- Create Task
266
- </Button>
267
- </div>
268
- );
269
- }
270
-
271
- return <ul role="list">...</ul>;
272
- }
273
- ```
274
-
275
- ## Responsive Design
276
-
277
- Design for mobile first, then expand:
278
-
279
- ```tsx
280
- // Tailwind: mobile-first responsive
281
- <div className="
282
- grid grid-cols-1 /* Mobile: single column */
283
- sm:grid-cols-2 /* Small: 2 columns */
284
- lg:grid-cols-3 /* Large: 3 columns */
285
- gap-4
286
- ">
287
- ```
288
-
289
- Test at these breakpoints: 320px, 768px, 1024px, 1440px.
290
-
291
- ## Loading and Transitions
292
-
293
- ```tsx
294
- // Skeleton loading (not spinners for content)
295
- function TaskListSkeleton() {
296
- return (
297
- <div className="space-y-3" aria-busy="true" aria-label="Loading tasks">
298
- {Array.from({ length: 3 }).map((_, i) => (
299
- <div key={i} className="h-12 bg-muted animate-pulse rounded" />
300
- ))}
301
- </div>
302
- );
303
- }
304
-
305
- // Optimistic updates for perceived speed
306
- function useToggleTask() {
307
- const queryClient = useQueryClient();
308
-
309
- return useMutation({
310
- mutationFn: toggleTask,
311
- onMutate: async (taskId) => {
312
- await queryClient.cancelQueries({ queryKey: ['tasks'] });
313
- const previous = queryClient.getQueryData(['tasks']);
314
-
315
- queryClient.setQueryData(['tasks'], (old: Task[]) =>
316
- old.map((t) => (t.id === taskId ? { ...t, done: !t.done } : t)),
317
- );
318
-
319
- return { previous };
320
- },
321
- onError: (_err, _taskId, context) => {
322
- queryClient.setQueryData(['tasks'], context?.previous);
323
- },
324
- });
325
- }
326
- ```
327
-
328
- ## Common Rationalizations
329
-
330
- | Rationalization | Reality |
331
- | ---------------------------------------------- | -------------------------------------------------------------------------------------------- |
332
- | "Accessibility is a nice-to-have" | It's a legal requirement in many jurisdictions and an engineering quality standard. |
333
- | "We'll make it responsive later" | Retrofitting responsive design is 3x harder than building it from the start. |
334
- | "The design isn't final, so I'll skip styling" | Use the design system defaults. Unstyled UI creates a broken first impression for reviewers. |
335
- | "This is just a prototype" | Prototypes become production code. Build the foundation right. |
336
- | "The AI aesthetic is fine for now" | It signals low quality. Use the project's actual design system from the start. |
337
-
338
- ## Red Flags
339
-
340
- - Components with more than 200 lines (split them)
341
- - Inline styles or arbitrary pixel values
342
- - Missing error states, loading states, or empty states
343
- - No keyboard navigation testing
344
- - Color as the sole indicator of state (red/green without text or icons)
345
- - Generic "AI look" (purple gradients, oversized cards, stock layouts)
346
-
347
- ## Verification
348
-
349
- After building UI:
350
-
351
- - [ ] Component renders without console errors
352
- - [ ] All interactive elements are keyboard accessible (Tab through the page)
353
- - [ ] Screen reader can convey the page's content and structure
354
- - [ ] Responsive: works at 320px, 768px, 1024px, 1440px
355
- - [ ] Loading, error, and empty states all handled
356
- - [ ] Follows the project's design system (spacing, colors, typography)
357
- - [ ] No accessibility warnings in dev tools or axe-core
@@ -1,123 +0,0 @@
1
- ---
2
- name: hydrate-context
3
- description: >-
4
- Hydrate a Story ticket into a structured ContextEnvelope (or the
5
- legacy `{ prompt }` stdout wrapper). Reads the ticket body, resolves the
6
- parent Epic, embeds the sectioned Epic body (acceptance-table section
7
- stripped), and assembles
8
- named sections with provenance and section-aware elision. Successor to
9
- the retired mandrel MCP `context.hydrate` tool.
10
- allowed_tools:
11
- - Read
12
- - Bash
13
- ---
14
-
15
- # hydrate-context
16
-
17
- ## Policy Capsule
18
-
19
- - Invoke via `node .agents/scripts/hydrate-context.js --ticket <id> [--epic <id>]`; the wrapping CLI is the only supported entry point and delegates to `lib/orchestration/context-hydration-engine.js`.
20
- - Treat the operation as strictly **read-only on GitHub** — never modify ticket bodies, never post comments, never apply labels.
21
- - When `--epic` is omitted, parse the Epic ID from the ticket body's `Epic: #N` line; do not infer it from elsewhere.
22
- - Surface `persona::*` and `skill::*` labels from the ticket into the composed prompt so the downstream executor can pin its sub-agent dispatch.
23
- - Emit exactly one JSON object on stdout (`{ "prompt": "..." }` by default, or `{ "envelope": {...} }` with `--emit envelope`) and nothing else — no temp files, no diagnostic prints that would corrupt the envelope.
24
- - Honour the engine's context-budget cap via section-aware elision (`elideEnvelope`): lower-priority sections drop or summarize before higher-priority ones. Never silently truncate mid-string.
25
- - Do not persist the composed prompt to disk; forwarding is the caller's responsibility.
26
-
27
- ## Role
28
-
29
- Context aggregator. Resolves a ticket's hierarchy (Story → Epic)
30
- and stitches the Epic body — the single planning document, carrying the
31
- folded Tech Spec sections — plus the Story body into a
32
- single prompt the executor consumes. The Epic body is embedded with its
33
- `## Acceptance Table` managed section stripped (close-time reconciliation
34
- detail the executor does not need); there is no separate Tech Spec fetch
35
- (Story #4324).
36
-
37
- ## When to use
38
-
39
- Whenever an Epic-scoped sub-agent needs the same context bundle the
40
- human operator would assemble manually before opening the file editor.
41
- The wrapping script `hydrate-context.js` is the CLI today; this Skill
42
- documents the dispatch contract for callers that want to invoke via
43
- the Skill tool.
44
-
45
- ## Inputs
46
-
47
- - `--ticket <id>` — GitHub issue number to hydrate (required).
48
- - `--epic <id>` (optional) — when omitted, parsed from the ticket
49
- body's `Epic: #N` line.
50
-
51
- Persona and skill labels are read off the ticket
52
- (`persona::*`, `skill::*`) and surfaced in the composed prompt so the
53
- executor can pin its sub-agent dispatch.
54
-
55
- ## Outputs
56
-
57
- The engine assembles a typed **ContextEnvelope** (`lib/orchestration/context-envelope.js`) and serializes it for consumers:
58
-
59
- | Field | Role |
60
- | --- | --- |
61
- | `schemaVersion` | Always `"1"` for the current contract. |
62
- | `task` | `{ id, title, persona?, skills?, protocolVersion? }` from the ticket and labels. |
63
- | `sections[]` | Named blocks (`protocolPolicy`, `persona`, `skillCapsules`, `hierarchy`, `acceptanceCriteria`, `verificationCommands`, `taskInstructions`) each with `priority`, `elideWhenOverBudget` (`drop` \| `summarize`), `content`, `estimatedTokens`, optional `source`. |
64
- | `provenance[]` | Ticket snapshots: `{ id, version, hash, retrievedAt }` so auditors can cite what was fetched. |
65
- | `budget` | `{ maxTokens, used, elided[] }` after `elideEnvelope` runs. |
66
- | `warnings[]` | Non-fatal hydration notices (missing files, skipped skills, etc.). |
67
-
68
- Default CLI stdout (backward-compatible wrapper):
69
-
70
- ```json
71
- { "prompt": "..." }
72
- ```
73
-
74
- `prompt` is `envelopeToPrompt(envelope)` — sections joined in `SECTION_RENDER_ORDER`, not elision priority. For inspection or downstream tools that consume the typed shape:
75
-
76
- ```bash
77
- node .agents/scripts/hydrate-context.js --ticket <id> --emit envelope
78
- ```
79
-
80
- ```json
81
- { "envelope": { "schemaVersion": "1", "task": { ... }, "sections": [ ... ], "provenance": [ ... ], "budget": { ... }, "warnings": [ ... ] } }
82
- ```
83
-
84
- The Skill writes nothing else — no GitHub comments, no temp files.
85
- Idempotence is trivial because the operation is read-only.
86
-
87
- ## Procedure
88
-
89
- ```bash
90
- node .agents/scripts/hydrate-context.js --ticket <id> [--epic <id>]
91
- ```
92
-
93
- Delegates to `hydrateContext` from
94
- `lib/orchestration/context-hydration-engine.js`. The engine handles
95
- provider I/O, body parsing, provenance stamping, and
96
- `elideEnvelope` when `budget.used` exceeds `limits.maxTokenBudget`.
97
-
98
- **Section-aware elision.** Each section carries a numeric `priority`
99
- (lower drops first) and an `elideWhenOverBudget` policy (`drop` removes
100
- the section; `summarize` keeps a head excerpt). Defaults live in
101
- `DEFAULT_SECTION_PRIORITIES` and `DEFAULT_ELIDE_POLICIES` in
102
- `context-envelope.js`. Elided section names are recorded in
103
- `budget.elided`.
104
-
105
- **Capsule-only skill loading.** Activated skills resolve through
106
- `skills.index.json` and `loadSkillCapsule`, emitting only the Policy
107
- Capsule (the skill's non-negotiables) plus a pointer instruction into the
108
- `skillCapsules` section. Full `SKILL.md` bodies are never inlined into a
109
- task prompt — the sub-agent reads the full playbook on demand via the
110
- rendered `Read <path>` pointer. The full-body injection path, the
111
- `fullSkillBodies` config flag, and the `skill::full` label were removed in
112
- a hard cutover (Story #3863); the only residual full-body emission is the
113
- defensive fallback when a `SKILL.md` is missing its capsule marker (a
114
- malformed manifest), which also logs a warning.
115
-
116
- ## Constraints
117
-
118
- - Do **not** modify ticket bodies or post comments. The Skill is
119
- strictly read-only on GitHub.
120
- - Do **not** persist the composed prompt to disk. The caller is
121
- responsible for forwarding the stdout envelope to its consumer.
122
- - Do **not** bypass the context-budget cap — honour `elideEnvelope`
123
- and the per-section policies; never silently truncate.