genesis-compiler 1.10.19 → 1.10.20

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.
@@ -0,0 +1,259 @@
1
+ ---
2
+ name: genesis-identity-pass
3
+ description: Give software a visual identity of its own (one seed colour, artwork drawn in code for each kind of content, a logo, empty states, a loading screen and a sign-in page) through an explicitly requested identity pass over the whole app, a named section, or the agent's own changes. Use when asked for a visual identity, a look, artwork or a logo, or to make an app look designed rather than like a default template.
4
+ ---
5
+
6
+ # Genesis identity pass
7
+
8
+ Give the software a look of its own, drawn in code, so it reads as designed
9
+ rather than as a default template. An identity pass is explicit: never run it
10
+ merely because implementation finished.
11
+
12
+ Resolve the invocation before running the first Genesis operation. Do not use a
13
+ Genesis operation or `genesis --version` as an availability probe.
14
+
15
+ 1. Read the repository-root `package.json`. Treat Genesis as project-pinned only
16
+ when that manifest's `name` is `genesis-compiler`, or its `dependencies`,
17
+ `devDependencies`, or `optionalDependencies` contain the exact
18
+ `genesis-compiler` key.
19
+ 2. For a project-pinned repository, invoke every Genesis CLI operation with
20
+ `npm exec --no -- genesis <arguments>`. This runs without fetching another
21
+ package. If the declared package is not installed, report that the project's
22
+ dependencies are not prepared; do not fall back to another Genesis version.
23
+ 3. Otherwise, do not try `npm exec`. Run `command -v genesis` (or the current
24
+ shell's equivalent `PATH` lookup). When it resolves an executable, invoke
25
+ `genesis <arguments>` directly.
26
+ 4. When neither source is available, stop and report that Genesis is
27
+ unavailable. Never install or update Genesis merely to satisfy a workflow
28
+ instruction.
29
+
30
+ Successful invocation resolution is routine. Do not narrate whether Genesis is
31
+ project-pinned or on `PATH`, and never describe direct `PATH` use as a fallback.
32
+ Mention how the invocation was selected only when resolution fails or the user
33
+ explicitly asks.
34
+
35
+ Follow the configured Collaboration approach for user-facing updates, including
36
+ its technical depth and response length. Report concrete progress,
37
+ findings, or blockers; do not announce that you are following guidance.
38
+
39
+ ## Load the effective project instructions once
40
+
41
+ An identity pass request may arrive as a complete Genesis-generated prompt or
42
+ as a direct request such as `Give the app its visual identity`.
43
+
44
+ If the current task already contains `GENESIS CONTEXT` whose task is
45
+ `identity-pass`, continue with it directly. Do not generate another prompt.
46
+
47
+ Otherwise, before resolving scope, run the Genesis `prompt --task identity-pass`
48
+ operation once using the invocation rule above. For a bare request, pass no
49
+ request argument. When the user names a section, commits or your own changes,
50
+ pass that exact request as one safely quoted argument. Treat the printed prompt
51
+ as the instructions for this same turn; do not dispatch it to another agent and
52
+ do not generate it again. This step composes the selected Stack's identity pass
53
+ guidance and any project customization with the portable contract below.
54
+
55
+ ## Resolve the scope
56
+
57
+ Inspect `git status --short` and the staged and unstaged diffs before editing.
58
+ A dirty worktree is allowed. Preserve the existing index and unrelated work; do
59
+ not stage, stash, commit, or discard changes as a prerequisite.
60
+
61
+ - **The whole app (default).** Every screen or view a person sees, the shell,
62
+ sign-in, the loading screen, the logo and the icons. An identity is
63
+ app-wide, so this is the scope when none is stated.
64
+ - **A section.** A named area (a module, a route subtree, a set of screens):
65
+ it receives the app's existing identity, such as art for a new kind of
66
+ content and its empty states.
67
+ - **The changes.** Your own changes for the current task, or explicit commits,
68
+ established and resolved as for Deslop: the screens they add or change
69
+ receive the existing identity.
70
+
71
+ A narrower scope in an app with no identity yet still needs the foundation
72
+ (the seed, the colour module and the logo, steps 1 and 2 below): build it, and
73
+ report that the rest of the app does not have the identity yet.
74
+
75
+ ## Study the software first
76
+
77
+ Before drawing anything, run the software and look at its screens, and read the
78
+ Blueprint. Write a short look spec, a few lines kept for the report:
79
+
80
+ - what the software is for, who uses it, and the tone that suits it;
81
+ - its **content kinds**: the categories people browse, pick or make (recipes
82
+ by course, workouts by type, books by genre, levels by world). Take them
83
+ from the data the software already has; do not invent a taxonomy the
84
+ product lacks. Art that follows the categories helps people recognise an
85
+ item at a glance;
86
+ - the **style option** below that fits, with the reason, and the seed colour.
87
+
88
+ ## Choose a style option
89
+
90
+ The look is a choice, not a fixed recipe. Pick the option that fits, or the one
91
+ the person or the project already uses:
92
+
93
+ - **Calm interface, energetic artwork.** The default for content apps, where
94
+ people browse, pick or make items. Interface surfaces stay quiet and the
95
+ generated artwork carries the colour and the energy, so the content stays at
96
+ the centre and the interface stays readable in both schemes.
97
+ - **Quiet tool.** For work tools, dashboards, administration and developer
98
+ tools, and command-line programs. The identity lives in the seed colour, the
99
+ logo, the type and the empty states, with little or no artwork in lists,
100
+ where density and quick scanning matter more.
101
+ - **The project's own brand.** When the project already has brand colours, a
102
+ logo or a style guide, follow them: the brand colour becomes the seed and its
103
+ other colours become named roles. Never redraw a brand's own logo.
104
+
105
+ Games and other expressive software usually have an art direction already. The
106
+ pass then brings the same discipline to it (one source for its colours, seeded
107
+ variation, contrast, reduced motion) instead of replacing it.
108
+
109
+ ## Build the identity
110
+
111
+ Draw everything in code when possible: no stock photos, no downloaded images,
112
+ and no new dependency for drawing. Drawn art scales, follows the palette, costs
113
+ little, works offline and carries no licence risk. Artwork the person supplies,
114
+ and a brand's own files, are used as given. Keep the code small and direct, as
115
+ the engineering approach asks: one art component, one colour module, motifs as
116
+ data.
117
+
118
+ 1. **One seed colour.** Generate the interface's colour schemes (light and
119
+ dark, where the platform has both) from one seed through the technology's
120
+ own theme mechanism, never by picking each colour by hand: one decision
121
+ keeps every role consistent, and both schemes follow when it changes. A
122
+ deep, slightly cool seed usually keeps its character in both schemes.
123
+ Colour roles the software needs of its own, such as one per content kind,
124
+ are named theme colours harmonised toward the seed, each with the roles for
125
+ writing on it and for a container, working in both schemes.
126
+ 2. **Every non-interface colour in one place.** Artwork gradients, the logo,
127
+ the sign-in panel, share images and avatar colours are named constants in
128
+ one module, each with a short comment saying where it is used. Interface
129
+ code uses theme roles only, never a literal colour. A colour scattered
130
+ through screens cannot follow the brand and drifts; this is "Data: one
131
+ source for each fact" in
132
+ `.agents/skills/genesis-project/references/sanity-checks.md`.
133
+ 3. **Artwork for each content kind.** One art component (a cover) draws an
134
+ item's art from its kind and a seed, the item's stable id or slug:
135
+ - per kind, a palette in the colour module: two gradient colours, an accent
136
+ and a light colour. Each kind has its own distinct gradient, and a brand
137
+ kind serves items without one;
138
+ - per kind, a **motif**: a few simple, bold geometric shapes that say what
139
+ the kind is (a bowl and rising steam for soups, a climbing line for
140
+ running, stacked spines for books, a leaf for plants). Describe each motif
141
+ as data (a shape name and its attributes) drawn by one renderer, so a new
142
+ kind is new data rather than new code;
143
+ - a **seeded random generator**, so the same item always draws the same art
144
+ and each item differs a little while staying recognisably its kind. For
145
+ example, mulberry32 over an FNV-1a hash of `kind:seed`:
146
+
147
+ ```js
148
+ function randomFor(kind, seed) {
149
+ let h = 2166136261;
150
+ for (const c of `${kind}:${seed}`) h = Math.imul(h ^ c.charCodeAt(0), 16777619);
151
+ let s = h >>> 0;
152
+ return () => {
153
+ s = (s + 0x6d2b79f5) >>> 0;
154
+ let n = Math.imul(s ^ (s >>> 15), 1 | s);
155
+ n = (n + Math.imul(n ^ (n >>> 7), 61 | n)) ^ n;
156
+ return ((n ^ (n >>> 14)) >>> 0) / 4294967296;
157
+ };
158
+ }
159
+ ```
160
+
161
+ Each seed moves the motif's centre a little (right of centre leaves room
162
+ for text), tilts the gradient within about 25 degrees either way, and
163
+ scatters a few soft dots behind the motif (small, in the light colour, at
164
+ low opacity). Never seed from the clock or an unseeded random: the art
165
+ would change on every load;
166
+ - drawing: thick strokes with round caps, two or three opacity levels, and
167
+ the accent used once per motif as its focal point. A wide 2:1 drawing
168
+ cropped to fill its box serves a card, a strip and a thumbnail alike.
169
+ Gradients and other definitions get ids unique to their kind and seed, so
170
+ two covers on one page never share one. The art is decorative: hide it
171
+ from assistive technology and let the item's title carry the meaning.
172
+ 4. **Where the identity appears**, where the software has these:
173
+ - **content cards** in lists and libraries: the art across the top, then the
174
+ title, the byline, a short description, chips (kind, level) and one meta
175
+ line (date, people). A "Featured" group can come before the rest;
176
+ - **a hero card and a profile header**: a strip of art with the avatar
177
+ overlapping its lower edge;
178
+ - **empty states**: a small cover with the state's icon on a disc in its
179
+ middle, a one-line title, a short hint and one action that gets the
180
+ person going. An empty screen is often a new person's first one;
181
+ - **the logo**: a rounded tile with the brand gradient and one bold symbolic
182
+ mark in two accent colours with a light core. The same drawing is the
183
+ favicon and the app icons. Draw it inline where possible rather than as a
184
+ cached image, so it follows the colour module;
185
+ - **the opening or loading screen**, shown before the software's code runs:
186
+ the logo, the name and a one-line tagline, with a way to reload if startup
187
+ fails. Its motion is gentle and stops when reduced motion is asked for;
188
+ - **sign-in**: on wide windows, a brand panel (a glow from the brand colour
189
+ into a dark ink, the logo, the name, the tagline and three short lines on
190
+ what the software does, with a large faint accent ring and a few soft light
191
+ bubbles); on phones, the logo and the name over a strip of art;
192
+ - a **command-line program** shows its name and tagline in help and version
193
+ output and maps its colours to the terminal's, with no colour when
194
+ `NO_COLOR` is set or the output is not a terminal; a **game** carries the
195
+ identity on its title and loading screens and its icons.
196
+ 5. **Polish that keeps the identity calm.** Follow the selected Stack's UI pass
197
+ rules for layout; in addition:
198
+ - while loading, show skeletons with the shape of the real content rather
199
+ than a spinner, so nothing jumps when the data arrives;
200
+ - numbers that change use tabular figures (`font-variant-numeric:
201
+ tabular-nums` on the web), so they do not shift as they change;
202
+ - a new item entering a list may pop in briefly (from about 0.6 scale,
203
+ fading in over about 600 ms), with no motion when reduced motion is asked
204
+ for;
205
+ - phone navigation follows the platform's own pattern for its size, and a
206
+ navigation drawer with nothing in it is removed.
207
+ 6. **Contrast.** Writing on any content or identity colour reaches at least
208
+ 4.5:1 (WCAG AA for body text) in every scheme; aim for about 5.4:1 with white
209
+ writing on identity colours, since art and gradients vary beneath it.
210
+ Measure the ratios rather than judging by eye.
211
+
212
+ ## Boundaries
213
+
214
+ - The pass changes how the software looks and adds only the few words an
215
+ identity needs (a tagline, the sign-in lines, empty-state hints). It does not
216
+ change what the software does: no feature, field, action, permission,
217
+ validation or data change. New words go through the project's translation
218
+ mechanism where it has one. A defect, missing behavior or test gap you notice
219
+ is a follow-up finding, left unchanged.
220
+ - The selected Stack's identity pass guidance says where each piece lives;
221
+ the identity never breaks a design rule the Stack marks as must-fix.
222
+ - **Fix at the owner.** When the framework itself blocks a result, report the
223
+ exact framework change instead of overriding it in the app's styles.
224
+ - You may add the art components, the colour module, the logo and icon files,
225
+ the loading screen and their styles, place the art in screens, and update
226
+ tests whose markup changed; every behavior assertion stays. Do not edit
227
+ `.genesis/`, Git metadata, dependency directories, generated build output,
228
+ retained migration history, or external resources.
229
+
230
+ ## Prove it
231
+
232
+ - Take screenshots of the main list, a detail page, an empty state, sign-in
233
+ (wide and phone) and the profile, at phone and desktop widths (390 and 1280
234
+ pixels on the web), in light and dark, through the host's managed browser or
235
+ a temporary browser test. Look at every one. Keep them out of the
236
+ repository's tracked files, delete temporary test files, and close every
237
+ browser you start.
238
+ - Confirm that every content kind has its own art, that the same item draws the
239
+ same art on every load (render one seed twice, or reload and compare), and
240
+ that two items of one kind differ.
241
+ - Measure the contrast of writing on each identity colour in both schemes.
242
+ - Confirm that nothing shifts while loading: compare the skeleton and the
243
+ loaded frame, or read the platform's layout-shift measure.
244
+ - Run the checks the Stack guidance names and the focused tests of the
245
+ affected screens.
246
+ - Update the Blueprint with a short paragraph describing the look in plain
247
+ words: the style option, the seed's character, and the art for each kind of
248
+ content. It is product intent, so it names no files.
249
+
250
+ Leave the pass as ordinary uncommitted work for review and a later normal
251
+ commit. Never amend or rewrite selected commits. Summarize the resolved scope,
252
+ the look spec (style option, seed, content kinds and their motifs), what
253
+ changed, files changed, the checks, contrast figures and screenshots actually
254
+ taken (with their paths), and follow-up findings left unchanged.
255
+
256
+ Once the pass has finished, end with the prompt's `PASS RECORD` step: the
257
+ Genesis `passes done identity-pass` operation records it in `genesis/passes.json`, an
258
+ uncommitted change that lands in the pass's own commit. A pass that stopped
259
+ early, was abandoned or still has failing checks is not recorded.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Genesis identity pass"
3
+ short_description: "Give the app a visual identity of its own"
4
+ default_prompt: "Use $genesis-identity-pass to give the whole app its visual identity."
@@ -284,7 +284,9 @@ across screens, navigation, layout at the standard widths, focus, the real
284
284
  sign-in); a new browser check is an assertion in the existing test that already
285
285
  reaches that screen, and a new browser test file is for a new flow. The app's
286
286
  own delays (retry backoff, debounce, polling) run on a fake clock, never in
287
- real time.
287
+ real time. A test's own time limit covers only its own work: what it needs
288
+ is loaded when its file loads, not inside the timed test, so a slow first load
289
+ on a busy machine cannot fail it.
288
290
 
289
291
  **Check:** after every run, read the suite time, each phase's time
290
292
  (preparation, import, sign-in, tests) and the slowest files. A wall time close
@@ -313,6 +315,9 @@ advance the clock instead, unless another test already proves that path.
313
315
  existing browser test could carry the one layout assertion for nothing.
314
316
  - A browser test waited out the app's two retries of a failed request in real
315
317
  time, 3 s on every run.
318
+ - A test loaded its modules inside its 20 s limit, and on a busy machine
319
+ after a fresh install the loading alone used it up; loading them with the
320
+ file moved about 9 s out of the test, which then took under a second.
316
321
 
317
322
  **Outer limit:** a suite running for hours (a small app's for an hour),
318
323
  preparation in minutes, or a limit ten times the measured need. A new test
@@ -0,0 +1,166 @@
1
+ ---
2
+ name: genesis-quality-pass
3
+ description: Make software hold up in real use through an explicitly requested quality pass over the whole app, a named section, or the agent's own changes, covering loading, empty and error states, nothing jumping, edge cases, every refusal explained to the person, and accessibility basics, verified by actually using it. Use when asked for a quality pass, polish, robustness, or to check every state and edge case.
4
+ ---
5
+
6
+ # Genesis quality pass
7
+
8
+ Make the software behave well in the situations people really meet, and prove
9
+ it by using it. A quality pass is explicit: never run it merely because
10
+ implementation finished.
11
+
12
+ Resolve the invocation before running the first Genesis operation. Do not use a
13
+ Genesis operation or `genesis --version` as an availability probe.
14
+
15
+ 1. Read the repository-root `package.json`. Treat Genesis as project-pinned only
16
+ when that manifest's `name` is `genesis-compiler`, or its `dependencies`,
17
+ `devDependencies`, or `optionalDependencies` contain the exact
18
+ `genesis-compiler` key.
19
+ 2. For a project-pinned repository, invoke every Genesis CLI operation with
20
+ `npm exec --no -- genesis <arguments>`. This runs without fetching another
21
+ package. If the declared package is not installed, report that the project's
22
+ dependencies are not prepared; do not fall back to another Genesis version.
23
+ 3. Otherwise, do not try `npm exec`. Run `command -v genesis` (or the current
24
+ shell's equivalent `PATH` lookup). When it resolves an executable, invoke
25
+ `genesis <arguments>` directly.
26
+ 4. When neither source is available, stop and report that Genesis is
27
+ unavailable. Never install or update Genesis merely to satisfy a workflow
28
+ instruction.
29
+
30
+ Successful invocation resolution is routine. Do not narrate whether Genesis is
31
+ project-pinned or on `PATH`, and never describe direct `PATH` use as a fallback.
32
+ Mention how the invocation was selected only when resolution fails or the user
33
+ explicitly asks.
34
+
35
+ Follow the configured Collaboration approach for user-facing updates, including
36
+ its technical depth and response length. Report concrete progress,
37
+ findings, or blockers; do not announce that you are following guidance.
38
+
39
+ ## Load the effective project instructions once
40
+
41
+ A quality pass request may arrive as a complete Genesis-generated prompt or as
42
+ a direct request such as `Quality pass` or `Quality pass the Orders section`.
43
+
44
+ If the current task already contains `GENESIS CONTEXT` whose task is
45
+ `quality-pass`, continue with it directly. Do not generate another prompt.
46
+
47
+ Otherwise, before resolving scope, run the Genesis `prompt --task quality-pass`
48
+ operation once using the invocation rule above. For a bare `Quality pass`
49
+ request, pass no request argument. When the user names a section, commits or
50
+ your own changes, pass that exact request as one safely quoted argument. Treat
51
+ the printed prompt as the instructions for this same turn; do not dispatch it
52
+ to another agent and do not generate it again. This step composes the selected
53
+ Stack's quality pass guidance and any project customization with the portable
54
+ contract below.
55
+
56
+ ## Resolve the scope
57
+
58
+ Inspect `git status --short` and the staged and unstaged diffs before editing.
59
+ A dirty worktree is allowed. Preserve the existing index and unrelated work; do
60
+ not stage, stash, commit, or discard changes as a prerequisite.
61
+
62
+ - **The whole app (default).** Every screen, command and flow a person uses.
63
+ - **A section.** A named area (a module, a route subtree, a set of screens or
64
+ commands): every screen and flow in it, touched or not.
65
+ - **The changes.** Your own changes for the current task, or explicit commits,
66
+ established and resolved as for Deslop: the screens and flows they create or
67
+ change.
68
+
69
+ If the scope is ambiguous, ask which section or changes.
70
+
71
+ ## List the states before changing anything
72
+
73
+ For each screen, command or flow in scope, write down what it shows or does,
74
+ where its data comes from, and each state it can be in: loading, empty, partial,
75
+ full, failed, refused, slow or offline, and first use. Mark which states exist
76
+ and which are missing or wrong. A missing state stays invisible in a demonstration
77
+ with good data and is often the first thing a real person meets.
78
+
79
+ ## Apply the quality contract
80
+
81
+ The sanity checks guide
82
+ (`.agents/skills/genesis-project/references/sanity-checks.md`) sections
83
+ "Screens in use", "The wait a person sees", "Inputs and access" and "Tests that
84
+ prove behavior" describe what good looks like. This pass works through the
85
+ whole scope with them and fixes what it finds:
86
+
87
+ - **Loading.** A wait shows a stable placeholder in the shape of what arrives,
88
+ never a blank screen, so nothing jumps when the data does. An action shows
89
+ that it is working and cannot be sent twice. Long work in a command-line
90
+ program reports progress.
91
+ - **Empty.** An empty view says what would be there and offers the next useful
92
+ action. A first-use empty state differs from "nothing matches this filter",
93
+ which offers clearing the filter.
94
+ - **Errors.** A failure says what happened, in the person's words, and what
95
+ they can do; it offers a retry where retrying can help, keeps what the person
96
+ typed, appears where the failure happened (beside the field, in the panel
97
+ that failed) and never covers the next action. A failure is never silent and
98
+ never a raw code or stack trace.
99
+ - **Nothing jumps.** Layout keeps its place through loading, arriving data,
100
+ feedback and errors, and feedback never covers the control the person reaches
101
+ for next.
102
+ - **Edge cases.** Try the ones that apply: very long and very short text,
103
+ missing optional values, zero, one and many items, large numbers, dates near
104
+ midnight and in another time zone, duplicates, a double click or double
105
+ submit, refresh or back in the middle of an action, two tabs, an expired
106
+ session, a slow or dropped connection. Fix what breaks, or report it.
107
+ - **Every refusal explained.** When the software refuses (invalid input, a
108
+ missing permission, a limit, a conflict, missing setup), the person sees what
109
+ was refused, why, and what they can do about it, in words they understand.
110
+ The server keeps the refusal's status, code and message to the client, and
111
+ the client shows that message rather than a generic failure. A refusal stays
112
+ a refusal: this pass explains it and never loosens it.
113
+ - **Accessibility basics.** Every control can be reached and used from the
114
+ keyboard in a sensible order, with visible focus; every field and icon-only
115
+ control has a name; status, selection and errors are never shown by colour
116
+ alone; contrast is at least WCAG AA in every scheme; text still works at 200%
117
+ zoom; motion stops when reduced motion is asked for; touch targets are about
118
+ 48 pixels; meaningful images have text alternatives and decorative ones are
119
+ hidden. A command-line program uses meaningful exit codes, writes errors to
120
+ standard error, has `--help` and honours `NO_COLOR`; a game offers
121
+ remappable controls and subtitles for its speech where it has them.
122
+
123
+ ## Use it
124
+
125
+ Verification is using the software as a person does, through its real
126
+ interface (a browser, a terminal, a device), not reading its code:
127
+
128
+ - use it as a new person (first run, no data) and as a returning one with
129
+ realistic data (hundreds of items, long names, a long history);
130
+ - walk each flow in scope to its end, then force each state: slow the network
131
+ or the server, go offline, make the server fail, empty the list, enter wrong
132
+ input, act without permission;
133
+ - go through each flow once with the keyboard only;
134
+ - take screenshots of each state you changed at phone and desktop widths (390
135
+ and 1280 pixels on the web), in light and dark, and look at every one. Keep
136
+ them out of the repository's tracked files, delete temporary test files, and
137
+ close every browser and process you start;
138
+ - lock in each fix with a test at the cheapest level that proves it, as the
139
+ sanity checks guide's "Tests: time" describes, and run the focused tests of
140
+ the affected areas and the checks the Stack guidance names.
141
+
142
+ ## Boundaries
143
+
144
+ - The pass changes behavior only to handle a state or an edge case and to
145
+ explain a refusal. It adds no feature and changes no permission, product rule
146
+ or stored data; a larger gap is a follow-up finding, left unchanged.
147
+ - The selected Stack's quality pass guidance names where states, errors and
148
+ refusals live in its technology; follow it.
149
+ - **Fix at the owner.** When the framework itself blocks a result, report the
150
+ exact framework change instead of working around it in the app.
151
+ - You may edit source, styles, messages and tests in scope; every existing
152
+ behavior assertion stays. Do not edit `.genesis/`, Git metadata, dependency
153
+ directories, generated build output, retained migration history, or external
154
+ resources.
155
+
156
+ Leave the pass as ordinary uncommitted work for review and a later normal
157
+ commit. Never amend or rewrite selected commits. Summarize the resolved scope,
158
+ the states listed for each screen or flow with what was missing and what
159
+ changed, the edge cases tried and their results, the refusals reworded, the
160
+ accessibility checks, the screenshots and tests actually taken and run (with
161
+ their paths), files changed, and follow-up findings left unchanged.
162
+
163
+ Once the pass has finished, end with the prompt's `PASS RECORD` step: the
164
+ Genesis `passes done quality-pass` operation records it in `genesis/passes.json`, an
165
+ uncommitted change that lands in the pass's own commit. A pass that stopped
166
+ early, was abandoned or still has failing checks is not recorded.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Genesis quality pass"
3
+ short_description: "Make every state, edge case and refusal hold up in use"
4
+ default_prompt: "Use $genesis-quality-pass to quality pass the whole app."
@@ -109,3 +109,8 @@ commit. Never amend or rewrite the selected commits. Summarize the resolved
109
109
  scope and any commit identities, what changed, files changed, the checks and
110
110
  screenshots actually taken (with their paths), and follow-up findings left
111
111
  unchanged.
112
+
113
+ Once the pass has finished, end with the prompt's `PASS RECORD` step: the
114
+ Genesis `passes done ui-pass` operation records it in `genesis/passes.json`, an
115
+ uncommitted change that lands in the pass's own commit. A pass that stopped
116
+ early, was abandoned or still has failing checks is not recorded.
@@ -14,6 +14,8 @@ import {
14
14
  inspectEnvironment,
15
15
  inspectStackSection,
16
16
  inspectSubsystems,
17
+ inspectPasses,
18
+ recordPassDone,
17
19
  inspectProject,
18
20
  inspectSkills,
19
21
  installCodex,
@@ -70,6 +72,7 @@ async function execute({ command, operands, options }, { signal, hostContext = n
70
72
  }
71
73
  if (command === 'migrate') return migrate({ projectRoot, stackPackages });
72
74
  if (command === 'skills') return syncSkills({ projectRoot, stackPackages });
75
+ if (command === 'passes') return { action: 'done', ...await recordPassDone({ projectRoot, pass: operands[1] }) };
73
76
  if (command === 'adopt') {
74
77
  return adoptProject({ projectRoot, request: operands.join(' '), stackPackages });
75
78
  }
@@ -148,7 +151,13 @@ async function execute({ command, operands, options }, { signal, hostContext = n
148
151
  }),
149
152
  };
150
153
  }
151
- const inspections = { subsystems: inspectSubsystems, environment: inspectEnvironment, project: inspectProject, skills: inspectSkills };
154
+ const inspections = {
155
+ subsystems: inspectSubsystems,
156
+ environment: inspectEnvironment,
157
+ project: inspectProject,
158
+ skills: inspectSkills,
159
+ passes: inspectPasses,
160
+ };
152
161
  return {
153
162
  inspection: operands[0],
154
163
  ...await inspections[operands[0]]({ projectRoot, stackPackages }),
package/src/cli.js CHANGED
@@ -26,6 +26,7 @@ const USAGE = `Usage:
26
26
  genesis stack list
27
27
  genesis stack add <piece...>
28
28
  genesis skills sync
29
+ genesis passes done <pass>
29
30
  genesis templates list
30
31
  genesis templates apply <catalogue:technology/variant>
31
32
  genesis context <path...>
@@ -38,9 +39,10 @@ const USAGE = `Usage:
38
39
  genesis inspect environment
39
40
  genesis inspect project
40
41
  genesis inspect skills
42
+ genesis inspect passes
41
43
  genesis inspect section <name>
42
44
  genesis prompt [request...]
43
- genesis prompt --task <start|adopt|work|deslop|ui-pass|program|blueprint|describe|review> [request...]
45
+ genesis prompt --task <start|adopt|work|deslop|ui-pass|identity-pass|quality-pass|data-pass|program|blueprint|describe|review> [request...]
44
46
  genesis verify
45
47
  genesis check
46
48
 
@@ -61,7 +63,7 @@ prompt to the agent you already use. Review all edits through the ordinary Git
61
63
  diff, then run genesis verify for the Stack's concrete checks.
62
64
  `;
63
65
 
64
- const COMMANDS = new Set(['adopt', 'check', 'codex', 'collaboration', 'context', 'engineering', 'hook', 'index', 'init', 'inspect', 'migrate', 'parsers', 'prompt', 'skills', 'stack', 'templates', 'verify']);
66
+ const COMMANDS = new Set(['adopt', 'check', 'codex', 'collaboration', 'context', 'engineering', 'hook', 'index', 'init', 'inspect', 'migrate', 'parsers', 'passes', 'prompt', 'skills', 'stack', 'templates', 'verify']);
65
67
 
66
68
  function parseCommand(argv) {
67
69
  if (argv.length === 0 || argv.includes('--help') || argv.includes('-h') || argv[0] === 'help') {
@@ -176,6 +178,10 @@ function parseCommand(argv) {
176
178
  if (operands.length !== 1 || operands[0] !== 'sync') {
177
179
  fail('CLI_SKILLS_ACTION_REQUIRED', 'Command skills requires exactly: sync.');
178
180
  }
181
+ } else if (command === 'passes') {
182
+ if (operands.length !== 2 || operands[0] !== 'done') {
183
+ fail('CLI_PASSES_ACTION_REQUIRED', 'Command passes requires exactly: done <pass>.');
184
+ }
179
185
  } else if (command === 'codex') {
180
186
  if (operands.length !== 1 || operands[0] !== 'install') {
181
187
  fail('CLI_CODEX_ACTION_REQUIRED', 'Command codex requires exactly: install.');
@@ -183,12 +189,12 @@ function parseCommand(argv) {
183
189
  } else if (command === 'context' && operands.length === 0) {
184
190
  fail('CONTEXT_PATH_REQUIRED', 'Command context requires at least one project path.');
185
191
  } else if (command === 'inspect') {
186
- const ordinaryInspection = operands.length === 1 && ['environment', 'project', 'skills', 'subsystems'].includes(operands[0]);
192
+ const ordinaryInspection = operands.length === 1 && ['environment', 'passes', 'project', 'skills', 'subsystems'].includes(operands[0]);
187
193
  const sectionInspection = operands.length >= 2 && operands[0] === 'section';
188
194
  if (!ordinaryInspection && !sectionInspection) {
189
195
  fail(
190
196
  'CLI_INSPECT_TARGET_REQUIRED',
191
- 'Command inspect requires project, environment, skills, subsystems, or section <name>.',
197
+ 'Command inspect requires project, environment, skills, passes, subsystems, or section <name>.',
192
198
  );
193
199
  }
194
200
  } else if (command === 'hook' && (operands.length !== 1 || !['discover', 'session', 'turn'].includes(operands[0]))) {
@@ -304,6 +310,17 @@ function writeResult(command, result) {
304
310
  else line(process.stdout, `Parsers verified: ${result.languages.join(', ')}`);
305
311
  return;
306
312
  }
313
+ if (command === 'inspect' && result.inspection === 'passes') {
314
+ for (const pass of result.passes) {
315
+ line(process.stdout, `${pass.id}: ${pass.title} — ${pass.description}`);
316
+ line(process.stdout, ` recommended ${pass.recommend.hint}; Stack guidance: ${pass.stackGuidance ? 'yes' : 'no'}; last run: ${pass.lastRun ?? 'never'}`);
317
+ }
318
+ return;
319
+ }
320
+ if (command === 'passes') {
321
+ line(process.stdout, `${result.pass}: recorded ${result.lastRun} in ${result.path}`);
322
+ return;
323
+ }
307
324
  if (command === 'inspect' && result.inspection === 'skills') {
308
325
  line(process.stdout, `Agent Skills: ${result.status}`);
309
326
  for (const skill of result.skills) line(process.stdout, ` - ${skill.name}: ${skill.status}`);
@@ -17,6 +17,7 @@ import { parse as parseYaml } from 'yaml';
17
17
 
18
18
  import { asDiagnostic, GenesisError } from './errors.js';
19
19
  import { claudeSkillLinks } from './claude-hooks.js';
20
+ import { PASSES } from './passes.js';
20
21
  import { sha256, stableJson, writeFileAtomic } from './utils.js';
21
22
 
22
23
  const packageRoot = fileURLToPath(new URL('../../', import.meta.url));
@@ -34,12 +35,13 @@ const SKILL_FIELDS = new Set([
34
35
  'allowed-tools',
35
36
  ]);
36
37
 
37
- const CORE_SKILLS = [
38
+ // Every project's Genesis workflow skills: the project and Program skills, and one for each pass.
39
+ export const CORE_SKILL_NAMES = Object.freeze([
38
40
  'genesis-project',
39
41
  'genesis-program',
40
- 'genesis-deslop',
41
- 'genesis-ui-pass',
42
- ].map((name) => ({
42
+ ...PASSES.map(({ task }) => `genesis-${task}`),
43
+ ]);
44
+ const CORE_SKILLS = CORE_SKILL_NAMES.map((name) => ({
43
45
  component: null,
44
46
  package: null,
45
47
  path: `skills/${name}`,
@@ -1,5 +1,7 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
 
3
+ import { PASSES } from './passes.js';
4
+
3
5
  const root = new URL('../../', import.meta.url);
4
6
  const assets = {
5
7
  start: new URL('prompts/start.txt', root),
@@ -9,8 +11,7 @@ const assets = {
9
11
  adopt: new URL('prompts/adopt.txt', root),
10
12
  work: new URL('prompts/work.txt', root),
11
13
  describe: new URL('prompts/describe.txt', root),
12
- deslop: new URL('prompts/deslop.txt', root),
13
- 'ui-pass': new URL('prompts/ui-pass.txt', root),
14
+ ...Object.fromEntries(PASSES.map(({ task }) => [task, new URL(`prompts/${task}.txt`, root)])),
14
15
  program: new URL('prompts/program.txt', root),
15
16
  blueprint: new URL('prompts/blueprint.txt', root),
16
17
  review: new URL('prompts/review.txt', root),
@@ -2,6 +2,7 @@ export const GENESIS_CONTRACTS = Object.freeze({
2
2
  subsystems: 'genesis.subsystems.v0',
3
3
  projectInspection: 'genesis.project-inspection.v1',
4
4
  promptTasks: 'genesis.prompt-tasks.v1',
5
+ passes: 'genesis.passes.v1',
5
6
  templates: 'genesis.templates.v1',
6
7
  templateApplication: 'genesis.template-application.v1',
7
8
  collaboration: 'genesis.collaboration.v1',