hatch3r 1.3.0 → 1.4.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/README.md +2 -1
- package/agents/hatch3r-a11y-auditor.md +7 -11
- package/agents/hatch3r-architect.md +7 -11
- package/agents/hatch3r-ci-watcher.md +7 -10
- package/agents/hatch3r-context-rules.md +5 -7
- package/agents/hatch3r-dependency-auditor.md +7 -13
- package/agents/hatch3r-devops.md +7 -13
- package/agents/hatch3r-docs-writer.md +7 -11
- package/agents/hatch3r-fixer.md +2 -8
- package/agents/hatch3r-implementer.md +2 -8
- package/agents/hatch3r-learnings-loader.md +5 -7
- package/agents/hatch3r-lint-fixer.md +7 -9
- package/agents/hatch3r-perf-profiler.md +7 -11
- package/agents/hatch3r-researcher.md +6 -8
- package/agents/hatch3r-reviewer.md +7 -10
- package/agents/hatch3r-security-auditor.md +7 -12
- package/agents/hatch3r-test-writer.md +7 -11
- package/agents/shared/external-knowledge.md +21 -0
- package/agents/shared/quality-charter.md +78 -0
- package/commands/board/pickup-azure-devops.md +4 -0
- package/commands/board/pickup-delegation-multi.md +3 -0
- package/commands/board/pickup-delegation.md +3 -0
- package/commands/board/pickup-github.md +4 -0
- package/commands/board/pickup-gitlab.md +4 -0
- package/commands/board/pickup-post-impl.md +8 -1
- package/commands/board/shared-azure-devops.md +13 -3
- package/commands/board/shared-github.md +1 -0
- package/commands/board/shared-gitlab.md +9 -2
- package/commands/hatch3r-agent-customize.md +5 -1
- package/commands/hatch3r-board-groom.md +55 -2
- package/commands/hatch3r-board-init.md +5 -2
- package/commands/hatch3r-board-shared.md +37 -2
- package/commands/hatch3r-command-customize.md +4 -0
- package/commands/hatch3r-hooks.md +1 -1
- package/commands/hatch3r-quick-change.md +29 -3
- package/commands/hatch3r-revision.md +136 -16
- package/commands/hatch3r-rule-customize.md +4 -0
- package/commands/hatch3r-skill-customize.md +4 -0
- package/commands/hatch3r-workflow.md +10 -1
- package/dist/cli/index.js +522 -360
- package/dist/cli/index.js.map +1 -1
- package/package.json +12 -9
- package/rules/hatch3r-agent-orchestration-detail.md +159 -0
- package/rules/hatch3r-agent-orchestration-detail.mdc +156 -0
- package/rules/hatch3r-agent-orchestration.md +91 -330
- package/rules/hatch3r-agent-orchestration.mdc +127 -149
- package/rules/hatch3r-code-standards.mdc +10 -2
- package/rules/hatch3r-component-conventions.mdc +0 -1
- package/rules/hatch3r-deep-context.mdc +30 -8
- package/rules/hatch3r-dependency-management.mdc +17 -5
- package/rules/hatch3r-i18n.mdc +0 -1
- package/rules/hatch3r-migrations.mdc +12 -1
- package/rules/hatch3r-observability.mdc +289 -0
- package/rules/hatch3r-security-patterns.mdc +11 -0
- package/rules/hatch3r-testing.mdc +1 -1
- package/rules/hatch3r-theming.mdc +0 -1
- package/rules/hatch3r-tooling-hierarchy.mdc +18 -4
- package/skills/hatch3r-agent-customize/SKILL.md +4 -72
- package/skills/hatch3r-command-customize/SKILL.md +4 -62
- package/skills/hatch3r-customize/SKILL.md +117 -0
- package/skills/hatch3r-rule-customize/SKILL.md +4 -65
- package/skills/hatch3r-skill-customize/SKILL.md +4 -62
|
@@ -163,3 +163,292 @@ Every telemetry-producing service must declare resource attributes at startup:
|
|
|
163
163
|
- Attribute values should be low-cardinality. Never use unbounded values (full URLs with query params, raw SQL, user-generated content) as attribute values.
|
|
164
164
|
- For high-cardinality identifiers (user IDs, request IDs), use span attributes sparingly and rely on correlated logs for detail.
|
|
165
165
|
- Prefer semantic convention attributes over custom attributes. When custom attributes are necessary, prefix them with your organization or project namespace (e.g., `myapp.feature.flag_key`).
|
|
166
|
+
|
|
167
|
+
### AI Agent Semantic Conventions
|
|
168
|
+
|
|
169
|
+
Follow the [OpenTelemetry GenAI Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/) (experimental, introduced 2024) for instrumenting AI/LLM agent systems. These conventions provide consistent attribute naming for generative AI operations, enabling interoperability across agent frameworks and observability backends.
|
|
170
|
+
|
|
171
|
+
#### `gen_ai.*` Span Attributes
|
|
172
|
+
|
|
173
|
+
Use these attributes on all spans that represent interactions with generative AI models:
|
|
174
|
+
|
|
175
|
+
| Attribute | Type | Description | Example |
|
|
176
|
+
|-----------|------|-------------|---------|
|
|
177
|
+
| `gen_ai.system` | string | The GenAI provider system name | `openai`, `anthropic`, `azure_openai` |
|
|
178
|
+
| `gen_ai.request.model` | string | Model name as specified in the request | `gpt-4o`, `claude-sonnet-4-20250514` |
|
|
179
|
+
| `gen_ai.response.model` | string | Model name as returned in the response (may differ from request) | `gpt-4o-2024-08-06` |
|
|
180
|
+
| `gen_ai.request.max_tokens` | int | Maximum number of tokens requested for generation | `4096` |
|
|
181
|
+
| `gen_ai.request.temperature` | float | Temperature parameter sent in the request | `0.7` |
|
|
182
|
+
| `gen_ai.request.top_p` | float | Top-p (nucleus sampling) parameter | `0.9` |
|
|
183
|
+
| `gen_ai.response.finish_reasons` | string[] | Reasons the model stopped generating | `["stop"]`, `["length"]`, `["tool_calls"]` |
|
|
184
|
+
| `gen_ai.usage.input_tokens` | int | Number of tokens in the input/prompt | `1250` |
|
|
185
|
+
| `gen_ai.usage.output_tokens` | int | Number of tokens in the generated output | `530` |
|
|
186
|
+
|
|
187
|
+
- Always set `gen_ai.system` and `gen_ai.request.model` on every GenAI span. These are required for meaningful filtering and cost attribution.
|
|
188
|
+
- Record `gen_ai.usage.input_tokens` and `gen_ai.usage.output_tokens` from the API response to enable token usage dashboards and cost tracking.
|
|
189
|
+
- Use `gen_ai.response.finish_reasons` to detect truncated outputs (`length`) and trigger re-prompting or alerting logic.
|
|
190
|
+
|
|
191
|
+
#### Agent Invocation Spans
|
|
192
|
+
|
|
193
|
+
Instrument the full lifecycle of an agent invocation with a dedicated span. This span is the parent for all LLM calls, tool executions, and sub-agent delegations within a single agent run.
|
|
194
|
+
|
|
195
|
+
- **Span name pattern:** `agent.{agent_name}.invoke` (e.g., `agent.code_reviewer.invoke`, `agent.research_assistant.invoke`)
|
|
196
|
+
- **Required attributes:**
|
|
197
|
+
|
|
198
|
+
| Attribute | Type | Description | Example |
|
|
199
|
+
|-----------|------|-------------|---------|
|
|
200
|
+
| `agent.id` | string | Unique identifier for this agent invocation | `agent-run-a1b2c3d4` |
|
|
201
|
+
| `agent.name` | string | Logical name of the agent | `code_reviewer` |
|
|
202
|
+
| `agent.parent_id` | string | ID of the parent agent (for sub-agent delegation chains) | `agent-run-x9y8z7` |
|
|
203
|
+
| `agent.task` | string | High-level description of the agent's assigned task | `review PR #42` |
|
|
204
|
+
| `agent.framework` | string | Agent framework in use | `langchain`, `autogen`, `custom` |
|
|
205
|
+
|
|
206
|
+
- **Span events for state transitions:** Record span events to mark key lifecycle transitions within the agent invocation:
|
|
207
|
+
- `agent.planning` — Agent begins task decomposition or reasoning.
|
|
208
|
+
- `agent.tool_selection` — Agent selects a tool to invoke.
|
|
209
|
+
- `agent.awaiting_human` — Agent pauses for human-in-the-loop confirmation.
|
|
210
|
+
- `agent.delegating` — Agent spawns a sub-agent.
|
|
211
|
+
- `agent.completed` — Agent finishes its task and produces a final output.
|
|
212
|
+
- `agent.error` — Agent encounters a non-recoverable error. Include `exception.type` and `exception.message` attributes on the event.
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
const agentSpan = tracer.startSpan('agent.code_reviewer.invoke', {
|
|
216
|
+
attributes: {
|
|
217
|
+
'agent.id': invocationId,
|
|
218
|
+
'agent.name': 'code_reviewer',
|
|
219
|
+
'agent.parent_id': parentAgentId ?? '',
|
|
220
|
+
'agent.task': `review PR #${prNumber}`,
|
|
221
|
+
'agent.framework': 'custom',
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
agentSpan.addEvent('agent.planning');
|
|
226
|
+
// ... agent reasoning and tool calls happen as child spans ...
|
|
227
|
+
agentSpan.addEvent('agent.completed');
|
|
228
|
+
agentSpan.end();
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### Tool Call Spans
|
|
232
|
+
|
|
233
|
+
Every tool invocation by an agent creates a child span of the agent invocation span. This enables tracing the full sequence of tool calls within an agent run, measuring tool latency, and detecting tool failures.
|
|
234
|
+
|
|
235
|
+
- **Span name pattern:** `tool.{tool_name}.execute` (e.g., `tool.file_read.execute`, `tool.web_search.execute`)
|
|
236
|
+
- **Required attributes:**
|
|
237
|
+
|
|
238
|
+
| Attribute | Type | Description | Example |
|
|
239
|
+
|-----------|------|-------------|---------|
|
|
240
|
+
| `tool.name` | string | Canonical name of the tool | `file_read`, `git_diff`, `web_search` |
|
|
241
|
+
| `tool.input_hash` | string | SHA-256 hash of the tool input (for deduplication, not logging raw input) | `sha256:3a7f...` |
|
|
242
|
+
| `tool.output_status` | string | Outcome of the tool execution | `success`, `error`, `timeout`, `rejected` |
|
|
243
|
+
| `tool.duration_ms` | float | Wall-clock execution time of the tool in milliseconds | `142.5` |
|
|
244
|
+
| `tool.parameters_count` | int | Number of parameters passed to the tool | `3` |
|
|
245
|
+
|
|
246
|
+
- **Parent-child relationship:** Tool spans must be children of the invoking agent span. Use `context.with(trace.setSpan(context.active(), agentSpan))` to propagate the agent span context to tool execution.
|
|
247
|
+
- Set span status to `ERROR` when `tool.output_status` is `error` or `timeout`. Attach exception details as a span event.
|
|
248
|
+
- For tools that perform I/O (HTTP requests, file system operations, database queries), create nested child spans using the appropriate semantic conventions (`http.*`, `db.*`) under the tool span.
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
const toolSpan = tracer.startSpan(
|
|
252
|
+
'tool.git_diff.execute',
|
|
253
|
+
{ attributes: { 'tool.name': 'git_diff' } },
|
|
254
|
+
trace.setSpan(context.active(), agentSpan),
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
const startTime = performance.now();
|
|
258
|
+
try {
|
|
259
|
+
const result = await tools.gitDiff(params);
|
|
260
|
+
toolSpan.setAttributes({
|
|
261
|
+
'tool.output_status': 'success',
|
|
262
|
+
'tool.duration_ms': performance.now() - startTime,
|
|
263
|
+
'tool.input_hash': hashInput(params),
|
|
264
|
+
});
|
|
265
|
+
} catch (err) {
|
|
266
|
+
toolSpan.setAttributes({
|
|
267
|
+
'tool.output_status': 'error',
|
|
268
|
+
'tool.duration_ms': performance.now() - startTime,
|
|
269
|
+
});
|
|
270
|
+
toolSpan.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
|
|
271
|
+
toolSpan.recordException(err);
|
|
272
|
+
throw err;
|
|
273
|
+
} finally {
|
|
274
|
+
toolSpan.end();
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
#### LLM Request/Response Tracing
|
|
279
|
+
|
|
280
|
+
Instrument every LLM API call with a dedicated span. These spans are typically children of an agent invocation span and capture model, token usage, and latency data for cost analysis and performance monitoring.
|
|
281
|
+
|
|
282
|
+
- **Span name pattern:** `gen_ai.{operation}` (e.g., `gen_ai.chat`, `gen_ai.completion`, `gen_ai.embeddings`)
|
|
283
|
+
- **Required attributes:** All applicable `gen_ai.*` attributes from the table above, plus:
|
|
284
|
+
|
|
285
|
+
| Attribute | Type | Description | Example |
|
|
286
|
+
|-----------|------|-------------|---------|
|
|
287
|
+
| `gen_ai.operation.name` | string | The specific API operation | `chat`, `completion`, `embeddings` |
|
|
288
|
+
| `gen_ai.request.stop_sequences` | string[] | Stop sequences sent in the request | `["\n\n", "END"]` |
|
|
289
|
+
| `server.address` | string | Hostname of the GenAI API endpoint | `api.openai.com` |
|
|
290
|
+
| `server.port` | int | Port of the GenAI API endpoint | `443` |
|
|
291
|
+
|
|
292
|
+
- **Input/output token tracking:** Always capture `gen_ai.usage.input_tokens` and `gen_ai.usage.output_tokens` from the API response. Aggregate these in metrics for cost dashboards:
|
|
293
|
+
- Counter: `gen_ai.tokens_total` with labels `{direction=input|output, model, agent_name}`
|
|
294
|
+
- Histogram: `gen_ai.request_duration_ms` with labels `{model, operation, agent_name}`
|
|
295
|
+
|
|
296
|
+
- **Model version tracking:** Record both `gen_ai.request.model` (what was requested) and `gen_ai.response.model` (what was actually used). API providers may silently route to different model versions; capturing both enables drift detection.
|
|
297
|
+
|
|
298
|
+
- **Error handling and retry spans:** When an LLM request fails and is retried, each attempt is a separate child span under the same parent. Record the error on the failed span and create a new span for the retry:
|
|
299
|
+
- Set `gen_ai.request.retries` (int) on the final successful span to indicate total retry count.
|
|
300
|
+
- Record `http.response.status_code` on failed spans to distinguish rate-limit errors (429) from server errors (500+).
|
|
301
|
+
- Use exponential backoff; the retry span's start time naturally captures the wait duration.
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
const llmSpan = tracer.startSpan(
|
|
305
|
+
'gen_ai.chat',
|
|
306
|
+
{
|
|
307
|
+
attributes: {
|
|
308
|
+
'gen_ai.system': 'openai',
|
|
309
|
+
'gen_ai.operation.name': 'chat',
|
|
310
|
+
'gen_ai.request.model': 'gpt-4o',
|
|
311
|
+
'gen_ai.request.max_tokens': 4096,
|
|
312
|
+
'gen_ai.request.temperature': 0.2,
|
|
313
|
+
'server.address': 'api.openai.com',
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
trace.setSpan(context.active(), agentSpan),
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
try {
|
|
320
|
+
const response = await openai.chat.completions.create({ /* ... */ });
|
|
321
|
+
llmSpan.setAttributes({
|
|
322
|
+
'gen_ai.response.model': response.model,
|
|
323
|
+
'gen_ai.response.finish_reasons': response.choices.map(c => c.finish_reason),
|
|
324
|
+
'gen_ai.usage.input_tokens': response.usage.prompt_tokens,
|
|
325
|
+
'gen_ai.usage.output_tokens': response.usage.completion_tokens,
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// Record token usage in metrics for cost tracking
|
|
329
|
+
tokenCounter.add(response.usage.prompt_tokens, {
|
|
330
|
+
direction: 'input', model: response.model, agent_name: agentName,
|
|
331
|
+
});
|
|
332
|
+
tokenCounter.add(response.usage.completion_tokens, {
|
|
333
|
+
direction: 'output', model: response.model, agent_name: agentName,
|
|
334
|
+
});
|
|
335
|
+
} catch (err) {
|
|
336
|
+
llmSpan.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
|
|
337
|
+
llmSpan.recordException(err);
|
|
338
|
+
throw err;
|
|
339
|
+
} finally {
|
|
340
|
+
llmSpan.end();
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
- Never log raw prompt content or full model responses as span attributes — these are high-cardinality and may contain sensitive data. Use `gen_ai.usage.*` token counts for cost tracking and correlated logs for prompt debugging in non-production environments.
|
|
345
|
+
- In production, sample GenAI spans at a higher rate than general spans (e.g., 50-100%) because each call is expensive and lower volume than typical HTTP traffic. Adjust sampling based on call volume and observability budget.
|
|
346
|
+
|
|
347
|
+
### Tool Call Audit Trail
|
|
348
|
+
|
|
349
|
+
Maintain a structured audit log for every tool invocation in agentic workflows. This log is separate from tracing spans and serves as an immutable compliance and debugging record.
|
|
350
|
+
|
|
351
|
+
#### Schema Definition
|
|
352
|
+
|
|
353
|
+
Every tool call audit log entry must include the following fields:
|
|
354
|
+
|
|
355
|
+
| Field | Type | Description |
|
|
356
|
+
|-------|------|-------------|
|
|
357
|
+
| `tool.name` | string | Name of the tool invoked |
|
|
358
|
+
| `tool.input_hash` | string | SHA-256 hash of the tool input (for privacy, never log raw input) |
|
|
359
|
+
| `tool.output_status` | string | Outcome of the tool execution: `success`, `error`, `timeout`, or `denied` |
|
|
360
|
+
| `tool.duration_ms` | float | Execution time in milliseconds |
|
|
361
|
+
| `agent.id` | string | ID of the agent that invoked the tool |
|
|
362
|
+
| `agent.name` | string | Human-readable agent name |
|
|
363
|
+
| `correlation.id` | string | Trace correlation ID linking this entry to the broader workflow |
|
|
364
|
+
| `timestamp` | string | ISO 8601 timestamp of the invocation |
|
|
365
|
+
| `session.id` | string | Session identifier for grouping related tool calls |
|
|
366
|
+
|
|
367
|
+
#### Logging Requirements
|
|
368
|
+
|
|
369
|
+
- Log every tool invocation at `info` level with the full schema above.
|
|
370
|
+
- Log tool failures at `error` level with additional `error.type` and `error.message` fields describing the failure.
|
|
371
|
+
- Aggregate tool call counts per agent per session for anomaly detection (e.g., an agent invoking an unusual number of tools may indicate a loop or misconfiguration).
|
|
372
|
+
- Retain audit logs for a minimum of 90 days to support post-incident investigation and compliance review.
|
|
373
|
+
|
|
374
|
+
#### Example Log Entry
|
|
375
|
+
|
|
376
|
+
```json
|
|
377
|
+
{
|
|
378
|
+
"timestamp": "2026-02-15T14:32:07.891Z",
|
|
379
|
+
"level": "info",
|
|
380
|
+
"correlation.id": "agent-run-550e8400-e29b-41d4-a716-446655440000",
|
|
381
|
+
"session.id": "sess-8f14e45f-ceea-467f-a8f0-3b5c6d7e8f9a",
|
|
382
|
+
"agent.id": "agent-run-a1b2c3d4",
|
|
383
|
+
"agent.name": "code_reviewer",
|
|
384
|
+
"tool.name": "git_diff",
|
|
385
|
+
"tool.input_hash": "sha256:3a7f2c9e8b1d4f6a0e5c7b9d2f4a6e8c0b3d5f7a9e1c3b5d7f9a2c4e6b8d0f",
|
|
386
|
+
"tool.output_status": "success",
|
|
387
|
+
"tool.duration_ms": 142.5
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Correlation IDs for Agent Workflows
|
|
392
|
+
|
|
393
|
+
Correlation IDs provide the connective thread linking all telemetry signals (logs, spans, metrics) across a multi-agent workflow. Every participant in the workflow uses the same correlation ID, enabling end-to-end traceability from the initial trigger through all agent delegations and tool calls.
|
|
394
|
+
|
|
395
|
+
#### ID Generation
|
|
396
|
+
|
|
397
|
+
- Use UUIDv4 for correlation IDs. Generate the ID at the workflow entry point (the first agent invocation or the orchestrator that initiates the run).
|
|
398
|
+
- Format: `{workflow-type}-{uuid}` (e.g., `agent-run-550e8400-e29b-41d4-a716-446655440000`, `review-flow-7c9e6679-7425-40de-944b-e07fc1f90ae7`).
|
|
399
|
+
- The workflow-type prefix provides human-readable context when scanning logs and makes it possible to filter by workflow category without parsing the full ID.
|
|
400
|
+
|
|
401
|
+
#### Propagation
|
|
402
|
+
|
|
403
|
+
- The correlation ID propagates from the parent agent to all sub-agents via context. Pass it explicitly when delegating to sub-agents or invoking tools.
|
|
404
|
+
- Every log entry, span, and metric produced during the workflow must include the `correlation.id` attribute.
|
|
405
|
+
- When crossing process boundaries (e.g., HTTP calls between services), propagate the correlation ID via a custom header (`X-Correlation-ID`) alongside standard W3C Trace Context headers.
|
|
406
|
+
|
|
407
|
+
#### Parent-Child Span Linking
|
|
408
|
+
|
|
409
|
+
- The parent agent's span ID becomes the `parent_span_id` attribute on child agent spans, establishing a clear hierarchy in trace visualizations.
|
|
410
|
+
- For cross-workflow references (e.g., an agent run triggered by a CI pipeline event), use OpenTelemetry `SpanLink` to connect the agent workflow trace to the originating trace without creating a parent-child relationship.
|
|
411
|
+
- SpanLinks preserve the independence of each workflow trace while enabling navigation between related workflows in the observability backend.
|
|
412
|
+
|
|
413
|
+
#### Implementation Pattern
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
import { randomUUID } from 'node:crypto';
|
|
417
|
+
import { context, trace, SpanStatusCode } from '@opentelemetry/api';
|
|
418
|
+
|
|
419
|
+
function generateCorrelationId(workflowType: string): string {
|
|
420
|
+
return `${workflowType}-${randomUUID()}`;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
async function runAgentWorkflow(task: string): Promise<void> {
|
|
424
|
+
const correlationId = generateCorrelationId('agent-run');
|
|
425
|
+
const tracer = trace.getTracer('agent-orchestrator');
|
|
426
|
+
|
|
427
|
+
const rootSpan = tracer.startSpan('agent.orchestrator.invoke', {
|
|
428
|
+
attributes: {
|
|
429
|
+
'correlation.id': correlationId,
|
|
430
|
+
'agent.name': 'orchestrator',
|
|
431
|
+
'agent.task': task,
|
|
432
|
+
},
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
const ctx = trace.setSpan(context.active(), rootSpan);
|
|
436
|
+
|
|
437
|
+
try {
|
|
438
|
+
// Sub-agent inherits the correlation ID from context
|
|
439
|
+
await context.with(ctx, async () => {
|
|
440
|
+
await delegateToSubAgent('code_reviewer', {
|
|
441
|
+
correlationId,
|
|
442
|
+
parentSpanId: rootSpan.spanContext().spanId,
|
|
443
|
+
task: 'review changes',
|
|
444
|
+
});
|
|
445
|
+
});
|
|
446
|
+
} catch (err) {
|
|
447
|
+
rootSpan.setStatus({ code: SpanStatusCode.ERROR, message: (err as Error).message });
|
|
448
|
+
rootSpan.recordException(err as Error);
|
|
449
|
+
throw err;
|
|
450
|
+
} finally {
|
|
451
|
+
rootSpan.end();
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
```
|
|
@@ -61,6 +61,11 @@ alwaysApply: true
|
|
|
61
61
|
- Enforce parameter schemas on every tool call. Reject calls with unexpected, missing, or out-of-range arguments.
|
|
62
62
|
- Rate-limit tool invocations per agent per time window. Alert on anomalous tool usage patterns.
|
|
63
63
|
- Sandbox tool execution: restrict file system access, network egress, and subprocess spawning.
|
|
64
|
+
- **MCP server filesystem scope:** MCP servers with filesystem access must be scoped to the minimum necessary directories:
|
|
65
|
+
- Restrict filesystem access to the project directory. MCP servers should never have access to the home directory, system directories, or unrelated project directories.
|
|
66
|
+
- Document which MCP servers have filesystem access and define their intended scope (read-only vs read-write, which directories).
|
|
67
|
+
- Configure `allowedDirectories` in MCP server configs where supported. If the server does not support directory restrictions, document this as a known risk and apply compensating controls (monitoring, read-only mode).
|
|
68
|
+
- Audit MCP server filesystem access on configuration changes. Verify that added servers do not expand the filesystem attack surface beyond the project boundary.
|
|
64
69
|
|
|
65
70
|
### ASI03 — Identity & Privilege Abuse
|
|
66
71
|
|
|
@@ -75,6 +80,12 @@ alwaysApply: true
|
|
|
75
80
|
- Verify package integrity (checksums, signatures) before loading tools or plugins.
|
|
76
81
|
- Audit third-party prompt templates for injected instructions before use.
|
|
77
82
|
- Maintain an allowlist of approved MCP servers and tool sources.
|
|
83
|
+
- **`npx -y` safety:** The `-y` flag auto-confirms installation of unknown packages without prompts, creating a supply chain attack vector:
|
|
84
|
+
- Never use `npx -y` with untrusted, unknown, or typo-squattable package names.
|
|
85
|
+
- Always pin explicit versions when using npx: `npx package@1.2.3` instead of `npx package`.
|
|
86
|
+
- Prefer `npm exec --package=package@version -- command` for critical tooling — it provides explicit version control and avoids silent auto-install.
|
|
87
|
+
- In CI pipelines, install tools as explicit `devDependencies` with pinned versions rather than relying on `npx` at runtime.
|
|
88
|
+
- Verify the package name and publisher on the npm registry before first use. Typosquatting attacks exploit `npx -y` by registering names similar to popular packages.
|
|
78
89
|
|
|
79
90
|
### ASI05 — Unexpected Code Execution
|
|
80
91
|
|
|
@@ -13,7 +13,7 @@ alwaysApply: true
|
|
|
13
13
|
- **Named clearly.** Describe behavior: `"should award 15 XP for 25-min focus block"`.
|
|
14
14
|
- **Regression.** Every bug fix includes a test that fails before the fix and passes after.
|
|
15
15
|
- **No network.** Unit tests must not make network calls. Use mocks.
|
|
16
|
-
- No
|
|
16
|
+
- No type escape hatches in tests. No `.skip` without a linked issue.
|
|
17
17
|
- Write tests to `tests/unit/`, `tests/integration/`, `tests/e2e/`, or equivalent.
|
|
18
18
|
- Use test fixtures from `tests/fixtures/` or equivalent.
|
|
19
19
|
- **Browser verification.** For UI changes, verify visually in the browser via browser automation MCP after automated tests pass. Capture screenshots as evidence.
|
|
@@ -10,25 +10,39 @@ alwaysApply: true
|
|
|
10
10
|
|
|
11
11
|
Read `platform` from `.agents/hatch.json` to determine which platform tools to use.
|
|
12
12
|
|
|
13
|
+
### Prerequisites
|
|
14
|
+
|
|
15
|
+
| Platform | Auth Setup |
|
|
16
|
+
|----------|-----------|
|
|
17
|
+
| **GitHub** | `gh auth login` or `GITHUB_TOKEN` env var. For Projects v2: `gh auth refresh -s project` |
|
|
18
|
+
| **Azure DevOps** | `az login` and `az devops configure --defaults organization=ORG project=PROJECT` |
|
|
19
|
+
| **GitLab** | `glab auth login` or `GITLAB_TOKEN` env var |
|
|
20
|
+
|
|
21
|
+
### Platform CLI Fallback Reference
|
|
22
|
+
|
|
13
23
|
**Fallback to the platform CLI only when:**
|
|
14
24
|
- The MCP tool catalog lacks the specific capability.
|
|
15
25
|
- An MCP call fails repeatedly and the CLI provides a viable alternative.
|
|
16
26
|
|
|
17
27
|
**Never** use the platform CLI for operations that have a direct MCP equivalent (issue CRUD, PR/MR CRUD, search, labels).
|
|
18
28
|
|
|
19
|
-
### Platform CLI Fallback Reference
|
|
20
|
-
|
|
21
29
|
| Action | GitHub | Azure DevOps | GitLab |
|
|
22
30
|
|--------|--------|--------------|--------|
|
|
23
31
|
| Create issue | `gh issue create` | `az boards work-item create` | `glab issue create` |
|
|
32
|
+
| Edit issue | `gh issue edit` | `az boards work-item update` | `glab issue update` |
|
|
24
33
|
| View issue | `gh issue view` | `az boards work-item show --id N` | `glab issue view` |
|
|
25
34
|
| List issues | `gh issue list` | `az boards work-item list` | `glab issue list` |
|
|
26
35
|
| Create PR/MR | `gh pr create` | `az repos pr create` | `glab mr create` |
|
|
27
36
|
| View PR/MR | `gh pr view` | `az repos pr show` | `glab mr view` |
|
|
28
37
|
| List PRs/MRs | `gh pr list` | `az repos pr list` | `glab mr list` |
|
|
38
|
+
| Merge PR/MR | `gh pr merge` | `az repos pr complete` | `glab mr merge` |
|
|
39
|
+
| Search issues | `gh search issues` | `az boards query` | `glab issue list --search` |
|
|
40
|
+
| Search PRs | `gh search prs` | `az repos pr list --status all` | `glab mr list --search` |
|
|
29
41
|
| Search code | `gh search code` | `az repos show` | `glab search` |
|
|
30
|
-
|
|
|
42
|
+
| Labels | `gh label create/list` | `az boards work-item update --fields` | `glab label create/list` |
|
|
31
43
|
| Releases | `gh release create` | `az repos release` | `glab release create` |
|
|
44
|
+
| CI runs | `gh run list/view/watch` | `az pipelines run list/show` | `glab ci list/view` |
|
|
45
|
+
| Projects | `gh project item-add/edit/list` | `az boards iteration/area` | GitLab Boards API |
|
|
32
46
|
|
|
33
47
|
## B. Documentation MCP for Library Documentation
|
|
34
48
|
|
|
@@ -94,7 +108,7 @@ Use browser automation MCP tools to visually verify UI changes after automated t
|
|
|
94
108
|
When seeking information, follow this priority order:
|
|
95
109
|
|
|
96
110
|
1. **Project specs and ADRs** — authoritative for project-specific behavior, constraints, and decisions.
|
|
97
|
-
2. **Codebase exploration** (
|
|
111
|
+
2. **Codebase exploration** (code search tools, semantic code search) — ground truth for current implementation.
|
|
98
112
|
3. **Documentation MCP** — authoritative for external library/framework APIs and patterns.
|
|
99
113
|
4. **Web research** — current events, best practices, security advisories, novel problems.
|
|
100
114
|
5. **Browser verification** — visual confirmation of UI changes after automated tests pass.
|
|
@@ -1,78 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: hatch3r-agent-customize
|
|
3
|
-
description:
|
|
3
|
+
description: Agent customization — redirects to the unified hatch3r-customize skill.
|
|
4
4
|
tags: [customize]
|
|
5
5
|
---
|
|
6
|
-
# Agent Customization
|
|
6
|
+
# Agent Customization
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
> **This skill has been consolidated.** Use the `hatch3r-customize` skill with `type: agent`.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
Task Progress:
|
|
12
|
-
- [ ] Step 1: Identify which agent to customize
|
|
13
|
-
- [ ] Step 2: Determine customization needs
|
|
14
|
-
- [ ] Step 3: Create the customization files
|
|
15
|
-
- [ ] Step 4: Sync to propagate changes
|
|
16
|
-
- [ ] Step 5: Verify the customized output
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Step 1: Identify Agent
|
|
20
|
-
|
|
21
|
-
Determine which hatch3r agent needs customization:
|
|
22
|
-
- Review the agents in `.agents/agents/` and their default behaviors
|
|
23
|
-
- Identify gaps between default behavior and project needs
|
|
24
|
-
- Check for existing customization files in `.hatch3r/agents/`
|
|
25
|
-
|
|
26
|
-
## Step 2: Determine Customization Needs
|
|
27
|
-
|
|
28
|
-
Decide which customization approach to use:
|
|
29
|
-
|
|
30
|
-
**YAML (`.customize.yaml`)** — for structured overrides:
|
|
31
|
-
- **Model**: Override the agent's preferred model (e.g., `model: opus`)
|
|
32
|
-
- **Description**: Change how the agent is described in adapter frontmatter
|
|
33
|
-
- **Enabled**: Set to `false` to disable the agent entirely
|
|
34
|
-
|
|
35
|
-
**Protected agents:** Some agents have `protected: true` in their canonical frontmatter. For these security-critical agents (e.g., reviewer, security-auditor, test-writer), customization cannot override `scope`, `description`, or `enabled` — only `model` and markdown instructions can be customized. See the `hatch3r-agent-customize` command for full details.
|
|
36
|
-
|
|
37
|
-
**Markdown (`.customize.md`)** — for free-form instructions:
|
|
38
|
-
- Domain-specific review checklists
|
|
39
|
-
- Architecture context and constraints
|
|
40
|
-
- Project-specific workflow steps
|
|
41
|
-
- Compliance and security requirements
|
|
42
|
-
|
|
43
|
-
## Step 3: Create Customization Files
|
|
44
|
-
|
|
45
|
-
Create files in `.hatch3r/agents/`:
|
|
46
|
-
|
|
47
|
-
**For YAML overrides:**
|
|
48
|
-
```yaml
|
|
49
|
-
# .hatch3r/agents/{agent-id}.customize.yaml
|
|
50
|
-
model: opus
|
|
51
|
-
description: "Security-focused reviewer for healthcare platform"
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**For markdown instructions:**
|
|
55
|
-
Create `.hatch3r/agents/{agent-id}.customize.md` with project-specific instructions. This content is injected into the managed block under `## Project Customizations`.
|
|
56
|
-
|
|
57
|
-
Set only the fields/content you need — partial customization is valid.
|
|
58
|
-
|
|
59
|
-
## Step 4: Sync
|
|
60
|
-
|
|
61
|
-
Run `npx hatch3r sync` to propagate customizations to all adapter outputs. The sync:
|
|
62
|
-
- Reads `.customize.yaml` for structured overrides (model, description, enabled)
|
|
63
|
-
- Reads `.customize.md` and appends it inside the managed block
|
|
64
|
-
- Generates updated output for every configured adapter (Cursor, Claude, etc.)
|
|
65
|
-
|
|
66
|
-
## Step 5: Verify
|
|
67
|
-
|
|
68
|
-
Confirm customizations appear in adapter output files:
|
|
69
|
-
- Check model appears in frontmatter (e.g., `.cursor/agents/hatch3r-reviewer.md`)
|
|
70
|
-
- Check markdown instructions appear inside the managed block
|
|
71
|
-
- Verify disabled agents are absent from adapter outputs
|
|
72
|
-
|
|
73
|
-
## Definition of Done
|
|
74
|
-
|
|
75
|
-
- [ ] Customization files created in `.hatch3r/agents/`
|
|
76
|
-
- [ ] `npx hatch3r sync` completes without errors
|
|
77
|
-
- [ ] Adapter output files reflect the customizations
|
|
78
|
-
- [ ] Customization files committed to the repository
|
|
10
|
+
For agent-specific reference (model resolution, protected agents, YAML schema), see the `hatch3r-agent-customize` command.
|
|
@@ -1,68 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: hatch3r-command-customize
|
|
3
|
-
description:
|
|
3
|
+
description: Command customization — redirects to the unified hatch3r-customize skill.
|
|
4
4
|
tags: [customize]
|
|
5
5
|
---
|
|
6
|
-
# Command Customization
|
|
6
|
+
# Command Customization
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
> **This skill has been consolidated.** Use the `hatch3r-customize` skill with `type: command`.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
Task Progress:
|
|
12
|
-
- [ ] Step 1: Identify which command to customize
|
|
13
|
-
- [ ] Step 2: Determine customization needs
|
|
14
|
-
- [ ] Step 3: Create the customization files
|
|
15
|
-
- [ ] Step 4: Sync to propagate changes
|
|
16
|
-
- [ ] Step 5: Verify the customized output
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Step 1: Identify Command
|
|
20
|
-
|
|
21
|
-
Determine which hatch3r command needs customization:
|
|
22
|
-
- Review the commands in `.agents/commands/` and their default behavior
|
|
23
|
-
- Identify gaps between default behavior and project needs
|
|
24
|
-
- Check for existing customization files in `.hatch3r/commands/`
|
|
25
|
-
|
|
26
|
-
## Step 2: Determine Customization Needs
|
|
27
|
-
|
|
28
|
-
Decide which customization approach to use:
|
|
29
|
-
|
|
30
|
-
**YAML (`.customize.yaml`)** — for structured overrides:
|
|
31
|
-
- **Description**: Change how the command is described in adapter outputs
|
|
32
|
-
- **Enabled**: Set to `false` to disable the command entirely
|
|
33
|
-
|
|
34
|
-
**Markdown (`.customize.md`)** — for free-form instructions:
|
|
35
|
-
- Project-specific workflow steps
|
|
36
|
-
- Additional prerequisites or constraints
|
|
37
|
-
- Custom deployment or release procedures
|
|
38
|
-
|
|
39
|
-
## Step 3: Create Customization Files
|
|
40
|
-
|
|
41
|
-
Create files in `.hatch3r/commands/`:
|
|
42
|
-
|
|
43
|
-
**For YAML overrides:**
|
|
44
|
-
```yaml
|
|
45
|
-
# .hatch3r/commands/{command-id}.customize.yaml
|
|
46
|
-
description: "Release workflow with staging validation"
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
**For markdown instructions:**
|
|
50
|
-
Create `.hatch3r/commands/{command-id}.customize.md` with project-specific additions. This content is injected into the managed block under `## Project Customizations`.
|
|
51
|
-
|
|
52
|
-
## Step 4: Sync
|
|
53
|
-
|
|
54
|
-
Run `npx hatch3r sync` to propagate customizations to all adapter outputs.
|
|
55
|
-
|
|
56
|
-
## Step 5: Verify
|
|
57
|
-
|
|
58
|
-
Confirm customizations appear in adapter output files:
|
|
59
|
-
- Check description in adapter outputs (where applicable)
|
|
60
|
-
- Check markdown instructions appear inside the managed block
|
|
61
|
-
- Verify disabled commands are absent from adapter outputs
|
|
62
|
-
|
|
63
|
-
## Definition of Done
|
|
64
|
-
|
|
65
|
-
- [ ] Customization files created in `.hatch3r/commands/`
|
|
66
|
-
- [ ] `npx hatch3r sync` completes without errors
|
|
67
|
-
- [ ] Adapter output files reflect the customizations
|
|
68
|
-
- [ ] Customization files committed to the repository
|
|
10
|
+
For command-specific reference (YAML schema, examples), see the `hatch3r-command-customize` command.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: hatch3r-customize
|
|
3
|
+
description: Create and manage customization files for any hatch3r artifact type (agents, commands, rules, skills). Supports model overrides, description changes, scope overrides, enable/disable control, and project-specific markdown instructions.
|
|
4
|
+
tags: [customize]
|
|
5
|
+
---
|
|
6
|
+
# Artifact Customization Management
|
|
7
|
+
|
|
8
|
+
## Quick Start
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Task Progress:
|
|
12
|
+
- [ ] Step 1: Identify what to customize (and why)
|
|
13
|
+
- [ ] Step 2: Determine customization needs
|
|
14
|
+
- [ ] Step 3: Multi-stakeholder review
|
|
15
|
+
- [ ] Step 4: Create the customization files
|
|
16
|
+
- [ ] Step 5: Sync to propagate changes
|
|
17
|
+
- [ ] Step 6: Verify the customized output
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Artifact Types
|
|
21
|
+
|
|
22
|
+
This skill handles customization for all artifact types. The `type` parameter determines file locations, available YAML fields, and verification steps.
|
|
23
|
+
|
|
24
|
+
| Type | Source Directory | Customization Directory | YAML Fields |
|
|
25
|
+
|------|-----------------|------------------------|-------------|
|
|
26
|
+
| `agent` | `.agents/agents/` | `.hatch3r/agents/` | `model`, `description`, `enabled` |
|
|
27
|
+
| `command` | `.agents/commands/` | `.hatch3r/commands/` | `description`, `enabled` |
|
|
28
|
+
| `rule` | `.agents/rules/` | `.hatch3r/rules/` | `scope`, `description`, `enabled` |
|
|
29
|
+
| `skill` | `.agents/skills/` | `.hatch3r/skills/` | `description`, `enabled` |
|
|
30
|
+
|
|
31
|
+
**Protected agents:** Some agents have `protected: true` in their canonical frontmatter. For these agents, `description` and `enabled` overrides are ignored — only `model` and markdown instructions can be customized.
|
|
32
|
+
|
|
33
|
+
## Step 1: Identify and Root-Cause
|
|
34
|
+
|
|
35
|
+
Determine which artifact needs customization and **why**:
|
|
36
|
+
|
|
37
|
+
1. Review the artifacts in the appropriate source directory and their default behaviors.
|
|
38
|
+
2. Identify gaps between default behavior and project needs.
|
|
39
|
+
3. Check for existing customization files in the appropriate `.hatch3r/{type}s/` directory.
|
|
40
|
+
4. **Root-cause analysis:** Before proceeding, consider:
|
|
41
|
+
- Is this a genuine project-specific need, or a workaround for a bug in the default content?
|
|
42
|
+
- Would this customization be better addressed upstream (by modifying the canonical artifact)?
|
|
43
|
+
- Could a rule or learning achieve the same effect with less coupling?
|
|
44
|
+
|
|
45
|
+
If the customization is working around a default content issue, note it as a candidate for upstream contribution before proceeding.
|
|
46
|
+
|
|
47
|
+
## Step 2: Determine Customization Needs
|
|
48
|
+
|
|
49
|
+
Decide which customization approach to use:
|
|
50
|
+
|
|
51
|
+
**YAML (`.customize.yaml`)** — for structured overrides:
|
|
52
|
+
|
|
53
|
+
| Field | Available For | Description |
|
|
54
|
+
|-------|--------------|-------------|
|
|
55
|
+
| `model` | agent only | Override the agent's preferred model |
|
|
56
|
+
| `scope` | rule only | Override when the rule applies (`always` or glob patterns) |
|
|
57
|
+
| `description` | all types | Change how the artifact is described in adapter outputs |
|
|
58
|
+
| `enabled` | all types | Set to `false` to exclude from adapter output generation |
|
|
59
|
+
|
|
60
|
+
**Markdown (`.customize.md`)** — for free-form instructions:
|
|
61
|
+
- Domain-specific checklists, constraints, or workflow additions
|
|
62
|
+
- Architecture context relevant to the artifact's function
|
|
63
|
+
- Project-specific requirements (compliance, testing, deployment)
|
|
64
|
+
|
|
65
|
+
Set only the fields/content you need — partial customization is valid.
|
|
66
|
+
|
|
67
|
+
## Step 3: Multi-Stakeholder Review
|
|
68
|
+
|
|
69
|
+
Before creating customization files, consider the impact from multiple perspectives:
|
|
70
|
+
|
|
71
|
+
1. **Developer experience:** Does this customization make the developer's workflow better or worse? Will it cause confusion for new team members?
|
|
72
|
+
2. **Quality impact:** Does disabling or weakening an artifact (especially agents or rules) reduce quality safeguards? What compensating controls exist?
|
|
73
|
+
3. **Maintenance burden:** Will this customization need updating when the upstream canonical artifact changes? Is the coupling acceptable?
|
|
74
|
+
4. **Consistency:** Does this customization create inconsistency with other artifacts or team conventions?
|
|
75
|
+
|
|
76
|
+
**Confidence expression:** State your confidence in the customization decision:
|
|
77
|
+
- **High confidence:** Clear project-specific need with no quality trade-offs.
|
|
78
|
+
- **Medium confidence:** Reasonable need but with trade-offs worth noting.
|
|
79
|
+
- **Low confidence:** Workaround or uncertain benefit — recommend revisiting after more experience.
|
|
80
|
+
|
|
81
|
+
## Step 4: Create Customization Files
|
|
82
|
+
|
|
83
|
+
Create files in `.hatch3r/{type}s/`:
|
|
84
|
+
|
|
85
|
+
**For YAML overrides:** Create `.hatch3r/{type}s/{artifact-id}.customize.yaml` with the applicable fields from the Step 2 table.
|
|
86
|
+
|
|
87
|
+
**For markdown instructions:** Create `.hatch3r/{type}s/{artifact-id}.customize.md` with project-specific content. This is injected into the managed block under `## Project Customizations`.
|
|
88
|
+
|
|
89
|
+
## Step 5: Sync
|
|
90
|
+
|
|
91
|
+
Run `npx hatch3r sync` to propagate customizations to all adapter outputs. The sync reads `.customize.yaml` for structured overrides, reads `.customize.md` and appends it inside the managed block, and generates updated output for every configured adapter.
|
|
92
|
+
|
|
93
|
+
## Step 6: Verify
|
|
94
|
+
|
|
95
|
+
Confirm customizations appear in adapter output files:
|
|
96
|
+
- Check YAML fields are reflected in adapter-specific frontmatter
|
|
97
|
+
- Check markdown instructions appear inside the managed block
|
|
98
|
+
- Verify disabled artifacts are absent from adapter outputs
|
|
99
|
+
- **For rules:** verify scope is applied correctly in adapter-specific frontmatter
|
|
100
|
+
|
|
101
|
+
### Quality Gate
|
|
102
|
+
|
|
103
|
+
Verification is not just "sync completes." Confirm:
|
|
104
|
+
- [ ] The adapter output for the customized artifact contains the expected changes
|
|
105
|
+
- [ ] No unrelated artifacts were affected by the sync
|
|
106
|
+
- [ ] If an artifact was disabled, verify no command or skill references it as a required dependency
|
|
107
|
+
- [ ] If a rule scope was narrowed, verify the excluded file patterns do not lose important coverage
|
|
108
|
+
|
|
109
|
+
## Definition of Done
|
|
110
|
+
|
|
111
|
+
- [ ] Root-cause considered (Step 1) — not working around an upstream issue
|
|
112
|
+
- [ ] Multi-stakeholder impact reviewed (Step 3)
|
|
113
|
+
- [ ] Customization files created in `.hatch3r/{type}s/`
|
|
114
|
+
- [ ] `npx hatch3r sync` completes without errors
|
|
115
|
+
- [ ] Adapter output files reflect the customizations
|
|
116
|
+
- [ ] Quality gate checks pass (Step 6)
|
|
117
|
+
- [ ] Customization files committed to the repository
|