Skip to content

Commit caf7d90

Browse files
feat(ga): v0.10.0 install-path RC — smoke CI, Codex re-pin 0.144.5, release guards, capability matrix, evidence bundle
- install-smoke-claude.yml: real marketplace install + headless /add:init (AC-022) - install-smoke-codex.yml + tests/smoke/codex/: pinned-CLI Docker smoke, verified green locally against 0.144.5 (AC-023/AC-035, Q-001 retired) - release.sh: refuse to tag unless HEAD CI green (--no-verify-ci override); capability matrix appended to every release's notes - docs/capability-matrix.md + SECURITY.md per-runtime enforcement pointer (AC-027) - scripts/release-evidence.sh: AC-025 bundle w/ migration-graph reachability check - fix(migrations): add 0.7.3→0.8.0 hop — 0.7.3 users were stranded (found by the new reachability check; same class as the v0.8.1→v0.9.3 incident) - D6/Q-MS-003: telemetry emission confirmed absent; finding recorded, fix deferred - milestone: D8 consolidation + submit-before-promote sequencing recorded Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent fdb6c3b commit caf7d90

21 files changed

Lines changed: 919 additions & 5 deletions

File tree

.add/handoff.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,30 @@
1-
# Handoff — GA path spec'd: v0.10.0 install-path RC (updated 2026-07-18)
1+
# Handoff — v0.10.0 install-path RC IMPLEMENTED (updated 2026-07-18, PM)
2+
3+
## v0.10.0 implementation (2026-07-18, same-day follow-up to the spec)
4+
All sections of specs/install-path-confirmation.md implemented in one pass:
5+
- **Codex re-pin 0.122.0 → 0.144.5** (adapter.yaml; min stays 0.122.0). Smoke
6+
**passed locally in Docker** against the new pin — 27/27 skills, F-002 path
7+
suite, version parity. Q-001 retired.
8+
- **Smoke workflows** install-smoke-claude.yml (marketplace install from
9+
checkout + headless /add:init, needs ANTHROPIC_API_KEY secret) and
10+
install-smoke-codex.yml (tests/smoke/codex/ Docker, pin via build-arg,
11+
needs OPENAI_API_KEY for agent leg; layout asserts gate regardless).
12+
**ACTION: add both secrets to repo settings** or agent legs skip w/ warning.
13+
- **release.sh**: CI-green guard (refuses tag unless HEAD checks green;
14+
--no-verify-ci override) + appends capability matrix to release notes.
15+
- **docs/capability-matrix.md** + SECURITY.md pointer (AC-027 done).
16+
- **scripts/release-evidence.sh** (AC-025) — first run CAUGHT A REAL BUG:
17+
migrations.json had no hop out of 0.7.3 (stranded users). Fixed. Check is
18+
graph-reachability. Dogfood bundle at reports/release-evidence/v0.9.11/.
19+
- **D6 answered: telemetry does NOT emit** (.add/telemetry/ absent). Finding
20+
recorded milestone+CHANGELOG; fix deferred.
21+
- Milestone doc: D8 decision (v0.10/v0.11 consolidation, submit-before-promote),
22+
status updates. CHANGELOG [Unreleased] staged for v0.10.0.
23+
- Branch protection: runbook section added; apply after first CI runs (real
24+
check-run names) — enforce_admins false to keep direct-push flow.
25+
26+
Remaining before cutting v0.10.0: smoke workflows green in CI (add secrets),
27+
apply branch protection, promote CHANGELOG, then release + marketplace submit.
228

329
## GA review + v0.10.0 spec (2026-07-18)
430
Reviewed GA readiness against docs/milestones/v1.0-ga.md: criteria #6 met, #1/#4
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: Claude install smoke
2+
3+
# Real Claude Code install smoke (spec AC-001–AC-007, milestone AC-022).
4+
# Installs ADD through the actual marketplace path — `claude plugin marketplace
5+
# add <checkout>` + `claude plugin install add@add-marketplace` — so the commit
6+
# under test is what gets installed, then drives a headless session through
7+
# /add:init --quick in a scratch project.
8+
#
9+
# Auth (AC-007): the agent-driven leg needs ANTHROPIC_API_KEY. When the secret
10+
# is absent (fork PRs), the install/discovery assertions still run and gate;
11+
# the agent leg skips with a loud workflow warning.
12+
13+
on:
14+
pull_request:
15+
branches: [main]
16+
push:
17+
branches: [main]
18+
tags: ['v*']
19+
workflow_dispatch:
20+
21+
jobs:
22+
smoke:
23+
name: Claude install smoke
24+
runs-on: ubuntu-latest
25+
steps:
26+
- uses: actions/checkout@v5
27+
28+
- uses: actions/setup-node@v4
29+
with:
30+
node-version: '22'
31+
32+
- name: Install Claude Code CLI
33+
run: |
34+
npm install -g @anthropic-ai/claude-code
35+
claude --version
36+
37+
- name: Marketplace install from this checkout (AC-002)
38+
run: |
39+
claude plugin marketplace add "$GITHUB_WORKSPACE"
40+
claude plugin install add@add-marketplace
41+
42+
- name: Assert skill discovery (AC-004)
43+
run: |
44+
EXPECTED=$(find plugins/add/skills -maxdepth 1 -mindepth 1 -type d | wc -l | tr -d ' ')
45+
CACHE_DIR=$(find ~/.claude/plugins -type d -name skills -path '*add*' | head -1)
46+
if [ -z "$CACHE_DIR" ]; then
47+
echo "::error::installed plugin skills directory not found under ~/.claude/plugins"
48+
exit 1
49+
fi
50+
INSTALLED=$(find "$CACHE_DIR" -maxdepth 1 -mindepth 1 -type d | wc -l | tr -d ' ')
51+
echo "expected=$EXPECTED installed=$INSTALLED ($CACHE_DIR)"
52+
[ "$INSTALLED" = "$EXPECTED" ] || { echo "::error::skill count mismatch"; exit 1; }
53+
54+
- name: Agent-driven /add:init smoke (AC-003, AC-005)
55+
env:
56+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
57+
run: |
58+
if [ -z "$ANTHROPIC_API_KEY" ]; then
59+
echo "::warning title=Claude smoke partial::install/discovery assertions ran; agent-driven /add:init skipped (no ANTHROPIC_API_KEY — expected on fork PRs)"
60+
exit 0
61+
fi
62+
SCRATCH=$(mktemp -d)
63+
cd "$SCRATCH"
64+
git init -q
65+
set +e
66+
claude -p "/add:init --quick" \
67+
--permission-mode acceptEdits \
68+
--max-turns 30 \
69+
> "$SCRATCH/session.log" 2>&1
70+
STATUS=$?
71+
set -e
72+
echo "--- session tail ---"
73+
tail -40 "$SCRATCH/session.log"
74+
if [ ! -f .add/config.json ]; then
75+
echo "::error::/add:init --quick did not produce .add/config.json (claude exit $STATUS)"
76+
exit 1
77+
fi
78+
# No config schema exists in core/schemas yet (spec deviation, recorded
79+
# in specs/install-path-confirmation.md) — assert parse + key fields.
80+
python3 -c "import json,sys; c=json.load(open('.add/config.json')); sys.exit(0 if ('version' in c and 'maturity' in c) else 1)" \
81+
|| { echo "::error::.add/config.json missing version/maturity keys"; exit 1; }
82+
echo "PASS: .add/config.json produced and well-formed"
83+
# AC-005 (Should, non-blocking): SessionStart rule loading evidence.
84+
if grep -qi "add.*rules\|load-rules" "$SCRATCH/session.log"; then
85+
echo "PASS: rule-loading evidence found in session output"
86+
else
87+
echo "::warning::no rule-loading evidence in session output (AC-005 soft check)"
88+
fi
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Codex install smoke
2+
3+
# Real Codex CLI install smoke (spec AC-012–AC-016, milestone AC-023/AC-035).
4+
# Builds the pinned-CLI container (pin sourced from runtimes/codex/adapter.yaml —
5+
# single source of truth) and runs the same curl-installer path a user takes.
6+
#
7+
# Secrets: OPENAI_API_KEY enables the agent-driven /add-init leg. When absent
8+
# (fork PRs), layout assertions still run and gate; the agent leg skips with a
9+
# workflow warning (spec AC-007 pattern).
10+
11+
on:
12+
pull_request:
13+
branches: [main]
14+
push:
15+
branches: [main]
16+
tags: ['v*']
17+
workflow_dispatch:
18+
19+
jobs:
20+
smoke:
21+
name: Codex install smoke
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@v5
25+
26+
- name: Read Codex CLI pin from adapter.yaml
27+
id: pin
28+
run: |
29+
PIN=$(grep '^codex_cli_version' runtimes/codex/adapter.yaml | cut -d'"' -f2)
30+
if [ -z "$PIN" ]; then
31+
echo "::error::codex_cli_version not found in runtimes/codex/adapter.yaml"
32+
exit 1
33+
fi
34+
echo "version=$PIN" >> "$GITHUB_OUTPUT"
35+
echo "Pinned Codex CLI: $PIN"
36+
37+
- name: Build pinned-CLI image
38+
run: |
39+
docker build \
40+
--build-arg CODEX_CLI_VERSION="${{ steps.pin.outputs.version }}" \
41+
-t add-codex-smoke \
42+
tests/smoke/codex
43+
44+
- name: Run install smoke
45+
env:
46+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
47+
run: |
48+
docker run --rm \
49+
-v "$PWD":/work \
50+
-e OPENAI_API_KEY \
51+
add-codex-smoke \
52+
bash tests/smoke/codex/run-smoke.sh

CHANGELOG.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,26 @@ Hotfix. Fixes three findings from the plugin-family release-hardening review bef
138138

139139
## [Unreleased]
140140

141-
_(Nothing yet — tracking items go here between releases.)_
141+
**Pending for v0.10.0 — "install path confirmed" GA release candidate** (spec: `specs/install-path-confirmation.md`; sequencing: smoke green → marketplace submission → v1.0.0 promotion tag on approval).
142+
143+
### Added
144+
145+
- **Real install smoke in CI (GA criterion #2).** `.github/workflows/install-smoke-claude.yml` — installs the checkout via the actual marketplace path (`claude plugin marketplace add` + `claude plugin install add@add-marketplace`), asserts skill discovery, and drives a headless `/add:init --quick` asserting `.add/config.json` (agent leg skips loudly without `ANTHROPIC_API_KEY`). `.github/workflows/install-smoke-codex.yml` + `tests/smoke/codex/` — Docker image with the Codex CLI pinned from `runtimes/codex/adapter.yaml` (single source of truth via build-arg), runs `scripts/install-codex.sh` for real, asserts 27/27 skills, hooks, shared assets, version parity, the F-002 path suite, and (with `OPENAI_API_KEY`) an agent-driven `/add-init`.
146+
- **`docs/capability-matrix.md` (GA criterion #3 / AC-027).** Per-runtime enforced vs agent-followed vs advisory truth table, appended to every release's notes by `release.sh`; `SECURITY.md` now points at it before the threat model.
147+
- **`scripts/release-evidence.sh` (GA criterion #4 / AC-025).** Assembles `reports/release-evidence/vX.Y.Z/` — version map, capability-matrix snapshot, command catalog, install-smoke run links, and a migration-graph reachability check; `--upload` attaches the bundle to the GitHub release.
148+
149+
### Changed
150+
151+
- **Codex CLI re-pinned 0.122.0 → 0.144.5** (`codex_cli_version`; `min_codex_version` stays 0.122.0). Install smoke verified green in Docker against the new pin (Q-001 re-baseline).
152+
- **`release.sh` is now release-blocking (GA criterion #1).** Refuses to tag unless HEAD is on origin/main with all CI check-runs green; `--no-verify-ci` is the loud emergency override.
153+
154+
### Fixed
155+
156+
- **`migrations.json`: v0.7.3 users were stranded** — no outgoing hop existed from 0.7.3 (same class as the v0.8.1→v0.9.3 chain break). Caught by the new reachability check; fixed with a 0.7.3→0.8.0 hop carrying the standard 0.8.0 steps.
157+
158+
### Known limitations
159+
160+
- **Telemetry emission confirmed absent (Q-MS-003/D6).** `.add/telemetry/` never populates — the spec exists, no hook writes it. Recorded as a finding; implementation deferred past v0.10.0 (does not gate the six GA criteria).
142161

143162
## [0.9.5] — 2026-04-22
144163

SECURITY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ When you install ADD into a project-aware agent runtime, you are granting:
1313

1414
ADD does not call external APIs, does not transmit telemetry, and does not contain any compiled code. But a malicious change to an ADD rule or skill file can rewrite agent behavior as effectively as any exploit, because the runtime reads those files as instructions.
1515

16+
**Enforcement differs by runtime.** On Claude Code, ADD's defenses run as hooks the agent cannot skip (mechanical detection, warn-only response); on Codex CLI several of them are advisory or require user opt-in, and prompt-injection scanning is documentation-only. The authoritative per-runtime breakdown is [`docs/capability-matrix.md`](docs/capability-matrix.md) — read it before assuming a mitigation below applies to your runtime.
17+
1618
## Threat Model
1719

1820
| Threat | Likelihood | Impact | Mitigation |

core/templates/migrations.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,49 @@
201201
],
202202
"description": "Learnings optimization \u2014 v0.7.x projects hop directly to 0.8.0"
203203
},
204+
{
205+
"from": "0.7.3",
206+
"to": "0.8.0",
207+
"steps": [
208+
{
209+
"file": ".add/config.json",
210+
"action": "add_fields",
211+
"params": {
212+
"fields": {
213+
"learnings.active_cap": 15,
214+
"learnings.archival_days": 90,
215+
"learnings.archival_max_severity": "medium"
216+
}
217+
},
218+
"description": "Add configurable learnings thresholds (active view cap and archival age)"
219+
},
220+
{
221+
"file": ".add/learnings.json",
222+
"action": "run_hook",
223+
"params": {
224+
"script": "hooks/filter-learnings.sh",
225+
"args": [
226+
"{file}"
227+
],
228+
"notify": "Generated .add/learnings-active.md \u2014 agents now read this compact view instead of the full JSON (72% smaller)."
229+
},
230+
"description": "Generate pre-filtered active view of project learnings"
231+
},
232+
{
233+
"file": "~/.claude/add/library.json",
234+
"action": "run_hook",
235+
"params": {
236+
"script": "hooks/filter-learnings.sh",
237+
"args": [
238+
"{file}"
239+
],
240+
"notify": "Generated ~/.claude/add/library-active.md \u2014 compact cross-project learning view."
241+
},
242+
"description": "Generate pre-filtered active view of cross-project library"
243+
}
244+
],
245+
"description": "Learnings optimization \u2014 same steps as 0.7.0\u21920.8.0; closes the 0.7.3 dead-end found by the release-evidence chain check (v0.10.0)"
246+
},
204247
{
205248
"from": "0.8.0",
206249
"to": "0.8.1",

dist/codex/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ That script installs:
2626
- `min_codex_version = "0.122.0"` — the oldest Codex CLI that
2727
supports every feature ADD emits (native Skills, sub-agents, hooks, plugin
2828
marketplace).
29-
- `codex_cli_version = "0.122.0"` — the version ADD's CI
29+
- `codex_cli_version = "0.144.5"` — the version ADD's CI
3030
validates against.
3131

3232
**Differences from the Claude adapter:**

dist/codex/templates/migrations.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,49 @@
201201
],
202202
"description": "Learnings optimization \u2014 v0.7.x projects hop directly to 0.8.0"
203203
},
204+
{
205+
"from": "0.7.3",
206+
"to": "0.8.0",
207+
"steps": [
208+
{
209+
"file": ".add/config.json",
210+
"action": "add_fields",
211+
"params": {
212+
"fields": {
213+
"learnings.active_cap": 15,
214+
"learnings.archival_days": 90,
215+
"learnings.archival_max_severity": "medium"
216+
}
217+
},
218+
"description": "Add configurable learnings thresholds (active view cap and archival age)"
219+
},
220+
{
221+
"file": ".add/learnings.json",
222+
"action": "run_hook",
223+
"params": {
224+
"script": "hooks/filter-learnings.sh",
225+
"args": [
226+
"{file}"
227+
],
228+
"notify": "Generated .add/learnings-active.md \u2014 agents now read this compact view instead of the full JSON (72% smaller)."
229+
},
230+
"description": "Generate pre-filtered active view of project learnings"
231+
},
232+
{
233+
"file": "~/.claude/add/library.json",
234+
"action": "run_hook",
235+
"params": {
236+
"script": "hooks/filter-learnings.sh",
237+
"args": [
238+
"{file}"
239+
],
240+
"notify": "Generated ~/.claude/add/library-active.md \u2014 compact cross-project learning view."
241+
},
242+
"description": "Generate pre-filtered active view of cross-project library"
243+
}
244+
],
245+
"description": "Learnings optimization \u2014 same steps as 0.7.0\u21920.8.0; closes the 0.7.3 dead-end found by the release-evidence chain check (v0.10.0)"
246+
},
204247
{
205248
"from": "0.8.0",
206249
"to": "0.8.1",

docs/capability-matrix.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Per-Runtime Capability Matrix
2+
3+
**Spec:** `specs/install-path-confirmation.md` AC-030 (milestone AC-027, GA criterion #3)
4+
**Maintenance:** hand-maintained, verified against `runtimes/codex/adapter.yaml` truth
5+
on every release; included in release notes from v0.10.0 onward. If this table and
6+
`adapter.yaml` disagree, `adapter.yaml` wins — fix the table.
7+
8+
Legend — **Enforced**: the runtime mechanically applies it (hook/loader; the agent
9+
cannot silently skip it). **Agent-followed**: shipped as instructions the agent is
10+
expected to obey; no mechanical backstop. **Advisory**: documentation/patterns only.
11+
****: not available on that runtime.
12+
13+
| Capability | Claude Code | Codex CLI | Notes |
14+
|---|---|---|---|
15+
| Skills (27, namespaced) | Enforced (plugin loader) | Enforced (native Skills, `~/.codex/skills/add-*`) | Codex names use `/add-<name>`; Claude `/add:<name>` |
16+
| Install path | Marketplace (`claude plugin install add@add-marketplace`) | curl installer (`scripts/install-codex.sh`) | Both covered by CI install smoke as of v0.10.0 |
17+
| Auto-loaded rules, maturity-scaled | Enforced (SessionStart `load-rules.sh` physically loads the maturity-appropriate set) | Agent-followed (static slim manifest in `AGENTS.md`; maturity-loader rule read at runtime) | Codex has no session hook doing physical selection |
18+
| Stale-rule-copy detection | Enforced (per-session warning, v0.9.11) || Codex `AGENTS.md` merged at init can drift; check planned (`/add-version`), v1.1 candidate |
19+
| Hooks (learnings filter, CHANGELOG, autofix) | Enforced (PreToolUse / SessionStart) | Agent-followed→Enforced only if user enables `[features] codex_hooks = true`; hook stderr not surfaced to the agent (F-012) | Codex `hooks.json` merge is manual when one already exists |
20+
| Prompt-injection scanning | Enforced detection, warn-only response (PostToolUse scanner emits ADD-SEC warnings + audit events at `.add/security/injection-events.jsonl`; never blocks by design) | Advisory (pattern catalog ships at `~/.codex/add/security/`; no scanner hook, no audit events) | Per adapter.yaml truth-pass (v0.9.8); Codex parity revisits v1.1 |
21+
| Secrets scanning / redaction | Enforced in hook pipeline (`lib/scan-secrets.sh` via scanner + learnings filter) | Advisory (library + catalog ship; skills reference them, no hook auto-registration) | |
22+
| Sub-agents (test-writer, implementer, reviewer, explorer) | Enforced (Task tool dispatch) | Agent-followed (TOML defs; requires `[features] collab = true`) | |
23+
| Learnings persistence + active view | Enforced (`filter-learnings.sh` hook auto-registered) | Shipped but NOT auto-registered | Codex user must wire the hook manually |
24+
| Telemetry JSONL emission | Spec'd; emission verification tracked as D6 (see milestone) || Several PRD metrics depend on this |
25+
| Migrations (`migrations.json` hop chain) | Enforced via `/add:version` | Agent-followed via `/add-version` | Chain continuity checked by release-evidence script (v0.10.0) |
26+
| GPG-signed releases | n/a (repo-level) | n/a (repo-level) | All tags signed; see `docs/release-signing.md` |
27+
28+
**Pinned Codex CLI (CI target):** see `codex_cli_version` in `runtimes/codex/adapter.yaml`
29+
(0.144.5 as of v0.10.0; minimum supported: 0.122.0).
30+
31+
**Summary for release notes:** on Claude Code, ADD's quality gates are mechanically
32+
enforced by hooks; on Codex CLI they are agent-followed unless the user enables
33+
Codex hook features, and prompt-injection defense is advisory-only. Anything
34+
marked warn-only here is stated identically in `SECURITY.md`.

0 commit comments

Comments
 (0)