feat(scripts): sync-spec.sh --ref flag + gh api transport#59
Merged
Conversation
Adds a `--ref <git-ref>` flag (and matching `SPEC_REF` env var) so the CLI can vendor agentnative-spec from an explicit branch, tag, or commit SHA, not just the latest `v*` tag. Default behavior (no `--ref`) is unchanged: resolves latest `v*` tag. Motivation: cross-repo coordination of in-flight spec work that hasn't released yet. The 2026-05-21 taxonomy unit (PR brettdavies/agentnative#34) landed on spec `dev` (commit b4f4d02) but not on `main` and not tagged, so a blind `sync-spec.sh` rerun re-pulled `v0.4.0` and silently missed the new conditional-applicability schema. The U2 work in agentnative-cli (per the scorecard-fairness plan in agentnative-site) needs the conditional shape from the spec to drive new probe statuses (`opt_out`, `n_a`); `--ref` makes that vendoring explicit. Implementation: refactored from `git clone` to `gh api`. All ref types (latest tag, branch, tag, SHA) take the same code path through `repos/{owner}/{repo}/contents/{path}?ref=<X>` with the `application/vnd.github.raw` accept header. No more shallow-vs-full clone distinction. The local-fallback path (when `gh api` is unreachable) still uses `git` against `SPEC_ROOT` for offline development. Surface mirrors the site-side script (brettdavies/agentnative-site feat/sync-spec-ref-flag): --ref <git-ref> CLI flag, wins over SPEC_REF env SPEC_REF=<ref> env var, same effect --help prints the usage banner Resolved short SHA is printed every run regardless of ref type so users can record the exact pin in a consumer PR body. Validated: - `--ref dev` pulls HEAD of dev with the conditional-applicability schema in p2 + p8 (verified via grep on the vendored files). - `--ref v0.4.0` pulls the released tag (90dd48b), without the conditional schema. Default-path (no --ref) matches. - Local fallback exercised; bad refs surface a fetch hint. - The script preserves repo-owned files in the destination (e.g., src/principles/spec/README.md is not overwritten).
Brings the SYNCS.md doc into line with the sync-spec.sh refactor on
this branch:
- Spec → cli mermaid arrow label updated to mention the gh api
transport and the `--ref <branch|tag|SHA>` flag.
- Upstream-data row for sync-spec.sh expanded with: gh api
resolution path, local-checkout fallback for offline runs,
`--ref` / `SPEC_REF` for cross-repo coordination of in-flight
spec work, and the record-the-resolved-SHA-in-the-PR-body
convention.
- Reference section's sync-spec.sh entry updated to mention the
`--ref` flag, `SPEC_REF` env var, the gh api transport, and the
local-checkout fallback for offline runs.
Caught while opening the PR for this branch — the comment header still referenced `anc check` from before PR #58. Now reads `anc audit`.
12 tasks
brettdavies
added a commit
that referenced
this pull request
May 27, 2026
## Summary `shellcheck scripts/sync-spec.sh` flagged a dead variable (`spec_ref`) introduced by the recent `--ref` refactor in #59. Removed. Zero behavior change. While here, closed the process gap that allowed it to ship: added `shellcheck` to the local pre-push hook. Also audited the sibling agentnative-* repos and the shared `brettdavies/.github` reusable workflow for the same gap; results in the Coverage Gap section below. ## Changelog ### Added - `scripts/hooks/pre-push` now runs `shellcheck --severity=warning` against every tracked `*.sh` plus everything under `scripts/hooks/` (so the hook itself is linted). Uses `git ls-files` so vendored / `.gitignore`d scripts are excluded. Skips with a one-line note if `shellcheck` is not installed, matching the existing `cargo deny` pattern. ### Fixed - Removed dead `spec_ref` variable in `scripts/sync-spec.sh` (SC2034). Declared during the `--ref` refactor in #59 but never read; the actual code uses the `SPEC_REF` env var directly. ## Type of Change - [x] `fix`: Bug fix (dead-code removal) - [x] `feat`: Pre-push hook gains a shellcheck step ## Related Issues/Stories - Story: n/a - Issue: n/a - Architecture: closes the local-side shell-linting gap that let SC2034 ship through #59. - Related PRs: #59 introduced the dead variable. CI-side and sibling-repo follow-ups described below. ## Testing - [x] Manual testing completed - [x] All tests passing **Test Summary:** - `shellcheck scripts/sync-spec.sh` → 0 findings (was 1 before). - `shellcheck --severity=warning <every tracked .sh + scripts/hooks/*>` → 0 findings across the whole tree. - `bash scripts/hooks/pre-push` runs end-to-end on the current tree: fmt, clippy, test, deny, shellcheck, windows-grep, windows-clippy all pass. - `bash scripts/sync-spec.sh --help` banner unchanged. - `cargo build --release` clean. ## Files Modified **Modified:** - `scripts/sync-spec.sh`: removed the `spec_ref=""` declaration and its stale comment line. - `scripts/hooks/pre-push`: added shellcheck step as step 5, renumbered windows-grep / windows-clippy to 6 / 7 in the source comments. **Created:** - None. **Renamed:** - None. **Deleted:** - None. ## Severity threshold rationale `--severity=warning` catches: - SC2034 (unused variable, what #59 shipped) - SC2086 (missing quoting that would break on spaces in paths) - SC2155 (`local var=$(...)` masking exit codes) - SC2046 (word splitting of unquoted command substitution) - SC2178 (writing scalar to an array variable) - SC2128 (using an array in scalar context) - (and the rest of the warning-tier rules) It deliberately skips info/style noise. Specifically lets through SC2016 on `scripts/prose-check.sh:196` (intentional single-quote `jaq` filter where the dollar-signs are jaq syntax, not shell variables) without needing an inline `# shellcheck disable=` directive. Tightening to `--severity=info` later is a one-line change if you want stricter enforcement. ## Coverage gap across the agentnative-* ecosystem Subagent sweep of the three sibling repos plus the shared reusable workflow: | Repo | Pre-push shellcheck | CI shellcheck | `.sh` files | | --------------------- | ------------------- | ----------------------------------------------------------------- | ---------------------------- | | `agentnative-cli` | **yes (this PR)** | no | ~7 | | `agentnative-spec` | no | no | 3 | | `agentnative-site` | no | no | **32** (largest exposure) | | `agentnative-skill` | no pre-push hook | yes (`ludeeus/action-shellcheck@2.0.0` on `./scripts/`, style severity) | 3 | | `brettdavies/.github` | n/a | no (`rust-ci.yml` has no shellcheck step; just fmt/clippy/test/deny/package/changelog) | n/a | Summary: the only repo with shellcheck today is `agentnative-skill`, and it runs in CI only. The shared `rust-ci.yml` that `agentnative-cli`, `agentnative-spec`, and `agentnative-site` all delegate to does NOT run shellcheck, so adding it there would close the gap across every Rust consumer in one stroke. ## Follow-up work (not in this PR) 1. **CI side for this repo**: add shellcheck to `brettdavies/.github`'s `rust-ci.yml` (closes the gap for cli + spec + site simultaneously), or add a job locally in `agentnative-cli/.github/workflows/ci.yml`. 2. **Pre-push hooks in sibling repos**: port this step to `agentnative-spec/scripts/hooks/pre-push` and `agentnative-site/scripts/hooks/pre-push`. Site has 32 `.sh` files, so the payoff is highest there. 3. **Pre-push hook in agentnative-skill**: add one. The repo has CI shellcheck but no fast-feedback loop locally. ## Breaking Changes - [x] No breaking changes Pre-push step is opt-in (skips silently if `shellcheck` is not installed). ## Deployment Notes - [x] No special deployment steps required Maintainers who want the new step should `brew install shellcheck` (or apt equivalent). Otherwise the existing pipeline behavior is preserved. ## Checklist - [x] Code follows project conventions and style guidelines - [x] Commit messages follow Conventional Commits - [x] Self-review of code completed - [x] Tests added/updated and passing - [x] No new warnings or errors introduced - [x] Changes are backward compatible
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
--ref <git-ref>flag (and matchingSPEC_REFenv var) toscripts/sync-spec.shso the cli can vendoragentnative-specfrom an explicit branch, tag, or commit SHA, not just the latestv*tag. Default behavior (no--ref) is unchanged: resolves the latestv*tag.Refactored the script's transport from
git clonetogh apiso all ref types (latest tag, branch, tag, SHA) take the same code path throughrepos/{owner}/{repo}/contents/{path}?ref=<X>with the raw accept header. The local-checkout fallback (whengh apiis unreachable) still usesgitagainstSPEC_ROOTfor offline development.Changelog
Added
scripts/sync-spec.shnow accepts--ref <git-ref>(orSPEC_REFenv var) to vendoragentnative-specfrom an explicit branch, tag, or commit SHA. Default behavior unchanged: resolves the latestv*tag.Changed
scripts/sync-spec.shtransport refactored fromgit clonetogh api. Reduces the shallow-vs-full clone distinction, makes ref resolution uniform across tag / branch / SHA, and removes the need for a local clone except as an offline fallback.scripts/SYNCS.mddocuments the new flag, thegh apitransport, the local-checkout fallback, and the convention of recording the resolved SHA in any consumer PR body.Type of Change
feat: New feature (non-breaking change which adds functionality)docs: Documentation updateRelated Issues/Stories
agentnative-cli,agentnative-spec, andagentnative-sitefor in-flight spec work.brettdavies/agentnative#34(spec taxonomy unit ondev, not yet tagged) is the motivating example. Site-side counterpart:brettdavies/agentnative-sitefeat/sync-spec-ref-flagships the same flag surface for parity.Testing
Test Summary:
cargo build --release: clean (the script change is a build-time input but the vendored tree on this branch is unchanged, so the codegen produces the sameREQUIREMENTSslice).bash scripts/sync-spec.sh --helpprints the documented banner including the new flag and env var.--ref) still resolves the latestv*tag viagh apiand writes the same files intosrc/principles/spec/as before.Files Modified
Modified:
scripts/sync-spec.sh:--refflag +SPEC_REFenv var,gh apitransport, local-checkout fallback, resolved-SHA printout, banner updated to current subcommand name (anc audit).scripts/SYNCS.md: documents the new flag, transport, fallback, and the consumer-PR-body recording convention.Created:
Renamed:
Deleted:
Key Features
v0.4.0and missed the conditional-applicability schema" surprises.gh apifor all ref types) eliminates a class of edge cases where shallow vs full clones behaved differently for tag vs branch resolution.Benefits
agentnative-cli, which needs the conditional-applicability shape that lives on the spec'sdevbranch but isn't tagged yet.~/dev/agentnative-speccheckout. Thegh apipath works in CI and on fresh machines without needing the spec repo cloned locally.Breaking Changes
Default behavior is byte-identical to before. The
--refflag is opt-in; existing scripts that callsync-spec.shwith no arguments get the same result.Deployment Notes
Build-time input only. The vendored tree is unchanged on this branch, so cargo's codegen produces the same output. The flag only matters when someone re-runs
sync-spec.shwith--ref.Checklist