Skip to content

Commit dea91be

Browse files
committed
docs: code→docs sync for the 2026.7.0 parity release
Reconcile documentation with the release changes (doc-sync, code-to-docs): - README: runtime-compat matrix now reflects the current-only e2e leg (prior-runtime leg removed, #127), M148 badge, 2026.7.x current row; dropped the dead pruned-runtime link + false backwards-compat-CI claim. - ADR-003 + SAD: Docker fallback documented as opt-in (CARBONYL_ALLOW_DOCKER) and digest-pinned (was described as automatic/un-pinned). - ADR-004: "No SHA256 verification (known gap)" → resolved (_verify_checksum); LATEST_TAG sentinel reference corrected. - ADR-005 + pyproject comment: MIT/Apache framing → GPL-3.0 wreq-util is AGPL-compatible (GPLv3 §13), aggregated in THIRD_PARTY_LICENSES.txt (#99); #100 tracks removal. - SAD references ADR-001..005; ci-cd-scaffold nightly-E2E marked implemented; release-runbook reconciled SemVer examples → CalVer. Audit + deferred items: .aiwg/reports/doc-sync-audit-2026-07-04.md. Docs only; no code logic changed (pyproject edit is a comment).
1 parent b29e7eb commit dea91be

11 files changed

Lines changed: 83 additions & 20 deletions

.aiwg/.last-doc-sync

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2026-07-04T20:33:54Z

.aiwg/architecture/adr-003-runtime-binary-discovery-order.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ The SDK must pick one deterministically on every invocation. Consumers need pred
2525
1. **`CARBONYL_BIN` environment variable** — explicit path override. Checked first. Must point to an executable file.
2626
2. **`~/.local/share/carbonyl/bin/<triple>/carbonyl`** — the installed location written by `carbonyl-agent install` (install.py lines 60–115). `<triple>` is computed by `_platform_triple()` (e.g. `x86_64-unknown-linux-gnu`, `aarch64-apple-darwin`).
2727
3. **`carbonyl` on `$PATH`** — resolved via `which carbonyl`. Honors any manual installation the user has done.
28-
4. **Docker fallback** — if steps 1–3 all return `None`, `open()` constructs a `docker run --rm -it ghcr.io/jmagly/carbonyl ...` command line and spawns that through pexpect instead (browser.py lines 227–248).
28+
4. **Docker fallback (opt-in)** — if steps 1–3 all return `None` **and `CARBONYL_ALLOW_DOCKER=1` is set**, `open()` spawns the **digest-pinned** `docker run --rm -it ghcr.io/jmagly/carbonyl@sha256:… ...` through pexpect; without the opt-in env var it raises (browser.py:461–482).
2929

3030
## Consequences
3131

3232
### Positive
3333

3434
- **Explicit override always wins**: Setting `CARBONYL_BIN=/path/to/custom` is the escape hatch for CI, local development of the upstream Carbonyl binary, or testing patched builds. No flag juggling required.
3535
- **Installer path takes precedence over `$PATH`**: If the user runs `carbonyl-agent install`, that binary is used even if a different Carbonyl is on `$PATH`. This avoids surprise version skew when `pip install -U carbonyl-agent && carbonyl-agent install` bumps the runtime.
36-
- **Graceful first-run experience**: A developer who never runs the installer but has Docker available still gets a working `CarbonylBrowser` the SDK transparently shells out to `docker run ghcr.io/jmagly/carbonyl`. This is important for smoke tests and README snippets.
36+
- **Graceful first-run experience**: A developer who never runs the installer but has Docker available can still get a working `CarbonylBrowser` by opting in with `CARBONYL_ALLOW_DOCKER=1`; the SDK then shells out to the digest-pinned `ghcr.io/jmagly/carbonyl@sha256:…` image. This is useful for smoke tests and README snippets.
3737
- **`LD_LIBRARY_PATH` is scoped**: When a local binary is used, the SDK sets `LD_LIBRARY_PATH=<binary_dir>` (browser.py line 217) so the adjacent `libcarbonyl.so` resolves without requiring `ldconfig` or system-wide `.so` placement.
3838

3939
### Negative

.aiwg/architecture/adr-004-gitea-release-runtime-distribution.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ Tag resolution supports a `runtime-latest` alias resolved via the Gitea API (`/a
5252

5353
### Negative
5454

55-
- **No SHA256 verification (known gap)**: `cmd_install` currently trusts HTTPS + the Gitea server. An attacker who compromised the Gitea instance or performed a TLS MITM could substitute a malicious binary, and the installer would extract it silently. This is documented in SAD §11 and the intake form. Mitigation plan: publish a signed `SHA256SUMS` manifest per release and verify before extraction.
55+
- **SHA256 verification (resolved — was a known gap)**: `cmd_install` now downloads the per-asset `.sha256` / `SHA256SUMS` and verifies the tarball before extraction (`_verify_checksum`), with a `--checksum` pin override. The original gap (trusting HTTPS + the server alone, allowing a compromised host or TLS MITM to substitute a binary) is closed; SAD §11 #1 marks it Resolved.
5656
- **Gitea uptime is a hard dependency**: If `git.integrolabs.net` is down, `carbonyl-agent install` fails. Users can set `GITEA_BASE` to a mirror, but no mirror exists by default. A GitHub-releases fallback is a reasonable follow-up.
5757
- **Public discoverability is limited**: Gitea releases are not indexed in the same way as PyPI or GitHub. First-time users must read the README to discover the install step.
58-
- **"Latest" resolution is dynamic**: `_resolve_tag` queries the Gitea API at install time, so reproducible installs require pinning a specific `runtime-<hash>` tag in CI. `LATEST_TAG = "runtime-latest"` (install.py line 31) is a sentinel, not a pinned version.
58+
- **"Latest" resolution is dynamic**: `_resolve_tag` queries the Gitea API at install time, so reproducible installs require pinning a specific `runtime-<hash>` tag in CI. `LATEST_TAG = runtime_pin.LATEST_SENTINEL` (install.py) is a sentinel, not a pinned version.
5959
- **Docker fallback becomes the safety net**: Users who can't reach Gitea can still smoke-test via the Docker image (see ADR-003), which somewhat softens the availability concern but does not replace a proper install.
6060

6161
### Neutral

.aiwg/architecture/adr-005-tls-fingerprint-http-client.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ The fallback path preserves Phase 1 behavior exactly so the rollback story is "u
119119
### Neutral
120120

121121
- The trait surface lives in `carbonyl-fingerprint` (W3A, #43); `wreq` integration code lives in W3B (#44). Layout is independent of this ADR.
122-
- License compatibility: MIT/Apache-2.0 dual is compatible with the project's downstream usage. No license escape hatch needed.
122+
- License compatibility: the `wreq` stack transitively pulls in GPL-3.0 `wreq-util`. The project is AGPL-3.0-only, and GPLv3 §13 makes GPL-3.0 and AGPL-3.0 compatible (attribution required, aggregated in `THIRD_PARTY_LICENSES.txt`; #99). #100 tracks replacing `wreq-util` with an in-house preset registry.
123123

124124
## Alternatives Considered
125125

.aiwg/architecture/software-architecture-doc.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ The architecture described here covers only the Python automation layer: the `ca
3030
- `README.md`, `CLAUDE.md`, `pyproject.toml`
3131
- `.aiwg/intake/project-intake.md`
3232
- Source tree: `src/carbonyl_agent/` (browser.py, daemon.py, session.py, screen_inspector.py, install.py)
33-
- ADR-001 through ADR-004 (this directory)
33+
- ADR-001 through ADR-005 (this directory)
3434
- Upstream: `roctinam/carbonyl` (Chromium fork + Rust FFI)
3535

3636
---
@@ -46,7 +46,7 @@ The architecture described here covers only the Python automation layer: the `ca
4646
| G5 | **Zero binary modifications** | The SDK must drive the upstream Carbonyl binary as-is, without patches or rebuilds. Decouples SDK releases from Chromium release cycles. |
4747
| G6 | **Local-only execution boundary** | The daemon is strictly local; authentication relies on filesystem permissions of the Unix socket. |
4848
| G7 | **Supply-chain integrity** | Runtime binary is downloaded over HTTPS from Gitea releases (install.py line 24). SHA256 checksum verification is enforced before extraction (install.py `_verify_checksum`). |
49-
| G8 | **Graceful fallback** | When no local binary is installed, fall back to Docker (`ghcr.io/jmagly/carbonyl`) so first-time users can smoke-test without the installer (browser.py lines 227–248). |
49+
| G8 | **Graceful fallback** | When no local binary is installed and `CARBONYL_ALLOW_DOCKER=1` is set, fall back to the digest-pinned `ghcr.io/jmagly/carbonyl@sha256:…` image so first-time users can opt in to a smoke-test without the installer (browser.py:461–482). |
5050

5151
---
5252

.aiwg/deployment/ci-cd-scaffold.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,5 +188,6 @@ Full procedure lives in `release-runbook.md`. Pre-flight: CI green on `main`, `C
188188

189189
- SLSA provenance via `pypa/gh-action-pypi-publish` attestations.
190190
- Sigstore signing of wheels.
191-
- Nightly E2E job against pinned Carbonyl runtime tags.
192191
- Publish coverage to Codecov / Coveralls for historical tracking.
192+
193+
(The nightly E2E job against the pinned Carbonyl runtime is now implemented — `.gitea/workflows/e2e.yml` runs on a `0 7 * * *` cron.)

.aiwg/deployment/release-runbook.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Complete **all** items before tagging. Check off as you go.
6666
- [ ] `main` branch CI is green on Gitea **and** GitHub for the latest commit
6767
- [ ] All iteration stories for this release are merged and closed
6868
- [ ] `CHANGELOG.md` has a finalized section for the new version (move items out of `Unreleased`, add release date, preserve Keep-a-Changelog format)
69-
- [ ] `pyproject.toml` `version` field bumped (semver: PATCH for bugfix, MINOR for additive, MAJOR for breaking)
69+
- [ ] `pyproject.toml` `version` field bumped (CalVer `YYYY.M.PATCH`, no leading zeros — reset PATCH to 0 on a new `YYYY.M`, else increment PATCH; see docs/versioning.md)
7070
- [ ] `README.md` install and quick-start examples verified in a fresh venv
7171
- [ ] All ADRs reflect the shipped design; no pending ADRs in `drafts/`
7272
- [ ] `.aiwg/security/threat-model.md` reviewed; no HIGH unmitigated items unless explicitly accepted
@@ -89,8 +89,8 @@ git checkout main
8989
git pull origin main
9090
git status # must be clean
9191

92-
# Tag
93-
VERSION="0.1.0"
92+
# Tag (project uses CalVer: YYYY.M.PATCH, no leading zeros — see docs/versioning.md)
93+
VERSION="2026.7.0"
9494
git tag -a "v${VERSION}" -m "carbonyl-agent v${VERSION}"
9595

9696
# Push to Gitea (origin) first
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Doc-Sync Audit — 2026-07-04 (code→docs)
2+
3+
**Direction:** code-to-docs (code is source of truth).
4+
**Scope:** docs that reflect the 2026.7.0 parity-release code/config changes
5+
(runtime pin, Docker fallback, license audit, CI workflows, version). Derived
6+
from `git diff b1baff0..HEAD`. Two bounded auditor lanes (architecture,
7+
deployment); detailed notes in `.aiwg/working/doc-sync/{architecture,deployment}-lane.md`.
8+
9+
## Applied (high-confidence, this pass)
10+
11+
| File | Fix |
12+
|------|-----|
13+
| `README.md` | Badge M147→M148; runtime-compat matrix: `2026.5.x``2026.7.x`, dropped the "current **and prior** runtimes" CI claim and the dead `runtime-dd69bef0ea4b2512` link + false backwards-compat-CI row → "Best-effort, not in CI (#127)" |
14+
| `pyproject.toml` | Wheel-attribution comment: "aggregates carbonyl-fingerprint only / GPL finding unresolved" → full-workspace incl. GPL-3.0 wreq-util (AGPL-compatible), #99 |
15+
| `adr-003` | Docker fallback described as automatic → **opt-in (`CARBONYL_ALLOW_DOCKER=1`) + digest-pinned** (step 4 + Positive "graceful first-run" bullet) |
16+
| `adr-004` | "No SHA256 verification (known gap)" → **Resolved** (`_verify_checksum` verifies before extraction); `LATEST_TAG = "runtime-latest" (line 31)``runtime_pin.LATEST_SENTINEL` |
17+
| `adr-005` | "MIT/Apache-2.0 dual … no license escape hatch" → GPL-3.0 `wreq-util` is AGPL-compatible (GPLv3 §13), aggregated in `THIRD_PARTY_LICENSES.txt` (#99); #100 tracks removal |
18+
| `software-architecture-doc.md` | References "ADR-001 through ADR-004" → ADR-005; G8 Docker fallback → opt-in + digest |
19+
| `ci-cd-scaffold.md` | Nightly E2E moved from "Future Enhancements" → noted implemented (`e2e.yml` cron) |
20+
| `release-runbook.md` | §1 version-bump note + §2 tag example: SemVer (`0.1.0`) → **CalVer** (`2026.7.0`, `YYYY.M.PATCH`) |
21+
22+
## Deferred (human-review / not auto-fixed)
23+
24+
- **SAD G1/G3 "Python-only surface / no compiled extensions / only pexpect+pyte"**
25+
flagged as drifting, but **still correct for the current wheel**: the native
26+
`carbonyl_wreq` module is dev-only and does not ship in the wheel until #88
27+
lands. Revisit when #88 bundles the cdylib. (MEDIUM)
28+
- **adr-004 Decision section** ("hosted on Gitea releases … downloaded") — now
29+
GitHub-assets-first with Gitea fallback (install.py) + semantic default tag.
30+
Core Gitea-distribution decision still holds; the GitHub-first primary is an
31+
additive later change. Worth a follow-up ADR note rather than an inline rewrite
32+
of the historical decision. (MEDIUM)
33+
- **adr-003:42 / SAD line refs** (`browser.py 227–248``~461–482`) — line-number
34+
drift only. (MEDIUM, low value)
35+
- **adr-005:51/53 library table** — could footnote that `wreq`'s own MIT/Apache
36+
license omits the GPL-3.0 `wreq-util` transitive (the :122 Neutral bullet now
37+
covers it). (MEDIUM)
38+
- **adr-005:94 "Chrome 147" fixture reference** — persona corpus is Chrome 148;
39+
verify against the Layer-2 test crate before editing (fixture may intentionally
40+
lag the runtime). (LOW-MEDIUM)
41+
- **adr-004:26 "v0.1.0, single maintainer"** project-stage marker. (LOW)
42+
43+
## Verified clean (NOT stale)
44+
45+
- No `fathyb/carbonyl` in any architecture/deployment doc except the intended
46+
historical README acknowledgment.
47+
- No reference to the old runtime hash `8f070d2720157bd0` in any doc.
48+
- No MIT-vs-GPL "wheel conflict" framing remains in the audited docs (the stale
49+
pyproject comment was the last one — now fixed).
50+
51+
## Validation
52+
- `git diff --stat` bounded to the doc files above; no code touched.
53+
- Auditors ran read-only; fixes applied by the orchestrator.

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,14 @@ clears the third-party license attribution release-blocker.
7575
`.aiwg/reports/carbonyl-parity-audit-2026-07-04.md` covering the runtime pin,
7676
trusted-input FFI gaps, distribution drift, and the outstanding backlog.
7777

78-
### Deferred
78+
### Docs
79+
80+
- Code→docs reconciliation (doc-sync): README runtime-compat matrix + M148 badge
81+
updated (dropped the removed prior-runtime CI claim, #127); ADR-003/SAD Docker
82+
fallback documented as opt-in (`CARBONYL_ALLOW_DOCKER`) + digest-pinned; ADR-004
83+
SHA256 "known gap" marked resolved; ADR-005 + pyproject license notes updated to
84+
the AGPL/GPL-3.0-compatible posture (#99); release-runbook + ci-cd-scaffold
85+
reconciled to CalVer and current CI. Audit: `.aiwg/reports/doc-sync-audit-2026-07-04.md`.
7986

8087
- **GPG release-signature verification** in `install.py` (upstream added
8188
per-asset GPG signatures in carbonyl alpha.15) is deferred to a tracked

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ carbonyl-agent install
1919

2020
[![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-blue.svg?style=flat-square)](LICENSE)
2121
[![Python](https://img.shields.io/badge/python-3.11%2B-blue?style=flat-square&logo=python&logoColor=white)](pyproject.toml)
22-
[![Carbonyl M147](https://img.shields.io/badge/carbonyl-M147-green?style=flat-square)](https://git.integrolabs.net/roctinam/carbonyl)
22+
[![Carbonyl M148](https://img.shields.io/badge/carbonyl-M148-green?style=flat-square)](https://git.integrolabs.net/roctinam/carbonyl)
2323

2424
[![Built With AIWG](https://aiwg.io/assets/badges/built-with-aiwg-dark.png)](https://aiwg.io)
2525

@@ -574,12 +574,12 @@ unreachable.
574574

575575
### Runtime compatibility matrix (#21, #92)
576576

577-
Each `carbonyl-agent` release pins a Carbonyl runtime hash. CI runs the full E2E suite (`tests/e2e/`) against the current and prior runtimes so SDK-vs-runtime drift is caught before it reaches users.
577+
Each `carbonyl-agent` release pins a Carbonyl runtime. CI runs the full E2E suite (`tests/e2e/`) against the current pinned runtime so SDK-vs-runtime drift is caught before it reaches users. (A prior-runtime regression leg was removed as chronically unreliable — see #127.)
578578

579-
| `carbonyl-agent` | Runtime hash | Carbonyl release | CI status |
579+
| `carbonyl-agent` | Runtime | Carbonyl release | CI status |
580580
|---|---|---|---|
581-
| `2026.5.x` (current) | [`v0.2.0-alpha.17`](https://github.com/jmagly/carbonyl/releases/tag/v0.2.0-alpha.17) | v0.2.0-alpha.17 (M148) | **Supported** — default for `carbonyl-agent install` |
582-
| `2026.4.x` and earlier | [`runtime-dd69bef0ea4b2512`](https://github.com/jmagly/carbonyl/releases/tag/runtime-dd69bef0ea4b2512) | v0.2.0-alpha.3 (M147) | **Backwards-compat tested**CI verifies SDK still works against it |
581+
| `2026.7.x` (current) | [`v0.2.0-alpha.17`](https://github.com/jmagly/carbonyl/releases/tag/v0.2.0-alpha.17) | v0.2.0-alpha.17 (M148) | **Supported** — default for `carbonyl-agent install` |
582+
| `2026.4.x` and earlier | older `v0.2.0-alpha.*` tags | v0.2.0-alpha.3 (M147) and earlier | **Best-effort**no longer exercised in CI (#127) |
583583
| any | older `runtime-*` tags | various | Best-effort; not in CI |
584584

585585
The canonical runtime tag list lives at [github.com/jmagly/carbonyl/releases](https://github.com/jmagly/carbonyl/releases) (mirror: [git.integrolabs.net/roctinam/carbonyl](https://git.integrolabs.net/roctinam/carbonyl)). The current pin for this checkout is in [`.carbonyl-runtime-version`](.carbonyl-runtime-version).

0 commit comments

Comments
 (0)