Skip to content

fix(repo): say why a target commit became unreachable instead of implying a bad pin (#23) - #24

Merged
braghettos merged 1 commit into
mainfrom
fix/22-23-observe-consults-forge
Sep 25, 2026
Merged

braghettos merged 1 commit into
mainfrom
fix/22-23-observe-consults-forge

Conversation

@braghettos

Copy link
Copy Markdown

Closes #23.

What happened

Nine Repo CRs began failing within 41 seconds of each other:

target commit <sha> not found on branch main while enableUpdate is false

That message describes what the check found, and reads as though each resource had been pinned to a commit that was never there. Nothing was pinned wrong. Their shared target repository was recreated at 12:24:15Z — its entire main history begins one second later — so the recorded commits were discarded along with the history that contained them.

Nine CRs, two distinct SHAs, one repository, one event. The old message sent the reader looking for nine separate mistakes.

The new one names the cause and both remedies. Offering only enableUpdate would push operators toward allowing overwrites they may not want; recreating the resource re-pins to the current history instead.

It is still an error — and that is the interesting part of this PR

My first attempt converted this into a quiet Ready=False with ResourceUpToDate: true. The reasoning looked sound: the branch immediately below already logs-and-continues for the analogous origin-commit case, so the two seemed inconsistent, and Update() already no-ops when enableUpdate is false.

The integration suite rejected it, correctly. TC12-DisableUpdateDetectsTargetDrift does exactly this scenario — deletes and recreates the target repository — and asserts Synced=False/ReconcileError. TC13-AutoHealAfterEnableUpdateFalse covers the heal once the flag is flipped. Together they pin a designed contract: enableUpdate: false surfaces an error until a human chooses.

That contract is right. A real decision is owed here, and reporting it until it is made is the correct behaviour. So this PR changes only the wording.

Worth recording that the test caught a wrong judgement rather than a typo — I had an argument for the change and the argument was wrong.

Not the same as #22, despite the shared function

Both failures are exits of one predicate in Observe (meta.GetExternalName(cr) == ""), which is why they looked related:

#22 the provider refuses on an ambiguity nothing will ever resolve — the resource is stranded with no path back. A deadlock, fixed in the runtime.
#23 a person has a genuine choice to make. Not a deadlock; reporting it is correct.

Same function, two exits, two different defects. Only one of them is a bug in the behaviour.

Detail worth keeping

The "target commit" substring is preserved. TC12 matches on it, and it is how this failure is found across a fleet — nine resources failing for one reason should be greppable as one string. There is a test asserting it stays.

Tests

  • message names the cause, the identifiers, and both remedies
  • the greppable prefix survives
  • full CI-equivalent suite green: go test -race -tags=unit,integration -p 1 -timeout 25m ./... — 9 packages, 0 failures, including TC12 and TC13

🤖 Generated with Claude Code

…ying a bad pin (#23)

Nine Repo CRs began failing within 41 seconds of each other with:

    target commit <sha> not found on branch main while enableUpdate is false

That message describes what the check found, and reads as though each resource had been
pinned to a commit that was never there. Nothing was pinned wrong. Their shared target
repository was recreated at 12:24:15Z — its entire main history begins one second later — so
the recorded commits were discarded along with the history containing them. Nine CRs, two
distinct SHAs, one repository, one event.

The message now names the cause and BOTH remedies. Offering only enableUpdate would push
operators toward allowing overwrites they may not want; re-creating the resource re-pins to the
current history instead.

Deliberately still an error. My first attempt converted this into a quiet Ready=False with
ResourceUpToDate: true, reasoning that the branch below already logs-and-continues for the
analogous origin-commit case. The integration suite rejected that, correctly:
TC12-DisableUpdateDetectsTargetDrift recreates the target repository and asserts
Synced=False/ReconcileError, and TC13-AutoHealAfterEnableUpdateFalse covers the heal once the
flag is flipped. Together they pin a designed contract — enableUpdate: false surfaces an error
until a human chooses — and a real decision is owed here, so reporting it until it is made is
right.

This is NOT the #22 situation despite both being reached from Observe. There the provider
refused on an ambiguity nothing would ever resolve, stranding the resource with no path back.
Here a person has a genuine choice to make. Same function, two exits, two different defects —
only one of them is a deadlock.

The "target commit" substring is preserved: TC12 matches on it, and it is how this failure is
found across a fleet. Nine resources failing for one reason should be greppable as one string.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@braghettos
braghettos merged commit 5e8e2fd into main Sep 25, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A rewritten or recreated target repo orphans every recorded TargetCommitId and hard-fails Observe permanently when enableUpdate is false

1 participant