genesis-compiler 1.2.13 → 1.2.15
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 +36 -19
- package/docs/assurance-model.md +1 -1
- package/docs/prompt-integration.md +18 -12
- package/docs/stack-components.md +18 -8
- package/package.json +2 -1
- package/plugins/genesis/.codex-plugin/plugin.json +1 -1
- package/prompts/deslop.txt +7 -0
- package/prompts/final-summary.txt +12 -0
- package/skills/genesis-deslop/SKILL.md +15 -7
- package/src/index/assets.js +1 -0
- package/src/index/codex-hooks.js +71 -7
- package/src/index/prompt.js +24 -9
- package/src/index/stack-piece.js +19 -5
- package/src/index/stack.js +1 -0
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ interaction.
|
|
|
14
14
|
genesis/
|
|
15
15
|
blueprint.md non-technical product intent
|
|
16
16
|
stack.md selected technology guidance, verification, declarations, and opaque extensions
|
|
17
|
-
stack/ optional per-component Description, Guidance, Adoption, and Deslop customization
|
|
17
|
+
stack/ optional per-component Description, Guidance, Adoption, Post-change, and Deslop customization
|
|
18
18
|
program/ concise explanations grouped into conceptual subsystems
|
|
19
19
|
.agents/skills/
|
|
20
20
|
genesis-* Genesis workflow skills
|
|
@@ -213,18 +213,25 @@ adds its adapter through its Stack piece rather than teaching Genesis prompts
|
|
|
213
213
|
to parse that language.
|
|
214
214
|
|
|
215
215
|
At the end of a turn that changed Git-visible project files, the Stop hook asks
|
|
216
|
-
Codex for
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
216
|
+
Codex for bounded follow-up turns. When the selected Stack contributes
|
|
217
|
+
`Post-change` work, all contributions compose deterministically into one
|
|
218
|
+
optional code-changing turn. Genesis then reconciles the Blueprint and affected
|
|
219
|
+
Program explanations from the complete changed-path set and actual Git diff,
|
|
220
|
+
and refreshes both City projections. A focused, behavior-preserving Deslop pass
|
|
221
|
+
runs before both Cities are refreshed again. Genesis then requests one concise
|
|
222
|
+
user-facing summary using conversation context only; that final phase is not
|
|
223
|
+
Stack-configurable and cannot schedule more cleanup. A project with no selected
|
|
221
224
|
Stack uses only the `genesis-deslop` skill. Selected Stack components enrich
|
|
222
|
-
reconciliation and cleanup with
|
|
223
|
-
further with technology-specific Deslop guidance.
|
|
225
|
+
Post-change work, reconciliation, and cleanup with general Guidance, and enrich
|
|
226
|
+
cleanup further with technology-specific Deslop guidance.
|
|
224
227
|
|
|
225
228
|
The hook never starts another Codex process. Its small per-session phase is
|
|
226
|
-
limited to `implementation -> reconcile -> deslop ->
|
|
227
|
-
|
|
229
|
+
limited to `implementation -> optional post-change -> reconcile -> deslop ->
|
|
230
|
+
summary -> done`, so it cannot keep continuing recursively. The summary prompt
|
|
231
|
+
forbids repository inspection, tools, commands, tests, and edits, and the next
|
|
232
|
+
Stop always clears the sequence rather than scheduling more work. Empty
|
|
233
|
+
Post-change content is skipped rather than producing an empty turn.
|
|
234
|
+
Question-only and unchanged turns finish normally.
|
|
228
235
|
|
|
229
236
|
Projects can customize a selected technology through its matching file, such
|
|
230
237
|
as `genesis/stack/jskit.md`:
|
|
@@ -242,6 +249,10 @@ Additional project-specific context about how JSKIT is used here.
|
|
|
242
249
|
|
|
243
250
|
- Additional project-specific implementation and review guidance.
|
|
244
251
|
|
|
252
|
+
### Post-change
|
|
253
|
+
|
|
254
|
+
- Additional project-specific work to perform once after implementation.
|
|
255
|
+
|
|
245
256
|
### Deslop
|
|
246
257
|
|
|
247
258
|
- Additional project-specific cleanup guidance.
|
|
@@ -256,6 +267,10 @@ A replacement for the installed JSKIT description.
|
|
|
256
267
|
|
|
257
268
|
- Replacement installed implementation and review guidance.
|
|
258
269
|
|
|
270
|
+
### Post-change
|
|
271
|
+
|
|
272
|
+
- Replacement installed post-change work.
|
|
273
|
+
|
|
259
274
|
### Deslop
|
|
260
275
|
|
|
261
276
|
- Replacement installed cleanup guidance.
|
|
@@ -263,10 +278,10 @@ A replacement for the installed JSKIT description.
|
|
|
263
278
|
|
|
264
279
|
Every field is optional. For each field, Genesis uses the installed value,
|
|
265
280
|
replaces it when `Override` supplies that field, then appends the corresponding
|
|
266
|
-
`Add` content. Customization affects only `Description`, `Guidance`,
|
|
267
|
-
`Deslop`; component dependencies, Agent Skill
|
|
268
|
-
verification commands retain their installed contracts.
|
|
269
|
-
preserves these matching customization files.
|
|
281
|
+
`Add` content. Customization affects only `Description`, `Guidance`,
|
|
282
|
+
`Adoption`, `Post-change`, and `Deslop`; component dependencies, Agent Skill
|
|
283
|
+
source, resources, and verification commands retain their installed contracts.
|
|
284
|
+
`genesis stack add` preserves these matching customization files.
|
|
270
285
|
|
|
271
286
|
Prompt generation remains available for other agents and explicit tasks:
|
|
272
287
|
|
|
@@ -350,6 +365,7 @@ Components may contribute:
|
|
|
350
365
|
|
|
351
366
|
- a concise description and supplemental Guidance used across relevant tasks;
|
|
352
367
|
- existing-project Adoption requirements used only while importing a codebase;
|
|
368
|
+
- optional Post-change work composed once after a code-changing implementation;
|
|
353
369
|
- one authoritative Agent Skill directory when the component owns one;
|
|
354
370
|
- generic external-resource requirements;
|
|
355
371
|
- cleanup advice used by explicit and automatic Deslop prompts;
|
|
@@ -358,7 +374,8 @@ Components may contribute:
|
|
|
358
374
|
|
|
359
375
|
Technology-specific supplemental rules intentionally remain in Stack pieces.
|
|
360
376
|
General `Guidance` enriches implementation, review, Program, description, and
|
|
361
|
-
cleanup tasks; `Adoption` adds import-only requirements; `
|
|
377
|
+
cleanup tasks; `Adoption` adds import-only requirements; `Post-change` composes
|
|
378
|
+
one optional code-changing continuation before explanation; `Deslop` adds
|
|
362
379
|
cleanup-only rules. None shadows an official generic technology skill or
|
|
363
380
|
assumes that an upstream skill contains every rule Genesis needs.
|
|
364
381
|
|
|
@@ -383,10 +400,10 @@ command without a shell. A complete successful run writes only
|
|
|
383
400
|
- the commands that passed.
|
|
384
401
|
|
|
385
402
|
The evidence becomes stale when code, selected components, declared resources,
|
|
386
|
-
or verification commands change. Description, Guidance, Adoption,
|
|
387
|
-
prose do not rewrite what an already-run command proved.
|
|
388
|
-
removes prior passing evidence before running.
|
|
389
|
-
whole-product correctness.
|
|
403
|
+
or verification commands change. Description, Guidance, Adoption, Post-change,
|
|
404
|
+
Agent Skill, and Deslop prose do not rewrite what an already-run command proved.
|
|
405
|
+
A failed verification removes prior passing evidence before running.
|
|
406
|
+
Verification does not claim whole-product correctness.
|
|
390
407
|
|
|
391
408
|
A project can replace component defaults in `genesis/stack.md`:
|
|
392
409
|
|
package/docs/assurance-model.md
CHANGED
|
@@ -17,7 +17,7 @@ Genesis reports only facts it can establish mechanically:
|
|
|
17
17
|
City projects the Program modules and source citations that exist. Neither
|
|
18
18
|
proves semantic equivalence, complete dynamic dispatch, or true duplication.
|
|
19
19
|
|
|
20
|
-
Prompt text, Stack Description/Guidance/Adoption/Deslop prose, Program prose, Agent Skill
|
|
20
|
+
Prompt text, Stack Description/Guidance/Adoption/Post-change/Deslop prose, Program prose, Agent Skill
|
|
21
21
|
content, and agent output are not assurance evidence. Genesis does not claim
|
|
22
22
|
that product intent and code have converged, that Program is complete or
|
|
23
23
|
semantically current, or that passing checks prove the whole product correct.
|
|
@@ -74,14 +74,19 @@ hosts can call `adoptProject()` and send its `prompt` directly.
|
|
|
74
74
|
|
|
75
75
|
Codex can instead use the project-local hooks installed by `genesis init`.
|
|
76
76
|
Those hooks inject a short operating guide, record whether the current turn
|
|
77
|
-
changed project files, then request
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
changed project files, then request bounded continuations. Selected
|
|
78
|
+
`Post-change` contributions compose into one optional code-changing turn;
|
|
79
|
+
Genesis then reconciles Blueprint and affected Program explanations from the
|
|
80
|
+
complete Git-visible change set and Deslops the implementation. One final
|
|
81
|
+
summary prompt then asks for a concise user-facing account from conversation
|
|
82
|
+
context only, forbids tools and edits, and cannot schedule more cleanup. The
|
|
83
|
+
hooks invoke the same Genesis project operations and never start another agent
|
|
84
|
+
process. A per-session phase permits only `implementation -> optional
|
|
85
|
+
post-change -> reconcile -> deslop -> summary -> done`. Empty Post-change
|
|
86
|
+
content skips that phase. Genesis refreshes both City projections after
|
|
87
|
+
reconciliation so Deslop sees the current explanation and function inventory,
|
|
88
|
+
then refreshes them again after Deslop in case cleanup changed the
|
|
89
|
+
implementation map.
|
|
85
90
|
|
|
86
91
|
Once Codex identifies relevant source, `genesis context <path...>` returns only
|
|
87
92
|
Program modules citing those paths plus concise selected Stack context, the
|
|
@@ -99,8 +104,9 @@ This follows Agent Skills progressive disclosure and keeps official or
|
|
|
99
104
|
user-installed generic technology skills independent.
|
|
100
105
|
|
|
101
106
|
Matching files under `genesis/stack/<component>.md` may add to or override that
|
|
102
|
-
selected component's Description, Guidance, Adoption, and Deslop
|
|
103
|
-
Guidance is used by work, review, Program, describe, Deslop,
|
|
104
|
-
generation. The Codex continuation flow also carries it into
|
|
105
|
-
cleanup; effective
|
|
107
|
+
selected component's Description, Guidance, Adoption, Post-change, and Deslop
|
|
108
|
+
fields. Effective Guidance is used by work, review, Program, describe, Deslop,
|
|
109
|
+
and path-context generation. The Codex continuation flow also carries it into
|
|
110
|
+
Post-change work, reconciliation, and cleanup; effective Post-change work runs
|
|
111
|
+
once before reconciliation, while Deslop guidance remains cleanup-only. Effective Adoption
|
|
106
112
|
guidance is included only in the adoption workflow.
|
package/docs/stack-components.md
CHANGED
|
@@ -68,6 +68,10 @@ Concise technology context.
|
|
|
68
68
|
|
|
69
69
|
- Existing-project import guidance.
|
|
70
70
|
|
|
71
|
+
## Post-change
|
|
72
|
+
|
|
73
|
+
- Optional work to perform once after a code-changing implementation turn.
|
|
74
|
+
|
|
71
75
|
## Deslop
|
|
72
76
|
|
|
73
77
|
- Technology-specific cleanup guidance.
|
|
@@ -82,9 +86,10 @@ Concise technology context.
|
|
|
82
86
|
```
|
|
83
87
|
````
|
|
84
88
|
|
|
85
|
-
`Description`, `Guidance`, `Adoption`, and `Deslop` are prose.
|
|
86
|
-
`Conflicts` define component selection. `Skill` names one
|
|
87
|
-
Agent Skill directory. `Indexers` selects installed
|
|
89
|
+
`Description`, `Guidance`, `Adoption`, `Post-change`, and `Deslop` are prose.
|
|
90
|
+
`Requires` and `Conflicts` define component selection. `Skill` names one
|
|
91
|
+
complete authoritative Agent Skill directory. `Indexers` selects installed
|
|
92
|
+
structural adapters.
|
|
88
93
|
`Resources`, `Environment defaults`, `Environment files`, and `Verification`
|
|
89
94
|
use the small Genesis grammars documented below. Every other `##` section is an
|
|
90
95
|
opaque extension.
|
|
@@ -155,8 +160,8 @@ contract therefore stales prior Genesis verification evidence even though
|
|
|
155
160
|
Genesis does not interpret the extension.
|
|
156
161
|
|
|
157
162
|
Prose and Agent Skill contents are instructions rather than verification
|
|
158
|
-
evidence. Changes to Description, Guidance, Adoption, Deslop, or
|
|
159
|
-
Skill do not rewrite what an already-run command proved.
|
|
163
|
+
evidence. Changes to Description, Guidance, Adoption, Post-change, Deslop, or
|
|
164
|
+
the installed Skill do not rewrite what an already-run command proved.
|
|
160
165
|
|
|
161
166
|
`City regions` and `Indexers` control only the derived structural maps. Indexers
|
|
162
167
|
identify language adapters. City regions can exclude test/spec paths and group
|
|
@@ -177,6 +182,10 @@ A selected component may have one prose-only customization at
|
|
|
177
182
|
|
|
178
183
|
- Additional project guidance.
|
|
179
184
|
|
|
185
|
+
### Post-change
|
|
186
|
+
|
|
187
|
+
- Additional project-specific post-change work.
|
|
188
|
+
|
|
180
189
|
## Override
|
|
181
190
|
|
|
182
191
|
### Deslop
|
|
@@ -184,9 +193,10 @@ A selected component may have one prose-only customization at
|
|
|
184
193
|
- Replacement cleanup guidance.
|
|
185
194
|
```
|
|
186
195
|
|
|
187
|
-
Customizations may add or override only Description, Guidance, Adoption,
|
|
188
|
-
Deslop. They cannot mutate selection, resources, environment
|
|
189
|
-
Verification, Agent Skill ownership, indexers, or opaque consumer
|
|
196
|
+
Customizations may add or override only Description, Guidance, Adoption,
|
|
197
|
+
Post-change, and Deslop. They cannot mutate selection, resources, environment
|
|
198
|
+
declarations, Verification, Agent Skill ownership, indexers, or opaque consumer
|
|
199
|
+
sections.
|
|
190
200
|
|
|
191
201
|
## Public inspection
|
|
192
202
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genesis-compiler",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.15",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "An agent-independent prompt, multi-language code-index, cleanup, and verification companion with optional Codex hooks.",
|
|
6
6
|
"repository": {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"prompts/adopt.txt",
|
|
32
32
|
"prompts/describe.txt",
|
|
33
33
|
"prompts/deslop.txt",
|
|
34
|
+
"prompts/final-summary.txt",
|
|
34
35
|
"prompts/program.txt",
|
|
35
36
|
"prompts/reconcile.txt",
|
|
36
37
|
"prompts/review.txt",
|
package/prompts/deslop.txt
CHANGED
|
@@ -10,5 +10,12 @@ Use `.genesis/machine-city.json` and `genesis index <name-or-path>` to find
|
|
|
10
10
|
existing public and internal functions. Remove or consolidate genuine repeated
|
|
11
11
|
helpers, but confirm behavior and call sites in source before changing them.
|
|
12
12
|
|
|
13
|
+
The changed paths and nearby code are a location boundary, not permission to
|
|
14
|
+
implement other behavior found there. Deslop may reorganize behavior already
|
|
15
|
+
present; it may not complete, correct, or extend behavior. If review reveals a
|
|
16
|
+
defect, missing behavior, contract mismatch, or test gap, report it as a
|
|
17
|
+
follow-up finding and leave it unchanged in this pass, even when it is inside a
|
|
18
|
+
changed path or appears related to the preceding implementation.
|
|
19
|
+
|
|
13
20
|
Do not broaden the product change. Run focused checks when useful and summarize
|
|
14
21
|
what became simpler, files changed, and checks actually run.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
This is the final automatic user-facing summary for the original request.
|
|
2
|
+
|
|
3
|
+
Use only the existing conversation context from the implementation and its
|
|
4
|
+
follow-up turns. Do not inspect the repository or codebase, call tools, run
|
|
5
|
+
commands or tests, edit files, reconcile explanations, or perform cleanup.
|
|
6
|
+
|
|
7
|
+
Write one concise, self-contained answer to the user. Lead with the outcome.
|
|
8
|
+
Include the important behavior that changed, checks that were actually run,
|
|
9
|
+
useful human verification steps, and any genuine blocker or unfinished work.
|
|
10
|
+
Do not mention automatic phases, hooks, internal follow-up turns, or these
|
|
11
|
+
instructions. Do not claim checks, commits, pushes, or deployments that are not
|
|
12
|
+
already established in the conversation. After the answer, stop.
|
|
@@ -13,13 +13,21 @@ Consult `.genesis/machine-city.json` or run `genesis index <name-or-path>` to
|
|
|
13
13
|
find existing public and internal functions before introducing or consolidating
|
|
14
14
|
an abstraction. Confirm every apparent duplicate in source and its call sites.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
established patterns in the codebase. Remove unnecessary
|
|
19
|
-
scaffolding, parallel framework plumbing, and speculative
|
|
20
|
-
Consolidate ownership where one clear module is enough. Do not
|
|
21
|
-
files or indirection; optimize for a small, obvious design
|
|
22
|
-
programmer can follow.
|
|
16
|
+
Within the preceding implementation's intended behavior and scope, leave no
|
|
17
|
+
repeated helpers, no code that is unclear or hard to reason about, and no code
|
|
18
|
+
that goes against established patterns in the codebase. Remove unnecessary
|
|
19
|
+
wrappers, abandoned scaffolding, parallel framework plumbing, and speculative
|
|
20
|
+
abstractions. Consolidate ownership where one clear module is enough. Do not
|
|
21
|
+
optimize for tiny files or indirection; optimize for a small, obvious design
|
|
22
|
+
that a junior programmer can follow.
|
|
23
|
+
|
|
24
|
+
Cleanup is not a second implementation pass. A changed path limits where cleanup
|
|
25
|
+
may occur; it does not authorize different behavior in that file. Deslop may
|
|
26
|
+
reorganize behavior already present; it may not complete, correct, or extend
|
|
27
|
+
behavior. If review reveals a defect, missing behavior, contract mismatch, or
|
|
28
|
+
test gap, report it as a follow-up finding and leave it unchanged, even when it
|
|
29
|
+
is inside a changed path or appears related to the preceding implementation. Do
|
|
30
|
+
not implement the finding or alter tests to accommodate it during Deslop.
|
|
23
31
|
|
|
24
32
|
Apply every technology-specific Deslop instruction supplied by the selected
|
|
25
33
|
Stack. Load applicable official technology skills for additional framework and
|
package/src/index/assets.js
CHANGED
|
@@ -8,6 +8,7 @@ const assets = {
|
|
|
8
8
|
describe: new URL('prompts/describe.txt', root),
|
|
9
9
|
reconcile: new URL('prompts/reconcile.txt', root),
|
|
10
10
|
deslop: new URL('prompts/deslop.txt', root),
|
|
11
|
+
finalSummary: new URL('prompts/final-summary.txt', root),
|
|
11
12
|
program: new URL('prompts/program.txt', root),
|
|
12
13
|
blueprint: new URL('prompts/blueprint.txt', root),
|
|
13
14
|
review: new URL('prompts/review.txt', root),
|
package/src/index/codex-hooks.js
CHANGED
|
@@ -134,8 +134,8 @@ export async function codexSessionContext({ projectRoot } = {}) {
|
|
|
134
134
|
'- Before creating a helper or public operation, run `genesis index <name-or-path>` and reuse an existing function when it already owns the behavior.',
|
|
135
135
|
'- `.genesis/machine-city.json` is the detailed code/function map; `.genesis/program-city.json` is the simpler subsystem/operation map.',
|
|
136
136
|
'- Program is fallible explanation; code, tests, and runtime behavior remain evidence.',
|
|
137
|
-
'- Keep implementation focused; the Stop hook owns
|
|
138
|
-
'- After a code-changing turn, Genesis may request separate explanation and
|
|
137
|
+
'- Keep implementation focused; the Stop hook owns optional Stack Post-change work, Blueprint/Program reconciliation, and Deslop turns.',
|
|
138
|
+
'- After a code-changing turn, Genesis may request separate post-change, explanation, cleanup, and final-summary turns.',
|
|
139
139
|
`Selected Stack components: ${stackStatus}.`,
|
|
140
140
|
].join('\n'),
|
|
141
141
|
};
|
|
@@ -173,8 +173,12 @@ function hookId(input, field) {
|
|
|
173
173
|
return value;
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
function normalizedPaths(values = []) {
|
|
177
|
+
return [...new Set(values.map(normalizeRelative).filter(Boolean))];
|
|
178
|
+
}
|
|
179
|
+
|
|
176
180
|
function zeroPaths(buffer) {
|
|
177
|
-
return buffer.toString('utf8').split('\0')
|
|
181
|
+
return normalizedPaths(buffer.toString('utf8').split('\0'));
|
|
178
182
|
}
|
|
179
183
|
|
|
180
184
|
async function repositorySnapshot(projectRoot) {
|
|
@@ -292,6 +296,24 @@ async function reconciliationContinuation(projectRoot, changedPaths) {
|
|
|
292
296
|
].join('\n');
|
|
293
297
|
}
|
|
294
298
|
|
|
299
|
+
function postChangeContinuation(changedPaths, stack) {
|
|
300
|
+
return [
|
|
301
|
+
'This is the one automatic Stack Post-change turn for the preceding implementation.',
|
|
302
|
+
'Use the same conversation context and the Git-visible changes below.',
|
|
303
|
+
'Perform only the composed Post-change work. Do not broaden the task, reconcile Genesis explanations, or perform Deslop yet.',
|
|
304
|
+
'Do not repeat or schedule another Post-change turn. If none of the configured work applies, make no changes and respond minimally.',
|
|
305
|
+
'',
|
|
306
|
+
'CHANGED PROJECT PATHS',
|
|
307
|
+
'',
|
|
308
|
+
...changedPathLines(changedPaths),
|
|
309
|
+
'',
|
|
310
|
+
'COMPOSED STACK POST-CHANGE WORK',
|
|
311
|
+
'',
|
|
312
|
+
stack.postChange,
|
|
313
|
+
...(stack.guidance ? ['', 'SELECTED STACK GUIDANCE', '', stack.guidance] : []),
|
|
314
|
+
].join('\n');
|
|
315
|
+
}
|
|
316
|
+
|
|
295
317
|
async function deslopContinuation(projectRoot, changedPaths) {
|
|
296
318
|
const [instructions, stack] = await Promise.all([
|
|
297
319
|
readInstalledAsset('deslop'),
|
|
@@ -318,6 +340,10 @@ async function deslopContinuation(projectRoot, changedPaths) {
|
|
|
318
340
|
].join('\n');
|
|
319
341
|
}
|
|
320
342
|
|
|
343
|
+
async function finalSummaryContinuation() {
|
|
344
|
+
return (await readInstalledAsset('finalSummary')).trim();
|
|
345
|
+
}
|
|
346
|
+
|
|
321
347
|
export async function completeCodexTurn({ input, projectRoot } = {}) {
|
|
322
348
|
const root = (await gitContext(projectRoot || input?.cwd)).repositoryRoot;
|
|
323
349
|
const statePath = await hookStatePath(root, input);
|
|
@@ -334,14 +360,18 @@ export async function completeCodexTurn({ input, projectRoot } = {}) {
|
|
|
334
360
|
await rm(statePath, { force: true });
|
|
335
361
|
return {};
|
|
336
362
|
}
|
|
363
|
+
const stack = await optionalStack(root);
|
|
364
|
+
const postChange = Boolean(stack?.postChange?.trim());
|
|
337
365
|
await writeTurnState(statePath, {
|
|
338
366
|
...state,
|
|
339
|
-
phase: 'reconcile',
|
|
367
|
+
phase: postChange ? 'post-change' : 'reconcile',
|
|
340
368
|
changedPaths,
|
|
341
369
|
});
|
|
342
370
|
return {
|
|
343
371
|
decision: 'block',
|
|
344
|
-
reason:
|
|
372
|
+
reason: postChange
|
|
373
|
+
? postChangeContinuation(changedPaths, stack)
|
|
374
|
+
: await reconciliationContinuation(root, changedPaths),
|
|
345
375
|
};
|
|
346
376
|
}
|
|
347
377
|
|
|
@@ -350,9 +380,32 @@ export async function completeCodexTurn({ input, projectRoot } = {}) {
|
|
|
350
380
|
return {};
|
|
351
381
|
}
|
|
352
382
|
|
|
383
|
+
if (state.phase === 'post-change') {
|
|
384
|
+
const currentPaths = await changedProjectPaths(root, state.snapshot, await repositorySnapshot(root));
|
|
385
|
+
const changedPaths = normalizedPaths([...state.changedPaths, ...currentPaths]).sort();
|
|
386
|
+
if (changedPaths.length === 0) {
|
|
387
|
+
await rm(statePath, { force: true });
|
|
388
|
+
return {};
|
|
389
|
+
}
|
|
390
|
+
await writeTurnState(statePath, {
|
|
391
|
+
...state,
|
|
392
|
+
phase: 'reconcile',
|
|
393
|
+
changedPaths,
|
|
394
|
+
});
|
|
395
|
+
return {
|
|
396
|
+
decision: 'block',
|
|
397
|
+
reason: await reconciliationContinuation(root, changedPaths),
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
|
|
353
401
|
if (state.phase === 'reconcile') {
|
|
354
402
|
const currentPaths = await changedProjectPaths(root, state.snapshot, await repositorySnapshot(root));
|
|
355
|
-
const changedPaths =
|
|
403
|
+
const changedPaths = normalizedPaths([...state.changedPaths, ...currentPaths]).sort();
|
|
404
|
+
if (changedPaths.length === 0) {
|
|
405
|
+
await refreshProjectIndex(root);
|
|
406
|
+
await rm(statePath, { force: true });
|
|
407
|
+
return {};
|
|
408
|
+
}
|
|
356
409
|
await refreshProjectIndex(root);
|
|
357
410
|
await writeTurnState(statePath, {
|
|
358
411
|
...state,
|
|
@@ -365,7 +418,18 @@ export async function completeCodexTurn({ input, projectRoot } = {}) {
|
|
|
365
418
|
};
|
|
366
419
|
}
|
|
367
420
|
|
|
368
|
-
|
|
421
|
+
if (state.phase === 'deslop') {
|
|
422
|
+
await refreshProjectIndex(root);
|
|
423
|
+
await writeTurnState(statePath, {
|
|
424
|
+
...state,
|
|
425
|
+
phase: 'summary',
|
|
426
|
+
});
|
|
427
|
+
return {
|
|
428
|
+
decision: 'block',
|
|
429
|
+
reason: await finalSummaryContinuation(),
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
|
|
369
433
|
await rm(statePath, { force: true });
|
|
370
434
|
return {};
|
|
371
435
|
}
|
package/src/index/prompt.js
CHANGED
|
@@ -4,6 +4,7 @@ import { buildProjectIndex, MACHINE_CITY_PATH, PROGRAM_CITY_PATH } from './code-
|
|
|
4
4
|
import { BLUEPRINT_SKELETON_SOURCE, readBlueprint } from './blueprint.js';
|
|
5
5
|
import { readStack, stackPromptContext } from './stack.js';
|
|
6
6
|
import { listStackCatalogPieces } from './stack-catalog.js';
|
|
7
|
+
import { normalizeStackPieceId } from './stack-piece.js';
|
|
7
8
|
import { GenesisError } from './errors.js';
|
|
8
9
|
import { gitContext } from './git.js';
|
|
9
10
|
import { inspectProgram } from './program.js';
|
|
@@ -25,13 +26,16 @@ const DEFAULT_REQUEST = {
|
|
|
25
26
|
review: 'Review the complete useful relationship between Blueprint, code, Program, and tests.',
|
|
26
27
|
};
|
|
27
28
|
|
|
28
|
-
function stackCatalogContext(pieces = []) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
requires,
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
function stackCatalogContext(pieces = [], hiddenStackPieces = []) {
|
|
30
|
+
const hidden = new Set(hiddenStackPieces.map(normalizeStackPieceId));
|
|
31
|
+
return pieces
|
|
32
|
+
.filter(({ id }) => !hidden.has(id))
|
|
33
|
+
.map(({ id, description, requires, conflicts }) => ({
|
|
34
|
+
id,
|
|
35
|
+
description,
|
|
36
|
+
requires,
|
|
37
|
+
conflicts,
|
|
38
|
+
}));
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
function requestText(value, task) {
|
|
@@ -205,7 +209,14 @@ async function generateExplanationPrompt({ instructions, program, request, root,
|
|
|
205
209
|
};
|
|
206
210
|
}
|
|
207
211
|
|
|
208
|
-
async function generateStartPrompt({
|
|
212
|
+
async function generateStartPrompt({
|
|
213
|
+
hiddenStackPieces,
|
|
214
|
+
instructions,
|
|
215
|
+
program,
|
|
216
|
+
request,
|
|
217
|
+
root,
|
|
218
|
+
stackPackages,
|
|
219
|
+
}) {
|
|
209
220
|
let blueprint;
|
|
210
221
|
try {
|
|
211
222
|
blueprint = await readBlueprint(root, { required: true });
|
|
@@ -255,7 +266,7 @@ async function generateStartPrompt({ instructions, program, request, root, stack
|
|
|
255
266
|
description: blueprint.description,
|
|
256
267
|
},
|
|
257
268
|
stack: stackPromptContext(stack),
|
|
258
|
-
availableStackPieces: stackCatalogContext(catalog),
|
|
269
|
+
availableStackPieces: stackCatalogContext(catalog, hiddenStackPieces),
|
|
259
270
|
program: programContext(program),
|
|
260
271
|
codeIndex: codeIndexContext(index),
|
|
261
272
|
},
|
|
@@ -273,6 +284,7 @@ async function generateStartPrompt({ instructions, program, request, root, stack
|
|
|
273
284
|
|
|
274
285
|
export async function generateProjectPrompt({
|
|
275
286
|
environment = process.env,
|
|
287
|
+
hiddenStackPieces = [],
|
|
276
288
|
projectRoot,
|
|
277
289
|
request = '',
|
|
278
290
|
stackPackages = [],
|
|
@@ -314,6 +326,7 @@ export async function generateProjectPrompt({
|
|
|
314
326
|
if (task === 'start') {
|
|
315
327
|
return generateStartPrompt({
|
|
316
328
|
instructions,
|
|
329
|
+
hiddenStackPieces,
|
|
317
330
|
program,
|
|
318
331
|
request: userRequest,
|
|
319
332
|
root,
|
|
@@ -338,6 +351,7 @@ export async function generateProjectPrompt({
|
|
|
338
351
|
if (error?.code !== 'STACK_REQUIRED') throw error;
|
|
339
352
|
return generateStartPrompt({
|
|
340
353
|
instructions: await readInstalledAsset('start'),
|
|
354
|
+
hiddenStackPieces,
|
|
341
355
|
program,
|
|
342
356
|
request: userRequest,
|
|
343
357
|
root,
|
|
@@ -347,6 +361,7 @@ export async function generateProjectPrompt({
|
|
|
347
361
|
if (stack.components.length === 0) {
|
|
348
362
|
return generateStartPrompt({
|
|
349
363
|
instructions: await readInstalledAsset('start'),
|
|
364
|
+
hiddenStackPieces,
|
|
350
365
|
program,
|
|
351
366
|
request: userRequest,
|
|
352
367
|
root,
|
package/src/index/stack-piece.js
CHANGED
|
@@ -8,7 +8,13 @@ import { normalizeSource } from './utils.js';
|
|
|
8
8
|
|
|
9
9
|
const STACK_PIECE_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
10
10
|
const STACK_CUSTOMIZATION_TITLE = /^# Stack customization: ([a-z0-9]+(?:-[a-z0-9]+)*)\s*$/u;
|
|
11
|
-
const STACK_CUSTOMIZATION_FIELDS = new
|
|
11
|
+
const STACK_CUSTOMIZATION_FIELDS = new Map([
|
|
12
|
+
['Description', 'description'],
|
|
13
|
+
['Guidance', 'guidance'],
|
|
14
|
+
['Adoption', 'adoption'],
|
|
15
|
+
['Post-change', 'postChange'],
|
|
16
|
+
['Deslop', 'deslop'],
|
|
17
|
+
]);
|
|
12
18
|
const STACK_PIECE_SECTIONS = new Set([
|
|
13
19
|
'Adoption',
|
|
14
20
|
'City regions',
|
|
@@ -19,6 +25,7 @@ const STACK_PIECE_SECTIONS = new Set([
|
|
|
19
25
|
'Environment files',
|
|
20
26
|
'Guidance',
|
|
21
27
|
'Indexers',
|
|
28
|
+
'Post-change',
|
|
22
29
|
'Requires',
|
|
23
30
|
'Resources',
|
|
24
31
|
'Skill',
|
|
@@ -73,7 +80,7 @@ function customizationSections(source, piecePath) {
|
|
|
73
80
|
if (!field) return;
|
|
74
81
|
const value = content.join('\n').trim();
|
|
75
82
|
if (!value) invalid(piecePath, `Stack customization ${mode} ${field} must not be empty.`);
|
|
76
|
-
result[mode.toLowerCase()][
|
|
83
|
+
result[mode.toLowerCase()][STACK_CUSTOMIZATION_FIELDS.get(field)] = value;
|
|
77
84
|
field = null;
|
|
78
85
|
content = [];
|
|
79
86
|
}
|
|
@@ -96,7 +103,7 @@ function customizationSections(source, piecePath) {
|
|
|
96
103
|
if (!mode || !STACK_CUSTOMIZATION_FIELDS.has(fieldHeading[1])) {
|
|
97
104
|
invalid(piecePath, `Unknown or misplaced customization field: ${fieldHeading[1]}.`);
|
|
98
105
|
}
|
|
99
|
-
const key = fieldHeading[1]
|
|
106
|
+
const key = STACK_CUSTOMIZATION_FIELDS.get(fieldHeading[1]);
|
|
100
107
|
if (Object.hasOwn(result[mode.toLowerCase()], key)) {
|
|
101
108
|
invalid(piecePath, `Duplicate ${mode} ${fieldHeading[1]} customization.`);
|
|
102
109
|
}
|
|
@@ -106,12 +113,12 @@ function customizationSections(source, piecePath) {
|
|
|
106
113
|
if (/^#{1,3}\s+/u.test(line)) invalid(piecePath, `Unknown customization heading: ${line.trim()}.`);
|
|
107
114
|
if (field) content.push(line);
|
|
108
115
|
else if (line.trim()) {
|
|
109
|
-
invalid(piecePath, 'Customization content must be below Description, Guidance, Adoption, or Deslop.');
|
|
116
|
+
invalid(piecePath, 'Customization content must be below Description, Guidance, Adoption, Post-change, or Deslop.');
|
|
110
117
|
}
|
|
111
118
|
}
|
|
112
119
|
finishField();
|
|
113
120
|
if (Object.values(result).every((values) => Object.keys(values).length === 0)) {
|
|
114
|
-
invalid(piecePath, 'Stack customization must add or override Description, Guidance, Adoption, or Deslop.');
|
|
121
|
+
invalid(piecePath, 'Stack customization must add or override Description, Guidance, Adoption, Post-change, or Deslop.');
|
|
115
122
|
}
|
|
116
123
|
return result;
|
|
117
124
|
}
|
|
@@ -243,6 +250,7 @@ export function parseStackPieceSource(value, {
|
|
|
243
250
|
const description = textSection(all, 'Description');
|
|
244
251
|
const guidance = textSection(all, 'Guidance');
|
|
245
252
|
const adoption = textSection(all, 'Adoption');
|
|
253
|
+
const postChange = textSection(all, 'Post-change');
|
|
246
254
|
const deslop = textSection(all, 'Deslop');
|
|
247
255
|
if (!description) invalid(piecePath, 'Stack piece needs Description.');
|
|
248
256
|
const verificationCommands = parseStackVerificationLines(
|
|
@@ -266,6 +274,7 @@ export function parseStackPieceSource(value, {
|
|
|
266
274
|
description,
|
|
267
275
|
guidance,
|
|
268
276
|
adoption,
|
|
277
|
+
postChange,
|
|
269
278
|
requires: idList(all, 'Requires', piecePath, { required: true }),
|
|
270
279
|
conflicts: idList(all, 'Conflicts', piecePath),
|
|
271
280
|
indexers: idList(all, 'Indexers', piecePath),
|
|
@@ -320,6 +329,11 @@ export function applyStackPieceCustomization(piece, customization) {
|
|
|
320
329
|
customization.override.adoption,
|
|
321
330
|
customization.add.adoption,
|
|
322
331
|
),
|
|
332
|
+
postChange: customizedText(
|
|
333
|
+
piece.postChange,
|
|
334
|
+
customization.override.postChange,
|
|
335
|
+
customization.add.postChange,
|
|
336
|
+
),
|
|
323
337
|
deslop: customizedText(piece.deslop, customization.override.deslop, customization.add.deslop),
|
|
324
338
|
};
|
|
325
339
|
}
|
package/src/index/stack.js
CHANGED
|
@@ -362,6 +362,7 @@ export async function readStack(projectRoot, { stackPackages = [] } = {}) {
|
|
|
362
362
|
resources,
|
|
363
363
|
guidance: composedProse(components, 'guidance'),
|
|
364
364
|
adoption: composedProse(components, 'adoption'),
|
|
365
|
+
postChange: composedProse(components, 'postChange'),
|
|
365
366
|
deslop: composedProse(components, 'deslop'),
|
|
366
367
|
};
|
|
367
368
|
}
|