Skip to content

fix: let the updater adopt a release's new generated outputs - #119

Merged
crypticpy merged 3 commits into
mainfrom
fix/updater-generated-outputs
Oct 17, 2026
Merged

crypticpy merged 3 commits into
mainfrom
fix/updater-generated-outputs

Conversation

@crypticpy

Copy link
Copy Markdown
Owner

Problem

A release that adds a generator output deadlocked downstream updates. rc.11 added submit/answers.schema.json and submit/agent-instructions.txt, and BCHC hit both halves of the deadlock:

  1. assertStableOwnershipContract refused the target's new merge=ours rules until the deployment had migrated (run 38987627059).
  2. Once migrated (BCHC #143), the deployment's pre-update ownership:check rejected the migration. That check runs the deployment's own generated_paths.mjs, which didn't list the new files (run 38988121431). It took a hand bridge (BCHC #144) to get through.

Change

resolveOwnershipContract and generatedOutputAdditions in scripts/apply_phct_update.mjs accept two kinds of target contract:

  • one equal to the current contract

  • one that only adds rules that are all of these:

    • a literal merge=ours path (no glob characters)
    • listed in the target's .phct/ownership.yml ownership.generated
    • absent from the deployment's tracked files
    • still deployment-owned after every target rule

    Every existing rule must also survive in order.

The updater then plans with the target's rules. It leaves those paths alone, npm run generate writes them from the deployment's data, and the log names them.

Every other ownership change still fails closed: a glob, a reclaim, a reorder, a removed rule, a file the deployment already has, a path that isn't a generator output, or a path a later exception unprotects. The pre-update check stops deadlocking because the deployment no longer migrates first. .gitattributes, .phct/ownership.yml and generated_paths.mjs all arrive from the target together, and the target's ownership:check validates them after generate.

assertStableOwnershipContract keeps its strict behaviour for existing callers.

Lag: a deployment runs the updater it already has. This takes effect from the update after the one that ships it, and that shipping release must not itself add a generated output. docs/upgrading.md and the CHANGELOG say so.

Evidence

  • Real replay of the deadlock: BCHC at the commit before #143 (rc.10, no migration), updated to rc.11 and then to rc.12 with the new script, following the workflow's step order:
    • The updater adopted both files.
    • All 204 protected files stayed byte-identical before and after.
    • generate wrote both files from BCHC's config.
    • The target's ownership:check passed.
    • The rc.12 replay ran the full npm run verify to exit 0: 1309 + 5 Node tests and 283 Ruby runs, with 0 failures.
  • New tests:
    • adoption, including a rule inserted between existing rules
    • nine fail-closed variants
    • an end-to-end git fixture where the adopted file isn't checked out from the template
  • Each new guard is tested: with the isForkOwned guard removed, the suite fails.
  • Repository gates: npm run lint is clean and npm test passes 1314/1314.
  • Independent adversarial review: no blockers. Its one test gap is covered in the second commit.

🤖 Generated with Claude Code

coa-chrisc and others added 2 commits October 17, 2026 12:26
A release that added a generator output deadlocked downstream updates:
the updater refused the new merge=ours rules until the deployment had
migrated, and the deployment's own ownership:check refused the migration
until it had the new generated_paths.mjs. rc.11 needed two hand-made
pull requests in BCHC (#143, #144) to get through.

The updater now accepts a target contract that is the current one plus
only literal merge=ours paths listed in the target's ownership.generated,
absent from the deployment, still protected after every target rule, with
every existing rule kept in order. It leaves those paths for npm run
generate. Every other ownership change still fails closed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rotects

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-17T17:41:55.257746Z 6a255e6 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a46234dff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/apply_phct_update.mjs
In the manual update flow an untracked file is missing from git ls-files,
so the updater would adopt the rule and npm run generate would replace
the file. Any path on disk now refuses the adoption.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@crypticpy
crypticpy merged commit e5a6d95 into main Oct 17, 2026
27 checks passed
@crypticpy
crypticpy deleted the fix/updater-generated-outputs branch October 17, 2026 19:06
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.

2 participants