chore(release): add sync-dev-after-release.sh + document post-publish backport - #37
Merged
Merged
Conversation
… backport Adds scripts/sync-dev-after-release.sh which backports the three release-bookkeeping files from main to dev after a release tag publishes: - Cargo.toml — surgical update of ONLY the [package].version line. Other Cargo.toml lines on dev (deps, rust-version) are preserved. - Cargo.lock — regenerated cleanly via cargo build --release. - CHANGELOG.md — copied verbatim from origin/main (main is authoritative). Lands as a single signed commit directly on dev (no PR, satisfies protect-dev's required_signatures via local commit signing). Idempotent — safe to re-run; exits 0 with no commit if dev is already in sync. Documents the backport step in RELEASES.md after the publish-pipeline table, establishing it as a deliberate convention. Supersedes the prior 'never back-merged' rule for these three files. Motivation: across v0.1.0 -> v0.2.0 dev's Cargo.toml stayed at 0.1.0, making 'anc --version' from dev builds report stale, and the embedded badge slug in dogfood scorecards point at the wrong release. The same gap left dev's CHANGELOG empty for the entire release history.
11 tasks
brettdavies
added a commit
that referenced
this pull request
Apr 30, 2026
…put.rs (#38) ## Summary Dogfooding `anc check .` against this repo on the v0.2.0 binary surfaced one FAIL and one multi-site WARN that together pulled the project-mode score down to 90%. This PR addresses both, taking the score to **97%** with **0 fail / 1 warn** (the remaining warn is `p2-json-output`'s known probe limitation — `--help`/`--version` short-circuit `--output` flags, so safe probes can't validate the JSON envelope; that's a check-design concern, not a real regression). Two related cleanups, plus the supporting refactor: 1. **Unwrap fail (4 sites → 0).** Three `.unwrap()` sites are infallible by upstream contract — clap's `ValueEnum::to_possible_value()` always returns `Some` for declared variants (`src/skill_install.rs:574, 613`), and `Path::file_name()` / `OsStr::to_str()` on a glob-matched ASCII filename in `build.rs` cannot fail in practice. All three are now `.expect("…")` calls naming the invariant in source so the next reader doesn't have to reconstruct the reasoning. 2. **Naked println warn (11 sites → 0).** Two distinct cases bundled here: - **build.rs (9 sites).** Cargo build scripts emit metadata via `println!("cargo:rerun-if-changed=…")` and `println!("cargo:warning=…")` directives — there's no other API. The `p7-naked-println` check now exempts `build.rs` at any crate root via a precise path-segment predicate (rejects misnamed `src/build.rs`, `tests/build.rs`, etc). - **main.rs:259 + skill_install.rs:510 (2 sites).** Both are legitimate stdout hand-offs at the orchestration boundary. New `src/output.rs` centralizes them behind `output::emit` (no trailing newline) and `output::emit_line` (with newline). The check's existing `output|display in path` exemption already covers the new module by convention — no check change needed for this case. ## Changelog ### Changed - `p7-naked-println` source check now exempts `build.rs` at any crate root. Cargo build scripts use `println!("cargo:…")` directives by protocol; flagging them produces noise without an alternative API. Misnamed `src/build.rs` or `tests/build.rs` files stay flagged. ### Fixed - Eliminated four `.unwrap()` calls on infallible operations across `src/skill_install.rs` and `build.rs`. Replaced with `.expect("…")` naming the upstream contract that guarantees `Some`/`Ok`. No behavior change — these were already infallible; the `expect` messages document why. ## Type of Change - [x] `fix`: Bug fix (non-breaking change which fixes an issue) ## Related Issues/Stories - Story: dogfooding the v0.2.0 binary against this repo to catch source-quality regressions before they reach Show HN readers. - Issue: n/a (surfaced via ``anc check .`` dogfood, not a filed issue). - Architecture: ``src/output.rs`` becomes the single stdout hand-off point for the binary; ``src/checks/source/rust/naked_println.rs`` exempts build scripts at any crate root. - Related PRs: sibling PR #37 (chore/sync-dev-after-release) — release backport script + RELEASES.md step. Both branches ride today's release together. ## Testing - [x] Unit tests added/updated - [x] All tests passing **Test Summary:** - Unit tests: 535 passing (2 new tests in ``naked_println.rs`` covering ``is_cargo_build_script`` predicate — positive cases bare/relative/absolute/Windows/case-insensitive; negative cases src/, tests/, examples/, benches/ subtrees and ``build.rs.bak`` — plus an integration check that the helper still warns at unit level while ``run()`` filters by path). - Integration tests: dogfood verification — ``anc check .`` reports 33 checks: 28 pass, 1 warn, 0 fail, 4 skip → 97% (was 90%). Binary mode unchanged at 89% (orthogonal to source-side findings). - Coverage: ``cargo fmt --check``, ``cargo clippy --release -- -Dwarnings``, full pre-push hook all green. ## Files Modified **Modified:** - ``build.rs`` — ``.unwrap().to_str().unwrap()`` chain → ``.expect("…")`` calls naming the invariant. - ``src/checks/source/rust/naked_println.rs`` — ``is_cargo_build_script`` helper exempts crate-root build scripts; doc-comment on the module updated; 2 new tests. - ``src/main.rs`` — declares the new ``output`` module; routes the final stdout hand-off through ``output::emit``. - ``src/skill_install.rs`` — two test-side ``.unwrap()`` → ``.expect()`` replacements; ``println!("{rendered}")`` → ``crate::output::emit_line(&rendered)``. **Created:** - ``src/output.rs`` — single stdout hand-off point with ``emit`` and ``emit_line`` helpers. **Renamed:** - None. **Deleted:** - None. ## Breaking Changes - [x] No breaking changes The naked-println exemption broadens what passes; no tool that previously passed will now fail. ## Deployment Notes - [x] No special deployment steps required ## 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
12 tasks
brettdavies
added a commit
that referenced
this pull request
Apr 30, 2026
…ak (#39) ## Summary `target.path` in the JSON scorecard previously emitted the canonicalized absolute path from `Project::discover` (e.g. `/home/<user>/dev/agentnative-cli`). That value flows into committed scorecards under `agentnative-site/scorecards/`, README badge URLs, Show HN comment paste-throughs, and any artifact an agent posts to a PR or issue. Three PII vectors leaked through it: - **operator username** via `/home/<user>/`, `/Users/<user>/`, `C:\Users\<user>\` - **org/employer directory structure** (e.g. `/home/<user>/work/<company>/...`) - **personal directory layout intent** (`~/dev` vs `~/code` vs `~/projects`) This PR switches `target.path` to the **basename** of the resolved target — the directory name in project mode, the file name in binary mode. That carries identical identifying signal to ``tool.name`` (the slug used by `/score/<slug>` URLs and badge embeds); anything richer was information leakage with no compensating consumer use. ``command`` mode is unchanged (always `null`). No `schema_version` bump — `target.path` stays `string | null`, always-present-null contract holds, no key changes. The `schema_version` field exists to signal *shape* changes for consumer feature-detection; this is a value-content fix on an existing key. ## Changelog ### Fixed - `target.path` in `anc check --output json` now emits the basename of the resolved target instead of the canonicalized absolute path, eliminating a home-directory / username PII leak that flowed into committed scorecards, badge URLs, and agent-posted artifacts. Project mode emits the directory name (e.g. `\"agentnative-cli\"`); binary mode emits the file name (e.g. `\"anc\"`); command mode unchanged at `null`. No schema bump — value semantics changed, schema shape did not. ## Type of Change - [x] `fix`: Bug fix (non-breaking change which fixes an issue) ## Related Issues/Stories - Story: surfaced during 2026-04-30 dogfood review when the saved scorecard JSON in `.context/dogfood/` was inspected and the absolute home-dir path stood out as obvious PII leakage. - Issue: n/a — caught by inspection, not filed. - Architecture: `src/main.rs::build_target_info` is the single derivation site for `TargetInfo`; doc-comment now names the leak-vector rationale so future readers understand why basename is non-negotiable. - Related PRs: rides the next release wave alongside #37 (release backport script) and #38 (source-quality fixes), all merged into ``dev``. ## Testing - [x] Unit tests added/updated - [x] Integration tests added/updated - [x] All tests passing **Test Summary:** - Unit tests: 535 passing (no count change — the basename helper is an internal refactor, integration tests carry the new assertions). - Integration tests: ``tests/scorecard_schema_v05.rs`` — project-mode test now pins ``parsed[\"target\"][\"path\"] == \"perfect-rust\"`` (was: just ``is_string()``); binary-mode test pins ``\"test.sh\"``; new test ``schema_v05_target_path_carries_no_separators`` rejects any forward or back slash in the value (regression guard against richer path representations creeping back in). 51 tests in this suite (was 50). - Manual / dogfood: ``cargo build --release`` green; ``anc check . --output json | jq .target.path`` returns ``\"agentnative-cli\"`` (was: ``/home/brett/dev/agentnative-cli``); binary mode returns ``\"anc\"`` (was: full path); command mode returns ``null`` (unchanged). ## Files Modified **Modified:** - ``src/main.rs`` — ``build_target_info`` now uses new ``basename_string()`` helper. Doc-comment expanded with PII-leak rationale. - ``src/scorecard/mod.rs`` — ``TargetInfo`` doc-comment specifies basename semantics + leak rationale. - ``tests/scorecard_schema_v05.rs`` — tightened project + binary mode assertions to pin literal basename values; added ``schema_v05_target_path_carries_no_separators`` regression guard. - ``CLAUDE.md`` — scorecard 0.4 ``target`` bullet updated with leak rationale + pointer to the regression-guard test. **Created:** - None. **Renamed:** - None. **Deleted:** - None. ## Breaking Changes - [x] No breaking changes The schema's contract (key presence, type) is unchanged — only the value-content shape changes. Any consumer relying on absolute-path semantics was already fragile across hosts (CI's ``/runner/work/...`` vs dev's ``/home/<user>/...``); ``tool.name`` is the right field for cross-host correlation and is unaffected. ## Deployment Notes - [x] No special deployment steps required Existing scorecards committed under ``agentnative-site/scorecards/`` retain their old absolute-path values until re-scored; the next ``anc check`` run on each tool emits the basename. Site renderers that read ``target.path`` for display will show shorter strings going forward — no consumer feature-detection needed. ## 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
brettdavies
added a commit
that referenced
this pull request
May 1, 2026
## Summary v0.3.0 promotes 15 PRs from `dev` to `main`. Headline: scorecard schema bumps `0.3` → `0.5` (cumulative — `anc.commit` removed before tag), a new `anc skill install <host>` subcommand with hardened `git clone` + build-time host-map codegen, and a published agent-native badge surface (text-mode hint + JSON `badge` block) gated on a 80% eligibility floor. Plus PII fix on `target.path`, source-quality cleanup, README refresh, cross-repo sync map, and tooling-side hardening (PR template `**Renamed:**` subsection, `sync-spec` modernization, `sync-skill-fixture` drift gate, triple-diff release-flow check with squash-merge triage guidance). The release-prep also surfaced four corrections that came in via the canonical PR-to-dev flow during this ship: `#43` resynced the `skill.json` build-time fixture against upstream `agentnative-site/dev` (drift was blocking every open PR); `#42` corrected cross-repo URLs in `.github/ISSUE_TEMPLATE/` (broken since the v0.1.1 squash on `main`); `#45` replaced the release-flow's single-direction leak check with a triple-diff plus `git cherry` patch-id check (the latter caught the URL drift that motivated the change); `#46` added squash-merge-noise triage guidance to the `git cherry` step (the check produced 55 noisy `+` lines on first run, all expected, but the original comment didn't explain that). `#47` dropped the `anc.commit` field from the scorecard JSON before the v0.3.0 tag, since the `cargo:rerun-if-changed` `.git/` watches made cached builds fragile and `anc.version` is sufficient build identity. ## Changelog <!-- Per the changelog generation rules, the canonical changelog is in CHANGELOG.md. This release section reflects the same content; generate-changelog.sh extracts from each contributing PR's ## Changelog block. The bullets below are a curated highlight set for the PR body itself. --> ### Added - `anc skill install <host>` subcommand for six hosts (`claude_code`, `codex`, `cursor`, `factory`, `kiro`, `opencode`) with `--dry-run` and `--output {text,json}` flags and a uniform JSON envelope across success, error, and dry-run paths (#35). - Scorecard `--output json` self-describing metadata: four top-level blocks (`tool`, `anc`, `run`, `target`) + a `badge` block with `eligible`, `score_pct`, `embed_markdown`, `scorecard_url`, `badge_url`, `convention_url` (#34, #36). - `--output text` post-summary agent-native badge embed hint when the tool clears the 80% eligibility floor; "do not nag" rule below (#36). ### Changed - Scorecard `schema_version` bumped `0.3` → `0.4` → `0.5` (cumulative — `anc.commit` field removed before the v0.3.0 tag, see #47) (#34, #36). - `sync-spec.sh` modernized — remote-first tag resolution, `SPEC_REF` env override removed (#33). - `p7-naked-println` source check now exempts `build.rs` at any crate root (#38). - README refreshed for current state (schema 0.5, badge block, `--audit-profile`, basename `target.path`); `rust-version` bumped `1.87` → `1.88` (#34, #40). - `--output json` scorecard `anc` block no longer includes a `commit` field — `anc.version` is the build identity (#47). ### Fixed - `target.path` in `--output json` now emits the basename of the resolved target instead of the canonicalized absolute path — eliminates a home-dir / username PII leak that flowed into committed scorecards, badge URLs, and agent-posted artifacts (#39). - Eliminated four `.unwrap()` calls on infallible paths across `src/skill_install.rs` and `build.rs`, replaced with `.expect("…")` naming the contract (#38). - Cross-repo URLs in `.github/ISSUE_TEMPLATE/` corrected: spec → `agentnative`, site → `agentnative-site`, double-`cli` typo → `agentnative-cli` (#42). ### Documentation - `scripts/SYNCS.md` cross-repo sync map (#41). - `RELEASES.md` § "After publish — sync `dev` with the release" + new `sync-dev-after-release.sh` script formalizing the post-publish backport convention (#37). - `RELEASES.md` § "Releasing dev to main" step 4 replaced with a triple-diff verification block (A: main→release, B: release→dev, C: dev→main) plus a `git cherry` patch-id check (#45), with squash-merge-noise triage guidance added in #46. - README `## Install the skill` section + `[![agent-native]]` badge row (#35, #40). ## Type of Change - [x] `feat`: New feature (non-breaking change which adds functionality) - [x] `fix`: Bug fix (non-breaking change which fixes an issue) - [x] `chore`: Maintenance tasks (dependencies, config, etc.) - [x] `docs`: Documentation update ## Related Issues/Stories - Story: v0.3.0 release — twelve PRs across two days of work post-v0.2.0 plus four release-prep PRs (#42, #43, #45, #46) opened during the release ceremony to fix issues caught by the new triple-diff verification, plus #47 dropping `anc.commit` before the tag. - Issue: n/a - Architecture: scorecard schema evolution (`0.3 → 0.4 → 0.5`) covered in CLAUDE.md `## Scorecard v0.5 Fields`; skill-install architecture covered in CLAUDE.md `## Skill Install Verb`; release ceremony in `RELEASES.md`. - Related PRs: #30, #33, #34, #35, #36, #37, #38, #39, #40, #41, #42, #43, #45, #46, #47 — all merged to `dev` and cherry-picked here in chronological order. ## Testing - [x] Unit tests added/updated - [x] Integration tests added/updated - [x] Manual testing completed - [x] All tests passing **Test Summary:** - Unit tests: 535+ passing across all #34, #35, #36, #38, #39 PRs (counts varied as PRs landed). #47 simplified to ~520+ after dropping the `anc_commit_when_present_looks_like_short_sha` test. - Integration tests: full suite green at every cherry-pick step. New tests added: `tests/scorecard_metadata_security.rs` (red-team regressions for hostile binaries), `tests/scorecard_schema_v05.rs` (schema drift guard with `target.path` regression test), `tests/skill_install.rs` (10 active + 1 ignored e2e), `tests/dogfood.rs` (p2/p5 dogfood guards). - Coverage: pre-push hook (CI mirror) green at every step — fmt, clippy `-Dwarnings`, full test suite, cargo-deny, Windows compat (libc grep + cross-target clippy). - Triple-diff verification (the new step from #45) confirmed only `docs/plans/`, `docs/brainstorms/`, `docs/ideation/` (guarded paths) and the `docs/solutions` symlink remain on dev. Release-prep files (`CHANGELOG.md`, `Cargo.{toml,lock}`, `completions/*`) will backport to dev via `scripts/sync-dev-after-release.sh` post-publish per the convention from #37. The `git cherry` patch-id check produced 55 `+` lines on first run; all audited as expected (squash-merge patch-id mismatch + conflict-resolution drift + intentional skips), zero real misses — motivated #46's triage guidance. ## Files Modified **Modified:** - `Cargo.toml`, `Cargo.lock` — version `0.2.0 → 0.3.0`; `time = "=0.3.47"` added; `rust-version` bumped. - `CHANGELOG.md` — v0.3.0 release notes prepended. - `README.md`, `AGENTS.md`, `CLAUDE.md` — updated for schema 0.4/0.5, skill-install architecture, audit-profile, basename `target.path`, badge surface, `anc.commit` removal. - `RELEASES.md` — post-publish backport step (#37); skill-fixture sync step; step 4 replaced with triple-diff + `git cherry` check (#45); squash-merge triage guidance added (#46). - `build.rs` — `emit_skill_hosts` codegen, `ANC_VERSION` emission (no longer Git-SHA-aware after #47). - `src/build_info.rs` — `ANC_VERSION` re-export; `ANC_COMMIT` and its test removed in #47. - `src/main.rs`, `src/cli.rs`, `src/error.rs`, `src/scorecard/mod.rs`, `src/argv.rs` — schema 0.4/0.5 metadata, skill-install dispatch, badge computation, basename helper. `AncInfo` shrinks to one field after #47. - `src/checks/source/rust/naked_println.rs` — build.rs exemption. - `src/skill_install/skill.json` — fixture refresh (`source.commit` pin and `verify` block removed by upstream). - `scripts/sync-spec.sh` — remote-first, `SPEC_REF` removed. - `scripts/hooks/pre-push` — Windows cross-clippy step. - `.github/pull_request_template.md` — `**Renamed:**` sub-header. - `.github/ISSUE_TEMPLATE/{config,false-positive,feature-request,scoring-bug}.yml` — corrected cross-repo URLs. - `completions/anc.{bash,zsh,fish,elvish,powershell}` — regenerated. **Created:** - `src/output.rs`, `src/skill_install.rs`, `src/skill_install/skill.json`. - `tests/dogfood.rs`, `tests/scorecard_metadata_security.rs`, `tests/scorecard_schema_v05.rs`, `tests/skill_install.rs`, `tests/fixtures/hostile-{hang,nonzero-exit,stdout-flood}/probe.sh`. - `scripts/sync-skill-fixture.sh`, `scripts/sync-dev-after-release.sh`, `scripts/SYNCS.md`. - `.github/workflows/skill-fixture-drift.yml`. - `.github/ISSUE_TEMPLATE/00-blank.yml`. **Renamed:** - `tests/scorecard_schema_v04.rs` → `tests/scorecard_schema_v05.rs` (drift guard now covers `badge.*` keys). - `tests/fixtures/skill.json` → `src/skill_install/skill.json` (codegen needs to read from a path inside cargo's package). **Deleted:** - `.github/ISSUE_TEMPLATE/grade-a-cli.yml`, `pressure-test.yml`, `spec-question.yml` — duplicates of the spec repo's set; routed via `config.yml`. - `src/build_info.rs::ANC_COMMIT` const (and its test) — dropped before tag, see #47. ## Breaking Changes - [x] No breaking changes The scorecard `schema_version` bumps (`0.3` → `0.4` → `0.5`) are additive within the documented `0.x` pre-launch policy. Pre-`0.4` consumers feature-detect the four metadata blocks; pre-`0.5` consumers feature-detect the `badge` key. `target.path` value semantics changed (basename instead of absolute path) — schema shape is unchanged, so consumers reading the field at all will continue to parse it; consumers using it for cross-host correlation should already have migrated to `tool.name`. `anc.commit` was added in 0.4 but removed before the v0.3.0 tag (#47); no public consumer of the field exists pre-launch. ## Deployment Notes - [x] No special deployment steps required Standard pipeline: tag push triggers crates.io publish (Trusted Publishing, OIDC), GitHub Release with all 5 platform archives + sha256sums, then dispatch to `brettdavies/homebrew-tap` for formula update. After `finalize-release.yml` flips `make_latest: true`, run `./scripts/sync-dev-after-release.sh v0.3.0` to backport `Cargo.toml`, `Cargo.lock`, `CHANGELOG.md` to dev (new convention from #37). ## Checklist - [x] Code follows project conventions and style guidelines - [x] Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/) - [x] Self-review of code completed - [x] Tests added/updated and passing - [x] No new warnings or errors introduced - [x] Changes are backward compatible (or breaking changes documented)
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
After every release tag publishes on
mainandfinalize-release.ymlflips the GitHub Release topublished, threerelease-bookkeeping files are authoritative on
mainand need to flow back todevso future builds fromdevreportthe released version. Across
v0.1.0→v0.2.0this didn't happen:dev'sCargo.tomlstayed at0.1.0, theCargo.lockpackage version line stayed stale, anddev'sCHANGELOG.mdwas empty for the entire release history.This PR ships a tiny bash script (
scripts/sync-dev-after-release.sh) that does the backport surgically and lands anew step in
RELEASES.mdafter the publish-pipeline table making the convention explicit. Companion commitabf1c6a(already ondev) did the one-time backport forv0.2.0itself; this PR is purely theprocess change so the next release doesn't drift again.
Changelog
Added
scripts/sync-dev-after-release.shbackportsCargo.toml[package].version,Cargo.lock, andCHANGELOG.mdfrom
maintodevafter a release tag publishes. Surgical (preserves dev's other Cargo.toml lines), idempotent(re-runs are a no-op when dev is already in sync), and signed via the operator's normal commit signing, which
satisfies
protect-dev'srequired_signaturesruleset without needing a CI bot identity.Documentation
RELEASES.md§ "After publish: syncdevwith the release" documents the backport step, supersedes the prior"never back-merged" rule for these three specific files, and points operators at the script.
Type of Change
chore: Maintenance tasks (dependencies, config, etc.)docs: Documentation updateRelated Issues/Stories
RELEASES.md§ "After publish: syncdevwith the release" (lands in this PR; documents the new convention)abf1c6a chore(release): backport v0.2.0 artifacts to devapplied the one-time backport that this script formalizes. Sibling PR fix(source-quality): eliminate unwraps + route stdout through src/output.rs #38 ships source-quality fixes that ride the same release as this one.Testing
Test Summary:
-Dwarnings, test, cargo-deny, Windows compat) green on the branch.Files Modified
Modified:
RELEASES.md: adds new### After publish: sync `dev` with the releasesubsection inside the Tagging and publishing section.Created:
scripts/sync-dev-after-release.sh(executable, +x). ~95 LOC bash.Renamed:
Deleted:
Breaking Changes
Deployment Notes
The script is invoked manually after each future release per the new RELEASES.md step.
Checklist