@ksuchoi216/ahe 0.1.10 → 0.1.12
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 +23 -29
- package/package.json +1 -1
- package/packages/ahe-antigravity/package.json +1 -1
- package/packages/ahe-codex/.codex/hooks/ahe-hook.js +21 -68
- package/packages/ahe-codex/.codex/skills/ahe/SKILL.md +5 -3
- package/packages/ahe-codex/.codex/skills/ahe-clean/SKILL.md +67 -0
- package/packages/ahe-codex/.codex/skills/ahe-harness/SKILL.md +10 -9
- package/packages/ahe-codex/.codex/skills/ahe-new/SKILL.md +6 -2
- package/packages/ahe-codex/.codex/skills/ahe-overview/SKILL.md +8 -31
- package/packages/ahe-codex/.codex/skills/ahe-think/SKILL.md +32 -21
- package/packages/ahe-codex/bin/ahe-codex +19 -19
- package/packages/ahe-codex/package.json +2 -2
- package/packages/ahe-codex/.codex/ahe-shared/config.yaml +0 -8
- package/packages/ahe-codex/.codex/skills/ahe-compress/SKILL.md +0 -120
- package/packages/ahe-codex/.codex/skills/ahe-compress/agents/openai.yaml +0 -6
- package/packages/ahe-codex/.codex/skills/ahe-compress/scripts/check-harness-size.sh +0 -121
- package/packages/ahe-codex/.codex/skills/ahe-compress/scripts/detect_stale_tests.py +0 -30
- package/packages/ahe-codex/.codex/skills/ahe-fix/SKILL.md +0 -59
- package/packages/ahe-codex/.codex/skills/ahe-fix/scripts/write_fix_plan.py +0 -108
package/README.md
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
# Awesome Harness Engineering (AHE)
|
|
2
2
|
|
|
3
3
|
AHE installs global Codex and Antigravity skills that manage harness files through chat. The repository uses a one-package, two-internal-packages layout (`packages/ahe-codex` and `packages/ahe-antigravity`) shipped as a single npm package. The
|
|
4
|
-
public entrypoints stay small: use `ahe
|
|
5
|
-
`ahe
|
|
6
|
-
`ahe
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
public entrypoints stay small: use exact `ahe` for bootstrap or continuation,
|
|
5
|
+
`ahe ship` to save the latest plan (in Codex) or refresh and execute a saved plan (in Antigravity),
|
|
6
|
+
and `ahe git` for safe git orchestration. Use `ahe <query>` or `<query> ahe`
|
|
7
|
+
for explicit AHE requests such as `ahe update product spec` or `ahe stale tests`.
|
|
8
|
+
For a detailed in-chat explanation of the AHE architecture and workflows, use the helper `ahe-overview`.
|
|
9
9
|
|
|
10
10
|
## Core Command Workflows
|
|
11
11
|
|
|
12
|
-
Here are intuitive flow examples for the primary AHE commands.
|
|
12
|
+
Here are intuitive flow examples for the primary AHE commands. The public work-routing surface is `ahe`, `ahe-ship`, and `ahe-git`; conversational queries such as `ahe add dashboard export feature` are routed through `ahe`.
|
|
13
13
|
|
|
14
|
-
### `ahe
|
|
14
|
+
### `ahe` Bootstrap Flow
|
|
15
15
|
1. **Empty Workspace**: You have a new or existing repo that needs AHE.
|
|
16
|
-
2. **ahe
|
|
17
|
-
3. **Initialization**:
|
|
16
|
+
2. **ahe calling**: You type `ahe` or `ahe new` in Codex.
|
|
17
|
+
3. **Initialization**: `ahe-think` detects the missing harness, calls internal `ahe-new`, and then hands off to `ahe-harness` to sync product docs.
|
|
18
18
|
|
|
19
19
|
### `ahe ship` Flow
|
|
20
20
|
1. **plan mode in codex**: Generate an implementation plan inside Codex.
|
|
21
21
|
2. **ahe-ship calling in codex**: If in Plan Mode, the Codex host exits Plan Mode and replays the command. Outside Plan Mode, Codex saves the plan to `.plans/` and stops.
|
|
22
22
|
3. **ahe-ship calling in antigravity**: Antigravity refreshes the saved plan against current code, executes it, and cleans it up.
|
|
23
23
|
|
|
24
|
-
### `ahe
|
|
24
|
+
### `ahe` Follow-Up Flow
|
|
25
25
|
1. **Error Encountered**: A test fails or intent changes after execution.
|
|
26
|
-
2. **ahe
|
|
27
|
-
3. **
|
|
26
|
+
2. **ahe query**: You type `ahe stale tests` or another explicit follow-up request in Codex.
|
|
27
|
+
3. **Normal Routing**: `ahe-think` treats that request as ordinary AHE work and routes it to the right internal worker.
|
|
28
28
|
|
|
29
29
|
### General `ahe` Flow
|
|
30
30
|
1. **Ongoing Work**: You need to implement a feature or update docs.
|
|
@@ -36,17 +36,16 @@ Here are intuitive flow examples for the primary AHE commands. While `ahe`, `ahe
|
|
|
36
36
|
| Skill | Role |
|
|
37
37
|
| --- | --- |
|
|
38
38
|
| `ahe` | Top-level user-facing continuation skill that routes exact `ahe` and `ahe` query forms through `ahe-think`. |
|
|
39
|
-
| `ahe-new` |
|
|
39
|
+
| `ahe-new` | Internal bootstrap workflow that `ahe-think` calls when the workspace has no usable harness yet. |
|
|
40
40
|
| `ahe-think` | Centered internal router that judges what is missing and chooses the next agent. |
|
|
41
41
|
| `ahe-review` | Review agent for repo code, harness state, and CodeGraph context. |
|
|
42
42
|
| `ahe-converse` | Clarification agent for recursive user conversation. |
|
|
43
|
-
| `ahe-harness` | Harness-management agent for product docs, instructions, feature tracking, todo sync
|
|
43
|
+
| `ahe-harness` | Harness-management agent for product docs, instructions, feature tracking, and todo sync. |
|
|
44
44
|
| `ahe-feature` | Internal helper for deriving feature-list entries from product context. |
|
|
45
|
-
| `ahe-fix` | Independent fix planner that writes `.plans/{plan_name}.md` for errors or changed user intent. |
|
|
46
45
|
| `ahe-solve` | Feature-solving agent that divides and plans implementation work. |
|
|
47
|
-
| `ahe-
|
|
48
|
-
| `ahe-overview` | Explains the AHE concept, entrypoints, and main workflows in chat with Mermaid diagrams. |
|
|
46
|
+
| `ahe-overview` | Helper skill that explains the AHE concept, entrypoints, and main workflows in chat. |
|
|
49
47
|
| `ahe-ship` | In Codex: saves Plan Mode plan to `.plans/`. In Antigravity: refreshes and executes exactly one plan from `.plans/`. |
|
|
48
|
+
| `ahe-git` | Independent git orchestration workflow for safe fetch, review, and commit handling. |
|
|
50
49
|
|
|
51
50
|
## Routing Model
|
|
52
51
|
|
|
@@ -54,9 +53,9 @@ The Codex-side model is centered but flexible:
|
|
|
54
53
|
|
|
55
54
|
- exact `ahe` -> `ahe-think` -> `ahe-review | ahe-converse | ahe-harness | ahe-solve`
|
|
56
55
|
- `ahe <query>` or `<query> ahe` -> `ahe-think` -> `ahe-review | ahe-converse | ahe-harness | ahe-solve`
|
|
57
|
-
-
|
|
56
|
+
- `ahe-think` may call internal `ahe-new` when the workspace needs bootstrap or restart handling
|
|
58
57
|
- exact `ahe ship` -> independent plan-export workflow (Codex) or execution workflow (Antigravity)
|
|
59
|
-
- exact `ahe
|
|
58
|
+
- exact `ahe git` -> independent git workflow
|
|
60
59
|
|
|
61
60
|
- `ahe-think` is the center of judgment.
|
|
62
61
|
- Worker agents can call each other directly when that is the logical next
|
|
@@ -69,16 +68,11 @@ The Codex-side model is centered but flexible:
|
|
|
69
68
|
- `ahe`
|
|
70
69
|
- `ahe new`
|
|
71
70
|
- `ahe ship`
|
|
72
|
-
- `ahe
|
|
73
|
-
- `ahe fix stale tests`
|
|
74
|
-
- `stale tests ahe fix`
|
|
75
|
-
- `ahe compress`
|
|
76
|
-
- `compress ahe`
|
|
71
|
+
- `ahe stale tests`
|
|
77
72
|
- `ahe update product spec`
|
|
78
73
|
- `ahe add dashboard export feature`
|
|
79
74
|
|
|
80
|
-
Only exact `ahe`, exact `ahe
|
|
81
|
-
exact `ahe
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
Middle mentions that do not fit those command shapes do not.
|
|
75
|
+
Only exact `ahe`, exact `ahe ship`, exact `ahe-ship`, exact `$ahe-ship`,
|
|
76
|
+
exact `ahe git`, exact `ahe-git`, exact `$ahe-git`, `ahe-overview`,
|
|
77
|
+
`ahe <query>`, and `<query> ahe` activate the hook. Middle mentions that do
|
|
78
|
+
not fit those command shapes do not.
|
package/package.json
CHANGED
|
@@ -37,7 +37,6 @@ const COMMON_ROUTING_LINES = [
|
|
|
37
37
|
" - Check `feature-list.json` as a derived tracker.",
|
|
38
38
|
" - Check `progress.md`.",
|
|
39
39
|
" - Use `ahe-think` as the internal decision layer before choosing the next action.",
|
|
40
|
-
" - Before reading large harness files wholesale, let `ahe-think` run the `ahe-compress` size detector and test-overlap detector. Call `ahe-compress` if compression is required.",
|
|
41
40
|
"",
|
|
42
41
|
"2. Review code through CodeGraph when available:",
|
|
43
42
|
" - Prefer CodeGraph MCP or CodeGraph exploration for code review and impact context after the preflight command succeeds.",
|
|
@@ -51,14 +50,14 @@ const AHE_PROGRESS_DIRECTIVE = [
|
|
|
51
50
|
AHE_DIRECTIVE_MARKER,
|
|
52
51
|
"AHE automatic operation activated.",
|
|
53
52
|
"",
|
|
54
|
-
"The user sent
|
|
53
|
+
"The user sent an AHE continuation request. Operate as the Awesome Harness Engineering router:",
|
|
55
54
|
"",
|
|
56
55
|
...CODEGRAPH_PREFLIGHT_LINES,
|
|
57
56
|
...COMMON_ROUTING_LINES,
|
|
58
57
|
"",
|
|
59
58
|
"4. Decide the next AHE workflow with `ahe-think`:",
|
|
60
|
-
" - Automatically invoke `@ahe-harness-manager` before `ahe-think` chooses the next workflow if the harness state needs supervision (missing/invalid harness files, unfinished features, completed trackers with possible next work, or code/docs/tracker mismatch).",
|
|
61
59
|
" - Route through `ahe-think` first.",
|
|
60
|
+
" - let `ahe-think` decide whether `@ahe-harness-manager` supervision is needed before choosing the next workflow.",
|
|
62
61
|
" - If no harness files exist, route to `ahe-new`.",
|
|
63
62
|
" - If `docs/product.md` or `docs/INSTRUCTIONS.md` is missing or empty, classify the state as `harness engineering not enough`.",
|
|
64
63
|
" - If `feature-list.json` is missing or invalid, generating an empty one from template is allowed, but do not write specific features until `docs/product.md` and `docs/INSTRUCTIONS.md` are created and organized.",
|
|
@@ -67,8 +66,9 @@ const AHE_PROGRESS_DIRECTIVE = [
|
|
|
67
66
|
" - If any feature in `feature-list.json` has a status other than `done`, classify the state as `in the middle of building features` and continue the first unfinished feature whose dependencies are satisfied.",
|
|
68
67
|
" - If all features are `done` and no obvious harness gap remains, classify the state as `completed all` and ask the user for the next task.",
|
|
69
68
|
" - Call `ahe-review` when repo or code understanding is needed.",
|
|
69
|
+
" - Call `ahe-clean` when stale completed tracking history makes the current next step harder to see.",
|
|
70
70
|
" - Call `ahe-converse` when the next safe step is blocked on user input.",
|
|
71
|
-
" - Call `ahe-harness` when product docs, instructions, tracking, todo sync
|
|
71
|
+
" - Call `ahe-harness` when product docs, instructions, tracking, or todo sync must change.",
|
|
72
72
|
" - Call `ahe-harness-checker` to validate and repair generated harness artifacts after bootstrap or harness maintenance work.",
|
|
73
73
|
" - Call `ahe-feature` to size and extract new features.",
|
|
74
74
|
" - Call `ahe-solve` when the next job is solving or planning a feature.",
|
|
@@ -79,27 +79,6 @@ const AHE_PROGRESS_DIRECTIVE = [
|
|
|
79
79
|
" - Continue automatically after classification.",
|
|
80
80
|
];
|
|
81
81
|
|
|
82
|
-
const AHE_NEW_DIRECTIVE = [
|
|
83
|
-
AHE_DIRECTIVE_MARKER,
|
|
84
|
-
"AHE automatic operation activated.",
|
|
85
|
-
"",
|
|
86
|
-
"The user sent the exact AHE new command. Treat this as a possible new start request:",
|
|
87
|
-
"",
|
|
88
|
-
...CODEGRAPH_PREFLIGHT_LINES,
|
|
89
|
-
"2. Route to `ahe-think` first.",
|
|
90
|
-
"3. `ahe-think` must route to `ahe-new`.",
|
|
91
|
-
"4. Automatically invoke `@ahe-harness-manager` only when existing harness files need review before determining the restart scope.",
|
|
92
|
-
"5. If no AHE-managed harness files exist, start initialization normally.",
|
|
93
|
-
"6. If any AHE-managed harness file exists, read the existing files, summarize the current project purpose and product specification state, and ask what restart scope the user wants.",
|
|
94
|
-
"7. Do not remove, overwrite, or refresh existing harness files before the user answers the restart-scope question.",
|
|
95
|
-
"8. If the chosen restart scope replaces prior harness history, summarize that replaced state in the refreshed tracking artifacts instead of creating backup copies.",
|
|
96
|
-
"9. Interpret the restart scope from the user's free-form answer; examples like `purpose` and `product` are not a closed list.",
|
|
97
|
-
"10. Product/instructions specification details belong in `docs/product.md` and `docs/INSTRUCTIONS.md`, not `AGENTS.md`.",
|
|
98
|
-
"11. After setup, call `ahe-harness` to build the initial product, instructions, and tracking state, and end with `ahe-harness-checker` validation/fix before the harness is considered usable.",
|
|
99
|
-
"12. Use `ahe-think` before clarification when the next setup step is uncertain.",
|
|
100
|
-
"13. If clarification is needed, call `ahe-converse` for the exact missing detail.",
|
|
101
|
-
].join("\n");
|
|
102
|
-
|
|
103
82
|
const AHE_SHIP_DIRECTIVE = [
|
|
104
83
|
AHE_DIRECTIVE_MARKER,
|
|
105
84
|
"AHE plan export activated.",
|
|
@@ -119,25 +98,6 @@ const AHE_SHIP_DIRECTIVE = [
|
|
|
119
98
|
"Do not run the normal AHE harness workflow.",
|
|
120
99
|
].join("\n");
|
|
121
100
|
|
|
122
|
-
const AHE_FIX_DIRECTIVE = [
|
|
123
|
-
AHE_DIRECTIVE_MARKER,
|
|
124
|
-
"AHE fix planning activated.",
|
|
125
|
-
"",
|
|
126
|
-
"The user invoked `ahe-fix`.",
|
|
127
|
-
"",
|
|
128
|
-
...CODEGRAPH_PREFLIGHT_LINES,
|
|
129
|
-
"2. Route to `ahe-think` first.",
|
|
130
|
-
"3. `ahe-think` must immediately call the `ahe-fix` skill.",
|
|
131
|
-
"4. Automatically invoke `@ahe-harness-manager` only when the fix target may conflict with current harness state.",
|
|
132
|
-
"5. Understand the user's error, bug, mismatch, or intended change from the current conversation and repository context.",
|
|
133
|
-
"6. Create a concrete fix plan for fixing errors or following the user's intention when it differs from normal AHE continuation.",
|
|
134
|
-
"7. If the fix goal, scope, or success criteria are unclear, call `ahe-converse` and ask one focused question before writing the plan.",
|
|
135
|
-
"8. Derive `plan_name` from the fix goal and create `.plans/{plan_name}.md`.",
|
|
136
|
-
"9. Use `.codex/skills/ahe-fix/scripts/write_fix_plan.py` to write the final markdown.",
|
|
137
|
-
"",
|
|
138
|
-
"Do not run the normal AHE harness workflow.",
|
|
139
|
-
].join("\n");
|
|
140
|
-
|
|
141
101
|
const AHE_GIT_DIRECTIVE = [
|
|
142
102
|
AHE_DIRECTIVE_MARKER,
|
|
143
103
|
"AHE Git activated.",
|
|
@@ -172,21 +132,11 @@ function isExactAheCommand(prompt) {
|
|
|
172
132
|
return normalizePrompt(prompt) === "ahe";
|
|
173
133
|
}
|
|
174
134
|
|
|
175
|
-
function isExactAheNewCommand(prompt) {
|
|
176
|
-
const normalizedPrompt = normalizePrompt(prompt);
|
|
177
|
-
return normalizedPrompt === "ahe-new" || normalizedPrompt === "ahe new";
|
|
178
|
-
}
|
|
179
|
-
|
|
180
135
|
function isExactAheShipCommand(prompt) {
|
|
181
136
|
const normalizedPrompt = normalizePrompt(prompt);
|
|
182
137
|
return normalizedPrompt === "ahe-ship" || normalizedPrompt === "ahe ship";
|
|
183
138
|
}
|
|
184
139
|
|
|
185
|
-
function isExactAheFixCommand(prompt) {
|
|
186
|
-
const normalizedPrompt = normalizePrompt(prompt);
|
|
187
|
-
return normalizedPrompt === "ahe-fix" || normalizedPrompt === "ahe fix";
|
|
188
|
-
}
|
|
189
|
-
|
|
190
140
|
function isExactAheGitCommand(prompt) {
|
|
191
141
|
const normalizedPrompt = normalizePrompt(prompt);
|
|
192
142
|
return normalizedPrompt === "ahe-git" || normalizedPrompt === "ahe git";
|
|
@@ -196,6 +146,21 @@ function isExactAheOverviewCommand(prompt) {
|
|
|
196
146
|
return normalizePrompt(prompt) === "ahe-overview";
|
|
197
147
|
}
|
|
198
148
|
|
|
149
|
+
function isAheQueryCommand(prompt) {
|
|
150
|
+
const normalizedPrompt = normalizePrompt(prompt);
|
|
151
|
+
|
|
152
|
+
if (
|
|
153
|
+
isExactAheCommand(prompt) ||
|
|
154
|
+
isExactAheShipCommand(prompt) ||
|
|
155
|
+
isExactAheGitCommand(prompt) ||
|
|
156
|
+
isExactAheOverviewCommand(prompt)
|
|
157
|
+
) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return /^ahe .+/.test(normalizedPrompt) || /^.+ ahe$/.test(normalizedPrompt);
|
|
162
|
+
}
|
|
163
|
+
|
|
199
164
|
async function main() {
|
|
200
165
|
let raw = "";
|
|
201
166
|
process.stdin.setEncoding("utf8");
|
|
@@ -231,12 +196,12 @@ async function main() {
|
|
|
231
196
|
return;
|
|
232
197
|
}
|
|
233
198
|
|
|
234
|
-
if (
|
|
199
|
+
if (isAheQueryCommand(parsed.prompt)) {
|
|
235
200
|
process.stdout.write(
|
|
236
201
|
JSON.stringify({
|
|
237
202
|
hookSpecificOutput: {
|
|
238
203
|
hookEventName: "UserPromptSubmit",
|
|
239
|
-
additionalContext:
|
|
204
|
+
additionalContext: AHE_PROGRESS_DIRECTIVE.join("\n"),
|
|
240
205
|
},
|
|
241
206
|
}) + "\n"
|
|
242
207
|
);
|
|
@@ -255,18 +220,6 @@ async function main() {
|
|
|
255
220
|
return;
|
|
256
221
|
}
|
|
257
222
|
|
|
258
|
-
if (isExactAheFixCommand(parsed.prompt)) {
|
|
259
|
-
process.stdout.write(
|
|
260
|
-
JSON.stringify({
|
|
261
|
-
hookSpecificOutput: {
|
|
262
|
-
hookEventName: "UserPromptSubmit",
|
|
263
|
-
additionalContext: AHE_FIX_DIRECTIVE,
|
|
264
|
-
},
|
|
265
|
-
}) + "\n"
|
|
266
|
-
);
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
223
|
if (isExactAheGitCommand(parsed.prompt)) {
|
|
271
224
|
process.stdout.write(
|
|
272
225
|
JSON.stringify({
|
|
@@ -14,7 +14,9 @@ work in the current workspace.
|
|
|
14
14
|
- `ahe <query>` and `<query> ahe` mean continue AHE work with the user's
|
|
15
15
|
explicit query.
|
|
16
16
|
- `ahe` must route through `ahe-think` as the central decision layer.
|
|
17
|
-
- `ahe`
|
|
17
|
+
- `ahe-think` may call `ahe-new` internally when the workspace has no usable
|
|
18
|
+
harness yet.
|
|
19
|
+
- `ahe` must stay separate from the dedicated `ahe-ship` and `ahe-git`
|
|
18
20
|
workflows when the user's prompt matches those command contracts.
|
|
19
21
|
|
|
20
22
|
## Routing
|
|
@@ -30,5 +32,5 @@ work in the current workspace.
|
|
|
30
32
|
## Scope
|
|
31
33
|
|
|
32
34
|
- Use this skill for ongoing harness work, product updates, and explicit AHE
|
|
33
|
-
requests such as `ahe
|
|
34
|
-
- Do not use this skill for standalone
|
|
35
|
+
requests such as `ahe update product spec` or `ahe fix stale tests`.
|
|
36
|
+
- Do not use this skill for standalone ship-plan export or git orchestration.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ahe-clean
|
|
3
|
+
description: Use when valid harness tracking artifacts contain too much stale completed history and the current next step is harder to see.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# AHE Clean
|
|
7
|
+
|
|
8
|
+
This is an internal AHE workflow skill, not a user-facing command.
|
|
9
|
+
|
|
10
|
+
Do not treat `$ahe-clean` as a user command.
|
|
11
|
+
Use it when `ahe-think` decides that completed tracker history should be compacted
|
|
12
|
+
to restore clarity for current work.
|
|
13
|
+
|
|
14
|
+
## Purpose
|
|
15
|
+
|
|
16
|
+
- Reduce stale completed history in `feature-list.json`.
|
|
17
|
+
- Reduce stale completed history in `session-handoff.md`.
|
|
18
|
+
- Keep the active work legible without turning tracking artifacts into archives.
|
|
19
|
+
- Follow the tracking-policy contract owned by `ahe-harness`.
|
|
20
|
+
|
|
21
|
+
## Scope
|
|
22
|
+
|
|
23
|
+
- Read only the context needed to judge relevance:
|
|
24
|
+
- `docs/product.md`
|
|
25
|
+
- active `docs/product{number}.md` stage when present
|
|
26
|
+
- `feature-list.json`
|
|
27
|
+
- `progress.md`
|
|
28
|
+
- `session-handoff.md`
|
|
29
|
+
- Do not become a general harness editor.
|
|
30
|
+
- Do not rewrite `docs/product.md` or `docs/INSTRUCTIONS.md`.
|
|
31
|
+
- Touch `progress.md` only when the active-feature or latest-completed-work text
|
|
32
|
+
must stay consistent after cleanup.
|
|
33
|
+
|
|
34
|
+
## Cleanup Rules For `feature-list.json`
|
|
35
|
+
|
|
36
|
+
- Preserve all non-`done` features.
|
|
37
|
+
- Preserve the active feature from `progress.md`.
|
|
38
|
+
- Preserve completed dependency features needed for the active feature.
|
|
39
|
+
- Preserve completed features still needed to understand the active product
|
|
40
|
+
stage or the current next work.
|
|
41
|
+
- Remove `done` features that are not relevant under those rules.
|
|
42
|
+
- Replace removed completed history with one stable summary feature entry.
|
|
43
|
+
- The summary entry must stay `status: "done"`.
|
|
44
|
+
- The summary entry must explain that older unrelated completed work was
|
|
45
|
+
compacted.
|
|
46
|
+
- The summary entry must record a covered feature ID span or covered count.
|
|
47
|
+
- The summary entry must be updated in place on future cleanup runs instead of
|
|
48
|
+
duplicating summaries.
|
|
49
|
+
|
|
50
|
+
## Cleanup Rules For `session-handoff.md`
|
|
51
|
+
|
|
52
|
+
- In `## Last Completed Work`, preserve only:
|
|
53
|
+
- items directly related to the active feature;
|
|
54
|
+
- items needed to explain current harness state;
|
|
55
|
+
- items needed to justify the next recommended step.
|
|
56
|
+
- Remove unrelated older completed bullets.
|
|
57
|
+
- Replace removed bullets with one compact summary bullet describing that older
|
|
58
|
+
unrelated completed work was condensed.
|
|
59
|
+
- Keep `## Current Product Context`, `## Important Files`,
|
|
60
|
+
`## Next Recommended Action`, and `## Verification Status` governed by the
|
|
61
|
+
normal handoff rules; do not broadly compress them here.
|
|
62
|
+
|
|
63
|
+
## Completion
|
|
64
|
+
|
|
65
|
+
- Keep `feature-list.json` valid JSON.
|
|
66
|
+
- Keep `session-handoff.md` focused on the next-session startup path.
|
|
67
|
+
- Preserve current-work clarity rather than long-form history.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ahe-harness
|
|
3
|
-
description: Internal AHE harness workflow for managing product docs, instructions, feature tracking, session artifacts, todo sync
|
|
3
|
+
description: Internal AHE harness workflow for managing product docs, instructions, feature tracking, session artifacts, and todo sync.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# AHE Harness
|
|
@@ -9,7 +9,7 @@ This is an internal AHE workflow skill, not a user-facing command.
|
|
|
9
9
|
|
|
10
10
|
Do not treat `$ahe-harness` as a user command.
|
|
11
11
|
Use it when `ahe-think` or another worker decides that harness artifacts must
|
|
12
|
-
be created, updated,
|
|
12
|
+
be created, updated, or reconciled.
|
|
13
13
|
|
|
14
14
|
## Command Workflow: harness
|
|
15
15
|
|
|
@@ -54,12 +54,12 @@ be created, updated, reconciled, or compressed. It remains responsible for track
|
|
|
54
54
|
- Update `feature-list.json` to derive the specific feature items from the updated `docs/product.md`.
|
|
55
55
|
- Update `progress.md`.
|
|
56
56
|
- Update `session-handoff.md`.
|
|
57
|
-
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
57
|
+
- Treat `feature-list.json` and `session-handoff.md` as current-work artifacts,
|
|
58
|
+
not archival logs; they are current-work artifacts, and unrelated completed
|
|
59
|
+
history may be compacted when it no longer helps the active work.
|
|
60
|
+
- unrelated completed feature entries may be compacted.
|
|
61
|
+
- unrelated completed handoff bullets may be compacted.
|
|
62
|
+
- current-work-relevant completed context must remain.
|
|
63
63
|
- If no new feature can be derived from `docs/product.md`, call `ahe-converse` to ask what next feature, product direction, or goal should be tracked.
|
|
64
64
|
- If a numbered product stage is active and no new feature can be derived from
|
|
65
65
|
that active product stage, call `ahe-converse` with the same clarification
|
|
@@ -70,10 +70,11 @@ be created, updated, reconciled, or compressed. It remains responsible for track
|
|
|
70
70
|
### Harness Completion
|
|
71
71
|
|
|
72
72
|
- Keep `feature-list.json` valid JSON.
|
|
73
|
-
- Do not create backup copies when compressing harness history.
|
|
74
73
|
- Keep `progress.md` focused on current work, decisions that still matter,
|
|
75
74
|
blockers, and recent verification evidence.
|
|
76
75
|
- Keep `session-handoff.md` focused on the next-session startup path.
|
|
76
|
+
- Keep tracking artifacts concise enough that the current next step is easy to
|
|
77
|
+
identify.
|
|
77
78
|
- Keep `status.json` aligned with the active workflow.
|
|
78
79
|
- When harness files are created or refreshed, hand off to `ahe-harness-checker` before considering the harness ready.
|
|
79
80
|
|
|
@@ -5,7 +5,10 @@ description: Initialize AHE in the current workspace and create the base harness
|
|
|
5
5
|
|
|
6
6
|
# AHE New
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
This is an internal AHE workflow skill, not a user-facing command.
|
|
9
|
+
|
|
10
|
+
Use this skill when `ahe-think` decides the workspace needs bootstrap or
|
|
11
|
+
restart handling.
|
|
9
12
|
|
|
10
13
|
## Command Workflow: new
|
|
11
14
|
|
|
@@ -26,7 +29,8 @@ Use this skill when the user invokes `$ahe-new`.
|
|
|
26
29
|
|
|
27
30
|
### Sequential Conversation Flow
|
|
28
31
|
|
|
29
|
-
- Treat
|
|
32
|
+
- Treat new-start or reset intent arriving through the normal `ahe` path as a
|
|
33
|
+
possible new start request.
|
|
30
34
|
- If no AHE-managed harness files exist, start initialization normally without asking a restart-scope question.
|
|
31
35
|
- If any AHE-managed harness file already exists, read the existing files first.
|
|
32
36
|
- When existing harness files are present, summarize the current project purpose and product specification state, then ask what restart scope the user wants before removing, overwriting, or refreshing existing harness files.
|
|
@@ -10,12 +10,12 @@ AHE is a framework and set of managed skills designed to maintain project harnes
|
|
|
10
10
|
## Public Entrypoints
|
|
11
11
|
|
|
12
12
|
You interact with AHE using the following user-facing commands:
|
|
13
|
-
- **`ahe` / `ahe <query
|
|
14
|
-
- **`ahe new` / `ahe-new`**: Starts the initialization or reset flow for a workspace.
|
|
15
|
-
- **`ahe fix` / `ahe fix <query>`**: Starts fix planning when an error occurs or user intent shifts, skipping normal continuation. For example: `ahe fix stale tests`.
|
|
13
|
+
- **`ahe` / `ahe <query>` / `<query> ahe`**: Automatically inspects the harness state and routes to the correct next step. This same entrypoint covers new-workspace bootstrap, normal continuation, and user-directed follow-up such as `ahe update product spec` or `ahe fix stale tests`.
|
|
16
14
|
- **`ahe ship`**: In Codex, saves the latest Plan Mode plan into `.plans/{plan_name}.md` without automatically executing it. In Antigravity, refreshes and executes exactly one plan from `.plans/`.
|
|
17
15
|
- **`ahe-git`**: In Antigravity, safely pulls and commits all nested repositories.
|
|
18
16
|
|
|
17
|
+
`ahe-overview` remains an explanation helper, not part of the normal work-routing surface.
|
|
18
|
+
|
|
19
19
|
## Thinker-Centered Routing Model
|
|
20
20
|
|
|
21
21
|
AHE operates through a central decision layer: **`ahe-think`**. This internal agent determines the current state of the harness and delegates tasks to specialized sub-skills:
|
|
@@ -24,7 +24,7 @@ AHE operates through a central decision layer: **`ahe-think`**. This internal ag
|
|
|
24
24
|
- **`ahe-converse`**: Pauses and asks the user for clarification when blocked.
|
|
25
25
|
- **`ahe-feature`**: Sizes and extracts new features from product documentation.
|
|
26
26
|
- **`ahe-solve`**: Solves or plans specific features.
|
|
27
|
-
- **`ahe-
|
|
27
|
+
- **`ahe-new`**: Internal bootstrap worker used when `ahe-think` detects that the workspace has no usable harness yet.
|
|
28
28
|
|
|
29
29
|
These internal sub-skills are not user-facing commands.
|
|
30
30
|
|
|
@@ -41,32 +41,9 @@ graph TD;
|
|
|
41
41
|
State -- Need Context --> Review[ahe-review]
|
|
42
42
|
State -- Blocked --> Converse[ahe-converse]
|
|
43
43
|
State -- Harness Work --> Harness[ahe-harness]
|
|
44
|
-
State -- Compress --> Compress[ahe-compress]
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### 2. `ahe new` (Initialization)
|
|
48
|
-
```mermaid
|
|
49
|
-
graph TD;
|
|
50
|
-
User[User: ahe new] --> Hook[ahe-hook.js]
|
|
51
|
-
Hook --> Think[ahe-think]
|
|
52
|
-
Think --> New[ahe-new]
|
|
53
|
-
New --> Scope{Check Scope}
|
|
54
|
-
Scope -- Clarification --> Converse[ahe-converse]
|
|
55
|
-
Scope -- Done --> Harness[ahe-harness]
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### 3. `ahe fix` (Fix Planning)
|
|
59
|
-
```mermaid
|
|
60
|
-
graph TD;
|
|
61
|
-
User[User: ahe fix] --> Hook[ahe-hook.js]
|
|
62
|
-
Hook --> Think[ahe-think]
|
|
63
|
-
Think --> Fix[ahe-fix]
|
|
64
|
-
Fix --> Clarify{Clear?}
|
|
65
|
-
Clarify -- No --> Converse[ahe-converse]
|
|
66
|
-
Clarify -- Yes --> Write[Write Fix Plan]
|
|
67
44
|
```
|
|
68
45
|
|
|
69
|
-
###
|
|
46
|
+
### 2. `ahe ship` (Export / Execute Plan)
|
|
70
47
|
|
|
71
48
|
**In Codex (Export):**
|
|
72
49
|
```mermaid
|
|
@@ -86,7 +63,7 @@ graph TD;
|
|
|
86
63
|
Read --> Execute[Execute Plan]
|
|
87
64
|
```
|
|
88
65
|
|
|
89
|
-
###
|
|
66
|
+
### 3. `ahe-git` (Repository Sync)
|
|
90
67
|
|
|
91
68
|
**In Antigravity:**
|
|
92
69
|
```mermaid
|
|
@@ -100,8 +77,8 @@ graph TD;
|
|
|
100
77
|
## Example of How to Use
|
|
101
78
|
|
|
102
79
|
### Harness Engineering
|
|
103
|
-
1. `ahe
|
|
104
|
-
(
|
|
80
|
+
1. `ahe`
|
|
81
|
+
(in a workspace with no harness, `ahe-think` routes internally to `ahe-new`)
|
|
105
82
|
2. `ahe update product spec`
|
|
106
83
|
(update product documentation)
|
|
107
84
|
3. `ahe add dashboard export feature`
|
|
@@ -13,35 +13,24 @@ Use it as the central decision layer for AHE work.
|
|
|
13
13
|
## Purpose
|
|
14
14
|
|
|
15
15
|
- Judge what is missing before another agent acts.
|
|
16
|
+
- Optionally invoke `@ahe-harness-manager` as a pre-routing supervisor when the
|
|
17
|
+
harness state itself is unclear or contradictory.
|
|
18
|
+
- Optionally invoke `ahe-clean` when tracking artifacts are valid but noisy
|
|
19
|
+
enough that stale completed history makes the current next step harder to see.
|
|
16
20
|
- Judge the active `project`, `feature`, or `sub-feature`.
|
|
17
21
|
- Decide which of `Why`, `What`, and `How` are still missing.
|
|
18
|
-
- Choose the next internal agent: `ahe-review`, `ahe-converse`,
|
|
22
|
+
- Choose the next internal agent: `ahe-clean`, `ahe-review`, `ahe-converse`,
|
|
19
23
|
`ahe-harness`, or `ahe-solve`.
|
|
20
24
|
- Receive each agent result, reassess the state, and decide the next step.
|
|
21
25
|
|
|
22
26
|
## Routing Inputs
|
|
23
27
|
|
|
24
28
|
- Exact `ahe` means continue existing harness work.
|
|
25
|
-
- Exact `ahe init`, exact `ahe-new`, and exact `$ahe-new` stay on the
|
|
26
|
-
`$ahe-new` path.
|
|
27
29
|
- `ahe <query>` and `<query> ahe` mean route the query through `ahe-think`.
|
|
30
|
+
- New-start intent such as `ahe new` arrives through the normal `ahe` query
|
|
31
|
+
path, and `ahe-think` decides whether to call `ahe-new`.
|
|
28
32
|
- Broad non-prefixed prompts must not activate AHE.
|
|
29
33
|
|
|
30
|
-
## Size and Stale-Test Preflight
|
|
31
|
-
|
|
32
|
-
- Before reading full harness files, run
|
|
33
|
-
`sh .codex/skills/ahe-compress/scripts/check-harness-size.sh`.
|
|
34
|
-
- Run the test-overlap detector `python .codex/skills/ahe-compress/scripts/detect_stale_tests.py`
|
|
35
|
-
when the user's explicit AHE query is compression-oriented (e.g., `ahe compress`).
|
|
36
|
-
- Run both compression detectors before choosing the next compression step.
|
|
37
|
-
- If either detector exits with `COMPRESSION_REQUIRED` or code `2`, call
|
|
38
|
-
`ahe-compress` before normal routing. However, `ahe-compress` must not delete tests directly;
|
|
39
|
-
for test compression, `ahe-think` must decide whether the next step is `ahe-harness` for
|
|
40
|
-
harness-file compaction, `ahe-review` for stale-test confirmation and keeper selection,
|
|
41
|
-
or both in sequence.
|
|
42
|
-
- Do not read oversized harness files wholesale before compression routing is
|
|
43
|
-
settled.
|
|
44
|
-
|
|
45
34
|
## Startup Contract
|
|
46
35
|
|
|
47
36
|
- Check whether the copied harness files are correct before reading their contents.
|
|
@@ -63,11 +52,29 @@ Use it as the central decision layer for AHE work.
|
|
|
63
52
|
- Choose the active product source as the lowest-numbered stage whose derived
|
|
64
53
|
feature work is not complete, or `docs/product.md` when no numbered stage
|
|
65
54
|
exists.
|
|
55
|
+
- Use `@ahe-harness-manager` as an optional pre-routing supervisor when:
|
|
56
|
+
- missing or invalid harness artifacts;
|
|
57
|
+
- `docs/*.md`, `feature-list.json`, `progress.md`, `session-handoff.md`, and
|
|
58
|
+
code appear to disagree;
|
|
59
|
+
- all tracked features are done but likely next work exists;
|
|
60
|
+
- the harness state is ambiguous enough that `ahe-review` vs `ahe-harness` vs `ahe-converse` is not yet clear.
|
|
61
|
+
- Keep `@ahe-harness-manager` advisory. It reports findings back to
|
|
62
|
+
`ahe-think`; it does not replace `ahe-think` as the decision layer.
|
|
63
|
+
- Use `ahe-clean` when the harness is valid but noisy, including:
|
|
64
|
+
- too many `done` entries in `feature-list.json` that are unrelated to active work;
|
|
65
|
+
- too many stale bullets in `session-handoff.md`;
|
|
66
|
+
- current next work is harder to identify because old completed detail dominates the trackers.
|
|
67
|
+
- Treat `ahe-clean` as distinct from `@ahe-harness-manager` escalation:
|
|
68
|
+
`ahe-clean` handles valid but noisy tracking state, while
|
|
69
|
+
`@ahe-harness-manager` handles missing, invalid, mismatched, or otherwise
|
|
70
|
+
ambiguous harness state.
|
|
66
71
|
- If the need is understanding repo code, harness drift, progress evidence, or
|
|
67
72
|
CodeGraph context, call `ahe-review`.
|
|
68
73
|
- If the need is user clarification, call `ahe-converse`.
|
|
69
|
-
- If the need is updating harness artifacts, product docs, feature tracking,
|
|
70
|
-
todo sync,
|
|
74
|
+
- If the need is updating harness artifacts, product docs, feature tracking, or
|
|
75
|
+
todo sync, call `ahe-harness`.
|
|
76
|
+
- If the need is compacting stale completed tracking history without changing
|
|
77
|
+
product or instruction content, call `ahe-clean`.
|
|
71
78
|
- If the need is solving or decomposing feature work, call `ahe-solve`.
|
|
72
79
|
|
|
73
80
|
## Interaction Model
|
|
@@ -75,6 +82,8 @@ Use it as the central decision layer for AHE work.
|
|
|
75
82
|
- `ahe-think` is centered, but direct worker-to-worker calls are allowed when
|
|
76
83
|
they are the obvious next step.
|
|
77
84
|
- Typical loops:
|
|
85
|
+
- `ahe-think -> @ahe-harness-manager -> ahe-think`
|
|
86
|
+
- `ahe-think -> ahe-clean -> ahe-think`
|
|
78
87
|
- `ahe-think -> ahe-review -> ahe-think`
|
|
79
88
|
- `ahe-think -> ahe-harness -> ahe-think`
|
|
80
89
|
- `ahe-think -> ahe-converse -> ahe-think`
|
|
@@ -93,7 +102,9 @@ Use it as the central decision layer for AHE work.
|
|
|
93
102
|
|
|
94
103
|
- Use `ahe-review` for review-first requests.
|
|
95
104
|
- Use `ahe-harness` for product, instructions, progress, feature-list, todo, or
|
|
96
|
-
|
|
105
|
+
tracker-policy maintenance.
|
|
106
|
+
- Use `ahe-clean` for reducing stale completed history in `feature-list.json`
|
|
107
|
+
and `session-handoff.md`.
|
|
97
108
|
- Use `ahe-solve` for feature implementation planning or execution work.
|
|
98
109
|
- Use `ahe-converse` when no safe next step exists without user input.
|
|
99
110
|
|
|
@@ -24,10 +24,9 @@ readonly AHE_CONFIG_BLOCK_START="# BEGIN AHE MANAGED CONFIG"
|
|
|
24
24
|
readonly AHE_CONFIG_BLOCK_END="# END AHE MANAGED CONFIG"
|
|
25
25
|
readonly MANAGED_SKILLS=(
|
|
26
26
|
"ahe"
|
|
27
|
-
"ahe-
|
|
27
|
+
"ahe-clean"
|
|
28
28
|
"ahe-converse"
|
|
29
29
|
"ahe-feature"
|
|
30
|
-
"ahe-fix"
|
|
31
30
|
"ahe-git"
|
|
32
31
|
"ahe-harness"
|
|
33
32
|
"ahe-harness-checker"
|
|
@@ -80,31 +79,38 @@ cleanup_ahe_config_entries() {
|
|
|
80
79
|
temp_path="${config_path}.ahe-cleanup"
|
|
81
80
|
awk -v block_start="${AHE_CONFIG_BLOCK_START}" -v block_end="${AHE_CONFIG_BLOCK_END}" '
|
|
82
81
|
function is_ahe_header(line) {
|
|
83
|
-
return line ~ /^\[
|
|
84
|
-
line ~ /^\[hooks\.state\."ahe[^"]*"\]$/ ||
|
|
82
|
+
return line ~ /^\[hooks\.state\."ahe[^"]*"\]$/ ||
|
|
85
83
|
line ~ /^\[plugins\."?ahe[^]]*"?\]$/ ||
|
|
86
84
|
line ~ /^\[plugins\."@ksuchoi216\/ahe[^"]*"\]$/
|
|
87
85
|
}
|
|
88
86
|
|
|
89
87
|
$0 == block_start {
|
|
90
|
-
|
|
88
|
+
in_block = 1
|
|
91
89
|
next
|
|
92
90
|
}
|
|
93
91
|
|
|
94
92
|
$0 == block_end {
|
|
95
|
-
|
|
93
|
+
in_block = 0
|
|
94
|
+
next
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
in_block == 1 {
|
|
96
98
|
next
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
/^\[/ {
|
|
100
102
|
if (is_ahe_header($0)) {
|
|
101
|
-
|
|
103
|
+
skip_section = 1
|
|
102
104
|
next
|
|
103
105
|
}
|
|
104
|
-
|
|
106
|
+
skip_section = 0
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
|
|
109
|
+
skip_section == 1 {
|
|
110
|
+
next
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
{
|
|
108
114
|
print
|
|
109
115
|
}
|
|
110
116
|
' "${config_path}" > "${temp_path}"
|
|
@@ -249,11 +255,10 @@ Global Codex home:
|
|
|
249
255
|
|
|
250
256
|
Next:
|
|
251
257
|
1. Open Codex chat in any workspace.
|
|
252
|
-
2. Use \`ahe
|
|
253
|
-
3. Use
|
|
254
|
-
4. Use \`ahe
|
|
255
|
-
5. Use \`ahe
|
|
256
|
-
6. Use \`ahe <query>\` for explicit AHE requests such as \`ahe compress\`.
|
|
258
|
+
2. Use exact \`ahe\` to continue existing harness work or start a new harness when the workspace has none.
|
|
259
|
+
3. Use \`ahe ship\` after Plan Mode to write the latest plan to .plans.
|
|
260
|
+
4. Use \`ahe git\` for the safe git orchestration workflow.
|
|
261
|
+
5. Use \`ahe <query>\` for explicit AHE requests such as \`ahe update product spec\`.
|
|
257
262
|
EOF
|
|
258
263
|
}
|
|
259
264
|
|
|
@@ -278,11 +283,6 @@ doctor() {
|
|
|
278
283
|
fi
|
|
279
284
|
done
|
|
280
285
|
|
|
281
|
-
if [ ! -f "${target_shared_dir}/config.yaml" ]; then
|
|
282
|
-
printf 'Missing: %s/config.yaml\n' "${target_shared_dir}" >&2
|
|
283
|
-
errors=$((errors + 1))
|
|
284
|
-
fi
|
|
285
|
-
|
|
286
286
|
if [ ! -d "${target_shared_dir}/templates" ]; then
|
|
287
287
|
printf 'Missing: %s/templates\n' "${target_shared_dir}" >&2
|
|
288
288
|
errors=$((errors + 1))
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ahe-compress
|
|
3
|
-
description: Internal AHE compression workflow for detecting oversized harness-engineering files or stale overlapping tests, and compacting them before AHE thinker or harness routing reads large context. Use when AGENTS.md, docs/product.md, docs/product{number}.md, docs/INSTRUCTIONS.md, feature-list.json, progress.md, session-handoff.md, docs/todo.md, or other AHE harness artifacts have too many lines or waste context. It also covers stale overlapping tests.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# AHE Compression
|
|
7
|
-
|
|
8
|
-
This is an internal AHE workflow skill, not a user-facing command.
|
|
9
|
-
|
|
10
|
-
Do not treat `$ahe-compress` as a user command.
|
|
11
|
-
Use it after `think` or `harness` decides that harness context is too large to read
|
|
12
|
-
efficiently, or when test-suite cleanup is needed. When the user explicitly asks
|
|
13
|
-
for `ahe compress`, this skill must check both harness-file size pressure and
|
|
14
|
-
stale overlapping tests before deciding the next action.
|
|
15
|
-
|
|
16
|
-
## Test Overlap Detection
|
|
17
|
-
|
|
18
|
-
Run the deterministic test-overlap detector script:
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
python .codex/skills/compress/scripts/detect_stale_tests.py
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
The script checks for legacy tests already covered by newer canonical files and prints `REVIEW_TEST\t<legacy-file>\tcovered_by=<keeper-files>`.
|
|
25
|
-
It exits with code `2` and prints `TEST_COMPRESSION_REQUIRED` when stale candidates exist.
|
|
26
|
-
|
|
27
|
-
Note: `compress` must not directly delete tests; it only signals compression pressure. The actual test consolidation must be routed by `think` through `review` first and then `solve` or `harness` as needed.
|
|
28
|
-
|
|
29
|
-
## Size Detection
|
|
30
|
-
|
|
31
|
-
Run the deterministic line-count preflight before reading full harness files:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
sh .codex/skills/compress/scripts/check-harness-size.sh
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
The script checks these AHE-managed files when they exist:
|
|
38
|
-
|
|
39
|
-
- `AGENTS.md`
|
|
40
|
-
- `docs/product.md`
|
|
41
|
-
- numbered product stage docs such as `docs/product1.md` and `docs/product2.md`
|
|
42
|
-
- `docs/INSTRUCTIONS.md`
|
|
43
|
-
- `feature-list.json`
|
|
44
|
-
- `progress.md`
|
|
45
|
-
- `session-handoff.md`
|
|
46
|
-
- `docs/todo.md`
|
|
47
|
-
|
|
48
|
-
Default thresholds are configured in `.codex/ahe-shared/config.yaml`:
|
|
49
|
-
|
|
50
|
-
- `agent_md`: 80
|
|
51
|
-
- `product_md`: 180
|
|
52
|
-
- `instructions_md`: 180
|
|
53
|
-
- `feature_list_json`: 180
|
|
54
|
-
- `progress_md`: 180
|
|
55
|
-
- `session_handoff_md`: 180
|
|
56
|
-
- `todo_md`: 180
|
|
57
|
-
- `total`: 750 (combined harness context limit)
|
|
58
|
-
|
|
59
|
-
Override thresholds only when the workspace has an explicit local rule using environment variables (e.g., `AHE_AGENT_MD_LIMIT`, `AHE_FILE_LINE_LIMIT`, `AHE_TOTAL_LINE_LIMIT`):
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
AHE_AGENT_MD_LIMIT=100 AHE_TOTAL_LINE_LIMIT=900 sh .codex/skills/compress/scripts/check-harness-size.sh
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Exit code meanings:
|
|
66
|
-
|
|
67
|
-
- `0`: no compression needed.
|
|
68
|
-
- `2`: compression needed.
|
|
69
|
-
- Output ending in `COMPRESSION_REQUIRED`: compression needed.
|
|
70
|
-
- Any other nonzero code: detector failed; fall back to `wc -l` on the same
|
|
71
|
-
file set and continue the decision manually.
|
|
72
|
-
|
|
73
|
-
## Compression Decision
|
|
74
|
-
|
|
75
|
-
- Run both compression detectors before choosing the next compression step.
|
|
76
|
-
- If the detector exits `2`, compress before normal AHE routing continues.
|
|
77
|
-
- If the harness-size detector exits `2`, compact harness files first.
|
|
78
|
-
- If the stale-test detector exits `2`, route through `review` before any test cleanup.
|
|
79
|
-
- If only one file exceeds the per-file threshold, compress that file first.
|
|
80
|
-
- If total harness context exceeds the total threshold, compress the largest
|
|
81
|
-
AHE-managed files until the total is under the threshold.
|
|
82
|
-
- If `AGENTS.md` is oversized, obey the local `AGENTS.md` instructions before
|
|
83
|
-
editing it. Compress only sections that local rules allow. If no section is
|
|
84
|
-
safely editable, report the blocker and compress other harness files instead.
|
|
85
|
-
- Do not read an oversized file wholesale after detection. Read headings,
|
|
86
|
-
current-status sections, JSON keys, or bounded line ranges needed to preserve
|
|
87
|
-
behavior.
|
|
88
|
-
|
|
89
|
-
## Compression Rules
|
|
90
|
-
|
|
91
|
-
- Preserve active requirements, current decisions, incomplete work, blockers,
|
|
92
|
-
dependencies, and verification evidence.
|
|
93
|
-
- Preserve required headers and file formats for `progress.md`,
|
|
94
|
-
`session-handoff.md`, `feature-list.json`, and `AGENTS.md`.
|
|
95
|
-
- Keep `feature-list.json` valid JSON. Replace stale completed-feature history
|
|
96
|
-
with one summarized done feature, preserve its `id`, `name`, `description`,
|
|
97
|
-
`dependencies`, `status`, and short evidence, and keep current unfinished
|
|
98
|
-
details as-is.
|
|
99
|
-
- Keep `docs/product.md` and `docs/INSTRUCTIONS.md` as the current harness
|
|
100
|
-
contract. Remove duplicate historical wording only when the active contract
|
|
101
|
-
remains clear.
|
|
102
|
-
- Keep numbered product stage docs in numeric suffix order. Ignore non-numeric
|
|
103
|
-
product docs such as `docs/product-alpha.md` for stage ordering.
|
|
104
|
-
- Preserve the active product stage and do not merge future product stages into
|
|
105
|
-
current feature-list work during compression.
|
|
106
|
-
- Keep `progress.md` focused on current status, recent completed work,
|
|
107
|
-
decisions that still matter, blockers, and latest verification.
|
|
108
|
-
- Keep `session-handoff.md` focused on the startup path for the next session,
|
|
109
|
-
important files, open questions, and current verification status.
|
|
110
|
-
- Do not create backup copies when compressing harness history. Preserve useful
|
|
111
|
-
context through concise summaries in the refreshed harness files instead.
|
|
112
|
-
|
|
113
|
-
## Completion
|
|
114
|
-
|
|
115
|
-
- Re-run the size detector after compression.
|
|
116
|
-
- Run JSON validation when `feature-list.json` changed.
|
|
117
|
-
- Run the repository's normal harness verification command when compression
|
|
118
|
-
changed tracked harness files.
|
|
119
|
-
- Update `progress.md` and `session-handoff.md` with the compression evidence
|
|
120
|
-
when they changed or when compression affects the active workflow.
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
set -eu
|
|
3
|
-
|
|
4
|
-
limit_agent_md=180
|
|
5
|
-
limit_product_md=180
|
|
6
|
-
limit_instructions_md=180
|
|
7
|
-
limit_feature_list_json=180
|
|
8
|
-
limit_progress_md=180
|
|
9
|
-
limit_session_handoff_md=180
|
|
10
|
-
limit_todo_md=180
|
|
11
|
-
limit_total=750
|
|
12
|
-
|
|
13
|
-
config_file=".codex/ahe-shared/config.yaml"
|
|
14
|
-
if [ -f "${config_file}" ]; then
|
|
15
|
-
while IFS= read -r line || [ -n "$line" ]; do
|
|
16
|
-
line="${line#"${line%%[![:space:]]*}"}"
|
|
17
|
-
line="${line%"${line##*[![:space:]]}"}"
|
|
18
|
-
case "$line" in
|
|
19
|
-
"" | \#*) continue ;;
|
|
20
|
-
esac
|
|
21
|
-
|
|
22
|
-
key="${line%%:*}"
|
|
23
|
-
val="${line#*:}"
|
|
24
|
-
key="${key%"${key##*[![:space:]]}"}"
|
|
25
|
-
val="${val#"${val%%[![:space:]]*}"}"
|
|
26
|
-
|
|
27
|
-
case "$val" in
|
|
28
|
-
''|*[!0-9]*) continue ;;
|
|
29
|
-
esac
|
|
30
|
-
|
|
31
|
-
case "$key" in
|
|
32
|
-
agent_md) limit_agent_md="$val" ;;
|
|
33
|
-
product_md) limit_product_md="$val" ;;
|
|
34
|
-
instructions_md) limit_instructions_md="$val" ;;
|
|
35
|
-
feature_list_json) limit_feature_list_json="$val" ;;
|
|
36
|
-
progress_md) limit_progress_md="$val" ;;
|
|
37
|
-
session_handoff_md) limit_session_handoff_md="$val" ;;
|
|
38
|
-
todo_md) limit_todo_md="$val" ;;
|
|
39
|
-
total) limit_total="$val" ;;
|
|
40
|
-
esac
|
|
41
|
-
done < "${config_file}"
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
limit_agent_md="${AHE_AGENT_MD_LIMIT:-${AHE_FILE_LINE_LIMIT:-$limit_agent_md}}"
|
|
45
|
-
limit_product_md="${AHE_PRODUCT_MD_LIMIT:-${AHE_FILE_LINE_LIMIT:-$limit_product_md}}"
|
|
46
|
-
limit_instructions_md="${AHE_INSTRUCTIONS_MD_LIMIT:-${AHE_FILE_LINE_LIMIT:-$limit_instructions_md}}"
|
|
47
|
-
limit_feature_list_json="${AHE_FEATURE_LIST_JSON_LIMIT:-${AHE_FILE_LINE_LIMIT:-$limit_feature_list_json}}"
|
|
48
|
-
limit_progress_md="${AHE_PROGRESS_MD_LIMIT:-${AHE_FILE_LINE_LIMIT:-$limit_progress_md}}"
|
|
49
|
-
limit_session_handoff_md="${AHE_SESSION_HANDOFF_MD_LIMIT:-${AHE_FILE_LINE_LIMIT:-$limit_session_handoff_md}}"
|
|
50
|
-
limit_todo_md="${AHE_TODO_MD_LIMIT:-${AHE_FILE_LINE_LIMIT:-$limit_todo_md}}"
|
|
51
|
-
total_limit="${AHE_TOTAL_LINE_LIMIT:-$limit_total}"
|
|
52
|
-
|
|
53
|
-
total_lines=0
|
|
54
|
-
compression_required=0
|
|
55
|
-
|
|
56
|
-
if [ "$#" -eq 0 ]; then
|
|
57
|
-
set -- \
|
|
58
|
-
"AGENTS.md" \
|
|
59
|
-
"docs/product.md" \
|
|
60
|
-
"docs/INSTRUCTIONS.md" \
|
|
61
|
-
"feature-list.json" \
|
|
62
|
-
"progress.md" \
|
|
63
|
-
"session-handoff.md" \
|
|
64
|
-
"docs/todo.md"
|
|
65
|
-
|
|
66
|
-
if [ -d "docs" ]; then
|
|
67
|
-
product_stage_number=1
|
|
68
|
-
while [ "${product_stage_number}" -le 999 ]; do
|
|
69
|
-
product_stage_path="docs/product${product_stage_number}.md"
|
|
70
|
-
if [ -f "${product_stage_path}" ]; then
|
|
71
|
-
set -- "$@" "${product_stage_path}"
|
|
72
|
-
fi
|
|
73
|
-
product_stage_number=$((product_stage_number + 1))
|
|
74
|
-
done
|
|
75
|
-
fi
|
|
76
|
-
fi
|
|
77
|
-
|
|
78
|
-
for file_path in "$@"; do
|
|
79
|
-
if [ ! -f "${file_path}" ]; then
|
|
80
|
-
continue
|
|
81
|
-
fi
|
|
82
|
-
|
|
83
|
-
line_count="$(wc -l < "${file_path}")"
|
|
84
|
-
line_count="${line_count#"${line_count%%[![:space:]]*}"}"
|
|
85
|
-
line_count="${line_count%"${line_count##*[![:space:]]}"}"
|
|
86
|
-
total_lines=$((total_lines + line_count))
|
|
87
|
-
|
|
88
|
-
current_limit=180
|
|
89
|
-
case "${file_path}" in
|
|
90
|
-
"AGENTS.md") current_limit="${limit_agent_md}" ;;
|
|
91
|
-
"docs/product.md") current_limit="${limit_product_md}" ;;
|
|
92
|
-
"docs/product"[0-9]*".md") current_limit="${limit_product_md}" ;;
|
|
93
|
-
"docs/INSTRUCTIONS.md") current_limit="${limit_instructions_md}" ;;
|
|
94
|
-
"feature-list.json") current_limit="${limit_feature_list_json}" ;;
|
|
95
|
-
"progress.md") current_limit="${limit_progress_md}" ;;
|
|
96
|
-
"session-handoff.md") current_limit="${limit_session_handoff_md}" ;;
|
|
97
|
-
"docs/todo.md") current_limit="${limit_todo_md}" ;;
|
|
98
|
-
*) current_limit="${AHE_FILE_LINE_LIMIT:-180}" ;;
|
|
99
|
-
esac
|
|
100
|
-
|
|
101
|
-
if [ "${line_count}" -ge "${current_limit}" ]; then
|
|
102
|
-
compression_required=1
|
|
103
|
-
printf 'COMPRESS\t%s\t%s\tlimit=%s\n' "${file_path}" "${line_count}" "${current_limit}"
|
|
104
|
-
else
|
|
105
|
-
printf 'OK\t%s\t%s\tlimit=%s\n' "${file_path}" "${line_count}" "${current_limit}"
|
|
106
|
-
fi
|
|
107
|
-
done
|
|
108
|
-
|
|
109
|
-
if [ "${total_lines}" -ge "${total_limit}" ]; then
|
|
110
|
-
compression_required=1
|
|
111
|
-
printf 'COMPRESS_TOTAL\t%s\tlimit=%s\n' "${total_lines}" "${total_limit}"
|
|
112
|
-
else
|
|
113
|
-
printf 'OK_TOTAL\t%s\tlimit=%s\n' "${total_lines}" "${total_limit}"
|
|
114
|
-
fi
|
|
115
|
-
|
|
116
|
-
if [ "${compression_required}" -eq 1 ]; then
|
|
117
|
-
printf 'COMPRESSION_REQUIRED\n'
|
|
118
|
-
exit 2
|
|
119
|
-
fi
|
|
120
|
-
|
|
121
|
-
printf 'COMPRESSION_NOT_REQUIRED\n'
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import os
|
|
3
|
-
|
|
4
|
-
def main():
|
|
5
|
-
test_dir = "tests"
|
|
6
|
-
if not os.path.isdir(test_dir):
|
|
7
|
-
sys.exit(0)
|
|
8
|
-
|
|
9
|
-
overlap_map = {
|
|
10
|
-
"test_new_workflow.py": ["test_ahe_new.py"],
|
|
11
|
-
"test_spec_workflow.py": ["test_clarification_prompt.py", "test_ahe_new.py"],
|
|
12
|
-
"test_specialized_workflows.py": ["test_ahe_new.py", "test_clarification_prompt.py", "test_command_set.py"]
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
stale_found = False
|
|
16
|
-
for legacy_file, keeper_files in overlap_map.items():
|
|
17
|
-
legacy_path = os.path.join(test_dir, legacy_file)
|
|
18
|
-
if os.path.exists(legacy_path):
|
|
19
|
-
stale_found = True
|
|
20
|
-
keepers_str = ",".join(f"tests/{f}" for f in keeper_files)
|
|
21
|
-
print(f"REVIEW_TEST\ttests/{legacy_file}\tcovered_by={keepers_str}")
|
|
22
|
-
|
|
23
|
-
if stale_found:
|
|
24
|
-
print("TEST_COMPRESSION_REQUIRED")
|
|
25
|
-
sys.exit(2)
|
|
26
|
-
else:
|
|
27
|
-
sys.exit(0)
|
|
28
|
-
|
|
29
|
-
if __name__ == "__main__":
|
|
30
|
-
main()
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ahe-fix
|
|
3
|
-
description: Create a concrete `.plans/{plan_name}.md` fix plan for errors, bugs, or user-intent changes. Use when the user explicitly invokes `$fix`, `fix`, `ahe fix`, `ahe fix <query>`, or `<query> ahe fix`, and call `converse` when the plan needs clarification.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# AHE Fix
|
|
7
|
-
|
|
8
|
-
`fix` is a user-facing AHE command for creating a fix plan. It is separate
|
|
9
|
-
from the normal `ahe` continuation workflow, including the thinker-routed
|
|
10
|
-
`ahe <query>` and `<query> ahe` forms.
|
|
11
|
-
|
|
12
|
-
Use this skill when the user wants a plan for fixing errors or following their
|
|
13
|
-
current intention when it differs from the previous AHE flow.
|
|
14
|
-
|
|
15
|
-
## Workflow
|
|
16
|
-
|
|
17
|
-
1. Inspect the current conversation and relevant repository context.
|
|
18
|
-
2. Identify the fix target:
|
|
19
|
-
- error, failure, regression, or broken behavior to repair.
|
|
20
|
-
- user intention that differs from the existing AHE direction.
|
|
21
|
-
3. If the fix goal, scope, or success criteria are unclear, call
|
|
22
|
-
`converse` and ask one focused question before writing the plan.
|
|
23
|
-
4. Derive `plan_name` from the fix goal. Use a short lowercase hyphenated name.
|
|
24
|
-
If no safe name can be derived, ask one focused question for the plan name.
|
|
25
|
-
5. Build a compact markdown plan with these sections:
|
|
26
|
-
- `# {Fix Plan Title}`
|
|
27
|
-
- `## Fix Goal`
|
|
28
|
-
- `## Current Evidence`
|
|
29
|
-
- `## Assumptions`
|
|
30
|
-
- `## Scope`
|
|
31
|
-
- `## Steps`
|
|
32
|
-
- `## Verification Plan`
|
|
33
|
-
- `## Risks and Open Questions`
|
|
34
|
-
- `## Instructions for Next Agent`
|
|
35
|
-
6. Write the final markdown through `scripts/write_fix_plan.py`.
|
|
36
|
-
7. Report the created `.plans/{plan_name}.md` path.
|
|
37
|
-
|
|
38
|
-
## Missing Context
|
|
39
|
-
|
|
40
|
-
- If the requested fix is ambiguous, use `converse` instead of guessing.
|
|
41
|
-
- If the target file already exists, ask whether to overwrite it or choose a
|
|
42
|
-
distinct plan name.
|
|
43
|
-
- Do not update `feature-list.json`, `progress.md`, or `session-handoff.md`
|
|
44
|
-
for a normal fix-plan export unless the user explicitly asks for harness
|
|
45
|
-
tracking changes too.
|
|
46
|
-
|
|
47
|
-
## Writer Script
|
|
48
|
-
|
|
49
|
-
Use:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
python3 .codex/skills/fix/scripts/write_fix_plan.py \
|
|
53
|
-
--root "$PWD" \
|
|
54
|
-
--plan-name "Fix Plan Title" \
|
|
55
|
-
< /tmp/fix-plan.md
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Add `--overwrite` only after the user explicitly confirms replacing an existing
|
|
59
|
-
file.
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env -S uv run --script
|
|
2
|
-
# /// script
|
|
3
|
-
# requires-python = ">=3.11"
|
|
4
|
-
# dependencies = []
|
|
5
|
-
# ///
|
|
6
|
-
#
|
|
7
|
-
# How to run:
|
|
8
|
-
# 1. Install uv (if not installed):
|
|
9
|
-
# curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
10
|
-
# 2. Run directly:
|
|
11
|
-
# uv run write_fix_plan.py --root "$PWD" --plan-name "Fix Plan Title" < /tmp/fix-plan.md
|
|
12
|
-
# 3. Or with Python when dependencies are already available:
|
|
13
|
-
# python3 write_fix_plan.py --root "$PWD" --plan-name "Fix Plan Title" < /tmp/fix-plan.md
|
|
14
|
-
|
|
15
|
-
from __future__ import annotations
|
|
16
|
-
|
|
17
|
-
import re
|
|
18
|
-
import sys
|
|
19
|
-
from dataclasses import dataclass
|
|
20
|
-
from pathlib import Path
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@dataclass(frozen=True, slots=True)
|
|
24
|
-
class WriteFixPlanArgs:
|
|
25
|
-
root: Path
|
|
26
|
-
plan_name: str
|
|
27
|
-
overwrite: bool
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class ArgumentError(Exception):
|
|
31
|
-
def __init__(self, message: str) -> None:
|
|
32
|
-
self.message = message
|
|
33
|
-
super().__init__(message)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class PlanAlreadyExistsError(Exception):
|
|
37
|
-
def __init__(self, path: Path) -> None:
|
|
38
|
-
self.path = path
|
|
39
|
-
super().__init__(f"Plan file already exists: {path}")
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def sanitize_plan_name(plan_name: str) -> str:
|
|
43
|
-
normalized_name = re.sub(r"[^a-z0-9]+", "-", plan_name.strip().lower()).strip("-")
|
|
44
|
-
if normalized_name:
|
|
45
|
-
return normalized_name
|
|
46
|
-
raise ArgumentError("plan name must contain at least one letter or digit")
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def parse_args(argv: list[str]) -> WriteFixPlanArgs:
|
|
50
|
-
root: Path | None = None
|
|
51
|
-
plan_name: str | None = None
|
|
52
|
-
overwrite = False
|
|
53
|
-
index = 0
|
|
54
|
-
|
|
55
|
-
while index < len(argv):
|
|
56
|
-
argument = argv[index]
|
|
57
|
-
match argument:
|
|
58
|
-
case "--root":
|
|
59
|
-
index += 1
|
|
60
|
-
if index >= len(argv):
|
|
61
|
-
raise ArgumentError("--root requires a value")
|
|
62
|
-
root = Path(argv[index])
|
|
63
|
-
case "--plan-name":
|
|
64
|
-
index += 1
|
|
65
|
-
if index >= len(argv):
|
|
66
|
-
raise ArgumentError("--plan-name requires a value")
|
|
67
|
-
plan_name = argv[index]
|
|
68
|
-
case "--overwrite":
|
|
69
|
-
overwrite = True
|
|
70
|
-
case _:
|
|
71
|
-
raise ArgumentError(f"unknown argument: {argument}")
|
|
72
|
-
index += 1
|
|
73
|
-
|
|
74
|
-
if root is None:
|
|
75
|
-
raise ArgumentError("--root is required")
|
|
76
|
-
if plan_name is None:
|
|
77
|
-
raise ArgumentError("--plan-name is required")
|
|
78
|
-
|
|
79
|
-
return WriteFixPlanArgs(root=root, plan_name=plan_name, overwrite=overwrite)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def write_fix_plan(args: WriteFixPlanArgs, markdown: str) -> Path:
|
|
83
|
-
filename = f"{sanitize_plan_name(args.plan_name)}.md"
|
|
84
|
-
plans_dir = args.root / ".plans"
|
|
85
|
-
plan_path = plans_dir / filename
|
|
86
|
-
|
|
87
|
-
if plan_path.exists() and not args.overwrite:
|
|
88
|
-
raise PlanAlreadyExistsError(plan_path)
|
|
89
|
-
|
|
90
|
-
plans_dir.mkdir(parents=True, exist_ok=True)
|
|
91
|
-
plan_path.write_text(markdown, encoding="utf-8")
|
|
92
|
-
return plan_path
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def main() -> int:
|
|
96
|
-
try:
|
|
97
|
-
args = parse_args(sys.argv[1:])
|
|
98
|
-
plan_path = write_fix_plan(args, sys.stdin.read())
|
|
99
|
-
except (ArgumentError, PlanAlreadyExistsError) as error:
|
|
100
|
-
print(error, file=sys.stderr)
|
|
101
|
-
return 1
|
|
102
|
-
|
|
103
|
-
print(plan_path)
|
|
104
|
-
return 0
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if __name__ == "__main__":
|
|
108
|
-
raise SystemExit(main())
|