Skip to content

chore(ci): stop racing publish-shims against release-binaries retries#450

Merged
rhuanbarreto merged 11 commits into
mainfrom
fix/publish-shims-race
Jul 3, 2026
Merged

chore(ci): stop racing publish-shims against release-binaries retries#450
rhuanbarreto merged 11 commits into
mainfrom
fix/publish-shims-race

Conversation

@rhuanbarreto

@rhuanbarreto rhuanbarreto commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • publish-shims.yml no longer triggers on release: published in parallel with release-binaries.yml — it's dispatched via gh workflow run from release-binaries.yml's trigger-shim-publish job once binaries + provenance are confirmed uploaded. Fixes a race where a needed retry on the binary build would leave the shim-publish job to time out and go cancelled (terminal), silently skipping PyPI/NuGet/Maven/Go-tag/RubyGem publishing.
  • publish-go-tag now has workflows: write — its tag push was being rejected by GitHub ("refusing to allow a GitHub App to create or update workflow ... without workflows permission"), confirmed on v0.45.7's failed run.
  • The CLI's background "update available" notice was printed to stdout unconditionally after every command, with no gating. This corrupted JSON.parse(stdout) for any script/agent piping output whenever a newer release existed — confirmed as the actual cause of v0.46.0's Windows test failures during this investigation (not flakiness). shouldPerformUpdateCheck() now gates the check to interactive TTY, non-CI, non-upgrade sessions only.
  • Added zizmor (GitHub Actions static analysis) as a PR check, uploading findings to the Security tab (GitHub Advanced Security, non-blocking for now — see commit message for why) rather than failing the build.
  • Addressed CodeRabbit's review: moved shell-interpolated values to env: blocks (template-injection), persist-credentials: false on checkouts that don't push, Boolean(Bun.env.CI) per ARCH-014, hoisted a test import, documented the upgrade exception.
  • Documented all of the above in CLAUDE.md and agent memory.

Context

Found while investigating why v0.46.0/v0.46.1 shim and binary publishing kept failing despite repeated manual retries. v0.46.1 is already fully published on all channels; v0.46.0 is superseded and was left as-is.

Test plan

  • bun run validate (lint, typecheck, format, full test suite, ADR check, knip, build check) — all green, after every commit
  • archgate check — 39/39 ADR checks pass
  • archgate:reviewer skill — CI, Distribution, General/Process, Architecture, Legal domains all PASS
  • New unit tests for shouldPerformUpdateCheck() covering TTY/CI/upgrade-command gating
  • uvx zizmor run locally against every touched workflow file to confirm fixes and scope the remaining pre-existing backlog

https://claude.ai/code/session_01SGjSjrywTnZDcUqgHWGrTj

…ng on release event

publish-shims.yml and release-binaries.yml both triggered on `release:
published`, racing each other: if the binary build needed a retry,
publish-shims.yml's fixed-budget wait-for-binaries poll timed out and
went `cancelled` (terminal) before the retry finished, silently
skipping shim publishing for that release.

publish-shims.yml is now workflow_dispatch-only; release-binaries.yml
dispatches it via `gh workflow run` once binaries + provenance succeed.

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
…ions

main() unconditionally printed an "update available" notice to stdout
after every command, with no gating. Any script, `| jq`, or agent
parsing stdout as JSON would have it corrupted whenever a newer
release happened to be available.

Add shouldPerformUpdateCheck() and use it to skip the check entirely
outside a genuine interactive terminal (piped output, CI, or the
upgrade command itself) — same guard shape as the existing
showFirstRunNoticeIfNeeded().

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
…ess feedback

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 3, 2026

Copy link
Copy Markdown

Deploying archgate-cli with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1c0120d
Status: ✅  Deploy successful!
Preview URL: https://392c8b45.archgate-cli.pages.dev
Branch Preview URL: https://fix-publish-shims-race.archgate-cli.pages.dev

View logs

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR changes the release publishing pipeline to trigger the shim-publishing workflow via explicit workflow_dispatch from the binaries workflow rather than parallel release.published events, updates downstream publish jobs to consistently use a dispatched tag input, and shortens the asset-presence polling check. Separately, the CLI's background update-check is gated by a new shouldPerformUpdateCheck helper that suppresses the notice unless run in a genuine interactive TTY outside CI and outside the upgrade command, with accompanying unit tests. New agent-memory documentation files and a CLAUDE.md section record these fixes and a concise-comments policy.

Related PRs

#450: This PR itself.

Suggested labels: ci, documentation, bug

Suggested reviewers: archgate-developer

Compact metadata

Poem
A rabbit dispatched a workflow with care,
No more racing triggers loose in the air,
It gated the update notice, quiet and TTY-wise,
Wrote down the gotchas so no one relies
On memory alone — just hop, build, and share.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly reflects the main CI release-pipeline change and is relevant to the PR.
Description check ✅ Passed The description matches the implemented workflow and CLI gating changes and is on-topic.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Code Coverage

Metric Value
Lines 90.0% (7196 / 7992)
Threshold 90% minimum — met
Platforms Linux + Windows

Full HTML report available in workflow artifacts.

Per-directory breakdown
Directory Coverage Lines
src/commands/ 88.7% 1994 / 2249
src/engine/ 90.9% 1463 / 1610
src/formats/ 100.0% 142 / 142
src/helpers/ 90.1% 3597 / 3991

…t rejected

git push origin "shims/go/\$TAG" was failing with "refusing to allow a
GitHub App to create or update workflow .github/workflows/release.yml
without workflows permission" — GitHub rejects any ref push reachable
through commits touching .github/workflows/*, even for an unrelated
tag, unless the token has workflows: write. Confirmed on v0.45.7's
publish-go-tag job log.

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
Signed-off-by: Rhuan Barreto <rhuan@barreto.work>

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

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/agent-memory/archgate-developer/MEMORY.md:
- Around line 74-76: The bullets in MEMORY.md are too verbose and read like
postmortems instead of one-line pointers. Trim each item under the release notes
section to a short pointer that names the issue only, and move the explanatory
detail into project_release_pipeline_gotchas.md and CLAUDE.md; keep the wording
concise while preserving references to the existing gotcha topics such as gh
workflow run, moonrepo/setup-toolchain, and shouldPerformUpdateCheck().

In @.github/workflows/publish-shims.yml:
- Around line 60-62: The checkout steps in the non-pushing publish jobs still
persist Git credentials, which unnecessarily leaves the token available during
build and publish steps. Update the actions/checkout usage in publish-pypi,
publish-nuget, publish-maven, and publish-rubygem to set persist-credentials to
false, and leave publish-go-tag unchanged since it needs the default behavior
for pushing tags. Use the checkout step invocations in publish-shims.yml to
apply the change consistently across those jobs.
- Around line 26-32: The TAG value is being interpolated directly inside shell
run blocks in the workflow, which triggers template-injection warnings. Update
the sanity-check and Go-tag steps to pass inputs.tag through env: as TAG, then
reference the environment variable inside the scripts instead of assigning it in
run:. Use the existing step blocks around the release asset verification and Go
tag generation to locate and adjust both occurrences.

In @.github/workflows/release-binaries.yml:
- Around line 184-190: The Dispatch publish-shims.yml step is interpolating
github.event.release.tag_name || inputs.tag directly into the shell script,
which should be avoided. Move the tag value into the step’s env block in
release-binaries.yml and reference it via $TAG inside the run script, keeping
the gh workflow run command unchanged otherwise. Use the existing Dispatch
publish-shims.yml step as the target for this update.

In `@CLAUDE.md`:
- Line 56: Update the note about `checkForUpdatesIfNeeded()` and
`shouldPerformUpdateCheck()` so it also mentions that the update-check notice is
skipped for `upgrade`, not just TTY/non-CI sessions. Keep the wording aligned
with the actual guard in `src/helpers/update-check.ts`, and make the memory note
consistent by explicitly including the `upgrade` exception.

In `@src/cli.ts`:
- Around line 158-164: The update-check gating in shouldPerformUpdateCheck is
using Bun.env.CI as a raw value even though it is only meant as a truthy flag.
Update the ci argument in src/cli.ts to use Boolean(Bun.env.CI) so the intent is
explicit and the typing stays boolean; keep the surrounding updateCheckPromise
logic unchanged.

In `@tests/helpers/update-check.test.ts`:
- Around line 8-57: The tests for shouldPerformUpdateCheck repeat the same
dynamic import in every case, which is unnecessary here. Hoist the import of
shouldPerformUpdateCheck from src/helpers/update-check to the top of
tests/helpers/update-check.test.ts and reuse it across all tests, since the
function is pure and does not require per-test module reloading.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1c79c0ea-9490-4ce4-bf0e-daf4499b3fa1

📥 Commits

Reviewing files that changed from the base of the PR and between fc209b3 and 49335cd.

📒 Files selected for processing (9)
  • .claude/agent-memory/archgate-developer/MEMORY.md
  • .claude/agent-memory/archgate-developer/feedback_concise_comments.md
  • .claude/agent-memory/archgate-developer/project_release_pipeline_gotchas.md
  • .github/workflows/publish-shims.yml
  • .github/workflows/release-binaries.yml
  • CLAUDE.md
  • src/cli.ts
  • src/helpers/update-check.ts
  • tests/helpers/update-check.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Cloudflare Pages
⚠️ CI failures not shown inline (12)

GitHub Actions: DCO / 0_DCO Sign-off Check.txt: fix(ci): stop racing publish-shims against release-binaries retries

Conclusion: failure

View job details

##[group]Run base="fc209b3cc8dca78685ee60b4794698d17e368ebf"
 �[36;1mbase="fc209b3cc8dca78685ee60b4794698d17e368ebf"�[0m
 �[36;1mhead="49335cd725ed866ea2c0f0d24e68d7a4c948cd4d"�[0m
 �[36;1mfailed=0�[0m
 �[36;1m�[0m
 �[36;1mfor sha in $(git rev-list --no-merges "$base".."$head"); do�[0m
 �[36;1m  if ! git log -1 --format='%B' "$sha" | grep -qiE '^Signed-off-by: .+ <.+>'; then�[0m
 �[36;1m    echo "::error::Commit $sha is missing a DCO Signed-off-by line."�[0m

GitHub Actions: DCO / DCO Sign-off Check: fix(ci): stop racing publish-shims against release-binaries retries

Conclusion: failure

View job details

##[group]Run base="fc209b3cc8dca78685ee60b4794698d17e368ebf"
 �[36;1mbase="fc209b3cc8dca78685ee60b4794698d17e368ebf"�[0m
 �[36;1mhead="49335cd725ed866ea2c0f0d24e68d7a4c948cd4d"�[0m
 �[36;1mfailed=0�[0m
 �[36;1m�[0m
 �[36;1mfor sha in $(git rev-list --no-merges "$base".."$head"); do�[0m
 �[36;1m  if ! git log -1 --format='%B' "$sha" | grep -qiE '^Signed-off-by: .+ <.+>'; then�[0m
 �[36;1m    echo "::error::Commit $sha is missing a DCO Signed-off-by line."�[0m

GitHub Actions: Code Quality: PR #450 / 3_Analyze (go).txt: Code Quality: PR #450

Conclusion: failure

View job details

racting types for package crypto/aes.
 [] [build-stderr] 2026/07/03 13:33:18 Done extracting types for package crypto/aes.
 [] [build-stderr] 2026/07/03 13:33:18 Processing package crypto/des.
 [] [build-stderr] 2026/07/03 13:33:18 Extracting types for package crypto/des.
 [] [build-stderr] 2026/07/03 13:33:18 Done extracting types for package crypto/des.
 [] [build-stderr] 2026/07/03 13:33:18 Processing package crypto/internal/fips140/nistec/fiat.
 [] [build-stderr] 2026/07/03 13:33:18 Extracting types for package crypto/internal/fips140/nistec/fiat.
 [] [build-stderr] 2026/07/03 13:33:18 Done extracting types for package crypto/internal/fips140/nistec/fiat.
 [] [build-stderr] 2026/07/03 13:33:18 Processing package crypto/internal/fips140/nistec.
 [] [build-stderr] 2026/07/03 13:33:18 Extracting types for package crypto/internal/fips140/nistec.
 [] [build-stderr] 2026/07/03 13:33:18 Done extracting types for package crypto/internal/fips140/nistec.
 [] [build-stderr] 2026/07/03 13:33:18 Processing package crypto/internal/fips140/ecdh.
 [] [build-stderr] 2026/07/03 13:33:18 Extracting types for package crypto/internal/fips140/ecdh.
 [] [build-stderr] 2026/07/03 13:33:18 Done extracting types for package crypto/internal/fips140/ecdh.
 [] [build-stderr] 2026/07/03 13:33:18 Processing package crypto/internal/fips140/edwards25519/field.
 [] [build-stderr] 2026/07/03 13:33:18 Extracting types for package crypto/internal/fips140/edwards25519/field.
 [] [build-stderr] 2026/07/03 13:33:18 Done extracting types for package crypto/internal/fips140/edwards25519/field.
 [] [build-stderr] 2026/07/03 13:33:18 Processing package crypto/ecdh.
 [] [build-stderr] 2026/07/03 13:33:18 Extracting types for package crypto/ecdh.
 [] [build-stderr] 2026/07/03 13:33:18 Done extracting types for package crypto/ecdh.
 [] [build-stderr] 2026/07/03 13:33:18 Processing package crypto/elliptic.
 [] [build-stderr] 2026/07/03 13:33:18 Extracting types for package crypto/elliptic.
 [] [build-stder...

GitHub Actions: Code Quality: PR #450 / Analyze (go): Code Quality: PR #450

Conclusion: failure

View job details

,"bundleSupportsIncludeLogs":true,"bundleSupportsOverlay":true,"databaseInterpretResultsSupportsSarifRunProperty":true,"featuresInVersionResult":true,"indirectTracingSupportsStaticBinaries":false,"informsAboutUnsupportedPathFilters":true,"supportsPython312":true,"mrvaPackCreate":true,"threatModelOption":true,"traceCommandUseBuildMode":true,"v2ramSizing":true,"mrvaPackCreateMultipleQueries":true,"setsCodeqlRunnerEnvVar":true,"sarifMergeRunsFromEqualCategory":true,"forceOverwrite":true,"generateSummarySymbolMap":true,"pythonDefaultIsToNotExtractStdlib":true,"queryServerRunQueries":true,"queryServerTrimCacheWithMode":true,"builtinExtractorsSpecifyDefaultQueries":true,"bqrsDiffResultSets":true,"bundleSupportsIncludeOption":true,"suppressesMissingFileBaselineWarning":true}}}
   CODEQL_ACTION_GO_BINARY: /home/runner/work/_temp/codeql-action-go-tracing/bin/go
   CODEQL_RAM: 14575
   CODEQL_THREADS: 4
   CODEQL_PROXY_HOST:
   CODEQL_PROXY_PORT:
   CODEQL_PROXY_CA_CERTIFICATE:
   CODEQL_PROXY_URLS:
 ##[endgroup]
 ##[group]Attempting to automatically build go code
 [command]/opt/hostedtoolcache/CodeQL/2.25.6/x64/codeql/codeql database trace-command --use-build-mode --working-dir /home/runner/work/cli/cli /home/runner/work/_temp/codeql_databases/go
 Picked up JAVA_TOOL_OPTIONS:  -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false
 Running command in /home/runner/work/cli/cli: [/opt/hostedtoolcache/CodeQL/2.25.6/x64/codeql/go/tools/autobuild.sh]
 [] [build-stderr] 2026/07/03 13:33:10 Autobuilder was built with go1.26.0, environment has go1.24.13
 [] [build-stderr] 2026/07/03 13:33:10 LGTM_SRC is /home/runner/work/cli/cli
 [] [build-stderr] 2026/07/03 13:33:10 Found no go.work files in the workspace; looking for go.mod files...
 [] [build-stderr] 2026/07/03 13:33:10 Found 1 go.mod files in: shims/go/go.mod.
 [] [build-stderr] 2026/07/03 13:33:10 Found 1 go.mod file(s).
 [] [build-stderr] 2026/07/03 13:33:10 Import path is 'github.com/archgate/cli'
 [] [build-stderr] 2026/07/...

GitHub Actions: Validate / 0_Validate Code.txt: fix(ci): stop racing publish-shims against release-binaries retries

Conclusion: failure

View job details

##[group]Run # shim-tests is skipped when no shim files changed — treat skipped as success.
 �[36;1m# shim-tests is skipped when no shim files changed — treat skipped as success.�[0m
 �[36;1mSHIM_OK="success"�[0m
 �[36;1mif [[ "$SHIM_OK" == "skipped" ]]; then SHIM_OK="success"; fi�[0m
 �[36;1m�[0m
 �[36;1mif [[ "success" != "success" ]] || \�[0m
 �[36;1m   [[ "$SHIM_OK" != "success" ]] || \�[0m
 �[36;1m   [[ "success" != "success" ]] || \�[0m
 �[36;1m   [[ "success" != "success" ]] || \�[0m
 �[36;1m   [[ "success" != "success" ]]; then�[0m
 �[36;1m  echo "::error::One or more jobs failed:"�[0m

GitHub Actions: Validate / Validate Code: fix(ci): stop racing publish-shims against release-binaries retries

Conclusion: failure

View job details

##[group]Run # shim-tests is skipped when no shim files changed — treat skipped as success.
 �[36;1m# shim-tests is skipped when no shim files changed — treat skipped as success.�[0m
 �[36;1mSHIM_OK="success"�[0m
 �[36;1mif [[ "$SHIM_OK" == "skipped" ]]; then SHIM_OK="success"; fi�[0m
 �[36;1m�[0m
 �[36;1mif [[ "success" != "success" ]] || \�[0m
 �[36;1m   [[ "$SHIM_OK" != "success" ]] || \�[0m
 �[36;1m   [[ "success" != "success" ]] || \�[0m
 �[36;1m   [[ "success" != "success" ]] || \�[0m
 �[36;1m   [[ "success" != "success" ]]; then�[0m
 �[36;1m  echo "::error::One or more jobs failed:"�[0m

GitHub Actions: Validate / Smoke Test (Linux) _ Linux: fix(ci): stop racing publish-shims against release-binaries retries

Conclusion: failure

View job details

##[group]Run if [ -z "$ARCHGATE_VERSION" ]; then
 �[36;1mif [ -z "$ARCHGATE_VERSION" ]; then�[0m
 �[36;1m  # Find the newest release that already has the Linux asset uploaded.�[0m
 �[36;1m  # On release-commit pushes the Validate and Release workflows start�[0m
 �[36;1m  # concurrently, so the latest tag may exist before its binaries are�[0m
 �[36;1m  # uploaded by release-binaries.yml — hitting a 404.�[0m
 �[36;1m  asset="archgate-linux-x64.tar.gz"�[0m
 �[36;1m  tags="$(gh release list --limit 5 --json tagName --jq '.[].tagName' 2>/dev/null || true)"�[0m
 �[36;1m  if [ -z "$tags" ]; then�[0m
 �[36;1m    echo "::warning::No releases found, skipping install.sh smoke test"�[0m
 �[36;1m    exit 0�[0m
 �[36;1m  fi�[0m
 �[36;1m  found=""�[0m
 �[36;1m  for tag in $tags; do�[0m
 �[36;1m    assets="$(gh release view "$tag" --json assets --jq '.assets[].name' 2>/dev/null || true)"�[0m
 �[36;1m    if echo "$assets" | grep -qF "$asset"; then�[0m
 �[36;1m      ARCHGATE_VERSION="$tag"�[0m
 �[36;1m      found=1�[0m
 �[36;1m      break�[0m
 �[36;1m    fi�[0m
 �[36;1m  done�[0m
 �[36;1m  if [ -z "$found" ]; then�[0m
 �[36;1m    echo "::warning::No release with $asset found, skipping install.sh smoke test"�[0m
 �[36;1m    exit 0�[0m
 �[36;1m  fi�[0m
 �[36;1m  export ARCHGATE_VERSION�[0m
 �[36;1mfi�[0m
 �[36;1mecho "Testing install.sh with version $ARCHGATE_VERSION"�[0m
 �[36;1m�[0m
 �[36;1mexport ARCHGATE_INSTALL_DIR="$(mktemp -d)"�[0m
 �[36;1m�[0m
 �[36;1msh install.sh�[0m
 �[36;1m�[0m
 �[36;1mif [ ! -f "$ARCHGATE_INSTALL_DIR/archgate" ]; then�[0m
 �[36;1m  echo "::error::archgate binary not found at $ARCHGATE_INSTALL_DIR/archgate after install"�[0m

GitHub Actions: Validate / 11_Lint, Test & Check.txt: fix(ci): stop racing publish-shims against release-binaries retries

Conclusion: failure

View job details

##[group]Run bun run docs/scripts/generate-llms-full.ts
 �[36;1mbun run docs/scripts/generate-llms-full.ts�[0m
 �[36;1mgit diff --exit-code docs/public/llms-full.txt || {�[0m
 �[36;1m  echo "::error::docs/public/llms-full.txt is out of date. Run 'bun run docs/scripts/generate-llms-full.ts' and commit the result."�[0m

GitHub Actions: Validate / 1_Coverage Report.txt: fix(ci): stop racing publish-shims against release-binaries retries

Conclusion: failure

View job details

##[group]Run COVERAGE="90.0"
 �[36;1mCOVERAGE="90.0"�[0m
 �[36;1mMIN_COVERAGE=90�[0m
 �[36;1mBELOW=$(awk "BEGIN{print ($COVERAGE < $MIN_COVERAGE) ? 1 : 0}")�[0m
 �[36;1mif [ "$BELOW" = "1" ]; then�[0m
 �[36;1m  echo "::error::Code coverage is ${COVERAGE}%, which is below the minimum threshold of ${MIN_COVERAGE}%."�[0m

GitHub Actions: Validate / Lint, Test & Check: fix(ci): stop racing publish-shims against release-binaries retries

Conclusion: failure

View job details

##[group]Run bun run docs/scripts/generate-llms-full.ts
 �[36;1mbun run docs/scripts/generate-llms-full.ts�[0m
 �[36;1mgit diff --exit-code docs/public/llms-full.txt || {�[0m
 �[36;1m  echo "::error::docs/public/llms-full.txt is out of date. Run 'bun run docs/scripts/generate-llms-full.ts' and commit the result."�[0m

GitHub Actions: Validate / 8_Smoke Test (Linux) _ Linux.txt: fix(ci): stop racing publish-shims against release-binaries retries

Conclusion: failure

View job details

##[group]Run if [ -z "$ARCHGATE_VERSION" ]; then
 �[36;1mif [ -z "$ARCHGATE_VERSION" ]; then�[0m
 �[36;1m  # Find the newest release that already has the Linux asset uploaded.�[0m
 �[36;1m  # On release-commit pushes the Validate and Release workflows start�[0m
 �[36;1m  # concurrently, so the latest tag may exist before its binaries are�[0m
 �[36;1m  # uploaded by release-binaries.yml — hitting a 404.�[0m
 �[36;1m  asset="archgate-linux-x64.tar.gz"�[0m
 �[36;1m  tags="$(gh release list --limit 5 --json tagName --jq '.[].tagName' 2>/dev/null || true)"�[0m
 �[36;1m  if [ -z "$tags" ]; then�[0m
 �[36;1m    echo "::warning::No releases found, skipping install.sh smoke test"�[0m
 �[36;1m    exit 0�[0m
 �[36;1m  fi�[0m
 �[36;1m  found=""�[0m
 �[36;1m  for tag in $tags; do�[0m
 �[36;1m    assets="$(gh release view "$tag" --json assets --jq '.assets[].name' 2>/dev/null || true)"�[0m
 �[36;1m    if echo "$assets" | grep -qF "$asset"; then�[0m
 �[36;1m      ARCHGATE_VERSION="$tag"�[0m
 �[36;1m      found=1�[0m
 �[36;1m      break�[0m
 �[36;1m    fi�[0m
 �[36;1m  done�[0m
 �[36;1m  if [ -z "$found" ]; then�[0m
 �[36;1m    echo "::warning::No release with $asset found, skipping install.sh smoke test"�[0m
 �[36;1m    exit 0�[0m
 �[36;1m  fi�[0m
 �[36;1m  export ARCHGATE_VERSION�[0m
 �[36;1mfi�[0m
 �[36;1mecho "Testing install.sh with version $ARCHGATE_VERSION"�[0m
 �[36;1m�[0m
 �[36;1mexport ARCHGATE_INSTALL_DIR="$(mktemp -d)"�[0m
 �[36;1m�[0m
 �[36;1msh install.sh�[0m
 �[36;1m�[0m
 �[36;1mif [ ! -f "$ARCHGATE_INSTALL_DIR/archgate" ]; then�[0m
 �[36;1m  echo "::error::archgate binary not found at $ARCHGATE_INSTALL_DIR/archgate after install"�[0m

GitHub Actions: Validate / Coverage Report: fix(ci): stop racing publish-shims against release-binaries retries

Conclusion: failure

View job details

##[group]Run COVERAGE="90.0"
 �[36;1mCOVERAGE="90.0"�[0m
 �[36;1mMIN_COVERAGE=90�[0m
 �[36;1mBELOW=$(awk "BEGIN{print ($COVERAGE < $MIN_COVERAGE) ? 1 : 0}")�[0m
 �[36;1mif [ "$BELOW" = "1" ]; then�[0m
 �[36;1m  echo "::error::Code coverage is ${COVERAGE}%, which is below the minimum threshold of ${MIN_COVERAGE}%."�[0m
🧰 Additional context used
📓 Path-based instructions (12)
**

⚙️ CodeRabbit configuration file

**: # CLAUDE.md

Archgate is a CLI tool for AI governance via Architecture Decision Records (ADRs) — combining human-readable docs with machine-checkable rules. The CLI dogfoods itself via ADRs in .archgate/adrs/. AI features are delivered as a Claude Code plugin (../plugins/claude-code), not via direct API calls.

Technology Stack

  • Runtime: Bun (>=1.2.21) — not Node.js compatible
  • Language: TypeScript (strict mode, ESNext, ES modules)
  • CLI framework: Commander.js (@commander-js/extra-typings)
  • Linter: Oxlint | Formatter: Oxfmt | Dead exports: Knip | Commits: Conventional Commits

Commands

bun run src/cli.ts <command>  # run CLI locally
bun run lint                  # oxlint
bun run typecheck             # tsc --build
bun run format                # oxfmt --write
bun run format:check          # oxfmt --check
bun run test                  # all tests (not bare `bun test` — picks up --timeout; see GEN-003)
bun run knip                  # dead export detection
bun run validate              # MANDATORY: lint + typecheck + format + test + ADR check + knip + build check
bun run build:check            # verify build compiles (CI builds binaries via release workflow)
bun run commit                # conventional commit wizard

Validation Gate

bun run validate must pass before any task is considered complete. Fail-fast pipeline: lint → typecheck → format → test → ADR check → knip → build check. Mirrors CI in .github/workflows/code-pull-request.yml.

Git Hooks (Git 2.54+)

Config-based hooks in .githooks run validation locally before commits and pushes:

  • pre-commit: lint + typecheck + format:check (~15s)
  • pre-push: full bun run validate (~60s, mirrors CI)

Activate once per clone:

git config --local include.path ../.githooks

Opt out of a specific hook: git config --local hook.<name>.enabled false. Skip all hooks for a single commit: git commit --no-verify.

GitHub Act...

Files:

  • CLAUDE.md
  • src/helpers/update-check.ts
  • tests/helpers/update-check.test.ts
  • src/cli.ts

⚙️ CodeRabbit configuration file

**: This project uses Archgate — an AI governance framework based on
Architecture Decision Records (ADRs). The ADRs in .archgate/adrs/
are the authoritative rules for this codebase. Each ADR has a companion
.rules.ts file with automated checks that run via archgate check.

When reviewing, you must:

  1. Treat ADR violations as blocking issues, not suggestions.
  2. Cite the specific ADR ID when flagging a violation (e.g., "Violates ARCH-006").
  3. Focus on semantic and contextual violations that automated rules cannot catch —
    the .rules.ts files already cover syntactic/structural patterns.
  4. If you are unsure whether something violates an ADR, flag it as a question
    rather than approving it.

Files:

  • CLAUDE.md
  • src/helpers/update-check.ts
  • tests/helpers/update-check.test.ts
  • src/cli.ts
src/**/*.ts

📄 CodeRabbit inference engine (.archgate/adrs/ARCH-002-error-handling.md)

src/**/*.ts: Use logError() from src/helpers/log.ts for user-facing errors instead of printing errors directly.
Exit with code 1 for expected failures such as missing config, invalid input, or validation violations.
Let unexpected errors crash naturally so they are treated as internal errors with exit code 2.
Include actionable suggestions in user-facing error messages whenever possible.
Write user-facing errors to stderr via logError(); do not send them to stdout.
When findProjectRoot() returns null for commands that do not require .archgate/, fall back to process.cwd() as the path key or working directory.
Catch ExitPromptError from Inquirer in the top-level error boundary and treat it as user cancellation: exit with code 130 without logging an error or sending it to Sentry.
Do not use console.error() directly; use logError() for consistent formatting.
Do not exit with codes other than 0, 1, 2, or 130.
Do not send user-cancellation errors such as Inquirer ExitPromptError to Sentry; filter them in beforeSend.

src/**/*.ts: Use styleText(format, text) from node:util for all terminal colors and formatting in CLI source files; do not use raw ANSI escape codes or third-party color libraries.
Commands that produce structured results and support --json must emit machine-readable JSON to stdout with no colors or decorative formatting.
When a command supports --json, use formatJSON() from src/helpers/output.ts for JSON serialization, and pass forcePretty: true when the user explicitly provided --json.
Use isAgentContext() from src/helpers/output.ts to enable auto-JSON behavior for commands that support both human-readable and JSON output modes.
CLI output must not include emoji; use text symbols and colors instead.
Send normal command output to stdout with console.log(), and send errors, warnings, and debug messages to stderr via logError(), logWarn(), and logDebug().
Keep CLI output concise and scannabl...

Files:

  • src/helpers/update-check.ts
  • src/cli.ts
src/{helpers,engine}/**/*.ts

📄 CodeRabbit inference engine (.archgate/adrs/ARCH-002-error-handling.md)

Do not use console.log(), console.warn(), or console.info() directly in helper or engine files; use logInfo() or logWarn() instead. Command files are exempt because they are the I/O layer.

Files:

  • src/helpers/update-check.ts
**/*.{ts,tsx,js,jsx,mjs,cjs}

📄 CodeRabbit inference engine (.archgate/adrs/ARCH-006-dependency-policy.md)

**/*.{ts,tsx,js,jsx,mjs,cjs}: Use Bun built-ins for file I/O (Bun.file, Bun.write), HTTP, subprocess execution (Bun.spawn), globbing (Bun.Glob), and testing (bun:test).
Do not use Node.js-specific APIs when Bun alternatives exist; for example, use Bun.file() instead of fs.readFile() for simple reads.
Prefer node: built-in modules such as node:util, node:path, and node:fs over npm alternatives.
Do not use utility libraries for single functions, such as importing lodash for one helper like pick.
Do not use path aliases (tsconfig paths); use relative imports with Bun's native module resolution.
Do not install packages globally during development; use bunx for one-off tools.

Files:

  • src/helpers/update-check.ts
  • tests/helpers/update-check.test.ts
  • src/cli.ts
src/**/!(*platform).ts

📄 CodeRabbit inference engine (.archgate/adrs/ARCH-009-platform-detection-helper.md)

src/**/!(*platform).ts: In src/ TypeScript source files, do not read process.platform directly; use src/helpers/platform.ts (isWindows(), isMacOS(), isLinux(), isWSL(), getPlatformInfo()) for all platform detection.
Use the centralized platform helper instead of duplicating OS/WSL detection logic inline anywhere in src/ TypeScript source.
When behavior differs between Linux and Windows, account for WSL by using isWSL() rather than assuming `

Files:

  • src/helpers/update-check.ts
  • src/cli.ts
{src,tests}/**/*.ts

📄 CodeRabbit inference engine (.archgate/adrs/LEGAL-001-spdx-license-headers.md)

{src,tests}/**/*.ts: Every TypeScript source file in src/ and tests/ must begin with // SPDX-License-Identifier: Apache-2.0 followed by // Copyright 2026 Archgate.
If a TypeScript file has a shebang line (for example #!/usr/bin/env bun in src/cli.ts), the SPDX license header must appear immediately after the shebang.
Use single-line // comments for the SPDX header; do not use block comments (/* */) or alternate license identifiers.

Files:

  • src/helpers/update-check.ts
  • tests/helpers/update-check.test.ts
  • src/cli.ts
src/helpers/update-check.ts

📄 CodeRabbit inference engine (CLAUDE.md)

shouldPerformUpdateCheck() must gate the background update notice so it only runs in TTY-only, non-CI sessions and does not corrupt piped or agent JSON output.

Files:

  • src/helpers/update-check.ts
.github/workflows/*.yml

📄 CodeRabbit inference engine (.archgate/adrs/CI-001-pin-github-actions-by-hash.md)

.github/workflows/*.yml: In GitHub Actions workflow files under .github/workflows/*.yml, every third-party uses: reference must be pinned to a full 40-character commit SHA and include a human-readable version comment on the same line (for example, uses: owner/action@<40-char-sha> # v4).
In GitHub Actions workflow files under .github/workflows/*.yml, do not reference third-party actions or reusable workflows by tag, branch, or abbreviated SHA; only a full 40-character commit SHA is allowed for third-party uses: entries.
In GitHub Actions workflow files under .github/workflows/*.yml, local workflow references (uses: ./.github/workflows/...) and local composite action references (uses: ./.github/actions/...) are exempt from SHA pinning because they stay within the same repository trust boundary.
In GitHub Actions workflow files under .github/workflows/*.yml, the slsa-framework/slsa-github-generator/.github/workflows/* reusable workflow is exempt from SHA pinning and must be referenced by tag (for example, @v2.1.0).

In GitHub Actions workflow steps that read repo-level config, verify whether the value lives in secrets or vars before using it, and when a continue-on-error: true step can skip internally, use ::warning:: or higher rather than ::notice:: so misconfigurations are visible.

Files:

  • .github/workflows/release-binaries.yml
  • .github/workflows/publish-shims.yml
.github/workflows/*

📄 CodeRabbit inference engine (.archgate/adrs/GEN-003-tool-invocation-via-scripts.md)

.github/workflows/*: Do not use direct lint/format binary invocations such as bunx prettier, bunx oxfmt, npx eslint, oxlint ., or similar in GitHub Actions workflows; call the repository scripts instead.
In GitHub Actions workflows, do not run bare bun test; use bun run test so the script-level flags from package.json are applied.

Files:

  • .github/workflows/release-binaries.yml
  • .github/workflows/publish-shims.yml
tests/**/*.test.ts

📄 CodeRabbit inference engine (.archgate/adrs/ARCH-005-testing-standards.md)

tests/**/*.test.ts: Use Bun's built-in test runner (bun:test) for all test files, and place tests under tests/ mirroring the src/ directory structure with <module-name>.test.ts naming.
Use temp directories (mkdtemp) for filesystem tests, and clean them up in afterEach or afterAll.
Close external SDK instances (servers, clients, transports, connections) in afterEach or afterAll, managing their lifecycle in hooks rather than inside individual test bodies.
When a test creates a temporary git repository and runs git commit, configure local user.email and user.name immediately after git init.
Test public module interfaces, not private implementation details.
Use descriptive test names that explain the expected behavior.
Every runnable test()/it() must contain at least one expect() assertion; smoke tests must make the contract explicit with expect(() => fn()).not.toThrow() or await expect(promise).resolves.toBeUndefined().
Use test.skip, test.skipIf, or test.todo for intentionally empty or disabled tests; do not use bare return or empty callbacks to skip work.
If the first expect() is being added to a previously assertion-less test file, add expect to the bun:test import.
When mocking fetch in tests, assign directly to globalThis.fetch and restore the original or use mock.restore() afterward.
Wrap spyOn() and inline mockImplementation() usage in try/finally, or create and restore spies in hooks, so mockRestore() always runs.
Only raise a per-test timeout above the global bun test --timeout 60000; never set a shorter per-test timeout.
Mock first-party modules with import * as mod plus spyOn(mod, "fn"), not mock.module().
When a test needs to redirect user-scope paths, mock os.homedir() instead of relying on HOME/Bun.env.HOME; restore the spy in test hooks.
Do not depend on network access in unit tests.
Do not leave temp files after test runs.
Do not leave external SDK instances open after tests...

Files:

  • tests/helpers/update-check.test.ts
tests/**/*.ts

📄 CodeRabbit inference engine (.archgate/adrs/ARCH-009-platform-detection-helper.md)

In test files, use _resetPlatformCache() to simulate different platforms instead of mocking or mutating process.platform directly.

Files:

  • tests/helpers/update-check.test.ts
src/cli.ts

📄 CodeRabbit inference engine (.archgate/adrs/ARCH-001-command-structure.md)

src/cli.ts: The main entry point must explicitly import and register every command; no auto-discovery is allowed.
All async bootstrap logic in src/cli.ts must be wrapped in an async main() function and invoked with main().catch((err) => { logError(String(err)); process.exit(2); }); top-level await is forbidden.
The CLI must run in-process in the same Bun process as the entry point; command execution should not rely on child processes.

Files:

  • src/cli.ts
🧠 Learnings (2)
📚 Learning: 2026-06-11T12:50:28.661Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 406
File: .claude/agent-memory/archgate-developer/feedback_prefer_tests_over_adr_rules.md:8-18
Timestamp: 2026-06-11T12:50:28.661Z
Learning: In `archgate/cli`, for markdown files under `.claude/agent-memory/`, follow the established convention: use YAML frontmatter (with a `name:` field used as the document title) and do not require a top-level `#` (H1) heading. During code review, do not flag missing first-line/first-top-level H1 headings (e.g., MD041) for these agent-memory files since markdownlint is not part of the repo’s `bun run validate` lint pipeline (oxlint/oxfmt only).

Applied to files:

  • .claude/agent-memory/archgate-developer/feedback_concise_comments.md
  • .claude/agent-memory/archgate-developer/project_release_pipeline_gotchas.md
  • .claude/agent-memory/archgate-developer/MEMORY.md
📚 Learning: 2026-07-02T16:03:33.031Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 446
File: src/helpers/session-context-opencode.ts:81-100
Timestamp: 2026-07-02T16:03:33.031Z
Learning: For synchronous helper functions that use Bun’s sqlite sync API (i.e., they must remain synchronous), it’s acceptable to use `existsSync` from `node:fs` to check whether the SQLite database file exists. Avoid using `Bun.file(path).exists()` for this purpose because it’s async and would force the helper to become async (no equivalent synchronous Bun alternative). If the DB file is missing, throw/return a clear, actionable "No database found" error (per ARCH-006) rather than letting the sqlite open fail with a generic DB-open error.

Applied to files:

  • src/helpers/update-check.ts
🪛 LanguageTool
.claude/agent-memory/archgate-developer/feedback_concise_comments.md

[uncategorized] ~10-~10: The official name of this software platform is spelled with a capital “H”.
Context: ...on where I wrote long comment blocks in .github/workflows/*.yml and src/cli.ts (mult...

(GITHUB)


[grammar] ~14-~14: Use a hyphen to join words.
Context: ...h with incident timelines, confirmed-via citations, or full backstory. Link to a ...

(QB_NEW_EN_HYPHEN)

🪛 markdownlint-cli2 (0.22.1)
.claude/agent-memory/archgate-developer/feedback_concise_comments.md

[warning] 8-8: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

.claude/agent-memory/archgate-developer/project_release_pipeline_gotchas.md

[warning] 8-8: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🪛 zizmor (1.26.1)
.github/workflows/release-binaries.yml

[error] 189-189: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 189-189: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 183-183: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment

(undocumented-permissions)

.github/workflows/publish-shims.yml

[error] 30-30: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[info] 20-20: workflow or action definition without a name (anonymous-definition): this job

(anonymous-definition)


[warning] 60-62: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 83-85: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 114-114: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 125-127: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 154-156: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🔇 Additional comments (4)
.github/workflows/publish-shims.yml (2)

3-6: LGTM!


45-50: LGTM!

src/helpers/update-check.ts (1)

12-24: LGTM!

src/cli.ts (1)

42-45: LGTM!

Comment thread .claude/agent-memory/archgate-developer/MEMORY.md Outdated
Comment thread .github/workflows/publish-shims.yml
Comment thread .github/workflows/publish-shims.yml
Comment thread .github/workflows/release-binaries.yml
Comment thread CLAUDE.md Outdated
Comment thread src/cli.ts Outdated
Comment thread tests/helpers/update-check.test.ts
- publish-shims.yml/release-binaries.yml: pass tag/output values via
  env: instead of interpolating directly into run: scripts
  (zizmor template-injection), set persist-credentials: false on
  checkouts that don't push, name the wait-for-binaries job, comment
  the trigger-shim-publish permission
- src/cli.ts, src/helpers/update-check.ts: shouldPerformUpdateCheck's
  ci param is now boolean (Boolean(Bun.env.CI) at the call site) per
  ARCH-014
- tests/helpers/update-check.test.ts: hoist the shouldPerformUpdateCheck
  import instead of re-importing per test (it's a pure function)
- CLAUDE.md, agent memory: mention the upgrade-command exception;
  minor grammar fixes

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
Runs zizmor (GitHub Actions static analysis) on every PR via
zizmor-action in GitHub Advanced Security mode — findings upload to
the Security tab (free for public repos) rather than failing the
build, since there's an existing unreviewed findings backlog across
several workflow files. Can be promoted to a hard gate later via
code-scanning merge protection once triaged.

zizmor.yml suppresses the one already-adjudicated exception: the SLSA
reusable workflow's tag-not-SHA reference, already documented in
CI-001.

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@rhuanbarreto

Copy link
Copy Markdown
Contributor Author

Addressed the CodeRabbit review (commit ec84f2d):

  • ✅ Template-injection warnings: moved all flagged ${{ }} interpolations into env: blocks (both the ones you flagged and a couple more of the same pattern I found while in these files — release-binaries.yml's upload-asset steps).
  • persist-credentials: false on checkout steps that don't push (left publish-go-tag's checkout with default persistence — it's the one job that needs it).
  • Boolean(Bun.env.CI)shouldPerformUpdateCheck's ci param is now typed boolean, matching ARCH-014.
  • ✅ Hoisted the shouldPerformUpdateCheck import in the test file (it's pure, no per-test reload needed).
  • CLAUDE.md now mentions the upgrade-command exception explicitly.
  • ➖ MEMORY.md lines 74-76: those were already one-line pointers with links to project_release_pipeline_gotchas.md as of the commit you reviewed — no further trimming applied.
  • ➖ MD041 (missing H1 in agent-memory files): known non-issue per an existing learning in this repo — agent-memory files use frontmatter name: as the title, and markdownlint isn't part of bun run validate.

Also added zizmor as an actual CI check (commit 7608cd6) rather than relying only on AI review to catch these — it's what caught your same findings (plus a pre-existing backlog across other workflow files, tracked separately, not blocking yet).

Comment thread .github/workflows/code-pull-request.yml
Fork PRs get a read-only GITHUB_TOKEN no matter what permissions the
workflow declares, so the zizmor job's security-events: write request
was silently denied and SARIF upload would fail — permanently
breaking the required status gate for any external contributor.

For fork PRs, fall back to advanced-security: false (console-only,
no write permission needed) wrapped in continue-on-error, so neither
the permission mismatch nor the pre-existing findings backlog can
fail the gate for contributions that don't originate from this repo.

Reported by Cursor Bugbot on PR #450.

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
@rhuanbarreto

Copy link
Copy Markdown
Contributor Author

Fixed in f334101 — good catch. Fork PRs now get `advanced-security: false` (no `security-events: write` needed) wrapped in `continue-on-error`, so neither the permission mismatch nor the pre-existing findings backlog can fail the required gate for external contributors. Non-fork PRs/pushes keep the full Advanced Security path.

CodeRabbit's re-check still flagged these as longer than a pointer
after the prior trim. Cut to single-clause bullets matching its own
suggested style.

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 3, 2026

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9ea652e. Configure here.

Comment thread .github/workflows/code-pull-request.yml
main() built the updateCheckPromise inline (gate check + ternary +
Promise.resolve(null)). Moved that wiring into a new
maybeCheckForUpdates() in src/helpers/update-check.ts so cli.ts just
calls one function; shouldPerformUpdateCheck() stays exported and
tested separately as the pure gating decision.

Added tests covering the gated-off (no network call) and gated-on
(calls through to checkForUpdatesIfNeeded) paths.

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
Empirically this wasn't failing — actions/checkout succeeds on public
repos without contents: read since the git-protocol clone doesn't
gate on the job's declared permissions (confirmed: 7 successful runs
of this job before this commit). Adding it anyway: it's what
zizmor-action's own quickstart example declares, costs nothing, and
removes any doubt.

Reported by Cursor Bugbot on PR #450.

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
@rhuanbarreto rhuanbarreto changed the title fix(ci): stop racing publish-shims against release-binaries retries chore(ci): stop racing publish-shims against release-binaries retries Jul 3, 2026
@rhuanbarreto rhuanbarreto enabled auto-merge (squash) July 3, 2026 14:34
@rhuanbarreto rhuanbarreto merged commit 3cb02b7 into main Jul 3, 2026
41 checks passed
@rhuanbarreto rhuanbarreto deleted the fix/publish-shims-race branch July 3, 2026 14:36
rhuanbarreto added a commit that referenced this pull request Jul 3, 2026
Origin/main (PR #450) independently refined the same update-check and
publish-shims/release-binaries work this branch had already done, so
those files take main's superseding versions verbatim (confirmed
byte-identical post-merge). Documentation conflicts (CLAUDE.md,
MEMORY.md, feedback_concise_comments.md) were near-duplicate content
from both sides; kept main's phrasing.

Also compacted MEMORY.md from 24.8KB to 5.5KB per the memory-index
size hook: moved long-form entries into topic files (oxlint gotchas,
test isolation, Windows subprocess quirks, CI workflow gotchas, rules
engine internals, i18n quality, CLI-skill flag sequencing) and left
one-line pointers in the index.

Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
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