genesis-compiler 1.2.26 → 1.2.28
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 +326 -55
- package/docs/prompt-integration.md +35 -15
- package/docs/stack-components.md +65 -23
- package/package.json +1 -1
- package/plugins/genesis/.codex-plugin/plugin.json +1 -1
- package/plugins/opencode/project-guidance.js +1 -2
- package/prompts/adopt.txt +5 -4
- package/prompts/deslop.txt +3 -1
- package/prompts/start.txt +48 -18
- package/prompts/work.txt +11 -3
- package/skills/genesis-deslop/SKILL.md +17 -0
- package/skills/genesis-project/SKILL.md +48 -9
- package/src/cli.js +19 -2
- package/src/index/codex-hooks.js +3 -1
- package/src/index/context.js +20 -0
- package/src/index/migration.js +12 -3
- package/src/index/project-format.js +1 -1
- package/src/index/session-context.js +18 -0
- package/src/index/stack-catalog.js +11 -0
- package/src/index/stack-project-contracts.js +205 -0
- package/src/index/stack-section.js +2 -2
- package/src/index/stack.js +91 -57
package/docs/stack-components.md
CHANGED
|
@@ -46,7 +46,26 @@ Concise technology context.
|
|
|
46
46
|
|
|
47
47
|
## Resources
|
|
48
48
|
|
|
49
|
-
-
|
|
49
|
+
```json genesis-resource
|
|
50
|
+
{
|
|
51
|
+
"id": "database",
|
|
52
|
+
"kind": "postgresql",
|
|
53
|
+
"environmentAlternatives": [
|
|
54
|
+
{
|
|
55
|
+
"bindings": {
|
|
56
|
+
"database": "DB_NAME",
|
|
57
|
+
"host": "DB_HOST",
|
|
58
|
+
"password": "DB_PASSWORD",
|
|
59
|
+
"port": "DB_PORT",
|
|
60
|
+
"username": "DB_USER"
|
|
61
|
+
},
|
|
62
|
+
"allowEmpty": ["password"],
|
|
63
|
+
"preferred": true
|
|
64
|
+
},
|
|
65
|
+
{ "bindings": { "url": "DATABASE_URL" } }
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
```
|
|
50
69
|
|
|
51
70
|
## Environment defaults
|
|
52
71
|
|
|
@@ -92,24 +111,27 @@ complete authoritative Agent Skill directory. `Indexers` selects installed
|
|
|
92
111
|
structural adapters.
|
|
93
112
|
`Resources`, `Environment defaults`, `Environment files`, and `Verification`
|
|
94
113
|
use the small Genesis grammars documented below. Every other `##` section is an
|
|
95
|
-
opaque extension.
|
|
114
|
+
opaque extension. These component sections are initial proposals. They do not
|
|
115
|
+
remain a hidden runtime layer beneath the project.
|
|
96
116
|
|
|
97
117
|
## Genesis-owned declarations
|
|
98
118
|
|
|
99
119
|
Resources describe required external inputs as alternatives of environment
|
|
100
120
|
variable names. Genesis can report which names are absent, but never reads a
|
|
101
|
-
service, provisions infrastructure, or returns a supplied value.
|
|
102
|
-
|
|
121
|
+
service, provisions infrastructure, or returns a supplied value. Selection
|
|
122
|
+
materializes the composed proposal into the project's `## Resources` section.
|
|
103
123
|
|
|
104
|
-
Environment defaults are public, non-secret constants. Component
|
|
124
|
+
Environment defaults are public, non-secret constants. Component proposals
|
|
105
125
|
compose by variable name; identical values collapse and conflicting values
|
|
106
|
-
fail.
|
|
107
|
-
Explicit process values always win.
|
|
126
|
+
fail. Selection writes the result into the project's `## Environment defaults`
|
|
127
|
+
section. Explicit process values always win. Conventional host, port, driver,
|
|
128
|
+
database, or username values may be proposed; passwords, tokens, and other
|
|
129
|
+
secrets must not be invented.
|
|
108
130
|
|
|
109
131
|
Environment files describe safe project-relative dotenv projection paths.
|
|
110
132
|
Genesis returns only the format and path. It does not materialize the file,
|
|
111
|
-
choose which values belong there, or store secrets.
|
|
112
|
-
|
|
133
|
+
choose which values belong there, or store secrets. Component paths compose
|
|
134
|
+
during selection and are then written as the project declaration.
|
|
113
135
|
|
|
114
136
|
Verification contains exact argv tokens:
|
|
115
137
|
|
|
@@ -122,8 +144,9 @@ Verification contains exact argv tokens:
|
|
|
122
144
|
|
|
123
145
|
Genesis is the consumer of this section. `genesis verify` runs the declared
|
|
124
146
|
commands directly without a shell after generic resource preflight and records
|
|
125
|
-
the exact successful code, Stack, and command hashes.
|
|
126
|
-
section
|
|
147
|
+
the exact successful code, Stack, and command hashes. Selection writes proposed
|
|
148
|
+
commands into the project Verification section; only that project section is
|
|
149
|
+
executed afterward.
|
|
127
150
|
|
|
128
151
|
## Opaque extensions
|
|
129
152
|
|
|
@@ -131,12 +154,16 @@ Any other `##` heading is consumer-owned data. Genesis validates only the
|
|
|
131
154
|
section name and composition. It does not parse the body, infer its purpose,
|
|
132
155
|
validate a private schema, map runtimes, execute commands, or prove success.
|
|
133
156
|
|
|
134
|
-
|
|
157
|
+
Proposal composition is intentionally small:
|
|
158
|
+
|
|
159
|
+
1. An existing project section remains authoritative and is never overwritten.
|
|
160
|
+
2. Without a project section, one component proposal is copied unchanged.
|
|
161
|
+
3. Competing component proposals produce `STACK_SECTION_AMBIGUOUS`; Genesis
|
|
162
|
+
never merges their bodies or guesses a winner.
|
|
135
163
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
never merges their bodies.
|
|
164
|
+
After selection every effective opaque section is project-owned. The component
|
|
165
|
+
catalog may improve later without silently changing the application's setup,
|
|
166
|
+
launch, deployment, packaging, signing, migration, or any other operation.
|
|
140
167
|
|
|
141
168
|
Call `inspectStackSection({ name, projectRoot })` or:
|
|
142
169
|
|
|
@@ -152,12 +179,18 @@ firmware, desktop software, and future systems Genesis has never seen.
|
|
|
152
179
|
|
|
153
180
|
## Selection and identity
|
|
154
181
|
|
|
155
|
-
`genesis stack add` records selected packages and component dependency closure
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
182
|
+
`genesis stack add` records selected packages and component dependency closure,
|
|
183
|
+
materializes every missing operation proposal, and preserves existing project
|
|
184
|
+
declarations. It then returns one preparation prompt containing every exact
|
|
185
|
+
project contract heading and body. The current agent must make the source and
|
|
186
|
+
commands satisfy those contracts or replace a complete section with evidenced
|
|
187
|
+
reality. Repeating an already-complete selection is quiet.
|
|
188
|
+
|
|
189
|
+
Stack identity includes component ids, project-owned resources, environment
|
|
190
|
+
declarations, Verification commands, City presentation, and every opaque
|
|
191
|
+
extension body. Changing any executable or consumer-owned contract therefore
|
|
192
|
+
stales prior Genesis verification evidence even though Genesis does not
|
|
193
|
+
interpret the extension.
|
|
161
194
|
|
|
162
195
|
Prose and Agent Skill contents are instructions rather than verification
|
|
163
196
|
evidence. Changes to Description, Guidance, Adoption, Post-change, Deslop, or
|
|
@@ -212,7 +245,16 @@ const operation = await inspectStackSection({
|
|
|
212
245
|
});
|
|
213
246
|
```
|
|
214
247
|
|
|
215
|
-
`inspectEnvironment()` uses `genesis.environment.
|
|
248
|
+
`inspectEnvironment()` uses `genesis.environment.v2` and never returns supplied
|
|
216
249
|
values. `inspectStackSection()` uses `genesis.stack-section.v1` and never
|
|
217
250
|
interprets the section. There is no generic Genesis API that executes an opaque
|
|
218
251
|
operation.
|
|
252
|
+
|
|
253
|
+
## Project format migration
|
|
254
|
+
|
|
255
|
+
Project format 2 removes runtime inheritance of operation declarations from
|
|
256
|
+
the catalog. `genesis migrate` upgrades format 1 projects by composing the
|
|
257
|
+
previously effective declarations once and writing them into
|
|
258
|
+
`genesis/stack.md`. Existing project sections win exactly as they did before.
|
|
259
|
+
Current-format reads reject a selected component whose required contract was
|
|
260
|
+
not materialized, so a tool upgrade cannot quietly substitute a new proposal.
|
package/package.json
CHANGED
|
@@ -50,8 +50,7 @@ export const GenesisProjectGuidance = async ({ directory, worktree } = {}) => {
|
|
|
50
50
|
const sessionId = String(input.sessionID || input.sessionId || "").trim();
|
|
51
51
|
if (!sessionId) return;
|
|
52
52
|
const context = await contextForSession(sessionId);
|
|
53
|
-
|
|
54
|
-
if (!system.includes(context)) output.system = [...system, context];
|
|
53
|
+
if (!output.system.includes(context)) output.system.push(context);
|
|
55
54
|
}
|
|
56
55
|
};
|
|
57
56
|
};
|
package/prompts/adopt.txt
CHANGED
|
@@ -26,8 +26,9 @@ Adoption requirements.
|
|
|
26
26
|
|
|
27
27
|
Read every selected technology skill named by the regenerated prompt and its
|
|
28
28
|
relevant existing-application migration reference. Apply all SELECTED STACK
|
|
29
|
-
ADOPTION GUIDANCE.
|
|
30
|
-
hypotheses until they match this source. They do not
|
|
29
|
+
ADOPTION GUIDANCE. Materialized component proposals describe current
|
|
30
|
+
foundations and remain hypotheses until they match this source. They do not
|
|
31
|
+
upgrade an older project.
|
|
31
32
|
|
|
32
33
|
Build one evidence-backed import inventory covering the selected technologies,
|
|
33
34
|
public environment/resource declarations, concrete Verification commands, and
|
|
@@ -36,8 +37,8 @@ selected technology skill and the section's declared schema for any
|
|
|
36
37
|
consumer-specific detail; do not invent a generic operational grammar.
|
|
37
38
|
|
|
38
39
|
Translate observed contracts into exact project-owned Stack sections whenever
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
a materialized proposal differs. Replace the complete section for that concern;
|
|
41
|
+
do not leave a proposal that the implementation cannot perform. Inspect retired
|
|
41
42
|
or tool-specific manifests as evidence and carry every still-valid fact into
|
|
42
43
|
Genesis; never add a permanent legacy reader or shim. Do not delete an old
|
|
43
44
|
manifest until all of its live facts have been accounted for.
|
package/prompts/deslop.txt
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
This Deslop task has already been rendered by Genesis. Do not generate another
|
|
2
|
+
Deslop prompt. Read and follow `.agents/skills/genesis-deslop/SKILL.md`
|
|
3
|
+
completely.
|
|
2
4
|
|
|
3
5
|
This is an explicitly requested behavior-preserving cleanup of committed work.
|
|
4
6
|
Resolve the commit or first-parent commit range from USER REQUEST exactly; when
|
package/prompts/start.txt
CHANGED
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
Read and follow `.agents/skills/genesis-project/SKILL.md` completely.
|
|
2
2
|
|
|
3
|
-
This is the project-opening conversation.
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
This is the project-opening conversation. For a new project, do not begin
|
|
4
|
+
technology research or create source until the user has made clear what is
|
|
5
|
+
being built, who or what will use or invoke it, and the first observable useful
|
|
6
|
+
outcome. Ask only unresolved high-impact questions. A reply confirms only what
|
|
7
|
+
it explicitly answers; Stack confirmation is not product intent.
|
|
6
8
|
|
|
7
|
-
When
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
When the user explicitly names a technology, framework, language, or database
|
|
10
|
+
that is not selected, make the existing Genesis `stack list` operation the
|
|
11
|
+
first technology action. If one catalog component exactly matches that choice,
|
|
12
|
+
ask: "<Technology> is available in Genesis. Would you like me to add it to this
|
|
13
|
+
project and prepare the app with its official guidance?" Do not run `stack add
|
|
14
|
+
<piece...>` without that confirmation. If confirmed, add it, let Genesis apply
|
|
15
|
+
its declared dependency closure and synchronize any skill the component
|
|
16
|
+
declares. Follow the preparation prompt returned by `stack add` in this same
|
|
17
|
+
task: make each materialized project contract true or replace a complete
|
|
18
|
+
section with evidenced reality. Then run `context .` (or the relevant source
|
|
19
|
+
path once source exists), load the applicable installed skill if present, and
|
|
20
|
+
follow the technology-owned guidance to prepare actual project dependencies.
|
|
21
|
+
Never infer an install command from a component id. If declined, continue
|
|
22
|
+
without adding it or asking again.
|
|
23
|
+
If no component matches, do not invent one; continue normally using
|
|
24
|
+
authoritative technology documentation.
|
|
25
|
+
|
|
26
|
+
When `projectKind` is `new`, establish what is being built, who or what will use
|
|
27
|
+
or invoke it, and its first observable useful outcome. Ask up to three concise,
|
|
28
|
+
high-impact questions at a time, and ask access, data, platform, or interface
|
|
29
|
+
questions only when they are material to that product. Use
|
|
30
|
+
`availableStackPieces` to present only the relevant choices, explain them in
|
|
31
|
+
product language, and let the user decide. Never silently select a technology.
|
|
32
|
+
After the user confirms the proposed component selection, use the Genesis
|
|
33
|
+
`stack add <piece...>` operation; do not edit `genesis/stack.md` by hand.
|
|
34
|
+
Establish the non-technical Blueprint from the user's answers before
|
|
13
35
|
implementation.
|
|
14
36
|
If the product direction becomes clear while Stack is still empty, do not end
|
|
15
37
|
the turn after only writing or summarizing the Blueprint: present the relevant
|
|
@@ -35,13 +57,13 @@ If the existing implementation is not yet explained, recommend the Genesis
|
|
|
35
57
|
description/adoption path instead of pretending its intent is known.
|
|
36
58
|
When an existing implementation has no selected Stack yet, inspect its actual
|
|
37
59
|
package scripts, build files, setup commands, server entrypoint, and readiness
|
|
38
|
-
route before recording the user's technology choice.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
60
|
+
route before recording the user's technology choice. Materialized component
|
|
61
|
+
proposals describe that component's current operational foundation; selecting
|
|
62
|
+
the component does not port an older implementation to it. If the existing
|
|
63
|
+
facts differ, replace the complete project-owned section using the consumer's
|
|
64
|
+
current schema and the code that exists. Never report a proposed operation as
|
|
65
|
+
usable merely because the component was selected, and never add compatibility
|
|
66
|
+
implementation without the user asking for a port.
|
|
45
67
|
|
|
46
68
|
When `projectKind` is `existing-uninitialized`, ask what the user wants to
|
|
47
69
|
understand or change and strongly recommend preparing the existing project for
|
|
@@ -53,5 +75,13 @@ operation yourself and follow its adoption prompt. If they decline, continue
|
|
|
53
75
|
normally and do not repeat the recommendation.
|
|
54
76
|
|
|
55
77
|
If the request already contains an unambiguous product description and an
|
|
56
|
-
explicit Stack choice,
|
|
57
|
-
|
|
78
|
+
explicit Stack choice, establish the Blueprint and ask for the component
|
|
79
|
+
confirmation described above before applying that choice. Otherwise this is a
|
|
80
|
+
conversational turn: ask, listen, and preserve the source.
|
|
81
|
+
|
|
82
|
+
Once product direction and any relevant Stack selection are clear, choose one
|
|
83
|
+
smallest implementation path through the applicable technology guidance, or
|
|
84
|
+
authoritative technology documentation when the catalog has no match, and read
|
|
85
|
+
only what that path requires. Do not survey alternative foundations, clone
|
|
86
|
+
whole technology repositories, inspect unrelated package internals, or
|
|
87
|
+
delegate research unless one concrete failure requires one exact investigation.
|
package/prompts/work.txt
CHANGED
|
@@ -3,7 +3,12 @@ implement the request in the ordinary local Git tree.
|
|
|
3
3
|
|
|
4
4
|
Load the applicable official or project technology skills listed below. Use
|
|
5
5
|
their normal generators, commands, packages, and established seams. Do not
|
|
6
|
-
|
|
6
|
+
turn technology choices into another product questionnaire. Choose one smallest
|
|
7
|
+
implementation path through selected guidance, or authoritative technology
|
|
8
|
+
documentation when the catalog has no match, and read only what that path
|
|
9
|
+
requires. Do not survey alternative foundations, clone whole technology
|
|
10
|
+
repositories, inspect unrelated package internals, or delegate research unless
|
|
11
|
+
one concrete failure requires one exact investigation.
|
|
7
12
|
Before adding a helper or public operation, query the Genesis
|
|
8
13
|
`index <name-or-path>` operation and reuse an existing function when it already
|
|
9
14
|
owns the behavior.
|
|
@@ -20,8 +25,11 @@ a genuinely missing resource instead of constructing a parallel fallback.
|
|
|
20
25
|
|
|
21
26
|
Apply any supplied Stack Post-change guidance before reporting completion. It
|
|
22
27
|
belongs to this implementation turn and does not request a follow-up agent turn.
|
|
23
|
-
Run focused checks when useful.
|
|
24
|
-
and
|
|
28
|
+
Run focused checks when useful. Before reporting completion, compare the
|
|
29
|
+
requested observable behavior, required inputs and resources, declared project
|
|
30
|
+
operations, and focused evidence with what actually exists. Summarize
|
|
31
|
+
files changed, checks actually run, anything not proven, and anything still
|
|
32
|
+
requiring attention.
|
|
25
33
|
|
|
26
34
|
If no Stack components are selected, continue the project-opening
|
|
27
35
|
conversation instead of guessing a technology. Use the Genesis `stack list`
|
|
@@ -15,6 +15,23 @@ package. Otherwise use `genesis <arguments>` only when that executable is
|
|
|
15
15
|
already available on `PATH`. Never install or update Genesis merely to satisfy
|
|
16
16
|
a workflow instruction.
|
|
17
17
|
|
|
18
|
+
## Load the effective project instructions once
|
|
19
|
+
|
|
20
|
+
A Deslop request may arrive either as a complete Genesis-generated prompt or
|
|
21
|
+
as a direct request such as `Deslop` in an agent session.
|
|
22
|
+
|
|
23
|
+
If the current task already contains `GENESIS CONTEXT` whose task is `deslop`,
|
|
24
|
+
continue with it directly. Do not generate another prompt.
|
|
25
|
+
|
|
26
|
+
Otherwise, before resolving Git scope, run the Genesis
|
|
27
|
+
`prompt --task deslop` operation once using the invocation rule above. For a
|
|
28
|
+
bare `Deslop` request, pass no request argument. When the user names a count,
|
|
29
|
+
commit, or range, pass that exact request as one safely quoted argument. Treat
|
|
30
|
+
the printed prompt as the instructions for this same turn; do not dispatch it
|
|
31
|
+
to another agent and do not generate it again. This step composes the selected
|
|
32
|
+
Stack's technology-specific Deslop guidance and any project customization with
|
|
33
|
+
the portable contract below.
|
|
34
|
+
|
|
18
35
|
## Resolve the committed scope
|
|
19
36
|
|
|
20
37
|
Before reading or editing the selected change, require a clean worktree and
|
|
@@ -8,6 +8,21 @@ description: Work safely in a Genesis-enriched codebase using its Blueprint, Sta
|
|
|
8
8
|
Genesis is an explanatory and verification companion. It does not replace the
|
|
9
9
|
codebase, tests, Git review, or the coding agent.
|
|
10
10
|
|
|
11
|
+
## Establish new-product direction
|
|
12
|
+
|
|
13
|
+
For a new project whose Blueprint does not yet establish product direction,
|
|
14
|
+
do not research technology or create source until the user has made clear what
|
|
15
|
+
is being built, who or what will use or invoke it, and the first observable
|
|
16
|
+
useful outcome. Ask only unresolved high-impact questions. A reply confirms only
|
|
17
|
+
what it explicitly answers; Stack confirmation is not product intent.
|
|
18
|
+
|
|
19
|
+
Once product direction is clear, choose one smallest implementation path
|
|
20
|
+
through selected technology guidance, or authoritative technology documentation
|
|
21
|
+
when the catalog has no match, and read only what that path requires. Do not
|
|
22
|
+
survey alternatives, clone whole technology repositories, inspect unrelated
|
|
23
|
+
package internals, or delegate research unless one concrete failure requires
|
|
24
|
+
one exact investigation.
|
|
25
|
+
|
|
11
26
|
## Run Genesis commands
|
|
12
27
|
|
|
13
28
|
When this repository is Genesis itself or has `genesis-compiler` installed
|
|
@@ -17,6 +32,28 @@ package. Otherwise use `genesis <arguments>` only when that executable is
|
|
|
17
32
|
already available on `PATH`. Never install or update Genesis merely to satisfy
|
|
18
33
|
a workflow instruction.
|
|
19
34
|
|
|
35
|
+
## Resolve explicit technology choices
|
|
36
|
+
|
|
37
|
+
Before external technology research or implementation, when the user explicitly
|
|
38
|
+
names a technology, framework, language, or database that is not selected:
|
|
39
|
+
|
|
40
|
+
1. Run the Genesis `stack list` operation as the first technology action.
|
|
41
|
+
2. If one catalog component exactly matches the choice, ask: "<Technology> is
|
|
42
|
+
available in Genesis. Would you like me to add it to this project and prepare
|
|
43
|
+
the app with its official guidance?" Do not run `stack add <piece...>`
|
|
44
|
+
without that confirmation.
|
|
45
|
+
3. If confirmed, add the component, let Genesis apply its declared dependency
|
|
46
|
+
closure and synchronize any authoritative Agent Skill declared by that
|
|
47
|
+
component. Follow the preparation prompt returned by `stack add` in the same
|
|
48
|
+
task: make each materialized project contract true or replace a complete
|
|
49
|
+
section with evidenced reality. Then run `context .`, or the relevant source
|
|
50
|
+
path once source exists, load the applicable installed skill if present, and
|
|
51
|
+
follow that technology-owned guidance to prepare actual project
|
|
52
|
+
dependencies. Never infer an installation command from a component id.
|
|
53
|
+
4. If declined, continue without adding the component or asking again. If no
|
|
54
|
+
catalog component matches, do not invent one; continue normally using
|
|
55
|
+
authoritative documentation owned by that technology.
|
|
56
|
+
|
|
20
57
|
## Establish context
|
|
21
58
|
|
|
22
59
|
1. Read `genesis/blueprint.md` for non-technical product intent.
|
|
@@ -34,13 +71,13 @@ a workflow instruction.
|
|
|
34
71
|
agent's own installed skill catalog.
|
|
35
72
|
|
|
36
73
|
For an existing application's first Stack selection, inspect its real setup,
|
|
37
|
-
build, and output commands before
|
|
38
|
-
component describes its current foundation; it does not silently
|
|
39
|
-
source. When the existing commands differ, keep the implementation
|
|
40
|
-
and
|
|
41
|
-
`## Workspace setup`
|
|
74
|
+
build, and output commands before accepting materialized component proposals.
|
|
75
|
+
A selected component describes its current foundation; it does not silently
|
|
76
|
+
port older source. When the existing commands differ, keep the implementation
|
|
77
|
+
unchanged and replace the complete project-owned consumer operation (for
|
|
78
|
+
Vibe64, `## Workspace setup` or `## Outputs`). Genesis treats those sections as
|
|
42
79
|
opaque text; the named consumer alone owns their meaning and execution. Do not
|
|
43
|
-
claim
|
|
80
|
+
claim a proposed recipe is usable until it matches the source.
|
|
44
81
|
|
|
45
82
|
Program is concise, fallible explanation. Its Sources and optional
|
|
46
83
|
Implementation maps aid navigation but never substitute for reading code,
|
|
@@ -90,6 +127,8 @@ Neither is authority or proof; both may be regenerated with the Genesis
|
|
|
90
127
|
After the selected technology's workspace substrate exists, use the Genesis
|
|
91
128
|
`verify` operation for the Stack's declared final checks. An unconfigured result
|
|
92
129
|
means the declared workspace or checks do not exist yet; it is not a failing
|
|
93
|
-
check.
|
|
94
|
-
|
|
95
|
-
|
|
130
|
+
check. Before reporting completion, compare the requested observable behavior,
|
|
131
|
+
required inputs and resources, declared project operations, and focused evidence
|
|
132
|
+
with what actually exists. Report files changed, checks actually run,
|
|
133
|
+
anything not proven, and anything still requiring attention. Never claim that
|
|
134
|
+
an unrun check passed or that passing checks prove the whole product.
|
package/src/cli.js
CHANGED
|
@@ -29,6 +29,8 @@ import {
|
|
|
29
29
|
projectFormatDiagnostic,
|
|
30
30
|
} from './index/project-format.js';
|
|
31
31
|
import { projectSessionContext } from './index/session-context.js';
|
|
32
|
+
import { installedFirstPartyStackPackages } from './index/stack-catalog.js';
|
|
33
|
+
import { readStack } from './index/stack.js';
|
|
32
34
|
|
|
33
35
|
const USAGE = `Usage:
|
|
34
36
|
genesis init
|
|
@@ -283,12 +285,27 @@ function writeResult(command, result) {
|
|
|
283
285
|
}
|
|
284
286
|
}
|
|
285
287
|
if (result.guidance) line(process.stdout, result.guidance);
|
|
288
|
+
if (result.prompt) {
|
|
289
|
+
line(process.stdout, '');
|
|
290
|
+
process.stdout.write(result.prompt.endsWith('\n') ? result.prompt : `${result.prompt}\n`);
|
|
291
|
+
}
|
|
286
292
|
line(process.stdout, `${command}: ${result.status}`);
|
|
287
293
|
}
|
|
288
294
|
|
|
295
|
+
async function cliStackPackages(projectRoot, supplied) {
|
|
296
|
+
if (supplied.length > 0) return supplied;
|
|
297
|
+
try {
|
|
298
|
+
const stack = await readStack(projectRoot);
|
|
299
|
+
if (stack.stackPackages.length > 0) return [];
|
|
300
|
+
} catch (error) {
|
|
301
|
+
if (error?.code !== 'STACK_REQUIRED') return [];
|
|
302
|
+
}
|
|
303
|
+
return installedFirstPartyStackPackages({ projectRoot });
|
|
304
|
+
}
|
|
305
|
+
|
|
289
306
|
async function execute({ command, operands, options }, { signal } = {}) {
|
|
290
307
|
const projectRoot = options.projectRoot || process.cwd();
|
|
291
|
-
const stackPackages = options.stackPackages || [];
|
|
308
|
+
const stackPackages = await cliStackPackages(projectRoot, options.stackPackages || []);
|
|
292
309
|
if (command === 'init') return initialize({ projectRoot, stackPackages });
|
|
293
310
|
if (command === 'migrate') return migrate({ projectRoot, stackPackages });
|
|
294
311
|
if (command === 'adopt') {
|
|
@@ -362,7 +379,7 @@ async function execute({ command, operands, options }, { signal } = {}) {
|
|
|
362
379
|
if (operands[0] === 'discover') {
|
|
363
380
|
return { kind: 'discover', ...await codexAdoptionRecommendation({ projectRoot }) };
|
|
364
381
|
}
|
|
365
|
-
return { kind: 'session', ...await projectSessionContext({ projectRoot }) };
|
|
382
|
+
return { kind: 'session', ...await projectSessionContext({ projectRoot, stackPackages }) };
|
|
366
383
|
}
|
|
367
384
|
if (command === 'verify') {
|
|
368
385
|
return verify({
|
package/src/index/codex-hooks.js
CHANGED
|
@@ -8,6 +8,7 @@ import { runGit } from './process.js';
|
|
|
8
8
|
import { normalizeRelative, pathState, writeFileAtomic } from './utils.js';
|
|
9
9
|
|
|
10
10
|
const HOOKS_PATH = '.codex/hooks.json';
|
|
11
|
+
const LEGACY_GENESIS_HOOKS_DESCRIPTION = 'Genesis project hooks.';
|
|
11
12
|
const PROJECT_HOOK_ACTIONS = ['session', 'begin', 'stop', 'end'];
|
|
12
13
|
|
|
13
14
|
function hookCommand(action) {
|
|
@@ -68,7 +69,7 @@ async function installedHooksSource(location) {
|
|
|
68
69
|
return { source, value };
|
|
69
70
|
} catch (error) {
|
|
70
71
|
if (['ENOENT', 'ENOTDIR'].includes(error?.code)) {
|
|
71
|
-
return { source: null, value: {
|
|
72
|
+
return { source: null, value: { hooks: {} } };
|
|
72
73
|
}
|
|
73
74
|
throw new GenesisError('CODEX_HOOKS_INVALID', `${HOOKS_PATH} is not valid hook configuration: ${error.message}.`);
|
|
74
75
|
}
|
|
@@ -78,6 +79,7 @@ export async function installCodexHooks({ projectRoot } = {}) {
|
|
|
78
79
|
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
79
80
|
const location = path.join(root, HOOKS_PATH);
|
|
80
81
|
const { source, value } = await installedHooksSource(location);
|
|
82
|
+
if (value.description === LEGACY_GENESIS_HOOKS_DESCRIPTION) delete value.description;
|
|
81
83
|
value.hooks ||= {};
|
|
82
84
|
removeGenesisProjectHooks(value.hooks);
|
|
83
85
|
const groups = value.hooks[SESSION_HOOK.event] ||= [];
|
package/src/index/context.js
CHANGED
|
@@ -46,6 +46,25 @@ function stackGuidance(stack) {
|
|
|
46
46
|
];
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
function stackContracts(stack) {
|
|
50
|
+
if (stack.projectContracts.length === 0) return [];
|
|
51
|
+
return [
|
|
52
|
+
'',
|
|
53
|
+
'## Project Stack contracts',
|
|
54
|
+
'',
|
|
55
|
+
'These exact project-owned sections in `genesis/stack.md` are authoritative. Genesis executes only Verification; each other named consumer owns its section.',
|
|
56
|
+
'',
|
|
57
|
+
...stack.projectContracts.flatMap(({ name, lines }) => [
|
|
58
|
+
`### \`## ${name}\``,
|
|
59
|
+
'',
|
|
60
|
+
'```markdown',
|
|
61
|
+
...lines,
|
|
62
|
+
'```',
|
|
63
|
+
'',
|
|
64
|
+
]),
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
|
|
49
68
|
function pathMatchesTarget(filePath, target) {
|
|
50
69
|
return !target || filePath === target || filePath.startsWith(`${target}/`);
|
|
51
70
|
}
|
|
@@ -108,6 +127,7 @@ export async function contextForProjectPaths({ paths, projectRoot, stackPackages
|
|
|
108
127
|
'',
|
|
109
128
|
...stackSummary(stack),
|
|
110
129
|
...stackGuidance(stack),
|
|
130
|
+
...stackContracts(stack),
|
|
111
131
|
'',
|
|
112
132
|
'## Existing functions',
|
|
113
133
|
'',
|
package/src/index/migration.js
CHANGED
|
@@ -11,14 +11,17 @@ import {
|
|
|
11
11
|
writeProjectFormatVersion,
|
|
12
12
|
} from './project-format.js';
|
|
13
13
|
import { PROJECT_VERSION_PATH } from './paths.js';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
materializeProjectStackContracts,
|
|
16
|
+
readLegacyStack,
|
|
17
|
+
} from './stack.js';
|
|
15
18
|
import { uniqueSorted } from './utils.js';
|
|
16
19
|
|
|
17
20
|
async function validateLegacyProject({ projectRoot, stackPackages }) {
|
|
18
21
|
try {
|
|
19
22
|
await readBlueprint(projectRoot, { required: true });
|
|
20
23
|
await readEngineering(projectRoot);
|
|
21
|
-
await
|
|
24
|
+
await readLegacyStack(projectRoot, { stackPackages });
|
|
22
25
|
try {
|
|
23
26
|
await inspectProgram(projectRoot);
|
|
24
27
|
} catch (error) {
|
|
@@ -33,8 +36,13 @@ async function validateLegacyProject({ projectRoot, stackPackages }) {
|
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
|
|
39
|
+
async function materializeProjectContracts({ projectRoot, stackPackages }) {
|
|
40
|
+
return materializeProjectStackContracts({ projectRoot, stackPackages });
|
|
41
|
+
}
|
|
42
|
+
|
|
36
43
|
const MIGRATIONS = new Map([
|
|
37
44
|
[0, validateLegacyProject],
|
|
45
|
+
[1, materializeProjectContracts],
|
|
38
46
|
]);
|
|
39
47
|
|
|
40
48
|
export async function migrateProject({ projectRoot, stackPackages = [] } = {}) {
|
|
@@ -62,7 +70,8 @@ export async function migrateProject({ projectRoot, stackPackages = [] } = {}) {
|
|
|
62
70
|
{ projectVersion: version, supportedVersion: CURRENT_PROJECT_FORMAT_VERSION },
|
|
63
71
|
);
|
|
64
72
|
}
|
|
65
|
-
await migration({ projectRoot: root, stackPackages });
|
|
73
|
+
const result = await migration({ projectRoot: root, stackPackages });
|
|
74
|
+
migratedFiles.push(...(result?.changedFiles || []));
|
|
66
75
|
version += 1;
|
|
67
76
|
await writeProjectFormatVersion(root, version);
|
|
68
77
|
migratedFiles.push(PROJECT_VERSION_PATH);
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from './paths.js';
|
|
13
13
|
import { normalizeSource, pathState, writeFileAtomic } from './utils.js';
|
|
14
14
|
|
|
15
|
-
export const CURRENT_PROJECT_FORMAT_VERSION =
|
|
15
|
+
export const CURRENT_PROJECT_FORMAT_VERSION = 2;
|
|
16
16
|
export const CURRENT_PROJECT_FORMAT_SOURCE = `${CURRENT_PROJECT_FORMAT_VERSION}\n`;
|
|
17
17
|
|
|
18
18
|
const VERSION_PATTERN = /^(0|[1-9][0-9]*)\n?$/u;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readEngineering, readEngineeringBaseline } from './engineering.js';
|
|
2
2
|
import { gitContext } from './git.js';
|
|
3
3
|
import { readStack } from './stack.js';
|
|
4
|
+
import { listStackCatalogPieces } from './stack-catalog.js';
|
|
4
5
|
|
|
5
6
|
async function optionalStack(projectRoot, stackPackages) {
|
|
6
7
|
try { return await readStack(projectRoot, { stackPackages }); } catch { return null; }
|
|
@@ -23,12 +24,23 @@ async function optionalEngineering(projectRoot) {
|
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
async function optionalStackComponentIds(projectRoot, stack, stackPackages) {
|
|
28
|
+
try {
|
|
29
|
+
const packages = [...new Set([...(stack?.stackPackages || []), ...stackPackages])];
|
|
30
|
+
return (await listStackCatalogPieces({ projectRoot, stackPackages: packages }))
|
|
31
|
+
.map(({ id }) => id);
|
|
32
|
+
} catch {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
26
37
|
export async function projectSessionContext({ projectRoot, stackPackages = [] } = {}) {
|
|
27
38
|
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
28
39
|
const [stack, engineering] = await Promise.all([
|
|
29
40
|
optionalStack(root, stackPackages),
|
|
30
41
|
optionalEngineering(root),
|
|
31
42
|
]);
|
|
43
|
+
const availableComponents = await optionalStackComponentIds(root, stack, stackPackages);
|
|
32
44
|
const selected = stack?.components.map(({ id }) => id) || [];
|
|
33
45
|
const stackStatus = stack
|
|
34
46
|
? (selected.length > 0 ? selected.join(', ') : 'none')
|
|
@@ -38,10 +50,16 @@ export async function projectSessionContext({ projectRoot, stackPackages = [] }
|
|
|
38
50
|
output: [
|
|
39
51
|
'This is a Genesis-enriched project.',
|
|
40
52
|
'- Read `genesis/blueprint.md`, `genesis/engineering.md`, and `genesis/stack.md` for product intent, engineering approach, and selected technology.',
|
|
53
|
+
'- For a new project whose Blueprint does not yet establish product direction, do not research technology or create source until the user has made clear what is being built, who or what will use or invoke it, and the first observable useful outcome. Ask only unresolved high-impact questions. A reply confirms only what it explicitly answers; Stack confirmation is not product intent.',
|
|
54
|
+
'- Once product direction is clear, choose one smallest implementation path through selected technology guidance, or authoritative technology documentation when the catalog has no match, and read only what that path requires. Do not survey alternatives, clone whole technology repositories, inspect unrelated package internals, or delegate research unless one concrete failure requires one exact investigation.',
|
|
55
|
+
`- Available Stack components: ${availableComponents.length > 0 ? availableComponents.map((id) => `\`${id}\``).join(', ') : 'none'}.`,
|
|
56
|
+
'- When the user names an unselected technology that exactly matches this catalog, run `genesis stack list`, ask whether to add and prepare it, and wait for confirmation. If confirmed, run `genesis stack add <piece...>` and follow its returned preparation prompt in the same task; then use `genesis context` and any installed technology skill. Never infer dependency commands from a component id. If declined or unmatched, continue through authoritative technology documentation without inventing a component.',
|
|
57
|
+
'- Project-owned operation sections in `genesis/stack.md` are the durable application contract. Make the implementation satisfy them or update a complete section to match evidenced reality; Genesis executes only Verification.',
|
|
41
58
|
'- Use the relevant project Agent Skills below `.agents/skills/`.',
|
|
42
59
|
'- After locating source, run `genesis context <path...>`; before adding a helper or public operation, run `genesis index <name-or-path...>` and reuse an existing owner.',
|
|
43
60
|
'- Program is fallible explanation; code, tests, and runtime behavior remain evidence.',
|
|
44
61
|
'- Keep Blueprint and affected Program explanations aligned with intentional observable product behavior in the same implementation turn. Private restructuring may need only source citations or no explanatory change.',
|
|
62
|
+
'- Before reporting completion, compare the requested observable behavior, required inputs and resources, declared project operations, and focused evidence with what actually exists. State anything not proven.',
|
|
45
63
|
'- Deslop only when explicitly requested. Genesis defines its behavior-preserving committed scope; selected Stack components may add technology-specific cleanup guidance.',
|
|
46
64
|
'- This guidance is loaded for a new session and refreshed after compaction. Continue the active request without restarting completed work.',
|
|
47
65
|
`Engineering profile: ${engineering.profile?.id || 'invalid; run the Genesis `check` operation'}.`,
|