Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .seeds/issues.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,9 @@
{"id":"mulch-f7bf","title":"T5: adaptive parallel shard runner (core-count agnostic)","status":"open","type":"task","priority":1,"createdAt":"2026-05-28T19:15:54.049Z","updatedAt":"2026-05-28T19:16:03.298Z","description":"GOAL: `bun test` runs all files sequentially in ONE process, so wall-clock = sum of file times. Add a runner that splits test files into N balanced shards and runs them as concurrent `bun test <files>` processes. Shard count MUST be derived from the runtime environment — never hardcoded to any developer machine spec.\n\nWorking dir: cd /Users/jayminwest/Projects/os-eco/mulch\nINDEPENDENT build (blocks T6).\n\nFILES TO ADD:\n- ADD scripts/test-parallel.ts (run via Bun):\n - Determine shard count: `MULCH_TEST_SHARDS` env > `--shards N` arg > Math.max(1, os.availableParallelism?.() ?? os.cpus().length). Cap to number of test files.\n - Discover test files (glob test/**/*.test.ts).\n - Weight files by historical timing parsed from junit.xml when present (reuse parseJUnit from scripts/report-test-timing.ts), else by file size; greedily bin-pack into shards for balance.\n - Spawn one `bun test <files-for-shard>` per shard concurrently (Bun.spawn), stream/prefix output, await all, exit non-zero if ANY shard fails.\n - SEQUENTIAL FALLBACK: if resolved shards <= 1, exec a single plain `bun test` (identical behavior to today).\n- ADD package.json script: \"test:parallel\": \"bun run scripts/test-parallel.ts\".\n- ADD scripts/test-parallel.test.ts: unit-test the pure pieces (shard-count resolution precedence, bin-packing balance, sequential fallback) — pure functions, no real spawning.\n\nDESIGN CONSTRAINTS:\n- Core-count agnostic + cloud-safe: works on a 1-vCPU box (falls back to sequential), a 2-4 vCPU cloud dev box, and large CI runners with the SAME code. No machine-specific constants.\n- Tests already isolate via mkdtemp unique prefixes, so cross-shard temp-dir collisions are not a concern.\n- Deterministic file->shard assignment given the same inputs (stable sort) for reproducibility.\n\nVERIFICATION (must exit 0):\n bun run lint && bun run typecheck\n bun test scripts/test-parallel.test.ts\n MULCH_TEST_SHARDS=1 bun run test:parallel # sequential fallback, full suite green\n MULCH_TEST_SHARDS=4 bun run test:parallel # parallel, same pass/fail outcome + lower wall-clock\n\nACCEPTANCE:\n- Same overall pass/fail result as `bun test` at any shard count.\n- Wall-clock scales down with shard count; sequential fallback exactly mirrors plain `bun test`.\n\nPITFALLS:\n- Aggregate exit code: fail if ANY shard fails (do not mask with tail/pipe).\n- os.availableParallelism may be undefined on older runtimes — guard with cpus().length.\n- Coverage merge across shards is handled in T6, but design spawn args so per-shard `--coverage --coverage-reporter=lcov` with distinct outfiles is possible.","blocks":["mulch-d61d","mulch-bee4"]}
{"id":"mulch-d61d","title":"T6: wire CI to sharded runner + coverage merge","status":"open","type":"task","priority":2,"createdAt":"2026-05-28T19:15:54.152Z","updatedAt":"2026-05-28T19:16:03.352Z","description":"GOAL: Use the T5 shard runner in CI with an EXPLICIT, deterministic shard matrix (not derived from runner core count, so behavior is reproducible across runner sizes), merge per-shard coverage, and keep the timing report.\n\nWorking dir: cd /Users/jayminwest/Projects/os-eco/mulch\nDEPENDS ON: T5 (runner must exist).\n\nFILES TO EDIT:\n- .github/workflows/ci.yml:\n - Replace the single test:ci step with a small matrix (e.g. shard: [1,2,3,4], total 4) OR a single job invoking `MULCH_TEST_SHARDS=4 bun run test:parallel` — choose whichever keeps coverage merge simplest; document the choice in the job.\n - Each shard runs `bun test --coverage --coverage-reporter=lcov --coverage-reporter=...` writing a shard-unique lcov path, plus --reporter=junit to a shard-unique junit file.\n - Add a merge step: combine shard lcov files into coverage/lcov.info (concatenate/merge) and shard junit files into junit.xml so existing check:coverage + report:timing + report:quality keep working unchanged.\n - Keep uploading coverage/lcov.info and junit.xml artifacts (VAL-CROSS-003) and appending report:timing to GITHUB_STEP_SUMMARY.\n\nVERIFICATION (must exit 0):\n bun run lint && bun run typecheck\n # Locally emulate: run the runner with coverage, merge, then:\n bun run check:coverage\n bun run report:timing\n ls -la coverage/lcov.info junit.xml\n\nACCEPTANCE:\n- CI wall-clock for tests drops vs the previous single sequential run.\n- Merged coverage feeds check:coverage with no budget regression; merged junit feeds report:timing.\n- Matrix is explicit/deterministic — independent of the physical runner's core count.\n\nPITFALLS:\n- lcov merge: same source files appear in multiple shards' reports only if executed there; merge must union records, not double-count lines (use a real lcov merge approach, not naive concat if it corrupts totals — verify check:coverage numbers are sane).\n- junit merge must keep total tests = sum across shards for report:timing accuracy.\n- Do not regress check:all ordering or artifact-upload steps.","blockedBy":["mulch-f7bf"],"blocks":["mulch-bee4"]}
{"id":"mulch-35c9","title":"pino-pretty transport fails for consumers (move to dep or fall back to JSON)","status":"closed","type":"bug","priority":2,"createdAt":"2026-06-02T19:20:56.332Z","updatedAt":"2026-06-02T19:23:22.152Z","description":"Symptom: running ml on a machine where mulch was installed without devDependencies (e.g. npm i -g @os-eco/mulch-cli, bun add, production install) throws: 'error: unable to determine transport target for \"pino-pretty\"'.\n\nRoot cause: pino-pretty is a devDependency, but src/log.ts createLogger() selects the pino-pretty transport whenever process.stderr.isTTY === true && MULCH_LOG_JSON !== \"1\". Published consumers running in an interactive terminal hit the pretty path, pino tries to load the pino-pretty transport target, the package is absent, and it throws. The file header claims published consumers 'get JSON logs and never need the pretty transport', but that only holds for non-TTY environments today.\n\nCurrent workaround (forces JSON path): MULCH_LOG_JSON=1 ml <command>\n\nProper fix (preferred): make the pretty transport optional in src/log.ts. Guard the pino-pretty transport behind a resolvability check (e.g. require.resolve('pino-pretty') in try/catch, or try/catch around logger construction) and fall back to JSON-to-stderr (pino.destination(2)) when pino-pretty is not installed. This keeps pretty output for dev while honoring the documented JSON-for-consumers promise.\n\nAlternative: move pino-pretty from devDependencies to dependencies so it always ships — simpler but bloats the published install with a dev-only transport.\n\nAcceptance:\n- ml runs in an interactive TTY without pino-pretty installed and does NOT throw; logs fall back to JSON on stderr.\n- Dev environments (pino-pretty present, TTY) still get pretty output.\n- Add a test in src/log.test.ts (or test/) covering the missing-pino-pretty fallback path.","labels":["area:cli"],"closedAt":"2026-06-02T19:23:22.152Z"}
{"id":"mulch-273e","title":"nightwatch patrol: 2026-06-08","status":"open","type":"task","priority":3,"createdAt":"2026-06-08T10:08:08.666Z","updatedAt":"2026-06-08T10:09:09.860Z","labels":["patrol","nightwatch"],"plan_id":"pl-1557","blockedBy":["mulch-ac84","mulch-6bb5","mulch-2d07","mulch-05e0","mulch-350f"]}
{"id":"mulch-ac84","title":"Dedup parseStrict* helpers: import from src/utils/numeric-flags.ts in ready/prime/compact/rank","status":"open","type":"task","priority":3,"plan_step_index":0,"description":"<!-- seeds:plan-backref:start -->\nStep 1 of plan pl-1557.\n\nParent seed: mulch-273e — nightwatch patrol: 2026-06-08\nPlan template: refactor\nPlan approach: Land each cleanup as its own small PR so the ratchet gates verify it in isolation. Start with the independent fixes (numeric-flag dedup, unused-barrel removal, unused-export pruning) since they touch disjoint files. Then refactor the…\n\nRun `sd plan show pl-1557` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-08T10:09:09.860Z","updatedAt":"2026-06-08T10:09:09.860Z","labels":["nightwatch","refactor","cleanup"],"plan_id":"pl-1557","blocks":["mulch-350f","mulch-273e"]}
{"id":"mulch-6bb5","title":"Delete unused barrel src/utils/index.ts","status":"open","type":"task","priority":3,"plan_step_index":1,"description":"<!-- seeds:plan-backref:start -->\nStep 2 of plan pl-1557.\n\nParent seed: mulch-273e — nightwatch patrol: 2026-06-08\nPlan template: refactor\nPlan approach: Land each cleanup as its own small PR so the ratchet gates verify it in isolation. Start with the independent fixes (numeric-flag dedup, unused-barrel removal, unused-export pruning) since they touch disjoint files. Then refactor the…\n\nRun `sd plan show pl-1557` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-08T10:09:09.860Z","updatedAt":"2026-06-08T10:09:09.860Z","labels":["nightwatch","cleanup","dead-code"],"plan_id":"pl-1557","blocks":["mulch-350f","mulch-273e"]}
{"id":"mulch-2d07","title":"Prune unused exports + exported types flagged by knip","status":"open","type":"task","priority":3,"plan_step_index":2,"description":"<!-- seeds:plan-backref:start -->\nStep 3 of plan pl-1557.\n\nParent seed: mulch-273e — nightwatch patrol: 2026-06-08\nPlan template: refactor\nPlan approach: Land each cleanup as its own small PR so the ratchet gates verify it in isolation. Start with the independent fixes (numeric-flag dedup, unused-barrel removal, unused-export pruning) since they touch disjoint files. Then refactor the…\n\nRun `sd plan show pl-1557` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-08T10:09:09.860Z","updatedAt":"2026-06-08T10:09:09.860Z","labels":["nightwatch","cleanup","dead-code"],"plan_id":"pl-1557","blocks":["mulch-350f","mulch-273e"]}
{"id":"mulch-05e0","title":"Split test/commands/record.test.ts so check:size ratchet goes green","status":"open","type":"task","priority":2,"plan_step_index":3,"description":"<!-- seeds:plan-backref:start -->\nStep 4 of plan pl-1557.\n\nParent seed: mulch-273e — nightwatch patrol: 2026-06-08\nPlan template: refactor\nPlan approach: Land each cleanup as its own small PR so the ratchet gates verify it in isolation. Start with the independent fixes (numeric-flag dedup, unused-barrel removal, unused-export pruning) since they touch disjoint files. Then refactor the…\n\nRun `sd plan show pl-1557` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-08T10:09:09.860Z","updatedAt":"2026-06-08T10:09:09.860Z","labels":["nightwatch","test","refactor"],"plan_id":"pl-1557","blocks":["mulch-350f","mulch-273e"]}
{"id":"mulch-350f","title":"Release: run /release per .claude/commands/release.md","status":"open","type":"task","priority":3,"plan_step_index":4,"description":"<!-- seeds:plan-backref:start -->\nStep 5 of plan pl-1557.\n\nParent seed: mulch-273e — nightwatch patrol: 2026-06-08\nPlan template: refactor\nPlan approach: Land each cleanup as its own small PR so the ratchet gates verify it in isolation. Start with the independent fixes (numeric-flag dedup, unused-barrel removal, unused-export pruning) since they touch disjoint files. Then refactor the…\n\nRun `sd plan show pl-1557` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-08T10:09:09.860Z","updatedAt":"2026-06-08T10:09:09.860Z","labels":["nightwatch","release"],"plan_id":"pl-1557","blockedBy":["mulch-ac84","mulch-6bb5","mulch-2d07","mulch-05e0"],"blocks":["mulch-273e"]}
Loading
Loading