Skip to content

feat(sync): add the Track B distribution caller workflow - #63

Merged
kyle-sexton merged 1 commit into
mainfrom
feat/standards-sync-caller
Jul 7, 2026
Merged

feat(sync): add the Track B distribution caller workflow#63
kyle-sexton merged 1 commit into
mainfrom
feat/standards-sync-caller

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Activates the Track B config-distribution caller per the plan doc's activation checklist (docs/dedup-program/config-distribution-plan.md):

  • Calls melodic-software/ci-workflows/.github/workflows/standards-sync.yml@9cf6d13 (latest main, includes the targets filter from ci-workflows#56), SHA-pinned per D5.
  • Wires STANDARDS_SYNC_APP_ID / STANDARDS_SYNC_APP_PRIVATE_KEY (already set on this repo; App verified installed on the org with exactly contents:write + pull_requests:write).
  • Deliberate deviation from the plan-doc snippet: workflow_dispatch only. The snippet's push (paths) + weekly schedule triggers would let a modules-touching merge or the Monday 06:00 UTC cron fire a full-fleet REAL sync before the single-target pilot is confirmed (inputs.dry-run || false evaluates to a real run on both events). They land in a follow-up PR after the pilot — the header comment carries the snippet's || false inversion warning forward.
  • Adds a targets passthrough so the pilot can run against melodic-software/github-iac alone.

Verification

actionlint + zizmor clean locally; the dry-run dispatch (engine plan job needs no secrets) is the next activation step.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GbDWhcUtduCejgi7mcbMfy


Note

Medium Risk
Enables org-wide config distribution PRs via a GitHub App once dry-run is turned off; staged dispatch limits blast radius but misconfiguration or premature activation could still open many PRs.

Overview
Adds .github/workflows/sync.yml, the Track B caller that invokes the SHA-pinned reusable standards-sync engine in ci-workflows to distribute manifest-driven config and open per-repo PRs.

Activation is staged: only workflow_dispatch with dry-run defaulting to true and an optional targets allowlist for a single-repo pilot. push and weekly schedule triggers are intentionally deferred so merges or cron cannot run a full-fleet real sync before the pilot. The job passes STANDARDS_SYNC_APP_* secrets and keeps contents: read on the caller.

Reviewed by Cursor Bugbot for commit 39b2fcb. Bugbot is set up for automated code reviews on this repo. Configure here.

@claude

claude Bot commented Jul 7, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 33s —— View job


Code Review

  • Load tools
  • Read guidelines and context
  • Analyze and write review

File reviewed: .github/workflows/sync.yml

This is a clean, well-scoped activation PR. The deliberate deviation from the plan-doc snippet is correctly reasoned and well-documented. No blocking issues found.


What looks good

SHA pinning — Full SHA (9cf6d135...) with inline short-hash + date comment on line 32 satisfies D5. Matches the pattern in ci-workflows' own referenced actions throughout ci.yml.

dry-run: true default — Safe for dispatch. The plan-doc snippet's inputs.dry-run || false pattern is only needed once schedule/push triggers land (to coerce nullfalse on non-dispatch events). Omitting it here is correct; using it here would be a no-op at best or confusing at worst.

Permission footprintpermissions: contents: read at the caller level is the right minimal scope. The cross-repo writes happen via the GitHub App installation token (minted inside the reusable engine), not GITHUB_TOKEN, so the caller needs no elevated permissions in this repo.

targets passthrough — Good pilot-phase control. Empty default preserves the "all targets" semantics for later; the pilot can pass melodic-software/github-iac explicitly without any code change.

Header comment — The || false inversion warning carried forward is worth keeping; it'll save the follow-up PR author from the same analysis.


Nits / low-risk observations

1. Missing concurrency block — Every other workflow in this repo uses:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

A workflow_dispatch-only workflow is low risk since back-to-back manual triggers are unlikely, but adding it now is cheap and consistent. The ref for dispatches is the selected branch, so the group key would correctly serialize per-branch runs. Worth adding before the follow-up PR wires the push/schedule triggers, where back-to-back invocations are real.

2. No timeout-minutes on the sync jobuses: jobs inherit GitHub's 6-hour runner default unless set. Every runs-on job in ci.yml specifies timeout-minutes: 15. The reusable engine presumably has its own job-level timeouts, but if it ever hangs, this caller has no backstop. Consider adding a conservative caller-level timeout (e.g. timeout-minutes: 30) to match the repo's convention and provide an upper bound independent of the engine's own settings.


Plan-doc checklist status (informational)

This PR correctly lands only the ungated "Author the standards caller workflow" item. The gated activation steps (re-confirming targets against live repos, GitHub App IaC wiring, Layer-1 package publishing) remain open per the plan doc — that's the right sequencing.


Verdict: approve with the above nits noted. Both are cosmetic/conventions issues, not correctness or security problems. The concurrency block is the more worthwhile of the two to address before the follow-up trigger PR lands.

Calls the ci-workflows standards-sync engine (SHA-pinned per D5) with
the App secrets wired. Dispatch-only for the staged activation: the
push-paths and weekly-schedule triggers land in a follow-up once the
single-target pilot is confirmed, so neither a modules-touching merge
nor the Monday cron can fire a full-fleet real sync before then.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GbDWhcUtduCejgi7mcbMfy

@cursor cursor 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.

Risk: medium. Cursor Bugbot completed with no findings. Approved; no reviewers assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@kyle-sexton
kyle-sexton merged commit 959c486 into main Jul 7, 2026
37 of 38 checks passed
@kyle-sexton
kyle-sexton deleted the feat/standards-sync-caller branch July 7, 2026 01:24
kyle-sexton added a commit that referenced this pull request Jul 15, 2026
…on governance (#123)

## Summary

Closes decisions **#27**, **#63**, and **#65** from the [Decisions
Log](https://claude.ai/code/artifact/232ecdce-8316-4880-8c0a-dc3c7dcf3a63)
(evidence/rationale:
https://claude.ai/code/artifact/3160ae0e-c02f-4619-8de3-60d73faa1100).

### #63 metadata-standards-copy-vs-cite-doctrine

Decision: **keep the "copy" adoption path, require back-link +
drift-check.**

Adds `distribution/governance-process.md`. `conventions/README.md`
already documents two adoption paths for reasoning-only prose — copy
into the consumer's tree, or point at this repo. The copy path stays
available (prose has no runtime coupling to enforce reconciliation the
way `sync-manifest.yml` does), but a copy now carries two mandatory
requirements:

- **Back-link** — every copied file cites its exact canonical source
(repo + path, inline header where the format allows it), using the same
stable-anchor citation discipline `reference-dont-duplicate.md` already
prescribes for the "Expose" file role.
- **Drift-check** — the adopting repo owns a periodic diff of its copy
against the current canonical source, with a named owner and trigger,
mirroring the recheck-trigger discipline
`documentation-and-citations.md` already requires for time-bound
external claims.

The doc is explicit that this is distinct from a `managed`
`sync-manifest.yml` component, which already reconciles automatically
and deliberately carries no downstream receipt — the
back-link/drift-check burden applies only where nothing else keeps a
copy current.

### #65 naming-cross-doc-reconciliation-process-ownership

Decision: **establish a standing cross-reference review step for
normative-doc changes.**

Same doc adds the standing process step: before a change to a normative
doc (`naming.md`, `process/issue-tracker.md`, `review/code-quality.md`,
and any other file in the catalog stating a rule another doc cites or
assumes) merges, a cross-reference check confirms no other doc now
contradicts it.

Ownership is named explicitly rather than left implicit:
`required_approving_review_count` stays at `0` org-wide (decision #11,
single-maintainer), so there is no independent blocking reviewer to gate
this. The step is documented as a **self-review checklist item the
author performs before merge**, with a documented future automation path
— extending the periodic cross-plugin-source consistency check (decision
#37, for `claude-code-plugins`) to this repo's own normative docs once
that check exists, so the control stops depending solely on author
diligence.

`conventions/README.md` gets a new "Changing a normative file" pointer
to this requirement; `distribution/README.md` gets a pointer alongside
its existing `THREAT-MODEL.md` reference.

### #27 tooling-gov-conventions-graduate-to-enforced

Decision: **graduate mechanically-checkable rules into
sync-manifest-tracked components.**

Reviewed every file under `conventions/` against
`enforceability-tiers.md`'s
deterministic/detect-then-judge/reasoning-only split. Finding: **no
ungraduated deterministic rule exists to graduate.** Every deterministic
(mechanically-checkable) rule already points to its owning component
instead of restating it:

| Convention area | Deterministic rule | Owning component | Tracked in
`sync-manifest.yml`? |
|---|---|---|---|
| Secrets (`review/security.md`) | no secrets in source | `gitleaks` |
yes |
| Comments (`review/code-quality.md`) | debt markers / tracker
provenance | `comment-hygiene` | yes (`comment-hygiene-action`) |
| Citations (`documentation-and-citations.md`) | cited URL resolves |
link check | yes (`lychee`) |
| TypeScript/JS (`review/overlays/typescript.md`) | lint/format/import
order, type correctness | `biome`, `tsconfig` | **no** — deliberately
native-package (`extends`) adoption per `distribution/README.md`'s
ownership model, not exact materialization |
| Python (`review/overlays/python.md`) | lint/format, type correctness |
`ruff`, `pyright` | yes |
| .NET (`review/overlays/dotnet.md`) | analyzers, code style, banned
symbols | `dotnet-analysis` | yes |
| Container build (`container-supply-chain.md`) | Docker Build checks,
OSV scans | *(none yet)* | **no** — the convention itself explicitly
defers this pending live-consumer admission evidence per
`docs/component-lifecycle.md`; graduating it without that evidence would
violate the same lifecycle contract |
| PR titles (`review/code-quality.md`) | Conventional Commits format |
*(ci-workflows `pr-title.yml`)* | out of this repo's materialization
surface — owned by `ci-workflows`, per README.md's ownership boundaries
|
| Naming (`naming.md`), label/issue-tracker usage
(`process/issue-tracker.md`), duplication
(`reference-dont-duplicate.md`) | — | — | self-declared reasoning-only;
no deterministic subset exists to graduate |

No `sync-manifest.yml` change is included. The one adjacent orphan
noticed in passing — `components/lefthook-typescript` exists, is fully
built, but is not registered in `sync-manifest.yml` for any target — is
tooling infrastructure, not a `conventions/` rule, and assigning it to a
target's `managed:` list is a separate adoption decision requiring its
own admission evidence; flagging it here for a follow-up rather than
folding it into this PR.

## Test plan

- [x] `npx markdownlint-cli2` — 0 errors across the full repo (71 files,
including the new/changed docs)
- [x] `lychee` — 21/21 links OK on the changed files (0 errors)
- [x] `typos` — clean on the changed files
- [x] `lefthook` pre-commit (typos, editorconfig, gitleaks,
markdownlint) — all passed at commit time
- [ ] Maintainer confirms the #27 classification table before merge — no
code/config changed, so this PR is prose-only and carries no behavioral
risk

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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.

1 participant