@pikku/skills 0.12.47 → 0.12.50

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.
@@ -8,13 +8,13 @@ project shaped so `pikku fabric init` later adopts it with zero rework.
8
8
 
9
9
  1. Write the knowledge graph — what the app IS, before any code
10
10
  2. Declare the people and the apps — personas, roles, frontends
11
- 3. Plan the milestones — the buildable pieces, in dependency order
12
- 4. Implement them one at a time — each proven by a scenario before the next starts
11
+ 3. File the work as changes — grouped into changesets, in dependency order
12
+ 4. Build them one changeset at a time — each proven by a scenario before it merges
13
13
 
14
14
  The sections below follow those phases in order, and are meant to be worked
15
15
  through rather than searched: §0 bootstrap, §1-§1a the last questions and the
16
16
  three languages, §2 the knowledge graph, §3-§4 personas and apps, §5-§5a the
17
- milestones and each one's technical plan, §6-§6a building and closing one,
17
+ changes and each changeset's technical plan, §6-§6a building and closing one,
18
18
  §7-§7a proving it, §8 design, §9 ship. Four of them hand off to their own file —
19
19
  [scenarios.md](scenarios.md), [design.md](design.md),
20
20
  [multi-app.md](multi-app.md) and [ship.md](ship.md) — at the point you need it.
@@ -63,7 +63,7 @@ in one message. Then stop; do not interview the user.
63
63
  roles they name.
64
64
  - **What are the two or three core objects?**
65
65
  - **What is the main thing someone does on their first visit?** This answer
66
- becomes the second milestone, not the tenth.
66
+ becomes the second changeset, not the tenth.
67
67
  - **One app or several?** Separate apps on separate hosts, or one app with paths.
68
68
  Cheap to answer now, expensive after the routes exist.
69
69
  - **What should it look like?** The template ships one theme — "Neutral", a
@@ -81,7 +81,7 @@ in one message. Then stop; do not interview the user.
81
81
  approved page becomes source of truth for the screens, and the theme is written
82
82
  before it so what they approve is what ships. Only an explicit no skips it.
83
83
  - **May I write test records into the system it talks to?** Ask only when the
84
- app reads a live system through an addon (an ERP, a CRM) and a milestone needs
84
+ app reads a live system through an addon (an ERP, a CRM) and a changeset needs
85
85
  data that isn't there yet: an unpaid invoice, a closed ticket. Say what you
86
86
  would create and that it will be marked "Test". A no means building those
87
87
  screens against their empty states.
@@ -156,17 +156,14 @@ discoverable from code, and the next agent will otherwise re-derive them wrong.
156
156
  `knowledge/` is not documentation you write at the end. It is the record of what
157
157
  the app IS, in the words its users use, and it is the one part of the project
158
158
  another agent picks up and continues from. **Nothing gets built until there is a
159
- milestone note to build.**
159
+ note saying what it is.**
160
160
 
161
161
  Read `knowledge/index.md` and the `pikku-knowledge` skill, then write the notes
162
162
  for what the user just told you. A project whose `knowledge/` is still only the
163
163
  shipped index is a project nobody can resume.
164
164
 
165
- Five sections, each answering exactly one question:
165
+ Four sections, each answering exactly one question:
166
166
 
167
- - `milestones/` — what is one buildable piece, and what proves it works
168
- (some scaffolds call these `slices/`; follow the name `knowledge/index.md`
169
- uses — `knowledge validate` accepts either)
170
167
  - `entities/` — what a thing IS, in the words users use for it
171
168
  - `decisions/` — what was chosen and what that rules out.
172
169
  `decisions/security/` for who may reach what, `decisions/design/` for how it
@@ -182,12 +179,9 @@ Rules that make it a graph rather than a pile of files:
182
179
  written in the same turn. Never scaffold empty directories, and never leave
183
180
  notes flat at the root: a `product.md` and a `glossary.md` at `knowledge/` is
184
181
  not a knowledge base, and it leaves the project unbuildable.
185
- - **A milestone note carries `status`** (`proposed` → `dispatched` → `built`,
186
- nothing else), **at most three `entities`** (past three it is not one piece —
187
- split it), and **its scenario as a fenced ` ```gherkin ` block in the third
188
- person** — `Given 'owner' has no entry`, never `Given I …`. A quoted word
189
- MEANS a persona, so quote only personas you declare in §3 and write domain
190
- values bare. That block becomes a real scenario in §7.
182
+ - **A note says what the app is, never what is left to do.** No status, no
183
+ todo list: the work is filed as changes in §5, and `pikku knowledge gaps`
184
+ says which notes no change builds yet.
191
185
  - **Record only what pikku cannot tell you.** Tables, columns, function
192
186
  signatures, routes, wirings, permissions and roles are all discoverable with
193
187
  `pikku info` / `pikku meta`. Copying them into a note gives you a second copy
@@ -332,7 +326,7 @@ Either way, write the choice and its reason into `knowledge/decisions/`.
332
326
 
333
327
  Recording the decision is Phase 2 work. **Creating the directory is not.**
334
328
  Cloning `apps/app` materialises a folder of copied screens, so it belongs to the
335
- milestone that first needs the second app, not to planning.
329
+ changeset that first needs the second app, not to planning.
336
330
 
337
331
  When you get there, read `references/multi-app.md`. It carries the clone, the
338
332
  `package.json` edits, the `frontends` map in `pikku.config.json`, the dev-runner
@@ -346,97 +340,79 @@ serves, written into `knowledge/decisions/`.
346
340
 
347
341
  ## PHASE 3 — The plan
348
342
 
349
- ## 5. Plan the milestones
343
+ ## 5. File the work as changes
350
344
 
351
- Turn the app into an ordered list of buildable pieces, each a note in
352
- `knowledge/milestones/`, each `status: proposed` with a gherkin block.
345
+ Turn the app into changes on the project's queue — the pikku-changes skill.
346
+ `pikku knowledge gaps` lists every note no change builds yet; file each as one
347
+ or more changes with `pikku changes file`, one commit's worth each, and
348
+ end every body with the gap's `Knowledge:` line so it is not filed twice.
353
349
 
354
- What a milestone is:
350
+ What a change is:
355
351
 
356
- - **One buildable piece, at most three entities.** Past three it is not one piece.
357
- - **Vertical, not layered.** "The owner sees this month's arrears" is a
358
- milestone — migration, function, screen, scenario. "Add the database schema" is
359
- not; it is a step inside one.
352
+ - **One commit's worth.** "The owner sees this month's arrears" is a change,
353
+ or a few. "Add the database schema" is not; it is a step inside one.
360
354
  - **It ends in something a person can do**, in a browser, signed in as a named
361
- persona. If you cannot write the gherkin, you cannot build it yet — that is a
362
- `questions/` note, not a milestone.
355
+ persona. If you cannot say what they see when it is done, that is a
356
+ `questions/` note, not a change.
363
357
 
364
- If §1's screen mock was made — approved, or drawn because nobody answered — the
365
- milestones are read off it: every screen on that page belongs to some milestone,
366
- and a screen no milestone builds
367
- is a hole in this plan. Say which milestone covers which screen.
358
+ If §1's screen mock was made — approved, or drawn because nobody answered —
359
+ every screen on that page belongs to some change, and a screen no change builds
360
+ is a hole in this plan.
368
361
 
369
- How to order them:
362
+ How they group into changesets, in order:
370
363
 
371
364
  1. **The spine first.** The one object everything else hangs off, and the screen
372
365
  that proves the app exists at all.
373
366
  2. **Then the loop the user named as "the main thing someone does on their first
374
- visit."** That answer from §1 is the second milestone, not the tenth.
367
+ visit."** That answer from §1 is the second changeset, not the tenth.
375
368
  3. **Then each audience's own surface**, one at a time. With two apps, finish one
376
369
  app's spine before starting the other's — a half-built app in each is worse
377
370
  than one working app.
378
- 4. **Refusals ride along with the milestone that creates the thing being
379
- refused**, never as a "permissions" milestone at the end. A milestone that
380
- creates a row and does not say who may not see it is not finished.
381
-
382
- Number the files (`01-…`, `02-…`) so the order is visible in the tree. Then
383
- `knowledge index && knowledge validate` before you write a line of code.
371
+ 4. **Refusals ride along with the changeset that creates the thing being
372
+ refused**, never as a "permissions" changeset at the end.
384
373
 
385
374
  **One approval, then build to the end.** Show the picture of the screens and
386
- the milestone list together, in one message, as the plan: which milestone builds
387
- which screen, in what order. That is the only approval you ask for. It is the
388
- last cheap moment to reorder: after §6 the migrations are numbered and the order
389
- is concrete.
390
-
391
- Once they approve it, or don't answer, build every milestone in order without
392
- stopping to ask between them. Post one line as each milestone closes, with its
393
- console links, and carry on. Stop only for what is theirs to decide: a
394
- credential you don't have, spending money, posting in public, deleting or
395
- overwriting their data, or a finding that changes the plan.
396
-
397
- ## 5a. The technical plan — one milestone at a time, before you build it
398
-
399
- The milestone note says what the app must DO. The **plan** says what has to
400
- exist for it: the tables, functions, wires, roles, scopes, screens and
401
- scenarios, split into passes. It is JSON, it lives beside the note, and
402
- `pikku knowledge plan progress` measures the finished build against it.
403
-
404
- **Read `pikku-architect` and follow it.** The plan is the denominator the
405
- completion check divides by, so a builder who plans after seeing their own work
406
- can build a fraction, plan only that fraction, and certify itself complete. The
407
- defence is the ORDER, and it only holds if you keep it: the plan is written
408
- against the note in its own turn,
375
+ the changes together, in one message, as the plan. That is the only approval you
376
+ ask for. Once they approve it, or don't answer, run `pikku changes next --exec <harness>
377
+ --loop`: it hands each changeset to a fresh agent, merges it, and moves on. Post
378
+ one line as each changeset merges, and carry on. Stop only for what is theirs to
379
+ decide: a credential you don't have, spending money, posting in public, deleting
380
+ or overwriting their data, or a finding that changes the plan.
381
+
382
+ ## 5a. The technical plan — per changeset, before you build it
383
+
384
+ `pikku changes claim` decides whether a changeset needs a **plan**: one
385
+ that creates or alters a table always does, and the judge decides the rest. The
386
+ plan says what has to exist: the tables, functions, wires, roles, scopes,
387
+ screens and scenarios, split into passes. It is JSON at
388
+ `knowledge/plans/<changeset>.plan.json`, committed on the changeset's branch,
389
+ and `pikku knowledge plan progress` measures the finished build against it.
390
+
391
+ **Read `pikku-architect` and follow it.** The plan is written in its own turn,
409
392
  before any of the code it measures exists, and is never edited afterwards to
410
393
  match what you ended up building. An item that will not land is deferred with
411
- its reason — `plan defer` — not quietly rewritten. Write it before you open a
412
- migration:
394
+ its reason — `plan defer` — not quietly rewritten:
413
395
 
414
396
  ```sh
415
397
  pikku knowledge plan schema # the only spec there is
416
- pikku knowledge plan set <milestone> /tmp/plan.json
417
- pikku knowledge plan show <milestone> --for-build # what you then build
398
+ pikku knowledge plan set <changeset> /tmp/plan.json
399
+ pikku knowledge plan show <changeset> --for-build # what you then build
418
400
  ```
419
401
 
420
- **Plan one milestone at a time, at the moment you are about to build it** — not
421
- all of them here. A plan written against a note that later moves is worse than
422
- no plan, and everything after the current milestone is still allowed to move.
423
-
424
402
  ---
425
403
 
426
404
  ## PHASE 4 — Build
427
405
 
428
- ## 6. Implement milestones, one at a time
406
+ ## 6. Build each changeset
429
407
 
430
- All of them, one after another, on the one approval from §5.
408
+ **Per changeset** — claim it, plan it if the claim says so (§5a), do the six
409
+ steps one commit per change, close it out (§6a), mark its changes done. Do not
410
+ mark the last one done until §6a passes, §7 is green for it _and §7a shows its
411
+ functions covered_; `changes done` refuses a planned changeset's last change
412
+ while the plan is short.
431
413
 
432
- **Per milestone** — plan it (§5a), set its note to `status: dispatched`, do the
433
- six steps, close it out (§6a), set it to `built`. Do not start the next one
434
- until §6a passes, §7 is green for this one _and §7a shows its functions
435
- covered_. A stack of half-milestones cannot be reviewed and cannot be handed
436
- over, and an uncovered function is a half-milestone whether or not the note says
437
- `built`.
438
-
439
- 1. **Migration.** SQL in `db/sqlite/` at the project root, numbered on from the
414
+ 1. **Migration.** SQL in `db/sqlite/` at the project root (`db/postgres/` or
415
+ `db/mysql/` when `createConfig` sets `postgresUrl` or `mysqlUrl`), numbered on from the
440
416
  ones already there. Apply with `bunx --bun pikku db migrate`, which also
441
417
  regenerates the Kysely types your functions import. **Neither `pikku all` nor
442
418
  restarting `pikku dev` applies a migration** — so a new column reads as
@@ -476,17 +452,17 @@ over, and an uncovered function is a half-milestone whether or not the note says
476
452
  **Read `references/design.md` before you write the first screen.** You commit
477
453
  to a design direction there and are then accountable to it — it hands you no
478
454
  layouts, because the design is yours to make. What you build here is then
479
- judged at step 7, at the end of this milestone rather than once at §8, where
455
+ judged at step 7, at the end of this changeset rather than once at §8, where
480
456
  the only affordable fix is a repaint of eight screens.
481
457
  6. **Scenario** (§7).
482
- 7. **Look at it.** Screenshot every screen this milestone touched, at both
458
+ 7. **Look at it.** Screenshot every screen this changeset touched, at both
483
459
  widths, with the seed in place, and look at the images. This is a gate, the
484
- same as the scenario: a milestone whose screens nobody has seen is not built,
460
+ same as the scenario: a changeset whose screens nobody has seen is not built,
485
461
  it is unproven at the one layer scenarios cannot reach. `references/design.md`
486
462
  carries how to take the shot when no browser tool is wired up, and what to
487
463
  look for. Then close it against its plan (§6a) — `pikku knowledge plan
488
- progress` has to exit zero before anything is `built` — and only then set
489
- `status: built`, saying in the note what you looked at and what it made you
464
+ progress` has to exit zero before the last change is done — and only then
465
+ mark it done, saying in the `--note` what you looked at and what it made you
490
466
  change.
491
467
 
492
468
  Rules that are not optional:
@@ -599,17 +575,17 @@ it is worth writing as a browser step on §7's scenario and running
599
575
  `pikku scenario run local --spawn --run browser`: same clicks, same assertions,
600
576
  in the repo, green or red on every future run.
601
577
 
602
- ## 6a. Close the milestone against its plan, not against your memory
578
+ ## 6a. Close the changeset against its plan, not against your memory
603
579
 
604
580
  ```sh
605
- pikku knowledge plan progress <milestone>
581
+ pikku knowledge plan progress <changeset>
606
582
  ```
607
583
 
608
584
  It reads §5a's plan and reconciles it against the generated meta under
609
585
  `.pikku/` — the function exists or it does not, the route is wired or it is not,
610
586
  the `pikkuScenario` export is there or it is not. Nothing it reports comes from
611
- what anyone claimed, which is the whole reason it replaced a todo list. It exits
612
- non-zero while anything in the first pass is missing.
587
+ what anyone claimed. It exits non-zero while anything in the first pass is
588
+ missing, and `changes done` runs the same check on the last change.
613
589
 
614
590
  Three things it says, and what each one asks of you:
615
591
 
@@ -618,14 +594,14 @@ Three things it says, and what each one asks of you:
618
594
  the record:
619
595
 
620
596
  ```sh
621
- pikku knowledge plan defer <milestone> function:sendReminder \
622
- -r "The email service it needs is the next milestone."
597
+ pikku knowledge plan defer <changeset> function:sendReminder \
598
+ -r "The email service it needs is the next changeset."
623
599
  ```
624
600
 
625
601
  **A deferral is capped at two per plan.** Past that, the plan was wrong and the
626
- milestone is two milestones — say so to the user rather than deferring again.
627
- What you may never do is drop the item silently: the plan is what the next
628
- person reads to know what this milestone was for.
602
+ changeset is two changesets — say so rather than deferring again. What you may
603
+ never do is drop the item silently. A merged changeset with deferrals leaves its
604
+ notes `partial`, and `pikku knowledge gaps` files what it left behind.
629
605
 
630
606
  - **PROBLEMS** — something exists but does not do what was planned. A function
631
607
  planned as restricted whose meta says `auth: false`; a `cascade` no migration
@@ -634,14 +610,13 @@ Three things it says, and what each one asks of you:
634
610
  - **DEFERRED to a later pass** — already accounted for. Reported so it is
635
611
  visible, never blocking.
636
612
 
637
- **Do not set the note to `built` while this exits non-zero**, and do not edit the
638
- plan to match what you built — the plan was written before the code on purpose,
639
- and rewriting your own denominator afterwards is exactly what that order exists
640
- to stop.
613
+ Do not edit the plan to match what you built — the plan was written before the
614
+ code on purpose, and rewriting your own denominator afterwards is exactly what
615
+ that order exists to stop.
641
616
 
642
- ### 6b. Feed the milestone back into the seats
617
+ ### 6b. Feed the changeset back into the seats
643
618
 
644
- Before starting the next milestone, answer two questions out loud:
619
+ Before starting the next changeset, answer two questions out loud:
645
620
 
646
621
  - **What did the plan fail to say?** A field nothing wrote, a promise no function
647
622
  could keep, a pass 1 that turned out to be two. That is a `pikku-architect`
@@ -650,11 +625,11 @@ Before starting the next milestone, answer two questions out loud:
650
625
  a stale process, a scenario that only passes once, a diagnostic that turned
651
626
  out to be an echo of an earlier one. That is a `pikku-build` lesson.
652
627
 
653
- Then edit the skill — **at most one change to each per milestone**, and only for
628
+ Then edit the skill — **at most one change to each per changeset**, and only for
654
629
  something that actually went wrong here. A rule with no incident behind it is a
655
630
  guess, and these files are read in full every time: they earn their length by
656
631
  naming failures a reader would otherwise repeat. Prefer sharpening an existing
657
- line to appending a new one, and delete a rule the last few milestones have
632
+ line to appending a new one, and delete a rule the last few changesets have
658
633
  shown to be noise.
659
634
 
660
635
  The gates are the compounding part. A lesson written into a scenario the suite
@@ -668,9 +643,9 @@ A scenario is a user journey run as one of your personas, over the real
668
643
  transport, with that persona's session. It is the only kind of test worth writing
669
644
  here, because a passing one proves the app works the way a signed-in person
670
645
  experiences it. Three ship in `packages/functions/test/scenarios/` — keep them
671
- green — and every milestone's gherkin block from §5 becomes one more.
646
+ green — and every scenario a changeset's plan names becomes one more.
672
647
 
673
- **Read [scenarios.md](scenarios.md) before writing the milestone's scenarios,
648
+ **Read [scenarios.md](scenarios.md) before writing the changeset's scenarios,
674
649
  and again whenever one of these describes what you are doing.** It is the file
675
650
  where the expensive lessons live, and most of them produce a GREEN suite that
676
651
  proves nothing:
@@ -681,7 +656,7 @@ proves nothing:
681
656
  - what to assert — refusals must read the REASON, totals must be deltas, and the
682
657
  assertion nobody writes is the row count
683
658
  - living without a state reset: the suite must be green on its SECOND run
684
- - how a shared step rots as later milestones add writers of the rows it selects
659
+ - how a shared step rots as later changesets add writers of the rows it selects
685
660
  - browser specifics — the click/navigate race, testids, and `Outlet` nesting
686
661
 
687
662
  Run them:
@@ -695,20 +670,10 @@ In a multi-app project that one run covers both frontends: each persona carries
695
670
  its own `app` and `@pikku/playwright` resolves the base url from the
696
671
  environment's `appUrls` map, so there is no second environment to run.
697
672
 
698
- **Run the whole suite, not the milestone's own scenarios.** The milestone's
699
- scenarios are the ones you wrote to pass; the regression lives in someone
700
- else's. Tightening what "archived" means is a one-function change that reads as
701
- local and quietly breaks the milestone-01 scenario nobody re-ran.
702
-
703
- **Restart the server after adding a function.** Hot reload does not register a
704
- new RPC and does not re-run `afterStart`, so a fresh function answers 404 and
705
- anything provisioned at boot is missing — failures that read like a wiring bug
706
- and are nothing but a stale process.
707
-
708
- **Run the whole suite, not the milestone's own scenarios.** The milestone's
673
+ **Run the whole suite, not the changeset's own scenarios.** The changeset's
709
674
  scenarios are the ones you wrote to pass; the regression lives in someone
710
675
  else's. Tightening what "archived" means is a one-function change that reads as
711
- local and quietly breaks the milestone-01 scenario nobody re-ran.
676
+ local and quietly breaks the first changeset's scenario nobody re-ran.
712
677
 
713
678
  **Restart the server after adding a function, and never edit one while a run is
714
679
  in flight.** Hot reload does not register a new RPC and does not re-run
@@ -733,17 +698,17 @@ bunx --bun pikku scenario run local --coverage # against that server
733
698
  **A function no scenario touches has no scenario coverage** — the file knows
734
699
  what the suite exercises and nothing else, so a unit test, a scheduled job, a
735
700
  webhook or a hand call leaves no trace in it. Read
736
- `coverage/scenario-coverage.json` **as each milestone closes** — per milestone it is a short list you can act on, whereas read for the
737
- first time after ten milestones it is a wall of red nobody triages. Every gap is
701
+ `coverage/scenario-coverage.json` **as each changeset closes** — per changeset it is a short list you can act on, whereas read for the
702
+ first time after ten changesets it is a wall of red nobody triages. Every gap is
738
703
  a missing scenario, a function that should not exist, or a deferral worth
739
704
  writing down; [scenarios.md](scenarios.md) says how to tell them apart. Report
740
- the number when you hand the milestone over.
705
+ the number when you hand the changeset over.
741
706
 
742
707
  ## 8. Make it look like someone designed it
743
708
 
744
709
  **This section numbers 8, but half of it has already happened.** Read
745
710
  `references/design.md` before the first screen is built — a design pass run on
746
- eight milestones of scaffolded screens is a repaint, and it shows. What is left
711
+ eight changesets of scaffolded screens is a repaint, and it shows. What is left
747
712
  here at §8 is the theme you may have deferred and the critique you cannot run
748
713
  until there are screens to critique.
749
714
 
@@ -849,7 +814,7 @@ problem it does not have.
849
814
 
850
815
  ## 9. Ship it, and stay Fabric-ready
851
816
 
852
- When every milestone is `built` and the scenarios are green, read
817
+ When the queue is empty, `pikku knowledge gaps` lists nothing and the scenarios are green, read
853
818
  `references/ship.md`. It carries the open-source deploy paths (`--provider
854
819
  standalone`, `cloudflare`, `aws`), how to serve several frontends behind one
855
820
  API, the pre-release gate to run, and the contract that keeps `pikku fabric init`
@@ -874,7 +839,7 @@ cheaper to honour than to retrofit:
874
839
 
875
840
  Read these when the section that names them comes up, not up front:
876
841
 
877
- - [multi-app.md](multi-app.md) — adding a second frontend (§4), at the milestone
842
+ - [multi-app.md](multi-app.md) — adding a second frontend (§4), at the changeset
878
843
  that needs it
879
844
  - [scenarios.md](scenarios.md) — writing journeys that stay proven (§7, §7a)
880
845
  - `references/design.md` — committing to a design direction, and how to tell
@@ -53,7 +53,7 @@ allowed is landing on one because it was nearest to hand.
53
53
 
54
54
  ## Offer to draw the screens before you build them
55
55
 
56
- Before the first milestone, **ask** whether they want to see the screens first.
56
+ Before the first changeset, **ask** whether they want to see the screens first.
57
57
  One question, in §1's round, not a gate of its own, with yes marked
58
58
  recommended every time:
59
59
 
@@ -120,7 +120,7 @@ Write it to `knowledge/decisions/design/screens.html` and treat it as **source o
120
120
  truth for the screens** once they approve it. That has consequences worth
121
121
  stating:
122
122
 
123
- - The milestones are read off it. A screen in the mock that no milestone builds
123
+ - The changes are read off it. A screen in the mock that no change builds
124
124
  is a gap in the plan, not a spare drawing.
125
125
  - A screen the build turns out to need that the mock does not have means the
126
126
  mock was wrong. Update it, and say you did. Do not let the app and the mock
@@ -194,14 +194,14 @@ the thing that made it is always yes. Use evidence.
194
194
  `Page.captureScreenshot`, write the PNG, and open it. Sign in the way a person
195
195
  does — click the dev actor switcher on the login page — rather than reaching
196
196
  for the secret the client uses; the UI path is shorter and it also proves the
197
- login screen works. Keep the script; you will run it at every milestone.
197
+ login screen works. Keep the script; you will run it at every changeset.
198
198
  - **Run `impeccable`** (`npx impeccable install`, Node 22.18+) and feed it the
199
199
  screenshots. It is external, it does not flatter, and it scores execution
200
200
  against interaction heuristics. But it audits how well you executed the design
201
201
  you chose — it will award a clean bill of health to a perfectly executed
202
202
  default. It checks step 2; it never replaces it.
203
- - **Look at every milestone, not once at the end.** A screen that was fine at
204
- three rows is a different screen at sixty, and the milestone that added the
203
+ - **Look at every changeset, not once at the end.** A screen that was fine at
204
+ three rows is a different screen at sixty, and the changeset that added the
205
205
  sixty is the cheapest place to notice.
206
206
 
207
207
  Questions worth answering honestly, per screen. The answers are yours; only the
@@ -245,23 +245,23 @@ uses a design system and an app that looks like one.
245
245
  The tell that you skipped this: your `components/` directory maps one-to-one onto
246
246
  your data model and contains nothing that names a *quality* of the product.
247
247
 
248
- ## Design is a gate on the milestone, not a phase at the end
248
+ ## Design is a gate on the changeset, not a phase at the end
249
249
 
250
250
  The loop that actually runs is plan, build, prove, close. Design advice that
251
251
  lives outside that loop does not run — it gets read, agreed with, and skipped,
252
- because nothing blocks on it. Milestones close on green scenarios, and scenarios
252
+ because nothing blocks on it. Changesets close on green scenarios, and scenarios
253
253
  say nothing about how anything looks.
254
254
 
255
- So put it in the loop. **A milestone is not built until its screens have been
255
+ So put it in the loop. **A changeset is not built until its screens have been
256
256
  looked at**, in the same sense that it is not built until its scenario passes:
257
257
 
258
- - Screenshot every screen the milestone touched, at both widths, with the seed
258
+ - Screenshot every screen the changeset touched, at both widths, with the seed
259
259
  in place.
260
260
  - Look at the images. Not the JSX.
261
- - Fix what they show, in this milestone, while it is one screen and not eight.
262
- - Say in the milestone note what you looked at and what you changed.
261
+ - Fix what they show, in this changeset, while it is one screen and not eight.
262
+ - Say in the `changes done --note` what you looked at and what you changed.
263
263
 
264
- A milestone closed without that is closed on a claim, not on evidence. The cost
264
+ A changeset closed without that is closed on a claim, not on evidence. The cost
265
265
  of being honest about it now is minutes; the cost at §8 is a repaint of the whole
266
266
  app, and by then the wrong register has been inherited by every screen so the
267
267
  repaint is a rewrite.
@@ -275,7 +275,7 @@ an empty state.
275
275
  This is a real and quiet failure: a list app whose seed has no list, a countdown
276
276
  whose seed has no dates, judged for weeks against its own empty state while the
277
277
  screen it was built for was never once looked at. The empty state is worth
278
- designing and is not what the milestone is about.
278
+ designing and is not what the changeset is about.
279
279
 
280
280
  Seed enough to be judged against: several rows, not three identical ones, and a
281
281
  deliberate spread of the cases the screen has to hold — a long title that wraps,
@@ -1,7 +1,7 @@
1
1
  # Adding a second frontend
2
2
 
3
3
  Read this when the split you recorded in Phase 2 is "separate apps" and you have
4
- reached the milestone that needs the second one. **Not before.** Cloning
4
+ reached the changeset that needs the second one. **Not before.** Cloning
5
5
  `apps/app` materialises a directory of copied screens; doing it during planning
6
6
  leaves `frontends` in `pikku.config.json` pointing at an app nobody has designed yet.
7
7
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  **This skill is a delta. `references/app.md` is the base — read it and follow it in
4
4
  full.** Everything there applies: knowledge base first, personas and roles,
5
- milestones planned then built one at a time, scenarios, design pass, deploy
5
+ changes grouped into changesets, planned then built one at a time, scenarios, design pass, deploy
6
6
  gates, Fabric-readiness. This file adds the surfaces that turn an app into a
7
7
  demonstration of the platform, and says where each one slots into that workflow.
8
8
 
@@ -20,13 +20,13 @@ Each surface lands with its console link, filtered by the person's level
20
20
  (SKILL.md, "Who you are talking to"): a non-technical person sees the workflow
21
21
  or agent page, never the queue, scheduler or wire pages behind it.
22
22
 
23
- Budget the extra surfaces at one milestone each. They are not free, and a
23
+ Budget the extra surfaces at one changeset each. They are not free, and a
24
24
  half-wired workflow engine is worse than no workflow engine.
25
25
 
26
26
  ## Choosing surfaces — during `references/app.md` §5 (planning)
27
27
 
28
- When you plan milestones, each surface below becomes its own milestone note in
29
- `knowledge/milestones/`, ordered after the spine it depends on.
28
+ When you file the work, each surface below becomes its own changeset, ordered
29
+ after the spine it depends on.
30
30
 
31
31
  **Five are required, and if the domain does not motivate them you chose the
32
32
  wrong domain:** workflows, schedules, queues, an AI agent, and realtime. They are
@@ -166,18 +166,18 @@ bunx --bun pikku versions init
166
166
  ```
167
167
 
168
168
  The CLI suggests this on every run of a project without it. Versioning a function
169
- contract, then changing it, is a short milestone that shows something no
169
+ contract, then changing it, is a short changeset that shows something no
170
170
  scaffold demonstrates on its own. `pikku release` derives the release version by
171
171
  comparing this build's surface against the last release, then ships it.
172
172
 
173
173
  ### Addons — `pikku-addon`
174
174
 
175
- `pikku new addon` scaffolds a publishable addon package. Worth one milestone if
175
+ `pikku new addon` scaffolds a publishable addon package. Worth one changeset if
176
176
  the domain has a piece that genuinely belongs to no single app.
177
177
 
178
178
  ## Coverage — where the bar is higher than the base workflow
179
179
 
180
- `references/app.md` §7a already has the mechanics and the per-milestone habit:
180
+ `references/app.md` §7a already has the mechanics and the per-changeset habit:
181
181
  run the server instrumented, run the scenarios against it, read
182
182
  `coverage/scenario-coverage.json`, and triage every gap as a missing scenario, a
183
183
  function that should not exist, or a documented deferral. Do all of that here.
@@ -8,7 +8,7 @@ signed-in screens in as few steps as possible.
8
8
  | Skipped | Cost |
9
9
  |---|---|
10
10
  | `knowledge/` | Another agent — or you next week — cannot resume this. Nothing records *why*. |
11
- | Milestone planning | No build order, no per-piece proof. Fine at this size, painful past it. |
11
+ | Changesets and plans | No build order, no per-piece proof. Fine at this size, painful past it. |
12
12
  | Design direction | It will look like the template. |
13
13
  | Refusal scenarios | Access control is asserted, not proven. |
14
14
 
@@ -103,7 +103,8 @@ codegen depends on; without it your first `db migrate` fails with
103
103
 
104
104
  Then, in this order — it is the order codegen depends on:
105
105
 
106
- 1. **Migration** — SQL in `db/sqlite/`, numbered on from what is there. Apply
106
+ 1. **Migration** — SQL in `db/sqlite/` (or `db/postgres/`, `db/mysql/` when
107
+ `createConfig` sets `postgresUrl` or `mysqlUrl`), numbered on from what is there. Apply
107
108
  with `bunx --bun pikku db migrate`, which regenerates the Kysely types.
108
109
  2. **Seed** — rows in `db/sqlite-dev-seed.sql`. There is no seed command:
109
110
  `bunx --bun pikku db reset` wipes, migrates and seeds in one go, and is the
@@ -226,7 +227,7 @@ bunx --bun pikku scenario run local --spawn
226
227
  Tell the user, in one short paragraph and at their level (SKILL.md, "Who you
227
228
  are talking to"), with console links rather than descriptions: what runs, what
228
229
  it is seeded with, and that this is a quick build — no knowledge base, no
229
- milestones, no design pass, access control clicked-through rather than proven.
230
+ changesets, no design pass, access control clicked-through rather than proven.
230
231
 
231
232
  **Upgrading to a real build is additive, not a rewrite.** If they want it, switch
232
233
  to `references/app.md` and do this, in order:
@@ -234,11 +235,11 @@ to `references/app.md` and do this, in order:
234
235
  1. Write `knowledge/` for what already exists — `entities/` for what you built,
235
236
  `decisions/` for what you chose silently, `questions/` for what you guessed
236
237
  at. Then `pikku knowledge index && pikku knowledge validate`.
237
- 2. Backfill a milestone note per screen you built, at `status: built`, each with
238
- its gherkin block.
238
+ 2. Backfill an entity note for each thing the app holds, so `pikku knowledge
239
+ gaps` has something to measure against.
239
240
  3. Write the refusal scenarios — the ones proving one persona cannot reach
240
241
  another's rows. This is the gap that matters most.
241
- 4. Then pick up `references/app.md` at its §4 (apps) or §5 (milestones) for
242
+ 4. Then pick up `references/app.md` at its §4 (apps) or §5 (changes) for
242
243
  anything new.
243
244
 
244
245
  Nothing built here has to be thrown away to do that — which is the whole reason