Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .codearbiter/.provenance/release-targets.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"entries": [
{
"drift_trigger": true,
"hash": "a39e18a12f1a3aefaebd5ac80b5519711d6aba84",
"hash": "7933577b4e8985942aed6caf2f859c121c57f7d0",
"path": "CHANGELOG.md"
},
{
Expand Down Expand Up @@ -64,7 +64,7 @@
},
{
"drift_trigger": true,
"hash": "8c98f20f9e4de1cdec10d6f99922e520347a3ba9",
"hash": "f963449c0e51f52a78ee77afa03315471dae0be7",
"path": "plugins/ca/.claude-plugin/plugin.json"
},
{
Expand Down
33 changes: 21 additions & 12 deletions .github/scripts/test_release_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@
two-manifest ca-pi shape, the three behaviors most
likely to drift in a migration.

Pre-change SHA (T-27b): `6a903e6` — the parent of `0664506` (the commit that
performed the mechanism split), i.e. the last commit at which
`.github/scripts/_releaselib.py` was still the ORIGINAL self-contained
module. Chosen over "origin/main's copy" because origin/main moves and a
SHA does not; pinning to the immediate pre-split commit is the tightest,
least-ambiguous "the module as it stood the moment before this migration
began" reference the spec's `git show <pre-change-sha>:...` instruction
asks for.
Pre-change SHA (T-27b): `469c2fb8` — the parent of `8ee5fe11` (the squash
merge that performed the mechanism split), i.e. the last reachable main
commit at which `.github/scripts/_releaselib.py` was still the ORIGINAL
self-contained module. Its module blob is byte-identical to the abandoned
feature-branch parent originally used here. Chosen over "origin/main's copy"
because origin/main moves and a SHA does not; pinning to the reachable
pre-merge commit is the tightest fresh-clone-safe reference the spec's
`git show <pre-change-sha>:...` instruction asks for.

Honest limit (stated once here, per the spec's own wording, rather than
repeated at every call site): `.github/scripts/_releaselib.py` at the
Expand Down Expand Up @@ -151,9 +151,9 @@
REPO_ROOT = os.path.dirname(os.path.dirname(HERE))
FIXTURE_DIR = os.path.join(HERE, "fixtures", "release-trace")

# T-27b: the parent of 0664506 (the mechanism-split commit) — see module
# docstring for why this SHA rather than "origin/main's copy" was chosen.
PRE_CHANGE_SHA = "6a903e6"
# T-27b: the parent of 8ee5fe11 (the mechanism-split squash merge) — see
# the module docstring for why this reachable SHA was chosen.
PRE_CHANGE_SHA = "469c2fb8"

CORE_RELEASELIB_PATH = os.path.join(REPO_ROOT, "core", "pysrc", "_releaselib.py")
SHIM_RELEASELIB_PATH = os.path.join(REPO_ROOT, ".github", "scripts", "_releaselib.py")
Expand Down Expand Up @@ -182,7 +182,7 @@ def setUpModule():
if not has_commit or not has_tags:
missing = []
if not has_commit:
missing.append(f"commit {PRE_CHANGE_SHA} is unreachable (shallow history)")
missing.append(f"commit {PRE_CHANGE_SHA} is unreachable from this checkout")
if not has_tags:
missing.append("no tags are present")
raise RuntimeError(
Expand Down Expand Up @@ -429,6 +429,15 @@ def test_old_lane_loads_the_pinned_pre_change_module(self):
"ca-sandbox": "ca-sandbox-v", "ca-pi": "ca-pi-v"})
self.assertTrue(callable(self.old_lane.last_tag_select))

def test_pinned_pre_change_commit_is_reachable_from_head(self):
result = subprocess.run(
["git", "merge-base", "--is-ancestor", PRE_CHANGE_SHA, "HEAD"],
cwd=REPO_ROOT, capture_output=True, text=True, timeout=30)
self.assertEqual(
result.returncode, 0,
f"{PRE_CHANGE_SHA} is not reachable from HEAD; a fresh full-history "
"checkout cannot load the pinned pre-change module")

def test_old_lane_loads_a_genuinely_historical_snapshot(self):
# Proves this is really pinned to git history and not accidentally
# reading the live (now-converted) shim: the pre-change source must
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ predate the plugin rewrite and are grouped by date.

## [Unreleased]

## [2.11.1] — 2026-08-03

### Fixed

- Restored fresh-clone release-trace verification by pinning its historical
reference to the reachable pre-migration commit with the same release-library
bytes.
- Stabilized repeated statusline-render tests by isolating their unrelated
repository-dirty probes.
- Kept the landing page's guarantee cards aligned by resetting inherited
sibling-flow spacing at the card boundary.

## [2.11.0] — 2026-07-31

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ project context. You decide. codeArbiter enforces.
<img alt="Claude Code plugin" src="https://img.shields.io/badge/Claude_Code-plugin-d97757">
<img alt="Codex plugin" src="https://img.shields.io/badge/OpenAI_Codex-plugin-10a37f">
<img alt="Pi Feature Forge preview" src="https://img.shields.io/badge/ca--pi-Feature_Forge_preview-d97757">
<img alt="version 2.11.0" src="https://img.shields.io/badge/version-2.11.0-2b7489">
<img alt="version 2.11.1" src="https://img.shields.io/badge/version-2.11.1-2b7489">
<img alt="commands" src="https://img.shields.io/badge/commands-40-555">
<img alt="skills" src="https://img.shields.io/badge/skills-23-555">
<img alt="agents" src="https://img.shields.io/badge/agents-28-555">
Expand Down
2 changes: 1 addition & 1 deletion plugins/ca/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ca",
"displayName": "codeArbiter",
"description": "Orchestration layer for Claude Code. Routes every intent through gated skills and reviewer agents, drives spec-driven TDD, mechanically enforces the commit and audit-trail gates, decides via SMARTS, and keeps an append-only audit trail. Requires Python 3 on PATH. Dormant until you opt a repo in; run /ca:init to activate.",
"version": "2.11.0",
"version": "2.11.1",
"author": { "name": "arbiterForge" },
"license": "AGPL-3.0-only",
"homepage": "https://github.com/arbiterForge/codeArbiter",
Expand Down
26 changes: 14 additions & 12 deletions plugins/ca/hooks/tests/test_colorlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,18 +241,19 @@ def test_failed_custom_theme_projects_effective_violet_and_legacy_bytes(self):
with open(cases["oversized"], "wb") as handle:
handle.write(b" " * (_colorlib.MAX_THEME_BYTES + 1))

with mock.patch.dict(os.environ, {"CODEARBITER_THEME": "violet"}):
violet = sl.render(payload)

for label, path in cases.items():
with self.subTest(case=label), mock.patch.dict(
os.environ, {"CODEARBITER_THEME": "custom",
"CODEARBITER_THEME_FILE": path}):
rendered = sl.render(payload)
self.assertEqual(rendered, violet)
self.assertEqual(sl._colorlib.ACTIVE_THEME_NAME, "violet")
self.assertIn(sl.fg(90, 60, 150), rendered)
self.assertIn(sl.fg(170, 110, 240), rendered)
with mock.patch.object(sl, "git_dirty", return_value=True):
with mock.patch.dict(os.environ, {"CODEARBITER_THEME": "violet"}):
violet = sl.render(payload)

for label, path in cases.items():
with self.subTest(case=label), mock.patch.dict(
os.environ, {"CODEARBITER_THEME": "custom",
"CODEARBITER_THEME_FILE": path}):
rendered = sl.render(payload)
self.assertEqual(rendered, violet)
self.assertEqual(sl._colorlib.ACTIVE_THEME_NAME, "violet")
self.assertIn(sl.fg(90, 60, 150), rendered)
self.assertIn(sl.fg(170, 110, 240), rendered)

def test_valid_partial_custom_keeps_custom_as_effective_theme(self):
with tempfile.TemporaryDirectory() as tmp:
Expand Down Expand Up @@ -322,6 +323,7 @@ def counted_read(path):
reads += 1
return real_read(path)
sl._colorlib._read_custom = counted_read
sl.git_dirty = lambda _root: True
out = sl.render(payload)
again = sl.render(payload)
if reads != 2:
Expand Down
5 changes: 3 additions & 2 deletions plugins/ca/hooks/tests/test_statusline.py
Original file line number Diff line number Diff line change
Expand Up @@ -825,8 +825,9 @@ def test_render_is_deterministic_for_same_input(self):
"context_window_size": 200000},
"cost": {"total_cost_usd": 1.23},
})
a = sl.render(payload)
b = sl.render(payload)
with mock.patch.object(sl, "git_dirty", return_value=True):
a = sl.render(payload)
b = sl.render(payload)
self.assertEqual(a, b)

def test_ledger_functions_reachable_via_statusline(self):
Expand Down
1 change: 1 addition & 0 deletions site/src/styles/landing.css
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ ca-splash-docs {

.ca-feature {
position: relative;
margin-block-start: 0;
padding: var(--ca-space-6);
}

Expand Down
6 changes: 6 additions & 0 deletions site/test/landing/landing-page.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ describe("first-class product splash", () => {
expect(indexMdx).toContain("./guides/uninstalling/");
});

it("keeps every guarantee card aligned despite Starlight's sibling flow spacing", () => {
expect(landingCss).toMatch(
/\.ca-feature\s*\{[^}]*margin-block-start:\s*0;/s,
);
});

it("uses page-relative internal links instead of a hardcoded deployment base", () => {
expect(indexMdx).not.toMatch(/href="\/codeArbiter/);
expect(indexMdx).toMatch(/href="\.\/getting-started\/install\//);
Expand Down
Loading