Skip to content

advisory check for published tarball drift [agent-managed] - #7019

Open
pip-the-concierge-via-chinmina[bot] wants to merge 7 commits into
mainfrom
agent/advisory-tarball-check
Open

advisory check for published tarball drift [agent-managed]#7019
pip-the-concierge-via-chinmina[bot] wants to merge 7 commits into
mainfrom
agent/advisory-tarball-check

Conversation

@pip-the-concierge-via-chinmina

@pip-the-concierge-via-chinmina pip-the-concierge-via-chinmina Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Objective

Advisory check: does the tarball we would publish differ from the one on npm, for a package with no changeset? Replaces the path-based changeset gate, which could not see changes that originate outside a package but still alter its output — a design-token value is inlined into @kaizen/components' built CSS. Pass/fail per package only; a human decides whether it warrants a release.

Not a merge gate — must not be added to required checks. No hard changeset gate remains, by design: a missing changeset means no publish, not a blocked merge. Runs on feature-branch pushes, the inverse of changeset.yaml.

Folds in #7018 (now closed): the publish-failure Slack detail and the .devbox/ lint ignores come with it.

Reviewer guide

  • Skim: pnpm-lock.yaml (adds tsx), .prettierignore + eslint.config.js (ignore devbox artefacts).
  • Judgement: scripts/check-package-output.ts — fingerprint and skip semantics.
  • Judgement: check-package-output.ymlbranches-ignore carries the whole guard, since head_ref is empty on push events.

Decisions

  • Kept the changeset cross-reference so PRs that already have one stay green, rather than reporting drift on every release PR. (Decision: Chris.)
  • No normalisation of tarball contents: pnpm pack matches publish output byte for byte, and the resolved workspace: version is part of the signal.
  • A toolchain bump (rollup, TS) will report every package at once. Correct behaviour, but expect it.

Verifications

  • Null test: all three published packages fingerprint identical to their npm tarballs, exit 0.
  • Drift: a one-line CSS change flags @kaizen/components alone, exit 1; with a changeset present it reports ~, exit 0.
  • An unpublished version reports skipped rather than drift.
  • eslint, prettier, stylelint and lint:ts pass locally.

Requested by: @ckychris

pip-the-concierge Bot and others added 2 commits August 10, 2026 05:22
…tions

- Add new check-changeset workflow that runs on PRs to detect when package
  source files change without an accompanying changeset. Non-package changes
  (like renovate config, docs, CI files) no longer require empty changesets.

- Split the changeset.yaml notify-slack job into two targeted notifications:
  - notify-slack-success: fires only when packages are actually published
  - notify-slack-failure: fires only when the version job fails (real publish
    failure), not when there are simply no changesets to publish

- Add check:changeset script to package.json for local changeset status checks

- Add .devbox/ to prettierignore and eslint ignores to prevent environment
  artifacts from failing lint checks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Chris Chan <chris.chan@cultureamp.com>
…-managed]

Replace the path-based check-changeset.yml (which missed cross-package
propagation like design-token changes affecting components' built CSS)
with a tarball-fingerprint check that compares pnpm-packed output against
the published npm registry version.

Changes:
- Add scripts/check-package-output.ts: per-package sha256 manifest
  fingerprinting against the published tarball on npm
- Add .github/workflows/check-package-output.yml: advisory PR check
  (not a merge gate) that reports drift without a changeset
- Delete .github/workflows/check-changeset.yml: superseded by the
  tarball check which catches all cases including cross-package deps
- Fix notify-slack-failure: add always() so the job actually runs
  when the version job fails (GitHub Actions skips dependents by default)
- Improve failure Slack notification: use Block Kit with commit SHA,
  actor, subject line, and a direct link to the failed run

No hard changeset gate remains — by design. A package change without a
changeset will merge and simply not publish.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Chris Chan <chris.chan@cultureamp.com>
@pip-the-concierge

pip-the-concierge Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

🛎️ Concierge

  • PR Review — AI-powered code review — ✅ Complete

    Run #10016 — ✅ 10m 30s
    Metric Value
    Duration 10m 30s
    Model Opus
    Turns 32
    Tokens 126,332

@changeset-bot

changeset-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9466747

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Comment thread .github/workflows/check-package-output.yml Outdated
Comment thread scripts/check-package-output.ts Outdated

@pip-the-concierge-via-chinmina pip-the-concierge-via-chinmina Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Overview

This PR replaces a path-based changeset check with an advisory tarball-fingerprint check that actually builds packages and compares their output to what's published on npm — a significant improvement in accuracy. It also fixes the notify-slack-failure job to actually fire on failure and upgrades the Slack payload to Block Kit. The architectural approach is sound and well-structured.

Issues

Two confirmed issues: (1) the curl command interpolates an unsanitized npm registry URL into a shell string, which is vulnerable to $(...) command injection; (2) the Slack Block Kit payload interpolates the commit subject directly into JSON without escaping, which will produce malformed JSON for commits containing quotes or backslashes.

For reviewers

Change groups

  • Advisory tarball drift check (new workflow + script): .github/workflows/check-package-output.yml, scripts/check-package-output.ts, package.json
  • Slack failure notification fix: .github/workflows/changeset.yaml (lines 54-116)

Reading order

  1. .github/workflows/check-package-output.yml — 26-line workflow; shows the trigger, build prerequisite, and script invocation
  2. scripts/check-package-output.ts — core logic: pack local tarball, download published tarball, fingerprint both, cross-reference changeset status, report drift
  3. .github/workflows/changeset.yaml — independent change: always() condition on notify-slack-failure job and new Block Kit payload

Key questions

  • The script shells out to curl with an unescaped tarballUrl from npm view (line 198) — is there any concern about URL injection from a compromised registry response?
  • Exit code 1 (drift detected) will surface as a red check on PRs even though it is advisory — is that the intended signal, or should it use continue-on-error / neutral conclusion to avoid confusion with true failures?

7 Low-signal findings hidden

click to expand
  • scripts/check-package-output.ts: Claimed path.join bug with absolute pnpm output — rejected (pnpm outputs filename only, not absolute path)
  • scripts/check-package-output.ts: Unhandled execSync for tar extraction — rejected (tied to false path.join premise; surrounding try/catch catches thrown errors)
  • .github/workflows/check-package-output.yml: Advisory vs blocking mismatch — rejected (non-required checks that exit 1 are standard advisory pattern in GitHub)
  • .github/workflows/changeset.yaml: ${{ }} wrapper on job if: claimed invalid — rejected (this is valid GitHub Actions syntax)
  • .github/workflows/check-package-output.yml: AI Testing Harness requirement — rejected (PR is currently going through that process)
  • .github/workflows/check-package-output.yml: Missing permissions key — rejected (consistent with all other CI workflows in this repo)
  • .github/workflows/check-package-output.yml: GitHub Actions contain on tech radar — rejected (repo already has 14 GH Actions workflows; this replaces an existing one)

generated using the pr-review workflow in 32 turns
give feedback with reactions 👍 👎

Comment thread scripts/check-package-output.ts Outdated
Comment thread .github/workflows/changeset.yaml
ckychris and others added 3 commits August 10, 2026 16:50
- Kept the changeset cross-reference so PRs that already have one stay green

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
- Trigger inverted to push/branches-ignore so the guard works without a PR context

Co-Authored-By: Claude <noreply@anthropic.com>
@ckychris
ckychris changed the base branch from agent/changeset-check-gate to main August 10, 2026 07:03
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

✨ Here is your branch preview! ✨

Last updated for commit 9466747: chore: drop check:changeset script

ckychris and others added 2 commits August 10, 2026 17:13
- npm view inherits pnpm's env config and buries the result in warnings
- A 404 is now distinguishable from a real registry failure

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent:background-agent Created by agent-workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant