@orkestrel/scaffold 0.0.63 → 0.0.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -103
- package/dist/bin/main.js +95 -27
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +2 -2
- package/dist/host/CLAUDE.md +6 -0
- package/dist/host/agents/orchestration.md +23 -15
- package/dist/host/agents/skills/enterprise-bootstrap/references/bootstrap-reference.md +16 -16
- package/dist/host/agents/skills/enterprise-bootstrap/references/frontend-design.md +6 -6
- package/dist/host/agents/skills/enterprise-bootstrap/references/utilities.md +4 -4
- package/dist/host/agents/skills/orkestrel-debrief/references/field-testing.md +5 -5
- package/dist/host/agents/skills/orkestrel-falsify/references/reconcile.md +1 -1
- package/dist/host/agents/skills/orkestrel-publish/SKILL.md +15 -15
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +43 -17
- package/dist/host/agents/skills/orkestrel-publish/references/window.md +41 -16
- package/dist/host/claude/agents/orkestrel.md +56 -56
- package/dist/host/claude/agents/reviewer.md +13 -0
- package/dist/host/claude/rules/architecture.md +51 -45
- package/dist/host/claude/rules/documentation.md +18 -1
- package/dist/host/claude/rules/portability.md +2 -0
- package/dist/host/claude/rules/quality.md +1 -1
- package/dist/host/claude/rules/tests.md +12 -11
- package/dist/host/claude/rules/typescript.md +5 -0
- package/dist/host/claude/rules/workspace.md +23 -18
- package/dist/host/claude/rules/writing.md +4 -0
- package/dist/host/codex/agents/orkestrel.toml +3 -3
- package/dist/host/codex/agents/reviewer.toml +4 -2
- package/dist/host/configs/helpers.ts +311 -2
- package/dist/host/configs/policy.ts +1100 -51
- package/dist/host/dotfiles/oxlintrc.json +72 -1
- package/dist/host/guides/guide.md +749 -222
- package/dist/host/guides/scaffold.md +472 -378
- package/dist/host/manifest.json +34 -33
- package/dist/host/scripts/codex.sh +0 -0
- package/dist/host/scripts/cursor.sh +0 -0
- package/dist/host/scripts/deps.sh +0 -0
- package/dist/host/scripts/ollama.sh +0 -0
- package/dist/host/tests/config.test.ts +1200 -16
- package/dist/host/tests/policy.test.ts +157 -173
- package/dist/host/tests/setupPolicy.ts +522 -1007
- package/dist/src/core/index.cjs +371 -277
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +130 -120
- package/dist/src/core/index.d.ts +130 -120
- package/dist/src/core/index.js +371 -276
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +28 -21
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +38 -33
- package/dist/src/server/index.d.ts +38 -33
- package/dist/src/server/index.js +28 -21
- package/dist/src/server/index.js.map +1 -1
- package/package.json +15 -16
package/dist/host/AGENTS.md
CHANGED
|
@@ -68,7 +68,7 @@ configs/ thin target wrappers around root Vite/TypeScript configuration
|
|
|
68
68
|
- **No nested functions.** Extract function declarations and assignments from bodies. The only exceptions are an anonymous callback passed directly as an argument and an anonymous function returned directly as a result.
|
|
69
69
|
- **Functional core, imperative shell.** Export pure leaves. Keep stateful or defining orchestration as class methods. Classes compose behavior; they do not forward 1:1 to helpers.
|
|
70
70
|
- **No superfluous wrappers.** A wrapper must add a boundary, invariant, composition, translation, lifecycle, or materially narrower contract. Otherwise use or rename the real symbol and update every consumer.
|
|
71
|
-
- **Minimal public API.** Add or substantively expand a capability with its first real consumer; do not speculate. This is a creation gate, never a later visibility gate. Once an intentional reusable capability exists, expose its top-level source exports through the correct environment barrel regardless of which consumers
|
|
71
|
+
- **Minimal public API.** Add or substantively expand a capability with its first real consumer; do not speculate. This is a creation gate, never a later visibility gate. Once an intentional reusable capability exists, expose its top-level source exports through the correct environment barrel regardless of which consumers use them, so developers receive the same supported mechanisms the package uses. Remove a symbol only when the capability itself must not exist. Prefer one minimal interface and one shared engine, allowing native backend overrides only for genuine faster paths.
|
|
72
72
|
- **No compatibility shims.** This is greenfield. Update every consumer in the same change.
|
|
73
73
|
- **Mechanism, not product policy.** Framework code supplies reusable mechanisms and stops before application decisions.
|
|
74
74
|
- **No polling architecture.** Park idle work on events and abort signals. Yield long work cooperatively.
|
|
@@ -101,7 +101,7 @@ configs/ thin target wrappers around root Vite/TypeScript configuration
|
|
|
101
101
|
7. **Document:** update the guide, examples, and parity contract.
|
|
102
102
|
8. **Verify:** audit discovery, deferrals, and package contents as applicable. Run the required gates and read their actual output before claiming success.
|
|
103
103
|
|
|
104
|
-
Quality gates before commit, in order. The acceptance gate is the non-mutating variant; run the mutating `lint` and then `format` first only to converge, then prove with the checks. `lint --fix` rewrites code and its output is not formatter-clean, so a `format` that ran before it leaves `format:check` failing on the file `lint`
|
|
104
|
+
Quality gates before commit, in order. The acceptance gate is the non-mutating variant; run the mutating `lint` and then `format` first only to converge, then prove with the checks. `lint --fix` rewrites code and its output is not formatter-clean, so a `format` that ran before it leaves `format:check` failing on the file `lint` rewrote:
|
|
105
105
|
|
|
106
106
|
```text
|
|
107
107
|
npm run format:check → npm run lint:check → npm run check → npm run build → npm test
|
package/dist/host/CLAUDE.md
CHANGED
|
@@ -53,3 +53,9 @@ follows it. This file adds only what Claude Code does differently, and cannot we
|
|
|
53
53
|
ChatGPT approval in the browser.
|
|
54
54
|
- `scripts/codex.sh` only reports readiness. It never installs, authenticates, logs out, reads the
|
|
55
55
|
auth cache, or performs a model call.
|
|
56
|
+
- `scripts/deps.sh` runs `npm ci --ignore-scripts` on every session start and resume whose
|
|
57
|
+
`package-lock.json` digest differs from `node_modules/.orkestrel-lock.sha256`, and a resume
|
|
58
|
+
follows every turn boundary. After a tracked command changes the lockfile in this checkout,
|
|
59
|
+
write the lockfile's SHA-256 digest to that marker in the same turn, before any unit or gate runs
|
|
60
|
+
here. A marker left stale reinstalls `node_modules` under a live suite on the next resume, and the
|
|
61
|
+
suite reports a missing package that is present a moment later.
|
|
@@ -138,7 +138,11 @@ Fall back in this order and record the substitution:
|
|
|
138
138
|
parallelism, independent review, or substantial context justifies it.
|
|
139
139
|
- Dispatch staging, packing, gate-chain invocation, and instrument authorship as units — `builder`
|
|
140
140
|
for a fully specified script, `verifier` for its evidence — each with a brief and an audit like
|
|
141
|
-
any other unit.
|
|
141
|
+
any other unit. The commit and the push stay with the Orchestrator.
|
|
142
|
+
- A release instrument installs, commits, or runs a mutating tree-wide command, which the
|
|
143
|
+
permission floor bars every role from, so its run is the Orchestrator's tracked command, retained
|
|
144
|
+
with its log as the authoring unit's acceptance evidence. An upload loop that must run inside a
|
|
145
|
+
one-time code's life with the user at the keyboard stays with the Orchestrator whole.
|
|
142
146
|
|
|
143
147
|
## Roles
|
|
144
148
|
|
|
@@ -265,13 +269,12 @@ edits, formatter and build races, cache phantoms, and validation cross-talk.
|
|
|
265
269
|
6. After integration, clear shared caches if needed, then have one independent `verifier` run the
|
|
266
270
|
authoritative tree-wide sweep. A writer's self-report never establishes green.
|
|
267
271
|
7. The Orchestrator's own sweep is a writing dispatch and queues behind the units that own those
|
|
268
|
-
files. A script that fixes one thing across every target is the
|
|
269
|
-
serialization rule,
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
mid-campaign rule under **Dispatch anatomy**. Never beside them.
|
|
272
|
+
files. A script that fixes one thing across every target is the most direct way to break the
|
|
273
|
+
serialization rule, because it does not feel like a dispatch — nobody was named, no brief was
|
|
274
|
+
written, and it finishes in seconds. It still writes into trees a live unit owns, and a unit
|
|
275
|
+
whose brief it invalidates will repair the same drift the other way and report a state that is
|
|
276
|
+
already false. Run it before the units, or after them, or send the decision to every unit in
|
|
277
|
+
flight per the mid-campaign rule under **Dispatch anatomy**. Never beside them.
|
|
275
278
|
8. A fleet pass that records a per-target status commits only the targets it recorded green. Reading
|
|
276
279
|
"is the tree dirty" instead of "did this target pass" pushes a red target the moment one exists,
|
|
277
280
|
and a flake makes that look like it worked. Refuse the failed row, name it, and re-run it alone
|
|
@@ -301,7 +304,7 @@ each CLI first (`codex --version`; `agent --version`, falling back to `agent.cmd
|
|
|
301
304
|
run the bench's authentication-state check where it exposes one. Neither answer is liveness. A
|
|
302
305
|
version string proves the binary is installed, and an authentication-state check reads stored
|
|
303
306
|
credentials, so both pass while the account is out of quota, while the routed model is unavailable to
|
|
304
|
-
it, while the server has already revoked the credential the check
|
|
307
|
+
it, while the server has already revoked the credential the check read, and inside a sandbox
|
|
305
308
|
with the network denied. Record a bench live only on a bounded round-tripped model call that came
|
|
306
309
|
back, and record what came back beside the routing decision. Probes are read-only, and the role file
|
|
307
310
|
owns each bench's exact probe.
|
|
@@ -362,7 +365,7 @@ longer holds.
|
|
|
362
365
|
plan did not consider; **unchanged**.
|
|
363
366
|
- Redraw the dependency order. Strike a unit whose subject a later unit deletes. State the new
|
|
364
367
|
prerequisite of a unit that acquired one.
|
|
365
|
-
- Walk the remaining units once and ask of each whether what
|
|
368
|
+
- Walk the remaining units once and ask of each whether what landed still supports it. A
|
|
366
369
|
decision taken inside a unit can remove a later unit's foundation, and the unit that took it
|
|
367
370
|
cannot see that.
|
|
368
371
|
- Re-baseline when a probe overturns a decision the plan rests on, not only at a phase boundary.
|
|
@@ -427,6 +430,8 @@ The harness bridge names the concrete mechanism for each of these.
|
|
|
427
430
|
so a report living only in the Orchestrator's context stops the next lane on arrival.
|
|
428
431
|
- Capture the unit's returned report to a file beside its brief under the same unit name, so a
|
|
429
432
|
unit's instruction and its outcome are one pair on disk.
|
|
433
|
+
- Name, inside a report that rests on a bench lane, that lane's journal path and session id, so
|
|
434
|
+
the provenance survives the journal's sweep.
|
|
430
435
|
- Amend a brief on re-run rather than restating it. A mid-campaign correction produces a successor
|
|
431
436
|
file recording what changed and why, and the original stays. A fix round's brief names the
|
|
432
437
|
findings it carries and where each came from.
|
|
@@ -604,7 +609,8 @@ command that outlives the turn that started it. Every law here binds all of them
|
|
|
604
609
|
byte offset rather than loading it, so an edit that shifts line numbers moves the text under that
|
|
605
610
|
offset and the shell resumes mid-construct. The run dies on a syntax error in a line the script
|
|
606
611
|
does not contain, which reads as a defect in the work rather than as the edit that caused it. Copy
|
|
607
|
-
the file, edit the copy, and launch the copy for the next run.
|
|
612
|
+
the file, edit the copy, and launch the copy for the next run. A successor's header names its own
|
|
613
|
+
file, its own log, and what changed from the file it supersedes.
|
|
608
614
|
- On a Windows host this binds every program-carrying command, not only long ones. Heredocs,
|
|
609
615
|
`node -e`, `node -p`, `&&` chaining, and any argument carrying `${...}` trip the Git Bash
|
|
610
616
|
approval classifier and turn an unattended run into a manual approval prompt. Write the program
|
|
@@ -848,9 +854,9 @@ either publishes packages nobody needed to publish or leaves a consumer pinned t
|
|
|
848
854
|
|
|
849
855
|
Every package is `0.0.x`, where a caret pins one exact release. A dependent therefore sees a new
|
|
850
856
|
version only after it re-pins and republishes, so the fleet publishes in topological layer order
|
|
851
|
-
derived from runtime `dependencies`
|
|
852
|
-
|
|
853
|
-
distinct types.
|
|
857
|
+
derived from the runtime `dependencies` and `peerDependencies` edges, never from a development
|
|
858
|
+
edge. Layers exist for a reason a flat pass cannot fix: ranges that disagree install duplicate
|
|
859
|
+
copies of the same package, and the compiler reads them as distinct types.
|
|
854
860
|
|
|
855
861
|
Read the order from the catalog table in `.claude/agents/orkestrel.md`, which `scaffold catalog`
|
|
856
862
|
regenerates from the registry. Its `Layer` column is the publish round. Regenerate it before
|
|
@@ -861,7 +867,9 @@ The tooling packages sit outside that order because nothing depends on them at r
|
|
|
861
867
|
is a development dependency of every package, including packages it depends on itself, so a runtime
|
|
862
868
|
layering would report a cycle that does not exist. Each package builds against the already-published
|
|
863
869
|
`scaffold`, never against an unpublished one, and a `scaffold` release therefore publishes on its own
|
|
864
|
-
and propagates as files rather than as a cascade.
|
|
870
|
+
and propagates as files rather than as a cascade. A package the fleet consumes as a development
|
|
871
|
+
dependency takes the same shape when its consumers' gates read its unpublished tip;
|
|
872
|
+
`.agents/skills/orkestrel-publish/references/wave.md` § Rule on the bump states that trigger.
|
|
865
873
|
|
|
866
874
|
`scaffold` also carries a second published surface beside `dist/src`: `package.json` ships
|
|
867
875
|
`dist/host`, the vendored file set every target receives through `repair`.
|
|
@@ -203,7 +203,7 @@ $utilities: map-merge(
|
|
|
203
203
|
@import 'bootstrap/scss/utilities/api';
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
-
Remove with `map-remove($utilities, "width")` or set the key to `null`. This is the sanctioned answer when the shipped scale is missing a step (
|
|
206
|
+
Remove with `map-remove($utilities, "width")` or set the key to `null`. This is the sanctioned answer when the shipped scale is missing a step (for example, a `vh-50` the design truly needs).
|
|
207
207
|
|
|
208
208
|
## Forms in Production
|
|
209
209
|
|
|
@@ -211,7 +211,7 @@ Remove with `map-remove($utilities, "width")` or set the key to `null`. This is
|
|
|
211
211
|
|
|
212
212
|
- **Top-aligned labels by default** — the evidence (eye-tracking form research) shows fastest completion and the cleanest single-column scan, and they survive narrow screens without reflow. Reserve left-aligned labels for dense read-back forms where vertical compression matters more than speed.
|
|
213
213
|
- Visible label or `.form-floating` — never placeholder-only (disappears on input, fails accessibility).
|
|
214
|
-
- **Do not say the same thing twice.** When the host already names the request — a card heading, a dialog title, a section header stating the question — the form associates with that name
|
|
214
|
+
- **Do not say the same thing twice.** When the host already names the request — a card heading, a dialog title, a section header stating the question — the form associates with that name through `aria-labelledby` instead of repeating the prompt in its own label. Repetition reads as separate questions to a screen-reader user and as clutter to everyone else.
|
|
215
215
|
- One column beats multi-column for completion; use the form grid (`row g-3` + `col-md-*`) only for genuinely paired fields (city/state/zip).
|
|
216
216
|
|
|
217
217
|
```html
|
|
@@ -237,7 +237,7 @@ Remove with `map-remove($utilities, "width")` or set the key to `null`. This is
|
|
|
237
237
|
- Once a field is in an error state, re-validate as the user types so they see the fix land.
|
|
238
238
|
- Always re-check everything on submit. Keep the submit button **enabled** — a disabled submit hides _what is_ wrong; a validating submit shows it.
|
|
239
239
|
- On failed submit of a long form, render an **error summary** at the top (focus it; link each item to its field) _and_ inline messages at each field — never summary-only, never inline-only.
|
|
240
|
-
- Error style = color + icon + text, stating what is wrong and how to fix it. Wire message to field with `aria-describedby`, mark the field `aria-invalid="true"`. Never report errors
|
|
240
|
+
- Error style = color + icon + text, stating what is wrong and how to fix it. Wire message to field with `aria-describedby`, mark the field `aria-invalid="true"`. Never report errors through a hover tooltip.
|
|
241
241
|
|
|
242
242
|
### Bootstrap validation mechanics
|
|
243
243
|
|
|
@@ -274,7 +274,7 @@ Client-side, the documented pattern:
|
|
|
274
274
|
</script>
|
|
275
275
|
```
|
|
276
276
|
|
|
277
|
-
**Documented limitation (enterprise-critical):** Bootstrap's client-side validation styles and `valid/invalid-tooltip`s are **not exposed to assistive technologies**. For accessible flows use the server-side pattern — apply `.is-invalid` / `.is-valid` directly (no `.was-validated` parent needed), with `.invalid-feedback` linked
|
|
277
|
+
**Documented limitation (enterprise-critical):** Bootstrap's client-side validation styles and `valid/invalid-tooltip`s are **not exposed to assistive technologies**. For accessible flows use the server-side pattern — apply `.is-invalid` / `.is-valid` directly (no `.was-validated` parent needed), with `.invalid-feedback` linked through `aria-describedby` — or rely on native browser validation.
|
|
278
278
|
|
|
279
279
|
```html
|
|
280
280
|
<input
|
|
@@ -290,7 +290,7 @@ Client-side, the documented pattern:
|
|
|
290
290
|
</div>
|
|
291
291
|
```
|
|
292
292
|
|
|
293
|
-
Details: input groups with feedback need `.has-validation` on the group (border-radius fix). `.valid-tooltip` and `.invalid-tooltip` need a `position-relative` parent. Validation colors are mode-adaptive
|
|
293
|
+
Details: input groups with feedback need `.has-validation` on the group (border-radius fix). `.valid-tooltip` and `.invalid-tooltip` need a `position-relative` parent. Validation colors are mode-adaptive through `--bs-form-valid-color`, `--bs-form-valid-border-color`, `--bs-form-invalid-color`, `--bs-form-invalid-border-color`.
|
|
294
294
|
|
|
295
295
|
### Autosave vs explicit save
|
|
296
296
|
|
|
@@ -498,7 +498,7 @@ Give header cells an **opaque background** (`bg-body-secondary` or a `.table-*`
|
|
|
498
498
|
```
|
|
499
499
|
|
|
500
500
|
- **Row actions:** 1–3 high-frequency actions inline; the rest behind a per-row kebab (dropdown). Hover-only reveal fails touch and keyboard — keep at least the overflow trigger always visible and ≥24px.
|
|
501
|
-
- **Selection & bulk actions:** header checkbox with indeterminate state for partial selection; per-row checkboxes with `aria-label` naming the row ("Select INV-1042"). When selection > 0, swap the toolbar's content in place for a contextual bar — "3 selected", the batch actions, and a clear-selection escape — never push the layout down (layout-shifting chrome is an anti-pattern). Announce the count
|
|
501
|
+
- **Selection & bulk actions:** header checkbox with indeterminate state for partial selection; per-row checkboxes with `aria-label` naming the row ("Select INV-1042"). When selection > 0, swap the toolbar's content in place for a contextual bar — "3 selected", the batch actions, and a clear-selection escape — never push the layout down (layout-shifting chrome is an anti-pattern). Announce the count through a polite live region.
|
|
502
502
|
- **Pagination vs scrolling:** paginate when users need position, totals, deep links, and "go to page N" — most enterprise CRUD. Virtualize (windowed rendering) for long uniform lists where scrolling is natural. True infinite scroll is for exploratory feeds only — never where users need a footer or a findable end.
|
|
503
503
|
- **Responsive, ranked:** (1) _priority columns_ — hide low-value columns per breakpoint (`d-none d-lg-table-cell`), always keeping the identifying + decision columns; (2) _horizontal scroll_ (`table-responsive`) when every column matters — remember it clips dropdowns; (3) _card-ify_ into label:value stacks below `md` for low row counts. Never card-ify a wide comparison table — comparison is the point.
|
|
504
504
|
- **Table states:** loading → **skeleton rows** matching the real column count/widths (a centered spinner collapses the layout); empty → distinguish _no data yet_ (invite the first action) from _no results for these filters_ (offer "Clear filters"); error → inline retry inside the table region, header and toolbar preserved.
|
|
@@ -532,12 +532,12 @@ Design **every one** for every data surface: ideal (populated), empty, loading,
|
|
|
532
532
|
|
|
533
533
|
### Feedback discipline
|
|
534
534
|
|
|
535
|
-
| Channel | Use for
|
|
536
|
-
| ----------------------------- |
|
|
537
|
-
| **Toast** | Transient confirmation of a
|
|
538
|
-
| **Inline alert** | Feedback tied to a specific field/section/action; persists in context
|
|
539
|
-
| **Banner** (page-level alert) | Persistent page/app conditions — outage, trial expiring, permissions
|
|
540
|
-
| **Modal / alertdialog** | Blocking decisions the user must resolve now
|
|
535
|
+
| Channel | Use for | Never for |
|
|
536
|
+
| ----------------------------- | --------------------------------------------------------------------------------------------- | -------------------------------------------------- |
|
|
537
|
+
| **Toast** | Transient confirmation of an action that finished a moment ago; auto-dismiss; `role="status"` | Errors needing action; anything the user must read |
|
|
538
|
+
| **Inline alert** | Feedback tied to a specific field/section/action; persists in context | App-wide conditions |
|
|
539
|
+
| **Banner** (page-level alert) | Persistent page/app conditions — outage, trial expiring, permissions | Action confirmations |
|
|
540
|
+
| **Modal / alertdialog** | Blocking decisions the user must resolve now | FYIs, success messages |
|
|
541
541
|
|
|
542
542
|
Blocking errors are never toasts. Keep the acting verb consistent across the flow: the "Publish" button confirms with "Published".
|
|
543
543
|
|
|
@@ -555,7 +555,7 @@ Do not type-gate a single-row delete; do not one-tap a tenant wipe. Confirm only
|
|
|
555
555
|
|
|
556
556
|
## RTL
|
|
557
557
|
|
|
558
|
-
- Enable per page: `<html lang="ar" dir="rtl">` + the RTL stylesheet `bootstrap.rtl.min.css` (built from the same source
|
|
558
|
+
- Enable per page: `<html lang="ar" dir="rtl">` + the RTL stylesheet `bootstrap.rtl.min.css` (built from the same source through RTLCSS). RTL support is documented as experimental.
|
|
559
559
|
- The logical properties model is why the utilities say start/end: `ms-*`/`me-*`, `ps-*`/`pe-*`, `text-start`/`text-end`, `float-start`/`float-end`, `offcanvas-start`/`end` all flip automatically. **Never write `left`/`right` positioning or physical margins in custom CSS** — use logical properties (`margin-inline-start`, `inset-inline-end`) so your custom rules flip too.
|
|
560
560
|
- Caveats: shipping LTR+RTL simultaneously costs significant extra CSS; the breadcrumb divider needs `$breadcrumb-divider-flipped`; source Sass can embed RTLCSS directives (`/* rtl: … */`) for value swaps like font stacks.
|
|
561
561
|
|
|
@@ -563,13 +563,13 @@ Do not type-gate a single-row delete; do not one-tap a tenant wipe. Confirm only
|
|
|
563
563
|
|
|
564
564
|
- Hide chrome, keep the data: `d-print-none` on nav, sidebars, toolbars, action buttons; the report/table itself stays printable.
|
|
565
565
|
- `d-print-block`/`d-print-table` can resurface content hidden on screen (a print-only header with report title/date).
|
|
566
|
-
- Print-check data screens users will export: collapse interactive affordances (sort carets, checkboxes)
|
|
566
|
+
- Print-check data screens users will export: collapse interactive affordances (sort carets, checkboxes) through `d-print-none`, and prefer `table-bordered` legibility over hover/stripe effects that may not print.
|
|
567
567
|
|
|
568
568
|
## Performance
|
|
569
569
|
|
|
570
570
|
- **Ship one CSS system and no more.** Bootstrap plus a second framework (or a parallel bespoke layer) doubles payload and guarantees specificity fights.
|
|
571
|
-
- **Compressed, the full build is cheap; incomplete builds are not.** Trimming
|
|
572
|
-
- **Icons:** Bootstrap Icons is a separate package — prefer inline SVG or an SVG sprite (crisp, styleable
|
|
571
|
+
- **Compressed, the full build is cheap; incomplete builds are not.** Trimming through a Sass-subset build (import only the parts used — see [Theming](#theming--design-tokens)) is the sanctioned diet. Aggressive purge tools are the risky one: Bootstrap adds classes **at runtime** (`show`, `showing`, `fade`, `collapsing`, `modal-open`, `modal-backdrop`, `offcanvas-backdrop`, tooltip/popover generated markup) — purging without safelisting them ships UIs whose modals silently stop rendering. If you purge, safelist every JS-toggled class and test every overlay.
|
|
572
|
+
- **Icons:** Bootstrap Icons is a separate package — prefer inline SVG or an SVG sprite (crisp, styleable through `currentColor`, no font flash) over the icon font; load only the icons used.
|
|
573
573
|
- **JS:** the bundle is small, but only load it where behavior exists; per-component ESM imports (`bootstrap/js/dist/modal`) trim further in bundlers.
|
|
574
574
|
- **Fonts:** each display face is a payload decision; subset and `font-display: swap` characterful faces, and let the data face fall back to the system stack when the brief allows.
|
|
575
575
|
|
|
@@ -57,7 +57,7 @@ product's, and keep the data surfaces disciplined and conventional enough to rea
|
|
|
57
57
|
|
|
58
58
|
## Process: brainstorm, explore, plan, critique, build, critique again
|
|
59
59
|
|
|
60
|
-
Calibrate against the looks AI-generated design
|
|
60
|
+
Calibrate against the looks AI-generated design clusters around: (1) a warm cream
|
|
61
61
|
background (near #F4F1EA) with a high-contrast serif display and a terracotta accent; (2) a
|
|
62
62
|
near-black background with a single bright acid-green or vermilion accent; (3) a broadsheet-style
|
|
63
63
|
layout with hairline rules, zero border-radius, and dense newspaper-like columns. Each is
|
|
@@ -81,8 +81,8 @@ only once the plan is specific to this brief, then follow the revised plan exact
|
|
|
81
81
|
color and type decision from it.
|
|
82
82
|
|
|
83
83
|
Structure your CSS selector specificities deliberately when writing the code. Classes cancel each
|
|
84
|
-
other out
|
|
85
|
-
|
|
84
|
+
other out, especially a type-based selector like `.section` against an element-based selector like
|
|
85
|
+
`.cta`, and the padding and margin between sections is where it happens most.
|
|
86
86
|
|
|
87
87
|
Do this planning and iteration in your thinking. Show the user a direction only once it satisfies
|
|
88
88
|
the brief and the quality floor below.
|
|
@@ -103,9 +103,9 @@ reads it.
|
|
|
103
103
|
|
|
104
104
|
## Writing in design
|
|
105
105
|
|
|
106
|
-
Keep a word only where it
|
|
107
|
-
the same intentionality to copy as to spacing and color. Before writing anything, decide what
|
|
108
|
-
design needs to say, and how to say it so the person can navigate the experience.
|
|
106
|
+
Keep a word only where it helps the reader understand the design, and so use it.
|
|
107
|
+
Bring the same intentionality to copy as to spacing and color. Before writing anything, decide what
|
|
108
|
+
the design needs to say, and how to say it so the person can navigate the experience.
|
|
109
109
|
|
|
110
110
|
Write from the end user's side of the screen. Name things by what people control and recognize,
|
|
111
111
|
never by how the system is built: a person manages notifications, not webhook config. Describe what
|
|
@@ -162,7 +162,7 @@ For borders that must stay visible in both color modes, prefer the `border-*-sub
|
|
|
162
162
|
|
|
163
163
|
### Sizing
|
|
164
164
|
|
|
165
|
-
Bootstrap ships exactly these — nothing else (no `.vw-25`, `.vh-50`, `.mw-auto`, `.min-vh-75
|
|
165
|
+
Bootstrap ships exactly these — nothing else (no `.vw-25`, `.vh-50`, `.mw-auto`, or `.min-vh-75`; add missing steps through the utilities API if a project truly needs them — see [bootstrap-reference.md](bootstrap-reference.md)):
|
|
166
166
|
|
|
167
167
|
```css
|
|
168
168
|
/* Width / height (percent of parent) */
|
|
@@ -288,12 +288,12 @@ Helpers are single-purpose classes that sit alongside utilities.
|
|
|
288
288
|
|
|
289
289
|
- **`.visually-hidden`** — hide visually, keep for screen readers (icon-button labels, table caption text, "Danger:" prefixes).
|
|
290
290
|
- **`.visually-hidden-focusable`** — hidden until focused; the skip-link class. Never combine with `.visually-hidden`.
|
|
291
|
-
- **`.stretched-link`** — makes a whole `position-relative` container (
|
|
291
|
+
- **`.stretched-link`** — makes a whole `position-relative` container (for example, a card) the click target of one inner link, without wrapping everything in `<a>`.
|
|
292
292
|
- **`.ratio .ratio-16x9`** (also `1x1`, `4x3`, `21x9`, or `--bs-aspect-ratio`) — responsive embeds/iframes.
|
|
293
293
|
- **`.vstack` / `.hstack gap-*`** — shorthand vertical/horizontal flex stacks for quick toolbars and side rails.
|
|
294
294
|
- **`.vr`** — vertical rule divider inside an `.hstack` or flex row.
|
|
295
|
-
- **`.focus-ring`** (+ `.focus-ring-primary` … per theme color) — opt-in focus ring for custom interactive elements; tune
|
|
296
|
-
- **`.icon-link`** (+ `.icon-link-hover`) — pairs a Bootstrap Icon SVG with a text link; icon auto-sizes to 1em; give decorative icons `aria-hidden="true"`. Hover shift
|
|
295
|
+
- **`.focus-ring`** (+ `.focus-ring-primary` … per theme color) — opt-in focus ring for custom interactive elements; tune through `--bs-focus-ring-width` (.25rem), `--bs-focus-ring-opacity` (.25), `--bs-focus-ring-color`, `--bs-focus-ring-x/y/blur`. Use it instead of `outline: none` hacks so keyboard focus stays visible.
|
|
296
|
+
- **`.icon-link`** (+ `.icon-link-hover`) — pairs a Bootstrap Icon SVG with a text link; icon auto-sizes to 1em; give decorative icons `aria-hidden="true"`. Hover shift through `--bs-icon-link-transform`.
|
|
297
297
|
|
|
298
298
|
## Enterprise notes (utilities)
|
|
299
299
|
|
|
@@ -8,10 +8,10 @@ model consumes.
|
|
|
8
8
|
Test from the top down, and do not stop at the tier that passes:
|
|
9
9
|
|
|
10
10
|
1. **Frontier** (the harness's default model) — proves the surface works at all.
|
|
11
|
-
2. **Mid tier** (
|
|
12
|
-
schema abbreviation and a model that reads less carefully.
|
|
13
|
-
3. **Small harness-native** (
|
|
14
|
-
tier: these must walk the surface unaided, or the surface is not done.
|
|
11
|
+
2. **Mid tier** (for example, a codex mechanical model) — proves the surface survives a
|
|
12
|
+
harness's schema abbreviation and a model that reads less carefully.
|
|
13
|
+
3. **Small harness-native** (for example, Haiku or a codex high-volume model) — the
|
|
14
|
+
acceptance tier: these must walk the surface unaided, or the surface is not done.
|
|
15
15
|
4. **Local floor** (a quantized 2B-class model through a real tool-calling client) — not
|
|
16
16
|
an acceptance gate; a stochastic probe that exposes teaching gaps nothing else hits.
|
|
17
17
|
Its residual failures must be provably consumer-floor (malformed emission, attention
|
|
@@ -29,7 +29,7 @@ Test from the top down, and do not stop at the tier that passes:
|
|
|
29
29
|
- **Caps and journals.** Every pass runs as a tracked background command under a hard
|
|
30
30
|
time cap with its transcript journaled; the journal is the evidence of record.
|
|
31
31
|
|
|
32
|
-
## Capture the reasoning, not
|
|
32
|
+
## Capture the reasoning, not the calls alone
|
|
33
33
|
|
|
34
34
|
Where the runtime exposes thinking (local runtimes expose it directly; harness stream
|
|
35
35
|
formats carry interstitial text), record it. The call log shows WHAT failed; the trace
|
|
@@ -120,7 +120,7 @@ leaves this round is the procedure.
|
|
|
120
120
|
|
|
121
121
|
When a round certifies an instrument — a pin, an identity check, a generated sweep — the controls
|
|
122
122
|
are usually drawn from whatever the instrument obviously covers, because that is where the examples
|
|
123
|
-
|
|
123
|
+
take the least construction. That sampling proves discrimination _within_ the population and is
|
|
124
124
|
routinely reported as proof the instrument works.
|
|
125
125
|
|
|
126
126
|
So before running controls, write down the instrument's **membership rule** in one sentence, then
|
|
@@ -10,8 +10,9 @@ description: Run an Orkestrel release from layer order to registry confirmation.
|
|
|
10
10
|
Read the current files in this order:
|
|
11
11
|
|
|
12
12
|
1. `AGENTS.md` and every applicable `.claude/rules/*.md` file.
|
|
13
|
-
2. `.agents/orchestration.md` § Publishing the fleet
|
|
14
|
-
section binds every step
|
|
13
|
+
2. `.agents/orchestration.md` § Publishing the fleet, § Long-running commands, § Orchestrator and
|
|
14
|
+
executor, § Writing concurrency, and § Dispatch anatomy. Each named section binds every step
|
|
15
|
+
here.
|
|
15
16
|
3. The reference the moment needs: [wave.md](references/wave.md) before visiting a repository,
|
|
16
17
|
ruling on a bump, or preparing a layer; [window.md](references/window.md) before running
|
|
17
18
|
`npm login` or any upload.
|
|
@@ -42,21 +43,17 @@ following the skill.
|
|
|
42
43
|
Derive each pin from that reading, never from a local manifest.
|
|
43
44
|
3. **Visit each repository.** Run the visit in [wave.md](references/wave.md) in its stated order,
|
|
44
45
|
in parallel slices of disjoint repositories, each slice serial inside itself.
|
|
45
|
-
4. **Rule on each package's bump.** Apply the triggers in [wave.md](references/wave.md)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
run each package's own `prepublishOnly` to green, commit, and push. Every one of those steps
|
|
50
|
-
happens outside the window.
|
|
46
|
+
4. **Rule on each package's bump.** Apply the triggers in [wave.md](references/wave.md) § Rule on
|
|
47
|
+
the bump; the contract's § What a bump obliges owns the blast radius.
|
|
48
|
+
5. **Prepare the whole layer before authenticating**, in the order [wave.md](references/wave.md)
|
|
49
|
+
§ Prepare a layer fixes. Every one of those steps happens outside the window.
|
|
51
50
|
6. **Reach the approval.** Follow [window.md](references/window.md), and launch the login chain
|
|
52
51
|
only after the user signals they are at the keyboard.
|
|
53
52
|
7. **Authorize and upload.** Follow [window.md](references/window.md). Take the account's one-time
|
|
54
|
-
code where it has one
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
install until the version it names exists, so preparation and publication interleave and cannot
|
|
59
|
-
be batched ahead.
|
|
53
|
+
code where it has one; § Authorize the upload there fixes that code's life and the layer it
|
|
54
|
+
carries. Where the account answers with no code, follow § Spend the window there.
|
|
55
|
+
8. **Close the layer from the registry, then prepare the next**, per [wave.md](references/wave.md)
|
|
56
|
+
§ Prepare a layer.
|
|
60
57
|
|
|
61
58
|
Run that sequence for every layer, from the registry reading to the registry close. Refresh the
|
|
62
59
|
registry evidence between layers rather than carrying the previous round's reading forward.
|
|
@@ -71,7 +68,10 @@ Completion requires:
|
|
|
71
68
|
that section requires;
|
|
72
69
|
- every tarball swap is restored per § Fixing a dependency before it publishes, and no target
|
|
73
70
|
repository is left holding an uncommitted bump or an unpushed commit;
|
|
74
|
-
- every gate that proved a package ran outside the window and against the artifact that shipped
|
|
71
|
+
- every gate that proved a package ran outside the window and against the artifact that shipped;
|
|
72
|
+
- every gate red at a package's baseline for a cause `ROADMAP.md` already carries is recorded as a
|
|
73
|
+
standing reading beside the package's row with its carrier, and the release report names it. A
|
|
74
|
+
standing reading is not a gate the release ran.
|
|
75
75
|
|
|
76
76
|
Report the layers in publish order, each package with its registry-confirmed version, the bump
|
|
77
77
|
rulings and their evidence, the approvals the user granted, and anything still unpublished. End
|
|
@@ -10,9 +10,11 @@ prepare the next.
|
|
|
10
10
|
Run the visit in this order. A step that reads generated or installed state is invalid before the
|
|
11
11
|
step that writes it.
|
|
12
12
|
|
|
13
|
-
1. Re-pin
|
|
14
|
-
current vendored host.
|
|
15
|
-
2.
|
|
13
|
+
1. Re-pin every `@orkestrel` range to the registry caret (peer ranges included) and install, so
|
|
14
|
+
the overwrite runs the current vendored host.
|
|
15
|
+
2. Commit the manifest and the lockfile as the preparation commit. `scaffold overwrite` refuses a
|
|
16
|
+
tree carrying uncommitted changes, and the install left both dirty.
|
|
17
|
+
3. Run `scaffold overwrite`. One run repairs the `AGENTS.md` and `CLAUDE.md` pointers and deletes
|
|
16
18
|
every tracked copy the target still holds at an instruction-canon path. Prove the sweep with a
|
|
17
19
|
second `scaffold audit` that exits `0`.
|
|
18
20
|
- Where the target's `.claude/agents/orkestrel.md` carries a body outside the marker-bounded
|
|
@@ -30,12 +32,16 @@ step that writes it.
|
|
|
30
32
|
rather than waiving past it.
|
|
31
33
|
- A copy the target git-ignores stays a `foreign` finding, so that target never reaches exit `0`
|
|
32
34
|
again. Keep a local MCP server registration outside the repository rather than at `.mcp.json`.
|
|
33
|
-
|
|
35
|
+
4. Force-verify every `@orkestrel` range against a registry sweep taken after the previous layer
|
|
34
36
|
published.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
6.
|
|
38
|
-
7.
|
|
37
|
+
5. Run the full install. The overwrite re-declares the toolchain ranges, so the lockfile the first
|
|
38
|
+
install regenerated no longer matches the manifest.
|
|
39
|
+
6. Sweep the self-pins, per § Sweep the self-pins: the re-pin moves the snapshot class.
|
|
40
|
+
7. Run the mutating `format` script to converge generated writes.
|
|
41
|
+
8. Run the quality gates.
|
|
42
|
+
9. Fetch the published tarball, then compare the rebuilt `dist/` against it for material content.
|
|
43
|
+
An absent baseline is an unanswered comparison, never a moved dist: fetch and re-run rather than
|
|
44
|
+
ruling a bump owed.
|
|
39
45
|
|
|
40
46
|
Restore any unpublished tarball the target is holding before the quality gates run, per
|
|
41
47
|
`.agents/orchestration.md` § Fixing a dependency before it publishes. A distribution proof run
|
|
@@ -69,7 +75,15 @@ final runtime dependency set differs from the published packument.
|
|
|
69
75
|
per package rather than assuming it: a package that imports its own `package.json` version into
|
|
70
76
|
published code emits that version, so its pre-bump dist is stale the moment the version moves.
|
|
71
77
|
Rebuild after the bump there and pack from the rebuilt tree. The `npm publish --ignore-scripts`
|
|
72
|
-
command skips `prepack`, so that rebuild is the operator's step rather than the publish's.
|
|
78
|
+
command skips `prepack`, so that rebuild is the operator's step rather than the publish's. The
|
|
79
|
+
same holds for a package that writes its declared ranges into published output: its `dist/`
|
|
80
|
+
moves on a development re-pin, and `.agents/orchestration.md` § What a bump obliges rules that
|
|
81
|
+
re-pin a release.
|
|
82
|
+
|
|
83
|
+
One trigger orders rather than bumps. A package the fleet consumes as a development dependency,
|
|
84
|
+
whose consumers' gates read its unpublished tip, publishes on its own account ahead of the layer
|
|
85
|
+
order and again at its own slot after its runtime ranges move: each consumer's visit installs the
|
|
86
|
+
registry copy over any staged tip, so every consumer stays red until that tip is on the registry.
|
|
73
87
|
|
|
74
88
|
## Prepare a layer
|
|
75
89
|
|
|
@@ -77,16 +91,22 @@ An unpublished package's first version is `0.0.1`. Do not bump it before that fi
|
|
|
77
91
|
registry has nothing to serve, so there is no version to move away from, and bumping produces a
|
|
78
92
|
package whose history starts at a number nothing explains.
|
|
79
93
|
|
|
80
|
-
Prepare a published package's layer in this order:
|
|
94
|
+
Prepare a published package's layer in this order, after the visit has ruled the package's bump:
|
|
81
95
|
|
|
82
96
|
1. **Bump from what the registry serves, not from the local manifest.** A repository's `version`
|
|
83
97
|
field can sit a release behind what was published from another checkout, and bumping that
|
|
84
98
|
produces a version the registry already holds, which fails on upload after the whole gate chain
|
|
85
99
|
has run. Read the registry first.
|
|
86
|
-
2. **Re-pin every `@orkestrel` range to what the registry serves, and install.**
|
|
87
|
-
|
|
100
|
+
2. **Re-pin every `@orkestrel` range to what the registry serves, and install.** The visit's
|
|
101
|
+
preparation commit already precedes the overwrite; this install regenerates the lockfile for the
|
|
102
|
+
bumped manifest.
|
|
103
|
+
3. **Sweep the self-pins**, per the following section: the bump moves the version class.
|
|
88
104
|
4. **Run each package's own `prepublishOnly` script to green.**
|
|
89
|
-
5. **
|
|
105
|
+
5. **Write the release commit and push before the window opens.** The preparation commit inside
|
|
106
|
+
the visit is a different commit at a different moment.
|
|
107
|
+
|
|
108
|
+
Where an inventory taken before the round already ruled every dist moved, the bump rides the
|
|
109
|
+
visit's first step and these steps fold into the visit, whose comparison then confirms the ruling.
|
|
90
110
|
|
|
91
111
|
Prepare the next layer only after this one is on the registry. A dependent's new pin cannot
|
|
92
112
|
install until the version it names exists, so preparation and publication interleave and cannot be
|
|
@@ -99,12 +119,17 @@ the flag is what stops the gate chain running a second time inside the five minu
|
|
|
99
119
|
## Sweep the self-pins
|
|
100
120
|
|
|
101
121
|
A package's own version appears in its source and its tests as a literal, and a bump falsifies
|
|
102
|
-
every one of them.
|
|
122
|
+
every one of them. A snapshot of generated output carries the ranges the package writes rather than
|
|
123
|
+
its own version, and any re-pin, a development one included, falsifies it. Run this sweep after the
|
|
124
|
+
re-pin install, not after the manifest edit.
|
|
103
125
|
|
|
104
|
-
-
|
|
105
|
-
|
|
126
|
+
- Search `tests/` and `src/` in the publishing package for the prior version literal, and rule on
|
|
127
|
+
every hit. A canned packument in a fixture and a looked-up version in a CLI suite carry the
|
|
106
128
|
version with no tripwire comment beside them, so they surface as a red gate after the bump
|
|
107
129
|
rather than as a planned edit before it.
|
|
130
|
+
- Search `tests/` for the prior range of every re-pinned dependency, and move each snapshot the
|
|
131
|
+
search hits with the re-pin. A generated-manifest fixture never carries the package's own prior
|
|
132
|
+
version, so the version sweep cannot reach it.
|
|
108
133
|
- Move a documented tripwire — a golden digest over generated output — in the same change as the
|
|
109
134
|
version bump. That is what the tripwire is for.
|
|
110
135
|
- Re-take a generated artifact's digest after the install, because the generated bytes can derive
|
|
@@ -120,4 +145,5 @@ every one of them. Run this sweep after the re-pin install, not after the manife
|
|
|
120
145
|
|
|
121
146
|
Refresh the registry evidence between layers and derive each round's pins from it. A pin can only
|
|
122
147
|
name a version the registry already serves, so a dependency shipping in the same window keeps the
|
|
123
|
-
resolvable previous pin and takes its development-only re-pin after the window closes.
|
|
148
|
+
resolvable previous pin and takes its development-only re-pin after the window closes. That re-pin
|
|
149
|
+
takes the self-pin sweep too, because the snapshot class moves with no bump.
|