fix(govern): address review and testing follow-ups for fallback sync

What does this MR do?

Follow-ups from the review and manual testing of !4013 (merged) (fallback periodic sync for glab govern).

Closes #8597 (closed) Related to gitlab-org/gitlab#632992

Changes

  • Keep unknown fields in existing Claude Code hooks (#8597 (closed)). glab govern setup rewrote ~/.claude/settings.json through types that only model type, command, timeout and matcher, so it dropped every other field. Dropping if widened a user's hook to run on every matching tool call. Hook entries and groups now keep fields glab doesn't model and write them back unchanged. Hook commands are also no longer written with HTML escapes (>/dev/null 2>&1 &).
  • doctor fails when the last fallback run only had errors. A run where every session failed (for example with a 404) used to show a passing check. Counts of one are now singular ("1 error").
  • Identity errors are recorded, and error prefixes aren't repeated. Failed agent identity registrations during sync --all now go into the status file, so doctor can show them. Session creation errors no longer read "could not create session: could not create session: …".
  • setup --uninstall checks for a job before asking. It used to ask for confirmation before finding there was nothing to remove. A job that's still loaded after its files were deleted is still removed.
  • A hung opencode export no longer blocks sync --all. A child process of opencode that kept stdout open made the export wait forever, even after the run was cancelled. The export now writes to temporary files instead of pipes, and each export has a 2-minute timeout.
  • Completed OpenCode sessions are forgotten 30 days after completion (part 1 of gitlab-org/gitlab#632992). Checking whether an OpenCode session still exists needs a full opencode export, and its "Session not found" isn't proof of deletion, so a fixed retention period is used instead. Part 2 of that issue, pausing when the OpenCode integration is removed, still depends on glab govern setup installing one.

How to test

  • go test ./internal/commands/govern/...
  • #8597 (closed): add the hook from the issue to ~/.claude/settings.json, run glab govern setup, and check that if and statusMessage are still there.
  • doctor: with a project where the governance API returns 404, run glab govern audit sync --all, then glab govern doctor; the fallback check fails and suggests running the sync to see the errors.
  • Hang: the tests in sync_all_test.go run a fake opencode that leaves a background child holding stdout. They fail after 20 seconds without this change.

Who is affected

Only users who run glab govern setup (an experimental command).

Merge request reports

Loading
Loading