@galda/cli 0.10.109 → 0.10.110

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/CLAUDE.md CHANGED
@@ -26,12 +26,53 @@
26
26
  - 新しいロジックは可能な限り純関数として `engine/lib.mjs` 等に切り出し、`engine/test/` にテストを追加する。
27
27
  - テストが書けない変更(純UI等)は、その理由と手動確認手順を報告に書く。
28
28
 
29
+ ### テストの書き方(Masa体感「変に判断せずつなぐだけになった」を守る・2026-07-30 追加)
30
+
31
+ 1日で main を2回赤にした型・3日間気付かれなかった型が実在する。以下は**好みでなく再発防止**。
32
+
33
+ - 🔴 **`app/index.html` のソース文字列を正規表現で照合するテストを新しく書かない。**
34
+ `align-items:center` や `outcome?.requirementEvidence?.…` という**式そのもの**を要求していたテストが、
35
+ 実装の書き換えだけで赤くなった(2026-07-29 に PR #574/#584 の2回)。
36
+ **正規表現は「書き方を変えた」と「壊した」を区別できない。**
37
+ → **実際に開いて、描かれたものを読む**。ヘルパは `engine/test/helpers/serve-app.mjs`+`helpers/browser.mjs`、
38
+ 実例は `engine/test/review-delivery-label.test.mjs`/`review-requirement-coverage-ui.test.mjs`。
39
+ - 🔴 **テストを足したら、製品を壊して赤くなることを必ず確認する**(1〜3通り)。落ちないテストは何も証明しない。
40
+ 確認したことと壊し方を PR 本文に書く。
41
+ - 🔴 **テストだけコミットして実装が無い状態を作らない。** 実例2件:
42
+ `5802056`(Reconnect のテストだけ main に入り実装が存在しなかった)/
43
+ **PR #396 が統合時に engine と app の実装を落とし、テストだけ入れた**(main が3日間、
44
+ 存在しない機能のテストで赤かった。復元=PR #586)。
45
+ → 複数レーンの成果を1本に統合する PR では、**テストだけでなく実装が入っているかを機械で照合する**
46
+ (`node tools/conflict-check.mjs` の `test-without-implementation`)。
47
+ - **transient な状態をポーリングで待たない。** 偽ワーカーは数msで返るので `running` は掴めない。
48
+ **残る証跡**(verdict・キューの中身・保存された状態)を待つ。時計を待つテストは飽和で揺れる。
49
+ - **赤を見つけたら、まず単体で再走**して「飽和フレーク」と「本物」を分ける。飽和で31秒かけて落ちるものが実在する
50
+ (`agent-picker-availability`)。素の `origin/main` と比べて自分の変更のせいかを判定する。
51
+ - **古い open PR をマージする前に、今日の `main` に載せて実機で確認する。**
52
+ main が既に別実装で解決済みなのに残っていた PR が実在(#425/#435/#509・全てクローズ)。
53
+ → `node tools/conflict-check.mjs --pr <n>` の `already-in-main` 検査。
54
+
29
55
  ## デザイン(Masa指示 2026-07-06・必読)
30
56
 
31
57
  - **UI(app/index.html・app/theme.css 等)に触る前に、必ず `docs/design/DESIGN-RULES.md` を読むこと**。特に §1.5 レイアウトの憲法(10条)と §5.5 美学。条文に反する実装はせず、変えたい場合は理由を添えて仲田さんの決定を仰ぐ。
32
58
  - app/ のUIファイル編集時はhook(tools/design_rules_hook.sh)が自動でリマインドする。リマインドが出たら読んだ上で作業すること。
33
59
  - 実装時の詳細契約は `docs/design/CTO-HANDOFF.md`(CDO→CTO引き継ぎ書)に従う。**既存パーツで作れない新しい画面・コンポーネントが必要になったら、自作せず実装前にCDOへ依頼すること。**
34
60
 
61
+ ## プロダクトの不変条件(実装前に読む・2026-07-30 追加)
62
+
63
+ **正典 = `docs/PRD.md` §0(薄いインターフェース+4決定)と §0.1(信頼性の不変条件)。** 実装で迷ったらここに戻る。
64
+ Galda の役割は**依頼を Claude Code / Codex に繋ぐこと**で、途中に自前の AI 判断を挟まない。要約すると:
65
+
66
+ - **測っていない割合を主張しない**(キャッシュヒット率は節約ではない)。基準線が無い間は黙る。
67
+ - **判定は必ず最新の試行のもの**(文章が最新・絵や判定が最初、を作らない。同じ形のバグが3か所にあった)。
68
+ - **出荷していないものを成功として祝わない**(未マージでクローズされた PR を done にしない)。
69
+ - **人が頼んでいないものを要求として数えない**(Manager 発の返信を要求カバレッジに載せない)。
70
+ - **止まっているものは「なぜ」を言う**(`stacked` は動いても失敗してもいない=外からは壊れて見える)。
71
+ - **このマシンにできないことは先に言う**(欠けている実行ファイル名でなく、何ができなくなるかを言う)。
72
+ - **助言と停止判断を混ぜない**(`npm test` を開始できないものだけが blocking。混ぜると「走らせていないスイートが0 failed」になる)。
73
+
74
+ 新しく「Galda が判断する」挙動を足したくなったら、**足す前に Masa の決定を仰ぐ**(§0 決定3の自動選択禁止と同じ理由)。
75
+
35
76
  ## 実装規律
36
77
 
37
78
  - 変更は最小限。周辺コードの流儀に合わせる。
package/app/index.html CHANGED
@@ -2279,19 +2279,6 @@
2279
2279
  /* Changed/Tests aligns with the request TEXT, not the number/chevron — same 18px
2280
2280
  the fold body below uses, so both sit under the same column (Masa 2026-07-29). */
2281
2281
  .redesign .rqit .rqev{font-size:12px;color:var(--ink3);margin:5px 0 0;padding-left:18px}
2282
- /* Canonical requirement coverage: one compact ledger, not three competing
2283
- interpretations. Status is text + a small rule/mark (no badge surface),
2284
- and Manager checks stay visually distinct from worker claims. */
2285
- .redesign .rqcov{display:flex;flex-direction:column;margin-top:2px}
2286
- .redesign .rqcov-row{padding:11px 0;border-top:1px solid var(--hair)}
2287
- .redesign .rqcov-row:first-child{padding-top:0;border-top:0}
2288
- .redesign .rqcov-main{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:14px;align-items:baseline}
2289
- .redesign .rqcov-text{font-size:13.5px;line-height:1.55;color:var(--ink)}
2290
- .redesign .rqcov-state{font:600 10px/1.4 var(--mono);letter-spacing:.02em;color:var(--ink3);white-space:nowrap}
2291
- .redesign .rqcov-state.verified{color:var(--green)}
2292
- .redesign .rqcov-state.failed{color:var(--danger)}
2293
- .redesign .rqcov-detail{margin-top:5px;font-size:11.5px;line-height:1.55;color:var(--ink3)}
2294
- .redesign .rqcov-detail b{font-weight:600;color:var(--ink2)}
2295
2282
  /* A long ask folds with the SAME .lacc pulldown Activity/Conversation use — chevron on
2296
2283
  the peek line, body is the genuine rest (no duplicate, no trailing "…": Masa
2297
2284
  2026-07-29 flagged both the vertical anchor line and the "…" as unnecessary — the
@@ -10282,18 +10269,6 @@ function saItemHtml(it, i){
10282
10269
  const summarySec = summaryText
10283
10270
  ? `<section class="rsec rsum"><div class="rsec-h">Summary</div><p class="rbody v">${esc(summaryText.slice(0, 200))}</p></section>`
10284
10271
  : '';
10285
- const coverage = (it.requirementCoverage || []).filter((r) => r.text);
10286
- const coverageRows = coverage.map((r) => {
10287
- const labels = { verified: 'Verified', failed: 'Failed', 'not-applicable': 'Not applicable', unverified: 'Not verified' };
10288
- const details = [
10289
- r.legacy ? 'Legacy item — no canonical evidence was recorded' : '',
10290
- r.checkFacts?.length ? `Manager: ${r.checkFacts.join(' · ')}` : '',
10291
- r.claims?.length ? `Worker claim: ${r.claims.join(', ')}` : '',
10292
- r.workerEvidence?.length ? r.workerEvidence.join(' · ') : '',
10293
- ].filter(Boolean);
10294
- return `<div class="rqcov-row" data-requirement-id="${esc(r.id)}"><div class="rqcov-main"><div class="rqcov-text">${esc(r.text)}</div><span class="rqcov-state ${esc(r.coverage)}">${esc(labels[r.coverage] || labels.unverified)}</span></div>${details.length ? `<div class="rqcov-detail">${details.map((detail, index) => index === 0 ? esc(detail) : `<br>${esc(detail)}`).join('')}</div>` : ''}</div>`;
10295
- }).join('');
10296
- const coverageSec = coverageRows ? `<section class="rsec"><div class="rsec-h">Requirement coverage</div><div class="rqcov">${coverageRows}</div></section>` : '';
10297
10272
  // ── Open it (Masa 2026-07-22): a plain section in the card's own typography — the same
10298
10273
  // heading + body shape as Request and Result, not a chip in another vocabulary. The
10299
10274
  // address the worker declared IS the control (press it → the process starts on demand →
@@ -10541,7 +10516,6 @@ function saItemHtml(it, i){
10541
10516
  ${reqSec}
10542
10517
  ${S('Open it', openBody + infraBody)}
10543
10518
  ${S('What to check', checkBody)}
10544
- ${coverageSec}
10545
10519
  ${S('Run state', interruptedBody)}
10546
10520
  ${S('PR', prRepairBody)}
10547
10521
  ${S('Also carries', carriesBody)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@galda/cli",
3
- "version": "0.10.109",
3
+ "version": "0.10.110",
4
4
  "type": "module",
5
5
  "description": "Galda - hand off work to Claude Code or Codex, get proof back. Runs on your existing subscription, no extra API cost.",
6
6
  "scripts": {