@techgoblin/gobstack 0.4.4-beta.7 → 0.5.0-beta.1
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 +28 -12
- package/VERSION +1 -1
- package/bin/goblin-audit +1 -1
- package/bin/goblin-bans +9 -1
- package/bin/goblin-init +55 -37
- package/bin/goblin-install +100 -12
- package/bin/goblin-lib.sh +59 -1
- package/bin/goblin-upgrade +1 -1
- package/bin/goblin-verify +52 -11
- package/docs/ADOPTION.md +42 -37
- package/docs/CI.md +11 -8
- package/docs/CONTRACTS.md +30 -15
- package/docs/ENFORCEMENT.md +24 -20
- package/docs/GUIDE.md +37 -33
- package/docs/LIMITS.md +20 -3
- package/manifest/classes.tsv +50 -60
- package/package.json +1 -1
- package/presets/electron-overlay.yaml +38 -0
- package/presets/{E-fleet-config.yaml → fleet.yaml} +1 -1
- package/presets/{C-game.yaml → game.yaml} +1 -1
- package/presets/{D-knowledge.yaml → research.yaml} +1 -1
- package/presets/{B-service-config.yaml → service.yaml} +1 -1
- package/presets/{A-shipped-software.yaml → software.yaml} +1 -1
- package/skills/goblin-bootstrap/SKILL.md +15 -7
- package/templates/AGENTS.md.tmpl +14 -5
- package/templates/goblin.yaml.tmpl +9 -1
- package/presets/F-electron.yaml +0 -67
package/docs/LIMITS.md
CHANGED
|
@@ -111,7 +111,7 @@ deliberate trade or an unfilled gap.
|
|
|
111
111
|
drift check — `IN-02`, `SK-02`, and `HS-01`'s hash of the harness dir — reads its expected
|
|
112
112
|
hash out of that one file, and that file is the one file no check protects. Measured: append a
|
|
113
113
|
byte to `.goblin/bin/goblin-verify`, rewrite its recorded hash in `installed.json`, commit, and
|
|
114
|
-
the run is **fully GREEN** (`
|
|
114
|
+
the run is **fully GREEN** (`38 passed, 0 failed`, exit 0). One edit defeats three rows at
|
|
115
115
|
once, and it is the cheapest way to fake a green run. Doing better needs an anchor the target
|
|
116
116
|
cannot edit — a signature, or a hash held outside the repo — and goblin-stack has no such
|
|
117
117
|
trust root: the source checkout is not guaranteed to exist at verify time, and any value
|
|
@@ -275,7 +275,8 @@ Electron perf number is a host gate, and the ratchet deliberately carries a diff
|
|
|
275
275
|
flow-style `jobs: {…}` mapping is refused, and a `#` inside a quoted string truncates the line
|
|
276
276
|
it is on. Two further measured gaps: the template's job is `ubuntu-latest` with no cache, so a
|
|
277
277
|
repo whose gate needs a display, a licence, a GPU or a signed-in session cannot use it at all
|
|
278
|
-
(that is a **host** gate — the class-C rule, restated for class F
|
|
278
|
+
(that is a **host** gate — the class-C rule, restated for class F; **corrected 2026-10-02 (W6):**
|
|
279
|
+
F is merged into `software`, so this is the electron opt-in), and a private repo's
|
|
279
280
|
Actions minutes are billed to the account (2,000/month free). Measured ground truth at W4:
|
|
280
281
|
**one** first-party workflow exists in the whole estate and it self-skips; five of the six
|
|
281
282
|
repos with a remote have none.
|
|
@@ -295,7 +296,9 @@ Electron perf number is a host gate, and the ratchet deliberately carries a diff
|
|
|
295
296
|
while the main thread went from 1.8 % to 54.5 % busy, `docs/CI.md` §3.3); an absolute FPS
|
|
296
297
|
claim is not. Three further Electron failure modes are **recorded, not mechanised**, and
|
|
297
298
|
`docs/CI.md` §4 says why: the dependency-graph boundary check, `ipcMain` sender validation,
|
|
298
|
-
and fuses at package time.
|
|
299
|
+
and fuses at package time. **Corrected 2026-10-02 (W6):** this preset is now
|
|
300
|
+
`presets/electron-overlay.yaml`, rendered over `presets/software.yaml` by `--electron` (or the
|
|
301
|
+
`desktop`/`F` install alias) — the old `F` class was merged into `software`.
|
|
299
302
|
36. **A ban's exemption reaches the probe through its environment, so a custom probe can ignore it.**
|
|
300
303
|
`bans_exempt:` and the inline `// BAN-OK(<id>): <reason>` are filtered *before* the exit code is
|
|
301
304
|
chosen, because a filter applied to a probe's stdout afterwards cannot change a verdict — that
|
|
@@ -589,3 +592,17 @@ the Node the gates ran under.
|
|
|
589
592
|
a source row can never fail a user's repo, and a target row can never substitute for the
|
|
590
593
|
framework's own suite. Recorded as a definition; `docs/ENFORCEMENT.md`'s scope paragraph
|
|
591
594
|
carries the same sentence for the reader who arrives there first.
|
|
595
|
+
|
|
596
|
+
53. **The sixth class is gone: the desktop shell is `software` + `electron: true`, and `A`..`E` are
|
|
597
|
+
read-time aliases.** W6 merged `F` into `software` because their `manifest/classes.tsv` need
|
|
598
|
+
columns were measured identical on all ten parts — the old column added config (the electron
|
|
599
|
+
`bans:`, the `perf.host_gate:`, the `app_bundle_bytes` ratchet, the `dist out release`
|
|
600
|
+
build-output scope), never a part. Measured on the merge tree (2026-10-02): the tsv is 50 rows
|
|
601
|
+
over five classes; `gob init --class desktop`, `--class F` and `--class software --electron`
|
|
602
|
+
render byte-identical `goblin.yaml` (`class: software`, `electron: true`); and a pre-merge repo
|
|
603
|
+
carrying `class: F` with no `electron:` key verifies unchanged, `38 passed, 0 failed, 11
|
|
604
|
+
advisory, 33 skipped`, exit 0, with `git status --porcelain` empty — zero writes, because its
|
|
605
|
+
bans and host gate live in its own config. What this costs, recorded rather than fixed: such a
|
|
606
|
+
repo gets the merge's declaration-time host-gate check only after hand-adding `electron: true`;
|
|
607
|
+
its bans and host gate keep running either way, so nothing fails closed, and the CLI keeps
|
|
608
|
+
accepting `desktop`/`F` as aliases.
|
package/manifest/classes.tsv
CHANGED
|
@@ -1,61 +1,51 @@
|
|
|
1
1
|
class part need
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
C tokens -
|
|
53
|
-
D tokens -
|
|
54
|
-
E tokens -
|
|
55
|
-
F tokens O
|
|
56
|
-
A ci-gate R
|
|
57
|
-
B ci-gate -
|
|
58
|
-
C ci-gate O
|
|
59
|
-
D ci-gate -
|
|
60
|
-
E ci-gate O
|
|
61
|
-
F ci-gate R
|
|
2
|
+
software handoff R
|
|
3
|
+
service handoff R
|
|
4
|
+
game handoff R
|
|
5
|
+
research handoff R
|
|
6
|
+
fleet handoff R
|
|
7
|
+
software spec R
|
|
8
|
+
service spec R
|
|
9
|
+
game spec R
|
|
10
|
+
research spec -
|
|
11
|
+
fleet spec R
|
|
12
|
+
software gate R
|
|
13
|
+
service gate R
|
|
14
|
+
game gate R
|
|
15
|
+
research gate O
|
|
16
|
+
fleet gate R
|
|
17
|
+
software replay R
|
|
18
|
+
service replay -
|
|
19
|
+
game replay R
|
|
20
|
+
research replay -
|
|
21
|
+
fleet replay O
|
|
22
|
+
software ratchet R
|
|
23
|
+
service ratchet O
|
|
24
|
+
game ratchet O
|
|
25
|
+
research ratchet -
|
|
26
|
+
fleet ratchet O
|
|
27
|
+
software pr-gate O
|
|
28
|
+
service pr-gate -
|
|
29
|
+
game pr-gate O
|
|
30
|
+
research pr-gate -
|
|
31
|
+
fleet pr-gate O
|
|
32
|
+
software review-panel O
|
|
33
|
+
service review-panel -
|
|
34
|
+
game review-panel R
|
|
35
|
+
research review-panel -
|
|
36
|
+
fleet review-panel O
|
|
37
|
+
software playbooks R
|
|
38
|
+
service playbooks R
|
|
39
|
+
game playbooks R
|
|
40
|
+
research playbooks R
|
|
41
|
+
fleet playbooks R
|
|
42
|
+
software tokens O
|
|
43
|
+
service tokens -
|
|
44
|
+
game tokens -
|
|
45
|
+
research tokens -
|
|
46
|
+
fleet tokens O
|
|
47
|
+
software ci-gate R
|
|
48
|
+
service ci-gate -
|
|
49
|
+
game ci-gate O
|
|
50
|
+
research ci-gate -
|
|
51
|
+
fleet ci-gate O
|
package/package.json
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# presets/electron-overlay.yaml — the electron opt-in for the `software` class.
|
|
2
|
+
#
|
|
3
|
+
# The `desktop` class is gone; F was merged into software because their classes.tsv need
|
|
4
|
+
# columns are IDENTICAL on all 10 parts (measured). Everything F added beyond software lives in
|
|
5
|
+
# plain goblin.yaml config keys, so it is an OVERLAY, not a class: `gob install --class software
|
|
6
|
+
# --electron` (or the `--class desktop` / `F` alias, which sets --electron) renders the keys
|
|
7
|
+
# below OVER the software preset. An absent key falls through to presets/software.yaml; a key
|
|
8
|
+
# present here — including an empty one like sec_write_routes: "" — wins.
|
|
9
|
+
#
|
|
10
|
+
# The prose F carried (label / done_means / notes) is preserved here for the record; it is not a
|
|
11
|
+
# rendered template key, so it never reaches a target's goblin.yaml.
|
|
12
|
+
label: Desktop shell
|
|
13
|
+
done_means: the renderer is isolated from Node, the main process is not busy, and the packaged bundle ships no dev dependency
|
|
14
|
+
# software's A-only second gate (the TODO ceiling) is NOT applied: F never had it.
|
|
15
|
+
gate2_name: ""
|
|
16
|
+
gate2_cmd: ""
|
|
17
|
+
# The perf lane is the shipped ratchet, reused verbatim; the hermetic number here is the
|
|
18
|
+
# packaged bundle's byte count (a fat bundle is a slow cold start on every machine).
|
|
19
|
+
ratchet_name: app_bundle_bytes
|
|
20
|
+
ratchet_cmd: find dist out release -type f -exec cat {} + 2>/dev/null | wc -c
|
|
21
|
+
sec_build_output: dist out release
|
|
22
|
+
# A renderer that reaches the filesystem or Node directly is forbidden, so there are no write
|
|
23
|
+
# routes to allow (software allows app/ and src/app/; the overlay blanks that).
|
|
24
|
+
sec_write_routes: ""
|
|
25
|
+
# perf_metric must EQUAL ratchet_name (PF-01 fails when the budget and the measurement disagree).
|
|
26
|
+
perf_metric: app_bundle_bytes
|
|
27
|
+
perf_cmd: find dist out release -type f -exec cat {} + 2>/dev/null | wc -c
|
|
28
|
+
# THE FPS NUMBER IS A HOST GATE, not the ratchet: the instrument that produces
|
|
29
|
+
# main_thread_busy_pct needs Playwright or Electron plus a GUI, which the no-npm contract
|
|
30
|
+
# forbids a shipped rule to launch. It is DECLARED here and carried in the HANDOFF with its date
|
|
31
|
+
# (docs/LIMITS.md #34, docs/CI.md carries the sweep). `electron: true` with this empty FAILs PF-01.
|
|
32
|
+
perf_host_gate: "Electron run - main_thread_busy_pct with a window open (app.getAppMetrics()[i].cpu.percentCPUUsage, or CDP Performance.getMetrics), on a machine with a display"
|
|
33
|
+
# The nine electron bans (G5's mechanism, G6's failure surface): nodeIntegration, context
|
|
34
|
+
# isolation / sandbox, the dangerous webPreferences, and synchronous IPC / @electron/remote. An
|
|
35
|
+
# unlisted ban SKIPs with a reason, so the other classes are unaffected; with electron: true the
|
|
36
|
+
# engine also treats BN-06..09 as enabled even if a hand-edited bans: list omits them.
|
|
37
|
+
bans: BN-01, BN-02, BN-05, BN-06, BN-07, BN-08, BN-09
|
|
38
|
+
notes: a perf number measured on one box is not a user's experience - the renderer half can be a CI job, the Electron half is a host gate and cannot be.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# presets/
|
|
1
|
+
# presets/fleet.yaml — the `fleet` class (letters/aliases E, agent).
|
|
2
2
|
#
|
|
3
3
|
# "Done" means a config change is applied, verified against the ARTIFACT, and versioned.
|
|
4
4
|
# The gate therefore checks the artifact (a commit exists, dated), never the intention.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# presets/
|
|
1
|
+
# presets/game.yaml — the `game` class (letter/alias C).
|
|
2
2
|
#
|
|
3
3
|
# "Done" means a suite green in the Editor AND a human feel verdict. The verdict is a
|
|
4
4
|
# first-class deliverable, which is why this class requires the review-panel part: the panel
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# presets/
|
|
1
|
+
# presets/research.yaml — the `research` class (letter/alias D).
|
|
2
2
|
#
|
|
3
3
|
# "Done" means a question is answered with sources and the answer is findable. A research
|
|
4
4
|
# note is not a spec, so the SPEC part is OFF, not optional. So are the REPLAY and the PR
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# presets/
|
|
1
|
+
# presets/service.yaml — the `service` class (letter/alias B).
|
|
2
2
|
#
|
|
3
3
|
# "Done" means a contract (schema, route, API) is unchanged, or the change is intentional
|
|
4
4
|
# and migrated. The class turns off the REPLAY and the PR gate, because a config repo has no
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# presets/
|
|
1
|
+
# presets/software.yaml — the `software` class (letters/aliases A, app).
|
|
2
2
|
#
|
|
3
3
|
# A class is not a stringency level. It selects WHICH PARTS are required, optional or off
|
|
4
4
|
# (manifest/classes.tsv), and it supplies the default gate/ratchet shape below. The gate
|
|
@@ -7,13 +7,21 @@ description: P8: adopt goblin-stack in a repo - classify, install, verify, then
|
|
|
7
7
|
|
|
8
8
|
Use when adopting goblin-stack in a repo, or starting one.
|
|
9
9
|
|
|
10
|
-
1. **Classify the project
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
1. **Classify the project into one of five classes.** `software`, `service`, `game`, `research` or
|
|
11
|
+
`fleet` — the class selects which parts are required, optional or off; it is not a stringency
|
|
12
|
+
level. `software` also carries the electron opt-in (`--electron`): an Electron app is `software`
|
|
13
|
+
with the electron bans and a host gate, not a sixth class. The letters `A`-`E` and the older
|
|
14
|
+
names are read-time aliases.
|
|
15
|
+
2. **`goblin-install --target <dir> --class <x>`** — the default install is a NEUTRAL harness:
|
|
16
|
+
no agent skills. Opt in per platform afterwards with `gob emit --platform <p>` (or vendor the
|
|
17
|
+
Hermes project tier with `--skills yes`).
|
|
18
|
+
3. **`goblin-verify`** — a default software-class install (no agent skills) verifies green:
|
|
19
|
+
`38 passed, 0 failed, 11 advisory, 33 skipped`, exit 0, once `HANDOFF.md` names a commit that
|
|
20
|
+
exists; before that edit the
|
|
21
|
+
scaffold's `0000000` placeholder is `HP-05`'s one expected day-one red (`37 passed, 1 failed`).
|
|
22
|
+
Thirty-three rows skip with a reason, and the reason matters: the five skill rows
|
|
23
|
+
(`SK-01`..`SK-04`, `AU-04`) skip on the `playbooks` opt-out a skills-free install records,
|
|
24
|
+
then `HS-02`
|
|
17
25
|
(no pinned pre-change commit yet, so the REPLAY is not provable), `AU-02`/`AU-03` (no report
|
|
18
26
|
has been filed in this repo), `SC-06`/`SC-07`/`SC-08` (no dependency manifest, no lockfile, no
|
|
19
27
|
audit record), `PF-01` (no perf baseline measured yet), `BN-01`/`BN-02`/`BN-05` (the ban table is
|
package/templates/AGENTS.md.tmpl
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
2
|
|
|
3
|
-
This repository uses **
|
|
3
|
+
This repository uses **gobstack** (class `{{CLASS}}`, installed {{DATE}}). It is a pointer,
|
|
4
4
|
not a rule dump — the rules live in one executable place, and facts beat requirements.
|
|
5
5
|
|
|
6
|
+
- **Harness entry point:** `.goblin/bin/goblin-verify` — exit 0 pass, 1 a check failed,
|
|
7
|
+
2 could not run, 3 the manifest is broken. Run it before you commit; the gate is the
|
|
8
|
+
same run.
|
|
6
9
|
- **Rules and their checks:** `.goblin/manifest/enforcement.tsv` (one row per rule; every row
|
|
7
10
|
carries a runnable check or the literal `advisory`).
|
|
8
11
|
- **Forbidden code (the ban list):** `.goblin/bin/goblin-bans` runs the bans named by `bans:` in
|
|
9
12
|
`.goblin/goblin.yaml`; each ban's mechanism lives in `.goblin/manifest/bans.tsv`. Run it before
|
|
10
13
|
you write the line, not after — a ban is a gate, and `goblin-verify` only reports it once the
|
|
11
14
|
code exists.
|
|
12
|
-
- **Verify:** `.goblin/bin/goblin-verify` — exit 0 pass, 1 a check failed, 2 could not run,
|
|
13
|
-
3 the manifest is broken.
|
|
14
|
-
- **Procedures:** the skills installed at `.hermes/skills/` (Hermes project tier — highest
|
|
15
|
-
precedence, repo-owned). Start with `goblin-mode`, which routes a request to a playbook.
|
|
16
15
|
- **Session state:** `HANDOFF.md` at the repo root. Read it before touching anything.
|
|
17
16
|
- **Project config:** `.goblin/goblin.yaml` (class, branch, gates, ratchet, runtime data,
|
|
18
17
|
replay, opt-outs). Edit it in place; the installer never overwrites it.
|
|
19
18
|
- **The referenced standard**, if configured, is named by `practice:` in `.goblin/goblin.yaml`.
|
|
20
19
|
Read it before starting work; this repo carries no copy of it.
|
|
21
20
|
|
|
21
|
+
**Agent skills are opt-in, per platform.** A default install ships none — this is a neutral
|
|
22
|
+
harness on purpose, so nothing here assumes which coding agent you use. To install the
|
|
23
|
+
procedure skills for your tool:
|
|
24
|
+
|
|
25
|
+
gob emit --platform <p>
|
|
26
|
+
|
|
27
|
+
(`--scope project` writes them inside this repo; `--scope global` writes them for your user.)
|
|
28
|
+
Run `gob emit` with no platform to see the list. If skills were installed here, they live
|
|
29
|
+
under the platform's own directory, and `gob verify` hashes them.
|
|
30
|
+
|
|
22
31
|
Two things this repo does not do: it does not choose models (a role resolves through the
|
|
23
32
|
mapping file named by `models_file:`), and it does not write outside its own tree.
|
|
@@ -4,9 +4,17 @@
|
|
|
4
4
|
# Format: a flat, line-oriented YAML subset, parsed by .goblin/bin/goblin-lib.sh. No YAML
|
|
5
5
|
# library, no network, no npm. Keep one key per line and keep comments on their own line.
|
|
6
6
|
|
|
7
|
-
# Which class this project is
|
|
7
|
+
# Which class this project is: software | service | game | research | fleet.
|
|
8
|
+
# The letters A-E and the older names app/agent/desktop are READ-TIME aliases, so an old
|
|
9
|
+
# value keeps verifying; `desktop`/`F` resolve to software. Selects the required parts
|
|
10
|
+
# (manifest/classes.tsv).
|
|
8
11
|
class: {{CLASS}}
|
|
9
12
|
|
|
13
|
+
# Electron opt-in (software class). true turns on the electron ban set (BN-06..09) even if the
|
|
14
|
+
# bans: list below omits them, and requires a declared perf.host_gate (PF-01 fails without one).
|
|
15
|
+
# The `desktop`/`F` install alias sets this true; a text-editor app leaves it false.
|
|
16
|
+
electron: {{ELECTRON}}
|
|
17
|
+
|
|
10
18
|
# The default branch, DECLARED, never assumed. A preset that assumes the wrong branch
|
|
11
19
|
# silently skips a repo.
|
|
12
20
|
branch: {{BRANCH}}
|
package/presets/F-electron.yaml
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# presets/F-electron.yaml — class F: desktop shell (Electron).
|
|
2
|
-
#
|
|
3
|
-
# A class is not a stringency level: it selects WHICH PARTS are required, optional or off
|
|
4
|
-
# (manifest/classes.tsv) and supplies the default gate/ratchet shape. A desktop shell needs a
|
|
5
|
-
# part no other class has — a HOST gate, a number measured on a machine with a display — and it
|
|
6
|
-
# forbids a thing the others allow: a renderer that reaches the filesystem or Node directly.
|
|
7
|
-
# That is a new row-set, not a flag on class A (G6 section B.2, Part B).
|
|
8
|
-
#
|
|
9
|
-
# THE PERF LANE IS THE SHIPPED RATCHET, NOT A SECOND ONE (G6 section B.3). There is one
|
|
10
|
-
# mechanism — `ratchet: {name, cmd, ceiling}`, enforced by GT-04/GT-05 and pinned to a commit by
|
|
11
|
-
# PF-01 — and this class reuses it verbatim. What the ratchet measures here is the one hermetic
|
|
12
|
-
# perf number a desktop shell has: the packaged bundle's byte count. A fat bundle is a slow
|
|
13
|
-
# cold start on every machine, and the number needs no browser, no display and no dependency.
|
|
14
|
-
#
|
|
15
|
-
# THE FPS NUMBER IS A HOST GATE, and this is a DEVIATION from G6 section B.3, recorded with its
|
|
16
|
-
# measured reason. G6 wants `main_thread_busy_pct` in the ratchet. It cannot be: the instrument
|
|
17
|
-
# that produces it (CDP `Performance.getMetrics` over a real Chromium, or
|
|
18
|
-
# `app.getAppMetrics()[i].cpu.percentCPUUsage` inside a real Electron) needs Playwright or
|
|
19
|
-
# Electron plus a GUI, and the dependency contract (docs/CONTRACTS.md) allows a shipped rule
|
|
20
|
-
# nothing but bash/git/awk/sed/grep/python3. A `ratchet.cmd` that cannot run on a fresh install
|
|
21
|
-
# makes a fresh install BORN RED, which is the one thing every class must not be. So the probe
|
|
22
|
-
# belongs to the project, next to the code it measures, and the number it produces is declared
|
|
23
|
-
# here as a host gate and carried in the HANDOFF with its date (the class C pattern).
|
|
24
|
-
#
|
|
25
|
-
# Why frame time is the WRONG number, measured in G6 on a real Chromium (CDP, 0 to 32 ms of
|
|
26
|
-
# work per frame): p50 frame time stayed FLAT at 16.70 ms while the main thread went from 1.8%
|
|
27
|
-
# to 54.5% busy, and the dropped-frame count was non-monotone (0,0,0,1,3,11,0 — the worst
|
|
28
|
-
# workload read 0). A frame-time gate at 16.7 ms is green on the idle tree AND on the loaded
|
|
29
|
-
# tree: PROJECT-PRACTICE section 3, reproduced live in the exact metric the note proposed.
|
|
30
|
-
# `main_thread_busy_pct` is the only monotone instrument in that sweep (1.8 -> 13.5 -> 26.0 ->
|
|
31
|
-
# 54.5 -> 76.9 -> 99.5%), which is why it is named here as the host gate's metric.
|
|
32
|
-
# docs/CI.md carries the sweep; docs/LIMITS.md #34 carries the gap.
|
|
33
|
-
label: Desktop shell
|
|
34
|
-
done_means: the renderer is isolated from Node, the main process is not busy, and the packaged bundle ships no dev dependency
|
|
35
|
-
harness_dir: checks
|
|
36
|
-
scaffold_checks: yes
|
|
37
|
-
gate_name: commit
|
|
38
|
-
gate_cmd: git rev-parse --verify --quiet HEAD
|
|
39
|
-
ratchet_name: app_bundle_bytes
|
|
40
|
-
ratchet_cmd: find dist out release -type f -exec cat {} + 2>/dev/null | wc -c
|
|
41
|
-
ratchet_ceiling: measure
|
|
42
|
-
replay_env: GOBLIN_PRE_COMMIT
|
|
43
|
-
replay_cmd: node checks/{name}.mjs
|
|
44
|
-
runtime_data: .goblin/state.json
|
|
45
|
-
sec_gitignore_family: yes
|
|
46
|
-
sec_build_output: dist out release
|
|
47
|
-
sec_audit_cmd: npm audit --json
|
|
48
|
-
sec_audit_max_age_days: 90
|
|
49
|
-
sec_waiver_max_age_days: 180
|
|
50
|
-
sec_write_routes: ""
|
|
51
|
-
# perf_metric must EQUAL ratchet_name (PF-01 fails when the budget and the measurement disagree),
|
|
52
|
-
# so the hermetic metric is named here too, and the host gate carries the FPS number beside it.
|
|
53
|
-
perf_metric: app_bundle_bytes
|
|
54
|
-
perf_cmd: find dist out release -type f -exec cat {} + 2>/dev/null | wc -c
|
|
55
|
-
perf_baseline_commit: ""
|
|
56
|
-
perf_baseline_value: 0
|
|
57
|
-
perf_measured: ""
|
|
58
|
-
perf_host_gate: "Electron run - main_thread_busy_pct with a window open (app.getAppMetrics()[i].cpu.percentCPUUsage, or CDP Performance.getMetrics), on a machine with a display"
|
|
59
|
-
# The nine electron bans (G5's mechanism, G6's failure surface): nodeIntegration, context
|
|
60
|
-
# isolation / sandbox, the dangerous webPreferences, and synchronous IPC / @electron/remote.
|
|
61
|
-
# An unlisted ban SKIPs with a reason, so the other classes are unaffected by this list.
|
|
62
|
-
bans: BN-01, BN-02, BN-05, BN-06, BN-07, BN-08, BN-09
|
|
63
|
-
notes: a perf number measured on one box is not a user's experience - the renderer half can be a CI job, the Electron half is a host gate and cannot be.
|
|
64
|
-
|
|
65
|
-
# The loop ceiling (G2, LP-03): the most turns ONE loop record may declare in its budget.
|
|
66
|
-
# The same number for every class - a ceiling, not a per-class policy. 20 is the engine default.
|
|
67
|
-
loop_max_turns_ceiling: 20
|