Skip to content
frontmatter
キー値
specdojo.idprj-0001:pjr-nfv7-result-trailing-newline
specdojo.typeproject
specdojo.statusready
specdojo.rulebookspecdojo:pjr-rulebook
specdojo.part_ofprj-0001:pjr-index
specdojo.item_typetodo
specdojo.item_statusdone
specdojo.prioritylow
specdojo.ownerDEV
specdojo.registered_at2026-09-23T21:26:24Z
specdojo.due_on2026-10-24
specdojo.completed_at2026-09-24T12:41:02Z
specdojo.block_reasonintegrate failed: git status failed: fatal: detected dubious ownership in repository at '/workspaces/specdojo-workspace/worktrees/prj-0001-PJR-NFV7' (args: --porcelain=v1 -z --untracked-files=all)
specdojo.conclusionplan と result の書き出し共通経路へ末尾改行の正規化を入れた。冪等で、Prettier 対象外のファイルも通る。

PJR-NFV7 result の末尾改行を runner 側で正規化する ​

1. 概要 ​

2026-09-23 夜間の grade routine が生成した result のうち 2 件に末尾改行が無く、npm run lint:md が MD047(Files should end with a single newline character)で失敗した。

text
docs/ja/projects/prj-0001/execution/exec/results/JBR-grade-deliverable-ceb925289809-result.md
docs/ja/projects/prj-0001/execution/exec/results/JBR-grade-kata-f8b11861e500-result.md

32 件中 2 件であり、書き出し処理が常に改行を落としているわけではない。reporter が生成した本文がそのまま書かれ、agent の出力にばらつきがあることに由来する。

lint:md は pre-commit で走るため、この状態のまま commit しようとすると止まる。routine は自動実行される前提なので、自動実行の成果物が人手の介入を呼ぶ形になっている。

2. 完了条件 ​

  • runner が result を書き出す際、末尾に改行が 1 つあることを保証する。既に改行がある場合は増やさない。
  • plan など、同じ経路で書き出す他の Markdown 成果物にも同じ正規化が適用されている。
  • 末尾改行の有無が異なる入力に対して、出力が同一になることを検証する単体テストがある。
  • 既存の result を再生成せずとも npm run lint:md が通過する状態を保つ。
  • npm run check が通過している。

3. 作業内容 ​

No作業担当状態メモ
1result の書き出し経路を特定するDEVdoneformatMarkdownFile に集約
2末尾改行の正規化を入れるDEVdone冪等に 1 改行へ正規化
3plan など同じ経路の成果物へも適用するDEVdoneplan / result の共通経路へ適用
4入力のばらつきに対する単体テストを追加するDEVdone改行あり/なし/複数を検証

4. 対応結果 ​

  • formatMarkdownFile で Markdown の末尾を 1 改行へ正規化するようにした。
  • Prettier 対象外の exec plan / result も本文は整形せず、末尾改行だけを正規化する。
  • plan / result の両方について、末尾改行なし・1つ・複数の入力が同一出力になる単体テストを追加した。

4.1. オーケストレーターによる確認 ​

normalizeTrailingNewline は末尾の改行類をすべて落としてから 1 つ付けるため冪等である。改行なし・1 つ・複数のいずれを入力しても同じ結果になる。

適用位置が適切である。src/exec-format.ts という書き出しの共通経路にあり、plan と result の両方を通る。Prettier 対象外のファイルも取りこぼしていない。

typescript
// exec の plan / result は本文保護のため Prettier 対象外だが、runner が生成する
// Markdown として末尾改行だけは同じ書き出し経路で必ず正規化する。
if (await isPrettierIgnored(filePath)) {
  if (normalized !== source) await writeFile(filePath, normalized, "utf8");
  return;
}

Prettier を通す経路でも整形後に再度正規化している。

4.2. 実行経路 ​

統合段で fatal: detected dubious ownership により一度失敗し、--resume で統合段だけを再開して完了した。所有者は一致しており再現しないため一過性と判断し、再試行の実装を prj-0001:pjr-bx79-integrate-dubious-ownership-retry として切り出した。

この失敗理由が読めたのは prj-0001:pjr-tr8g-git-failure-reason-progress の整形が入っていたためである。

5. 関連ドキュメント ​