check-safety/docs/adr/0003-isolate-proto-freshness-generation.md
2026-08-25 21:27:37 +08:00

2.9 KiB

Isolate proto freshness generation from the scanned repository

Decided 2026-08-25. Check 2f ran make proto in the scanned CMS working tree and compared git status before and after. That made a read-oriented safety check destructive: concurrent checker processes generated into the same files, an interrupted run could leave a partially rewritten tree, and a generated file that was already dirty could change bytes without changing its porcelain status.

Decision

  • Copy the proto generation inputs and existing generated outputs into a unique temporary sandbox for every freshness invocation.
  • Run make proto only in that sandbox. Link only the installed package-local generator executables and their package entrypoints needed by Buf and the export script; generated output paths never point back into the scanned repository.
  • Snapshot generated regular files and symlinks by type, mode, link target, and SHA-256 content digest before and after generation. Sort paths before reporting added, modified, and removed outputs in the existing porcelain-like CLI format.
  • Remove the owned sandbox on success, generator failure, and all ordinary return paths. Abrupt process interruption can affect only disposable system temporary state, never the scanned working tree.
  • Exercise the boundary with real make recipes, including independent concurrent checker processes and a generator that writes partial output before failing.

A repository-wide lock was rejected because it serializes independent safety runs and still leaves the live working tree vulnerable to interrupted generation. Comparing only Git status in a temporary checkout was rejected because status is not a content comparison and can conceal a second rewrite of an already-modified file. Copying the entire repository, including dependency trees and build artifacts, was rejected because proto generation needs only a small, explicit input and output surface.

Consequences

  • Parallel check-safety processes can run proto freshness checks without contending on generated files or corrupting the CMS checkout.
  • Check 2f retains its make proto success, failure, and before/after finding messages while its freshness verdict now follows deterministic file content.
  • Generator stderr is still returned through protoFreshnessResult.output, and sandbox preparation, snapshot, generation, and cleanup failures retain their causal error chains.
  • proto_freshness.go owns isolation and comparison; focused regression coverage lives in proto_freshness_test.go.

Keywords: check-safety, check 2f, proto freshness, make proto, concurrency, interruption safety, sandbox, checkProtoGeneratedFreshness, checkProtoGeneratedFreshnessInSandbox, protoFreshnessResult, proto_freshness.go, proto_freshness_test.go, backend/internal/api, backend/internal/mcpserver/generated, packages/api/src, buf generate, pnpm generate-exports