Skip to content

Retire pairwise BC4↔BC5 canary; keep single-backend BC5 live canary#394

Merged
jeremy merged 6 commits into
mainfrom
retire-pairwise-canary
Jul 24, 2026
Merged

Retire pairwise BC4↔BC5 canary; keep single-backend BC5 live canary#394
jeremy merged 6 commits into
mainfrom
retire-pairwise-canary

Conversation

@jeremy

@jeremy jeremy commented Jul 22, 2026

Copy link
Copy Markdown
Member

Why

make check fails on 7 zizmor secrets-outside-env findings in live-canary.yml (real-account secrets read in step-level env: without an environment:). Chasing that surfaced a deeper issue: the workflow (added in #308) is a pairwise BC4↔BC5 forward-compat canary, but BC5 has replaced BC4 in production (COORDINATION.md: "there is no live BC4 backend"). With one backend, both passes capture identical snapshots and the comparison passes vacuously — a nightly false green that tests nothing.

The one live rule it carried (the memories additive-only waiver) is already settled by documented contract (bc3 #11628: BC5 ships memories: [] permanently).

What

Simplify to a single-backend live canary against production BC5 — preserving the durable value (live schema validation, extras-observed forward-compat reporting, 4-language wire-decode consistency) and removing the now-vacuous pairwise machinery. The zizmor fix (scope secrets behind a branch-gated basecamp-canary environment) still applies, now with a smaller secret set.

  • Workflow — single-backend BC5 canary; job bound to the basecamp-canary environment (clears all 7 findings); secrets are the CANARY_BASECAMP_* set (no BC5_HOST), provisioned as environment secrets on that environment so the credential is scoped to this job (an org/repo secret would be readable by any workflow in the repo); runs make conformance-canary.
  • Makefilecheck-bc5-compatconformance-canary (one conformance-live pass, BASECAMP_BACKEND=production; hardened rm -rf guard preserved); deleted check-compare-canary and dropped it from make check.
  • Scripts — deleted compare-canary-runs.sh + its unit test.
  • Fixture — dropped pairwiseAssertions on GetMyNotifications; kept liveAssertions.
  • Docs — retired the pairwise narrative in CONTRIBUTING.md / COORDINATION.md / the api-gap record; kept the memories: [] contract (now settled by documentation).

Verification

  • make lint-actions (zizmor) → No findings (original 7 cleared)
  • actionlint .github/workflows/live-canary.yml → OK
  • make conformance-canary without secrets → exits with a clear required-env message (graceful, matching the workflow no-op gate); make -n dry-runs cleanly
  • make validate-api-gaps → clean

Follow-up (parked — not in this PR)

Blocked on Basecamp personal access token support. Running the canary in CI requires an OAuth token in a secret, and Basecamp has no PAT/service-token story yet — a user OAuth token in CI is a no-go. So provisioning is parked until that lands, not merely waiting on an admin.

When it's unblocked: create the basecamp-canary environment (default-branch policy, no required reviewers) and provision CANARY_BASECAMP_TOKEN / CANARY_BASECAMP_ACCOUNT_ID / CANARY_BASECAMP_HOST as environment secrets on that environment — not org/repo secrets. Per review (cubic P1), only environment secrets scope the credential to this job; an org/repo secret of the same name would be readable by any workflow in the repo, so the environment would gate the job but not the secret. CANARY_BASECAMP_* stays a cross-repo naming convention (each app on its own <app>-canary environment), not a shared org secret.

Until then the canary no-ops gracefully (missing secrets → clean skip), so this PR is safe to land and simply leaves the canary dormant. The zizmor fix and the pairwise retirement stand on their own.

The pairwise engine remains recoverable from git history (#308) if a reachable legacy backend ever warrants restoring it.


Summary by cubic

Retires the BC4↔BC5 pairwise canary and replaces it with a single-backend live canary against production BC5. Pins the backend label to bc5, removes the false-green nightly, clears the 7 zizmor findings, and keeps live schema validation and 4-language decode checks.

  • Refactors

    • Workflow: run make conformance-canary; job bound to the basecamp-canary environment; secrets are environment-scoped CANARY_BASECAMP_*; no BC5_HOST; clears all 7 zizmor findings.
    • Makefile: add conformance-canary; pin BASECAMP_BACKEND=bc5 inside the sub-make to prevent override; remove check-bc5-compat/check-compare-canary; update make check; keep the hardened rm -rf guard.
    • Schema: reject pairwiseAssertions in conformance/schema.json to prevent dead pairwise rules; recovery noted in docs.
    • Scripts: delete scripts/compare-canary-runs.sh and its unit test.
    • Fixtures/Docs: update GetMyNotifications to reflect live-call + schema-validate only; clarify BASECAMP_HOST is optional only for conformance-typescript-live (canary/CI require it); tighten environment-gating wording; note bubble_ups/scheduled_bubble_ups are modeled (not extras-observed); document that BASECAMP_BACKEND defaults to unknown when unset and that disables only per-backend overrides — generic BASECAMP_<FIXTURE> overrides still apply; the canary requires bc5.
  • Migration

    • Create the basecamp-canary environment (default-branch policy as desired).
    • Add environment secrets on that environment: CANARY_BASECAMP_TOKENBASECAMP_TOKEN, CANARY_BASECAMP_ACCOUNT_IDBASECAMP_ACCOUNT_ID, CANARY_BASECAMP_HOSTBASECAMP_HOST.
    • Until provisioned, the canary no-ops safely.

Written for commit 22fed3d. Summary will update on new commits.

Review in cubic

BC5 has replaced BC4 in production (COORDINATION.md: "there is no live
BC4 backend"). The pairwise forward-compat canary added in #308 captured
snapshots from two live backends and asserted BC5 was an additive
superset of BC4 — but with one backend both passes capture identical
snapshots and the comparison passes vacuously, a nightly false green.

Simplify to a single-backend live canary against production BC5. This
preserves the durable value — live schema validation, extras-observed
forward-compat reporting, and 4-language wire-decode consistency — while
removing the now-vacuous pairwise machinery. The one live rule it carried
(the `memories` additive-only waiver) is already settled by documented
contract (bc3 #11628: BC5 ships `memories: []` permanently).

- Workflow: single-backend BC5 canary; scope secrets behind the
  branch-gated `basecamp-canary` environment (clears the 7 zizmor
  secrets-outside-env findings); reduce to the CANARY_BASECAMP_* secret
  set (no BC5_HOST); run `make conformance-canary`.
- Makefile: replace check-bc5-compat with conformance-canary (one
  conformance-live pass, BASECAMP_BACKEND=production); delete
  check-compare-canary and drop it from `make check`.
- Delete scripts/compare-canary-runs.sh and its unit test.
- Fixture: drop pairwiseAssertions on GetMyNotifications; keep
  liveAssertions (BC5 schema validation).
- Docs: retire the pairwise narrative in CONTRIBUTING.md/COORDINATION.md
  and the api-gap record; keep the memories: [] contract (now settled by
  documentation rather than a live rule). Pairwise engine recoverable
  from git history (#308) if a legacy backend ever warrants restoring it.
Copilot AI review requested due to automatic review settings July 22, 2026 19:34
@github-actions github-actions Bot added documentation Improvements or additions to documentation github-actions Pull requests that update GitHub Actions spec Changes to the Smithy spec or OpenAPI conformance Conformance test suite labels Jul 22, 2026
@github-actions

Copy link
Copy Markdown

Sensitive Change Detection (shadow mode)

This PR modifies control-plane files:

  • .github/workflows/live-canary.yml

Shadow mode — this check is informational only. When activated, changes to these paths will require approval from a maintainer.

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

Spec Change Impact

  • Modified Operations: Retired operations related to pairwise BC4↔BC5 canary; single-backend BC5 live canary remains active.
  • Removed Operations/Types: Any operations or related types tied to BC4↔BC5 canary have been removed.
  • Added Operations/Types: None.
  • Breaking API Change: Yes, removal of operations/fields constitutes a breaking change.

SDKs Needing Updates

  • Go
  • TypeScript
  • Ruby
  • Kotlin
  • Swift

@github-actions github-actions Bot added enhancement New feature or request and removed documentation Improvements or additions to documentation labels Jul 22, 2026

Copilot AI 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.

Pull request overview

This PR retires the now-vacuous pairwise BC4↔BC5 live canary and simplifies the system to a single-backend live conformance canary against production BC5, while also tightening secrets handling for the scheduled workflow.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Changes:

  • Replace the two-backend check-bc5-compat orchestrator + pairwise compare with a single-backend conformance-canary target running conformance-live once against production.
  • Remove the pairwise comparison scripts/tests and drop the pairwiseAssertions fixture for GetMyNotifications.
  • Update docs and the scheduled workflow to reflect the single-backend model and scope secrets behind a protected GitHub environment.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
spec/api-gaps/memories-emptied-regression.md Updates the narrative to reflect the retirement of pairwise enforcement and the settled BC5 memories: [] contract.
scripts/test-compare-canary-runs.sh Deletes the regression test suite for the removed pairwise compare script.
scripts/compare-canary-runs.sh Deletes the pairwise BC4↔BC5 snapshot comparison implementation.
Makefile Replaces check-bc5-compat with conformance-canary and removes the compare-script regression target from make check.
COORDINATION.md Updates coordination guidance to the single-backend BC5 canary and removes pairwise expectations.
CONTRIBUTING.md Updates live-canary docs to the single-backend conformance-canary flow and retains pairwise as a historical note.
conformance/tests/live-my-surface.json Removes pairwiseAssertions for GetMyNotifications, keeping schema validation via liveAssertions.
.github/workflows/live-canary.yml Converts the workflow to single-backend BC5 and gates secrets via the basecamp-canary environment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/live-canary.yml Outdated
Comment thread CONTRIBUTING.md Outdated

@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: 35bc991dd7

ℹ️ 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 Makefile Outdated
- Codex (Makefile): BASECAMP_BACKEND drives the fixture-override prefix
  (BASECAMP_<BACKEND>_*) in conformance/runner/typescript/fixtures.ts and
  must be a valid Backend value (bc4|bc5). `production` broke the advertised
  BASECAMP_BC5_* overrides and isn't a Backend value; use `bc5` (production
  runs BC5). Updated the Makefile label, comments, and docs.
- Copilot (live-canary.yml, CONTRIBUTING.md): reworded to state that
  branch-gating comes from the basecamp-canary environment's deployment-branch
  policy gating the whole job (a job runs only after its environment's
  protection rules pass), not from the secrets being environment-scoped. Kept
  org-level CANARY_BASECAMP_* naming per the cross-repo convention.
Copilot AI review requested due to automatic review settings July 22, 2026 19:48
@github-actions github-actions Bot added documentation Improvements or additions to documentation and removed documentation Improvements or additions to documentation labels Jul 22, 2026

@cubic-dev-ai cubic-dev-ai 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.

Review completed against the latest diff

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread COORDINATION.md

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment thread CONTRIBUTING.md Outdated
…P_HOST

- cubic (schema.json): the pairwise compare engine is gone, but the fixture
  contract still blessed `pairwiseAssertions` — a future fixture could declare
  pairwise rules that validate yet silently never run. Replaced the definition
  with an explicit rejection (`"not": {}`) plus a note pointing at COORDINATION.md
  and the git-history recovery path (PR #308).
- Copilot (CONTRIBUTING.md): `BASECAMP_HOST` is optional only for the bare
  `conformance-typescript-live` target (SDK falls back to its default origin);
  the `conformance-canary` orchestrator and CI require it with no default.
  Clarified the optional-env bullet to say so.
Copilot AI review requested due to automatic review settings July 22, 2026 19:58
@github-actions github-actions Bot added documentation Improvements or additions to documentation and removed documentation Improvements or additions to documentation labels Jul 22, 2026

Copilot AI 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.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread Makefile Outdated
Comment thread conformance/tests/live-my-surface.json Outdated

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 4 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread .github/workflows/live-canary.yml Outdated
Comment thread .github/workflows/live-canary.yml Outdated
Comment thread Makefile Outdated
Comment thread Makefile Outdated
…abel; doc accuracy

Secret scoping (cubic P1, Copilot x2): org/repo secrets are readable by any
workflow in the repo, so the basecamp-canary environment gates this job but not
the credential — only *environment* secrets scope the credential to the gated
job. Reworked the workflow header/comment and CONTRIBUTING to specify
environment secrets on basecamp-canary, keeping CANARY_BASECAMP_* as a
cross-repo naming convention (not org-level). Qualified the branch-gate claim:
repo admins can bypass environment protection rules by default (cubic P2), so
it's defense-in-depth, not absolute.

Backend label hijack (cubic P2): `make BASECAMP_BACKEND=bc4 conformance-canary`
propagated as a command-line variable and overrode the recipe-shell env prefix,
capturing production traffic under the wrong label (verified). Pin bc5 as a
sub-make command-line variable, which wins over the inherited override.

Comment/doc accuracy:
- Makefile:526 (cubic P3, Copilot): stop overstating the Backend type
  (bc4|bc5|unknown); describe the canary requirement (bc5).
- live-my-surface.json (Copilot): the GetMyNotifications description implied it
  enforces memories-empty; it only asserts liveCallSucceeds + liveSchemaValidate.
  Reworded to what's actually asserted, keeping the contract as context.
Copilot AI review requested due to automatic review settings July 23, 2026 02:24
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jul 23, 2026
@github-actions github-actions Bot removed the documentation Improvements or additions to documentation label Jul 23, 2026

Copilot AI 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.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread spec/api-gaps/memories-emptied-regression.md Outdated
Comment thread CONTRIBUTING.md Outdated
- memories-emptied-regression.md (Copilot): bubble_ups / scheduled_bubble_ups
  are modeled in openapi.json, so they schema-validate normally rather than
  surfacing as extras-observed. Reworded so extras-observed describes future,
  not-yet-modeled additions.
- CONTRIBUTING.md (Copilot): the Backend label bullet said (bc4|bc5) but the
  type also has `unknown` (the unset default). Reworded to note the unset
  default and drop the incomplete constraint.
Copilot AI review requested due to automatic review settings July 24, 2026 01:50
@github-actions github-actions Bot added documentation Improvements or additions to documentation and removed documentation Improvements or additions to documentation labels Jul 24, 2026

Copilot AI 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.

Pull request overview

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

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 2 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread CONTRIBUTING.md Outdated
…havior

cubic P3: unset BASECAMP_BACKEND (unknown) disables only the per-backend
BASECAMP_<BACKEND>_* overrides; the generic BASECAMP_<FIXTURE> overrides still
apply before discovery (fixtures.ts fromEnv). Reworded so 'discovery only' no
longer misstates it.
Copilot AI review requested due to automatic review settings July 24, 2026 15:39
@github-actions github-actions Bot added documentation Improvements or additions to documentation and removed documentation Improvements or additions to documentation labels Jul 24, 2026
@jeremy
jeremy merged commit b9230af into main Jul 24, 2026
47 checks passed
@jeremy
jeremy deleted the retire-pairwise-canary branch July 24, 2026 15:46

Copilot AI 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.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Comment thread Makefile
Comment on lines 509 to 510
WIRE_REPLAY_DIR="$$LRD" $(MAKE) conformance-kotlin-replay
@echo "==> conformance-live: capture + replay complete for backend $$BASECAMP_BACKEND"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conformance Conformance test suite enhancement New feature or request github-actions Pull requests that update GitHub Actions spec Changes to the Smithy spec or OpenAPI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants