@meyverick/agentic 5.0.2
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/AGENTS.md +234 -0
- package/CHANGELOG.md +236 -0
- package/README.md +50 -0
- package/install.ts +349 -0
- package/package.json +37 -0
- package/scripts/check-deps.mjs +587 -0
- package/scripts/git-dl.mjs +100 -0
- package/skills/check/SKILL.md +108 -0
- package/skills/check/evals/benchmark.json +40 -0
- package/skills/check/evals/evals.json +38 -0
- package/skills/check/references/diagnostic-matrix.md +170 -0
- package/skills/check/references/script-anatomy.md +154 -0
- package/skills/create-skill/SKILL.md +291 -0
- package/skills/create-skill/assets/templates/SKILL.md.template +118 -0
- package/skills/create-skill/assets/templates/evals.json.template +36 -0
- package/skills/create-skill/assets/templates/grading.json.template +26 -0
- package/skills/create-skill/evals/benchmark.json +41 -0
- package/skills/create-skill/evals/evals.json +50 -0
- package/skills/create-skill/evals/grading-template.json +36 -0
- package/skills/create-skill/evals/near-misses.json +35 -0
- package/skills/create-skill/evals/trigger-queries.json +80 -0
- package/skills/create-skill/references/antipatterns.md +123 -0
- package/skills/create-skill/references/component-decomposition.md +130 -0
- package/skills/create-skill/references/content-quality-criteria.md +61 -0
- package/skills/create-skill/references/description-optimization.md +90 -0
- package/skills/create-skill/references/eval-methodology.md +100 -0
- package/skills/create-skill/references/fragility-matching.md +88 -0
- package/skills/create-skill/references/gotchas-patterns.md +80 -0
- package/skills/create-skill/references/specification.md +77 -0
- package/skills/create-skill/scripts/audit-antipatterns.mjs +164 -0
- package/skills/create-skill/scripts/compute-benchmark.mjs +111 -0
- package/skills/create-skill/scripts/run-cold-eval.mjs +118 -0
- package/skills/create-skill/scripts/scaffold-skill.mjs +86 -0
- package/skills/create-skill/scripts/validate-routing.mjs +137 -0
- package/skills/create-skill/scripts/validate-structure.mjs +223 -0
- package/skills/design-craft/SKILL.md +134 -0
- package/skills/design-craft/evals/benchmark.json +41 -0
- package/skills/design-craft/evals/evals.json +81 -0
- package/skills/design-craft/references/anti-slop-patterns.md +49 -0
- package/skills/design-craft/references/art-direction.md +89 -0
- package/skills/design-craft/references/design-engineering.md +122 -0
- package/skills/design-craft/references/motion-craft.md +124 -0
- package/skills/design-craft/references/process.md +47 -0
- package/skills/design-craft/references/review-checklist.md +121 -0
- package/skills/guardrails/SKILL.md +118 -0
- package/skills/guardrails/evals/benchmark.json +40 -0
- package/skills/guardrails/evals/evals.json +49 -0
- package/skills/guardrails/references/guardrails-patterns.md +43 -0
- package/skills/okf-docs/SKILL.md +79 -0
- package/skills/okf-docs/evals/benchmark.json +21 -0
- package/skills/okf-docs/evals/evals.json +37 -0
- package/skills/okf-docs/references/okf-spec.md +56 -0
- package/skills/okf-docs/scripts/validate-frontmatter.mjs +130 -0
- package/skills/openspec-harden/SKILL.md +138 -0
- package/skills/openspec-harden/evals/benchmark.json +40 -0
- package/skills/openspec-harden/evals/evals.json +38 -0
- package/skills/openspec-learn/SKILL.md +216 -0
- package/skills/openspec-learn/evals/benchmark.json +44 -0
- package/skills/openspec-learn/evals/evals.json +48 -0
- package/skills/openspec-learn/evals/retrieval-bench.json +27 -0
- package/skills/openspec-learn/references/conflict-handling.md +20 -0
- package/skills/openspec-learn/references/evaluation-methodology.md +126 -0
- package/skills/openspec-learn/references/examples.md +37 -0
- package/skills/openspec-learn/references/improvement-patterns.md +155 -0
- package/skills/openspec-learn/references/report-analysis.md +104 -0
- package/skills/openspec-learn/references/skill-quality.md +103 -0
- package/skills/openspec-learn/references/tool-type-detection.md +30 -0
- package/skills/openspec-report/SKILL.md +104 -0
- package/skills/openspec-report/assets/templates/assessment.md.template +84 -0
- package/skills/openspec-report/assets/templates/report.md.template +92 -0
- package/skills/openspec-report/evals/benchmark.json +44 -0
- package/skills/openspec-report/evals/evals.json +46 -0
- package/skills/qmd-research/SKILL.md +89 -0
- package/skills/qmd-research/evals/benchmark.json +40 -0
- package/skills/qmd-research/evals/evals.json +38 -0
- package/skills/qmd-research/references/index-management.md +69 -0
- package/skills/qmd-research/references/query-craft.md +82 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "guardrails",
|
|
3
|
+
"generated": {
|
|
4
|
+
"by": "process:structural-stage/1.0",
|
|
5
|
+
"at": "2026-09-02T10:56:00Z"
|
|
6
|
+
},
|
|
7
|
+
"stage": "behavioral",
|
|
8
|
+
"structural": {
|
|
9
|
+
"validate_structure": {
|
|
10
|
+
"pass": true,
|
|
11
|
+
"note": "recorded at apply gate (task 6.1)"
|
|
12
|
+
},
|
|
13
|
+
"validate_routing": {
|
|
14
|
+
"checks_total": 6,
|
|
15
|
+
"positive_triggers": 4,
|
|
16
|
+
"anti_triggers": 2,
|
|
17
|
+
"single_responsibility": true
|
|
18
|
+
},
|
|
19
|
+
"evals": {
|
|
20
|
+
"count": 4,
|
|
21
|
+
"assertions": 9,
|
|
22
|
+
"anti_trigger_coverage": true
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"behavioral_dxm": "1×0.33",
|
|
26
|
+
"ship_gate": {
|
|
27
|
+
"criterion": "d = +1 and m >= 0.2",
|
|
28
|
+
"applies_to": "behavioral stage"
|
|
29
|
+
},
|
|
30
|
+
"behavioral": {
|
|
31
|
+
"at": "2026-09-02T08:59:00.285Z",
|
|
32
|
+
"evals": 4,
|
|
33
|
+
"assertions": 12,
|
|
34
|
+
"baseline": 0.5,
|
|
35
|
+
"with_skill": 0.8333,
|
|
36
|
+
"d": 1,
|
|
37
|
+
"m": 0.3333,
|
|
38
|
+
"ship": "pass"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "guardrails",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "I'm about to commit code that handles user auth. Check for security pitfalls.",
|
|
7
|
+
"expected_output": "Guardrails triggers, lists Anti-example 2 (secret leak) and 1 (on* stripping), shows Do: envx + .gitignore, not commit .env.",
|
|
8
|
+
"files": [],
|
|
9
|
+
"assertions": [
|
|
10
|
+
"Guardrails skill triggered",
|
|
11
|
+
"Anti-example for secret commit shown",
|
|
12
|
+
"Correct pattern envx + .gitignore shown"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"id": 2,
|
|
17
|
+
"prompt": "I need to update SvelteKit adapter for deployment to distroless.",
|
|
18
|
+
"expected_output": "Guardrails triggers, shows Anti-example 3: before svelte-adapter-bun vs after @sveltejs/adapter-static + tower-http, with fallback index.html.",
|
|
19
|
+
"files": [],
|
|
20
|
+
"assertions": [
|
|
21
|
+
"Guardrails triggered on deprecated adapter query",
|
|
22
|
+
"Contrast table includes Before adapter-bun vs After adapter-static",
|
|
23
|
+
"Why explains Axum serves static, single distroless binary"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": 3,
|
|
28
|
+
"prompt": "Review my Rust code that checks if user is null and handles lifetimes.",
|
|
29
|
+
"expected_output": "Guardrails triggers, shows Anti-examples 4 (null vs Option) and 5 (lifetime elision) with before/after Rust snippets.",
|
|
30
|
+
"files": [],
|
|
31
|
+
"assertions": [
|
|
32
|
+
"Guardrails triggered on system gotcha",
|
|
33
|
+
"Anti-example 4: null vs Option shown with if let Some",
|
|
34
|
+
"Anti-example 5: lifetime 'a correct snippet shown"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": 4,
|
|
39
|
+
"prompt": "I'm just exploring the codebase, reading the README without modifying anything.",
|
|
40
|
+
"expected_output": "Guardrails does NOT trigger — only reading, no code touching deps/Docker/HTML/auth. Suggest explore mode, no guardrails load.",
|
|
41
|
+
"files": [],
|
|
42
|
+
"assertions": [
|
|
43
|
+
"Guardrails did NOT trigger on read-only prompt",
|
|
44
|
+
"Response does not include Anti-examples",
|
|
45
|
+
"Anti-trigger respected"
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Guardrails Patterns — Level 2
|
|
2
|
+
|
|
3
|
+
On-demand detail for each cross-cutting anti-example in `SKILL.md`. Keep SKILL.md Level 1 inline; this file is Level 2 (~700 tokens).
|
|
4
|
+
|
|
5
|
+
## 1. `on*` Stripping
|
|
6
|
+
|
|
7
|
+
- **Before (wrong):** `<div oncustom={h}>` — Svelte 5 strips unknown `on*` attributes at compile, no warning, handler never fires
|
|
8
|
+
- **After (right):** `<div on:click={h}>` or `<div use:action>` — explicit Svelte 5 event syntax
|
|
9
|
+
- **Signal:** No runtime error, silent loss of interactivity; test via `vite build` + click
|
|
10
|
+
- **Why:** Security sanitization in Svelte 5 — unknown `on*` is treated as potential XSS
|
|
11
|
+
|
|
12
|
+
## 2. Secret Leak
|
|
13
|
+
|
|
14
|
+
- **Before (wrong):** `git add .env && git commit` — secrets in git history forever, leaked to logs via `dokku config:set` echo
|
|
15
|
+
- **After (right):** `echo ".env" >> .gitignore` at repo root + each submodule; `envx set KEY`; `dokku config:set` guarded (only when var unset/changed, output suppressed)
|
|
16
|
+
- **Signal:** `git log --all -p | grep WARERA_KEY` or `deploy-dokku.sh` stdout contains `...KEY=...`
|
|
17
|
+
- **Why:** `AGENTS.md` Must-follow `NEVER commit credentials/.env` + GDPR Zero Trust — rotate leaked secrets immediately
|
|
18
|
+
|
|
19
|
+
## 3. Deprecated Adapter
|
|
20
|
+
|
|
21
|
+
- **Before (wrong):** `svelte-adapter-bun` — Bun-specific, incompatible with `gcr.io/distroless/static-debian13:nonroot` single binary
|
|
22
|
+
- **After (right):** `@sveltejs/adapter-static` with `fallback: 'index.html'` + Axum `tower-http` `ServeDir`/`ServeFile`; `Vite → Rust musl → distroless`
|
|
23
|
+
- **Signal:** `vite build` outputs `adapter-bun` warning, or Docker `CMD` fails on distroless (no Bun)
|
|
24
|
+
- **Why:** 3.0.0 canonical 5-tier — Axum/Tokio sole coordinator, static SPA served by `tower-http`, preserves file routing without Bun
|
|
25
|
+
|
|
26
|
+
## 4. `null` vs `Option`
|
|
27
|
+
|
|
28
|
+
- **Before (wrong, C# model):** `if (user != null) { use(user) }` — assumes `null` is valid for any reference
|
|
29
|
+
- **After (right, Rust model):** `if let Some(u) = user { use(u) }` or `user.map(|u| ...)` — absence encoded in type `Option<T>`
|
|
30
|
+
- **Signal:** `cargo clippy` or `rustc` error `expected Option<T>, found T` or `NullReferenceException` becomes compile error
|
|
31
|
+
- **Why:** Rust has no `null` — `Option` forces handling of `None` at compile time, prevents runtime panic
|
|
32
|
+
|
|
33
|
+
## 5. Lifetime Elision
|
|
34
|
+
|
|
35
|
+
- **Before (wrong):** `fn longest(x: &str, y: &str) -> &str` — elides lifetimes, compiler cannot infer borrowing
|
|
36
|
+
- **After (right):** `fn longest<'a>(x: &'a str, y: &'a str) -> &'a str` — explicit `'a` ties output lifetime to inputs
|
|
37
|
+
- **Signal:** `rustc` `error[E0106]: missing lifetime specifier` or `borrow checker: cannot return value referencing temporary`
|
|
38
|
+
- **Why:** Borrow checker tracks references — output `&str` must borrow from `x` or `y`, explicit `'a` declares that
|
|
39
|
+
|
|
40
|
+
## When to Use This File
|
|
41
|
+
|
|
42
|
+
- Task touches `deps/Docker/HTML/auth` and `SKILL.md` Level 1 table was insufficient — read this file on-demand
|
|
43
|
+
- Never load at startup — `AGENTS.md` pointer loads `SKILL.md` first; this file is Tier 3
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: okf-docs
|
|
3
|
+
description: >
|
|
4
|
+
Author OKF v0.2-compliant documents — ADRs, module documentation, decision
|
|
5
|
+
records — with mandatory provenance frontmatter (type, generated by/at,
|
|
6
|
+
sources, status lifecycle) and mechanical validation via the bundled script.
|
|
7
|
+
Use when writing or updating any structured document in this workspace, or
|
|
8
|
+
when adding provenance to existing docs. Do NOT use when generating OpenSpec
|
|
9
|
+
reports from archived changes or analyzing reports for skill improvements.
|
|
10
|
+
allowed-tools: Bash(node:*), Bash(bun:*)
|
|
11
|
+
license: MIT
|
|
12
|
+
compatibility: Requires node or bun for the bundled validator.
|
|
13
|
+
metadata:
|
|
14
|
+
author: agentic
|
|
15
|
+
version: "1.0.0"
|
|
16
|
+
positive_triggers:
|
|
17
|
+
- "write an ADR or decision record"
|
|
18
|
+
- "create module documentation"
|
|
19
|
+
- "add OKF frontmatter provenance to a document"
|
|
20
|
+
anti_triggers:
|
|
21
|
+
- "generate an OpenSpec report from an archived change"
|
|
22
|
+
- "analyze reports and improve skills"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Okf Docs
|
|
26
|
+
|
|
27
|
+
Author structured documents with mandatory provenance. Every deliverable passes the bundled validator before hand-off.
|
|
28
|
+
|
|
29
|
+
## Procedure
|
|
30
|
+
|
|
31
|
+
### 1. Select Document Type
|
|
32
|
+
|
|
33
|
+
| Intent | `type` value |
|
|
34
|
+
|--------|--------------|
|
|
35
|
+
| Architecture/design decision | Architecture Decision Record |
|
|
36
|
+
| Module reference doc | Module Documentation |
|
|
37
|
+
| Workspace directive | SystemDirective |
|
|
38
|
+
| Skill definition | Skill |
|
|
39
|
+
| Session report | Report / Assessment |
|
|
40
|
+
|
|
41
|
+
### 2. Apply Frontmatter Contract
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
---
|
|
45
|
+
okf_version: "0.2"
|
|
46
|
+
type: <from table above>
|
|
47
|
+
title: <short name>
|
|
48
|
+
description: <one-line summary>
|
|
49
|
+
generated: { by: <actor>, at: <ISO 8601> }
|
|
50
|
+
sources:
|
|
51
|
+
- { id: <source-id>, resource: <url|path> }
|
|
52
|
+
status: draft # draft | stable | deprecated
|
|
53
|
+
stale_after: YYYY-MM-DD
|
|
54
|
+
---
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Actor values for `generated.by`: `<producer>/<version>` (agents) · `human:<id>` (people) · `process:<id>` (automation). Full semantics: [references/okf-spec.md](references/okf-spec.md).
|
|
58
|
+
|
|
59
|
+
### 3. Attribute Claims
|
|
60
|
+
|
|
61
|
+
Body claims sourced from `sources:` entries cite via footnotes (`[^source-id]`). No uncited external facts.
|
|
62
|
+
|
|
63
|
+
### 4. Lifecycle
|
|
64
|
+
|
|
65
|
+
Set `status: draft` on creation. Flip to `stable` after human review (`verified: { by: human:<id>, at }`). Set `stale_after` when content is time-sensitive. Deprecated docs keep standing but state successor.
|
|
66
|
+
|
|
67
|
+
### 5. Validate Before Delivery
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
bun scripts/validate-frontmatter.mjs <document.md>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Envelope must read `pass: true`. Fix named FAIL entries; re-run until clean.
|
|
74
|
+
|
|
75
|
+
## Gotchas
|
|
76
|
+
|
|
77
|
+
- Dates are ISO 8601 only — no locale formats.
|
|
78
|
+
- `stale_after` must not predate `generated.at`.
|
|
79
|
+
- README files are promotional (zero tech detail) — OKF applies to technical docs, wikis, ADRs, directives.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "okf-docs",
|
|
3
|
+
"generated": { "by": "process:structural-stage/1.0", "at": "2026-08-23T19:45:00Z" },
|
|
4
|
+
"stage": "structural",
|
|
5
|
+
"structural": {
|
|
6
|
+
"validate_structure": { "pass": null, "note": "recorded at apply gate (task 5.1)" },
|
|
7
|
+
"validate_routing": {
|
|
8
|
+
"checks_total": 6,
|
|
9
|
+
"positive_triggers": 3,
|
|
10
|
+
"anti_triggers": 2,
|
|
11
|
+
"single_responsibility": true
|
|
12
|
+
},
|
|
13
|
+
"evals": {
|
|
14
|
+
"count": 3,
|
|
15
|
+
"assertions": 8,
|
|
16
|
+
"anti_trigger_coverage": true
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"behavioral_dxm": "pending_cold_agent_run",
|
|
20
|
+
"ship_gate": { "criterion": "d = +1 and m >= 0.2", "applies_to": "behavioral stage" }
|
|
21
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "okf-docs",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "Write an ADR documenting our decision to adopt PostgreSQL as the central datastore.",
|
|
7
|
+
"expected_output": "Skill activates; authored document carries OKF v0.2 frontmatter (type: Architecture Decision Record, generated actor-convention provenance, sources list) and passes scripts/validate-frontmatter.mjs before delivery.",
|
|
8
|
+
"files": [],
|
|
9
|
+
"assertions": [
|
|
10
|
+
"Frontmatter contains type + generated.by/at in actor convention",
|
|
11
|
+
"Sources listed with footnote attribution for the decision context",
|
|
12
|
+
"Validator executed with pass:true before delivery"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"id": 2,
|
|
17
|
+
"prompt": "Generate an OpenSpec report from the archived change and analyze it for skill improvements.",
|
|
18
|
+
"expected_output": "okf-docs does NOT activate. Report generation belongs to opsx-report; analysis belongs to opsx-learn.",
|
|
19
|
+
"files": [],
|
|
20
|
+
"assertions": [
|
|
21
|
+
"Anti-trigger fires: request routes to opsx-report/opsx-learn pipeline",
|
|
22
|
+
"No OKF authoring procedure started"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": 3,
|
|
27
|
+
"prompt": "Add proper frontmatter to this legacy module doc so it passes validation.",
|
|
28
|
+
"expected_output": "Agent applies OKF v0.2 frontmatter (type per intent, generated provenance, status lifecycle), runs validate-frontmatter.mjs, iterates until pass:true, and leaves body content unaltered beyond attribution footnotes if claims need sourcing.",
|
|
29
|
+
"files": [],
|
|
30
|
+
"assertions": [
|
|
31
|
+
"Validator run on the updated document",
|
|
32
|
+
"Final envelope pass:true",
|
|
33
|
+
"Actor convention respected (human:<id> for user-authored claims)"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
okf_version: "0.2"
|
|
3
|
+
type: Reference
|
|
4
|
+
title: OKF v0.2 Contract
|
|
5
|
+
description: Distilled Open Knowledge Format v0.2 requirements — frontmatter schema, actor convention, trust lifecycle, separation rules, syntax conventions.
|
|
6
|
+
generated: { by: ox-alpha/1.0, at: 2026-08-23T12:00:00Z }
|
|
7
|
+
sources:
|
|
8
|
+
- { id: mini, resource: prototype/documentation-okf/AGENTS.md }
|
|
9
|
+
- { id: spec, resource: references/okf/SPEC.md }
|
|
10
|
+
status: stable
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# OKF v0.2 Contract
|
|
14
|
+
|
|
15
|
+
## Frontmatter Schema
|
|
16
|
+
|
|
17
|
+
| Field | Required | Constraint |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `okf_version` | yes | `"0.2"` |
|
|
20
|
+
| `type` | yes | Document kind (ADR · Module Documentation · SystemDirective · Skill · Report · Assessment) |
|
|
21
|
+
| `title` | yes | Short name |
|
|
22
|
+
| `description` | yes | One-line summary |
|
|
23
|
+
| `generated` | yes | `{ by: <actor>, at: <ISO 8601> }` — replaces deprecated `timestamp` |
|
|
24
|
+
| `sources` | recommended | List of `{ id, resource: <url\|path> }` — body claims cite via `[^source-id]` footnotes; replaces deprecated `# Citations` heading |
|
|
25
|
+
| `verified` | optional | `{ by: human:<id>, at }` — human-reviewed tier |
|
|
26
|
+
| `status` | recommended | `draft` \| `stable` \| `deprecated` |
|
|
27
|
+
| `stale_after` | optional | `YYYY-MM-DD` — re-verify date for time-sensitive content |
|
|
28
|
+
|
|
29
|
+
## Actor Convention
|
|
30
|
+
|
|
31
|
+
`generated.by` / `verified.by` values:
|
|
32
|
+
- `<producer>/<version>` — agents (e.g. `ox-alpha/1.0`, `openspec-report/1.0`)
|
|
33
|
+
- `human:<id>` — people (only prefix granting human-reviewed tier)
|
|
34
|
+
- `process:<id>` — automation
|
|
35
|
+
|
|
36
|
+
## Trust & Lifecycle
|
|
37
|
+
|
|
38
|
+
Created as `draft`. Human review flips to `stable` and records `verified`. Superseded content → `deprecated` (state successor). Time-sensitive docs carry `stale_after`; past that date, re-verify before trusting.
|
|
39
|
+
|
|
40
|
+
## Separation Rules
|
|
41
|
+
|
|
42
|
+
- **README**: promotional showcase for everyday users. Zero technical detail. Zero terminal blocks.
|
|
43
|
+
- **Wiki** (`<module>/wiki/`): technical documentation per module. Synced remotely only if public.
|
|
44
|
+
- **AGENTS.md**: agent operational directives — never duplicated into human docs.
|
|
45
|
+
|
|
46
|
+
## Syntax Conventions
|
|
47
|
+
|
|
48
|
+
Codebase patterns via `[✅ GOOD]` vs `[❌ BAD]` code blocks. No verbose prose explanations.
|
|
49
|
+
|
|
50
|
+
## Progressive Disclosure
|
|
51
|
+
|
|
52
|
+
`index.md` at directory roots synthesizes catalogs. Absolute markdown links (`[/backend/schema.md]`). Heavy reference data offloaded to `references/`, loaded on demand.
|
|
53
|
+
|
|
54
|
+
## Reference Ingestion [CRITICAL]
|
|
55
|
+
|
|
56
|
+
`./references/` present → scan + index via QMD → treat as READ-ONLY. Maintenance after doc mutations: `qmd update && qmd embed --chunk-strategy auto`.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* validate-frontmatter.mjs — OKF v0.2 frontmatter gate
|
|
4
|
+
* Usage: node validate-frontmatter.mjs <document.md>
|
|
5
|
+
* Output: unified JSON envelope {target, pass, checks:[{id,status,detail}], summary}
|
|
6
|
+
*
|
|
7
|
+
* Checks: required keys (type/generated.by/at) · ISO 8601 formats · actor
|
|
8
|
+
* convention values · status enum · stale_after chronology.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { readFileSync, existsSync } from 'fs';
|
|
12
|
+
|
|
13
|
+
const docPath = process.argv[2];
|
|
14
|
+
|
|
15
|
+
if (!docPath) {
|
|
16
|
+
console.error(JSON.stringify({ error: 'Usage: node validate-frontmatter.mjs <document.md>' }));
|
|
17
|
+
process.exit(2);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!existsSync(docPath)) {
|
|
21
|
+
console.log(JSON.stringify({
|
|
22
|
+
target: docPath,
|
|
23
|
+
pass: false,
|
|
24
|
+
checks: [{ id: 'okf.file', status: 'FAIL', detail: 'Document not found' }],
|
|
25
|
+
summary: { total: 1, pass: 0, fail: 1, warn: 0, skip: 0 }
|
|
26
|
+
}));
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const content = readFileSync(docPath, 'utf-8');
|
|
31
|
+
const checks = [];
|
|
32
|
+
|
|
33
|
+
const add = (id, ok, detail) => checks.push({ id, status: ok ? 'PASS' : 'FAIL', detail });
|
|
34
|
+
const warn = (id, detail) => checks.push({ id, status: 'WARN', detail });
|
|
35
|
+
|
|
36
|
+
// Extract frontmatter
|
|
37
|
+
const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
38
|
+
if (!fmMatch) {
|
|
39
|
+
console.log(JSON.stringify({
|
|
40
|
+
target: docPath,
|
|
41
|
+
pass: false,
|
|
42
|
+
checks: [{ id: 'okf.frontmatter', status: 'FAIL', detail: 'No frontmatter block found' }],
|
|
43
|
+
summary: { total: 1, pass: 0, fail: 1, warn: 0, skip: 0 }
|
|
44
|
+
}));
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
add('okf.frontmatter', true, 'Frontmatter block present');
|
|
48
|
+
|
|
49
|
+
// Parse simple YAML subset (top-level + one nested level for generated)
|
|
50
|
+
const fm = fmMatch[1];
|
|
51
|
+
function get(key) {
|
|
52
|
+
const m = fm.match(new RegExp(`^${key}:\\s*(.+)$`, 'm'));
|
|
53
|
+
return m ? m[1].trim().replace(/^["']|["']$/g, '') : null;
|
|
54
|
+
}
|
|
55
|
+
function getNested(parent, key) {
|
|
56
|
+
const m = fm.match(new RegExp(`^${parent}:\\s*\\{\\s*([^}]*)\\}`, 'm'));
|
|
57
|
+
if (!m) return null;
|
|
58
|
+
const inner = m[1].match(new RegExp(`${key}:\\s*([^,}]+)`));
|
|
59
|
+
return inner ? inner[1].trim() : null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// type (FAIL if missing/empty)
|
|
63
|
+
const type = get('type');
|
|
64
|
+
add('okf.type', !!type, type ? `type = ${type}` : "Missing required 'type'");
|
|
65
|
+
|
|
66
|
+
// generated.by + at (FAIL if missing; actor convention + ISO for at)
|
|
67
|
+
const by = getNested('generated', 'by');
|
|
68
|
+
const at = getNested('generated', 'at');
|
|
69
|
+
add('okf.generated-by', !!by, by ? `generated.by = ${by}` : "Missing required 'generated.by'");
|
|
70
|
+
|
|
71
|
+
const actorRe = /^([a-z0-9][a-z0-9-]*\/\d+(\.\d+)*|human:[a-z0-9-]+|process:[a-z0-9-]+)$/;
|
|
72
|
+
add('okf.actor-convention',
|
|
73
|
+
!!by && actorRe.test(by),
|
|
74
|
+
by ? (actorRe.test(by) ? `Actor '${by}' matches convention` : `Actor '${by}' violates convention (<producer>/<version> | human:<id> | process:<id>)`) : 'No actor to check');
|
|
75
|
+
|
|
76
|
+
const isoRe = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?Z)?$/;
|
|
77
|
+
add('okf.generated-at-format',
|
|
78
|
+
!!at && isoRe.test(at),
|
|
79
|
+
at ? (isoRe.test(at) ? `generated.at = ${at}` : `'${at}' is not ISO 8601`) : "Missing required 'generated.at'");
|
|
80
|
+
|
|
81
|
+
// sources (WARN if missing — recommended not mandatory)
|
|
82
|
+
const hasSources = /^sources:/m.test(fm);
|
|
83
|
+
if (!hasSources) warn('okf.sources', "Missing 'sources:' list — claims uncited (recommended)");
|
|
84
|
+
|
|
85
|
+
// status enum (FAIL on invalid value, WARN if missing)
|
|
86
|
+
const status = get('status');
|
|
87
|
+
if (!status) {
|
|
88
|
+
warn('okf.status', "Missing 'status' (draft | stable | deprecated)");
|
|
89
|
+
} else if (!['draft', 'stable', 'deprecated'].includes(status)) {
|
|
90
|
+
failStatus(status);
|
|
91
|
+
} else {
|
|
92
|
+
add('okf.status', true, `status = ${status}`);
|
|
93
|
+
}
|
|
94
|
+
function failStatus(value) {
|
|
95
|
+
add('okf.status', false, `Invalid status '${value}' — must be draft | stable | deprecated`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// stale_after chronology vs generated.at
|
|
99
|
+
const stale = get('stale_after');
|
|
100
|
+
if (stale) {
|
|
101
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(stale)) {
|
|
102
|
+
add('okf.stale-after', false, `stale_after '${stale}' is not YYYY-MM-DD`);
|
|
103
|
+
} else if (at) {
|
|
104
|
+
const genDay = at.slice(0, 10);
|
|
105
|
+
add('okf.stale-after', stale >= genDay,
|
|
106
|
+
stale >= genDay ? `stale_after ${stale} ≥ generated ${genDay}` : `stale_after ${stale} predates generation ${genDay}`);
|
|
107
|
+
} else {
|
|
108
|
+
add('okf.stale-after', true, `stale_after = ${stale} (no generated.at to compare)`);
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
warn('okf.stale-after', 'No stale_after set (fine for non-time-sensitive docs)');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Unified envelope
|
|
115
|
+
const fails = checks.filter(c => c.status === 'FAIL').length;
|
|
116
|
+
console.log(JSON.stringify({
|
|
117
|
+
target: docPath,
|
|
118
|
+
pass: fails === 0,
|
|
119
|
+
checks,
|
|
120
|
+
summary: {
|
|
121
|
+
total: checks.length,
|
|
122
|
+
pass: checks.filter(c => c.status === 'PASS').length,
|
|
123
|
+
fail: fails,
|
|
124
|
+
warn: checks.filter(c => c.status === 'WARN').length,
|
|
125
|
+
skip: checks.filter(c => c.status === 'SKIP').length
|
|
126
|
+
}
|
|
127
|
+
}));
|
|
128
|
+
|
|
129
|
+
process.exit(fails > 0 ? 1 : 0);
|
|
130
|
+
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: openspec-harden
|
|
3
|
+
description: >
|
|
4
|
+
Harden an existing OpenSpec change for cold application by a fresh agent.
|
|
5
|
+
Use when you have just run /opsx-propose and want to enrich the proposal,
|
|
6
|
+
specs, design, and tasks with concrete file paths, code blocks, verify steps,
|
|
7
|
+
and grounded codebase context before handing to a cold agent for /opsx-apply.
|
|
8
|
+
Do NOT use when implementing changes (use openspec-apply-change), creating a
|
|
9
|
+
new change from scratch, or when no change exists yet.
|
|
10
|
+
allowed-tools: Bash(openspec:*), Read, Grep
|
|
11
|
+
license: MIT
|
|
12
|
+
compatibility: Requires openspec CLI and ripgrep.
|
|
13
|
+
metadata:
|
|
14
|
+
author: agentic
|
|
15
|
+
version: "1.0.0"
|
|
16
|
+
positive_triggers:
|
|
17
|
+
- "harden proposal for cold apply"
|
|
18
|
+
- "improve change for fresh agent"
|
|
19
|
+
- "enrich specs and tasks with file paths"
|
|
20
|
+
anti_triggers:
|
|
21
|
+
- "implement changes from tasks or apply change"
|
|
22
|
+
- "implement the change and edit project code"
|
|
23
|
+
- "create a new change from scratch"
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Openspec Proposal Improve
|
|
27
|
+
|
|
28
|
+
Enrich an existing change in place so a cold agent with no conversation memory can apply it correctly.
|
|
29
|
+
|
|
30
|
+
**Planning boundary:** This skill operates in planning-only mode. Do NOT edit project code — only files under `openspec/changes/<name>/`. Proposal Why/What Changes are append-only: preserve original intent verbatim and mark any inferred addition as `Assumption:` or `Inferred:`.
|
|
31
|
+
|
|
32
|
+
## Cold-Readiness Checklist (gate)
|
|
33
|
+
|
|
34
|
+
All must pass or be explicitly marked `Needs human decision: <question>` before claiming hardening complete:
|
|
35
|
+
|
|
36
|
+
- [ ] Every task has concrete file path (`path/to/file.ts:line` or `new file to create`) + exact shell command where applicable + `Verify:` clause (command, grep, or observable)
|
|
37
|
+
- [ ] Every spec scenario is testable, has concrete example values, and includes at least one error/edge case
|
|
38
|
+
- [ ] Design lists integration points grounded via codebase search as `file:line` refs
|
|
39
|
+
- [ ] Design has rollback plan (or `Rollback: N/A — docs only` if truly no code)
|
|
40
|
+
- [ ] No vague tasks remain ("update auth system" → must be split)
|
|
41
|
+
- [ ] No untestable scenario remains ("works correctly" → must have WHEN/THEN with values)
|
|
42
|
+
- [ ] Proposal Why/What Changes preserve original intent (no rewriting, only appending with Assumption/Inferred tags)
|
|
43
|
+
|
|
44
|
+
If any item fails and cannot be inferred from codebase, pause and emit `Needs human decision: <question>` — do not hallucinate.
|
|
45
|
+
|
|
46
|
+
Idempotent re-run: Running the skill twice on an already-hardened change without intervening edits SHALL produce no further artifact changes (idempotent).
|
|
47
|
+
|
|
48
|
+
## Workflow — 6 Steps
|
|
49
|
+
|
|
50
|
+
### Step 1: Load
|
|
51
|
+
|
|
52
|
+
- Resolve store (if any):
|
|
53
|
+
```bash
|
|
54
|
+
openspec store list --json
|
|
55
|
+
```
|
|
56
|
+
If a store is selected (explicit user selection, or project `store:` pointer, or global `defaultStore`), treat `--store <id>` as sticky on every openspec command below. All examples without the flag are shorthand — append the flag before running.
|
|
57
|
+
- Load change:
|
|
58
|
+
```bash
|
|
59
|
+
openspec status --change "<name>" --json
|
|
60
|
+
```
|
|
61
|
+
Parse `planningHome`, `changeRoot`, `artifactPaths`, `actionContext`. Use `artifactPaths` as the only source of artifact file paths — do not guess.
|
|
62
|
+
- Read every file in `artifactPaths` (proposal, specs, design, tasks) from disk. Re-read even if seen before (user may have edited).
|
|
63
|
+
|
|
64
|
+
### Step 2: Ground
|
|
65
|
+
|
|
66
|
+
- Use `Grep` (ripgrep) to discover integration points: spec names, file paths, callers, schema files, tests, existing patterns. Example:
|
|
67
|
+
```bash
|
|
68
|
+
Grep pattern="auth.*middleware" path="src"
|
|
69
|
+
Grep pattern="Requirement:" path="openspec/specs"
|
|
70
|
+
```
|
|
71
|
+
- Use `Read` to verify every candidate file path exists. If a path does not exist, mark task as `new file to create` — do not invent a path that fails `Grep`.
|
|
72
|
+
- Record all inferred additions as `Assumption:` or `Inferred:` in the enriched artifact. Inferred file paths must be verified by `Grep`/`Read` or explicitly marked as new.
|
|
73
|
+
|
|
74
|
+
Requires `Bash(openspec:*)` for status/instructions/validate and `Grep` for grounding. Every added path must be verified or marked new.
|
|
75
|
+
|
|
76
|
+
### Step 3: Audit
|
|
77
|
+
|
|
78
|
+
Compare loaded artifacts against the Cold-Readiness Checklist above. Build a gap list per artifact:
|
|
79
|
+
- `proposal.md`: missing constraints, edge cases, out-of-scope, dependencies, rollback
|
|
80
|
+
- `specs/**/spec.md`: vague scenarios, missing examples, missing error cases, untestable WHEN/THEN
|
|
81
|
+
- `design.md`: missing file:line integration points, missing sequence/data-flow, missing rollback, missing ASCII diagram for cross-file flows
|
|
82
|
+
- `tasks.md`: vague tasks, missing file:line, missing command, missing Verify, unordered dependencies
|
|
83
|
+
|
|
84
|
+
If gap requires human decision (material ambiguity on scope/behavior/compatibility), prepare `Needs human decision: <question>` and pause per guardrails.
|
|
85
|
+
|
|
86
|
+
### Step 4: Enrich
|
|
87
|
+
|
|
88
|
+
Apply per-artifact rules, grounded in Step 2:
|
|
89
|
+
|
|
90
|
+
- **proposal.md**: append only. Add `Assumption:`/`Inferred:` sections for missing constraints, edge cases (`Edge cases: ...`), out-of-scope (`Out-of-scope: ...`), dependencies (`Depends on: ...` with file paths). Never rewrite Why.
|
|
91
|
+
- **specs/**/spec.md**: make scenarios concrete: add example payloads/code blocks, add error case scenario per requirement, ensure 4-hash `#### Scenario` format. Preserve existing scenarios; add, don't replace.
|
|
92
|
+
- **design.md**: add `Integration points:` list as `file:line` refs from Ground step, add `Sequence:` or ASCII diagram if cross-file, add `Rollback:` plan. Keep existing Decisions.
|
|
93
|
+
- **tasks.md**: split vague tasks into ordered small tasks (one file per task where possible) with `file:line`, exact command (`bun run check`, `cargo test`, etc.), and `Verify:` clause. Order topologically; note `requires X.Y` where needed.
|
|
94
|
+
|
|
95
|
+
Rules: Do NOT edit project code — only `openspec/changes/<name>/`. Preserve original intent — proposal Why/What Changes are append-only.
|
|
96
|
+
|
|
97
|
+
### Step 5: Validate
|
|
98
|
+
|
|
99
|
+
- Re-run:
|
|
100
|
+
```bash
|
|
101
|
+
openspec status --change "<name>" --json
|
|
102
|
+
openspec validate --change "<name>" # or openspec validate --specs if needed
|
|
103
|
+
```
|
|
104
|
+
With store flag if applicable (sticky).
|
|
105
|
+
- Re-evaluate Cold-Readiness Checklist. If any item still fails, loop to Enrich or pause for human decision.
|
|
106
|
+
- Verify idempotent re-run: second run without edits should be no-op.
|
|
107
|
+
- Verify idempotence note: second run without edits should be no-op.
|
|
108
|
+
|
|
109
|
+
### Step 6: Summarize
|
|
110
|
+
|
|
111
|
+
Display:
|
|
112
|
+
- Change name and store used
|
|
113
|
+
- What was enriched per artifact (bullets) vs what was already cold-ready
|
|
114
|
+
- Any `Assumption:`/`Inferred:` added and any `Needs human decision:` still open
|
|
115
|
+
- Checklist result (pass/fail per item) and `openspec validate` result
|
|
116
|
+
- Next: `Agent 2 (cold) can now run /opsx-apply <name>` or `openspec-apply-change`
|
|
117
|
+
|
|
118
|
+
## Store Handling
|
|
119
|
+
|
|
120
|
+
Mirror `openspec-propose`/`openspec-apply-change`: discover via `openspec store list --json`, pass `--store <id>` on every openspec command that accepts it, keep sticky. Hints printed by commands already carry the flag; keep it on follow-ups. Without a store, act on nearest local `openspec/` root.
|
|
121
|
+
|
|
122
|
+
## Guardrails
|
|
123
|
+
|
|
124
|
+
- Read-only commands and file reads (`Read`, `Grep`, `Bash(openspec status/instructions)`) need no confirmation.
|
|
125
|
+
- Keep the planning boundary: Do NOT edit project code. Only `openspec/changes/<name>/` is writable.
|
|
126
|
+
- Preserve original intent: proposal.md Why/What Changes are append-only. Never rewrite author's Why.
|
|
127
|
+
- Ground every added path with `Grep`/`Read` or mark `new file to create`. Do not hallucinate file paths.
|
|
128
|
+
- Never copy `<context>`/`<rules>` verbatim into artifacts — apply as constraints.
|
|
129
|
+
- Pause on material ambiguity — do not absorb scope silently.
|
|
130
|
+
|
|
131
|
+
## Reference
|
|
132
|
+
|
|
133
|
+
- Direct triggering: harnesses invoke this skill directly via `/openspec-harden <change-name>` (no prompt shim needed).
|
|
134
|
+
- Install: `project/install.ts` copies `project/skills/*` → `.agents/skills/` atomically — no manual wiring needed.
|
|
135
|
+
|
|
136
|
+
## Related Skills
|
|
137
|
+
|
|
138
|
+
Complements `openspec-learn` (proposal generation) and `openspec-report` (report meditation) — this skill hardens proposals for cold apply, while those create and reflect.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "openspec-harden",
|
|
3
|
+
"generated": {
|
|
4
|
+
"by": "process:structural-stage/1.0",
|
|
5
|
+
"at": "2026-09-12T11:38:00Z"
|
|
6
|
+
},
|
|
7
|
+
"stage": "behavioral",
|
|
8
|
+
"structural": {
|
|
9
|
+
"validate_structure": {
|
|
10
|
+
"pass": true,
|
|
11
|
+
"note": "recorded at apply gate (task 3.4)"
|
|
12
|
+
},
|
|
13
|
+
"validate_routing": {
|
|
14
|
+
"checks_total": 6,
|
|
15
|
+
"positive_triggers": 3,
|
|
16
|
+
"anti_triggers": 3,
|
|
17
|
+
"single_responsibility": true
|
|
18
|
+
},
|
|
19
|
+
"evals": {
|
|
20
|
+
"count": 3,
|
|
21
|
+
"assertions": 9,
|
|
22
|
+
"anti_trigger_coverage": true
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"behavioral_dxm": "1×0.33",
|
|
26
|
+
"ship_gate": {
|
|
27
|
+
"criterion": "d = +1 and m >= 0.2",
|
|
28
|
+
"applies_to": "behavioral stage"
|
|
29
|
+
},
|
|
30
|
+
"behavioral": {
|
|
31
|
+
"at": "2026-09-12T09:38:54.142Z",
|
|
32
|
+
"evals": 3,
|
|
33
|
+
"assertions": 9,
|
|
34
|
+
"baseline": 0.5556,
|
|
35
|
+
"with_skill": 0.8889,
|
|
36
|
+
"d": 1,
|
|
37
|
+
"m": 0.3333,
|
|
38
|
+
"ship": "pass"
|
|
39
|
+
}
|
|
40
|
+
}
|