@haus-tech/haus-workflow 5.12.0 → 6.0.0
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/CHANGELOG.md +61 -0
- package/README.md +7 -4
- package/dist/cli.js +7184 -4302
- package/library/catalog/manifest.json +126 -9
- package/library/global/agents/request-design-reviewer.md +54 -0
- package/library/global/agents/request-designer.md +113 -0
- package/library/global/skills/haus-workflow/SKILL.md +7 -3
- package/library/global/skills/haus-workflow/references/init.md +7 -4
- package/library/global/skills/request/SKILL.md +487 -104
- package/library/global/skills/request/scripts/archive.mjs +697 -48
- package/library/global/skills/request/scripts/bedom.mjs +651 -0
- package/library/global/skills/request/scripts/korning.mjs +911 -70
- package/library/global/skills/request/scripts/lib.mjs +328 -3
- package/library/global/skills/request/scripts/precheck.mjs +134 -34
- package/library/global/skills/request/scripts/svep.mjs +44 -14
- package/library/global/skills/request-assess-impact/SKILL.md +1 -4
- package/library/global/skills/request-sync/SKILL.md +8 -2
- package/package.json +1 -1
|
@@ -13,19 +13,19 @@ the respective skill. Only routing, context carrying, the archive and the dispat
|
|
|
13
13
|
|
|
14
14
|
`/request [task]`: without an argument, show the menu below.
|
|
15
15
|
|
|
16
|
-
| Task
|
|
17
|
-
|
|
|
18
|
-
| `speca <request or gid>`
|
|
19
|
-
| `designa <gid, slug or nr>`
|
|
20
|
-
| `bedöm <gid, slug or nr>`
|
|
21
|
-
| `status`
|
|
22
|
-
| `godkänn <nr or gid>`
|
|
23
|
-
| `underkänn <nr or gid> <reason>`
|
|
24
|
-
| `döm <item>`
|
|
25
|
-
| `detaljer <gid, slug or nr> [step]` | Print archived JSON/documents for the item
|
|
26
|
-
| `byt titel <nr or gid>`
|
|
27
|
-
| `utvärdera <item…> <model…>`
|
|
28
|
-
| `hjälp`
|
|
16
|
+
| Task | Does |
|
|
17
|
+
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
18
|
+
| `speca <request or gid>` | Source manifest → dispatch `request-specifier` → archive spec + reviewer block |
|
|
19
|
+
| `designa <gid, slug or nr>` | Gate on `✅ Spec ok` → `superpowers:brainstorming` with the user → the design doc in the repo + `design.md` in the archive; never Asana; a clean record continues into `bedöm` |
|
|
20
|
+
| `bedöm <gid, slug or nr>` | Gate → form check → `bedom.mjs` prices (a design draft and its review in draft mode, analysis, two scorers, archive) → BLUF; with several items or none, a batch |
|
|
21
|
+
| `status` | Queue state via request-sync, BLUF table with row numbers |
|
|
22
|
+
| `godkänn <nr or gid>` | Move Offer status forward via request-sync; see the gate section |
|
|
23
|
+
| `underkänn <nr or gid> <reason>` | Reason as an Asana comment + iteration counter via request-sync |
|
|
24
|
+
| `döm <item>` | Human ruling on OLIKA: choose a run, order a rerun or reject the source material |
|
|
25
|
+
| `detaljer <gid, slug or nr> [del-N] [step]` | Print archived JSON/documents for the item, or for one split part |
|
|
26
|
+
| `byt titel <nr or gid>` | Rename the Asana task to the spec title (`state.json.title`) via request-sync, on request only |
|
|
27
|
+
| `utvärdera <item…> <model…>` | Run the flow once per named model against the experiment area, at least one model; `sammanställ` gives the sweep view, `rapport` a readable comparison |
|
|
28
|
+
| `hjälp` | Explain the tasks, touch no files |
|
|
29
29
|
|
|
30
30
|
## Hard rules
|
|
31
31
|
|
|
@@ -123,8 +123,18 @@ this skill (and the agents through their prompts) maintains it.
|
|
|
123
123
|
the same request) becomes several directories: the score is set per item, so a directory
|
|
124
124
|
with several specs cannot be assessed.
|
|
125
125
|
|
|
126
|
+
The archive root is the main checkout's `.haus-workflow/requests/`, never a worktree's
|
|
127
|
+
(ADR-0154). At the start of every task that reads or writes the archive, run
|
|
128
|
+
`node <skillkatalog>/scripts/archive.mjs rot` first and use its `ARKIVROT:` line as
|
|
129
|
+
`<arkivrot>` below; the cwd may be the main checkout or any of its worktrees.
|
|
130
|
+
`IGNORERAD: nej` stops the task before any write: name `haus apply --write` in the main
|
|
131
|
+
checkout as the fix (it writes the rule) and rerun `rot` once the user says it has run;
|
|
132
|
+
never run it yourself from this skill. `rot` refuses a bare repository, a submodule
|
|
133
|
+
checkout and a `--separate-git-dir` clone (their common dir is not named `.git`): run the
|
|
134
|
+
task from the superproject's own checkout, or from an ordinary clone.
|
|
135
|
+
|
|
126
136
|
```
|
|
127
|
-
<
|
|
137
|
+
<arkivrot>/<gid-eller-slug>/
|
|
128
138
|
├── spec.md ONE spec, byte-faithful: what the reviewer approves
|
|
129
139
|
├── granskarblock.md "## For the reviewer" (bundle: the part's own
|
|
130
140
|
│ block, never a copied one, ADR-0118)
|
|
@@ -156,7 +166,9 @@ its stop (`designa` step 5), with no runs row, since the design is no dispatch.
|
|
|
156
166
|
the line yourself, and never hand-edit the block. If the archive is still tracked in git:
|
|
157
167
|
run `haus apply --write`, which both writes the rule and untracks the files.
|
|
158
168
|
Pricing material must not enter the customer's history. `.haus-workflow/request.json` (the sync's
|
|
159
|
-
config) stays tracked: it is configuration, not working material.
|
|
169
|
+
config) stays tracked: it is configuration, not working material. It lives in the main
|
|
170
|
+
checkout and carries the board's choices (`auto_sync_spec`, ADR-0157; `design_mode`,
|
|
171
|
+
ADR-0156).
|
|
160
172
|
- **Old archive under `.haus/`:** moved by `haus apply` to
|
|
161
173
|
`.haus-workflow/` (ADR-0103). Never write to `.haus/` again, and do not move it
|
|
162
174
|
yourself: run `haus apply --write` and let the command do it.
|
|
@@ -179,6 +191,7 @@ its stop (`designa` step 5), with no runs row, since the design is no dispatch.
|
|
|
179
191
|
"respec_varv": 0,
|
|
180
192
|
"coverage_post": null,
|
|
181
193
|
"design": null,
|
|
194
|
+
"board": null,
|
|
182
195
|
"runs": []
|
|
183
196
|
}
|
|
184
197
|
```
|
|
@@ -195,15 +208,19 @@ its stop (`designa` step 5), with no runs row, since the design is no dispatch.
|
|
|
195
208
|
strings); `nasta-steg` and `bluf` refuse a split whose parts disagree on `of` or carry a
|
|
196
209
|
non-integer `of`.
|
|
197
210
|
- `stopp` = a stop outcome that the scripts have proven without a scorer:
|
|
198
|
-
`{ "utfall": "KONCEPT" | "DIAGNOS" | "TILLBAKA_TILL_SPEC" | "ESKALERA", "kalla": "spec.md" | "impact.md" | "granskarblock.md" | "design-avvisad-<datum>.md", "date": "YYYY-MM-DD", "orsak"?: string }`,
|
|
199
|
-
|
|
211
|
+
`{ "utfall": "KONCEPT" | "DIAGNOS" | "TILLBAKA_TILL_SPEC" | "ESKALERA", "kalla": "spec.md" | "impact.md" | "granskarblock.md" | "design-avvisad-<datum>.md" | "design-intervju-kravs-<datum>.md", "date": "YYYY-MM-DD", "orsak"?: string }`,
|
|
212
|
+
`design-avvisad-<datum>.md` for a design refused on `## Spec conflicts` (`designa` step 5),
|
|
213
|
+
`design-intervju-kravs-<datum>.md` for the designer's `INTERVJU KRÄVS` in draft mode
|
|
214
|
+
(always ESKALERA; `add-design` clears it, since `designa` answers it).
|
|
200
215
|
Written ONLY by `archive.mjs stopp` (which itself checks that the source carries
|
|
201
216
|
what is claimed: the candidate marker in `spec.md`, the label `contradiction` in
|
|
202
217
|
`impact.md`, the price-decisive open choice in `granskarblock.md`, ADR-0118, at
|
|
203
|
-
least one conflict under `## Spec conflicts` in `design-avvisad-<datum>.md
|
|
218
|
+
least one conflict under `## Spec conflicts` in `design-avvisad-<datum>.md`, a first line
|
|
219
|
+
`INTERVJU KRÄVS: <reason>` in `design-intervju-kravs-<datum>.md`).
|
|
204
220
|
`add-design` clears a design-conflict stop (`kalla` `impact.md`, `orsak`
|
|
205
221
|
`design conflict: …`) and supersedes the analysis it came from (`impact.md` →
|
|
206
|
-
`impact-superseded-<datum>.md`), or a receipt replaces it (`designa` step 5);
|
|
222
|
+
`impact-superseded-<datum>.md`), or a receipt replaces it (`designa` step 5); it also
|
|
223
|
+
clears a stop from `design-intervju-kravs-<datum>.md`, which only a design answers; every
|
|
207
224
|
other stop is reset ONLY by `archive.mjs respec`.
|
|
208
225
|
`orsak` is set when `utfall` is `ESKALERA` (the command requires `--orsak` then,
|
|
209
226
|
so a human sees why the item did not go back to the spec once more) and for the
|
|
@@ -220,7 +237,8 @@ its stop (`designa` step 5), with no runs row, since the design is no dispatch.
|
|
|
220
237
|
lack the field and are read as `0`.
|
|
221
238
|
- `coverage_post` mirrors the score envelope's optional `coverage_post: { yta, omfattning }`
|
|
222
239
|
(ADR-0119). `archive.mjs add-run` copies the field from the
|
|
223
|
-
latest pricing file that carries it
|
|
240
|
+
latest main pricing file (no suffix) that carries it; a `-run2` or `-avvisad`
|
|
241
|
+
file never sets it, whatever the stamping order. The skeleton (`ny-korning`/`ny-del`) sets
|
|
224
242
|
it to `null`. `bluf` shows `täckningspost: <yta>` in the `anm` column when
|
|
225
243
|
the field is set.
|
|
226
244
|
- `design` is written ONLY by `archive.mjs add-design` and reset ONLY by
|
|
@@ -231,7 +249,23 @@ its stop (`designa` step 5), with no runs row, since the design is no dispatch.
|
|
|
231
249
|
`add-design` writes no runs row: `runs[]` records dispatches and the design is not
|
|
232
250
|
one; the receipt is the field itself, write-once per version (a new design puts the
|
|
233
251
|
old copy aside as `design-superseded-<datum>.md`). Older archives lack the field
|
|
234
|
-
and are read as `null`.
|
|
252
|
+
and are read as `null`. The field may also carry
|
|
253
|
+
`review` = `{ verdict, sha256, date, model }`, written ONLY by `archive.mjs add-design-review`
|
|
254
|
+
(the second reader's verdict on a draft), reset by `add-design` and `respec`
|
|
255
|
+
(both put `design-review.md` aside as `design-review-superseded-<datum>.md`);
|
|
256
|
+
`precheck --design` refuses to price a `stopp`. Whether the design is a draft is read
|
|
257
|
+
from `mode: draft` in `design.md`'s frontmatter, never from `state.json` (ADR-0156).
|
|
258
|
+
- `board` is the receipt of the last Offer status move this flow recorded: speca step 7, bedöm step 8 (on a split root, the move of the parent) and `underkänn`; `godkänn` and `byt titel` record none. Form `{ "offer_status": "<value>", "date": "YYYY-MM-DD" }`, written ONLY by `archive.mjs synced` and reset to `null` by `archive.mjs respec` and by `add-run` on a round's main pricing file. On a split root it is the receipt of the sync that moved the parent; `respec` or a new round's main pricing file on one of its parts resets the root's receipt too; a cache note, never the truth (Hard rules).
|
|
259
|
+
- `korning` = the running receipt `{ "pid": <heltal>, "started": "<ISO>", "katalog": "<abs>|null" }`
|
|
260
|
+
or `null`: written ONLY by `archive.mjs korning-start` (under the archive lock; it
|
|
261
|
+
refuses a living pid, so two starters never price the same item) and cleared ONLY by
|
|
262
|
+
`archive.mjs korning-slut`. `nasta-steg` writes `pågår (pid N)` while the pid lives and
|
|
263
|
+
`avbruten körning` when it is dead; the next `korning-start` takes a dead pid over;
|
|
264
|
+
`respec` refuses while a pid lives. Older archives lack the field and are read as
|
|
265
|
+
`null` (ADR-0155).
|
|
266
|
+
- a runs row may carry `repo_sha`, the `HEAD` of the checkout the assessor read, written
|
|
267
|
+
by `korning.mjs` through `add-run --repo-sha` on `impact.md` rows; absent on older rows
|
|
268
|
+
and on rows the main conversation stamps (ADR-0155).
|
|
235
269
|
- `umbrella` is written ONLY by `archive.mjs paraply` (ADR-0144):
|
|
236
270
|
`{ "date": "YYYY-MM-DD", "sha256": "<marker-stripped hash of the umbrella spec.md>" }`,
|
|
237
271
|
the receipt that the parent's `spec.md` was rewritten one level up after a split.
|
|
@@ -239,7 +273,7 @@ its stop (`designa` step 5), with no runs row, since the design is no dispatch.
|
|
|
239
273
|
parts keep their inherited copies of it. `paraply` also sets `title` from the umbrella's
|
|
240
274
|
heading; approval, design, runs, stops and the parts are untouched. The field is absent
|
|
241
275
|
until `paraply` writes it and is never reset.
|
|
242
|
-
- `approval` is written by the gate in `designa` or `bedöm
|
|
276
|
+
- `approval` is written ONLY by `archive.mjs approve`, run by the gate in `designa` or `bedöm` after it has read the board, and copied unchanged into a new split part by `archive.mjs ny-del` (the part inherits the approved spec, ADR-0144):
|
|
243
277
|
`{ "source": "asana" | "manual", "by": "<namn, krävs vid manual>",
|
|
244
278
|
"status_read": "<värde>", "date": "YYYY-MM-DD" }`.
|
|
245
279
|
The note is traceability, never the approval itself.
|
|
@@ -321,7 +355,7 @@ its stop (`designa` step 5), with no runs row, since the design is no dispatch.
|
|
|
321
355
|
Model runs from `utvärdera` live in a tree of their own and are never pricing items:
|
|
322
356
|
|
|
323
357
|
```
|
|
324
|
-
<
|
|
358
|
+
<arkivrot>/experiments/<slug>/
|
|
325
359
|
├── experiment.json ticket reference, date, model list, manifest hash,
|
|
326
360
|
│ status per run
|
|
327
361
|
├── <modell>/ `default` as the model value gives the directory name
|
|
@@ -403,6 +437,8 @@ Model runs from `utvärdera` live in a tree of their own and are never pricing i
|
|
|
403
437
|
the heading skeleton in `RUBRIKER:` follows that language, see the prompt template) and
|
|
404
438
|
`DEPS:` (`installerade` when `node_modules/` or equivalent exists under
|
|
405
439
|
REPO-ROT, otherwise `saknas`; without a repo always `saknas`).
|
|
440
|
+
`REPO-ROT:` is the checkout whose code is read; it is not the archive root, which
|
|
441
|
+
`rot` gives.
|
|
406
442
|
Write the manifest to `<katalog>/kallmanifest.md` in every directory the spec
|
|
407
443
|
is archived in (step 5), so that `bedöm` can give the assessor the same manifest without
|
|
408
444
|
building a new one. The manifest's first line is `SPRÅK: <svenska|engelska>`,
|
|
@@ -490,7 +526,13 @@ på request-write-spec/references/specformat.md>`. The script sets
|
|
|
490
526
|
stop nothing.
|
|
491
527
|
7. **Reply BLUF:** one line per spec (heading + any flags), then the reviewer block
|
|
492
528
|
in its entirety. Offer to place the specs on the board via request-sync (🔍); do
|
|
493
|
-
it only on explicit request
|
|
529
|
+
it only on explicit request when the main checkout's `.haus-workflow/request.json`
|
|
530
|
+
(`ARKIVROT:`'s parent) carries `auto_sync_spec: false`; otherwise (`true` or absent,
|
|
531
|
+
ADR-0157) place every spec of this round that passed the form check in step 6 on the board now, in this turn, in the
|
|
532
|
+
main conversation, one item at a time through request-sync's ordinary spec sync (the
|
|
533
|
+
Decision read, the read-back, the three automatic rename cases are request-sync's and do
|
|
534
|
+
not change), a candidate included (the customer dialogue is its next step), a spec with a BRIST or a standing stop (`PRISAVGORANDE`, ADR-0118) never, it waits for `synka` as today. The ⚖️ sync is not covered: it waits for `synka` (`bedöm` step 8, ADR-0155).
|
|
535
|
+
Placing a spec on the board is no rename: request-sync
|
|
494
536
|
renames the task to the spec title by itself only in the three automatic cases
|
|
495
537
|
(ADR-0144): the task name is empty, `Original request title` is empty, or the task is
|
|
496
538
|
one of several minted from one source. In the Closing, under the board line,
|
|
@@ -498,30 +540,49 @@ på request-write-spec/references/specformat.md>`. The script sets
|
|
|
498
540
|
title and `byt titel <item>` is the optional next action. When an item is placed on the board: set status
|
|
499
541
|
`spec_synced`, rename the slug directory to the minted gid, note the slug
|
|
500
542
|
in `former_slug` and update `request_id` in `state.json`.
|
|
543
|
+
Then record the write: `node <skillkatalog>/scripts/archive.mjs synced <katalog> --offer-status "<the status request-sync set>"`.
|
|
501
544
|
**Close per `## Closing: where the item stands`** (the table from
|
|
502
|
-
`archive.mjs nasta-steg`, the board line, the ISÄR check
|
|
545
|
+
`archive.mjs nasta-steg`, the board line, the ISÄR check, and the wrap-up lines at a
|
|
546
|
+
resting point), never without.
|
|
503
547
|
|
|
504
548
|
## Task: `designa`
|
|
505
549
|
|
|
506
550
|
Runs the design leg: brainstorming with the user against the approved spec, the
|
|
507
551
|
design doc saved in the customer repo and recorded in the archive. Runs in the main
|
|
508
552
|
conversation (the brainstorming skill asks the user questions), in a session whose cwd
|
|
509
|
-
is the customer repo. Nothing here touches Asana: the design is internal source
|
|
553
|
+
is the customer repo or one of its worktrees (the archive root comes from `rot`). Nothing here touches Asana: the design is internal source
|
|
510
554
|
material for `bedöm`'s assessor and never reaches the board.
|
|
511
555
|
|
|
556
|
+
**Draft mode (ADR-0156).** When `.haus-workflow/request.json` in the main checkout carries
|
|
557
|
+
`design_mode: draft`, an approved item without a design is designed by the machine inside
|
|
558
|
+
`bedöm`: `bedom.mjs` passes the mode on, `korning.mjs` dispatches `request-designer` (opus),
|
|
559
|
+
records the doc with `add-design`, has `request-design-reviewer` (fable) read it, and goes on
|
|
560
|
+
to the analysis only on `VERDICT: fortsätt`. `designa <item>` is still the interactive path
|
|
561
|
+
in both modes and supersedes a draft. A draft carries `mode: draft` in its frontmatter and
|
|
562
|
+
three sections the interactive doc may omit: `## Assumptions` (every HOW question the machine
|
|
563
|
+
answered, the option taken, the options not taken), `## Removed or renamed` (every symbol
|
|
564
|
+
the design deletes or renames; `precheck --design` and `add-design` grep each one outside
|
|
565
|
+
the files under `## Files touched`, a hit refuses the record) and `## Files touched`. An
|
|
566
|
+
architectural item comes back as `intervju krävs` with the receipt
|
|
567
|
+
`design-intervju-kravs-<datum>.md` and an ESKALERA stop that `designa` clears, and a reviewer
|
|
568
|
+
`stopp` leaves the item `designed` with `design-review.md` in the archive; both route here,
|
|
569
|
+
to the interview.
|
|
570
|
+
|
|
512
571
|
1. **Gate. Identical to `bedöm` step 1.** Read Offer status via request-sync in the
|
|
513
572
|
main conversation immediately before the run. Only `✅ Spec ok` (normalized on the
|
|
514
573
|
alphabetic core) lets it through. An item without a gid follows `bedöm`'s rules for
|
|
515
574
|
that case (refuse when the repo has `.haus-workflow/request.json`, otherwise the
|
|
516
575
|
explicit "approved by whom" question). An item with a gid but no local archive
|
|
517
|
-
directory: not supported, say so and stop.
|
|
518
|
-
`
|
|
576
|
+
directory: not supported, say so and stop. Record the passed gate with
|
|
577
|
+
`archive.mjs approve` exactly as `bedöm` does; a later `bedöm` rereads the board.
|
|
519
578
|
2. **Form check.** Run `node <skillkatalog>/scripts/precheck.mjs <katalog>`. A
|
|
520
579
|
`KANDIDAT:` line or a standing `stopp` means the item is not ready for a design,
|
|
521
580
|
with one exception: a stop from `impact.md` whose `orsak` starts with
|
|
522
581
|
`design conflict:` (the assessor found the design unbuildable) is exactly what a
|
|
523
582
|
redesign answers, continue to step 3; `add-design` clears that stop and puts the
|
|
524
583
|
old analysis aside as `impact-superseded-<datum>.md` when it records the redesign.
|
|
584
|
+
The same holds for an ESKALERA stop from `design-intervju-kravs-<datum>.md` (the
|
|
585
|
+
designer asked for this interview): continue, `add-design` clears it.
|
|
525
586
|
Any other such line or stop: route it as the stop outcome (see `bedöm`) and stop. A
|
|
526
587
|
`spec.md` with more than one spec block is a BRIST, as in `bedöm`. Other BRISTER:
|
|
527
588
|
fix the link that is defective before anything is designed.
|
|
@@ -530,8 +591,9 @@ material for `bedöm`'s assessor and never reaches the board.
|
|
|
530
591
|
Otherwise, if `state.json.design` is set, run
|
|
531
592
|
`node <skillkatalog>/scripts/precheck.mjs <katalog> --design`. Three branches:
|
|
532
593
|
(a) it passes (the hash still matches `design.md` and the canonical file): ask ONE
|
|
533
|
-
question via AskUserQuestion: keep it, or redesign. Keep:
|
|
534
|
-
a new brainstorming
|
|
594
|
+
question via AskUserQuestion: keep it, or redesign. Keep: continue per step 6 without
|
|
595
|
+
a new brainstorming; a kept design that passed `precheck --design` continues into
|
|
596
|
+
`bedöm` the same way a fresh record does. Redesign: continue; `add-design` supersedes the old one
|
|
535
597
|
(`design-superseded-<datum>.md`), it never overwrites.
|
|
536
598
|
(b) its only design BRISTER are the hash lines
|
|
537
599
|
(`design.md: hashen är inte state.design.sha256 …` and/or
|
|
@@ -604,12 +666,7 @@ material for `bedöm`'s assessor and never reaches the board.
|
|
|
604
666
|
item's state (status `priced` or `guard_run`, a standing stop other than a design
|
|
605
667
|
conflict) is not fixed in the doc: `respec`, or decide the stop first.
|
|
606
668
|
|
|
607
|
-
6. **Reply BLUF:** one line per item (the design's title and path), the
|
|
608
|
-
`## Spec conflicts` section verbatim when it is not `none`, the commit offer, then
|
|
609
|
-
**Close per `## Closing: where the item stands`** (the table from
|
|
610
|
-
`archive.mjs nasta-steg`, the board line, the ISÄR check), never without. For a doc
|
|
611
|
-
refused on conflicts, the Closing's part 4 presents the conflicts as the choice
|
|
612
|
-
(`## Avgjorda val`, `respec`, `speca <adress>`).
|
|
669
|
+
6. **Continue into `bedöm`, or close.** When `add-design` recorded the doc, `precheck --design` wrote no BRIST and `## Spec conflicts` is `none`, run `bedöm <adress>` now, in the same turn, from its step 1 (the gate is reread from the board; the design is internal, so nothing reaches the customer before `bedöm`'s own sync rule, ADR-0153): the turn then ends with `bedöm`'s BLUF and Closing, never with a second block. If `bedöm` stops before its step 8 (its gate, a candidate, a contradiction), its Closing still carries the design doc's path and the commit offer. VARNING lines stop nothing: the chain runs. In every other case (a refused doc, a BRIST, an interview that ended without a file), **Reply BLUF:** one line per item (the design's title and path), the `## Spec conflicts` section verbatim when it is not `none`, the commit offer, then **Close per `## Closing: where the item stands`** (the table from `archive.mjs nasta-steg`, the board line, the ISÄR check), never without. For a doc refused on conflicts, the Closing's part 4 presents the conflicts as the choice (`## Avgjorda val`, `respec`, `speca <adress>`).
|
|
613
670
|
|
|
614
671
|
## Task: `bedöm`
|
|
615
672
|
|
|
@@ -634,7 +691,10 @@ drift guard.
|
|
|
634
691
|
- **The item has a gid but lacks a local archive directory:** not supported yet
|
|
635
692
|
(hydration from the board comes with the batch step); say so and stop;
|
|
636
693
|
the reviewer block cannot be recreated from Asana.
|
|
637
|
-
-
|
|
694
|
+
- Record the passed gate with
|
|
695
|
+
`node <skillkatalog>/scripts/archive.mjs approve <katalog> --source asana --status "<Offer status as read>"`
|
|
696
|
+
(the manual case: `--source manual --by <name>`); the script refuses any status
|
|
697
|
+
other than ✅ Spec ok, so a gate that was not read cannot be noted.
|
|
638
698
|
The next `bedöm` reads the status again.
|
|
639
699
|
- **Gate 1b, the design (only when the assessor is to be dispatched).** When
|
|
640
700
|
`impact.md` is missing, or precheck rejects it on source-material provenance
|
|
@@ -647,6 +707,15 @@ drift guard.
|
|
|
647
707
|
with one exception: a split part (`state.split.parent` set) is not gated, the
|
|
648
708
|
split copied the parent's `design.md` into it, and the assessor gets it as the
|
|
649
709
|
`DESIGN` block.
|
|
710
|
+
In draft mode (`design_mode: draft` in `.haus-workflow/request.json` in the main
|
|
711
|
+
checkout, ADR-0156), an item whose only design lines are the no-design signature,
|
|
712
|
+
`DESIGN: saknas` and the two BRISTER `design.md: saknas` and
|
|
713
|
+
`state.json: fältet "design" är null`, is not refused: it goes on to step 2, and
|
|
714
|
+
`bedom.mjs` has the design drafted and reviewed before the analysis (`designa`, Draft
|
|
715
|
+
mode). A recorded design is gated as above in both modes, a draft included: an
|
|
716
|
+
interactive doc without the draft sections passes with VARNING lines only, and a
|
|
717
|
+
stopped review (`designgranskningen stoppade utkastet`) is a BRIST whose way on is
|
|
718
|
+
`designa <adress>`.
|
|
650
719
|
2. **Form check.** Run `node <skillkatalog>/scripts/precheck.mjs <katalog> --impact`
|
|
651
720
|
(without `--impact` if the analysis does not exist yet). A `spec.md` with more than one
|
|
652
721
|
spec block is a BRIST: split the item per the archive rule before anything is dispatched.
|
|
@@ -660,6 +729,37 @@ drift guard.
|
|
|
660
729
|
an identical repeat call is harmless), and route the item as the stop outcome
|
|
661
730
|
below. No analysis and no score may ever be dispatched on a
|
|
662
731
|
candidate.
|
|
732
|
+
|
|
733
|
+
**Steps 3 to 7 run as ONE process in production (ADR-0155).** After step 2 has passed,
|
|
734
|
+
run `node <skillkatalog>/scripts/bedom.mjs --repo-rot <abs> --arkiv <arkivrot> --post <gid>`
|
|
735
|
+
as a background process and wait for its exit: it starts `korning.mjs` in production mode
|
|
736
|
+
on the item directory, which runs the analysis when it is missing or stale, the two
|
|
737
|
+
scorers at once, `kontroll.mjs`, `compare-scores.mjs` and the archiving through
|
|
738
|
+
`archive.mjs`, exactly as steps 3 to 7 describe; those steps are the contract the script
|
|
739
|
+
implements and its tests pin, not instructions for the main conversation, which
|
|
740
|
+
dispatches no agent and runs no check in this leg. `--repo-rot` is the checkout whose
|
|
741
|
+
code the assessor reads (the session's cwd; a worktree is fine) and `--arkiv` is
|
|
742
|
+
`ARKIVROT:` from `rot`. The starter writes the running receipt (`archive.mjs korning-start`,
|
|
743
|
+
`state.korning`) before the process starts and clears it after
|
|
744
|
+
(`korning-slut`), skips an item whose receipt carries a living pid (`pågår`), and stops
|
|
745
|
+
starting items when the batch's cost reaches `max_usd_per_batch` in
|
|
746
|
+
`.haus-workflow/request.json` (default 100 USD; `--max-usd` overrides one run), counting an
|
|
747
|
+
item in flight at the average of the finished ones. Read its
|
|
748
|
+
final table (`| post | status | poäng | utfall | wall | USD |`), paste it under the BLUF
|
|
749
|
+
in step 8, and route every row by its status: `priced` goes on to step 8, `stopp` and
|
|
750
|
+
`väntar på dom` take the stop and OLIKA routing below, `ofärdig` shows the reason from
|
|
751
|
+
the table and `<post>/korningar/<körning>/stderr.log`, `grind` and `tak nått` show the
|
|
752
|
+
reason and stop, and a `pågår` row is left alone.
|
|
753
|
+
`bedom.mjs` passes the board's design mode on to `korning.mjs` as `--design-mode`
|
|
754
|
+
(`design_mode` in `.haus-workflow/request.json`; `interview` and an absent key read as
|
|
755
|
+
`intervju`; the flag overrides one run). In draft mode the process drafts a missing design
|
|
756
|
+
(`request-designer`, recorded with `add-design`) and has `request-design-reviewer` read it
|
|
757
|
+
before the analysis (ADR-0156); the verdict is a judgment and is never redispatched. A
|
|
758
|
+
`stopp` row whose reason starts with `intervju krävs:` (the stop from
|
|
759
|
+
`design-intervju-kravs-<datum>.md`) or reads `designgranskningen stoppade (design-review.md)`
|
|
760
|
+
routes to `designa <adress>`, the interview. Commit nothing in `--repo-rot` while
|
|
761
|
+
the process runs: the impact row records the `HEAD` the assessor read (`repo_sha`).
|
|
762
|
+
|
|
663
763
|
3. **Analysis.** If `impact.md` is missing, or precheck rejects it on
|
|
664
764
|
source-material provenance (the analysis was made against another spec or another design): this requires a repo in
|
|
665
765
|
the session (otherwise stop: a guessed analysis is forbidden by the skill itself).
|
|
@@ -692,9 +792,10 @@ drift guard.
|
|
|
692
792
|
(the command sets status `assessed`), skip steps 4 to 7 and route
|
|
693
793
|
the item as the stop outcome below: no scorer is dispatched on source material
|
|
694
794
|
that already says the spec must go back. When the deviation line's text after the
|
|
695
|
-
label starts with `design conflict:`,
|
|
696
|
-
|
|
697
|
-
|
|
795
|
+
label starts with `design conflict:`, the command reads that text from `impact.md` as
|
|
796
|
+
the stop's `orsak` (#595; an `--orsak` that contradicts the file is refused, exit 2):
|
|
797
|
+
the item goes back to the design, not to the spec, and the Closing routes it to
|
|
798
|
+
`designa <adress>` (a redesign clears the stop, see `add-design`). `ingen` and `precisering` go
|
|
698
799
|
on to step 4. If precheck rejects the new
|
|
699
800
|
draft → redispatch the assessor ONCE per the redispatch rule, and give
|
|
700
801
|
the rejected draft a receipt exactly as in speca step 6: archive it as
|
|
@@ -718,8 +819,12 @@ drift guard.
|
|
|
718
819
|
`resolve-anchors.mjs` (evidence anchors to verbatim source blocks;
|
|
719
820
|
OLÖST/FLERTYDIG is a contract breach) and contract-check in one process; a
|
|
720
821
|
protocol-term breach in a pure customer-text field is rewritten by a cheap model
|
|
721
|
-
instead of costing a new scorer run. The `REPARERAT:` lines are
|
|
722
|
-
the BLUF reply
|
|
822
|
+
instead of costing a new scorer run. The `REPARERAT:` lines are written into the runs
|
|
823
|
+
row's `--note`, never pasted into the chat; the BLUF reply mentions a repair in plain
|
|
824
|
+
words only when it matters to the reviewer (`## Reply wording`). A runs row takes ONE
|
|
825
|
+
`--note` (`add-run` reads only the first): when step 6 adds comparison rows to the same
|
|
826
|
+
row, pass both in one value joined with `; `, each repair line prefixed `reparerat: `
|
|
827
|
+
(the form `korning.mjs` writes).
|
|
723
828
|
`impact.md` is ALWAYS sent to contract-check, never only the spec:
|
|
724
829
|
the script reads the label on `**Deviation from the spec:**` and rejects every
|
|
725
830
|
outcome other than TILLBAKA_TILL_SPEC when the analysis carries `contradiction`
|
|
@@ -727,11 +832,13 @@ drift guard.
|
|
|
727
832
|
has still reached this point has source material the script must get to see). The same script requires
|
|
728
833
|
every `bracket.steps[i]` to be exactly `{anchor, relation, grund}`.
|
|
729
834
|
BROTT that remain after the repairs → redispatch ONCE per
|
|
730
|
-
the redispatch rule, with the error lines in the prompt. If breaches remain:
|
|
731
|
-
|
|
835
|
+
the redispatch rule, with the error lines in the prompt. If breaches remain: stop
|
|
836
|
+
without archiving the reply as a valid round, but do not throw it away:
|
|
732
837
|
archive it as `score-pricing-vN-avvisad.json` (outside the N count) with
|
|
733
838
|
the check's error lines in a runs row, so even failed runs have a
|
|
734
|
-
receipt.
|
|
839
|
+
receipt. Tell the user in plain words that the scoring failed an automatic check
|
|
840
|
+
twice and was not counted (`## Reply wording`). An `AVVIKELSE:` line is always
|
|
841
|
+
reported to the user, as what the scorer flagged, in plain words (`## Reply wording`).
|
|
735
842
|
6. **Double run (drift guard).** Run 2 ALWAYS starts at the same time as
|
|
736
843
|
run 1, with the same prompt and in a new isolated run; in production
|
|
737
844
|
both Agent calls are dispatched at once (#500, ADR-0113), the prompts are
|
|
@@ -765,13 +872,18 @@ drift guard.
|
|
|
765
872
|
rows `double_run: "olika"` with `superseded_by: null`).
|
|
766
873
|
Status `assessed`. No customer text may go to
|
|
767
874
|
request-sync while the hold stands (`archive.mjs sparr` is the interpreter).
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
875
|
+
Describe in the BLUF reply the evidence behind the disagreement, per
|
|
876
|
+
`## Reply wording`: first one sentence on what the runs disagree on (the price,
|
|
877
|
+
the conditions, what is priced, how the work compares with the reference
|
|
878
|
+
assignments; two runs can disagree at the same score), then for each run, one or
|
|
879
|
+
two sentences on where it landed and
|
|
880
|
+
what it leaned on, built from all of its `drivers[].citat`/`pastaende` (the
|
|
881
|
+
diff rows have no row link to the evidence, `drivers[]` is a list of its own),
|
|
882
|
+
quoting the source text where it decides. It was the evidence that decided the
|
|
883
|
+
ruling in every measured genuine disagreement. Never paste the diff rows:
|
|
884
|
+
the diff rows go into run 1's runs row `--note`, so `detaljer <item> state` shows
|
|
885
|
+
them. Then refer to `döm <item>` and STOP: no rerun, no escalation, no choice
|
|
886
|
+
of run.
|
|
775
887
|
- **LIKA_TOLERANS** (a score difference ≤ 0.5 with the same outcome, regardless of
|
|
776
888
|
confidence, a confidence difference alone never rejects a pair within
|
|
777
889
|
the tolerance) → the pair counts as confirmed. The run the verdict line points out
|
|
@@ -782,7 +894,12 @@ drift guard.
|
|
|
782
894
|
the difference lies within the tolerance. Set `double_run: "tolerans"` on
|
|
783
895
|
both runs rows. The tolerance is a deliberate pricing rule: the highest
|
|
784
896
|
value protects the margin, and an average is still never
|
|
785
|
-
computed.
|
|
897
|
+
computed. Write the tolerance rows into the main file's runs row `--note`, so
|
|
898
|
+
`detaljer <item> state` shows them, and say in the BLUF reply, per
|
|
899
|
+
`## Reply wording`, that the two scorings landed close and which score applies;
|
|
900
|
+
a row that shows something only one run found (an alternative, a different type)
|
|
901
|
+
is told in a sentence too.
|
|
902
|
+
A pair of two
|
|
786
903
|
`OVER_SKALAN` with the SAME floor where only the confidence differs
|
|
787
904
|
also writes `LIKA_TOLERANS`, but with no score to compare (OVER_SKALAN carries
|
|
788
905
|
`score: null`) run 1 wins deterministically, never "the highest
|
|
@@ -822,16 +939,34 @@ ref-hash.mjs på request-score/references/poangskala.md>
|
|
|
822
939
|
as it is (`| post | poäng | utfall | konfidens | anm |`, one row per
|
|
823
940
|
directory and part; the score from the files, stop outcomes from `stopp`, OLIKA and
|
|
824
941
|
tolerance in `anm`), NEVER handwritten: a handwritten table
|
|
825
|
-
misreported in a live run.
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
942
|
+
misreported in a live run. When the item's design is a draft (the first line of
|
|
943
|
+
`archive.mjs antaganden <katalog>` reads `Designläge: draft`), paste
|
|
944
|
+
`node <skillkatalog>/scripts/archive.mjs antaganden <katalog>` under the BLUF as it is: every
|
|
945
|
+
question the machine answered with the option taken and the options not taken, the review
|
|
946
|
+
verdict and the spec conflicts; this is the human's reading before `synka`, never
|
|
947
|
+
handwritten. Under the table, one plain sentence per deviation
|
|
948
|
+
worth seeing (an escalation, a split, missing input, something the scorer
|
|
949
|
+
flagged), per `## Reply wording`. The JSON is not shown in the chat:
|
|
950
|
+
`detaljer <item>` does that. When `bedöm` was entered from `designa` (designa step 6), the BLUF also carries the design doc's path and the commit offer `designa` would have printed. Writing back to the board happens via request-sync
|
|
829
951
|
in the main conversation, only on explicit request, and it is that move
|
|
830
952
|
that takes the item ✅ Spec ok → ⚖️ Poängsättning redo för granskning per
|
|
831
|
-
the sync's rules. **Close per `## Closing: where the item stands`**
|
|
953
|
+
the sync's rules. Then record the write: `node <skillkatalog>/scripts/archive.mjs synced <katalog> --offer-status "<the status request-sync set>"` (not on a split part, whose receipt is `set-split-gid`; on the split root, in the run that moves the parent). **Close per `## Closing: where the item stands`**
|
|
832
954
|
(the table from `archive.mjs nasta-steg`, the board line, the ISÄR check, and
|
|
833
955
|
a stop outcome or OLIKA as a choice the user must make; a `DELA_UPP` as the two
|
|
834
|
-
separate choices in the routing below), never without.
|
|
956
|
+
separate choices in the routing below; the wrap-up lines at a resting point), never without.
|
|
957
|
+
|
|
958
|
+
**Several items in one `bedöm`.** `bedöm` with several items, or with none, is a batch:
|
|
959
|
+
with none, the candidates are every item at ✅ Spec ok in request-sync's queue reading
|
|
960
|
+
(as `status`) that has an archive directory. A split root is left out: its parts are priced
|
|
961
|
+
one by one (`<gid>/del-N`) and the parent moves when the last part is in (the routing below).
|
|
962
|
+
Steps 1 and 2 run per item in the main
|
|
963
|
+
conversation (one request-sync read and one `approve` each; an item that fails its gate
|
|
964
|
+
or form check is listed with the reason and left out), then ONE `bedom.mjs` with one
|
|
965
|
+
`--post` per item that passed (two at a time, `--parallellt 2`), then step 8 per item in
|
|
966
|
+
one reply, each with its own `bluf` and `nasta-steg` tables and the starter's USD column.
|
|
967
|
+
The ⚖️ sync still waits for `synka`, the user's explicit request to publish the score (step
|
|
968
|
+
8, in any wording; ADR-0155): after a batch, that request publishes every `priced` item in turn, one request-sync write and one `synced` receipt at a time, never
|
|
969
|
+
in parallel.
|
|
835
970
|
|
|
836
971
|
**Stop outcomes are routed, never interpreted.** A stop outcome is archived as the round's
|
|
837
972
|
file (step 7), the status becomes `assessed`, never `priced`, and the item is routed:
|
|
@@ -839,9 +974,14 @@ file (step 7), the status becomes `assessed`, never `priced`, and the item is ro
|
|
|
839
974
|
- `DELA_UPP` → the Closing offers two separate yes/no choices (ADR-0144), each answered on its own:
|
|
840
975
|
1. **Split the item** (as before): a new analysis round per part; the parts become
|
|
841
976
|
directories of their own, `del-1/ … del-M/` under the parent's directory, with `split`
|
|
842
|
-
set (`parent`/`part`/`of`), each
|
|
843
|
-
|
|
844
|
-
|
|
977
|
+
set (`parent`/`part`/`of`), each created with
|
|
978
|
+
`node <skillkatalog>/scripts/archive.mjs ny-del <förälderns katalog> --typ split --part N --of M`,
|
|
979
|
+
never a hand-written `state.json`: under a real item at the scorer's `DELA_UPP` it
|
|
980
|
+
writes a production part (no `experiment` marker, `split.parent` the parent's gid or,
|
|
981
|
+
without one, its directory name, the parent's `approval` inherited, `part`/`of`
|
|
982
|
+
integers checked against the siblings under the parent's lock; `--request-id` is
|
|
983
|
+
optional there and must match the parent) and refuses anything else, exit 2; under
|
|
984
|
+
an experiment directory it stays the experiment's command. A part without a ceiling becomes `OVER_SKALAN`,
|
|
845
985
|
never DELA_UPP again. Sub-items inherit, per the skill, the item's spec and never write
|
|
846
986
|
one of their own: the parent's `spec.md`, `granskarblock.md` and `design.md` are COPIED
|
|
847
987
|
unchanged into each part directory, separately (one reviewer block per part directory,
|
|
@@ -927,14 +1067,20 @@ get wrong:
|
|
|
927
1067
|
- **`underkänn <nr|gid> <reason>`:** the reason is mandatory: without a reason, ask
|
|
928
1068
|
for it. request-sync adds the reason as a comment on the item, raises
|
|
929
1069
|
the iteration counter and moves the status backward per its backward-move rules.
|
|
1070
|
+
When the move was from ⚖️, request-sync reports it done and the item has an archive
|
|
1071
|
+
directory, record the move: `node <skillkatalog>/scripts/archive.mjs synced <katalog> --offer-status "<the status request-sync set>"`
|
|
1072
|
+
(not on a split part, whose receipt is `split.gid`), so `nasta-steg` stops calling the
|
|
1073
|
+
⚖️ sync done. A refused move records nothing. `godkänn` records no receipt, and `byt titel` moves no status, so neither writes one.
|
|
930
1074
|
- **An item without a board** (archive only): `godkänn` notes
|
|
931
|
-
`approval: {source: "manual", date}` in `state.json`
|
|
1075
|
+
`approval: {source: "manual", by, date}` in `state.json` through
|
|
1076
|
+
`archive.mjs approve <katalog> --source manual --by <name>` after an explicit
|
|
932
1077
|
confirmation question. Say clearly that this is not visible to anyone other than the archive.
|
|
933
1078
|
- The verbs touch Offer status and comments, never Score, Class or
|
|
934
1079
|
description fields.
|
|
935
1080
|
- **Close per `## Closing: where the item stands`** when the item has an
|
|
936
1081
|
archive directory: the table from `archive.mjs nasta-steg` plus the board line, so
|
|
937
|
-
the move is visible together with what it opens up for (`designa`, customer, nothing)
|
|
1082
|
+
the move is visible together with what it opens up for (`designa`, customer, nothing),
|
|
1083
|
+
and the wrap-up lines at a resting point.
|
|
938
1084
|
|
|
939
1085
|
## Task: `döm`
|
|
940
1086
|
|
|
@@ -957,9 +1103,11 @@ run again for the same item, whose resumability rule re-evaluates a
|
|
|
957
1103
|
`"väntar på dom"` variant and makes the outcome visible to the report when it runs
|
|
958
1104
|
(see `utvärdera`).
|
|
959
1105
|
|
|
960
|
-
1. **Show the source material.** Run the comparison script on the current pair and
|
|
961
|
-
every
|
|
962
|
-
|
|
1106
|
+
1. **Show the source material.** Run the comparison script on the current pair and
|
|
1107
|
+
describe every difference it finds, with each run's evidence in sentences and the
|
|
1108
|
+
source quotes that drove it (as in bedöm step 6, `## Reply wording`); the raw rows
|
|
1109
|
+
stay behind `detaljer <item> state`. No summary instead of the evidence: the ruling
|
|
1110
|
+
is made on it.
|
|
963
1111
|
2. **Ask the reviewer** (AskUserQuestion) with three paths.
|
|
964
1112
|
- **"Run N holds"** (N is 1 or 2, whichever of the two measured
|
|
965
1113
|
runs was right): write the ruling via `archive.mjs utslag <katalog> --typ viktning --beslut "<ordagrant>" --beslutad-av <namn> --axel score --n <n> --galler-fil <fil>`.
|
|
@@ -1036,13 +1184,21 @@ facts in the analysis above.
|
|
|
1036
1184
|
|
|
1037
1185
|
## Task: `detaljer`
|
|
1038
1186
|
|
|
1039
|
-
`detaljer <gid|slug|nr> [step]`: print archived files for the item: without
|
|
1187
|
+
`detaljer <gid|slug|nr> [del-N] [step]`: print archived files for the item: without
|
|
1040
1188
|
a step, a list of what exists; with a step (`spec`, `granskarblock`, `design`,
|
|
1041
|
-
`analys`, `poäng`, `state`) the file's content raw (`design` prints `design.md
|
|
1189
|
+
`granskning`, `analys`, `poäng`, `state`) the file's content raw (`design` prints `design.md`,
|
|
1190
|
+
`granskning` prints `design-review.md` when present);
|
|
1042
1191
|
`klass` reads older archives'
|
|
1043
1192
|
classification files (before ADR-0098). For `klass`/`poäng`: the latest
|
|
1044
1193
|
`-pricing-vN.json` without a suffix (never `-run2`/`-avvisad`).
|
|
1045
1194
|
|
|
1195
|
+
On a split root, the listing without a step also lists the parts (the `del-1/ … del-M/`
|
|
1196
|
+
directories with `split` set), one line each with the part's status and, when recorded,
|
|
1197
|
+
its subtask gid (`split.gid`). `detaljer <item> del-N [step]` reads that part's directory
|
|
1198
|
+
(the form `<gid>/del-N` that `bedöm` and `bedom.mjs` print is the same address) the same way: its own `impact.md`, pricing files and `state.json`, and the copies of the
|
|
1199
|
+
parent's `spec.md`, `granskarblock.md` and `design.md` it inherited. A `del-N` that does
|
|
1200
|
+
not exist: say so and list the parts that do.
|
|
1201
|
+
|
|
1046
1202
|
## Task: `byt titel`
|
|
1047
1203
|
|
|
1048
1204
|
`byt titel <nr|gid>`: rename the item's Asana task to the spec title, on request only
|
|
@@ -1068,9 +1224,9 @@ reaches the name.
|
|
|
1068
1224
|
## Task: `utvärdera`
|
|
1069
1225
|
|
|
1070
1226
|
Model evaluation: `utvärdera <item…> <model…>`, with at least one model. Runs an
|
|
1071
|
-
item through the whole flow once per named model, each round with
|
|
1072
|
-
|
|
1073
|
-
|
|
1227
|
+
item through the whole flow once per named model, each round with
|
|
1228
|
+
every agent step forced to the round's model (six with `design_mode=draft`: specifier,
|
|
1229
|
+
designer, reviewer, assessor, two scorers; `--modell default` keeps the pins), so that each round measures an actual model difference instead of noise between
|
|
1074
1230
|
a fixed production mix and a single experiment model.
|
|
1075
1231
|
`default` as the model value gives the agent defaults (today's production mix) and
|
|
1076
1232
|
runs without an override; the directory name then becomes `baseline/`, for all other values
|
|
@@ -1154,6 +1310,11 @@ The question is therefore about the cost, not the risk of losing data.
|
|
|
1154
1310
|
carries the same value is a no-op. `sprak` is read from the request's body text by
|
|
1155
1311
|
the main conversation, just as in `speca` step 2; `korning.mjs` refuses
|
|
1156
1312
|
to start without it (it never guesses the language, ADR-0114).
|
|
1313
|
+
`design_mode` is optional: `--satt design_mode=draft|intervju` in a call of its own,
|
|
1314
|
+
absent is `intervju`. With `draft`, `korning.mjs` drafts and reviews the design in every
|
|
1315
|
+
part directory that has no `design.md` before the assessor, the same two steps as
|
|
1316
|
+
production (ADR-0156), so a measurement sweep compares machine drafts with human designs
|
|
1317
|
+
on the same specs before any board opts in; a pinned design (step 2) is never redrafted.
|
|
1157
1318
|
|
|
1158
1319
|
At the same time, note the item's `permalink_url` (`--satt permalink_url=<url>`)
|
|
1159
1320
|
when the gid reply carries it. It comes from the same read-only fetch
|
|
@@ -1215,12 +1376,16 @@ The question is therefore about the cost, not the risk of losing data.
|
|
|
1215
1376
|
model:
|
|
1216
1377
|
|
|
1217
1378
|
```
|
|
1218
|
-
node <skillkatalog>/scripts/svep.mjs --repo-rot <abs> --konto <namn> \
|
|
1379
|
+
node <skillkatalog>/scripts/svep.mjs --repo-rot <abs> --arkiv <arkivrot> --konto <namn> \
|
|
1219
1380
|
--modell <modell> [--modell <modell>]... \
|
|
1220
1381
|
--exp experiments/<slug> [--exp experiments/<slug>]... \
|
|
1221
1382
|
[--tickets-parallellt 2] [--modeller-parallellt 4] [--om | --hoppa-över]
|
|
1222
1383
|
```
|
|
1223
1384
|
|
|
1385
|
+
`--repo-rot <abs>` is the checkout whose code is read; `--arkiv <abs>` is
|
|
1386
|
+
`ARKIVROT:` from `rot` (ADR-0154, ADR-0155); a worktree as `--repo-rot` is
|
|
1387
|
+
fine, the archive root never comes from it.
|
|
1388
|
+
|
|
1224
1389
|
Every round is started by `svep.mjs` as ONE `korning.mjs` process, and that is
|
|
1225
1390
|
what gives the measurement for free. The parallel rule: two tickets at a time, at most
|
|
1226
1391
|
four models for one ticket in flight (`--modeller-parallellt`, #526), and
|
|
@@ -1269,7 +1434,8 @@ The question is therefore about the cost, not the risk of losing data.
|
|
|
1269
1434
|
a run without the field as measured under unknown concurrency (#526).
|
|
1270
1435
|
- **The provenance is stamped AFTER `korning.json`, never before**, otherwise
|
|
1271
1436
|
the stamp lacks the billing data. The command itself computes `skill_sha256`
|
|
1272
|
-
(over `SKILL.md` plus the
|
|
1437
|
+
(over `SKILL.md` plus the six agent definitions, `request-designer` and
|
|
1438
|
+
`request-design-reviewer` among them) and `underlag_sha256`,
|
|
1273
1439
|
reads `korning.json` and notes `fakturerade_modeller` (the
|
|
1274
1440
|
canonicalized key set from `modelUsage`, suffixes like `[1m]` stripped,
|
|
1275
1441
|
ADR-0099), and also stamps every `del-N/`. Without that stamp it is
|
|
@@ -1314,8 +1480,8 @@ The question is therefore about the cost, not the risk of losing data.
|
|
|
1314
1480
|
anchor resolution, double run per bedöm) against the directory it is given, without
|
|
1315
1481
|
the approval gate, and touches nothing outside it. If the model is `default`,
|
|
1316
1482
|
the ordinary prompt templates and the agents' defaults are used, no override. If
|
|
1317
|
-
it is a model name, every agent process gets a model override to it on
|
|
1318
|
-
|
|
1483
|
+
it is a model name, every agent process gets a model override to it on every
|
|
1484
|
+
agent step; the override is `--model` on the process, never a prompt line, and
|
|
1319
1485
|
the agent definitions are never touched; the effort is taken from the definition
|
|
1320
1486
|
as usual, except when `korning.mjs` has been given `--effort`: then every
|
|
1321
1487
|
agent process gets the same `--effort` override, the step entry and `runs[]` carry it
|
|
@@ -1504,13 +1670,45 @@ across items with different model sets, or state which outcome
|
|
|
1504
1670
|
was correct. The judgment of what is an acceptable outcome is
|
|
1505
1671
|
the human's, made on experience of the system. The report shows the spread.
|
|
1506
1672
|
|
|
1673
|
+
## Reply wording: what the reviewer reads
|
|
1674
|
+
|
|
1675
|
+
The sentences the orchestrator writes around the scripts' tables (the BLUF lines, how
|
|
1676
|
+
two scorings compared, a repair, a retake, a disagreement) say what the result means
|
|
1677
|
+
for the reviewer's decision, in plain sentences. The tables from `bluf` and
|
|
1678
|
+
`nasta-steg` are pasted as they are; this rule governs the sentences around them.
|
|
1679
|
+
|
|
1680
|
+
- **No internal vocabulary in those sentences:** no reference-scale position names
|
|
1681
|
+
(the anchor ids), no rule or protocol terms (floor, ceiling, between, LIKA,
|
|
1682
|
+
LIKA_TOLERANS, OLIKA, BROTT, REPARERAT, contract, tolerance rows) and no archive file
|
|
1683
|
+
names. Outcome codes (ESKALERA, DELA_UPP, INPUT_SAKNAS, OVER_SKALAN,
|
|
1684
|
+
TILLBAKA_TILL_SPEC, KONCEPT, DIAGNOS) are said as what they mean (an escalation, a
|
|
1685
|
+
split, missing input, above the scale and quoted separately). Quoting the item's own
|
|
1686
|
+
source text from `drivers[].citat` is fine.
|
|
1687
|
+
- **After a pricing check, answer in this order:**
|
|
1688
|
+
1. Did the two scorings agree, and how close they were.
|
|
1689
|
+
2. Which score applies, with the reason in a clause; when both runs land above the
|
|
1690
|
+
scale, that the item has no score and is quoted separately.
|
|
1691
|
+
3. Anything that should lower trust in the number: a scoring that failed an
|
|
1692
|
+
automatic check and was redone, a repair to customer text, something the scorer
|
|
1693
|
+
flagged, an alternative or a type only one run found. A routine repair that changes nothing the reviewer decides on needs no
|
|
1694
|
+
mention.
|
|
1695
|
+
4. On disagreement, the evidence in sentences: first what the runs disagree on, then
|
|
1696
|
+
per run where it landed and what it leaned on, then the ruling command.
|
|
1697
|
+
- **Raw details stay behind `/request detaljer <item>`:** `poäng` prints the
|
|
1698
|
+
scoring, `state` the runs rows with their notes (the repairs, and the comparison rows
|
|
1699
|
+
a `bedöm` double run wrote).
|
|
1700
|
+
Point there in one line when the reviewer may want them.
|
|
1701
|
+
|
|
1702
|
+
Example: "Two independent scorings landed close (2.75 and 3), so 3 applies. One of
|
|
1703
|
+
them failed an automatic check and was redone once; the redo agreed with the other run."
|
|
1704
|
+
|
|
1507
1705
|
## Closing: where the item stands
|
|
1508
1706
|
|
|
1509
1707
|
The tasks `speca`, `designa`, `bedöm`, `godkänn`, `underkänn`, `döm` and `byt titel` ALWAYS end
|
|
1510
|
-
with this block (#530). A reply that ends without it leaves
|
|
1708
|
+
with this block (#530). A `designa` that continues into `bedöm` (designa step 6) ends the turn with `bedöm`'s block, once: the block is per turn, never per task. A reply that ends without it leaves
|
|
1511
1709
|
the user to guess where the item stands, what they should do and which command
|
|
1512
1710
|
runs on, and the archive and the board can then drift apart silently (`spec_draft`
|
|
1513
|
-
locally, empty Offer status on the board). The block consists of
|
|
1711
|
+
locally, empty Offer status on the board). The block consists of five parts, in order:
|
|
1514
1712
|
|
|
1515
1713
|
1. **The table from `node <skillkatalog>/scripts/archive.mjs nasta-steg <katalog>`**
|
|
1516
1714
|
is pasted as it is (`| post | står | väntar på | nästa |`, one row per
|
|
@@ -1526,7 +1724,9 @@ locally, empty Offer status on the board). The block consists of four parts, in
|
|
|
1526
1724
|
2. **The board line.** If the item has a gid: fetch Offer status via request-sync in
|
|
1527
1725
|
the main conversation (never from memory) and write the line
|
|
1528
1726
|
`Bräda: <Offer status>` directly under the table. If the item lacks a gid: write
|
|
1529
|
-
`Bräda: ingen (posten ligger inte på brädan)`.
|
|
1727
|
+
`Bräda: ingen (posten ligger inte på brädan)`. When step 7 placed the item on the board
|
|
1728
|
+
under `auto_sync_spec`, the board line ends with `(synkad automatiskt, auto_sync_spec)`.
|
|
1729
|
+
For an item at
|
|
1530
1730
|
⚖️ Poängsättning redo för granskning, add one line: the analysis and the pricing are
|
|
1531
1731
|
not on the board (ADR-0144), `detaljer <item>` shows them.
|
|
1532
1732
|
3. **The ISÄR check.** The archive status and the Offer status must correspond to each other
|
|
@@ -1556,22 +1756,49 @@ locally, empty Offer status on the board). The block consists of four parts, in
|
|
|
1556
1756
|
are presented as a choice the user must make, not just as routing:
|
|
1557
1757
|
"here is your choice", followed by the alternatives (for TILLBAKA_TILL_SPEC the
|
|
1558
1758
|
open choice from `stopp.orsak` or the source file; for OLIKA the two
|
|
1559
|
-
runs' evidence
|
|
1759
|
+
runs' evidence in sentences, see bedöm step 6 and `## Reply wording`) and the command that
|
|
1560
1760
|
carries out the answer (`speca <item>` after `## Avgjorda val` + `respec`,
|
|
1561
1761
|
`döm <item>`, customer dialogue). A `TILLBAKA_TILL_SPEC` from `impact.md` whose
|
|
1562
1762
|
`orsak` starts with `design conflict:` routes to `designa <item>` (a redesign, bedöm
|
|
1563
|
-
step 3), not to `speca`; the command for that case is `designa <item>`. A
|
|
1763
|
+
step 3), not to `speca`; the command for that case is `designa <item>`. A row
|
|
1764
|
+
`designed, granskningen stoppade` is a choice: read `design-review.md` (`detaljer <item>`)
|
|
1765
|
+
and run `designa <item>` for the interview, or accept the draft as it stands with
|
|
1766
|
+
`node <skillkatalog>/scripts/archive.mjs add-design-review <katalog> --file <katalog>/design-review.md --verdict fortsätt --model människa`
|
|
1767
|
+
(the human's verdict is a receipt; the reviewer is never run again on the same doc). A
|
|
1768
|
+
`stopp ESKALERA ur design-intervju-kravs-<datum>.md` row is the designer asking for the
|
|
1769
|
+
interview: run `designa <item>`. A stop that
|
|
1564
1770
|
is only routed is read as "the machine is working on it", and nobody does anything.
|
|
1565
1771
|
A `DELA_UPP` is presented as two separate yes/no choices, split the item and rewrite
|
|
1566
1772
|
the parent as an umbrella (bedöm's routing, ADR-0144), each answered on its own.
|
|
1773
|
+
A `pågår` row from `nasta-steg` is not a choice: the item is being priced by
|
|
1774
|
+
`bedom.mjs`, wait for its table.
|
|
1775
|
+
|
|
1776
|
+
5. **Wrapping up, at a resting point.** A resting point is a turn that leaves the item
|
|
1777
|
+
on the board at 🔍 (spec review), ⚖️ (price review) or 📤 (done, with the customer),
|
|
1778
|
+
with no part-4 choice open. There, end with a few plain lines on
|
|
1779
|
+
what to do before the session closes, per `## Reply wording` (no anchor ids, protocol
|
|
1780
|
+
terms or archive file names):
|
|
1781
|
+
- Commit the design document and the setup files (the board connection and what
|
|
1782
|
+
`haus apply` wrote), if they are not committed yet; in a temporary workspace, get
|
|
1783
|
+
them onto the main branch before the workspace is removed. This line replaces the
|
|
1784
|
+
separate design commit offer in the same turn.
|
|
1785
|
+
- Keep the specs, analyses and scores out of the customer's history: they stay in the
|
|
1786
|
+
local request archive, which is kept out of git on purpose.
|
|
1787
|
+
- When the customer orders, planning starts from the saved design document; if the
|
|
1788
|
+
spec changes before that, the design is redone first.
|
|
1789
|
+
|
|
1790
|
+
Leave out a line that does not apply (nothing to commit, no design yet). No line about
|
|
1791
|
+
moving the archive out of a workspace: the archive always lives in the main checkout
|
|
1792
|
+
(ADR-0154). An old archive left in a workspace shows up as `archive.mjs rot`'s
|
|
1793
|
+
VARNING line; pass that line on to the user in plain words when it appears.
|
|
1567
1794
|
|
|
1568
1795
|
## Mechanical scripts: `scripts/`
|
|
1569
1796
|
|
|
1570
|
-
|
|
1797
|
+
Thirteen deterministic scripts live in the directory: the five checks below,
|
|
1571
1798
|
`kontroll.mjs` which runs the scorer's check chain in one process,
|
|
1572
1799
|
`archive.mjs` which owns the archive's directories, holds and `experiment.json`,
|
|
1573
|
-
`svep.mjs` which is utvärdera's starter,
|
|
1574
|
-
`korning.mjs` which is utvärdera's inner process, `report.mjs` which
|
|
1800
|
+
`svep.mjs` which is utvärdera's starter, `bedom.mjs` which is bedöm's starter,
|
|
1801
|
+
`korning.mjs` which is utvärdera's inner process and bedöm's in production, `report.mjs` which
|
|
1575
1802
|
renders the model report (see `utvärdera rapport`), `lib.mjs` with the shared
|
|
1576
1803
|
building blocks and `ref-hash.mjs` for stable hashing. The checks replace
|
|
1577
1804
|
model runs where the check is pure form:
|
|
@@ -1591,7 +1818,10 @@ reference files whose rules it mirrors and WARNS when a catalog bump has changed
|
|
|
1591
1818
|
_Lösning_ (_Solution_) is a BRIST. With `--impact` the label on the analysis's row
|
|
1592
1819
|
`**Deviation from the spec:**` is read and written as `AVVIKELSE: ingen`,
|
|
1593
1820
|
`AVVIKELSE: precisering` or `AVVIKELSE: motsägelse`; a row without a
|
|
1594
|
-
label is a BRIST.
|
|
1821
|
+
label is a BRIST. When the row carries text after its label, the line
|
|
1822
|
+
`AVVIKELSE-TEXT: <text>` follows right after `AVVIKELSE:`; the orchestrator and
|
|
1823
|
+
`korning.mjs` read the design-conflict text from that line, never from the file
|
|
1824
|
+
(ADR-0155). The orchestrator reads candidate and deviation from those
|
|
1595
1825
|
lines, never from the files itself. The spec rules live in `lib.mjs` (`specForm`),
|
|
1596
1826
|
shared with `archive.mjs paraply` (ADR-0144).
|
|
1597
1827
|
With `--design` (`designa` step 3 and `bedöm` gate 1b): `design.md` must exist,
|
|
@@ -1607,6 +1837,16 @@ reference files whose rules it mirrors and WARNS when a catalog bump has changed
|
|
|
1607
1837
|
match the analysis row's `underlag_sha256["design.md"]`, the same provenance rule
|
|
1608
1838
|
as for `spec.md`, except that a missing design hash is a BRIST, not a VARNING:
|
|
1609
1839
|
the design existed when the analysis should have seen it.
|
|
1840
|
+
`--design` also checks the draft's form (ADR-0156): it prints
|
|
1841
|
+
`DESIGN-LÄGE: draft|intervju` (from `mode:` in the frontmatter); on a draft a missing or
|
|
1842
|
+
malformed `## Assumptions`, `## Removed or renamed` or `## Files touched` is a BRIST, on an
|
|
1843
|
+
interactive doc a VARNING; every symbol under `## Removed or renamed` is grepped
|
|
1844
|
+
(`git grep`, in the repo of the canonical file) outside the files under `## Files touched`
|
|
1845
|
+
and a hit is a BRIST with its `file:line`, while a grep that cannot run is a VARNING; and a
|
|
1846
|
+
`state.design.review` verdict `stopp` is a BRIST. `--design-utkast <abs fil> [--repo-rot <abs>]`
|
|
1847
|
+
checks a draft file without `state.design` (the experiment channel): the same section and
|
|
1848
|
+
symbol checks, the frontmatter against the directory's id and the current `spec.md` hash,
|
|
1849
|
+
`## Spec conflicts` `none`, and the `DESIGN-LÄGE:` line; exit 1 on a BRIST.
|
|
1610
1850
|
- `scripts/resolve-anchors.mjs <run.json> <spec.md> [impact.md]`: resolves
|
|
1611
1851
|
evidence anchors (`belagg_ankare`/`ankare`) to verbatim source blocks, runs
|
|
1612
1852
|
BEFORE contract-check. Exit 0 = everything resolved (or no anchors in the file), 1 =
|
|
@@ -1664,20 +1904,55 @@ reference files whose rules it mirrors and WARNS when a catalog bump has changed
|
|
|
1664
1904
|
byte-identically, writes `state.design` and sets status `designed`; no runs row;
|
|
1665
1905
|
refuses a file under `.haus-workflow/`, a `priced` or `guard_run` item and any
|
|
1666
1906
|
standing stop except a design conflict from `impact.md`, which it clears, putting
|
|
1667
|
-
`impact.md` aside as `impact-superseded-<datum>.md`;
|
|
1907
|
+
`impact.md` aside as `impact-superseded-<datum>.md`; also refuses a draft whose sections
|
|
1908
|
+
fail the form check and a removed symbol still in use outside the touched files, and
|
|
1909
|
+
resets `design.review`, ADR-0156;
|
|
1668
1910
|
exit 2 on every refusal, under the archive lock),
|
|
1911
|
+
`add-design-review <katalog> --file <abs> --verdict fortsätt|stopp --model <m>` (the one
|
|
1912
|
+
writer of `state.design.review`: copies the reviewer's reply byte-identically to
|
|
1913
|
+
`design-review.md`, an earlier one put aside as `design-review-superseded-<datum>.md`,
|
|
1914
|
+
writes `{ verdict, sha256, date, model }` and prints `OK: design-review <verdict> (<sha256>)`;
|
|
1915
|
+
refuses an item without a design, a verdict outside the two literals, an unreadable file
|
|
1916
|
+
and an experiment directory, exit 2; no runs row; under the archive lock; ADR-0156),
|
|
1917
|
+
`antaganden <katalog>` (read-only, what `bedöm` step 8 pastes before `synka`: the line
|
|
1918
|
+
`Designläge: draft|intervju`, then `Antaganden (N):` with one block per assumption (the
|
|
1919
|
+
question, `vald:`, `ej valda:`, `skäl:`), or `Antaganden: inga`, or
|
|
1920
|
+
`Antaganden: avsnitt saknas`, then `Granskning: <verdict> (<K> fynd)` or
|
|
1921
|
+
`Granskning: ingen`, then `Spec conflicts: none` or the count with the lines; refuses an
|
|
1922
|
+
item without `design.md`, exit 2; ADR-0156),
|
|
1669
1923
|
`set-split-gid <del-katalog> --gid <gid>` (records a split part's Asana subtask gid in
|
|
1670
1924
|
`split.gid` under the archive lock; refuses a directory without `split`, a gid that is not
|
|
1671
1925
|
digits only and a different gid already recorded, while the same gid again is a no-op;
|
|
1672
1926
|
ADR-0144),
|
|
1927
|
+
`approve <katalog> --source asana|manual` (`--status "<Offer status as read>"` for
|
|
1928
|
+
asana, `--by <name>` for manual; the one writer of `state.approval`, under the archive
|
|
1929
|
+
lock, overwriting an earlier note; refuses an asana status whose alphabetic core is not
|
|
1930
|
+
`specok`, manual without `--by` and an experiment directory, exit 2; ADR-0153),
|
|
1931
|
+
`synced <katalog> --offer-status "<Offer status>"` (the one writer of `state.board`, the
|
|
1932
|
+
receipt of a board write: `{ offer_status, date }`, the value verbatim, under the archive
|
|
1933
|
+
lock, overwriting the previous receipt; refuses a missing or empty `--offer-status`, an
|
|
1934
|
+
experiment directory and a split part, whose receipt is `split.gid`, exit 2; `nasta-steg`
|
|
1935
|
+
reads it; ADR-0153),
|
|
1936
|
+
`korning-start <katalog> --pid <N> [--katalog-korning <abs>]` /
|
|
1937
|
+
`korning-slut <katalog>` (the running receipt's two writers, `state.korning`, under the
|
|
1938
|
+
archive lock; start refuses a living pid, exit 2 `pågår (pid N)`, and takes a dead one
|
|
1939
|
+
over; both refuse an experiment directory, exit 2; `bedom.mjs` runs them around every
|
|
1940
|
+
item; ADR-0155),
|
|
1941
|
+
`rot [<dir>]` (takes no archive directory: prints `ARKIVROT: <abs>`, the main checkout's
|
|
1942
|
+
`.haus-workflow/requests/`, and `IGNORERAD: ja|nej`, exit 0, plus a third line
|
|
1943
|
+
`VARNING: arkiv i worktree: <abs> (flytta per ADR-0154)` when the cwd's own checkout holds
|
|
1944
|
+
an archive of its own; refuses a directory outside a git repository, a bare repository, a
|
|
1945
|
+
submodule checkout and a `--separate-git-dir` clone, exit 2; ADR-0154),
|
|
1673
1946
|
`paraply <katalog> --file <spec>` (rewrites the parent's spec as an umbrella: refuses a
|
|
1674
1947
|
split part, an item without `approval`, a file that fails the spec form check
|
|
1675
1948
|
`precheck.mjs` runs, a file without a title line and an unreadable file; puts `spec.md`
|
|
1676
1949
|
aside as `spec-superseded-<datum>.md`, copies the file in, sets `title` from its heading
|
|
1677
1950
|
and records `state.umbrella = { date, sha256 }`; approval, design, runs, stops and the
|
|
1678
1951
|
parts are untouched; prints `OK: paraply <sha256>`; ADR-0144),
|
|
1679
|
-
`stopp <katalog> --utfall KONCEPT|DIAGNOS|TILLBAKA_TILL_SPEC|ESKALERA --kalla spec.md|impact.md|granskarblock.md|design-avvisad-<datum>.md [--orsak <text>]`
|
|
1952
|
+
`stopp <katalog> --utfall KONCEPT|DIAGNOS|TILLBAKA_TILL_SPEC|ESKALERA --kalla spec.md|impact.md|granskarblock.md|design-avvisad-<datum>.md|design-intervju-kravs-<datum>.md [--orsak <text>]`
|
|
1680
1953
|
(writes `state.stopp` after checking that the source carries the outcome;
|
|
1954
|
+
`--kalla design-intervju-kravs-<datum>.md` requires a first line `INTERVJU KRÄVS: <reason>`
|
|
1955
|
+
and takes only `ESKALERA` with `--orsak`, written by `korning.mjs` in draft mode;
|
|
1681
1956
|
`--kalla design-avvisad-<datum>.md` requires at least one conflict under
|
|
1682
1957
|
`## Spec conflicts` in that receipt and takes `TILLBAKA_TILL_SPEC` or `ESKALERA`,
|
|
1683
1958
|
and replaces a standing design-conflict stop from `impact.md` (any other standing
|
|
@@ -1685,8 +1960,9 @@ reference files whose rules it mirrors and WARNS when a catalog bump has changed
|
|
|
1685
1960
|
`--kalla impact.md` sets status `assessed`, the other sources do not touch
|
|
1686
1961
|
the status), `respec <katalog>` (puts `impact.md` aside as
|
|
1687
1962
|
`impact-superseded-<datum>.md` and `design.md` as `design-superseded-<datum>.md`,
|
|
1688
|
-
resets status (to `spec_draft`), `approval`, `granskarutslag`, `stopp
|
|
1689
|
-
`design`, never touches `runs[]`
|
|
1963
|
+
resets status (to `spec_draft`), `approval`, `granskarutslag`, `stopp`,
|
|
1964
|
+
`design` and `board`, never touches `runs[]`; `design.review` goes with `design`, and `design-review.md` is put aside as
|
|
1965
|
+
`design-review-superseded-<datum>.md`) and
|
|
1690
1966
|
`bluf <katalog>` (the markdown table `| post | poäng | utfall | konfidens | anm |`
|
|
1691
1967
|
over the directory and its `del-N/` recursively, the bundle root as
|
|
1692
1968
|
`bunt (N delar)`, a split root with `K av M delar prissatta` in `anm`; the values from
|
|
@@ -1698,11 +1974,19 @@ reference files whose rules it mirrors and WARNS when a catalog bump has changed
|
|
|
1698
1974
|
outcome per the rule table in the script; on a split root the parent row counts the
|
|
1699
1975
|
parts (`se delarna (K av M delar prissatta)`) until every part is `priced` or
|
|
1700
1976
|
`OVER_SKALAN` and then names the sync that moves the parent, and a part row says
|
|
1701
|
-
whether its subtask is recorded (`split.gid`);
|
|
1977
|
+
whether its subtask is recorded (`split.gid`); a living `korning.pid` gives `pågår (pid N)`
|
|
1978
|
+
with `vänta; bedöm igen när bedom.mjs är klar`, a dead one prefixes the row with
|
|
1979
|
+
`avbruten körning, ` (ADR-0155); a `designed` item whose review stopped gives
|
|
1980
|
+
`| <post> | designed, granskningen stoppade | människa | designa <id> (intervju; se design-review.md) |`
|
|
1981
|
+
(ADR-0156) and an `INTERVJU KRÄVS` stop gives
|
|
1982
|
+
`| <post> | stopp ESKALERA ur design-intervju-kravs-<datum>.md | människa | designa <id> (intervju; se design-intervju-kravs-<datum>.md) |`;
|
|
1983
|
+
an unknown state is written as
|
|
1702
1984
|
`okänt läge: <status>` with exit 0, a broken `state.json` is exit 2, see
|
|
1703
1985
|
`## Closing: where the item stands`). `add-run` reads
|
|
1704
1986
|
`effort:` from the agent definition when `--effort` is omitted and canonicalizes
|
|
1705
|
-
`--model
|
|
1987
|
+
`--model`, and `add-run … [--repo-sha <sha>]` writes `repo_sha` on the row (40 lowercase
|
|
1988
|
+
hex digits, otherwise exit 2; `korning.mjs` passes it on `impact.md` rows, ADR-0155);
|
|
1989
|
+
`set-status priced` refuses when `stopp` is set.
|
|
1706
1990
|
`experiment <experimentkatalog> [--satt nyckel=värde]... [--variant <modell>]... [--korning <modell>/k<N> --status <klar|ofärdig|stopp|väntar på dom> [--orsak <text>] [--pid <heltal>]]`
|
|
1707
1991
|
is the ONLY writer of `experiment.json` (see `utvärdera` step 1): a locked
|
|
1708
1992
|
read-modify-write with an atomic write; the directory and file are created if they are
|
|
@@ -1714,7 +1998,7 @@ reference files whose rules it mirrors and WARNS when a catalog bump has changed
|
|
|
1714
1998
|
the starter's pid on the row; a status write without `--pid` replaces the row
|
|
1715
1999
|
entirely, so the pid disappears with the final status (#516). Exit 0 ok, 2
|
|
1716
2000
|
a usage or state error.
|
|
1717
|
-
- `scripts/svep.mjs --repo-rot <abs> --konto <namn> --modell <m>... --exp experiments/<slug>... [--tickets-parallellt 2] [--modeller-parallellt 4] [--om | --hoppa-över]`:
|
|
2001
|
+
- `scripts/svep.mjs --repo-rot <abs> [--arkiv <abs>] --konto <namn> --modell <m>... --exp experiments/<slug>... [--tickets-parallellt 2] [--modeller-parallellt 4] [--om | --hoppa-över]`:
|
|
1718
2002
|
utvärdera's starter (see `utvärdera` step 4 and Batch). Runs two tickets at
|
|
1719
2003
|
a time with at most four models per ticket in flight, the next ticket when one is completely
|
|
1720
2004
|
done, and does per round `ny-korning`, the start of `korning.mjs`,
|
|
@@ -1725,12 +2009,39 @@ reference files whose rules it mirrors and WARNS when a catalog bump has changed
|
|
|
1725
2009
|
`väntar på dom` is tested with `sparr`, `ofärdig` is rerun, except when the row carries
|
|
1726
2010
|
a living `pid` (in progress in another sweep, skipped as `pågår`, #516). An `--exp` without
|
|
1727
2011
|
`onskemal.md`, `kallmanifest.md` or `experiment.json` with `request_id` is marked
|
|
1728
|
-
and skipped.
|
|
1729
|
-
|
|
1730
|
-
|
|
2012
|
+
and skipped. `--arkiv` is the archive root; omitted, it is derived from
|
|
2013
|
+
`--repo-rot`'s git common dir (ADR-0154). Exit 0 when no run became
|
|
2014
|
+
`ofärdig`, 1 otherwise, 2 on a usage error.
|
|
2015
|
+
- `scripts/bedom.mjs --repo-rot <abs> [--arkiv <abs>] --post <gid|gid/del-N>... [--parallellt 2] [--max-usd <n>] [--claude <kommando>] [--om] [--sprak <svenska|engelska>]`:
|
|
2016
|
+
production's starter (see `bedöm`), one `korning.mjs --post` process per item, two at a
|
|
2017
|
+
time. `--post` is relative to the archive root (`--arkiv`, or derived from `--repo-rot`'s
|
|
2018
|
+
git common dir as in `svep.mjs`); an absolute `--post` is a usage error. Per item: the
|
|
2019
|
+
receipt via `archive.mjs korning-start`/`korning-slut` (the latter always, also when the
|
|
2020
|
+
run fails), the run directory `<post>/korningar/<stämpel>/` with `stderr.log`,
|
|
2021
|
+
`matning.json` and the raw replies under `steg/`, the cap from `request.json`
|
|
2022
|
+
(`max_usd_per_batch`, default 100 USD, `--max-usd` overrides; once the finished items'
|
|
2023
|
+
USD, plus each item in flight at the average of the finished ones, reaches it no further
|
|
2024
|
+
item starts, `tak nått`, and a running item is never killed), `--startare <its own pid>` on
|
|
2025
|
+
every `korning.mjs` it starts, SIGINT and SIGTERM both killing the running items and
|
|
2026
|
+
clearing their receipts (exit 130),
|
|
2027
|
+
and the final table `| post | status | poäng | utfall | wall | USD |` in argument order
|
|
2028
|
+
with the line `tak: <n> USD, använt: <m> USD`. Exit 0 when every item ended in a result
|
|
2029
|
+
(`priced`, `stopp`, `väntar på dom`), 1 on `ofärdig`, `pågår`, `grind` or `tak nått`, 2
|
|
2030
|
+
on a usage error (ADR-0155).
|
|
2031
|
+
`bedom.mjs` takes `--design-mode draft|intervju` and passes it to every `korning.mjs` it
|
|
2032
|
+
starts; without the flag the value is `request.json`'s `design_mode` (`interview` is read
|
|
2033
|
+
as `intervju`), and without that key `intervju` (ADR-0156).
|
|
2034
|
+
- `scripts/korning.mjs --katalog <abs k<N>> --exp <abs experimentkatalog> --repo-rot <abs> --request-id <gid eller slug> --modell <modell|default> [--claude <kommando>] [--delar-parallellt 2] [--effort <low|medium|high|xhigh|max|default>] [--sprak <svenska|engelska>]`:
|
|
1731
2035
|
utvärdera's inner process (see `utvärdera` step 4), a script without
|
|
1732
|
-
model turns.
|
|
1733
|
-
`
|
|
2036
|
+
model turns. In production (`bedom.mjs`) `--post <abs postkatalog>` replaces `--exp`
|
|
2037
|
+
plus `--request-id` (giving `--request-id` with `--post` is a usage error, the id comes
|
|
2038
|
+
from the item's `state.json`) and runs `bedöm` steps 3 to 7 on the item directory,
|
|
2039
|
+
printing `STATUS: <priced|assessed|stopp|väntar på dom|ofärdig>` on stdout (ADR-0155).
|
|
2040
|
+
`--startare <pid>` (production only, a usage error with `--exp`) is the starter's pid,
|
|
2041
|
+
checked every 30 s: a dead starter aborts the run like SIGTERM (exit 130).
|
|
2042
|
+
`--sprak` overrides the language in both modes; in production it otherwise comes from
|
|
2043
|
+
`SPRÅK:` in `kallmanifest.md`, and a missing language is exit 2. In utvärdera it builds
|
|
2044
|
+
the prompts from `onskemal.md`, `kallmanifest.md` and `experiment.json`, where `sprak` is MANDATORY: if it is missing, an
|
|
1734
2045
|
instruction is written on stderr and the script ends with exit 2 before any prompt
|
|
1735
2046
|
is built (ADR-0114). Every agent step is a `claude -p --agent` process of its own with
|
|
1736
2047
|
the raw reply under `k<N>/steg/`, and the checks (precheck, `kontroll.mjs`,
|
|
@@ -1742,9 +2053,22 @@ reference files whose rules it mirrors and WARNS when a catalog bump has changed
|
|
|
1742
2053
|
before; everything else is passed to the process and to `add-run --effort` as
|
|
1743
2054
|
requested, never verified (#525). `korning.json` is the sum over the steps
|
|
1744
2055
|
(`korningsmotor`, `steg` with `effort_begard` and `samtidiga_processer` per
|
|
1745
|
-
step, `modellverifiering` plus the report's usual keys).
|
|
1746
|
-
the
|
|
1747
|
-
|
|
2056
|
+
step, `modellverifiering` plus the report's usual keys). The impact row gets
|
|
2057
|
+
`--repo-sha`, the checkout's `HEAD` when the assessor read it (ADR-0155).
|
|
2058
|
+
`korning.mjs` takes `--design-mode draft|intervju` (default `intervju`; in utvärdera the
|
|
2059
|
+
value is `design_mode` in `experiment.json`). With `draft`, a part without `design.md`
|
|
2060
|
+
(in production: and not a split part) gets two steps before the assessor (ADR-0156):
|
|
2061
|
+
`request-designer`, whose doc is written at the `designa` path in `--repo-rot` and recorded
|
|
2062
|
+
with `add-design` (in utvärdera written as the part's `design.md` and checked with
|
|
2063
|
+
`precheck --design-utkast`), then `request-design-reviewer`, whose reply is recorded with
|
|
2064
|
+
`add-design-review` (in utvärdera copied as the part's `design-review.md`).
|
|
2065
|
+
`INTERVJU KRÄVS:` gives `stopp` with `intervju krävs: <reason>` and writes nothing, a
|
|
2066
|
+
refusal on `## Spec conflicts` gives the receipt and the stop of `designa` step 5, any other
|
|
2067
|
+
refusal, BRIST or symbol hit gives `ofärdig`, and `VERDICT: stopp` gives `stopp` with
|
|
2068
|
+
`designgranskning: <first finding>`. A reviewer reply without a `VERDICT:` first line is a
|
|
2069
|
+
script-proven breach and is redispatched ONCE; the verdict itself never is.
|
|
2070
|
+
Exit 0 when the run went through, 1 when at least one part became
|
|
2071
|
+
unfinished, 2 on a usage error.
|
|
1748
2072
|
- `scripts/kontroll.mjs <svar.txt> <spec.md> <impact.md> --expect-id <id> --ut <ren.json> [--fixa-kundtext] [--claude <kommando>] [--fix-modell sonnet] [--fix-fil <rå.json>]`:
|
|
1749
2073
|
the scorer's check chain in ONE process (see `bedöm` step 5): tail lines,
|
|
1750
2074
|
JSON extraction, deterministic repairs, then check-lasta,
|
|
@@ -1769,7 +2093,7 @@ an item that passes can still be stopped by the protocols themselves, and that i
|
|
|
1769
2093
|
their job. On a script error (exit 2 or a crash): show the error and stop, never
|
|
1770
2094
|
continue as if the check had passed.
|
|
1771
2095
|
|
|
1772
|
-
## Dispatch contract (applies to
|
|
2096
|
+
## Dispatch contract (applies to every agent)
|
|
1773
2097
|
|
|
1774
2098
|
- The prompt is self-contained: the agent does not see this conversation.
|
|
1775
2099
|
- **Prompt templates, the labels verbatim:**
|
|
@@ -1825,6 +2149,58 @@ continue as if the check had passed.
|
|
|
1825
2149
|
The umbrella dispatch writes no runs row: `state.umbrella` is its receipt once `paraply`
|
|
1826
2150
|
accepts the draft.
|
|
1827
2151
|
|
|
2152
|
+
`request-designer` (draft mode, ADR-0156):
|
|
2153
|
+
|
|
2154
|
+
```
|
|
2155
|
+
SPEC:
|
|
2156
|
+
<spec.md bytetroget>
|
|
2157
|
+
|
|
2158
|
+
GRANSKARBLOCK:
|
|
2159
|
+
<granskarblock.md bytetroget>
|
|
2160
|
+
|
|
2161
|
+
URSPRUNGLIG FÖRFRÅGAN:
|
|
2162
|
+
<onskemal.md ordagrant när posten har en, annars "(saknas i arkivet)": då arbetar designern ur specen ensam>
|
|
2163
|
+
|
|
2164
|
+
REPO-ROT: <absolut sökväg>
|
|
2165
|
+
DEPS: <installerade | saknas>
|
|
2166
|
+
SPRÅK: <svenska | engelska>
|
|
2167
|
+
KÄLLOR:
|
|
2168
|
+
<kallmanifest.md ordagrant, eller "inga">
|
|
2169
|
+
|
|
2170
|
+
KONFIG: <absolut sökväg till .haus-workflow/workflow-config.md>
|
|
2171
|
+
ID: <katalogens id>
|
|
2172
|
+
SPEC-SHA256: <ref-hash.mjs på spec.md>
|
|
2173
|
+
DATUM: <YYYY-MM-DD>
|
|
2174
|
+
```
|
|
2175
|
+
|
|
2176
|
+
`request-design-reviewer` (draft mode, ADR-0156):
|
|
2177
|
+
|
|
2178
|
+
```
|
|
2179
|
+
SPEC:
|
|
2180
|
+
<spec.md bytetroget>
|
|
2181
|
+
|
|
2182
|
+
GRANSKARBLOCK:
|
|
2183
|
+
<granskarblock.md bytetroget>
|
|
2184
|
+
|
|
2185
|
+
DESIGN:
|
|
2186
|
+
<design.md bytetroget, utkastet som granskas>
|
|
2187
|
+
|
|
2188
|
+
REPO-ROT: <absolut sökväg>
|
|
2189
|
+
DEPS: <installerade | saknas>
|
|
2190
|
+
SPRÅK: <svenska | engelska>
|
|
2191
|
+
```
|
|
2192
|
+
|
|
2193
|
+
The designer and the reviewer are dispatched only by `korning.mjs`, never from the main
|
|
2194
|
+
conversation: a design without a human is a background step, the interview is `designa`.
|
|
2195
|
+
The designer triages as brainstorming does (spike, bounded, architectural) without
|
|
2196
|
+
loading it, takes the recommended option on every HOW question and records it under
|
|
2197
|
+
`## Assumptions`, puts every WHAT question under `## Spec conflicts` unanswered and every
|
|
2198
|
+
defect outside the spec's _När det är klart_ under `## Out of scope`; it replies with the
|
|
2199
|
+
doc, or with the single line `INTERVJU KRÄVS: <reason>` for an architectural item. The
|
|
2200
|
+
reviewer verifies and never redesigns: its reply starts with `VERDICT: fortsätt` or
|
|
2201
|
+
`VERDICT: stopp`, then `## Findings`. `KONFIG:` is a path the designer reads for repo-wide
|
|
2202
|
+
answers (the test command, the formatter); the file is never pasted.
|
|
2203
|
+
|
|
1828
2204
|
`request-assessor`:
|
|
1829
2205
|
|
|
1830
2206
|
```
|
|
@@ -1865,6 +2241,11 @@ continue as if the check had passed.
|
|
|
1865
2241
|
`designa`), pasted, never pointed to by path: the hard rule "documents are pasted
|
|
1866
2242
|
byte-faithfully" applies. Without a design (a split part of a parent analysed under
|
|
1867
2243
|
the old rules, or a standalone assessor run) the block is the single line `DESIGN: ingen`.
|
|
2244
|
+
In draft mode (ADR-0156) the doc is a draft (`mode: draft`) written by `request-designer`,
|
|
2245
|
+
and the reviewer's verdict sits beside it in the archive as `design-review.md`. The block
|
|
2246
|
+
is pasted the same way and the assessor's rule is unchanged: every decision in it is
|
|
2247
|
+
taken, the machine-taken ones included; the human reads those in the Closing
|
|
2248
|
+
(`antaganden`), not in a reopened analysis.
|
|
1868
2249
|
|
|
1869
2250
|
`request-scorer` (source material by path, ADR-0099: never pasted):
|
|
1870
2251
|
|
|
@@ -1888,12 +2269,12 @@ continue as if the check had passed.
|
|
|
1888
2269
|
`contract-check --sprak` rejects customer text in the wrong language.
|
|
1889
2270
|
|
|
1890
2271
|
- **Tail lines after the main content**, in this order: `MODELL: <modell-id>`
|
|
1891
|
-
(all agents), `LÄSTA: <kommaseparerade absoluta sökvägar eller "inga">`
|
|
2272
|
+
(all agents; the designer's `INTERVJU KRÄVS:` reply is the one line and carries none), `LÄSTA: <kommaseparerade absoluta sökvägar eller "inga">`
|
|
1892
2273
|
(only the scorer: its Read is prompt-restricted, the line makes the rule
|
|
1893
2274
|
reviewable), `AVVIKELSE: <text>` (only if something in the prompt broke the agent's
|
|
1894
2275
|
rules, e.g. a price list in the source material). The tail lines are stripped before every
|
|
1895
2276
|
mechanical check and before archiving; MODELL is noted in the runs row,
|
|
1896
|
-
AVVIKELSE is always
|
|
2277
|
+
AVVIKELSE is always reported to the user, in plain words (`## Reply wording`). LÄSTA is checked MECHANICALLY by
|
|
1897
2278
|
`scripts/check-lasta.mjs` (ADR-0099): the line must carry the source material's two
|
|
1898
2279
|
pointed-out paths (both mandatory) and may beyond that carry only files
|
|
1899
2280
|
under the skill's own directory (the reference file); everything else is a
|
|
@@ -1912,7 +2293,9 @@ continue as if the check had passed.
|
|
|
1912
2293
|
with an `-avvisad` suffix (pricing: `<typ>-pricing-vN-avvisad.json`;
|
|
1913
2294
|
text steps: `spec-avvisad-<datum>.md` / `impact-avvisad-<datum>.md`) and gets
|
|
1914
2295
|
a runs row of its own with the check's error lines: two runs of the same step
|
|
1915
|
-
without a trace of why is exactly the gap the receipt closes.
|
|
2296
|
+
without a trace of why is exactly the gap the receipt closes. In the chat, a retake is
|
|
2297
|
+
told in plain words ("one scoring failed an automatic check and was redone once"),
|
|
2298
|
+
never by its archive file name (`## Reply wording`).
|
|
1916
2299
|
|
|
1917
2300
|
## Do not use when
|
|
1918
2301
|
|