genesis-compiler 1.10.14 → 1.10.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 CHANGED
@@ -367,7 +367,9 @@ The same baseline keeps what the software builds fast and correct as it
367
367
  grows, through checks the agent makes and judges rather than numbers it must
368
368
  hit. A request, job or test costs in proportion to the rows it handles, never
369
369
  to stored history: the agent counts a list's, batch's or write's queries at a
370
- few rows and at a realistic number and finds what grows with the rows. Tests
370
+ few rows and at a realistic number and finds what grows with the rows. Each
371
+ read asks the store for exactly the rows the code uses, with filters, existence
372
+ checks and counts in the query and pickers searching on the server. Tests
371
373
  take the time their work needs: the agent reads the suite's time and its
372
374
  slowest files and fixes where the time goes, prepares test databases once per
373
375
  run (usually from a stored snapshot checked by a digest, with the full
@@ -380,17 +382,17 @@ pre-existing, and a final run is one whole run of the pushed tree. Each declared
380
382
  constraint and protection is tried with one input that breaks it, access comes
381
383
  from the trusted context, and a change others depend on fails loudly where the
382
384
  old shape is still used. A short list names what is wrong in any context, such
383
- as a silently capped read, an edited migration that has run, an edited
384
- generated file, or tests against a real database. A time limit catches a hang;
385
- a slow check is measured and its cause fixed, never hidden by a longer limit,
386
- retries or smaller data. Coarse outer limits, such as a list making hundreds of
387
- queries or a suite running for hours, mark what is clearly broken; they are not
388
- targets. The baseline is the short form: the genesis-project skill's sanity
389
- checks guide (`references/sanity-checks.md`) gives each check's examples and
390
- outer limits and is read before the agent reports such work done, and each
391
- Stack piece's "Sanity checks with <stack>" guidance names the stack's own tools
392
- for them, such as its query counter, parallel test runner and strict loading
393
- mode.
385
+ as a silently capped read, a read narrowed in code, an edited migration that has
386
+ run, an edited generated file, or tests against a real database. A time limit
387
+ catches a hang; a slow check is measured and its cause fixed, never hidden by a
388
+ longer limit, retries or smaller data. Coarse outer limits, such as a list
389
+ making hundreds of queries or a suite running for hours, mark what is clearly
390
+ broken; they are not targets. The baseline is the short form: the
391
+ genesis-project skill's sanity checks guide (`references/sanity-checks.md`)
392
+ gives each check's examples and outer limits and is read before the agent
393
+ reports such work done, and each Stack piece's "Sanity checks with <stack>"
394
+ guidance names the stack's own tools for them, such as its query counter,
395
+ parallel test runner and strict loading mode.
394
396
 
395
397
  The installed, versioned profile descriptions live in
396
398
  `profiles/engineering/*.md`. Straight Genesis users can inspect and select them
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genesis-compiler",
3
- "version": "1.10.14",
3
+ "version": "1.10.15",
4
4
  "type": "module",
5
5
  "description": "An agent-independent prompt, multi-language code-index, cleanup, and verification companion with project agent guidance.",
6
6
  "repository": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genesis",
3
- "version": "1.10.14",
3
+ "version": "1.10.15",
4
4
  "description": "Makes Codex aware of optional Genesis adoption for existing projects.",
5
5
  "author": {
6
6
  "name": "Mobily Enterprises"
@@ -2,17 +2,19 @@
2
2
 
3
3
  - Every implementation must be easy to reason about and be the smallest targeted change that fully satisfies the known requirements.
4
4
  - Prefer direct control flow, existing ownership boundaries, and established project or technology seams.
5
- - Do not overengineer or overcomplicate the solution. Do not add speculative abstractions, layers, dependencies, infrastructure, compatibility paths, distributed patterns, cryptography, enterprise patterns, or other advanced machinery unless an explicit requirement or a concrete constraint makes it necessary.
5
+ - Do not overengineer or overcomplicate: add no speculative abstractions, layers, dependencies, infrastructure, compatibility paths, distributed patterns, cryptography, enterprise patterns or other advanced machinery unless an explicit requirement or a concrete constraint makes it necessary.
6
6
  - If good software requires material complexity beyond these rules, stop before writing it. Explain the requirement, why the direct design is insufficient, and the smallest added complexity proposed, then ask the user to approve or clarify the tradeoff.
7
- - A request, job or test costs what the rows it handles cost, never what stored history or the whole dataset costs; this is the direct design, not speculative scale work. Check it instead of assuming it: count a list's, batch's or write's queries or storage calls at a few rows and at a realistic number, and judge whether the count follows the pages read or grows with the rows. A count that grows usually means a read, lookup or access check runs per row, or an access check is sized by stored history; related rows come in batches, one query per related table, and every visibility check is bounded by the rows being read. A list that makes hundreds of queries, or a save that takes tens of seconds, is broken: find the cause first. Such limits mark what is clearly broken; they are not targets, and code is never bent to reach a number.
8
- - Give list, batch and write paths a test at realistic row counts and history, since a handful of rows hides per-row work; it compares counts at two sizes rather than holding a fixed ceiling tuned until it passes. Tests take the time their work needs, no more: read the suite's total time and its slowest files, and find where a slow file's time goes (database preparation, replayed migrations, fixed sleeps, polling, server or build starts). Prepare databases and shared fixtures once per run and reuse them, usually from a stored schema and seed snapshot checked by a digest of their sources rather than by replaying migrations, and keep the full-history migration proof as one separate check. Each test file owns its data, ports and files, never touches a development or production database, and can run beside any other, so two identical runs give the same result; files run in parallel within the machine's test budget, and a suite whose wall time is close to the sum of its files' times ran them one at a time, so find why. A suite that runs for hours, or test preparation measured in minutes, is broken.
7
+ - A request, job or test costs what the rows it handles cost, never what stored history or the whole dataset costs; this is the direct design, not speculative scale work. Check it: count a list's, batch's or write's queries or storage calls at a few rows and at a realistic number, and judge whether the count follows the pages read or grows with the rows. A count that grows usually means a read, lookup or access check runs per row, or an access check is sized by stored history; related rows come in batches, one query per related table, and every visibility check is bounded by the rows being read. A list making hundreds of queries, or a save taking tens of seconds, is broken: find the cause first. Such limits mark what is clearly broken; they are not targets, and code is never bent to reach a number.
8
+ - A read asks the store for exactly the rows the code uses: filters, sorting, limits, existence checks and counts go in the query, and pickers and lookups search on the server.
9
+ - Give list, batch and write paths a test at realistic row counts and history, since a handful of rows hides per-row work; it compares counts at two sizes rather than holding a fixed ceiling tuned until it passes. Tests take the time their work needs, no more: read the suite's total time and its slowest files, and find where a slow file's time goes (database preparation, replayed migrations, fixed sleeps, polling, server or build starts). Prepare databases and shared fixtures once per run, usually from a stored schema and seed snapshot checked by a digest of their sources rather than by replaying migrations, and keep the full-history migration proof as one separate check. Each test file owns its data, ports and files, and can run beside any other, so two identical runs give the same result; files run in parallel within the machine's test budget, and a suite whose wall time is close to the sum of its files' times ran them one at a time, so find why. A suite that runs for hours, or test preparation measured in minutes, is broken.
10
+ - A new test proves its behavior at the cheapest level; one that is mostly its own setup around one check is not acceptable.
9
11
  - A refactor, consolidation or move keeps every behavior, or drops one only with the person's agreement. Before changing code, list what it does (its operations, inputs and their validation, permissions, states and edge cases) with the test covering each, adding one where none does; afterwards walk the list again, with the original tests passing and their assertions unchanged. A change that deletes tests or weakens their assertions is not a refactor.
10
- - A failing test is a defect to explain, in the product or in the test, never noise or a "pre-existing" baseline: do not rerun it until it passes, skip it or loosen it to finish. A final run is one run of the whole suite on the tree that is pushed; reruns, chunks and partial runs are reported as partial. A skipped test records its reason and the run that does cover it. A new test is seen to fail once, by breaking the behavior or reverting the fix.
12
+ - A failing test is a defect to explain, in the product or in the test, never noise or a "pre-existing" baseline: do not rerun it until it passes, skip it or loosen it to finish. A final run is one run of the whole suite on the tree that is pushed; reruns, chunks and partial runs are reported as partial. A skipped test records its reason and the run that covers it. A new test is seen to fail once, by breaking the behavior or reverting the fix.
11
13
  - Every constraint and protection the code declares is enforced: send one input that breaks each (a missing required field, a call past a rate limit, a caller without permission, another tenant's id) and see it refused. Authorization is decided before validation answers, from the trusted context rather than ids the client sends, and a missing value, scope or collaborator refuses instead of allowing.
12
14
  - A change that other code depends on (a name, a default, a contract) fails loudly, naming its fix, wherever the old shape is still used, and every dependent project is booted and checked with it.
13
- - Never, whatever the context: cap a read its callers treat as complete; drop a behavior, rule or access decision silently; declare a constraint or protection that nothing enforces; let a client's ids or a missing value decide access; store a missing value as a real one; run tests against a developer's or production database or configuration; edit a migration that has run anywhere; edit a generated file instead of its source; let the first visitor to a new deployment own it; run production with development settings; release a test's servers, processes or timers only where a timeout skips it. Each one silently loses data, protection or a whole run.
14
- - During implementation, run the relevant checks and batch related cases when they share setup. Follow the project's verification policy for broad or final checks; do not repeat them merely because an item finishes or a session resumes. Preserve required coverage and isolation.
15
- - Bound each long check by a time limit so it ends even when it hangs; write its complete output to a local file and preserve its exit status. Afterwards read concise counts, timings and actionable failure excerpts first, expanding evidence only when needed; never load full passing reports into agent context. Retain startup and cleanup failures; retry only after a change or new evidence justifies it.
15
+ - Never, whatever the context: cap a read its callers treat as complete, or narrow a broad or capped read in code; drop a behavior, rule or access decision silently; declare a constraint or protection that nothing enforces; let a client's ids or a missing value decide access; store a missing value as a real one; run tests against a developer's or production database or configuration; edit a migration that has run anywhere; edit a generated file instead of its source; let the first visitor to a new deployment own it; run production with development settings; release a test's servers, processes or timers only where a timeout skips it. Each one silently loses data, protection or a whole run.
16
+ - During implementation, run the relevant checks, batching cases that share setup. Follow the project's verification policy for broad or final checks; do not repeat them just because an item finishes or a session resumes. Preserve required coverage and isolation.
17
+ - Bound each long check by a time limit so a hang ends it; write its complete output to a local file and keep its exit status. Then read counts, timings and failure excerpts first, expanding only when needed; never load full passing reports into agent context. Retain startup and cleanup failures; retry only after a change or new evidence justifies it.
16
18
  - A time limit catches a hang; it does not fix slowness. When a check, test or request is slower than its work needs, measure where the time goes and fix the cause; never raise a time limit, add retries, repeat a call or shrink realistic data or coverage to make it pass.
17
- - For browser verification, batch related actions and return only the relevant values or page region. Capture screenshots at meaningful visual checkpoints or failures, not after every action. Preserve required viewport, identity and security coverage; prefer existing automated cases for repeated checks.
18
- - These are the short form. Genesis's sanity checks guide (`.agents/skills/genesis-project/references/sanity-checks.md`) gives each check's examples and outer limits: read the section that applies before reporting data access, tests, a refactor, a screen or a release done, and apply it with the tools your Stack pieces name.
19
+ - For browser verification, batch related actions, return only the relevant values or page region, and take screenshots at visual checkpoints or failures, not after every action. Preserve required viewport, identity and security coverage; prefer existing automated cases for repeated checks.
20
+ - Genesis's sanity checks guide (`.agents/skills/genesis-project/references/sanity-checks.md`) gives each check's examples and outer limits: read the section that applies before reporting data access, tests, a refactor, a screen or a release done, and apply it with the tools your Stack pieces name.
@@ -27,11 +27,22 @@ timing where one exists and the code path otherwise: a list or batch whose
27
27
  query count grows with its rows, an access check whose cost grows with stored
28
28
  history, a list, batch or write path never tested at realistic counts, test
29
29
  preparation that replays the migration history, tests that share drifting data
30
- or cannot run in parallel, and a time limit raised to absorb slowness. Report
30
+ or cannot run in parallel, and a time limit raised to absorb slowness. Search
31
+ for reads whose rows are then filtered, found, sliced or tested in code,
32
+ pickers and lookups included, and for capped reads (the latest N, a default
33
+ page) used as if complete: each belongs in the query unless the code shows the
34
+ store cannot express it, and a capped one also loses every match past the cap,
35
+ so report it as a defect, not only a cost. Report
31
36
  behavior a refactor dropped: operations, validation, permissions or edge cases
32
37
  the earlier code had and the current code lacks, and tests deleted or weakened
33
38
  with it. Report declared constraints and protections that nothing enforces, and
34
39
  access decided from ids the client sends rather than the trusted context.
40
+ Judge the structure, not only the change, since a change can look fine alone
41
+ in an application that lacks a layer: run the project's lint and checks and
42
+ read what they report; ask whether every table has one owner, whether every
43
+ query of a table goes through that owner, and whether an owner or repository
44
+ layer exists at all; and report work over a whole population (every user,
45
+ row or tenant) done inside a request rather than over the request's own rows.
35
46
  Judge each against the matching section and outer limit of
36
47
  `.agents/skills/genesis-project/references/sanity-checks.md`.
37
48
 
@@ -170,7 +170,10 @@ row counts and history that compares its query count at a few rows and at a
170
170
  realistic number. Read the run's preparation, suite and slowest-file timings
171
171
  with its counts; when one grows with the data, find the cause (a read per row,
172
172
  an access check sized by stored history, test preparation that replays
173
- migrations) before reporting completion. After a refactor, walk the behavior
173
+ migrations) before reporting completion. Search the changed reads, pickers and
174
+ lookups included, for rows filtered, found, sliced or tested in code and for a
175
+ capped read used as if complete; move each into the query, or state in the code
176
+ why the store cannot express it. After a refactor, walk the behavior
174
177
  list made before it and report any item that no longer holds. Before reporting
175
178
  data access, tests, a refactor, a screen or a release done, read the matching
176
179
  section of [the sanity checks guide](references/sanity-checks.md) and apply its
@@ -21,6 +21,8 @@ reporting data access, tests, a refactor, a screen or a release done.
21
21
  Each one silently loses data, protection or a whole run.
22
22
 
23
23
  - Cap a read its callers treat as complete: they act on a silent first page.
24
+ - Narrow a broad or capped read in code: a broad one reads what it discards, a
25
+ capped one loses every match past the cap.
24
26
  - Drop a behavior, rule or access decision silently in a restructure.
25
27
  - Declare a constraint or protection that nothing enforces.
26
28
  - Let a client's ids or a missing value decide access.
@@ -32,6 +34,29 @@ Each one silently loses data, protection or a whole run.
32
34
  - Release a test's servers, processes or timers only where a timeout skips it.
33
35
  - Edit a generated file instead of its source: the next generation erases it.
34
36
 
37
+ ## Data: one owner per table
38
+
39
+ **Good:** every table has one owner, a repository or resource module, and every
40
+ query of the table goes through it, so the table's scoping, validation and
41
+ locking live in one place. A request works on the rows it concerns; work over a
42
+ whole population runs as a job in bounded chunks.
43
+
44
+ **Check:** judge the structure, not only a change. Run the project's lint and
45
+ checks and read what they report. For each table, name its owner and search for
46
+ queries that reach the table from anywhere else: routes, services, another
47
+ table's owner, raw SQL. Read each request path for work that covers every user,
48
+ row or tenant (a recount, a backfill, a sweep) instead of the request's own
49
+ rows. Each read and write path needs a test that seeds a second owner and sees
50
+ its rows stay unseen and unchanged, write hooks and side effects included.
51
+
52
+ **Examples:**
53
+ - An application had no repository layer: each route queried the tables it
54
+ needed with its own copy of the tenant filter, and every change looked fine
55
+ in a review of that change alone.
56
+
57
+ **Outer limit:** an application with no owner layer, a table written from
58
+ several places, or a request whose work grows with the whole population.
59
+
35
60
  ## Data: loading a dataset
36
61
 
37
62
  **Good:** a list, page or report takes about as many queries for 10 rows as
@@ -65,18 +90,46 @@ Compare a response's size with what the screen shows of it.
65
90
  a quiet database, runs the same access check more than a few times per
66
91
  request, or returns megabytes for one screen is broken. Find the loop first.
67
92
 
93
+ ## Data: each read asks for the rows it uses
94
+
95
+ **Good:** a read asks the data store for exactly the rows the code uses.
96
+ Filtering, sorting, limits, existence checks and counts go in the query. A
97
+ picker, lookup or autocomplete asks the server for the narrowed set, searching
98
+ on the server, instead of loading a list and filtering it in the browser.
99
+
100
+ **Check:** search for reads whose results are then filtered, found, sliced or
101
+ tested in code (`filter`, `find`, `some`, `slice`, a loop that skips rows, a
102
+ length taken to count rows or test for one), and for capped reads (the latest
103
+ N, a default page, a fixed limit) used as if complete. Move each into the
104
+ query, or the code states why the store cannot express it. A capped read
105
+ narrowed afterwards also loses every match past the cap, so it is a
106
+ correctness bug, not only a cost: seed more rows than the cap, with the oldest
107
+ one matching, and see it found.
108
+
109
+ **Examples:**
110
+ - Pickers loaded the latest 200 records of every kind and kept one kind in
111
+ code: slow, and a matching record older than the newest 200 never appeared.
112
+
113
+ **Outer limit:** a capped read narrowed in code is broken at any size.
114
+
68
115
  ## Data: saves, batches and background work
69
116
 
70
117
  **Good:** a batch writes each table in a few statements inside the owner's
71
118
  transaction, not one full create per row. Work nobody waits for runs as a
72
- scheduled or queued job in bounded chunks. A read request takes no lock and
73
- writes nothing. Two writers on the same records never produce a server error.
119
+ scheduled or queued job in bounded chunks: it loops over units of work (a
120
+ tenant, a user), one transaction each, never one around the whole run and
121
+ never one per row. A read request takes no lock and writes nothing. Every path
122
+ takes its locks in one order, parents before children, so two transactions
123
+ never wait on each other. Two writers on the same records never produce a
124
+ server error.
74
125
 
75
126
  **Check:** count a batch's statements at 10 items and at 500. Look for due work
76
127
  run inside whichever request comes first, and one long transaction around it.
77
128
  Find any lock or write a read path takes for one-time setup: read first, lock
78
- only on the rare unset path. Run two writers on the same records; a retried
79
- transaction must be safe to repeat.
129
+ only on the rare unset path. Compare the order in which each path locks rows.
130
+ Run two writers on the same records; a retried transaction must be safe to
131
+ repeat, so HTTP calls, email and uploads go before or after it, or into an
132
+ outbox row written inside it.
80
133
 
81
134
  **Examples:**
82
135
  - An import created each row through the full single-record create path, with
@@ -122,8 +175,8 @@ decision, or drops one only with the person's agreement.
122
175
 
123
176
  **Check:** before changing code, list its operations, inputs and their
124
177
  validation, permissions per role, states and edge cases, with the test covering
125
- each. Afterwards walk the list again with the original tests passing and their
126
- assertions unchanged. Compare per-file test counts before and after, and name
178
+ each; pin what a path answers with a test before moving it. Afterwards walk the
179
+ list again with the original tests passing and their assertions unchanged. Compare per-file test counts before and after, and name
127
180
  each removal. Search for what a removed caller was the only caller of. After a
128
181
  mechanical sweep, compare files changed with files expected and search for the
129
182
  old form. A new mechanism replaces the one already doing the job.
@@ -161,26 +214,50 @@ look green, or dozens of skips nobody can place.
161
214
  **Good:** tests take the time their work needs. Files run in parallel within
162
215
  the machine's test budget. Databases and fixtures are prepared once per run
163
216
  from a stored schema and seed, checked by a digest of their sources, and the
164
- full migration history is replayed once, as its own check. Builds and server starts happen once per run.
217
+ full migration history is replayed once, as its own check. Builds and server
218
+ starts happen once per run. Each test proves its behavior at the cheapest
219
+ level that can: rules and calculations in a unit test; data, access and
220
+ refusals in a server or integration test; a component's content and states in
221
+ a component test. A browser test checks only what needs a real browser (a flow
222
+ across screens, navigation, layout at the standard widths, focus, the real
223
+ sign-in); a new browser check is an assertion in the existing test that already
224
+ reaches that screen, and a new browser test file is for a new flow. The app's
225
+ own delays (retry backoff, debounce, polling) run on a fake clock, never in
226
+ real time.
165
227
 
166
228
  **Check:** after every run, read the suite time, each phase's time
167
229
  (preparation, import, sign-in, tests) and the slowest files. A wall time close
168
230
  to the sum of the files' times means they ran one at a time: find why. In a
169
231
  slow file, find where the time goes: repeated preparation, replayed
170
- migrations, fixed sleeps, polling, a process per test, repeated builds or
171
- sign-ins. Split test time into the app's request time and the harness's before
172
- choosing a fix. Remove exact repeats across CI jobs. Each sleep names the
173
- condition it waits for; wait for that. Compare each raised time limit with the
174
- measured need, and check a limit exists. Assert counts, not tight times.
232
+ migrations, fixed sleeps, polling, a process per test, repeated builds,
233
+ sign-ins or page loads. Split test time into the app's request time and the
234
+ harness's before choosing a fix. Remove exact repeats across CI jobs. Each
235
+ sleep names the condition it waits for; wait for that. Compare each raised
236
+ time limit with the measured need, and check a limit exists. Assert counts,
237
+ not tight times. Before adding a test, find the cheapest level that proves the
238
+ behavior and the existing test that already pays its setup; after adding it,
239
+ report its time, how much of that is setup, and the suite's time before and
240
+ after. A test that is mostly setup around one check is in the wrong place:
241
+ move the check, then see it fail once there. A test that changes its input to
242
+ skip a wait (another error, a shorter path) stops proving the skipped path:
243
+ advance the clock instead, unless another test already proves that path.
175
244
 
176
245
  **Examples:**
177
246
  - 359 tests ran one file at a time, 163 s in all, because the test command
178
247
  forced a concurrency of one.
179
248
  - Test databases were rebuilt by replaying every migration for each file.
180
249
  - Time limits were raised until slow tests passed, and the slowness stayed.
250
+ - A new browser test file took 21 s for two cases checking what one card on a
251
+ page shows. A component test proves that in milliseconds, and the page's
252
+ existing browser test could carry the one layout assertion for nothing.
253
+ - A browser test waited out the app's two retries of a failed request in real
254
+ time, 3 s on every run.
181
255
 
182
256
  **Outer limit:** a suite running for hours (a small app's for an hour),
183
- preparation in minutes, or a limit ten times the measured need.
257
+ preparation in minutes, or a limit ten times the measured need. A new test
258
+ whose time is mostly its own setup, for a check that a cheaper level or an
259
+ existing test could make, is not acceptable: every run, by every person and
260
+ agent, pays for it for as long as it exists.
184
261
 
185
262
  ## Tests: each owns what it uses
186
263
 
@@ -305,7 +305,10 @@ async function resolveLocator(locator) {
305
305
  : `genesis:${locator.path}`
306
306
  );
307
307
  const skill = await describeSkill(directory, source);
308
- if (!skill) invalidSkill(`Selected Agent Skill is unavailable: ${directory}.`);
308
+ // A selected skill the installed package does not contain is missing from the project's dependencies, not malformed.
309
+ if (!skill) {
310
+ throw new GenesisError('AGENT_SKILL_UNAVAILABLE', `Selected Agent Skill is unavailable: ${directory}.`, { path: directory });
311
+ }
309
312
  return { ...skill, component: locator.component };
310
313
  }
311
314