Skip to content

release(#408): v2.1.0#409

Merged
atlas-apex merged 3 commits into
mainfrom
release/v2.1.0
May 25, 2026
Merged

release(#408): v2.1.0#409
atlas-apex merged 3 commits into
mainfrom
release/v2.1.0

Conversation

@atlas-apex

Copy link
Copy Markdown
Collaborator

v2.1.0 — 2026-05-24

MINOR release. Adds the /release-sync skill — automates main→dev sync after each release-PR merge so the squash-merge divergence stops compounding. Bundled with a small /pdf convert.sh bug fix. This is the last cherry-pick release; from v2.2.x onwards /release-sync enables the canonical dev → main release flow.

This PR will tag v2.1.0 on main after merge.

Added

  • feat(#403) /release-sync skill — runs as Step 9 of /release. Creates a sync branch from upstream/dev, merges upstream/main with --no-ff -X ours (dev wins on conflicts because dev already has the un-squashed equivalents), opens a sync PR. Stops at PR creation; normal Rex + CEO merge gate applies. Framework-only (refuses on managed projects). Defensive cases handled: already-in-sync (no-op exit 0), going-backwards (refuse exit 1). 11 unit tests + AgDR-0052 documents design trade-offs (explicit-skill vs auto-invoke, -X ours vs -X theirs).

Fixed

  • fix(#404) /pdf convert.sh fallback path — removed stale --pdf-output-folder and --dest-name flags from the md-to-pdf dispatch branch (md-to-pdf removed both flags in a breaking API change). New strategy: stage source into a temp dir under the desired output stem, run npx md-to-pdf, move the result to the requested destination. Pandoc preferred-path unchanged; graceful-degrade (exit 3) on no converter preserved. New regression test (test_md_to_pdf_fallback.sh) catches future upstream API drift.

Compatibility

No breaking changes. Adopters using /pdf on systems without pandoc see the fallback path work again. Adopters using /release get a new optional Step 9; existing release flow unchanged unless /release-sync is invoked.

Release strategy

Branched release/v2.1.0 from upstream/main. Cherry-picked the 2 squashed commits from dev in order:

  1. 6a6f3b0fix(#404) (clean, no conflicts — only touches .claude/skills/pdf/)
  2. e3e742cfeat(#403) (auto-merge in 3 site files, no manual resolution needed)

Then the CHANGELOG + version-pill bump as a third commit. The cherry-pick path is being used for the third release in a row because dev still carries the v1.4→v2.0 squash divergence (124 commits). After this release, /release-sync is live on main, so v2.2.x and beyond can:

  1. Run /release-sync v2.1.0 once to back-fill the v2.1.0 squash into dev
  2. Then start using the canonical dev → main release flow

A separate task should kick off the historical sync for v1.2.0, v1.3.0, v2.0.0 squashes that never made it back to dev (the /release-sync skill handles N=1 at a time; can be looped).

Skip markers

Testing

  • bash .claude/hooks/tests/test_site_counts.sh — PASS (55 skills now actual; site copy updated to match via the feat(#403): /release-sync — main→dev sync after each release #406 cherry-pick)
  • git log upstream/main..HEAD shows exactly 3 commits (2 cherry-picks + CHANGELOG/version bump)
  • find .claude/skills -maxdepth 1 -type d | wc -l returns 55 (was 54 on v2.0.2; +1 for /release-sync)
  • CHANGELOG ## [2.1.0] section structured parallel to ## [2.0.2] directly below
  • Site version link updated v2.0.2v2.1.0
  • Netlify deploy preview surfaces from this PR — visual mobile check
  • After merge: v2.1.0 tag pushed to upstream/main
  • After merge: GitHub Release created with CHANGELOG section
  • After merge: drift banner on adopters' forks fires on next session

Glossary

Term Definition
MINOR bump Semver second-position increment (X.Y+1.0). Triggered by feat: commits — new functionality, no breaking changes.
Cherry-pick release path Branch off upstream/main, pick specific dev commits, PR back to main. Used here because dev carries 124 commits of v1.4→v2.0 squash divergence that would conflict on a normal release. v2.1.0 is the LAST cherry-pick release — /release-sync ships in this PR.
/release-sync New skill (Step 9 of /release). Branches from upstream/dev, merges upstream/main with --no-ff -X ours, opens a sync PR. Makes the release squash commit an ancestor of dev so future dev→main releases don't re-conflict.
-X ours vs -X theirs Git merge strategy options. "ours" = the branch you're ON when running merge. Since /release-sync branches from dev and merges in main, "ours" = dev = correct winner (dev has the unsquashed equivalents). AgDR-0052 details the semantic.
Squash divergence Each squash-merge to main creates a commit with a different SHA than the equivalent unsquashed history on dev. dev still carries the unsquashed commits unless synced back. The /release-sync skill prevents future accumulation.

Closes #408

atlas-apex and others added 3 commits May 24, 2026 22:34
…tch (#405)

md-to-pdf removed --pdf-output-folder and --dest-name in a breaking
API change; convert.sh still passed both flags, causing every
npx md-to-pdf invocation to abort with:

  ArgError: unknown or unexpected option: --pdf-output-folder

Fix: stage the source into a private temp dir under the desired output
stem (e.g. WORK/out.pdf → WORK/out.md), invoke `npx -y md-to-pdf
<tmp>.md`, then mv the resulting <tmp>.pdf to the requested TO_ABS.
md-to-pdf writes <basename>.pdf next to the source by default, so this
is compatible with every currently-released version.

The same fix is applied to the md-to-pdf-html branch (HTML → PDF
fallback), which had identical stale flags.

Adds regression test at .claude/skills/pdf/tests/test_md_to_pdf_fallback.sh
covering four cases: successful conversion, absence of the stale
--pdf-output-folder flag, absence of --dest-name, and custom output
path resolution. All four pass locally against the current npm latest.

Refs #404

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(#403): /release-sync skill — main→dev sync after each release

Introduces the /release-sync skill to address squash-merge divergence
that accumulated across releases and produced 99 conflicts on the v2.0.0
release PR. After each release, /release-sync vX.Y.Z opens a sync PR
that merges upstream/main into upstream/dev with -X ours (dev wins on
conflicts), making the squash commit an ancestor of dev so future release
PRs only show genuinely-new commits.

- .claude/skills/release-sync/SKILL.md — new skill spec with pre-flight
  checks, idempotent no-op, edge-case table, and PR body template
- .claude/skills/release/SKILL.md — adds Step 9 (mandatory invoke of
  /release-sync) and updates Related section
- docs/agdr/AgDR-0052-release-sync-skill.md — records the design choice
  (explicit skill vs auto-invoke vs switch-to-merge-commit) and the
  merge-strategy direction reasoning (-X ours on a dev-based branch)
- .claude/hooks/tests/test_release_sync.sh — 11 sandbox-based smoke
  tests covering already-in-sync no-op, diverged detection, branch name
  shape, -X ours direction, idempotence, post-sync state, and version
  argument validation; all 11 pass

Refs #403

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#403): refresh site skill-count (54→55) + 2 MD032 lint fixes

Address red CI on Rex-approved release-sync PR:

- site-counts drift: new /release-sync skill bumps total to 55. Update
  all 12 marketing-copy references across architecture.html, *.md.gen,
  llms.txt, llms-full.txt, skill.md (incl. 2 multiline / phrasing-variant
  references caught by the post-#377 cross-newline scanner).
- markdownlint MD032: add blank lines around the bullet lists in
  release-sync SKILL.md (line 80) and AgDR-0052 (line 36).

Refs #403

---------

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Append [2.1.0] section above [2.0.2]
- Bump site/index.html version pill v2.0.2 → v2.1.0
- Last cherry-pick release; /release-sync now live for v2.2.x+

Refs #408
@netlify

netlify Bot commented May 24, 2026

Copy link
Copy Markdown

Deploy Preview for apexyard ready!

Name Link
🔨 Latest commit 0dc5201
🔍 Latest deploy log https://app.netlify.com/projects/apexyard/deploys/6a136f4c0a92860008579809
😎 Deploy Preview https://deploy-preview-409--apexyard.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@atlas-apex atlas-apex left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Code Review: PR #409 — v2.1.0 release

Commit: 0dc52012e618d41bed226a9447854b152caa80fd

Summary

MINOR release cutting v2.1.0 from release/v2.1.0 to main. Bundles two previously-merged-to-dev PRs:

  • fix(#404)/pdf convert.sh stale-flag fix (cherry-pick of 6a6f3b0)
  • feat(#403) — new /release-sync skill (cherry-pick of e3e742c)

Plus a third release-bookkeeping commit (0dc5201) adding CHANGELOG [2.1.0] and bumping the site version pill v2.0.2 → v2.1.0. This is the last cherry-pick release; /release-sync ships in this PR and enables the canonical dev → main flow from v2.2.x onwards.

Checklist Results

  • Architecture & Design: Pass — release-cut PR, no architectural changes beyond the bundled feature (which already shipped its AgDR-0052)
  • Code Quality: Pass — cherry-picks preserve byte-identical content; no drift introduced
  • Testing: Pass — site-counts test green; test_md_to_pdf_fallback.sh (4 cases) + test_release_sync.sh (11 cases) carried over from cherry-picks
  • Security: N/A — no auth/crypto/secrets paths touched
  • Performance: N/A — release-cut PR
  • PR Description & Glossary: Pass — 5-term glossary covering MINOR bump, cherry-pick release path, /release-sync, -X ours vs -X theirs, squash divergence
  • Summary Bullet Narrative: Pass — each bullet verb + rationale + mechanism + test/AgDR pointer; well above the 6-word threshold
  • Technical Decisions (AgDR):N/A — release PR is a version-cut; /release-sync's design trade-offs documented in AgDR-0052 which shipped in PR #406
  • Adopter Handbooks: N/A — no handbooks loaded (release-cut PR; touched paths are CHANGELOG.md, site/, .claude/skills/, .claude/hooks/tests/, docs/agdr/, none of which trigger architecture/general/language handbook buckets)

Diff scope verification

Three commits, all files match the brief exactly:

Commit Files Verdict
22b6679 (fix #404 cherry-pick) .claude/skills/pdf/convert.sh, .claude/skills/pdf/tests/test_md_to_pdf_fallback.sh Matches brief; both blobs byte-identical to original 6a6f3b0
bf5717f (feat #403 cherry-pick) 4 core files (test, SKILL.md ×2, AgDR-0052) + 6 site copy files + 1 marketing markdown Matches brief; core 4 files byte-identical to original e3e742c; site files diverge only on the 54→55 absorption (expected auto-merge behaviour because main has had other site copy edits since e3e742c was created on dev)
0dc5201 (chore #408) CHANGELOG.md (+18, -0), site/index.html (+1, -1) Matches brief exactly

Cherry-pick fidelity (blob-SHA spot checks)

Original (e3e742c on dev) vs cherry-pick (bf5717f on release branch), core feat-#403 files:

  • .claude/skills/release-sync/SKILL.md168f032b… = 168f032b… MATCH
  • .claude/skills/release/SKILL.md086dd9a5… = 086dd9a5… MATCH
  • docs/agdr/AgDR-0052-release-sync-skill.md802a5977… = 802a5977… MATCH
  • .claude/hooks/tests/test_release_sync.sh6b7600d2… = 6b7600d2… MATCH

Fix #404 files (6a6f3b0 vs 22b6679):

  • .claude/skills/pdf/convert.sh31e1be5b… = 31e1be5b… MATCH
  • .claude/skills/pdf/tests/test_md_to_pdf_fallback.shc209465e… = c209465e… MATCH

The 3 site files where blob SHAs diverge (site/architecture.html, site/llms-full.txt, site/llms.txt) show ONLY the 54→55 count delta when diffed across the cherry-pick commit pair — i.e. the cherry-pick correctly absorbed surrounding text that main had evolved since dev branched, and only the substantive 54→55 changes from feat #403 landed. No silent drift.

CHANGELOG [2.1.0] section

Structured parallel to [2.0.2] directly below — same date format, narrative summary paragraph, ### Added/### Fixed/### Compatibility subsections, feat(#403)/fix(#404) bullet pattern, technical depth (mechanism + AgDR-0052 reference + test count). Pass.

Version pill bump

site/index.html:1576 — anchor href …/releases/tag/v2.0.2…/releases/tag/v2.1.0, inner text v2.0.2v2.1.0, surrounding styling string preserved. Pass.

PR title

release(#408): v2.1.0 matches the release(#N): vMAJOR.MINOR.PATCH shape (per pr.title_type_whitelist). The PR-title check job passed CI. Pass.

Site-counts drift

After feat #403's /release-sync skill, .claude/skills/ now contains 57 entries — 55 skill directories + 2 helper files (_lib-mermaid-lint.sh, _lib-mermaid-lint.test.sh). All marketing copy references 55. The site-counts drift detection CI job passes. Pass.

Markdownlint

markdownlint-cli2 job passes — MD032 fixes from PR #406's CI-fix commit carried over via the cherry-pick. Pass.

CI status (gh pr checks 409)

All 9 checks resolved:

  • Verify Ticket ID — pass
  • lychee — pass
  • markdownlint-cli2 — pass
  • shellcheck .claude/hooks — pass
  • site-counts drift detection — pass
  • Header rules - apexyard — pass
  • Redirect rules - apexyard — pass
  • netlify/apexyard/deploy-preview — pass
  • Pages changed - apexyard — skipping (status, not failure)

Pass.

/release-sync skill quality

Verified the cherry-picked skill at .claude/skills/release-sync/SKILL.md byte-identical to the version Rex approved on PR #406 at SHA 6e7f757 (blob SHA 168f032b… matches). Skill structure preserved: frontmatter (name, description, argument-hint, allowed-tools), Usage section, Process steps 1–6 (pre-flight, divergence check, backwards case, sync branch, -X ours merge with full rationale, PR creation), framework-only refusal, idempotent no-op exit 0, version-arg validation. Pass.

Skip markers

All 3 markers justified inline:

  • <!-- private-refs: allow -->apexscript token in yard.apexscript.com is the framework's own marketing domain; recurring false-positive on every v2.x.x release PR (matches the memory).
  • <!-- multi-close: approved --> — defensive habit for release PRs; only 1 Closes line here (#408); #403 + #404 already auto-closed on dev merges.
  • <!-- agdr: not-applicable --> — release PR is a pure version-cut; #403's AgDR-0052 already shipped in PR #406.

Pass.

Issues Found

None.

Suggestions

None — the release PR is mechanically clean and the cherry-picks are blob-identical for all core files. The 3 site files with auto-merged context are the expected behaviour and verified to only carry the substantive count deltas.

Verdict

APPROVED


Reviewed by Rex (Code Reviewer Agent)
Reviewed commit: 0dc52012e618d41bed226a9447854b152caa80fd

@atlas-apex atlas-apex merged commit fb861f4 into main May 25, 2026
9 checks passed
@atlas-apex atlas-apex deleted the release/v2.1.0 branch May 25, 2026 06:08
OmarElaraby26 pushed a commit to OmarElaraby26/apexyard that referenced this pull request May 27, 2026
* fix(me2resh#404): remove stale --pdf-output-folder flag from md-to-pdf dispatch (me2resh#405)

md-to-pdf removed --pdf-output-folder and --dest-name in a breaking
API change; convert.sh still passed both flags, causing every
npx md-to-pdf invocation to abort with:

  ArgError: unknown or unexpected option: --pdf-output-folder

Fix: stage the source into a private temp dir under the desired output
stem (e.g. WORK/out.pdf → WORK/out.md), invoke `npx -y md-to-pdf
<tmp>.md`, then mv the resulting <tmp>.pdf to the requested TO_ABS.
md-to-pdf writes <basename>.pdf next to the source by default, so this
is compatible with every currently-released version.

The same fix is applied to the md-to-pdf-html branch (HTML → PDF
fallback), which had identical stale flags.

Adds regression test at .claude/skills/pdf/tests/test_md_to_pdf_fallback.sh
covering four cases: successful conversion, absence of the stale
--pdf-output-folder flag, absence of --dest-name, and custom output
path resolution. All four pass locally against the current npm latest.

Refs me2resh#404

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(me2resh#403): /release-sync — main→dev sync after each release (me2resh#406)

* feat(me2resh#403): /release-sync skill — main→dev sync after each release

Introduces the /release-sync skill to address squash-merge divergence
that accumulated across releases and produced 99 conflicts on the v2.0.0
release PR. After each release, /release-sync vX.Y.Z opens a sync PR
that merges upstream/main into upstream/dev with -X ours (dev wins on
conflicts), making the squash commit an ancestor of dev so future release
PRs only show genuinely-new commits.

- .claude/skills/release-sync/SKILL.md — new skill spec with pre-flight
  checks, idempotent no-op, edge-case table, and PR body template
- .claude/skills/release/SKILL.md — adds Step 9 (mandatory invoke of
  /release-sync) and updates Related section
- docs/agdr/AgDR-0052-release-sync-skill.md — records the design choice
  (explicit skill vs auto-invoke vs switch-to-merge-commit) and the
  merge-strategy direction reasoning (-X ours on a dev-based branch)
- .claude/hooks/tests/test_release_sync.sh — 11 sandbox-based smoke
  tests covering already-in-sync no-op, diverged detection, branch name
  shape, -X ours direction, idempotence, post-sync state, and version
  argument validation; all 11 pass

Refs me2resh#403

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(me2resh#403): refresh site skill-count (54→55) + 2 MD032 lint fixes

Address red CI on Rex-approved release-sync PR:

- site-counts drift: new /release-sync skill bumps total to 55. Update
  all 12 marketing-copy references across architecture.html, *.md.gen,
  llms.txt, llms-full.txt, skill.md (incl. 2 multiline / phrasing-variant
  references caught by the post-me2resh#377 cross-newline scanner).
- markdownlint MD032: add blank lines around the bullet lists in
  release-sync SKILL.md (line 80) and AgDR-0052 (line 36).

Refs me2resh#403

---------

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(me2resh#408): CHANGELOG v2.1.0 + site version pill bump

- Append [2.1.0] section above [2.0.2]
- Bump site/index.html version pill v2.0.2 → v2.1.0
- Last cherry-pick release; /release-sync now live for v2.2.x+

Refs me2resh#408

---------

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
mosta7il pushed a commit to mosta7il/apexyard that referenced this pull request Jun 8, 2026
* fix(me2resh#404): remove stale --pdf-output-folder flag from md-to-pdf dispatch (me2resh#405)

md-to-pdf removed --pdf-output-folder and --dest-name in a breaking
API change; convert.sh still passed both flags, causing every
npx md-to-pdf invocation to abort with:

  ArgError: unknown or unexpected option: --pdf-output-folder

Fix: stage the source into a private temp dir under the desired output
stem (e.g. WORK/out.pdf → WORK/out.md), invoke `npx -y md-to-pdf
<tmp>.md`, then mv the resulting <tmp>.pdf to the requested TO_ABS.
md-to-pdf writes <basename>.pdf next to the source by default, so this
is compatible with every currently-released version.

The same fix is applied to the md-to-pdf-html branch (HTML → PDF
fallback), which had identical stale flags.

Adds regression test at .claude/skills/pdf/tests/test_md_to_pdf_fallback.sh
covering four cases: successful conversion, absence of the stale
--pdf-output-folder flag, absence of --dest-name, and custom output
path resolution. All four pass locally against the current npm latest.

Refs me2resh#404

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(me2resh#403): /release-sync — main→dev sync after each release (me2resh#406)

* feat(me2resh#403): /release-sync skill — main→dev sync after each release

Introduces the /release-sync skill to address squash-merge divergence
that accumulated across releases and produced 99 conflicts on the v2.0.0
release PR. After each release, /release-sync vX.Y.Z opens a sync PR
that merges upstream/main into upstream/dev with -X ours (dev wins on
conflicts), making the squash commit an ancestor of dev so future release
PRs only show genuinely-new commits.

- .claude/skills/release-sync/SKILL.md — new skill spec with pre-flight
  checks, idempotent no-op, edge-case table, and PR body template
- .claude/skills/release/SKILL.md — adds Step 9 (mandatory invoke of
  /release-sync) and updates Related section
- docs/agdr/AgDR-0052-release-sync-skill.md — records the design choice
  (explicit skill vs auto-invoke vs switch-to-merge-commit) and the
  merge-strategy direction reasoning (-X ours on a dev-based branch)
- .claude/hooks/tests/test_release_sync.sh — 11 sandbox-based smoke
  tests covering already-in-sync no-op, diverged detection, branch name
  shape, -X ours direction, idempotence, post-sync state, and version
  argument validation; all 11 pass

Refs me2resh#403

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(me2resh#403): refresh site skill-count (54→55) + 2 MD032 lint fixes

Address red CI on Rex-approved release-sync PR:

- site-counts drift: new /release-sync skill bumps total to 55. Update
  all 12 marketing-copy references across architecture.html, *.md.gen,
  llms.txt, llms-full.txt, skill.md (incl. 2 multiline / phrasing-variant
  references caught by the post-me2resh#377 cross-newline scanner).
- markdownlint MD032: add blank lines around the bullet lists in
  release-sync SKILL.md (line 80) and AgDR-0052 (line 36).

Refs me2resh#403

---------

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(me2resh#408): CHANGELOG v2.1.0 + site version pill bump

- Append [2.1.0] section above [2.0.2]
- Bump site/index.html version pill v2.0.2 → v2.1.0
- Last cherry-pick release; /release-sync now live for v2.2.x+

Refs me2resh#408

---------

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Chore] Cut v2.1.0 release

2 participants