Skip to content

Promote develop to main After the Hub-Hosted Merge-Bot and the PhotoCleaner Report - #746

Merged
ptr727 merged 2 commits into
mainfrom
develop
Aug 15, 2026
Merged

Promote develop to main After the Hub-Hosted Merge-Bot and the PhotoCleaner Report#746
ptr727 merged 2 commits into
mainfrom
develop

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Promote develop to main, carrying two changes:

The release that follows this promotion is the first tag naming merge-bot-task.yml, which is the pin the downstream caller stubs use, so the merge-bot adoption sweep and the catalog snippet both wait on it. A Dependabot pull request against main after this merge is the --merge half of the live proof of the callee.

Refs #521 (hub half shipped in #744, sweep half is the adoption). No issue closes on this promotion.

…nc (#739)
Follow-up to #723 after ptr727/PhotoCleaner#51 promoted `develop` to
`main` (`f56178a`), carrying ptr727/PhotoCleaner#50 and
ptr727/PhotoCleaner#52.
`spec/audit.py PhotoCleaner` at hub `b09078e` reports **clean** at
`main` (`audit run 2026-08-15T18:43:20Z | hub b09078e`) and at
`develop`, including the two hub-only workflow findings that #736
settled. The report moves to **operational**: `readme-structure` and
`agent-instruction-set` to pass, no defects, no drift, nothing in
flight. It records the one-round `dead-path` block on the promotion
(#721, fixed by #731, cleared by a re-run since the gate reads rules
from hub `develop`) and closes both escalations (#721, #722). The
registry entry is unchanged: `status` stays `cataloged` (the schema's
only non-backlog value) and both `driftNotes` still describe reality
(publish shape, private-for-now) and assert no outstanding work.
Report lints clean (markdownlint, prose_lint), and `spec/validate.py`
passes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## What
The first step of moving the fleet's standard workflows out of every
repo and into the hub, once, as `workflow_call` tasks a downstream repo
reaches through a pinned `uses:` rather than carries. Repo-specific
behavior lands in a composite-action hook at a conventional path, with a
hub default where one makes sense.
- **`docs/reusable-workflows.md`** (hub-only): the target model, the
hook contract, the pin and secrets policy, the hook catalog, the Docker
family design, the migration phases, the merge-bot adoption stub, what a
pilot proves, and the open decisions.
- **`spec/workflow_reuse.py` and `reports/workflow-reuse.md`**: the
burn-down. It reads every cataloged repo's `.github/workflows/` from its
ground-truth branch, compares each file against the hub canonical after
the verbatim engine's normalization, and clusters the copies into
variants. First run at hub `7c67328`: 108 files and 10,964 lines across
20 downstream repos, 5,385 lines (49 percent) byte-identical to a hub
canonical, one file reaching the hub. Its `--selftest` runs in CI beside
the audit engine's.
- **`.github/workflows/merge-bot-task.yml`**: the merge-bot as a hub
task. Three jobs, `merge-dependabot`, `merge-app` (built-in codegen and
upstream-version pairs plus a `rules` JSON input for a repo's own
tracker), and `disable-auto-merge-on-maintainer-push`. Inputs
`app-login`, `rules`, `delete-branch`. Explicit `secrets:` declarations,
no `inherit`. No `GITHUB_TOKEN` scope in the callee and `permissions:
{}` in the caller, which is the hub half of #521.
- **`.github/workflows/merge-bot-pull-request.yml`**: the hub's own
caller stub, byte-shaped like the downstream one apart from the `./`
uses.
- **`spec/files.json`**: the merge-bot contract becomes the caller job,
the hub task token, and the two mapped secrets. Every downstream copy
now reports `missing required job 'merge-bot'`, which is the adoption
work list the TODO sweep entry carries.
- **`TODO.md`**: the "Hub-Hosted Reusable Workflows" cluster (gates,
pure functions, release chain and Docker core, type-specific tasks, the
catalog snippet, three open decisions, the Dockerfile shape item), the
merge-bot adoption sweep, the superseded investigation entry removed,
and "The Merge-Bot Token Grants" folded in.
- Prose that described copied jobs: GOVERNANCE.md "Hub-Hosted Tooling"
(one sentence, verbatim section) and the concurrency exception,
WORKFLOW.md D8.3 and the D8/D9 audit line, the catalog README and the
upstream tracker's `bump-branch-prefix` comment, the two stale "override
seam" pointers in `spec/fidelity-model.md` and `spec/audit.py`, and the
two skills that describe copied orchestration.
## Why the catalog snippet is not in this PR
`catalog/snippets/workflows/` is scanned by `repo_gate.py
check_sha_pin`, so a caller snippet cannot carry a placeholder SHA, and
no released hub commit carries `merge-bot-task.yml` until this promotes
and releases. The stub's text is in the doc's "Adopting the Merge-Bot"
and the TODO cluster carries the follow-up.
## Verification
- `python3 spec/workflow_reuse.py --selftest` and `--report` (the report
is regenerated from the live fleet).
- The `merge-app` rule filter run standalone against the four built-in
pairs, an `ha-version-bump/` prefix on `develop` and on `main`, an empty
prefix, and three malformed `rules` inputs.
- `python3 spec/audit.py --selftest` with four new interface cases for
the stub, `python3 -m unittest discover -s scripts/tests` (668 tests,
one new for an owner-scoped reusable-workflow pin), `python3
spec/validate.py`, `python3 scripts/repo_gate.py`, `python3
scripts/build_dist.py --check`, `python3 scripts/prose_lint.py` with the
CI rule list, actionlint, markdownlint, cspell, editorconfig-checker,
ruff check and format, mypy.
- `python3 spec/audit.py HomeAutomation-Config` reports the new
merge-bot finding as designed.
## What this PR cannot prove
The hub's own stub proves the callee mechanics on the first Dependabot
PR after this lands on `develop`, since under `pull_request_target` a
feature branch's callee resolves from the base branch. What only a
downstream adopter proves is cross-repository resolution of the
owner-scoped `uses:`, Dependabot bumping a `# <tag>` pin on a reusable
workflow, and the `rules` input end to end. The doc states these as the
pilot's checklist rather than as claims.
Refs #521 (hub half done here, the sweep half is the adoption). Settles
the workflow half of #735 by design once the phases land, and #585 and
#729 land inside the gates phase.
CopilotAI lite review requested due to automatic review settings August 15, 2026 20:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Promotes develop to main, bringing in the hub-hosted Merge-Bot reusable workflow model (plus measurement/reporting for workflow reuse across the fleet) and refreshing the PhotoCleaner audit report to operational status.

Changes:

  • Add a hub-hosted reusable workflow for the Merge-Bot (merge-bot-task.yml) and convert the hub’s merge-bot entry workflow into a thin caller stub.
  • Introduce spec/workflow_reuse.py plus a generated reports/workflow-reuse.md report to quantify workflow duplication and track the migration burn-down.
  • Update the audit/contracts/docs to reflect the new reusable-workflow model and refresh PhotoCleaner’s audit report.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
WORKFLOW.mdUpdates D8.3/D8-D9 wording to reflect merge-bot rule matching (built-ins or caller-provided rules).
TODO.mdReworks the workflow-reuse workstream into the new “Hub-Hosted Reusable Workflows” cluster and updates adoption tracking.
spec/workflow_reuse.pyAdds the workflow-reuse measurement tool with offline self-tests and report generation.
spec/files.jsonUpdates the merge-bot workflow interface contract to require the new caller-stub shape and secret mappings.
spec/fidelity-model.mdExpands interface fidelity description to include bot workflows and reusable-workflow caller stubs.
spec/audit.pyUpdates interface drift messaging and adds self-tests for the merge-bot caller stub contract.
scripts/tests/test_repo_gate.pyAdds coverage ensuring reusable-workflow refs are treated like action pins for SHA resolution.
reports/workflow-reuse.mdAdds the generated workflow-reuse burn-down report.
reports/photocleaner/audit.mdRefreshes PhotoCleaner audit report to “operational” after its promotion.
GOVERNANCE.mdUpdates hub-hosted tooling section to include pinned reusable workflows alongside pinned actions.
docs/reusable-workflows.mdAdds hub-only design doc describing the reusable-workflow migration model, hooks, and phases.
catalog/snippets/workflows/README.mdDocuments that the hub now carries hosted reusable tasks (starting with merge-bot-task).
catalog/snippets/workflows/check-upstream-version-task.ymlUpdates comments/description to align upstream-version branch prefix with merge-bot rules model.
.github/workflows/validate-task.ymlExtends script self-tests to include spec/workflow_reuse.py --selftest.
.github/workflows/merge-bot-task.ymlAdds the hub-hosted merge-bot reusable workflow (workflow_call) implementing merge/disable logic.
.github/workflows/merge-bot-pull-request.ymlConverts the merge-bot workflow into a thin caller stub with permissions: {} and local task use.
.github/copilot-instructions.mdRecords a disproved claim about hyphenated inputs in GitHub Actions expressions (merge-bot-task context).
.gitattributesPins LF for spec/workflow_reuse.py.
.editorconfigPins LF for spec/workflow_reuse.py to match shebang-executed tooling conventions.
.claude-plugin/fleet-skills/skills/workflow-ci-contract/SKILL.mdUpdates workflow CI contract guidance to incorporate the “reached, not carried” reusable-workflow model.
.claude-plugin/fleet-skills/skills/operational-vs-release-workflow/references/release-publish-mechanics.mdUpdates guidance to reference the reusable-workflow release-chain phase approach.
.claude-plugin/fleet-skills/.source-digestUpdates the fleet-skills source digest for the plugin copy.
.agents/skills/workflow-ci-contract/SKILL.mdMirrors the workflow CI contract update in the agents skills tree.
.agents/skills/operational-vs-release-workflow/references/release-publish-mechanics.mdMirrors the release-publish mechanics update in the agents skills tree.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@ptr727
ptr727 merged commit 20616e0 into mainAug 15, 2026
7 checks passed
ptr727 added a commit that referenced this pull request Aug 16, 2026
## What
- `docs/reusable-workflows.md` gains a **Rollout** section replacing the
prose "Migration Phases": six stages (0 design and merge-bot task, 1
merge-bot adoption, 2 gates, 3 pure functions, 4 release chain and
Docker core, 5 type-specific), each with hub, release, and per-repo
adoption checkboxes. Items are ticked only with the evidence that closed
them (PR, commit, tag, run URL), and the section opens with how a
session resumes from it: read it first, take the first unchecked item in
an open stage, verify against the tree, work in a worktree, tick in the
same PR. Stage 0 is ticked with #744, #746, and release `2.0.338`, apart
from the two live-proof items that wait on the next Dependabot PRs.
- `catalog/snippets/workflows/merge-bot-pull-request.yml`: the caller
stub, now that `2.0.338` on `20616e0` carries `merge-bot-task.yml`. The
pin resolves under `repo_gate.py check_sha_pin`. The doc's stub carries
the same pin, and the catalog README gains the row.
- `TODO.md`: the cluster names the Rollout section as the state tracker
and drops the snippet entry it just shipped.
## Why
The plan lived as prose and as TODO entries, and nothing in git said
which stage was done, so a cold session had no first unchecked item to
take. Only git persists.
## Verification
prose_lint (CI rule list), actionlint, markdownlint, `repo_gate.py` (the
new pin resolved against GitHub), unit tests, audit self-test,
build_dist --check.
Sign up for freeto 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

@ptr727