Skip to content

Releases: Cranot/roam-code

v13.2

16 May 14:33

Choose a tag to compare

What's Changed

  • wip: v13.2 session — Pattern-2c + evidence_stale arcs + CI hardening by @Cranot in #36

New Contributors

Full Changelog: v13.1...v13.2

v13.1 — Pattern-2 propagation + shared YAML helper + 3 flagship silent-fallback seals

15 May 17:37

Choose a tag to compare

PyPI: https://pypi.org/project/roam-code/13.1/
Install: `pip install roam-code==13.1`

See CHANGELOG.md for the full v13.1 release notes.

Highlights:

  • 3 flagship Pattern-2 silent-fallback bugs sealed (cmd_taint security-critical, cmd_health CI-gate-critical, cmd_doctor)
  • Shared YAML config-loader helper (load_yaml_with_warnings); 5 of 7 callsites migrated; net ~125 LOC removed
  • 5 new smell detectors (type-switch, speculative-generality, empty-catch, rename-invariant-clone, cross-layer-clone, parallel-hierarchy)
  • @detector registry consolidation (Gate-1 closure)
  • 14 cargo-cult `or ""` cleanups + 3 helpers None-guarded
  • 26 SQL LIKE wildcard patterns hardened with ESCAPE discipline
  • 30+ behavioral Pattern-2 fixes across alerts / smells / pr-risk / taint / health / doctor / suppression / sarif
  • Empty-corpus smoke sweep covering 25+ detectors

No persisted-data breaks. Hash-stability mandate held.

SBOM: CycloneDX 1.5 SBOM attached as `roam-code-13.1.cdx.json`.

v13.0 — Agent-OS substrate + Laravel idioms + Vue SFC

15 May 17:37

Choose a tag to compare

PyPI: https://pypi.org/project/roam-code/13.0/ — see CHANGELOG.md. SBOM backfilled 2026-05-15 (v13.0 release initially shipped without a GitHub Release object due to publish.yml bug fixed by W1047).

v12.47 — internal cleanup + anti-drift CI gates

08 May 03:34

Choose a tag to compare

[12.47] - 2026-05-08

Internal cleanup + anti-drift CI gates

A maintenance release that scrubs internal session shorthand from source
comments, docstrings, CHANGELOG entries, and template files; aligns
surface counts across documentation; and lands four CI gates that
prevent regression.

Anti-drift CI gates (new)

  • tests/test_no_internal_language.py — fails any commit that
    re-introduces 16 forbidden patterns: session-pass numbering, letter-
    coded date markers (R5/W3/X14/etc.), "Phase X of v2 monetization plan",
    internal-doc cross-references, dogfood-notes session markers, personal
    Windows paths, day-job customer names, claude-memory paths, the old
    cranot.github.io docs URL, CFO-objection sales-pitch language,
    Greek-vendor exclusion clauses.
  • scripts/sync_surface_counts.py — single source of truth via
    roam.surface_counts + roam.languages.registry. Dry-run reports
    drift; --write rewrites README + llms-install + server.json.
  • scripts/linkcheck.py — walks every tracked landing-page HTML and
    asserts every internal href + #anchor resolves. --external optional.
  • scripts/strip_metadata.py — scans every tracked PDF / PNG / SVG
    for identifying metadata; dry-run reports leaks, --write rewrites
    files with neutral metadata.
  • All four wired into .github/workflows/roam-ci.yml as a new
    doc-hygiene job that runs on every PR.

Source comments + tests

  • Bulk-scrubbed ~110 source files of internal session prefixes
    (numbered "Pass" comments, letter-coded date markers, "Phase-N
    polish", "Python-pivot dogfood" annotations).
  • cmd_audit.py + cmd_audit_trail_export.py + cmd_postmortem.py +
    cmd_article_12_check.py + cmd_permit.py docstrings rewritten as
    neutral product descriptions.
  • Restored if not include_tooling: guard + excluded_tooling = 0
    initializer + from roam.output.file_role_hints import is_excluded_path
    in cmd_smells.py (fixed an indentation regression caught by the
    test suite).
  • Renamed regression-FP corpus fixtures to neutral names; per-entry
    description prefixes scrubbed.

Documentation + product naming

  • Audit deliverable name reframed: "AI Agent Readiness Audit" →
    "PR Replay" on landing-page upsell + "Codebase Architecture Audit"
    on legal templates and the audit-report template/sample/PDF.
  • DPA + SOW master template generalized: dropped Stripe-Atlas /
    Greek-IKE entity-structure language; tier rows replaced with
    bracketed placeholders.
  • templates/legal/security-procurement-packet.md — links into
    docs/strategy/... replaced with public roam-code.com/pricing URL.
  • templates/email/customer-journey.md — hard-coded "— Dimitris"
    signature replaced with [YOUR_NAME] placeholder.
  • README + llms-install + server.json + mcp-server-card.json
    surface counts: 194 → 202 commands, 27 → 28 languages,
    5 → 6 cross-language bridges (Django bridge added).
  • Old cranot.github.io documentation URL replaced with
    roam-code.com/docs/ across 9 tracked files (config, source,
    tests, docs).

History rewrites

  • Six force-pushes during the cleanup sweep, each documented in the
    new internal/runbook-history-rewrite.md (gitignored). Removed from
    history: 27 strategic / internal docs (docs/strategy/*,
    docs/products/*, dev/REPORT-*.md, dev/CODE-BACKLOG.md,
    dev/COMPETITOR-WATCH-*.md, templates/distribution/landing-page-spec.md,
    Greek-vendor-exclusion templates), 5 session-named regression-FP
    fixtures (renamed to neutral corpus_*.json paths).
  • Author rewrite: 389 commits authored as "CosmoHac" + 11 commits
    authored as "Claude" rewritten to "Cranot" so GitHub Insights shows
    uniform attribution. Third-party contributors (Chuck Jewell, holive,
    Mark Ramsell, Livio Ravetto) untouched.

pyproject.toml

  • authors updated to Cranot (was CosmoHac).

v12.28 — detector quality round: 14 FP fixes + suppression mechanism

06 May 09:20

Choose a tag to compare

Patch on top of 12.27

Detector quality pass driven by user feedback after running roam math / over-fetch / missing-index / auth-gaps on a real multi-tenant Laravel + Vue 3 codebase. 14 systematic false-positive patterns fixed, plus a three-path suppression mechanism so verified FPs stop showing up on every run.

Math (`roam math` / `algo`)

  • M1 — findings now point at the exact AST node, not the enclosing function. User: "highest single-leverage UX fix on its own — cuts triage time in half."
  • M2 — `if (depth > limit) return` early-return guards now recognised as bounded recursion (was only matching `<` continue form). Plus Set/Map/WeakSet param detection. Real-world: `deepEqual` no longer flagged as O(2^n) when guarded.
  • M3 — cache-vs-IO distinction expanded: Apollo (`client.readQuery` / `cache.modify`), SWR (`mutate`), TanStack lifecycle (`invalidateQueries` / `removeQueries` / `cancelQueries`), native collections (`Map.has` / `Set.delete` / `WeakMap.set`).
  • M4 — DEV-only block recognition: `import.meta.env.DEV` / `DEV` / `process.env.NODE_ENV !== 'production'` / `if (DEBUG)` / `console.assert` demote findings inside them.
  • M5 — sort-then-subscript with full iteration → demoted (display-order pattern, not min/max).
  • M6 — every finding carries a `to_suppress` evidence block.
  • M8 — confidence floor: `branching-recursion` + `sort-to-select` cap at "medium" unless runtime-hot.

Missing-index (`roam missing-index`)

  • M9 — `protected $table = '...'` now read cross-file as source of truth. Eliminates 6/6 high-confidence FPs from `advances`/`payments`/`reminders` model overrides.
  • M13 — multi-tenant per-schema migrations recognised: `Schema::connection('payroll')->create("{$schema}.payroll_advances", ...)` now matched + table prefix normalised.

Auth-gaps (`roam auth-gaps`)

  • M10 — non-auth route guards (`throttle` / `signed` / `verified` / `can` / `scope`) flagged at "low" with "intentional public-but-protected" note instead of high-confidence "missing auth".
  • M11 — tenant-scoped controllers (`officeScoped()` / `multiTenant()` / `Resource::for(...)` / `forTenant()` / `belongsToCurrentUser()` / `currentTeam()`) recognised as authorization-equivalent. Real-world: ~115 FPs eliminated.

Over-fetch (`roam over-fetch`)

  • M12 — direct-return scan is now method-body-scoped, not file-level. Previously: any controller importing `LedgerAccount` could be flagged for over-fetching it just because `return $aadeService->getDocs()` matched the generic `return $var;` pattern. Now: model must actually be USED in the same method body.

Suppression mechanism (M7) — three layered paths

  • Inline annotation — `# roam: ignore-math[branching-recursion]` on the symbol line. Bare `# roam: ignore-math` covers all task-ids on that line. `[*]` covers all. Supported across all four detector commands.
  • `.roamignore-findings` — repo-level YAML/JSON with `task_id` + `path_glob` rules.
  • `.roam/suppressions.json` via new `roam suppress --reason "…"` command. Each finding now carries a deterministic `finding_id` (sha256 truncated to 16 chars) so suppressions survive reindex.

Suppressed findings stay in the JSON envelope (under `finding["suppressed"]`) so consumers can detect over-suppression. Text output filters them by default.

M14 — verdict line truth

When suppressions fire, the verdict reads "N unsuppressed candidates surfaced; M suppressed via .roamignore-findings / inline annotation / suppressions.json" instead of just "N findings".

Surface counts

  • CLI: 186 → 187 (+1: `suppress`)
  • MCP tools: 136 (unchanged)
  • Core preset: 49 (unchanged)

Tests

198 detector tests pass (+72 new across `test_math_fp_fixes.py` (22), `test_finding_suppress.py` (20), `test_laravel_fp_fixes.py` (16)). 405 v2 tests still pass — no regressions.

Install

```bash
pip install roam-code==12.28
```

Full changelog

See CHANGELOG.md.

v12.27 — round-5 polish: 15 v2 improvements, no surface bump

06 May 08:24

Choose a tag to compare

Patch on top of 12.26.1

Round-5 polish + dogfood pass. 15 small-to-medium improvements, no new top-level commands, no surface count changes (still 186 / 136 / 49). First release shipped end-to-end via the new tag-triggered Trusted Publishing workflow — no manual twine.

New flags + features

  • `roam pr-analyze --diff-from-pr URL` — fetch GitHub PR diff via `gh pr diff`. Smoke-tested against fastapi#15482.
  • `roam pr-analyze --watch SECONDS` — poll diff source; re-run on change. Local dogfood mode for refactor sessions.
  • `roam pr-analyze --batch --stream-jsonl` — emit per-file rows as JSONL lines as soon as they complete. Long batches feel responsive.
  • `roam pr-analyze --audit-trail` auto-runs conformance check — Article 12 score attached to envelope on every emission. Surfaced inline as `conformance: NN/100`.
  • `roam audit-trail-export --top-actors N` — procurement-friendly hot list ranked by BLOCK count.
  • `roam rules-validate --fix` — auto-coerce safe schema mistakes (severity casing, glob whitespace). Skips real typos.
  • `metrics-push --include-pr-analysis` now includes conformance score — Cloud Lite Growth dashboard input.
  • `_compute_drift` per-rule breakdown — distinguishes "rule fired this PR for the first time" from "existing rule's violation count changed".

Content additions

Total starter packs now: 6 (Python, TypeScript, Go, Java, Kotlin, Rust).

CI hardening

  • publish.yml triggers on tag push + release + workflow_dispatch
  • `skip-existing: true` for idempotency (manual twine no longer collides)
  • Build job verifies wheel contains ≥8 v2 command files before PyPI sees it

Internal

  • `_build_rationale` cc=39 → <23 split into per-concern collectors + `_compose_next_steps` + `_extract_suggested_reviewers`
  • `_emit_batch` cc=48 → 26 split into `_run_batch_serial` + `_run_batch_parallel`
  • 17 new unit tests in `tests/test_pr_analyze_helpers.py` covering the small helpers
  • README v2 quickstart subsection — `git diff | roam pr-analyze` now in main Quick Start

Tests

405 v2 + adjacent tests pass (was 386 in 12.26.1). +19 new tests across 4 files.

Install

```bash
pip install roam-code==12.27
roam --version
roam dogfood
```

Full changelog

See CHANGELOG.md.

v12.26.1 — Go/Java rule packs, dogfood CI, conformance --sarif

06 May 07:12

Choose a tag to compare

Patch on top of 12.26

No new CLI commands, no surface count changes (still 186 / 136 / 49). Three real improvements driven by integration testing this round:

Added

  • audit-trail-conformance-check --sarif — emit SARIF 2.1.0 envelope with failed checks as findings. Drops directly into GitHub Code Scanning UI. Each rule's helpUri points at https://artificialintelligenceact.eu/article/12/.
  • templates/rules/go/.roam-rules.yml — 12-rule starter pack: no-unsafe, no-cgo, no-md5/sha1, no-panic, no-init-funcs, hallucinated imports, layer violations.
  • templates/rules/java/.roam-rules.yml — 12-rule starter pack: no-Runtime.exec, no-System.exit-in-libs, no-ObjectInputStream (deserialization RCE), no-printStackTrace, no-raw-types, no-Thread.stop, layer violations.
  • .github/workflows/dogfood.yml — self-CI workflow for roam-code itself. Runs roam dogfood on every PR + push, posts a sticky PR comment via roam pr-comment-render, uploads the audit trail as a workflow artifact. Eat our own cooking publicly.

Fixed

  • _save_baseline now stamps _meta.timestamp at save time. Without this, pr-comment-render --from-baseline silently couldn't compute baseline age (the "saved X days ago" line never fired). Caught by the new end-to-end integration test.

Internal

  • Cognitive complexity reductions (continued from 12.26):
    • _build_payload cc=49 → split into _extract_metrics + _extract_hotspots + _build_last_pr_block helpers
    • pr_analyze (the command coordinator) cc=38 → extracted _serve_from_cache + _apply_drift + _emit_audit_trail
  • New tests/test_v2_integration.py — 3 end-to-end tests exercise the whole v2 pipeline. Catches schema drift across the chain.
  • Cache stress-test on a 30-real-commit batch: 54.7× warm-cache speedup (60s cold → 1.1s warm) sequentially; 2.55× cold speedup with --parallel 4.
  • Real-OSS validation: ran pr-analyze on 3 small human-written PRs (fastapi#15482, requests#7401, httpx#3773); all SAFE with AI-likelihood 13-23. Confirms scorer doesn't false-positive on legitimate human work.

Install

pip install roam-code==12.26.1
roam --version
roam dogfood

Full changelog

See CHANGELOG.md.

v12.26 — Roam Agent Review + Cloud Lite engines + EU AI Act audit-trail toolkit

06 May 06:28

Choose a tag to compare

What's new

8 new CLI commands + 8 new MCP tools shipping the v2 monetization layer.

Roam Agent Review (PR-bot engine)

  • roam pr-analyze — agent-aware PR risk verdict (INTENTIONAL / SAFE / REVIEW / BLOCK). 9-signal AI-likelihood scoring (add/remove ratio, comment density, test coverage, function-size variance, generic naming, orphan imports, placeholder density, LLM-phrase fingerprints, suspicious imports). Language-aware weights. .roam/rules.yml enforcement (4 pattern types). Drift detection. --gate, --audit-trail, --batch DIR --parallel N, --cache, --quiet, --rules-strict.
  • roam pr-comment-render — markdown PR comment from the envelope. Before-after drift rendering, regression banners, plain-English signal explanations, baseline-age line.

Roam Cloud Lite (metrics-history engine)

  • roam metrics-push — push metrics-only summary (no source code) to Roam Cloud Lite. --anonymize SHA-256 hashes paths. --include-pr-analysis folds last-PR verdict + age + stale fields. --dry-run default-safe.

EU AI Act Article 12 audit-trail toolkit

  • roam audit-trail-verify — SHA-256 chain integrity verifier. --gate exits 5 on broken chain.
  • roam audit-trail-export — markdown / JSON / CSV export with date / verdict filters. --aggregate for procurement summary tables. --finalize writes a closing AuditIntegritySummary record.
  • roam audit-trail-conformance-check — score the trail against an Article 12 6-check checklist. --gate exits 5 on score < 100. Triage signal — not legal advice.

Production tooling

  • roam rules-validate — lint a .roam/rules.yml for typos, schema mistakes, unknown patterns, duplicate IDs, unbalanced glob brackets. --against DIFF dry-runs. --strict + --gate for CI. --explain prints pattern reference.
  • roam dogfood — one-shot v2 stack runner: audit + pr-analyze + audit-trail + conformance in one envelope.

Distribution surface

  • templates/rules/{python,typescript}/.roam-rules.yml — 14-rule starter packs each, validated clean.
  • templates/examples/.roam-rules.yml — example pack covering all 4 pattern types.
  • src/roam/templates/ci/agent-review.yml — drop-in GitHub Actions workflow.
  • README.md gains dedicated "Roam Agent Review" + "Roam Cloud Lite" sections.

Internal

  • Shared git_helpers + audit_trail_helpers modules eliminate ~120 lines of duplicated subprocess + JSONL-loading code.
  • 5 functions refactored to drop cognitive complexity below the project's 99-cc gate (_compute_ai_likelihood 110→<28, _render_github_markdown 101→<28, _load_rules_yaml 71→<23, _emit_batch 48→26, _build_rationale 39→<23).
  • Cache speedup measured: 24.5× cold→warm on a 5-real-commit batch.

Surface counts

  • CLI commands: 178 → 186
  • MCP tools: 128 → 136
  • Core MCP preset: 41 → 49

Tests

  • +280 new tests across 14 new test files. 383 pass in the targeted v2 sweep.

Install

pip install roam-code==12.26
roam --version
roam dogfood

License

Apache 2.0 (unchanged from 12.23).

Full changelog

See CHANGELOG.md.

v12.25 — QueryCursor shim for tree-sitter < 0.24

05 May 15:33

Choose a tag to compare

12.24 narrowed the fastmcp marker so 3.9 stopped failing at install. The next failure: from tree_sitter import QueryCursor in query_engine.pyQueryCursor was added in tree-sitter 0.24 but Python 3.9 pins to 0.23.x (newer versions need >= 3.10).

This was also a real runtime bug — any Python 3.9 user installing roam-code from PyPI would have hit ImportError on first index of a YAML-extractor language.

Fix

try:
    from tree_sitter import QueryCursor
except ImportError:
    # tree-sitter 0.23 exposes .matches/.captures on Query directly
    class QueryCursor:
        def __init__(self, query): self._query = query
        def matches(self, root): return self._query.matches(root)
        def captures(self, root): return self._query.captures(root)

Once 3.9 support drops the shim can go.

Install: pip install --upgrade roam-code

v12.24 — narrow fastmcp marker for Python 3.9

05 May 15:17

Choose a tag to compare

12.23 added fastmcp>=2.0 to [dev] without a Python-version marker, but fastmcp >= 2.0 requires Python >= 3.10. The 3.9 CI lane therefore failed at pip install. Marker is now fastmcp>=2.0; python_version >= '3.10' so 3.9 skips the install. The MCP-runtime test already guards on _HAS_FASTMCP (12.23) so 3.9 simply skips that single assertion.

Install: pip install --upgrade roam-code