T03: game-kernel SOTA survey with measured boardgame.io baseline harness
This commit is contained in:
parent
38ffd8b7fd
commit
a7e31d4210
7 changed files with 376 additions and 1 deletions
71
history/260731-game-kernel-research.md
Normal file
71
history/260731-game-kernel-research.md
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
# 2026-07-31 — game-kernel research trail (CB-RES-0001, T03)
|
||||||
|
|
||||||
|
How the survey was actually conducted, per InnerLoop §Step 2. Session:
|
||||||
|
custodian on claude-fable-5.
|
||||||
|
|
||||||
|
## Sources and queries
|
||||||
|
|
||||||
|
1. WebSearch `boardgame.io maintained status 2026 alternative open source
|
||||||
|
board game engine framework` → Snyk maintenance page (key fact:
|
||||||
|
**Inactive, v0.50.2, last publish ~4 years ago**), GitHub issue #1150
|
||||||
|
("What's the state of the project?"), Vassal as the named alternative
|
||||||
|
(module player for humans, no programmable rules kernel — not pursued
|
||||||
|
as a kernel candidate).
|
||||||
|
2. WebFetch `github.com/boardgameio/boardgame.io` → 12.4k stars, 830 forks,
|
||||||
|
1,894 commits; feature list (phases, log/time-travel, multiplayer sync).
|
||||||
|
3. WebFetch `boardgame.io/documentation/#/` → **dead end**: docsify SPA,
|
||||||
|
no content server-side. Architecture facts were instead verified from
|
||||||
|
the installed package source (`node_modules/boardgame.io`) during
|
||||||
|
harness construction (Redux + Immer pipeline, plugins incl. seeded
|
||||||
|
`random`, `playerView`/`STRIP_SECRET`, `activePlayers` stages).
|
||||||
|
4. WebSearch `Rune games SDK deterministic logic.js …` →
|
||||||
|
developers.rune.ai docs: deterministic-JS enforcement (patched
|
||||||
|
`Math.random`, static checks), predict-rollback sync model.
|
||||||
|
5. WebFetch `api.tabletopsimulator.com` → Global vs Object scripts, Lua
|
||||||
|
state persisted as strings in save JSON; deeper pages not fetched —
|
||||||
|
remaining TTS characterization (no move validation, hand zones,
|
||||||
|
no replay) is prior knowledge, marked *cited* in the survey.
|
||||||
|
6. Event-sourcing and bevy_ecs performance figures are **cited/estimated**
|
||||||
|
from general engineering knowledge (cqrs-es aggregate pattern,
|
||||||
|
EventStoreDB append throughput class, Bevy's published bench claims) —
|
||||||
|
not fetched this session. Flagged as directional in the survey;
|
||||||
|
parity-cap rule applies.
|
||||||
|
|
||||||
|
## Harness (measured baseline)
|
||||||
|
|
||||||
|
`research/CB-RES-0001-harness/boardgame-io/bench.js` — boardgame.io 0.50.2,
|
||||||
|
headless `Client`, synthetic 3-player GROUND-shaped workload (relationship
|
||||||
|
map, hands, commit list, resolve step), seeded, SHA-256 state hash.
|
||||||
|
|
||||||
|
Dead ends and fixes:
|
||||||
|
|
||||||
|
- **v1 harness used `turn.stages` + `setActivePlayers` events** to model
|
||||||
|
the commit/reveal windows faithfully. The client rejected the moves
|
||||||
|
("disallowed move/event") — stage gating plus client-sent events needs
|
||||||
|
more setup than the bench warrants. Rewrote with flat top-level moves and
|
||||||
|
`activePlayers: {all: Stage.NULL}`. Fidelity cost: stage-machinery
|
||||||
|
overhead is *not* measured; the reducer/log pipeline (the thing we
|
||||||
|
benchmark) is. Noted in the survey's risk paragraph.
|
||||||
|
- Side-effect: the v1 "8.4 s for 100k moves" figure was garbage — moves
|
||||||
|
were being rejected, so it measured no-ops. Discarded.
|
||||||
|
- **100k-move run did not finish in 300 s** and was killed. Reran at
|
||||||
|
5k/10k/20k, which exposed the real story: throughput halves as history
|
||||||
|
doubles (1,930 → 1,605 → 870 moves/s). The degradation is the finding;
|
||||||
|
a single big-N number would have hidden it.
|
||||||
|
- A stray broken edit left duplicate code in bench.js (syntax error);
|
||||||
|
fixed before the measured runs. Measurements reported in the survey are
|
||||||
|
from the clean file only.
|
||||||
|
|
||||||
|
Environment: Node v24.11.1, bnt-lap001 (WSL2), single process, no other
|
||||||
|
load control — numbers are same-machine comparable per MetricsAndScenarios
|
||||||
|
§3, not lab-grade.
|
||||||
|
|
||||||
|
## What was deliberately not done
|
||||||
|
|
||||||
|
- No local measurement of a Rust event-sourcing comparator (would harden
|
||||||
|
the D3 ceiling row; candidate follow-up if the adversarial review demands
|
||||||
|
it).
|
||||||
|
- Vassal, Tabletopia, Phaser/Godot examined only far enough to exclude:
|
||||||
|
none is a programmable authoritative rules kernel.
|
||||||
|
- boardgame.io server-side master (no client subscription) not separately
|
||||||
|
benchmarked; harness measures canonical client usage.
|
||||||
154
research/CB-RES-0001-game-kernel.md
Normal file
154
research/CB-RES-0001-game-kernel.md
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
# CB-RES-0001: game-state kernel
|
||||||
|
|
||||||
|
capability: game.kernel.authoritative-state
|
||||||
|
status: draft # becomes approved only after adversarial review (T04)
|
||||||
|
tier: L (structural L, chaos roll pending at T04 declaration — see history trail)
|
||||||
|
runnable-baseline: invoked — harness in research/CB-RES-0001-harness/boardgame-io/
|
||||||
|
|
||||||
|
Survey of the best existing implementations of a **turn/phase game-state
|
||||||
|
kernel**: deterministic authoritative state, command → validation → events,
|
||||||
|
simultaneous commit/reveal, hidden information, replay. Conducted
|
||||||
|
2026-07-31; research trail in
|
||||||
|
[history/260731-game-kernel-research.md](../history/260731-game-kernel-research.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Candidates
|
||||||
|
|
||||||
|
### 1. boardgame.io 0.50.2 (JS/TS) — measured
|
||||||
|
|
||||||
|
The most direct comparator: a declarative turn-based game engine.
|
||||||
|
|
||||||
|
- **Data model:** single plain-object `G` (game state) + framework `ctx`
|
||||||
|
(turn/phase bookkeeping). Game defined declaratively: `setup`, `moves`,
|
||||||
|
`phases`, `turn.stages`.
|
||||||
|
- **Mutation:** moves are reducer functions run through Redux + Immer;
|
||||||
|
mutate a draft, framework produces immutable next state and appends to an
|
||||||
|
action **log** (basis for time travel).
|
||||||
|
- **Determinism/replay:** seeded RNG via `random` plugin; log + seed give
|
||||||
|
replay and time travel. Measured: same seed → identical state hash across
|
||||||
|
runs; different seed diverges. ✅
|
||||||
|
- **Hidden information:** `playerView` projection (e.g. `STRIP_SECRET`) —
|
||||||
|
server strips secret state per player.
|
||||||
|
- **Simultaneous actions:** `activePlayers` stages give simultaneous move
|
||||||
|
windows; no built-in cryptographic commit/reveal — commitment is plain
|
||||||
|
state the server can see (fine for server-authoritative, nothing for
|
||||||
|
peer settings).
|
||||||
|
- **Maturity:** 12.4k GitHub stars, but **inactive** — last npm release
|
||||||
|
0.50.2 ≈ 4 years ago (Snyk: "maintenance: Inactive").
|
||||||
|
- **Measured performance** (our harness, synthetic 3-player GROUND-shaped
|
||||||
|
commit/reveal workload, Node v24, this machine `bnt-lap001`):
|
||||||
|
|
||||||
|
| applied moves | moves/s | elapsed | RSS |
|
||||||
|
|---:|---:|---:|---:|
|
||||||
|
| 5,000 | 1,930 | 2.6 s | 224 MB |
|
||||||
|
| 10,000 | 1,605 | 6.2 s | 229 MB |
|
||||||
|
| 20,000 | 870 | 23.0 s | 271 MB |
|
||||||
|
| 100,000 | did not finish in 300 s | — | — |
|
||||||
|
|
||||||
|
**Per-move cost grows with history length** (log accumulation + state
|
||||||
|
pipeline): throughput halves as move count doubles — superlinear total
|
||||||
|
cost. This is architectural (unbounded redux log per client), not a
|
||||||
|
tuning artifact.
|
||||||
|
- **Weight:** 120 transitive npm packages, 37 MB `node_modules`, core
|
||||||
|
package 3.9 MB.
|
||||||
|
|
||||||
|
### 2. Tabletop Simulator scripting model (Lua) — cited
|
||||||
|
|
||||||
|
The dominant commercial virtual tabletop; reference for *tabletop
|
||||||
|
semantics*, not a rules kernel.
|
||||||
|
|
||||||
|
- **Data model:** none authoritative — game state *is* the physical scene;
|
||||||
|
Lua state serialized as strings into the save JSON (`onSave`/`onLoad`).
|
||||||
|
- **Mutation:** imperative Lua in a Global script + per-object scripts with
|
||||||
|
event hooks; **no move validation or rules engine** — rules are social,
|
||||||
|
physics is primary (sandbox mode in Clay-Borg terms).
|
||||||
|
- **Determinism/replay:** none. Hidden info via hand zones (engine feature,
|
||||||
|
not a projection model).
|
||||||
|
- Valuable as the pattern source for object-attached behavior and hand
|
||||||
|
zones; architecturally the anti-model for an authoritative kernel.
|
||||||
|
|
||||||
|
### 3. Rune SDK (JS) — cited
|
||||||
|
|
||||||
|
Modern (active, 2024–2026) deterministic multiplayer engine for casual web
|
||||||
|
games.
|
||||||
|
|
||||||
|
- **Data model/mutation:** pure `logic.js` — game state + action functions,
|
||||||
|
statically checked for nondeterminism (mutation escape, `Math.random`
|
||||||
|
patched deterministic).
|
||||||
|
- **Sync:** predict-rollback: all clients + server simulate the same
|
||||||
|
deterministic logic; server authoritative, clients predict. Strongest
|
||||||
|
determinism *discipline* of the candidates — enforced by tooling, not
|
||||||
|
convention.
|
||||||
|
- **Limits:** platform-bound (Rune's hosted app ecosystem), not an
|
||||||
|
embeddable open kernel; no phase/stage framework, hidden-information
|
||||||
|
projection, or event-sourced replay surface comparable to boardgame.io.
|
||||||
|
|
||||||
|
### 4. Event-sourcing kernels (Rust `cqrs-es` pattern / EventStoreDB) — cited
|
||||||
|
|
||||||
|
The general-purpose form of our mutation pipeline (command → validate →
|
||||||
|
events → fold).
|
||||||
|
|
||||||
|
- Aggregates validate commands and emit events; state is a fold over the
|
||||||
|
append-only log; snapshots bound replay cost. Replay/audit are native.
|
||||||
|
- **Performance (cited/estimated):** in-process Rust event application is
|
||||||
|
memory-bandwidth-bound — order 10⁵–10⁶ small events/s per core is the
|
||||||
|
commonly reported range for fold-style aggregates; dedicated stores
|
||||||
|
(EventStoreDB) sustain tens of thousands of appends/s over the network.
|
||||||
|
No game semantics: phases, visibility, simultaneity all DIY.
|
||||||
|
|
||||||
|
### 5. bevy_ecs 0.x (Rust) — cited
|
||||||
|
|
||||||
|
Archetypal ECS; the world/spatial layer in our architecture, surveyed as a
|
||||||
|
kernel candidate for completeness.
|
||||||
|
|
||||||
|
- Cache-friendly iteration: millions of entity-component accesses per frame
|
||||||
|
(cited from Bevy's own benches; ns-scale per component access).
|
||||||
|
- No authoritative command/event pipeline, no replay, no hidden-info
|
||||||
|
projection; determinism requires care (system ordering, hash maps).
|
||||||
|
Confirms the ADR-anticipated split: ECS for world representation,
|
||||||
|
**typed aggregates for the semantic kernel** — not a competitor on this
|
||||||
|
capability.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Baselines (benchmark-to-beat)
|
||||||
|
|
||||||
|
| Dimension | Baseline holder | Metric | Value | Provenance |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| D1 ease of specification | boardgame.io | LOC to express the synthetic 3p commit/reveal game (declarative object) | ~45 LOC | measured (harness bench.js game def) |
|
||||||
|
| D1 | — (no candidate) | rule-to-scenario traceability (M-D1-COV) | 0 % — none of the candidates link rules to tests | measured/observed |
|
||||||
|
| D2 implementation weight | boardgame.io | transitive deps / install size | 120 pkgs / 37 MB | measured |
|
||||||
|
| D3 throughput | boardgame.io | applied moves/s, 3p workload @5k moves | 1,930 moves/s | measured, bnt-lap001 |
|
||||||
|
| D3 scaling | boardgame.io | throughput @20k vs @5k moves | 0.45× (superlinear cost) | measured, bnt-lap001 |
|
||||||
|
| D3 memory | boardgame.io | RSS @5k moves | 224 MB | measured, bnt-lap001 |
|
||||||
|
| D3 ceiling (adjacent layer) | in-proc event-sourcing (Rust) | events applied/s per core | ~10⁵–10⁶ | cited/estimated — directional, caps our verdict at parity unless we measure a Rust comparator |
|
||||||
|
| D4 optionality | Rune | determinism enforced by tooling | static nondeterminism checks | cited |
|
||||||
|
| D4 | boardgame.io | replaceability of subsystems | plugin API, but JS-ecosystem-locked; no null/reference impl pattern | observed |
|
||||||
|
|
||||||
|
**Headline benchmark-to-beat for the Clay-Borg kernel (proposed for the
|
||||||
|
ADR):** ≥ 100,000 applied events/s sustained with **flat scaling** (throughput
|
||||||
|
@100k events within 10% of @5k), deterministic replay bit-identical, on the
|
||||||
|
same machine and workload shape as the boardgame.io harness.
|
||||||
|
|
||||||
|
## Verdict
|
||||||
|
|
||||||
|
- **Per dimension:** D1 — boardgame.io's declarative game object is the bar
|
||||||
|
to match; nobody has rule-to-scenario traceability (open surpass lane).
|
||||||
|
D2 — boardgame.io's 120-dep footprint is beatable by an order of
|
||||||
|
magnitude in Rust. D3 — boardgame.io is slow *and* degrades; the honest
|
||||||
|
comparison class is in-proc event sourcing (10⁵–10⁶/s), and our D3
|
||||||
|
advantage over boardgame.io is partly language choice — the meaningful
|
||||||
|
target is **flat scaling + the 100k/s floor**, not the ×50 headline.
|
||||||
|
D4 — Rune's tooling-enforced determinism is the discipline to assimilate;
|
||||||
|
no candidate offers a null/reference/optimized port pattern.
|
||||||
|
- **What none of them do:** combine deterministic replayable authoritative
|
||||||
|
state, first-class simultaneous commit/reveal with hidden-information
|
||||||
|
projection, flat per-event cost with snapshots, and an embeddable
|
||||||
|
language-portable boundary. That combination is the surpass opportunity.
|
||||||
|
- **Risks in these baselines:** the boardgame.io harness measures the
|
||||||
|
headless *client* pipeline (includes subscription/log overhead — canonical
|
||||||
|
usage, but a bare server-side master could differ); the event-sourcing
|
||||||
|
numbers are cited, not locally measured; TTS and Rune numbers are
|
||||||
|
qualitative. The D3 event-sourcing row is directional and caps related
|
||||||
|
evidence verdicts at parity per MetricsAndScenarios §3.
|
||||||
2
research/CB-RES-0001-harness/boardgame-io/.gitignore
vendored
Normal file
2
research/CB-RES-0001-harness/boardgame-io/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules/
|
||||||
|
package-lock.json
|
||||||
116
research/CB-RES-0001-harness/boardgame-io/bench.js
Normal file
116
research/CB-RES-0001-harness/boardgame-io/bench.js
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
// Baseline harness for CB-RES-0001 — boardgame.io v0.50.2, headless client.
|
||||||
|
// Measures: (1) throughput of applying moves to authoritative state,
|
||||||
|
// (2) determinism across two seeded runs, (3) commit/reveal-style stage flow.
|
||||||
|
// Fidelity note: synthetic GROUND-shaped workload (3 players, relationship
|
||||||
|
// map, per-player hands, commit list), not a real GROUND implementation.
|
||||||
|
// Run: node bench.js [numMoves]
|
||||||
|
|
||||||
|
const { Client } = require('boardgame.io/client');
|
||||||
|
const { Stage } = require('boardgame.io/core');
|
||||||
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
const NUM_MOVES = parseInt(process.argv[2] || '100000', 10);
|
||||||
|
const NUM_PLAYERS = 3;
|
||||||
|
|
||||||
|
const SyntheticGround = {
|
||||||
|
name: 'synthetic-ground',
|
||||||
|
setup: ({ ctx }) => ({
|
||||||
|
round: 0,
|
||||||
|
relationships: {}, // "a->b" -> {kind, strength}
|
||||||
|
hands: Object.fromEntries(
|
||||||
|
Array.from({ length: ctx.numPlayers }, (_, i) => [String(i), Array.from({ length: 7 }, (_, c) => c)])
|
||||||
|
),
|
||||||
|
committed: {},
|
||||||
|
revealed: [],
|
||||||
|
score: Object.fromEntries(Array.from({ length: ctx.numPlayers }, (_, i) => [String(i), 0])),
|
||||||
|
}),
|
||||||
|
moves: {
|
||||||
|
commitAction: ({ G, playerID, random }, targetOffset) => {
|
||||||
|
const target = String((Number(playerID) + targetOffset) % NUM_PLAYERS);
|
||||||
|
const card = G.hands[playerID].length > 0 ? G.hands[playerID][0] : random.D6();
|
||||||
|
G.committed[playerID] = { target, card };
|
||||||
|
},
|
||||||
|
resolveAll: ({ G, random }) => {
|
||||||
|
const order = Object.keys(G.committed).sort();
|
||||||
|
for (const p of order) {
|
||||||
|
const { target, card } = G.committed[p];
|
||||||
|
const key = `${p}->${target}`;
|
||||||
|
const rel = G.relationships[key] || { kind: 'rivalry', strength: 0 };
|
||||||
|
rel.strength = (rel.strength + card + random.D6()) % 10;
|
||||||
|
G.relationships[key] = rel;
|
||||||
|
G.score[p] += rel.strength;
|
||||||
|
G.revealed.push({ p, target, card });
|
||||||
|
if (G.revealed.length > 50) G.revealed.shift();
|
||||||
|
}
|
||||||
|
G.committed = {};
|
||||||
|
G.round += 1;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
turn: { activePlayers: { all: Stage.NULL } },
|
||||||
|
};
|
||||||
|
|
||||||
|
function makeClient(seed) {
|
||||||
|
return Client({
|
||||||
|
game: { ...SyntheticGround, seed },
|
||||||
|
numPlayers: NUM_PLAYERS,
|
||||||
|
playerID: '0',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function stateHash(client) {
|
||||||
|
const { G } = client.getState();
|
||||||
|
return crypto.createHash('sha256').update(JSON.stringify(G)).digest('hex');
|
||||||
|
}
|
||||||
|
|
||||||
|
function run(seed, numMoves, collectHash) {
|
||||||
|
const client = makeClient(seed);
|
||||||
|
// Drive all players through commit windows via events/moves.
|
||||||
|
// Each "round" = NUM_PLAYERS commitAction moves + 1 resolveAll.
|
||||||
|
const rounds = Math.floor(numMoves / (NUM_PLAYERS + 1));
|
||||||
|
const t0 = process.hrtime.bigint();
|
||||||
|
for (let r = 0; r < rounds; r++) {
|
||||||
|
for (let p = 0; p < NUM_PLAYERS; p++) {
|
||||||
|
client.updatePlayerID(String(p));
|
||||||
|
client.moves.commitAction(1 + (r % (NUM_PLAYERS - 1)));
|
||||||
|
}
|
||||||
|
client.updatePlayerID('0');
|
||||||
|
client.moves.resolveAll();
|
||||||
|
}
|
||||||
|
const t1 = process.hrtime.bigint();
|
||||||
|
const elapsedMs = Number(t1 - t0) / 1e6;
|
||||||
|
const applied = rounds * (NUM_PLAYERS + 1);
|
||||||
|
return {
|
||||||
|
applied,
|
||||||
|
elapsedMs,
|
||||||
|
movesPerSec: Math.round(applied / (elapsedMs / 1000)),
|
||||||
|
hash: collectHash ? stateHash(client) : null,
|
||||||
|
finalRound: client.getState().G.round,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- throughput ---
|
||||||
|
const warm = run(42, Math.min(NUM_MOVES, 5000), false); // warmup/JIT
|
||||||
|
const main = run(42, NUM_MOVES, true);
|
||||||
|
|
||||||
|
// --- determinism: same seed twice, different seed once ---
|
||||||
|
const detA = run(7, 4000, true);
|
||||||
|
const detB = run(7, 4000, true);
|
||||||
|
const detC = run(8, 4000, true);
|
||||||
|
|
||||||
|
// --- memory ---
|
||||||
|
const mem = process.memoryUsage();
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
library: 'boardgame.io@0.50.2',
|
||||||
|
node: process.version,
|
||||||
|
workload: `synthetic-ground ${NUM_PLAYERS}p commit/reveal`,
|
||||||
|
applied_moves: main.applied,
|
||||||
|
elapsed_ms: Math.round(main.elapsedMs),
|
||||||
|
moves_per_sec: main.movesPerSec,
|
||||||
|
final_round: main.finalRound,
|
||||||
|
determinism_same_seed: detA.hash === detB.hash,
|
||||||
|
determinism_diff_seed_differs: detA.hash !== detC.hash,
|
||||||
|
rss_mb: Math.round(mem.rss / 1048576),
|
||||||
|
heap_mb: Math.round(mem.heapUsed / 1048576),
|
||||||
|
};
|
||||||
|
console.log(JSON.stringify(result, null, 2));
|
||||||
16
research/CB-RES-0001-harness/boardgame-io/package.json
Normal file
16
research/CB-RES-0001-harness/boardgame-io/package.json
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "boardgame-io",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"type": "commonjs",
|
||||||
|
"dependencies": {
|
||||||
|
"boardgame.io": "^0.50.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"library": "boardgame.io@0.50.2",
|
||||||
|
"node": "v24.11.1",
|
||||||
|
"machine": "bnt-lap001 (WSL2)",
|
||||||
|
"recorded": "2026-07-31",
|
||||||
|
"workload": "synthetic-ground 3p commit/reveal (bench.js)",
|
||||||
|
"runs": [
|
||||||
|
{"applied_moves": 5000, "moves_per_sec": 1930, "elapsed_ms": 2590, "rss_mb": 224},
|
||||||
|
{"applied_moves": 10000, "moves_per_sec": 1605, "elapsed_ms": 6232, "rss_mb": 229},
|
||||||
|
{"applied_moves": 20000, "moves_per_sec": 870, "elapsed_ms": 22978, "rss_mb": 271},
|
||||||
|
{"applied_moves": 100000, "note": "did not finish within 300s; killed"}
|
||||||
|
],
|
||||||
|
"determinism_same_seed": true,
|
||||||
|
"determinism_diff_seed_differs": true,
|
||||||
|
"dependency_stats": {"transitive_packages": 120, "node_modules_size": "37M", "core_package_size": "3.9M"}
|
||||||
|
}
|
||||||
|
|
@ -77,7 +77,7 @@ contains. These are the instruments the loop measures with; without them
|
||||||
|
|
||||||
```task
|
```task
|
||||||
id: CB-WP-0001-T03
|
id: CB-WP-0001-T03
|
||||||
status: todo
|
status: done
|
||||||
priority: high
|
priority: high
|
||||||
state_hub_task_id: "8dec6577-9397-40ee-b99b-9119dcdac115"
|
state_hub_task_id: "8dec6577-9397-40ee-b99b-9119dcdac115"
|
||||||
```
|
```
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue