Convert fresh-repository ChangeGuard friction into researched, backward-compatible, security-hardened conductor work with explicit tests, edge cases, contracts, review, and closure gates

Summary: Drafted comprehensive TA32-TA34 specs and implementation plans


Folded validated external review feedback into implementation-ready conductor specifications while preserving conservative execution and state-safety boundaries

Summary: Expanded TA32-TA34 for Deno and monorepo verification, structured credential URLs and Windows rename-aside recovery, bounded empty-index diagnostics, and transaction-safe metadata repair


Summary: Implement stack-aware verification


Added missing git diff neutral checks, corrected Node/Deno script inference logic, and parsed nextest.toml for slow/compile-fail profiles as requested in trackTA32 review.

Summary: Fixed TA32 spec deviations


Addressed high-severity issues from TA32 round 3 code review

Summary: Fixed missing deno fmt fallback and nextest.toml parsing


Post-implementation review found 9 spec defects across 4 rounds; all fixed and gated clean (1307 tests pass)

Summary: TA32 stack-aware verify defaults: repo detection, auto policy, hook stderr fixes, nextest probe, third-party guard, repo_root threading


Security track: starter TOML sanitization, transactional alias replacement with crash-safe locking, platform no-replace publication, 16 findings resolved across 6 review rounds

Summary: TA33: init secret sanitization and alias-refresh hardening


Pre-commit hook intent transaction for TA33 implementation commit

Summary: TA33 commit sidecar


Summary: Added TA34 spec and plan


Added new track specifications to conductor

Summary: Add TA34 spec and plan


Summary: Fix compilation error in release mode


Summary: Fix macOS test flakiness


Ensure staleness queries recognize fresh empty repositories

Summary: Fix missing index completion marker


Complete track TA34 requirements for typed freshness assessment

Summary: Implement fresh empty-repository index semantics


Provide robust type-safe semantics and shadow-state rollback repair for empty repositories

Summary: Implement TA34: Fresh Empty-Repository Index Semantics


CI exposed cross-platform fixture assumptions and an action installer that built the remote default branch instead of the tested checkout

Summary: Repair TA34 PR CI across formatting, platform tests, cache timing, and action checkout install


Format the TA34 implementation, correct platform-specific tests, harden cache timing, and install the checked-out action source

Summary: Fix TA34 cross-platform CI failures


GitHub does not populate GITHUB_ACTION_PATH for this JavaScript action runtime

Summary: Discover action checkout from the JavaScript entry point when GITHUB_ACTION_PATH is absent


GITHUB_ACTION_PATH is unavailable for the JavaScript action runtime

Summary: Add JavaScript action entry-point fallback for source discovery


Generated verify config differs between local templates and CI defaults, while crates.io transport failures repeatedly broke install smoke

Summary: Make TA33 CI fixtures environment-independent and smoke installs resilient


Ensure generated config variants remain valid and transient Cargo downloads do not mask install results

Summary: Harden CI workflow and verify fixture for TA33 closeout


Eliminate empty-repo stale loops and make corrupt metadata repair rollback-safe without replacing ledger or Cozo state

Summary: Finish TA34 typed empty-index freshness and atomic metadata repair


Associate the completed Git commit with the ledger after the commit hook created its change record

Summary: Record committed TA34 implementation


Complete RENAME-1 with migrated state and env identity, packaging updates, licensing artifacts, tests, and verified review fixes

Summary: Implemented and independently reviewed the full Ledgerful rename and private-tree relicensing


Keep git diff hygiene clean after the generated notice was staged

Summary: Removed trailing whitespace from generated third-party notice


Close the post-commit sidecar created for commit ea2ee25

Summary: Recorded the committed RENAME-1 implementation


Close the post-commit sidecar for ec504fb

Summary: Recorded third-party notice whitespace cleanup


Prepare repo for public release by removing internal specs and old name references

Summary: Clean up historical docs and legacy references


chore: clean up historical docs and legacy references


rename acceptance + distribution backbone

Summary: v0.1.6 first release: rename acceptance gate + deny.toml license fix + CHANGELOG + license finalization + release.yml macos fix + tag + checksum-verified install smoke


supply-chain + CI security baseline across all 3 repos

Summary: A5+A6: slopsquatting sweep (126 deps, 0 flagged), gitleaks history scan (0 real secrets), cargo-audit/deny + npm audit in CI, semgrep SAST, SHA-pinned actions, least-privilege permissions, CODEOWNERS, dependabot, AI-code review protocol + enforcement gate. Fixed anyhow RUSTSEC-2026-0190. Branch protection deferred (requires GitHub Pro/public).


Address Phase 1 findings F1-1, F1-3, F1-4, F1-5, F1-6, F1-7 per 0005 spec DoD-1

Summary: E1-CRYPTO Phase 1 remediation: XChaCha20-Poly1305, AAD, token hardening, key perms, Argon2 errors


F2 findings: explicit shell opt-in in VerificationStep, argv-only direct execution for rule steps, canonical path ProcessPolicy with strict mode, control-char validation for entity substitution, timeouts and policy checks for MCP/SCIP self-spawn

Summary: Harden process runner policy and subprocess execution


Summary: F3-1..F3-4 path handling: clean .. in normalize_root, component-level schema.rs checks, symlink-aware ensure_path_within_root, Windows special-path detection, proptest dev-dep


F4-1 verifies Ed25519 on raw manifest bytes before full Manifest deserialization; F4-2 caps bundle and manifest sizes; F4-3 validates entry/tombstone bounds and entry_count; F4-4/F4-5 hard-cap MCP Content-Length and JSON body. Adds regression tests for F4-1, F4-2, F4-4.

Summary: E1-CRYPTO F4 deserialization hardening: Ed25519 before deser, bundle/MCP size caps


Summary: DoD-3: proptest lexical fuzz + symlink-escape integration test + normalize_root regression test


User requested not to commit ledger transaction

Summary: Transaction Rolled Back


Pre-existing pending security tx on server.rs belongs to this track; adopt before continuing.

Summary: Adopt pending security work for 0006-DaemonHardening


Pre-existing pending tx for daemon-hardening; adopt as starting point for 0006.

Summary: Adopt pending daemon-hardening tx


Completes DoD-1 through DoD-5,7,8 for track 0006. Verified by clippy, nextest, ledgerful verify full, and frontend build/lint/tests.

Summary: Implement loopback daemon hardening (0006-DaemonHardening): Host validation, CORS tightening, token header transport, CSP


Track 0010: GitHub-recognized SECURITY.md with dual-channel reporting, scoped safe-harbor (DRAFT pending counsel), supported versions, realistic response windows, no PGP/no bounty. Email provisioning pending Cloudflare.

Summary: A3-DISCLOSE: SECURITY.md + responsible disclosure channel (email + GitHub private reporting)


Track 0011: endpoint-aware OpenAPI (docs/api/openapi.json, 23 routes), drift test proven to bite, wire casing fidelity, §4.2/§4.4 reconciled, §4.8 fetchStatus divergence documented, deferred #30 resolved

Summary: A4-CONTRACT: utoipa OpenAPI + drift test + coordination.md reconciliation


Track 0013 engine phase: /api/sync/status in OpenAPI with 200+501, snapshot.recent_changes typed as Vec<ChangeResponse>, snapshot.top_hotspots typed as Vec<HotspotResponse>, WebError::NotImplemented (501), ProblemDetail ToSchema, sync module split (hlc/state/error un-gated)

Summary: A1+A2: sync/status schema exposure + 501 no-sync behavior, snapshot typed (ChangeResponse+HotspotResponse)


Track 0014 Phase B DoD-5 + DoD-6: clear the private.pem misnomer deferred row; memmap2 0.5.10 via cozo cannot be bumped (no compatible patch); codex re-review clean

Summary: Active one-time migrate of private.pem→private.key with identity preservation; memmap2 patch attempted (left deferred); fixed 0013 sync_status test bug


Eliminate test leakage into real ~/.ledgerful/keys, add DI signing variant, assert keys stay within state root, add explicit keypair consistency verification. Addresses conductor track 0015.

Summary: Crypto test isolation and keypair-consistency hardening


Completing prior bugfix transaction before finalizing work.

Summary: Bugfix cleanup or completion


Cross-model review of conductor track 0015: HIGH symlink-escape and MEDIUM refusal-path coverage findings. assert_within_state_root now canonicalizes the full path when the target exists, resolving symlinks before containment check; extracted parent+name fallback to parent_plus_name helper. Added unit test proving symlink escape is rejected on Unix and existing-file path still passes on Windows. Added integration test proving verify_signature returns false without panicking in a mismatched-key directory state.

Summary: Fix symlink escape in assert_within_state_root and add read-only verify test for mismatched key state


Codex review for tracks 0016/0017: scope first-byte timeout to headers, use get_keys_dir in re-sign, keep dry-run read-only.

Summary: Fix HIGH-1 first-byte timeout scope, HIGH-2 re-sign keys dir, MEDIUM-1 dry-run immutability


Replace throwaway external DB script with audited, safe-by-default re-sign path. Reuses 0015 invalid-sig detection, re-signs via engine DI signing API, WAL-safe backup (Online Backup API + integrity_check), single MAINTENANCE audit entry per batch. Cross-model review: codex R1 found 2 HIGH + 2 MEDIUM, all fixed; Claude R3 clean. Gates: fmt/clippy/1895 nextest/verify full green.

Summary: First-class ledger re-sign / key-repair command (track 0016)


Fix two pre-existing defects: (1) impact stalls ~10min when completion model unreachable — added first-byte timeout (15s headers-only, generous read for body) + bounded retries + graceful degradation annotation in impact output; (2) cozodb_integrity flaky under parallel load — root-caused as resource contention (30 subprocesses x parallel tests), serialized with #[serial(test)]. Cross-model: codex R1 found 2 HIGH + 2 MEDIUM, fixed; Claude R2+R3 clean. Gates: fmt/clippy/1895 nextest/verify full green. Cosmetic lows #3/#5 logged to deferred.md.

Summary: Engine reliability: impact graceful degradation + flake fix (track 0017)


- hook_post_commit: run incremental_index() in the post-commit detached
  thread before hotspot trend recording, best-effort/non-fatal, 30s budget
- vector_store: lower ef_construction 200->100 to halve HNSW rebuild time
  with negligible recall impact (ef_search=100 compensates)
- scip/orchestrator: raise SCIP timeout 300s->600s for cold-cache rust-analyzer
  runs on large workspaces with vendored crates

Summary: perf: auto-incremental-index on post-commit + lower HNSW build cost + raise SCIP timeout


rust-analyzer scip emits thousands of stderr warning lines. The
original code piped stderr but never read it until after wait_timeout,
causing the OS pipe buffer (~64KB on Windows) to fill and the child
to block on write() — a false timeout no matter how high the limit.

Fix: spawn background threads to drain stdout/stderr continuously while
the main thread waits for exit. Capture the last 8KB of stderr for
error reporting.

Summary: fix: drain SCIP process pipes to prevent deadlock


Adding toolchain: stable to 14 rust-toolchain actions that were missing the required input, causing cargo audit/deny to fail on every PR

Summary: Fix missing toolchain inputs in CI workflows + review findings


All 14 dtolnay/rust-toolchain invocations across ci.yml, security.yml,
release.yml, and smoke.yml were missing the required 'toolchain' input,
causing cargo audit and cargo deny to fail with 'toolchain is a required
input' on every PR and push.

Summary: fix(ci): add missing toolchain: stable to all rust-toolchain actions


Completes track 0032-UnexposedCommandSurface — all 7 DoDs met, 2 internal review rounds + 3 codex gate rounds clean, 1387 tests pass

Summary: Wire 5 unexposed ledger/utility commands to CLI dispatcher: ledger resume, export-provenance (safe-path), hook-repair, openapi, register (internal)


- ledger resume [--tx <id>] — resume pending transaction
- ledger export-provenance [--out <path>] [--force] — safe-path resolution
  (refuse src/, .ledgerful/state/, Cargo.toml; refuse existing without --force;
  post-canonicalization symlink re-check; default stdout)
- ledger hook-repair [--force] — repair stale post-commit hook sidecar
- ledgerful openapi — print OpenAPI JSON to stdout (CLI, not web route;
  works in openapi-only and web builds)
- execute_ledger_register marked pub(crate) + #[doc(hidden)] (internal API)

2 internal review rounds + 3 codex gate rounds (all clean). 1387 tests pass.

Summary: feat(0032): wire 5 unexposed commands to CLI dispatcher


Behavior-preserving extraction of shared DTOs and helpers from api.rs and server.rs into a new types module with pub use re-exports; OpenAPI artifact regenerated to reflect moved annotations. Full clippy/format/lib+bin tests pass.

Summary: Phase 0.5: extract shared web DTOs to src/commands/web/types.rs


Summary: Phase 0.5: extract web/types.rs


Behavior-preserving refactor + skip .opencode/node_modules in scan_dependency_dir

Summary: Phase 0.5: extract web/types.rs + fix federated scan hang


scan_dependency_dir recursively walked the entire repo tree including
.opencode/node_modules (2494 JS/TS files), causing scan --impact to
hang for minutes. Add node_modules, .opencode, .cargo, .claude,
.config, .agents, vendor to the skip list alongside .git/.ledgerful/target.

1387 tests pass. scan --impact: 8s (was hung indefinitely).

Summary: fix: skip .opencode/node_modules/vendor in federated scan_dependency_dir


Completed submodule extraction, regenerated openapi.json, moved tests, fixed feature-gated imports

Summary: Phase 2 God File Refactor: split web api.rs into openapi.rs, cozo.rs, dto.rs, handlers.rs


- Extract OpenAPI doc + generate_openapi_json into api/openapi.rs

- Extract CozoDB KG/security-boundary queries into api/cozo.rs

- Add api/dto.rs and api/mod.rs re-exports

- Keep api/handlers.rs as rename target with handler fns + shared helpers

- Move hotspot DTO and KgNode serialization tests into web::types

- Regenerate docs/api/openapi.json

- Fix feature-gated axum http imports in server/handlers.rs

Summary: refactor(0033): Phase 2 — split api.rs into api/ submodules


God-file refactor; behavior preserved, public API re-exported, fmt/clippy/nextest green

Summary: Phase 3: split src/commands/ask.rs into ask/ submodules


refactor(0033): Phase 3 — split ask.rs into ask/ submodules


Behavior-preserving refactor to reduce god-file responsibility mixing per 0033 spec

Summary: Phase 4: split src/commands/index.rs into index/ submodules


git mv index.rs -> index/mod.rs (preserves blame provenance).
Extract 7 focused submodules:
- modes.rs (453 lines) — mode routing: execute_index/main/check/export
- semantic.rs (577 lines) — semantic indexing pipeline + dry-run
- scip.rs (84 lines) — SCIP ingestion
- graph.rs (61 lines) — docs indexing + contracts
- output.rs (267 lines) — JSON + human output formatting
- repair.rs (110 lines) — metadata repair
- check.rs (87 lines) — standalone index check

Tests colocated in submodules. pub use re-exports preserve imports.
Gate: fmt OK, clippy OK, 1387 tests pass. ledgerful index --check: 0 stale.

Summary: refactor(0033): Phase 4 — split index.rs into index/ subdirectory


Behavior-preserving god-file refactoring per 0033 Phase 5; preserve import paths via pub use re-exports, colocate tests in submodules

Summary: Split src/commands/config.rs into config/ subdirectory


refactor(0033): Phase 5 split config.rs into config/ subdirectory


Behavior-preserving god-file refactor; pub-use re-exports keep existing crate::state::storage::StorageManager imports working; tests colocated in submodules

Summary: Phase 6: split src/state/storage.rs into storage/ submodules (connection, packets, verification, schema, migrations, ledger)


refactor(0033): Phase 6 split storage.rs into storage/ subdirectory


Codex review finding: em-dashes/ellipsis/arrows in web handler doc comments were double-encoded (UTF-8 interpreted as IBM437). Replaced corrupted sequences with correct Unicode, removed BOMs, regenerated docs/api/openapi.json under UTF-8 codepage.

Summary: Fix OpenAPI mojibake in handler doc comments and regenerate openapi.json


Codex review finding: add explanatory doc comment above scan_dependency_dir skip-list and add unit test verifying node_modules/ is skipped during federated dependency scanning.

Summary: Document and test federated scanner tooling-cache exclusions


Summary: Phase 0.5-6 + review fixes


fix(0033): codex gate v2 fixes — OpenAPI mojibake + scanner test


Behavior-preserving refactor. All gates green. Codex gate clean.

Summary: Track 0033 complete: 6 god files split into focused subdirectories


Post-0033 dogfooding found scan --impact silently hanging on large trees; 0034 bounds all hang paths so the scan always completes, progresses, or diagnoses

Summary: Eliminate silent-hang paths in scan --impact and federated scanning: subprocess timeout + process-group kill, file-count budget, config-driven exclusions, cooperative backstop deadline, threshold-gated progress, structured degradation warnings


Track 0034 complete; clearing ledger before starting 0031

Summary: 0034: eliminated silent-hang paths in scan --impact (subprocess timeout+group kill, file budget, config-driven exclusions, backstop deadline)


Defensive hardening of MCP tool results and LLM analysis pipeline against adversarial repo content; adds deterministic bounds and explicit cloud egress opt-in for MCP ask tool.

Summary: Harden AI/agent boundary (0031): MCP sanitization, prompt injection mitigation, parse bounds, cloud egress gate


Track 0031 implementation complete; clearing ledger before cross-model gate

Summary: 0031: harden AI/agent boundary — MCP Markdown/HTML sanitization (split content vs structured), prompt injection mitigation (fence escaping, DATA framing), LLM parse bounds + fail-closed, cloud egress confused-deputy gate (mcp_allow_cloud_egress)


MCP tool-result hardening (DoD-1):
- New sanitize_mcp_content() escapes Markdown fences/images/links/headings/tables/HTML/control/bidi chars
- New sanitize_mcp_structured() preserves JSON structure while escaping Markdown in string values
- text_response uses full sanitize; json_response uses structured sanitize
- Subprocess stdout/stderr capped at 4MB to prevent OOM
- Adversarial tests: fence-breakout, image-exfil, zero-width bypass, nested fences, unicode, oversized

Pipeline integrity (DoD-2):
- escape_code_chunk replaces backticks with U+02CB before fencing (prevents fence-breakout)
- intent_drafter wraps git diff/commit as [Untrusted repository content] DATA with backtick escaping
- Unknown LLM categories/relations collected into parse_warnings Vec (not just warn!)
- parse_warnings surfaced in graph.rs

Parse robustness (DoD-3):
- 10MB response size limit, 10k nodes/edges cap, 10k field length cap
- Fail-closed: parse errors return Err with annotation (not silent skip)
- floor_char_boundary for safe UTF-8 truncation

Cloud egress gate (DoD-4):
- MCP ask tool forces --backend local by default (confused-deputy mitigation)
- New config.ask.mcp_allow_cloud_egress (default false) opts into cloud via MCP
- Trust boundary documented in review.md
- AI-path claims reconciled (no site drift found)

Summary: fix(0031): harden AI/agent boundary — MCP sanitization, prompt injection mitigation, parse bounds, cloud egress gate


feat(cli): enhance verbosity filtering and ledger reporting for Track 35


docs(agents): update codex skill with windows stdin pipe workaround and opencode fallback


Summary: chore: untrack local .agents directory


Summary: Map verify runs to transaction IDs (Phase 0-C)


[FEATURE] Map verify runs to transaction IDs (Phase 0-C)

Ledger: 763d8993-c145-4684-a43c-08fc5517bded
Signed-off-by: Ledgerful Bot <bot@ledgerful.io>


Garbage collection of stale PENDING transaction

Summary: Transaction Rolled Back


chore(0036): finalize track - remove debug eprintlns, close conductor


docs: add verify tx-provenance binding to Features.md (track 0036)


Add per-file additions/deletions to changed_files at commit time via shared numstat helper, m48 migration, and API surface (DoD-1..7)

Summary: Implement per-file diff stats for ledger entries (track 0037)


Track 0037: per-file addition/deletion stats computed from committed diff, stored outside signing basis

Summary: Add diff stats to changed_files


per-file addition/deletion stats computed from committed diff, stored outside signing basis

Summary: Track 0037 diff stats


Summary: Track 0037 diff stats


Summary: Transaction Rolled Back


Track 0037-LedgerDiffStats complete. All DoD met. Codex final review clean (0 findings). Frontend type regeneration deferred to ledgerful-frontend repo.

Summary: Finalize track 0037: review.md, conductor.md Completed, deferred.md cross-repo frontend follow-up, fresh clean codex gate PASS


Honest-zero #3: dashboard fetchTrends() was a mock returning empty array. Now the backend serves real project-level trend data from a precomputed rollup.

Summary: Add GET /api/trends endpoint with cached daily rollup (migration m49, project_trend_days table). Rollup populated incrementally by post-commit hook + bounded 90-day catch-up. No per-request git walk.


- Migration m49: project_trend_days table (day TEXT PK, score, changes,
  high_risk_count) — m44-style, idempotent, unconditional
- Post-commit hook: upsert_project_trend_day aggregates the latest
  hotspot_trends snapshot for the UTC day into the rollup (Rust-side
  normalize_score log-scale transform, clamped 0-100)
- catch_up_project_trends: bounded 90-day idempotent backfill from
  existing hotspot_trends data (INSERT OR REPLACE on day PK)
- GET /api/trends endpoint (web-gated): returns TrendsResponse with
  TrendPointDto (camelCase wire matching frontend TrendPoint)
- Tests: 8 unit + 3 integration (empty/populated/off-by-one)
- coordination.md: §3.2 updated, §4.10 added, §11 changelog
- Codex cross-model review: 6 rounds, final PASS with 0 findings above LOW

Summary: feat(0038): project-level trends API with cached daily rollup


Record start of implementation for gate mode feature

Summary: Start track 0050-ObserveEnforceMode: gate mode observe/enforce default and init next-steps block


Summary: test commit


Summary: test observe


- GateConfig (mode = observe | enforce, default observe)
- ledgerful init --enforce, ledgerful gate mode observe|enforce
- Mode transitions write signed MAINTENANCE ledger entry (atomic: entry before config)
- Observe mode: block conditions route to WARN, no blocking exits
- observed metadata marker on entries with warned conditions (unsigned, outside signing basis)
- observe_warned flag on TransactionManager, propagated through sidecar
- Migration m50: observed column on ledger_entries
- Doctor: config/ledger mode-mismatch warning
- SOC2 export: four-field mode disclosure (reported mode, transition history, chain status, completeness)
- Init status block: deterministic hooks/keys/mode/model/next-steps
- 6 integration tests (observe/enforce, fidelity, observed marker, transition entry)
- 12 codex review rounds, final: 1 low deferred
- 1459 unit + 547 integration tests pass

Summary: feat(0050): observe/enforce gate mode


Implement prev_hash column, chain hash linking, verify chain integrity, re-sign command with single maintenance entry and CSV export fix.

Summary: Add ledger prev_hash chain integrity and re-sign maintenance


Update tests for prev_hash CSV export, re-sign maintenance summary filter, get_related_ledger_entries prev_hash column, and security boundaries empty-state after seeded mode node.

Summary: Fix chain integrity tests, related query columns, and empty-state expectations


Fixes R1-F1 through R1-F12: tests for concurrency, downgrade, export rollback, tamper; CAS guard compare; determinism; docs; banned terms. Full gate passed.

Summary: Address 0046-LedgerChainHash review findings


- Migration m51: prev_hash column on ledger_entries + chain_head singleton table
- Chain hash: SHA-256(tx_id || signature_hex || prev_hash) per entry
- Signed chain head: binds (latest_entry_hash, genesis, length)
- CAS: conditional UPDATE with row-count check on chain_head
- Canonical ordering: committed_at ASC, tx_id ASC in all entry queries
- verify --signatures --chain: full-linkage walk, break localization
- Fail-closed on downgrade: stripped head + entries with prev_hash
- verify --against-export: rollback/tail-truncation detection
- Orphan head detection: empty entries + remaining chain_head
- Pre-chain ledgers: benign (no prev_hash, no head)
- SOC2 export: chain_head.json + prev_hash in ledger.csv
- Mode disclosure: real chain continuity status
- Re-sign: new chain segment + MAINTENANCE entry linking old->new head
- signing_required threaded into chain head signing (graceful degradation)
- 7 codex review rounds (final: CLEAN, no findings above LOW)
- 1459 unit + 560 integration tests pass

Summary: feat(0046): additive ledger chain hash (Option A)


Add export cargo feature, expose export module unconditionally, wire CLI dispatch with 0032 path-safety, add parity/path-safety tests; no-web build compiles and full verify passes

Summary: Implement Phase 1 of Track 0039: export evidence --profile soc2 CLI command


New 'export' cargo feature (in default + web) makes the SOC2 export
callable without the web feature. 'ledgerful export evidence --profile soc2'
with --out/--force uses 0032 path-safety (canonicalize, symlink re-check,
refuse src/state/Cargo.toml, refuse overwrite without --force).

Tests: 8 integration (parity, CLI/direct/web comparison, path-safety,
overwrite refusal, symlink re-check on Windows + Unix).

Summary: feat(0039): export evidence --profile soc2 CLI command


First-class 'ledgerful demo' command: creates a synthetic invoice-service
repo, runs the real hook flow through 5 commit cycles producing real
Ed25519-signed entries from an ephemeral keypair, runs verify, and exports
a self-identifying DEMO SOC2 evidence zip.

- Ephemeral keys via HOME/USERPROFILE redirect to demo dir (0015 DI)
- Repo-local git config (user.name/email + core.hooksPath) for isolation
- DEMO marker: manifest demo:true, index.md, filename, entry summaries, stdout
- generate_soc2_export_with_options(layout, demo) for demo vs real exports
- 8 integration tests: hook-fired, keys-sentinel, manifest-demo, keep/cleanup,
  force, git-config-unchanged, stdout-markers

Summary: feat(0039): ledgerful demo command with DEMO SOC2 export


Track 0039 Phase 2: first-class demo command with ephemeral keys, DEMO markers, git isolation

Summary: ledgerful demo command: synthetic repo, real hook flow, DEMO SOC2 export


Track 0039: closes launch demo gaps per research5 2.2-2.3

Summary: Track 0039: DemoPathAndCliExport — demo command + CLI evidence export


docs(0039): add demo + CLI evidence export to Features.md


Review fixes (4 HIGH + 6 MEDIUM + 2 LOW):
- HIGH: dir_is_non_empty now counts dotfiles (prevent destructive rm of .git)
- HIGH: wall-clock budget test asserts demo completes within 90s
- HIGH: dashboard instruction uses correct 'cd <dir> && ledgerful web start'
- HIGH: verify instruction only printed when --keep (export is cleaned up otherwise)
- MEDIUM: manifest demo field uses skip_serializing_if (no schema change for non-demo)
- MEDIUM: [DEMO] prefix in conventional subjects so ledger summaries carry marker
- MEDIUM: use std::env::current_exe() for verify subprocess (self-contained)
- MEDIUM: ledger.csv [DEMO] assertion + wall-clock budget test added
- MEDIUM: README.md commands list updated with demo + export
- MEDIUM: gate mode notice clarified (enforce doesn't block well-formed commits)
- LOW: SAFETY comment expanded for subprocess env inheritance
- LOW: modify closures use into_diagnostic()? instead of unwrap_or_default

Summary: fix(0039): address review findings — dotfile safety, DEMO in summaries, wall-clock test, correct commands


Codex R1 findings (4 MEDIUM):
- Use observe mode (0050 default) instead of enforce — shows real onboarding
- Don't print 'ready: <path>' when cleaning up (path no longer exists)
- Prefix verify output with [DEMO] for self-identification
- ledger start → git commit not needed in observe mode (hook auto-drafts);
  removed unused DemoCycle fields (entity/category/message)

Summary: fix(0039): codex R1 — observe mode, verify DEMO prefix, no ready-path on cleanup, ledger start not needed in observe


- Write .ledgerful/DEMO_MARKER so web UI can self-identify synthetic repos
- Document verify non-zero acceptance (synthetic repo can't pass cargo clippy;
  the spec's goal is populating verification_history.csv, not passing verify)
- Test asserts DEMO_MARKER exists with --keep

Summary: fix(0039): codex R2 — DEMO_MARKER file + verify-fail-closed documentation


- Export CLI + web handler check for .ledgerful/DEMO_MARKER and pass
  demo=true when present — prevents synthetic evidence from looking real
  when a kept demo repo is later exported
- Verifier command includes 'cd <demo_dir> &&' prefix so it targets the
  correct repo when run from the original cwd

Summary: fix(0039): codex R3 — auto-detect DEMO_MARKER in export, fix verifier cd prefix


- generate_soc2_export_with_options takes optional keys_dir; demo repos
  pass <repo>/.ledgerful/keys/ so re-exports use ephemeral keys, not
  production ~/.ledgerful/keys/
- CLI export defaults to ledgerful-DEMO-evidence.zip when DEMO_MARKER present
- Web handler uses DEMO filename in Content-Disposition when marker present
- Demo run_export passes repo-local keys_dir explicitly

Summary: fix(0039): codex R4(f) — demo-local keys for kept-repo exports, DEMO filename


StatusResponse gains is_demo field (skip_serializing_if=false) so the
dashboard can render a DEMO banner when the repo was created by
ledgerful demo. OpenAPI spec regenerated.

Summary: fix(0039): codex final — wire DEMO_MARKER to /api/status for dashboard header


- Scaffold commit subject now includes [DEMO] so all demo-generated
  ledger entry summaries self-identify
- Test asserts ALL non-system rows (excluding gate-mode init entry)
  contain [DEMO]

Summary: fix(0039): codex clean — [DEMO] in scaffold commit subject, all-rows test


fix(0039): codex final clean - gate demo export, add is_demo status test


Verifiable end-to-end release integrity: per-release SBOM (absorbs E4-SBOM), cosign keyless artifact signing, SLSA build provenance, SBOM attestation, and cargo auditable embedded deps. Post-launch supply-chain hardening, not launch-blocking. Phase 3 attestations gated on public/Enterprise repo.

Summary: Track 0053: supply-chain attestation pipeline — CycloneDX SBOM, cosign keyless signing, SLSA build-provenance via actions/attest, SBOM attestation via actions/attest-sbom, cargo auditable builds, SECURITY.md supply-chain section, release-notes template. No Rust source or Cargo.toml changes.


v0.1.8: track 0053 supply-chain attestation, docs refresh, action/ removal

Track 0053-SupplyChainAttestation (engine slice):
- CycloneDX SBOM (engine --all-features + MCP npm), schema-validated
- cosign keyless signing (archives + SBOM + .tgz)
- SLSA build-provenance via actions/attest in build matrix
- SBOM attestation via actions/attest-sbom in sign job
- cargo auditable builds on all 4 targets
- SECURITY.md supply-chain section + RELEASE_NOTES_TEMPLATE.md
- All actions SHA-pinned, permissions least-privilege per job
- Phase 3 attestations gated on public/internal repo visibility

Version bump 0.1.7 -> 0.1.8, crossbeam-epoch 0.9.18 -> 0.9.20 (RUSTSEC-2026-0204)

Docs refresh:
- CHANGELOG.md: [0.1.8] section with all changes since v0.1.6
- installation.md: version examples 0.1.5 -> 0.1.8
- api/openapi.json + openapi.rs: version 0.1.6 -> 0.1.8
- architecture.md: data flow + command responsibilities updated
- breaking.md: rusqlite 0.39 -> 0.40, gix 0.81 -> 0.84, nextest commands
- AI-CODE-REVIEW-PROTOCOL.md: fix crypto path refs
- Ledgerful/skill.md: regenerated from internal SKILL.md
- init.rs: fix dangling docs/testing.md -> docs/Engineering.md

Cleanup:
- Remove action/ (initial-commit scaffolding, track 0047 belongs in
  separate ledgerful-action repo)
- Remove review.md (stale track 0036 artifact)
- deny.toml: add MIT-0 to match about.toml
- Delete output/ scratch dir (gitignored)


Full git-history gitleaks scan completed before public flip:
- 11 findings, all confirmed false positives (fake test keys in
  redact tests, deterministic test hex, SQLite C source/headers,
  cryptographic algorithm names in SECURITY.md)
- No real secrets, .env files, or credential patterns in history
- Baseline suppresses known false positives so future scans are clean
- Verified: gitleaks git scan returns 0 leaks with baseline

Summary: chore: add .gitleaksignore baseline for false-positive suppression


Pre-public-flip secret scan: 11 gitleaks findings, all confirmed false positives (fake test keys, SQLite source, algorithm names). No real secrets in git history. Baseline suppresses known FPs.

Summary: Add .gitleaksignore baseline for full-history false-positive suppression


- scanner.rs: ProcessGroup -> ProcessGroup::leader() (process-wrap 9.1.0 API)
- web/mod.rs: wrap std::env::set_var in unsafe block (Rust 2024 edition)
- release.yml: CycloneDX schema URL master -> refs/tags/1.5 (404 fix)
- mcp-server/package.json: version 0.1.6 -> 0.1.8 (match engine)

These only affect non-Windows targets (Unix cfg gates); Windows build
was unaffected. All 1463 lib + 578 integration tests pass.

Summary: fix: cross-platform compile + SBOM schema URL for release pipeline


ProcessGroup::leader() API fix, unsafe set_var for Rust 2024, CycloneDX schema URL 404 fix

Summary: Fix cross-platform compile errors blocking release pipeline


fix: correct CycloneDX schema URL path (schema/bom-1.5.schema.json)


fix: add export feature to MCP package build command


- cosign-installer: 6f9f177 -> 3094a48 (latest main)
- cosign-release: v2.9.0 -> v3.1.1 (latest stable)
- verify-blob: use --bundle instead of --signature/--certificate
  (v3.x bundle format is the default; old flags deprecated)

Summary: fix: update cosign-installer to latest SHA + cosign v3.1.1


- install.js: inline archivePath/destination in Expand-Archive
  command string (fixes  binding issue with PowerShell -Command)
- package.json: add ledgerfulEngineTag field (v0.1.8) decoupling
  MCP package version from engine release tag
- install.js: releaseBaseUrl uses engineReleaseTag() instead of
  packageVersion() for the download URL
- platform.test.js: test updated for engine release tag

Published as @ledgerful/mcp-server@0.1.10 on npm

Summary: fix(mcp): Windows Expand-Archive + engine release tag decoupling


Replace internal 'Work by conductor track' jargon in README with public-facing
Contributing section routing to Discussions/Issues/Security. Add bug_report.md
issue template with routing notice for general questions. Update SECURITY.md
supported version to v0.1.8 and remove DRAFT safe-harbor banner (counsel-
reviewed, LLC formed, license in force per deferred.md legal cluster).

Summary: docs: track 0042 — public Contributing section, bug_report issue template, SECURITY.md version update


Track 0042 engine slice: public-facing repo hardening before launch

Summary: Replaced conductor jargon with public Contributing section, added bug_report issue template, updated SECURITY.md version to v0.1.8 and removed DRAFT safe-harbor banner


Remove conductor track references from docs/Features.md (Track 0046/0039 →
plain descriptions, add issue #6 link for chain-hash limitation). Fix
SECURITY.md: remove stale provisioning note (mailbox is live per 0027),
update supply-chain status block from future tense to active, fix cosign
certificate-identity URL casing (ledgerful → Ledgerful), update example
version v0.1.7 → v0.1.8, remove 'gated until public' language (repo is public).
Remove unnecessary pull-requests:write from ci.yml top-level permissions.

Summary: docs: track 0042 R1 — clean public docs of conductor refs, fix stale SECURITY.md status


Summary: Removed conductor track refs from Features.md, fixed SECURITY.md stale supply-chain status and mailbox provisioning note, removed ci.yml unnecessary pull-requests:write, added chain-hash issue link


Remove '0027 public flip' references from release.yml comments/echo (10
occurrences → neutral 'when the repository becomes public'). Remove
'conductor track 0004' from ai-review-gate.yml header comment. Fix
cargo fmt on src/commands/web/mod.rs (unsafe set_var block formatting).

Summary: fix: track 0042 R2 — remove conductor refs from workflow comments, fix fmt


Summary: Removed conductor track refs from release.yml and ai-review-gate.yml, fixed cargo fmt on web/mod.rs


security: track 0042 R3 — pin frontend checkout SHA, fix cosign verify instructions

Pin ledgerful-frontend checkout to commit 4a1df7e in release.yml, ci.yml,
and smoke.yml for reproducible builds (prevents a backend tag building
against an unreviewed frontend HEAD). Fix cosign verify-blob instructions
in SECURITY.md and RELEASE_NOTES_TEMPLATE.md to use --bundle (matching
the shipped .bundle asset files, not separate .sig/.pem files).


Track 0042 R3 codex review fixes — reproducible builds + working public verification path

Summary: Pinned frontend checkout to SHA 4a1df7e in release/ci/smoke workflows, fixed cosign verify-blob instructions to use --bundle in SECURITY.md and RELEASE_NOTES_TEMPLATE.md


User requested all deferred items be resolved

Summary: Resolve all 3 deferred P3 items: remove stale DRAFT banner from THIRD_PARTY_NOTICES, remove Track 0013 from source doc comments + regenerate openapi.json, replace conductor track refs in operator-surface-policy.md and skill.md


THIRD_PARTY_NOTICES: remove stale DRAFT banner (LLC formed, license in force).
Source doc comments: remove Track 0013 from error.rs, types.rs, handlers.rs,
usage.rs, sync/mod.rs. Regenerate openapi.json from cleaned sources.
operator-surface-policy.md: conductor tracks -> development tasks.
skill.md: conductor track -> development task.

Summary: docs: resolve all deferred P3 items — remove conductor refs, stale DRAFT banner


Adds HMAC-pseudonym, bot-key signing, deterministic NDJSON bundle, offline verifier, and integration tests per 0045 spec.

Summary: Implement ledger export-public engine slice


feat: implement ledger export-public engine slice (0045)


Document public bundle semantics, allowlist, honest ceiling, verification, and publishing per track 0045 DoD-4

Summary: Create public-ledger.md developer doc


Ensure sensitive fields cannot reach the public export allowlist without a deferred.md exception; track 0045 DoD-6

Summary: Add CI allowlist guard test


Grep public_export.rs for network dependencies and publish evidence as a 90-day artifact; track 0045 DoD-4 part 2

Summary: Add no-network public export CI job


Add [[test]] ci entry in Cargo.toml so the allowlist guard is built and run

Summary: Register tests/ci test target


docs: add public-ledger.md + CI allowlist guard + no-network workflow (0045)


Address P0-P3 findings: verifier payload, deterministic manifest, explicit preserve_order, doc refs, error handling, status mapping, allowlist notes, and entry signature integration test

Summary: Fix 0045 review findings in public export


fix: address review findings — verifier payload, deterministic manifest, serde_json preserve_order, expect() removal (0045 R1)


fix: gate test_compute_author_pseudonym with cfg(test) (0045 R2)