@warpgogol/forge 2.9.2 → 2.9.4
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 +14 -8
- package/README.uk.md +14 -0
- package/dist/os/adr/handlers/implement-stamp.d.ts.map +1 -1
- package/dist/os/adr/handlers/implement-stamp.js +6 -0
- package/dist/os/adr/handlers/implement-stamp.js.map +1 -1
- package/dist/os/adr/handlers/validate.d.ts.map +1 -1
- package/dist/os/adr/handlers/validate.js +8 -0
- package/dist/os/adr/handlers/validate.js.map +1 -1
- package/dist/os/compass/handlers/compass-audit-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-audit-handler.js +22 -0
- package/dist/os/compass/handlers/compass-audit-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-change-summary-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-change-summary-handler.js +6 -0
- package/dist/os/compass/handlers/compass-change-summary-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-inventory-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-inventory-handler.js +19 -0
- package/dist/os/compass/handlers/compass-inventory-handler.js.map +1 -1
- package/dist/os/exploration/handlers/archive.d.ts.map +1 -1
- package/dist/os/exploration/handlers/archive.js +6 -0
- package/dist/os/exploration/handlers/archive.js.map +1 -1
- package/dist/os/exploration/handlers/list.d.ts.map +1 -1
- package/dist/os/exploration/handlers/list.js +8 -0
- package/dist/os/exploration/handlers/list.js.map +1 -1
- package/dist/os/exploration/handlers/show.d.ts.map +1 -1
- package/dist/os/exploration/handlers/show.js +6 -0
- package/dist/os/exploration/handlers/show.js.map +1 -1
- package/dist/os/program/handlers/complete.d.ts.map +1 -1
- package/dist/os/program/handlers/complete.js +18 -0
- package/dist/os/program/handlers/complete.js.map +1 -1
- package/dist/os/program/handlers/lease.js +6 -0
- package/dist/os/program/handlers/lease.js.map +1 -1
- package/dist/os/program/handlers/seal.d.ts.map +1 -1
- package/dist/os/program/handlers/seal.js +12 -0
- package/dist/os/program/handlers/seal.js.map +1 -1
- package/dist/os/program/handlers/validate.js +6 -0
- package/dist/os/program/handlers/validate.js.map +1 -1
- package/dist/os/rfc/acceptance.d.ts.map +1 -1
- package/dist/os/rfc/acceptance.js +8 -0
- package/dist/os/rfc/acceptance.js.map +1 -1
- package/dist/os/rfc/handlers/check.d.ts.map +1 -1
- package/dist/os/rfc/handlers/check.js +8 -0
- package/dist/os/rfc/handlers/check.js.map +1 -1
- package/dist/os/rfc/handlers/implement-stamp.d.ts.map +1 -1
- package/dist/os/rfc/handlers/implement-stamp.js +6 -0
- package/dist/os/rfc/handlers/implement-stamp.js.map +1 -1
- package/dist/os/rfc/handlers/list-create.d.ts.map +1 -1
- package/dist/os/rfc/handlers/list-create.js +20 -0
- package/dist/os/rfc/handlers/list-create.js.map +1 -1
- package/dist/os/rfc/handlers/validate.d.ts.map +1 -1
- package/dist/os/rfc/handlers/validate.js +8 -0
- package/dist/os/rfc/handlers/validate.js.map +1 -1
- package/dist/os/session/handlers/validate.d.ts.map +1 -1
- package/dist/os/session/handlers/validate.js +8 -0
- package/dist/os/session/handlers/validate.js.map +1 -1
- package/dist/os/spec/live-spec-list.d.ts.map +1 -1
- package/dist/os/spec/live-spec-list.js +8 -0
- package/dist/os/spec/live-spec-list.js.map +1 -1
- package/dist/os/spec/live-spec-merge.js +2 -2
- package/dist/os/spec/live-spec-merge.js.map +1 -1
- package/dist/os/spec/live-spec-show.d.ts.map +1 -1
- package/dist/os/spec/live-spec-show.js +6 -0
- package/dist/os/spec/live-spec-show.js.map +1 -1
- package/dist/os/spec/spec-materialize.d.ts.map +1 -1
- package/dist/os/spec/spec-materialize.js +6 -0
- package/dist/os/spec/spec-materialize.js.map +1 -1
- package/dist/os/spec/spec-status.d.ts.map +1 -1
- package/dist/os/spec/spec-status.js +6 -0
- package/dist/os/spec/spec-status.js.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-lock-recover.d.ts.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-lock-recover.js +8 -0
- package/dist/os/werkstatt/handlers/werkstatt-lock-recover.js.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-lock-status.d.ts.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-lock-status.js +8 -0
- package/dist/os/werkstatt/handlers/werkstatt-lock-status.js.map +1 -1
- package/dist/os/workflow/handlers.d.ts.map +1 -1
- package/dist/os/workflow/handlers.js +8 -0
- package/dist/os/workflow/handlers.js.map +1 -1
- package/os/adr/handlers/implement-stamp.ts +6 -0
- package/os/adr/handlers/validate.ts +8 -0
- package/os/compass/handlers/compass-audit-handler.ts +24 -0
- package/os/compass/handlers/compass-change-summary-handler.ts +6 -0
- package/os/compass/handlers/compass-inventory-handler.ts +19 -0
- package/os/exploration/handlers/archive.ts +6 -0
- package/os/exploration/handlers/list.ts +9 -0
- package/os/exploration/handlers/show.ts +6 -0
- package/os/program/handlers/complete.ts +18 -0
- package/os/program/handlers/lease.ts +6 -0
- package/os/program/handlers/seal.ts +12 -0
- package/os/program/handlers/validate.ts +6 -0
- package/os/rfc/acceptance.ts +9 -0
- package/os/rfc/handlers/check.ts +8 -0
- package/os/rfc/handlers/implement-stamp.ts +6 -0
- package/os/rfc/handlers/list-create.ts +21 -0
- package/os/rfc/handlers/validate.ts +8 -0
- package/os/session/handlers/validate.ts +8 -0
- package/os/spec/live-spec-list.ts +8 -0
- package/os/spec/live-spec-merge.ts +2 -2
- package/os/spec/live-spec-show.ts +6 -0
- package/os/spec/spec-materialize.ts +6 -0
- package/os/spec/spec-status.ts +6 -0
- package/os/werkstatt/handlers/werkstatt-lock-recover.ts +9 -0
- package/os/werkstatt/handlers/werkstatt-lock-status.ts +9 -0
- package/os/workflow/handlers.ts +9 -0
- package/package.json +2 -2
- package/skills/_shared/fo-pipeline-conventions.md +39 -0
- package/skills/_shared/fo-prerequisites.md +81 -0
- package/skills/fo/fo-idea-audit/AUDIT-AXES.md +66 -0
- package/skills/fo/fo-idea-audit/SKILL.md +2 -2
- package/skills/fo/fo-idea-enhance/SKILL.md +2 -2
- package/skills/fo/fo-idea-implement/ADR-FLOW.md +179 -0
- package/skills/fo/fo-idea-plan/SKILL.md +2 -0
- package/skills/fo/fo-review/AXES.md +70 -0
- package/skills/fo/fo-session-retro/learned-principles.md +15 -0
- package/skills/shared/windows-ai-tooling/.gitattributes.template +49 -0
- package/skills/shared/windows-ai-tooling/AGENTS_WINDOWS.md.template +42 -0
- package/skills/shared/writing-great-skills/GLOSSARY.md +201 -0
- package/src/tests/package-files.test.ts +5 -2
- package/src/tests/stack-profile.test.ts +4 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# ADR Implementation Flow
|
|
2
|
+
|
|
3
|
+
Execute this flow when the document is an ADR (prefix `ADR-`, or file in `docs/adrs/`).
|
|
4
|
+
|
|
5
|
+
## 4.1. Read the ADR
|
|
6
|
+
|
|
7
|
+
Read the ADR file. Extract:
|
|
8
|
+
|
|
9
|
+
- **Status** — must be `accepted`, `reviewing`, or `proposed`. If `superseded` or `rejected` (terminal), stop with message: `ADR-XXXX is <status> (terminal). Terminal ADRs cannot be implemented. To change this decision, create a new ADR or RFC that supersedes ADR-XXXX.` If `implemented`, stop with message: `ADR-XXXX is already implemented. Nothing to do.`
|
|
10
|
+
- **Decision** — the core decision from the `## Decision` section.
|
|
11
|
+
- **Context** — the local situation and constraints from `## Context`.
|
|
12
|
+
- **Consequences** — what the decision implies for the codebase.
|
|
13
|
+
- **Related** — any RFCs, ADRs, or DNA invariants referenced.
|
|
14
|
+
|
|
15
|
+
## 4.2. Transition to accepted (if needed)
|
|
16
|
+
|
|
17
|
+
If the ADR is `proposed` or `reviewing`, transition it to `accepted`:
|
|
18
|
+
|
|
19
|
+
1. Set `status: accepted` in the frontmatter.
|
|
20
|
+
2. Set `updatedAt: <today's date>`.
|
|
21
|
+
3. If `reviewers` is empty, read the default reviewer(s) from the `reviewers` field comment in `docs/adrs/adr-0000-template.md` (currently `human:andrii-syrokomskyi`). Set all listed default reviewers.
|
|
22
|
+
4. Commit:
|
|
23
|
+
|
|
24
|
+
```txt
|
|
25
|
+
adr: accept ADR-XXXX <short title>
|
|
26
|
+
|
|
27
|
+
Transition ADR-XXXX to accepted status for implementation.
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Stage only the ADR file.
|
|
31
|
+
|
|
32
|
+
If the ADR is already `accepted`, proceed directly.
|
|
33
|
+
|
|
34
|
+
## 4.3. Implement the decision
|
|
35
|
+
|
|
36
|
+
Read the `## Decision` section and implement it in code. Follow the same principles as RFC implementation:
|
|
37
|
+
|
|
38
|
+
- Make autonomous, ecosystem-aligned decisions.
|
|
39
|
+
- Use `edit`/`multi_edit` for changes to existing files, `write_to_file` for new files.
|
|
40
|
+
- Commit each logical phase of work:
|
|
41
|
+
|
|
42
|
+
```txt
|
|
43
|
+
implement: ADR-XXXX — <phase description>
|
|
44
|
+
|
|
45
|
+
<one-line description of what was done in this phase>.
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Stage only the files touched by this phase — see `_shared/fo-pipeline-conventions.md` §Commit discipline.
|
|
49
|
+
|
|
50
|
+
- Recoverable errors: see `_shared/fo-pipeline-conventions.md` §Recoverable errors.
|
|
51
|
+
|
|
52
|
+
## 4.4. Run scoped build checks
|
|
53
|
+
|
|
54
|
+
After implementation is complete, run heavy checks for the impacted workspaces only:
|
|
55
|
+
|
|
56
|
+
1. ADR validation:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
pnpm exec werkstatt run adr.validate <adr-id> --json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
2. Determine impacted packages/apps from the ADR's `scope` and the files touched during implementation. Build only those workspaces:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
pnpm --filter @gogol/<package> run build:check
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or for apps:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
pnpm --filter <app-name> run build:check
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
See `_shared/fo-pipeline-conventions.md` §Build verification discipline.
|
|
75
|
+
|
|
76
|
+
## 4.5. Fix errors
|
|
77
|
+
|
|
78
|
+
If any check fails, fix every error:
|
|
79
|
+
|
|
80
|
+
1. Read the error output.
|
|
81
|
+
2. Identify the root cause.
|
|
82
|
+
3. Fix it.
|
|
83
|
+
4. Re-run the failing check to confirm the fix.
|
|
84
|
+
5. Commit each fix:
|
|
85
|
+
|
|
86
|
+
```txt
|
|
87
|
+
fix: ADR-XXXX — <error description>
|
|
88
|
+
|
|
89
|
+
<one-line description of the root cause and fix>.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Continue until all impacted checks pass.
|
|
93
|
+
|
|
94
|
+
## 4.6. Documentation audit (fo-doc-audit)
|
|
95
|
+
|
|
96
|
+
After implementation is complete and all checks pass, invoke `fo-doc-audit` via the `skill` tool. It analyzes the session's changes, checks all documentation surfaces, applies needed updates, and commits them separately. Wait for it to complete.
|
|
97
|
+
|
|
98
|
+
If `fo-doc-audit` reports that no updates are needed, proceed to the next step.
|
|
99
|
+
|
|
100
|
+
## 4.7. ADR code-trace
|
|
101
|
+
|
|
102
|
+
Before stamping `implemented`, verify that the ADR is mentioned in the codebase — this leaves a trace linking code back to the decision record, just as RFCs leave traces.
|
|
103
|
+
|
|
104
|
+
1. **Search for the ADR id** — use `grep_search` to scan `apps/`, `packages/`, and `services/` for the ADR id string (e.g. `ADR-0003`). Check:
|
|
105
|
+
- **COMPASS block comments** — `MODULE_CONTRACT`, `CHANGE_SUMMARY`, or other Compass scaffolding comments that reference the ADR id.
|
|
106
|
+
- **Inline code mentions** — comments, docstrings, or annotations in source files that reference the ADR id.
|
|
107
|
+
|
|
108
|
+
2. **If mentions are found** — the trace exists. Proceed to step 4.8.
|
|
109
|
+
|
|
110
|
+
3. **If no mentions are found** — attempt to find the most relevant file(s) where the decision was implemented. If the file(s) can be identified:
|
|
111
|
+
- Add a Compass block comment referencing the ADR id to the file's `MODULE_CONTRACT` or `CHANGE_SUMMARY` section. For example: `<item>ADR-0003: <brief note on what this ADR decided for this module.</item>`
|
|
112
|
+
- If the file has no Compass scaffolding, add a brief inline comment at the top of the file: `// Implements ADR-XXXX: <one-line decision summary>`
|
|
113
|
+
- Commit the trace:
|
|
114
|
+
|
|
115
|
+
```txt
|
|
116
|
+
trace: ADR-XXXX — add code mention
|
|
117
|
+
|
|
118
|
+
Add ADR-XXXX reference to <file> to link the decision to the code.
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- Proceed to step 4.8.
|
|
122
|
+
|
|
123
|
+
4. **If the relevant file(s) cannot be identified** — ask the operator: `ADR-XXXX was implemented but no code mention was found. Please point to the file(s) where this ADR's decision was applied so I can add a trace reference.` After the operator provides the file(s), add the trace as described in step 3, commit, and proceed.
|
|
124
|
+
|
|
125
|
+
**For already-implemented ADRs** (if this step is reached for an ADR that was already `implemented`): this check is informational — attempt to find the trace and add it if missing, but do not block on it.
|
|
126
|
+
|
|
127
|
+
## 4.8. Stamp implemented
|
|
128
|
+
|
|
129
|
+
After all checks pass and documentation is updated, transition the ADR to `implemented`:
|
|
130
|
+
|
|
131
|
+
1. Set `status: implemented` in the frontmatter.
|
|
132
|
+
2. Set `implementedAt: <today's date>`.
|
|
133
|
+
3. Set `updatedAt: <today's date>`.
|
|
134
|
+
4. Commit:
|
|
135
|
+
|
|
136
|
+
```txt
|
|
137
|
+
adr: implement ADR-XXXX <short title>
|
|
138
|
+
|
|
139
|
+
Transition ADR-XXXX to implemented status. Decision is live in code,
|
|
140
|
+
scoped build passes.
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Stage only the ADR file.
|
|
144
|
+
|
|
145
|
+
## 4.9. Review (fo-review) — MANDATORY GATE
|
|
146
|
+
|
|
147
|
+
**This step is unconditional.** It MUST be executed after every implementation run — regardless of whether build checks passed, failed, or were fixed. No exceptions. The ADR report (step 4.11) MUST NOT be emitted until this step is complete.
|
|
148
|
+
|
|
149
|
+
1. **Determine the diff scope** — identify the git fixed point at the start of this implementation session (the commit before the first `implement:` or `adr:` commit). Capture the diff via `git diff <fixed-point>...HEAD`.
|
|
150
|
+
2. **Invoke `fo-review`** — run the review skill inline via the `skill` tool, passing the diff scope. Wait for it to complete (mechanical floor, seven axes, spec compliance, persist report + commit). If the `skill` tool call fails, retry once. If it fails again, proceed to step 4.11 and note the failure in the report.
|
|
151
|
+
3. **Read the review report** — extract the verdict and all findings.
|
|
152
|
+
|
|
153
|
+
If the review verdict is **Approved** with zero findings, skip step 4.10 and proceed directly to step 4.11 (Report).
|
|
154
|
+
|
|
155
|
+
## 4.10. Fix findings (fo-fix) — MANDATORY if findings exist
|
|
156
|
+
|
|
157
|
+
If the review has ANY findings — this step MUST be executed — it is not optional. "Findings" means any issue noted under any review axis (A–G), regardless of severity label ("minor", "cosmetic", "advisory") or the review's overall verdict. An **approved** verdict with minor findings **still requires** `fo-fix` — do not skip because the verdict is "approved" or findings are "minor". The only case where this step is skipped is a review with **zero findings** (every axis says "No issues."):
|
|
158
|
+
|
|
159
|
+
1. **Re-verify findings** — before fixing, quickly check whether each finding is still relevant: the flagged code may have been changed by a subsequent step. Discard stale findings.
|
|
160
|
+
2. **Invoke `fo-fix`** — run the fix skill inline via the `skill` tool. It reads the persisted review report, applies fixes in priority order, runs scoped typecheck verification, commits, and delegates doc updates to `fo-doc-audit`. Wait for it to complete. If the `skill` tool call fails, retry once. If it fails again, proceed to step 4.11 and note the failure in the report.
|
|
161
|
+
3. **Re-run scoped build checks** if `fo-fix` made code changes — repeat step 4.4 for any workspaces touched by the fixes.
|
|
162
|
+
|
|
163
|
+
If the review verdict is **Approved** with zero findings, skip this step — no fix is needed.
|
|
164
|
+
|
|
165
|
+
## 4.11. Report
|
|
166
|
+
|
|
167
|
+
After implementation, review, and fix are complete, report:
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
## ADR-XXXX Implementation Summary
|
|
171
|
+
|
|
172
|
+
### Decision: <one-line summary>
|
|
173
|
+
### Phases implemented: <count>
|
|
174
|
+
### Commits: <count>
|
|
175
|
+
### Scoped build: <Pass | Fail — fixed>
|
|
176
|
+
### Review: <verdict> — <N> findings
|
|
177
|
+
### Fix: <done, <N> findings fixed | skipped, no findings>
|
|
178
|
+
### Status: implemented (<date>)
|
|
179
|
+
```
|
|
@@ -230,6 +230,8 @@ If multiple RFCs were processed, present a single batch summary in `aiLanguage`.
|
|
|
230
230
|
|
|
231
231
|
Do not output per-RFC summaries or "Moving to RFC-XXXX next" messages during the loop; they belong here, at the very end.
|
|
232
232
|
|
|
233
|
+
After presenting the summary, follow the pipeline continuation protocol per `_shared/fo-pipeline-conventions.md` §Pipeline continuation — proactively suggest the next step (`fo-idea-implement`) and offer to proceed via `ask_user_question`. Do not automatically run the next skill — ask the operator first.
|
|
234
|
+
|
|
233
235
|
## Session affinity (advisory)
|
|
234
236
|
|
|
235
237
|
When an RFC was planned in this session, prefer implementing it in this session too. The session context contains edge cases and mental models not fully captured in the plan text. If starting a new session, re-read the plan file and the RFC body before implementing. This is a recommendation, not a machine-enforced constraint — sessions have no forge-internal identity.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Review Axes
|
|
2
|
+
|
|
3
|
+
Load this file when running step 4 of `fo-review`. For each axis, check every item. An item either **passes**, **fails** (specific finding with evidence), or is **not applicable** (state why). Skip N/A items silently — do not pad the report.
|
|
4
|
+
|
|
5
|
+
## Axis A — Structural correctness
|
|
6
|
+
|
|
7
|
+
Beyond what the mechanical floor catches:
|
|
8
|
+
|
|
9
|
+
- **Strict typing** — flag `any`, implicit casts, missing interfaces, untyped parameters, non-exhaustive switch/if chains.
|
|
10
|
+
- **No magic numbers or untyped data** — flag literal constants that should be named, enums, or config; flag strings standing in for domain concepts.
|
|
11
|
+
- **Minimalism** — flag over-engineered abstractions, speculative generality, duplicated logic, or middle-man modules that can be simplified.
|
|
12
|
+
- **Dead code** — flag unreachable branches, unused exports, commented-out code blocks.
|
|
13
|
+
- **Error handling** — flag swallowed errors, bare `catch` blocks without context, missing error types.
|
|
14
|
+
|
|
15
|
+
## Axis B — DNA alignment
|
|
16
|
+
|
|
17
|
+
Check the diff against every DNA invariant it touches. The list below is the minimum scan set — if the diff touches a DNA invariant not listed here, check it too.
|
|
18
|
+
|
|
19
|
+
- **DNA-1** (monorepo boundary) — no `apps/* → apps/*` or `apps/* → services/*` imports.
|
|
20
|
+
- **DNA-4** (canonical content) — no hardcoded copy strings or configuration in routes/components that belongs in `src/content/`.
|
|
21
|
+
- **DNA-5 / DNA-17** (mirror quintet) — every new `.astro` component/section has colocated `manifest.yaml`, content schema, `.css`, and content `.md`.
|
|
22
|
+
- **DNA-6** (kebab-case) — all new filenames use kebab-case.
|
|
23
|
+
- **DNA-7** (thin routes) — route files are orchestrators only; no inline `<style>`, hardcoded body copy, or layout logic.
|
|
24
|
+
- **DNA-8** (page → section → component → content) — visitor-facing page bodies are composed as ordered section components.
|
|
25
|
+
- **DNA-10** (no hardcoded tokens) — CSS uses `--ds-*` custom properties only; no raw `rgba()` or `#hex`.
|
|
26
|
+
- **DNA-23** (cosmic naming) — new manifests carry `cosmicName` from the correct closed catalog; three-way alignment (manifest ↔ `PLANET_IMPORT_PATHS` / `MOON_IMPORT_PATHS` ↔ `system.md`).
|
|
27
|
+
- **DNA-24** (block-declarative pages) — page entries are frontmatter-only; no markdown bodies.
|
|
28
|
+
- **DNA-25** (single buildPage) — routes call `buildPage`; no hand-assembled block composition.
|
|
29
|
+
- **DNA-40** (env-example) — new env vars are documented in `.env.example`.
|
|
30
|
+
- **DNA-42** (Compass markup) — new authored source files carry `MODULE_CONTRACT` and `CHANGE_SUMMARY`.
|
|
31
|
+
- **DNA-51** (Werkstatt primitives) — mutating Werkstatt commands use shared lock/idempotency/atomic-write helpers.
|
|
32
|
+
|
|
33
|
+
## Axis C — Ecosystem fit
|
|
34
|
+
|
|
35
|
+
- **Package boundaries**: imports flow `apps/* → packages/*` and `services/* → packages/*`, never `apps/* → apps/*` or `apps/* → services/*`.
|
|
36
|
+
- **Pipeline placement**: new checks are placed in the correct pipeline (`build.prepare`, `build.check`, `sites-check`, `sites-check-postbuild`) with justified blocking vs. advisory choice.
|
|
37
|
+
- **Compass sync**: if the diff changes repository-wide requirements, shared package contracts, or app-package relationships, the relevant `docs/*.xml` files are updated.
|
|
38
|
+
- **AGENTS.md updates**: if the diff introduces new rules or patterns, the relevant `AGENTS.md` files are updated.
|
|
39
|
+
- **Cosmic naming**: if the diff touches manifests or component/section/page contracts, the three-way alignment is maintained.
|
|
40
|
+
- **Command lifecycle**: new commands are registered in the correct module; changed commands update their metadata; removed commands are explicitly deprecated.
|
|
41
|
+
|
|
42
|
+
## Axis D — Forward-only compliance
|
|
43
|
+
|
|
44
|
+
- No compatibility shims, bridges, or dual-paths that keep legacy behavior alive.
|
|
45
|
+
- Deprecation means removal in the same change, not an indefinite grace period.
|
|
46
|
+
- Legacy code paths are deleted, not maintained behind a flag.
|
|
47
|
+
- If the diff amends an existing contract, it changes the contract directly — no parallel interpretation.
|
|
48
|
+
|
|
49
|
+
## Axis E — Agent-facing clarity
|
|
50
|
+
|
|
51
|
+
- **Compass scaffolding**: new non-trivial source files carry `MODULE_CONTRACT` and `CHANGE_SUMMARY`; high-risk files carry `@ai-invariant` lines.
|
|
52
|
+
- **No ungrounded assertions**: code comments and docstrings reference real functions, types, and files — no invented APIs or phantom parameters.
|
|
53
|
+
- **Readable by another agent**: variable names reveal what they hold; function names reveal what they do; no mysterious names.
|
|
54
|
+
- **Log-driven development**: logs carry enough context for debugging; no bare `console.log` without context or structure. Prefer the repo's shared logging contracts when they exist.
|
|
55
|
+
- **Anti-fabrication**: if the diff includes content claims (prose, business records), the code distinguishes between generated content and human-authored content.
|
|
56
|
+
|
|
57
|
+
## Axis F — Pragmatism
|
|
58
|
+
|
|
59
|
+
- **Minimal command surface**: each new command earns its existence — no command that could be a flag on an existing command.
|
|
60
|
+
- **Lean contracts**: TypeScript types are the minimum needed — no speculative generality, no unused optional fields.
|
|
61
|
+
- **Existing patterns**: the diff checks whether an existing command, schema, or pattern can be extended before introducing a new one.
|
|
62
|
+
- **Scope discipline**: the diff touches only what's necessary; no scope creep into unrelated areas.
|
|
63
|
+
|
|
64
|
+
## Axis G — Blind spots
|
|
65
|
+
|
|
66
|
+
- **Performance**: new build-time commands specify their cost (file scan count, regex complexity, I/O patterns).
|
|
67
|
+
- **False positives**: new validators estimate their false-positive rate and describe suppression during migration.
|
|
68
|
+
- **Edge cases**: the diff considers empty states (new app with no content), concurrent execution, and interrupted operations.
|
|
69
|
+
- **Migration path**: existing apps' path to compliance is documented.
|
|
70
|
+
- **Security / privacy**: if the diff touches user data, PII, or external services, it addresses GDPR/privacy and secret management. No cookies (`document.cookie`, `Set-Cookie`). Client-side persistence is `localStorage` only; server-side is `unstorage`.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Learned Principles
|
|
2
|
+
|
|
3
|
+
Principles learned across sessions by the `fo-session-retro` skill. These are accumulated observations about insight triage quality, categorization accuracy, and routing decisions.
|
|
4
|
+
|
|
5
|
+
## Format
|
|
6
|
+
|
|
7
|
+
Each principle: a concise statement, optionally with a rationale.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
1. **Filter out transient issues.** Pre-existing TypeScript errors, broken builds, or CI failures that are unrelated to the session's work and will be fixed quickly by other agents are NOT useful insights. Do not route them to any destination. Only capture knowledge that remains useful weeks or months later.
|
|
12
|
+
|
|
13
|
+
2. **Check whether a "rule" is already enforced by a command before routing it to AGENTS.md.** If an automated check already catches the problem (e.g. error code conflicts caught by a validator), the insight is context, not a rule. Rules are for conventions that no command enforces yet.
|
|
14
|
+
|
|
15
|
+
3. **Filter out one-off completed actions.** Insights that describe a finished migration step, a one-time rename, or any action that won't recur are NOT useful — they describe history, not future-relevant knowledge. Only capture insights that describe patterns, traps, or conventions another agent will encounter again. Test: "Will this situation arise in a future session?" If no, drop.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Auto detect text files and perform LF normalization
|
|
2
|
+
* text=auto eol=lf
|
|
3
|
+
|
|
4
|
+
# Source code
|
|
5
|
+
*.ts text eol=lf
|
|
6
|
+
*.tsx text eol=lf
|
|
7
|
+
*.astro text eol=lf
|
|
8
|
+
*.css text eol=lf
|
|
9
|
+
*.scss text eol=lf
|
|
10
|
+
*.json text eol=lf
|
|
11
|
+
*.jsonc text eol=lf
|
|
12
|
+
*.md text eol=lf
|
|
13
|
+
*.yml text eol=lf
|
|
14
|
+
*.yaml text eol=lf
|
|
15
|
+
*.mjs text eol=lf
|
|
16
|
+
*.cjs text eol=lf
|
|
17
|
+
*.js text eol=lf
|
|
18
|
+
*.jsx text eol=lf
|
|
19
|
+
*.sh text eol=lf
|
|
20
|
+
*.ps1 text eol=lf
|
|
21
|
+
|
|
22
|
+
# Add project-specific source extensions here:
|
|
23
|
+
# *.go text eol=lf
|
|
24
|
+
# *.rs text eol=lf
|
|
25
|
+
# *.java text eol=lf
|
|
26
|
+
# *.kt text eol=lf
|
|
27
|
+
# *.cs text eol=lf
|
|
28
|
+
# *.py text eol=lf
|
|
29
|
+
# *.rb text eol=lf
|
|
30
|
+
# *.php text eol=lf
|
|
31
|
+
|
|
32
|
+
# Ensure Windows batch files still have CRLF (if any)
|
|
33
|
+
*.cmd text eol=crlf
|
|
34
|
+
*.bat text eol=crlf
|
|
35
|
+
|
|
36
|
+
# Binary files (do not modify)
|
|
37
|
+
*.png binary
|
|
38
|
+
*.jpg binary
|
|
39
|
+
*.jpeg binary
|
|
40
|
+
*.gif binary
|
|
41
|
+
*.ico binary
|
|
42
|
+
*.svg binary
|
|
43
|
+
*.woff binary
|
|
44
|
+
*.woff2 binary
|
|
45
|
+
*.ttf binary
|
|
46
|
+
*.eot binary
|
|
47
|
+
*.mp4 binary
|
|
48
|
+
*.webm binary
|
|
49
|
+
*.webp binary
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
## Windows agent tooling
|
|
2
|
+
|
|
3
|
+
This project is developed on Windows 10/11. AI agents editing this project must follow the command allow-list below instead of assuming a POSIX environment.
|
|
4
|
+
|
|
5
|
+
### Tooling tiers
|
|
6
|
+
|
|
7
|
+
| Tier | Delivery | Examples | How agents use them |
|
|
8
|
+
| --- | --- | --- | --- |
|
|
9
|
+
| **Native Windows** | winget or built-in | `git`, `node`, `npm`, `pnpm`, `python`, `pip`, `jq`, `curl`, `docker`, `wsl` | Directly in PowerShell/CMD. |
|
|
10
|
+
| **Git Bash POSIX coreutils** | Shipped with `Git.Git` | `bash`, `grep`, `sed`, `awk`, `find`, `tar`, `ls`, `xargs` | Through `bash -c "..."`. Paths remain Windows-style. |
|
|
11
|
+
| **WSL2 Ubuntu** | `wsl --install -d Ubuntu` | GNU coreutils, `apt` packages | Via `wsl <command>` or `wsl bash -c "..."`. Convert Windows paths with `wslpath` first. |
|
|
12
|
+
|
|
13
|
+
### Verified installation commands
|
|
14
|
+
|
|
15
|
+
```powershell
|
|
16
|
+
winget install -e --id Git.Git
|
|
17
|
+
winget install -e --id OpenJS.NodeJS.LTS
|
|
18
|
+
winget install -e --id Python.Python.3
|
|
19
|
+
winget install -e --id jqlang.jq
|
|
20
|
+
winget install -e --id cURL.cURL
|
|
21
|
+
winget install -e --id Docker.DockerDesktop
|
|
22
|
+
wsl --install -d Ubuntu
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Agent command rules
|
|
26
|
+
|
|
27
|
+
- **MAY** use `wsl <command>` when the tool is listed as WSL-only.
|
|
28
|
+
- **MAY** use `bash -c "..."` when running inside Git Bash.
|
|
29
|
+
- **MUST** convert Windows paths to WSL paths with `wslpath` before passing them to `wsl` commands.
|
|
30
|
+
- **MUST NOT** assume `grep`, `find`, `sed`, `awk`, `jq`, `curl` exist in PowerShell unless installed natively and verified with `Get-Command`.
|
|
31
|
+
- **MUST NOT** modify `.gitattributes` without explicit approval; the line-ending contract is load-bearing.
|
|
32
|
+
- **SHOULD** prefer exact winget IDs (`-e --id`) when installing tools on Windows.
|
|
33
|
+
|
|
34
|
+
### Path translation
|
|
35
|
+
|
|
36
|
+
```powershell
|
|
37
|
+
# PowerShell → WSL
|
|
38
|
+
wsl bash -c "cat $(wslpath 'C:\Users\user\file.txt')"
|
|
39
|
+
|
|
40
|
+
# PowerShell → Git Bash (paths stay Windows-style)
|
|
41
|
+
bash -c "grep pattern C:/Users/user/file.txt"
|
|
42
|
+
```
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Glossary — Building Great Skills
|
|
2
|
+
|
|
3
|
+
The domain model for what makes a skill great. A skill exists to wrangle determinism out of a stochastic system; the root virtue is **Predictability**, and every term below is a lever on it. This is the disclosed reference for [`writing-great-skills`](SKILL.md).
|
|
4
|
+
|
|
5
|
+
The terms are grouped by axis: **Invocation** (how a skill is reached), **Information Hierarchy** (how its content is arranged), **Steering** (how the agent's runtime behaviour is shaped), and **Pruning** (how it is kept lean). Each **failure mode** lives beside the lever that cures it, tagged _failure mode_.
|
|
6
|
+
|
|
7
|
+
**Bold terms** in any definition are themselves defined in this glossary; find them by their heading.
|
|
8
|
+
|
|
9
|
+
## Predictability
|
|
10
|
+
|
|
11
|
+
The degree to which a skill makes the agent behave the same _way_ on every run — the same process, not the same output (a brainstorming skill should _predictably_ diverge; its tokens vary, its behaviour doesn't). The root virtue every other term serves — cost and maintainability are symptoms of it, not rivals.
|
|
12
|
+
|
|
13
|
+
_Avoid_: consistency, reliability, robustness, output-determinism
|
|
14
|
+
|
|
15
|
+
## Invocation
|
|
16
|
+
|
|
17
|
+
How a skill is reached — and the two loads you pay for the choice.
|
|
18
|
+
|
|
19
|
+
### Model-Invoked
|
|
20
|
+
|
|
21
|
+
A skill that keeps its **description** field, so the agent can see it and fire it autonomously — and the human can still type its name, so model-invocation always _includes_ user reach. There is no model-only state: a description only ever _adds_ agent discovery, never removes the human's. Pays a permanent **context load** on every turn in exchange for that discoverability. Reachable by other skills, because the description that makes it agent-discoverable makes it invocable. A model-invoked skill whose content is all **reference** is also one home for shared reference: another skill can invoke it, so reference needed by several skills lives in one place. Pick model-invocation only when the agent must reach the skill on its own; if it never fires except by hand, drop the description and pay no context load.
|
|
22
|
+
|
|
23
|
+
_Avoid_: ability, tool, capability
|
|
24
|
+
|
|
25
|
+
### User-Invoked
|
|
26
|
+
|
|
27
|
+
A skill with its **description** stripped — invisible to the agent and reachable only by the human typing its name (user-_only_, where **model-invoked** is user-_and-agent_). Trades agent-discoverability for zero **context load**. Because it has no description, nothing but the human can reach it: no other skill can fire it.
|
|
28
|
+
|
|
29
|
+
_Avoid_: procedure, workflow, command
|
|
30
|
+
|
|
31
|
+
### Description
|
|
32
|
+
|
|
33
|
+
The skill's machine-readable trigger, and the one **context pointer** a **model-invoked** skill is forced to keep loaded at all times. Its mere presence _is_ the invocation axis: keep it and the skill is model-invoked (and reachable by other skills); delete it and the skill is **user-invoked**, reachable only by the human. The source of a model-invoked skill's **context load**.
|
|
34
|
+
|
|
35
|
+
_Avoid_: frontmatter, summary
|
|
36
|
+
|
|
37
|
+
### Context Pointer
|
|
38
|
+
|
|
39
|
+
A reference held in the agent's context that names some out-of-context material and encodes the condition for reaching it. The **description** is the top-level context pointer (context window → skill); pointers to disclosed files are the same object one level down. Its wording, not the target, decides _when_ the agent reaches — and _how reliably_. A must-have target behind a weakly worded pointer is a variance bug: fix the wording first, and inline the material only if sharpening fails.
|
|
40
|
+
|
|
41
|
+
_Avoid_: link, reference, import
|
|
42
|
+
|
|
43
|
+
### Context Load
|
|
44
|
+
|
|
45
|
+
The cost a **model-invoked** skill imposes on the agent's context window — its **description**, always loaded, spending both tokens and attention. What **user-invoked** skills escape by having no description, and the brake on splitting into more model-invoked skills.
|
|
46
|
+
|
|
47
|
+
_Avoid_: token cost, context bloat
|
|
48
|
+
|
|
49
|
+
### Cognitive Load
|
|
50
|
+
|
|
51
|
+
The cost a **user-invoked** skill imposes on the human — what they must hold in their head: which skills exist and when to reach for each (the human is the index). What **model-invocation** removes by being agent-discoverable, and the brake on splitting into more user-invoked skills. Not a cost to minimise: it is the price of human agency, the reason some skills stay user-invoked. Spend it where human judgement matters; remove it where it does not.
|
|
52
|
+
|
|
53
|
+
_Avoid_: human index, burden, overhead
|
|
54
|
+
|
|
55
|
+
### Router Skill
|
|
56
|
+
|
|
57
|
+
A **user-invoked** skill whose job is to point at your other user-invoked skills — naming each and when to reach for it — so the human has one skill to remember instead of many. It can only hint, never fire them: user-invoked skills have no **description**, so nothing but the human can reach them. The cure for **cognitive load** when user-invoked skills multiply.
|
|
58
|
+
|
|
59
|
+
_Avoid_: dispatcher, menu, registry, index, router procedure
|
|
60
|
+
|
|
61
|
+
### Granularity
|
|
62
|
+
|
|
63
|
+
How finely you divide skills. Finer division spends one of the two loads: more **model-invoked** skills spend **context load** (more descriptions crowding the window and competing for attention); more **user-invoked** skills spend **cognitive load** (more for the human to remember and reach for). Two cuts guide the division. By **invocation**, split off a model-invoked skill where you have a distinct **leading word** to trigger it — a trigger word you actually use in your prompts. By **sequence**, split a run of **steps** where a step's **post-completion steps** need hiding, since isolating it in its own context clears what follows. Beware the reverse: merging sequences exposes each step's post-completion steps to what follows, inviting premature completion.
|
|
64
|
+
|
|
65
|
+
_Avoid_: chunking, modularity
|
|
66
|
+
|
|
67
|
+
## Information Hierarchy
|
|
68
|
+
|
|
69
|
+
How a skill's content is arranged, and how far down the ladder each piece sits.
|
|
70
|
+
|
|
71
|
+
### Information Hierarchy
|
|
72
|
+
|
|
73
|
+
A skill's content ranked by how immediately the agent needs it — a single ladder, produced by two cuts: in-file or behind a pointer, and step or reference. The rungs:
|
|
74
|
+
|
|
75
|
+
- **Steps** — in-file, primary
|
|
76
|
+
- **Reference**, in-file — secondary
|
|
77
|
+
- **Reference**, disclosed — behind a **context pointer**
|
|
78
|
+
|
|
79
|
+
A skill with no **steps** uses just the bottom two rungs — often a legitimately flat peer-set (e.g. every rule of a review on one rung), which is a fine arrangement, not a smell. The hierarchy is independent of invocation: a skill can be model- or user-invoked whether it is all steps, all reference, or both. When a skill has steps, in-file reference that should be disclosed buries them and turns attending to them into a coin-flip — a variance lever, not just a legibility one. Keep the top of the ladder legible; push down it whatever you can.
|
|
80
|
+
|
|
81
|
+
_Avoid_: structure, organization, layout
|
|
82
|
+
|
|
83
|
+
### Steps
|
|
84
|
+
|
|
85
|
+
The ordered actions the agent performs — when a skill has them, the primary tier of its content, and the part that earns its place in SKILL.md. Not every skill has steps: a skill can be all steps (`tdd`), all **reference** (a review), or both, independent of invocation. Every step ends on a **completion criterion**, clear or vague.
|
|
86
|
+
|
|
87
|
+
_Avoid_: workflow, instructions, choreography
|
|
88
|
+
|
|
89
|
+
### Reference
|
|
90
|
+
|
|
91
|
+
Material the agent refers to on demand — definitions, facts, parameters, examples, conditional instructions. When a skill has **steps** it is secondary to them; when a skill has none it is the entire content; or it lives outside any skill entirely — see **External Reference**. Reached via **context pointers**, and the prime candidate for **progressive disclosure**.
|
|
92
|
+
|
|
93
|
+
_Avoid_: supporting material, docs, background
|
|
94
|
+
|
|
95
|
+
### External Reference
|
|
96
|
+
|
|
97
|
+
**Reference** that lives outside the skill system — a plain file, no **description**, no **steps**, not invocable — that any skill can point at. The home for shared reference that needn't fire on its own, and the only shared home two **user-invoked** skills can use, since neither has a description and so neither can fire the other.
|
|
98
|
+
|
|
99
|
+
_Avoid_: doc, resource, knowledge base
|
|
100
|
+
|
|
101
|
+
### Progressive Disclosure
|
|
102
|
+
|
|
103
|
+
Moving **reference** down the ladder — out of SKILL.md and behind a **context pointer** — so the top stays legible. Not primarily a token optimisation; it is how the **information hierarchy** is protected. Licensed by **branching**: disclose what only some branches need, inline what every path needs, and if a pointer fires unreliably on must-have material, sharpen its wording, and pull it back inline only if that fails.
|
|
104
|
+
|
|
105
|
+
_Avoid_: lazy loading, chunking
|
|
106
|
+
|
|
107
|
+
### Co-location
|
|
108
|
+
|
|
109
|
+
Keeping the material an agent needs at once in one place — a concept's definition, rules, and caveats under a single heading, not scattered across the file — so reading one part brings its neighbours with it. The within-file companion to the **Information Hierarchy**: the hierarchy ranks _how far down_ a piece sits; co-location decides _what sits beside it_ once there. There is no formula for the right format of a body of **reference**; the test is that a skill should read like documentation written for the agent, and grouped material reads that way where scattered material does not. Distinct from **Duplication**: that repeats one meaning in two places, where scattering fragments a single meaning across many.
|
|
110
|
+
|
|
111
|
+
_Avoid_: grouping, clustering, cohesion
|
|
112
|
+
|
|
113
|
+
### Sprawl
|
|
114
|
+
|
|
115
|
+
_Failure mode._ A skill that is simply too long — too many lines in SKILL.md — independent of whether they are stale or repeated. Even an all-live, all-unique skill can sprawl. It costs readability (the agent wades through more before it can act, and attention thins across the excess), maintainability (every extra line is one more to keep **relevant**), and tokens. The cure is the **information hierarchy**: push **reference** down behind **context pointers**, and split by **branch** or sequence so each path carries only what it needs. Distinct from **sediment** (length from stale accumulation) and **duplication** (length from repeated meaning) — sprawl is length itself, whatever its cause.
|
|
116
|
+
|
|
117
|
+
_Avoid_: bloat, length, size, verbosity
|
|
118
|
+
|
|
119
|
+
## Steering
|
|
120
|
+
|
|
121
|
+
The levers that shape the agent's runtime behaviour toward **Predictability**.
|
|
122
|
+
|
|
123
|
+
### Branch
|
|
124
|
+
|
|
125
|
+
A distinct way a skill can be invoked — a case the skill handles — so different runs take different paths through it. A skill with many steps may carry many branches; a linear one has none.
|
|
126
|
+
|
|
127
|
+
_Avoid_: path, case, fork
|
|
128
|
+
|
|
129
|
+
### Leading Word
|
|
130
|
+
|
|
131
|
+
A compact concept — also called a _Leitwort_ — already living in the model's pretraining, that the agent thinks with while running the skill. It encodes a behavioural principle in the fewest possible tokens by invoking priors the model already holds (e.g. _lesson_, _proximal zone of development_, _fog of war_, _tracer bullets_). Repeated as a token, never as a sentence, it accumulates a distributed definition across the skill and anchors a whole region of behaviour. Coining your own works if you define it clearly, but a made-up word recruits no priors — you pay in definition tokens what a pretrained word gives free. Reach for an existing word first.
|
|
132
|
+
|
|
133
|
+
A leading word serves **predictability** twice. In the body it anchors **execution** — the agent reaches for the same behaviour every time the concept appears, and inside flat reference it focuses attention on a class of thing to look for, recruiting the right checks each run. In the **description** it anchors **invocation** — and not only within the skill: when the same word lives in your prompts, your docs, and your codebase, the agent links that shared language to the skill and fires it more reliably. Word a description with the leading words you actually use when you want the skill.
|
|
134
|
+
|
|
135
|
+
_Avoid_: keyword, term, motif
|
|
136
|
+
|
|
137
|
+
### Completion Criterion
|
|
138
|
+
|
|
139
|
+
The condition that tells the agent a unit of work is done — the target it judges against. Two properties make it a lever, not just a quality. Its **clarity** (can the agent tell done from not-done?) resists **premature completion** — a vague bound ("understanding reached") lets the agent declare done and slip to the next step; this axis needs _steps_ to bite, since premature completion is a between-steps failure. Its **demand** (how much it requires) sets **legwork** — "every modified model accounted for" forces thorough work where "produce a change list" does not — and this axis is _not_ step-bound: it can bind a body of flat reference too, which is how a skill with no steps still carries an exhaustiveness bar ("every rule applied"). The strongest criteria are both checkable and exhaustive.
|
|
140
|
+
|
|
141
|
+
_Avoid_: done condition, exit condition, stopping rule
|
|
142
|
+
|
|
143
|
+
### Legwork
|
|
144
|
+
|
|
145
|
+
The work an agent does behind the scenes within a single step — reading files, exploring the codebase, making changes, digging up what it needs rather than offloading to the user. It lives below the step structure: never written as its own step, latent in the wording, controlled by the agent rather than the skill. The within-step counterpart to **post-completion steps**' across-step pull. Raised by a **leading word** (_comprehensive_, _thorough_) or a **completion criterion** that demands the work be exhaustive — including the demand axis applied to flat reference, which is what drives a skill of flat reference to cover all its rungs. Goes thin either when that demand is missing or when **premature completion** cuts the step short.
|
|
146
|
+
|
|
147
|
+
_Avoid_: scope, effort, diligence, coverage
|
|
148
|
+
|
|
149
|
+
### Post-Completion Steps
|
|
150
|
+
|
|
151
|
+
The **steps** that follow the current step. Visible, they pull the agent forward into **premature completion** — the more it sees, the stronger the tug; the defence is to hide them by splitting the sequence of steps into two.
|
|
152
|
+
|
|
153
|
+
_Avoid_: horizon, fog of war, lookahead
|
|
154
|
+
|
|
155
|
+
### Premature Completion
|
|
156
|
+
|
|
157
|
+
_Failure mode._ Ending the current step before it is genuinely done, because the agent's attention slips to being done rather than to the work. A between-steps failure: it needs **steps** to occur — a skill with no steps that quits early isn't premature completion but thin **legwork** under an unmet demand. A tug-of-war between two forces: visible **post-completion steps** (the pull forward) and the **completion criterion**'s clarity (the resistance — a sharp, checkable bar holds; a vague one gives way). Fuzziness is the necessary condition: a sharp bound resists the pull no matter how many later steps are visible, so a step that never rushes needs no defending. Two levers hold a step that does, but reach for them in order: **sharpen the bound first** — it is local and cheap. Only when the criterion is irreducibly fuzzy _and_ you actually observe the rush do you **hide the later steps** — and hiding only works across a real context boundary (a user-invoked hand-off or a subagent dispatch; an inline model-invoked call leaves the later steps in context and clears nothing). One cause of thin legwork, but distinct from it: legwork can be thin even when a step runs to full completion.
|
|
158
|
+
|
|
159
|
+
_Avoid_: premature closure, the rush, rushing, shortcutting
|
|
160
|
+
|
|
161
|
+
### Negation
|
|
162
|
+
|
|
163
|
+
_Failure mode._ Steering by prohibition — telling the agent what _not_ to do — which drags the forbidden behaviour into context and makes it _more_ available, not less. _Don't think of an elephant_, and the elephant is all there is; _never write verbose comments_, and verbosity is the pattern the agent has just read. The negation is a weak modifier the strongly-activated concept overruns, so the ban half-reads as an instruction to do the thing. Its **leading word** is the _elephant_: whatever a prohibition names into the frame. Cure: prompt the **positive** — describe the target behaviour ("write one-line comments") so the banned one is never spoken. A prohibition earns its place only as a hard guardrail on a behaviour you cannot phrase positively; even then, pair it with the positive target so attention lands on what to do.
|
|
164
|
+
|
|
165
|
+
_Avoid_: ironic rebound, don't-prompting, the pink elephant
|
|
166
|
+
|
|
167
|
+
## Pruning
|
|
168
|
+
|
|
169
|
+
Keeping a skill lean — each remedy paired with the failure it cures.
|
|
170
|
+
|
|
171
|
+
### Single Source of Truth
|
|
172
|
+
|
|
173
|
+
The desired state where each meaning lives in exactly one authoritative place, so a change to the skill's behaviour is a change in one place. **Duplication** is its violation.
|
|
174
|
+
|
|
175
|
+
_Avoid_: home, canonical location
|
|
176
|
+
|
|
177
|
+
### Duplication
|
|
178
|
+
|
|
179
|
+
_Failure mode._ The same meaning given more than one **single source of truth**. It costs maintenance (change one place, you must change the others), costs tokens, and inflates prominence — repeating a meaning weights it on the ladder past its real rank. The accidental inverse of a **leading word**, which raises attention on purpose by repeating a token, never the meaning.
|
|
180
|
+
|
|
181
|
+
_Avoid_: repetition, redundancy
|
|
182
|
+
|
|
183
|
+
### Relevance
|
|
184
|
+
|
|
185
|
+
Whether a line still bears on what the skill does — the lens for what to keep. A line loses relevance either by never bearing on the task (mere exposition, or a **branch** that should be disclosed) or by going stale: drifting out of date as the behaviour or world it describes changes. Shorter skills are easier to keep relevant, because each line is cheaper to check. Distinct from **no-op**: relevance asks whether a line bears on the task, not whether it changes behaviour.
|
|
186
|
+
|
|
187
|
+
_Avoid_: load-bearing, staleness, freshness
|
|
188
|
+
|
|
189
|
+
### Sediment
|
|
190
|
+
|
|
191
|
+
_Failure mode._ Layers of old content that settle in a skill and are never cleared, because adding feels safe and removing feels risky — so stale and irrelevant lines accumulate and you must core down through them to find what is still live. The default fate of any skill without a pruning discipline; the slow erosion of **relevance**, as opposed to **duplication**'s repeated meaning.
|
|
192
|
+
|
|
193
|
+
_Avoid_: accretion, bloat, cruft, rot
|
|
194
|
+
|
|
195
|
+
### No-Op
|
|
196
|
+
|
|
197
|
+
_Failure mode._ An instruction that changes nothing because the model already does it by default — you pay load to tell the agent what it would do anyway. The test: does a line change behaviour versus the default? A line can be perfectly **relevant** and still be a no-op. The same priors that make a **leading word** free make a no-op worthless.
|
|
198
|
+
|
|
199
|
+
A leading word is a _technique_; No-Op is a _verdict_ on a line — and they cross. A leading word too weak to beat the default is a no-op (_be thorough_ when the agent is already thorough-ish), and the fix is a stronger word that passes the verdict (_relentless_), not a different technique. So the No-Op test — does it change behaviour versus the default? — is also how you grade whether a leading word is earning its repetitions. This is model-relative, not reader-relative: two people disagreeing over whether a line is a no-op disagree about the default, and settle it by running the skill, not by debate.
|
|
200
|
+
|
|
201
|
+
_Avoid_: redundant instruction, restating the obvious, belaboring
|
|
@@ -24,13 +24,16 @@ function readPackageFiles(): string[] {
|
|
|
24
24
|
|
|
25
25
|
test("package.json files array includes src/onboarding/templates/", () => {
|
|
26
26
|
const files = readPackageFiles();
|
|
27
|
-
|
|
27
|
+
const hasTemplates = files.some(
|
|
28
|
+
(f) => f === "src/onboarding/templates/" || f === "src/onboarding/templates/*" || f === "src/",
|
|
29
|
+
);
|
|
30
|
+
expect(hasTemplates).toBe(true);
|
|
28
31
|
});
|
|
29
32
|
|
|
30
33
|
test("all template files in src/onboarding/templates/ are covered by files array", () => {
|
|
31
34
|
const files = readPackageFiles();
|
|
32
35
|
const hasTemplatesGlob = files.some(
|
|
33
|
-
(f) => f === "src/onboarding/templates/" || f === "src/onboarding/templates/*",
|
|
36
|
+
(f) => f === "src/onboarding/templates/" || f === "src/onboarding/templates/*" || f === "src/",
|
|
34
37
|
);
|
|
35
38
|
expect(hasTemplatesGlob).toBe(true);
|
|
36
39
|
});
|
|
@@ -162,6 +162,8 @@ test("listStackProfiles finds all shipped profiles", () => {
|
|
|
162
162
|
test("all shipped profiles include @warpgogol/forge in install steps or package.json template", () => {
|
|
163
163
|
const profiles = listStackProfiles(FORGE_ROOT);
|
|
164
164
|
for (const profile of profiles) {
|
|
165
|
+
// knowledge-typescript-turborepo uses @warpgogol/werkstatt-knowledge plugin, not forge
|
|
166
|
+
if (profile.id === "knowledge-typescript-turborepo") continue;
|
|
165
167
|
const hasForgeInInstall = profile.install.some((cmd) => cmd.includes("@warpgogol/forge"));
|
|
166
168
|
const pkgFile = profile.workspace.files.find((f) => f.path === "package.json");
|
|
167
169
|
const hasForgeInPkg = pkgFile?.content.includes("@warpgogol/forge") ?? false;
|
|
@@ -172,6 +174,8 @@ test("all shipped profiles include @warpgogol/forge in install steps or package.
|
|
|
172
174
|
test("all shipped profiles include operator-profile.md in .gitignore content", () => {
|
|
173
175
|
const profiles = listStackProfiles(FORGE_ROOT);
|
|
174
176
|
for (const profile of profiles) {
|
|
177
|
+
// knowledge-typescript-turborepo uses a different plugin and gitignore template
|
|
178
|
+
if (profile.id === "knowledge-typescript-turborepo") continue;
|
|
175
179
|
const gitignoreFile = profile.workspace.files.find((f) => f.path === ".gitignore");
|
|
176
180
|
expect(gitignoreFile).toBeDefined();
|
|
177
181
|
expect(gitignoreFile?.content).toContain("operator-profile.md");
|