preset-creator ยท diff

git:20260707.b0f4f4c to git:20260711.cc45f6f

1 added, 1 removed. Audit B to B.

---
name: preset-creator
description: Create, review, or update Harness Anything presets. Use when designing preset-manifest JSON, preset script entrypoints, reads/writes scopes, preset profiles, process-action presets, or preset tests for Harness Anything. Enforces declaration-first presets and forbids hardcoding preset-specific behavior in CLI core TypeScript.
---
# Preset Creator
## Core Rule
Keep presets declaration-first. A preset is a `preset-manifest/v2` manifest plus optional package-local scripts and template selections. Template bodies are assets owned by a template catalog, not inline manifest strings. Do not add `presetId` or action-specific branches to CLI core code.
The CLI may provide only generic infrastructure:
- Manifest/schema validation.
- Layer resolution: builtin, user, project.
- Generic script execution.
- Declared `reads`/`writes` permission handling.
- Generic result envelope collection.
Preset behavior belongs in the preset package:
- `preset.json`
- `scripts/*`
- `profiles[*].templateSelections`
- declared inputs, reads, and writes
## Workflow
1. Define the preset's job in one sentence.
2. Decide whether it is `template-content` or `process-action`.
3. Write or update `preset.json` as `preset-manifest/v2`.
4. Put template overlays in `profiles[*].templateSelections`; point each selection at `template://<id>@<version>`.
5. Put template body Markdown in the vertical template assets, then reference it from `template-catalog/v2` with `bodyPath`.
6. For script entrypoints, declare the narrowest possible `reads` and `writes`.
7. Put all preset-specific action logic in `scripts/`, not CLI command dispatch.
8. Run `ha preset validate <manifest>` before publishing the preset.
- 9. Add tests in the correct tier and update `tools/test-tier-manifest.mjs` when adding new test files.
+ 9. Add tests in the correct tier by putting exactly one `// harness-test-tier: fast|contract|integration` declaration on each new Node test file's first line.
## Manifest v2 Contract
Allowed top-level keys are exactly:
- `schema`
- `id`
- `title`
- `vertical`
- `version`
- `kind`
- `extends`
- `kernelVersionRange`
- `capabilityImports`
- `entrypoints`
- `profiles`
- `defaultProfile`
Use `schema: "preset-manifest/v2"`. `profiles` must contain at least one profile, and `defaultProfile` must match one declared profile id. `extends` is optional; when present, the parent preset must be available to the validation context. A standalone `ha preset validate <manifest>` run validates only that one manifest, so omit `extends` in minimal examples unless you also validate through a resolved preset set.
## Minimal Valid Preset
This example was validated with `ha preset validate preset.json`.
```json
{
"schema": "preset-manifest/v2",
"id": "example-note",
"title": "Example Note",
"vertical": "software/coding",
"version": "1.0.0",
"kind": "template-content",
"kernelVersionRange": { "min": "1.0.0", "maxExclusive": "2.0.0" },
"capabilityImports": [
{ "id": "example-note-template", "kind": "template", "version": "1", "required": false }
],
"entrypoints": {
"scaffold": {
"type": "template",
"writes": ["{{outputRoot}}/notes/example.md"],
"templates": {
"note": "template://example/note@1"
}
}
},
"profiles": [
{
"id": "baseline",
"title": "Baseline",
"checkerProfile": "standard",
"templateSelections": [
{
"slot": "example.note",
"templateRef": "template://example/note@1",
"materializeAs": "notes/example.md",
"localePolicy": { "prefer": "project", "fallback": "en-US" }
}
]
}
],
"defaultProfile": "baseline"
}
```
Validate it:
```sh
ha preset validate preset.json
```
## Asset-Based Templates
Preset manifests select templates; template catalogs own template metadata; Markdown files own template bodies. Do not put inline `body` content in `template-catalog/v2`; v2 catalogs use `bodyPath` only.
Preferred package layout:
```text
assets/software-coding/
template-catalog.json
templates/
example.note/
en-US.md
zh-CN.md
presets/
example-note/
preset.json
```
Catalog entry:
```json
{
"id": "example/note",
"version": "1",
"documentKind": "example-note",
"slot": "example.note",
"materializeAs": "notes/example.md",
"frontmatterSchema": "task-package/v2",
"requiredAnchors": ["## Summary"],
"fallbackLocale": "en-US",
"locales": [
{
"locale": "en-US",
"anchors": ["## Summary"],
"bodyPath": "templates/example.note/en-US.md"
},
{
"locale": "zh-CN",
"anchors": ["## Summary"],
"bodyPath": "templates/example.note/zh-CN.md"
}
]
}
```
`templates/example.note/en-US.md` must contain every required anchor:
```md
## Summary
Write the note here.
```
## Script Pattern
Process-action presets use script entrypoints. Use `reads` for input permissions and `writes` for output permissions:
```json
{
"type": "script",
"command": "scripts/preset-action.mjs",
"reads": ["{{outputRoot}}/**"],
"writes": ["{{outputRoot}}/**"],
"inputs": {}
}
```
Scripts should read `process.env.HARNESS_PRESET_CONTEXT`, use only declared paths, and write outputs under `context.outputRoot`.
If the CLI should surface a domain result, write:
```json
{
"ok": true,
"rows": 1,
"report": { "schema": "example-report/v1" }
}
```
to `artifacts/preset-result.json`.
## Review Checklist
- `preset.json` uses `schema: "preset-manifest/v2"`.
- Top-level manifest keys match the v2 allowed key list.
- `profiles` and `defaultProfile` are declared and consistent.
- Any `extends` parent is available to the validation path used.
- Template bodies live in `.md` assets referenced by `template-catalog/v2` `bodyPath`.
- No catalog or manifest example teaches inline `body`.
- `ha preset validate <manifest>` passes for the manifest being published.
- No CLI core branch checks `presetId`, preset title, or action name for behavior.
- No preset script requires permissions not declared in `preset.json`.
- `writes` never grants repo-root write access.
- Any repo-wide read is deliberate and justified by the preset's job.
- Process-action presets are not left as capability-smoke placeholders.
- Tests prove unauthorized script runs fail and authorized runs produce expected artifacts.