diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4422c17..15ffd5a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,10 @@ permissions: contents: write security-events: write +env: + TOOL_MDBOOK_VERSION: "0.5.0" + TOOL_MDBOOK_MERMAID_VERSION: "0.17.0" + jobs: test-and-build: runs-on: ubuntu-latest @@ -116,8 +120,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} docs-check: - needs: test-and-build - if: github.event_name == 'pull_request' + name: Validate GitHub Pages docs build runs-on: ubuntu-latest steps: - name: Checkout @@ -132,20 +135,17 @@ jobs: - name: Install just run: cargo install just --locked - - name: Setup mdBook - uses: jontze/action-mdbook@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - use-mermaid: true - - - name: Install mdbook binaries - run: cargo install mdbook mdbook-mermaid --locked + - name: Install mdBook toolchain + run: | + cargo install mdbook --version "$TOOL_MDBOOK_VERSION" --locked + cargo install mdbook-mermaid --version "$TOOL_MDBOOK_MERMAID_VERSION" --locked - name: Install mdbook-admonish - run: cargo install mdbook-admonish --locked + # TODO: pin to a released version once tommilligan/mdbook-admonish#235 merges + run: cargo install --git https://github.com/padamson/mdbook-admonish.git --branch feat/mdbook-0.5-compat mdbook-admonish - name: Install mdbook-rhai-mermaid run: cargo install --path crates/mdbook-rhai-mermaid - - name: Validate docs - run: just docgen-check + - name: Validate GitHub Pages docs payload + run: just docgen-pages-check diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 4f30538..df11906 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -9,6 +9,10 @@ on: permissions: contents: write +env: + TOOL_MDBOOK_VERSION: "0.5.0" + TOOL_MDBOOK_MERMAID_VERSION: "0.17.0" + jobs: deploy: runs-on: ubuntu-latest @@ -19,26 +23,26 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable + - name: Setup Node + uses: actions/setup-node@v4 + - name: Install just run: cargo install just --locked - - name: Setup mdBook - uses: jontze/action-mdbook@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - use-mermaid: true - - - name: Install mdbook binaries - run: cargo install mdbook mdbook-mermaid --locked + - name: Install mdBook toolchain + run: | + cargo install mdbook --version "$TOOL_MDBOOK_VERSION" --locked + cargo install mdbook-mermaid --version "$TOOL_MDBOOK_MERMAID_VERSION" --locked - name: Install mdbook-admonish - run: cargo install mdbook-admonish --locked + # TODO: pin to a released version once tommilligan/mdbook-admonish#235 merges + run: cargo install --git https://github.com/padamson/mdbook-admonish.git --branch feat/mdbook-0.5-compat mdbook-admonish - name: Install mdbook-rhai-mermaid run: cargo install --path crates/mdbook-rhai-mermaid - - name: Build docs - run: just docgen + - name: Validate GitHub Pages docs payload + run: just docgen-pages-check - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v3 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e4aeac4..7191d5f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -53,47 +53,54 @@ jobs: publish-crates: runs-on: ubuntu-latest needs: publish-ghcr - if: ${{ secrets.CRATES_IO_TOKEN != '' }} + env: + CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} steps: - name: Checkout + if: ${{ env.CRATES_IO_TOKEN != '' }} uses: actions/checkout@v4 - name: Install Rust + if: ${{ env.CRATES_IO_TOKEN != '' }} uses: dtolnay/rust-toolchain@stable - name: Publish ledger-core + if: ${{ env.CRATES_IO_TOKEN != '' }} run: cargo publish -p ledger-core --token "${CRATES_IO_TOKEN}" - env: - CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} - name: Wait for crates.io index propagation + if: ${{ env.CRATES_IO_TOKEN != '' }} run: sleep 20 - name: Publish ledgerr-mcp + if: ${{ env.CRATES_IO_TOKEN != '' }} run: cargo publish -p ledgerr-mcp --token "${CRATES_IO_TOKEN}" - env: - CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} publish-pypi: runs-on: ubuntu-latest needs: publish-ghcr - if: ${{ secrets.PYPI_API_TOKEN != '' }} + env: + PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} steps: - name: Checkout + if: ${{ env.PYPI_API_TOKEN != '' }} uses: actions/checkout@v4 - name: Set up Python + if: ${{ env.PYPI_API_TOKEN != '' }} uses: actions/setup-python@v5 with: python-version: "3.11" - name: Build Python package + if: ${{ env.PYPI_API_TOKEN != '' }} working-directory: plugins/l3dg3rr-plugin-create/python run: | python -m pip install --upgrade pip build python -m build - name: Publish to PyPI + if: ${{ env.PYPI_API_TOKEN != '' }} uses: pypa/gh-action-pypi-publish@release/v1 with: packages-dir: plugins/l3dg3rr-plugin-create/python/dist/ diff --git a/.github/workflows/wrkflw-ci-build.yml b/.github/workflows/wrkflw-ci-build.yml new file mode 100644 index 0000000..239d57c --- /dev/null +++ b/.github/workflows/wrkflw-ci-build.yml @@ -0,0 +1,59 @@ +# wrkflw-ci-build: local CI build verification (emulation mode, no Docker required) +# Run with: wrkflw run .github/workflows/wrkflw-ci-build.yml +# Or via: just build +# +# Proves that: +# 1. cargo chef prepare succeeds (the planner step that failed without kani-proofs) +# 2. cargo build -p ledgerr-mcp compiles cleanly +# +# Requires: Rust toolchain on host (cargo-chef installed automatically if missing) +name: wrkflw-ci-build + +on: + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: "1" + +defaults: + run: + shell: bash + +jobs: + planner-smoke: + name: "Planner smoke (cargo chef prepare)" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install cargo-chef + run: | + if ! command -v cargo-chef >/dev/null 2>&1; then + cargo install cargo-chef --locked + fi + + - name: Run cargo chef prepare + run: | + cargo chef prepare --recipe-path /tmp/recipe.json + echo "=== recipe.json written ($(wc -c < /tmp/recipe.json) bytes) ===" + python3 -c " + import json, sys + d = json.load(open('/tmp/recipe.json')) + members = [m['relative_path'] for m in d['skeleton']['manifests']] + print('workspace members in recipe:', len(members)) + for m in members: + print(' ', m) + assert any('kani-proofs' in m for m in members), 'kani-proofs missing from recipe!' + print('PASS: kani-proofs present in cargo chef recipe') + " + + build-mcp: + name: "Build ledgerr-mcp" + needs: [planner-smoke] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build ledgerr-mcp + run: cargo build -p ledgerr-mcp --bin ledgerr-mcp-server diff --git a/.github/workflows/wrkflw-docgen.yml b/.github/workflows/wrkflw-docgen.yml index b9bea1e..ceaa1f5 100644 --- a/.github/workflows/wrkflw-docgen.yml +++ b/.github/workflows/wrkflw-docgen.yml @@ -23,7 +23,7 @@ env: # (wrkflw secure-emulation runs as host processes — no sandboxing of the daemon). # If sccache is not installed, RUSTC_WRAPPER is silently ignored by cargo. RUSTC_WRAPPER: sccache - SCCACHE_DIR: ${{ runner.temp || '/tmp' }}/sccache + SCCACHE_DIR: /tmp/sccache CARGO_TERM_COLOR: always RUST_BACKTRACE: "1" diff --git a/Dockerfile b/Dockerfile index 8cc7e50..a9d226b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,7 @@ FROM chef AS planner COPY Cargo.toml Cargo.lock ./ COPY crates ./crates COPY xtask ./xtask +COPY kani-proofs ./kani-proofs RUN cargo chef prepare --recipe-path recipe.json # ── build ───────────────────────────────────────────────────────────────────── @@ -28,6 +29,7 @@ RUN cargo chef cook --release --recipe-path recipe.json COPY Cargo.toml Cargo.lock ./ COPY crates ./crates COPY xtask ./xtask +COPY kani-proofs ./kani-proofs COPY docs ./docs COPY rules ./rules COPY scripts ./scripts diff --git a/Justfile b/Justfile index a6c4412..3217b43 100644 --- a/Justfile +++ b/Justfile @@ -433,9 +433,12 @@ stats: # Build mdbook documentation locally # Requires: cargo install mdbook mdbook-mermaid && cargo install --path crates/mdbook-rhai-mermaid +# mdbook-admonish: cargo install --git https://github.com/padamson/mdbook-admonish.git --branch feat/mdbook-0.5-compat mdbook-admonish +# TODO: switch to a released version once tommilligan/mdbook-admonish#235 merges docgen: @if [ ! -x ~/.cargo/bin/mdbook ]; then echo "error: mdbook not found — run: cargo install mdbook mdbook-mermaid"; exit 1; fi @if [ ! -x ~/.cargo/bin/mdbook-mermaid ]; then echo "error: mdbook-mermaid not found — run: cargo install mdbook-mermaid"; exit 1; fi + @if [ ! -x ~/.cargo/bin/mdbook-admonish ]; then echo "error: mdbook-admonish not found — see comment above docgen recipe in Justfile"; exit 1; fi @if [ ! -x ~/.cargo/bin/mdbook-rhai-mermaid ]; then cargo install --path crates/mdbook-rhai-mermaid --quiet; fi PATH="$HOME/.cargo/bin:$PATH" ~/.cargo/bin/mdbook build book @echo "Docs built in book/book/ — serve with: npx serve book/book" @@ -475,9 +478,19 @@ docgen-check: @echo "Running live-editor unit tests..." @node --test book/theme/rhai-live-core.test.js @echo "Checking iso-pipeline-objects.html has at least 5 mermaid blocks..." - @count=$$(grep -c 'class="mermaid"' book/book/iso-pipeline-objects.html); echo "Found $$count mermaid blocks in iso-pipeline-objects.html"; if [ "$$count" -lt 5 ]; then echo "error: expected at least 5 mermaid blocks, found $$count"; exit 1; fi; echo "✓ iso-pipeline-objects.html has $$count mermaid blocks (>= 5)" + @count=$(grep -c 'class="mermaid"' book/book/iso-pipeline-objects.html || true); echo "Found $count mermaid blocks in iso-pipeline-objects.html"; if [ "$count" -lt 5 ]; then echo "error: expected at least 5 mermaid blocks, found $count"; exit 1; fi; echo "✓ iso-pipeline-objects.html has $count mermaid blocks, expected at least 5" @echo "All documentation diagrams validated!" +# Verify the exact mdBook output directory published to GitHub Pages. +docgen-pages-check: + just docgen-check + @test -f book/book/index.html || { echo "error: GitHub Pages publish payload missing book/book/index.html"; exit 1; } + @compgen -G 'book/book/theme/rhai-live-core*.js' >/dev/null || { echo "error: GitHub Pages publish payload missing live editor core asset"; exit 1; } + @compgen -G 'book/book/theme/rhai-live-*.js' >/dev/null || { echo "error: GitHub Pages publish payload missing live editor asset"; exit 1; } + @compgen -G 'book/book/mdbook-admonish*.css' >/dev/null || { echo "error: GitHub Pages publish payload missing admonish CSS"; exit 1; } + @grep -q 'l3dg3rr Ledger Documentation' book/book/index.html || { echo "error: GitHub Pages index does not look like the hosted docs"; exit 1; } + @echo "✓ GitHub Pages docs payload validated at book/book/" + # Negative test: verify broken cross-references are present in output (mdBook # does not fail on broken links at build time — this confirms the behavior) docgen-check-negative: @@ -505,6 +518,16 @@ docgen-check-negative: test-mcp-providers: cargo test -p ledgerr-mcp --test mcp_provider_smoke 2>&1 | tail -20 +# ─── build: local CI build via wrkflw ────────────────────────────────────── + +# Prove the Dockerfile planner fix: runs cargo chef prepare + ledgerr-mcp build +# via wrkflw emulation mode (no Docker required). +build emulation="emulation": + @if ! command -v wrkflw >/dev/null 2>&1; then echo "error: wrkflw not found — run: cargo install wrkflw"; exit 1; fi + @echo "=== wrkflw: CI build verification ===" + wrkflw run --runtime {{emulation}} .github/workflows/wrkflw-ci-build.yml + @echo "=== build complete ===" + # ─── wrkflw: local CI pipeline runner ────────────────────────────────────── # Run the wrkflw-local-docgen workflow locally using emulation mode (no Docker). diff --git a/book/book.toml b/book/book.toml index 8bab09f..5ab4c4d 100644 --- a/book/book.toml +++ b/book/book.toml @@ -4,17 +4,17 @@ language = "en" src = "src" title = "l3dg3rr Ledger Documentation" -[preprocessor.admonish] -command = "mdbook-admonish" -assets_version = "3.1.0" # do not edit: managed by `mdbook-admonish install` - [preprocessor.rhai-mermaid] command = "mdbook-rhai-mermaid" before = ["mermaid"] [preprocessor.mermaid] optional = true -after = ["rhai-mermaid", "admonish"] +after = ["rhai-mermaid"] + +[preprocessor.admonish] +command = "mdbook-admonish" +assets_version = "3.1.0" # do not edit: managed by `mdbook-admonish install` [output.html] edit-url-template = "https://github.com/PromptExecution/l3dg3rr/edit/main/book/src/{path}#L{line}" diff --git a/book/src/intro.md b/book/src/intro.md index e183bca..6a90c72 100644 --- a/book/src/intro.md +++ b/book/src/intro.md @@ -1,8 +1,9 @@ # Introduction -```admonish info -**l3dg3rr** is designed for US expats who need to reconcile complex financial histories across multiple jurisdictions (US, AU, UK) without compromising privacy. -``` +
+
Info
+

l3dg3rr is designed for US expats who need to reconcile complex financial histories across multiple jurisdictions (US, AU, UK) without compromising privacy.

+
`l3dg3rr` is a local-first financial document intelligence system for retroactive U.S. expat tax preparation. It ingests raw statements, classifies transactions with editable rules, verifies hard constraints, and exports an accountant-usable Excel workbook with audit history. @@ -53,3 +54,16 @@ The visualization chapters document the live mdBook diagram system. They are imp - [Workbook & Audit](./workbook-audit.md) - [Theory of Operation](./theory.md) - [Graph Data Model](./graph.md) + + +```admonish note title="Local-first by design" +All processing runs on your machine — no private financial data leaves the host. +``` + +```admonish warning +PDF ingestion rewrites the workbook in-place. Back up `tax-ledger.xlsx` before running a full re-ingest. +``` + +```admonish tip title="CPA handoff" +Export the workbook after every classification pass so your accountant always has the latest reconciled state. +``` diff --git a/book/src/iso-pipeline-objects.md b/book/src/iso-pipeline-objects.md index ab8cf0b..c2682b0 100644 --- a/book/src/iso-pipeline-objects.md +++ b/book/src/iso-pipeline-objects.md @@ -29,6 +29,52 @@ screen_y = origin_y + (pt.x + pt.z) * scale * 0.5 - pt.y * scale Contract test: `iso_project(Vec3{x:192, y:0, z:0}, 1.0, 0.0, 0.0)` → `IsoProjected{screen_x:≈166.27, screen_y:96.0}`. +## Rendered Mini-DSL Samples + +These samples use the supported Rhai diagram mini-DSL so the mdBook preprocessor +can emit Mermaid blocks for the GitHub Pages build. + +```rhai +fn raw_statement() -> extracted_rows +fn extracted_rows() -> deterministic_tx_ids +fn deterministic_tx_ids() -> validated_facts +fn validated_facts() -> classified_tx +fn classified_tx() -> workbook_projection +``` + +```rhai +if constraint_passed == true -> legal_verification +if constraint_passed == false -> operator_review +if recovered == true -> legal_verification +if recovered == false -> blocked_queue +``` + +```rhai +match issue.disposition => Unrecoverable -> blocked_queue +match issue.disposition => Recoverable -> repair_pipeline +match issue.disposition => Advisory -> workbook_projection +``` + +```rhai +fn z3_rule_check() -> proof_result +if proof_result == satisfied -> commit_gate +if proof_result == violated -> legal_review +if proof_result == unknown -> operator_review +``` + +```rhai +fn commit_gate() -> audit_log +fn audit_log() -> evidence_graph +fn evidence_graph() -> cpa_workbook +fn cpa_workbook() -> exported_artifact +``` + +```rhai +fn operator_review() -> approval_decision +fn approval_decision() -> replayable_audit_event +fn replayable_audit_event() -> evidence_graph +``` + ## Pipeline Layer (z=1) ### `PipelineState` diff --git a/cog.toml b/cog.toml index 8da73e2..e52fb45 100644 --- a/cog.toml +++ b/cog.toml @@ -1,7 +1,6 @@ from_latest_tag = true tag_prefix = "v" ignore_merge_commits = true -ignore_fixup_commits = true disable_changelog = false disable_bump_commit = false generate_mono_repository_global_tag = true diff --git a/docs/mcp-capability-contract.md b/docs/mcp-capability-contract.md index 1e43f79..0c53b13 100644 --- a/docs/mcp-capability-contract.md +++ b/docs/mcp-capability-contract.md @@ -11,7 +11,7 @@ The default catalog is intentionally small: 9 top-level `ledgerr_*` tools. Each | Tool | Purpose | Common actions | |---|---|---| | `ledgerr_documents` | document intake (PDF, image, CSV), tagging, filesystem metadata sync | `list_accounts`, `pipeline_status`, `validate_filename`, `ingest_pdf`, `ingest_image`, `ingest_rows`, `get_raw_context`, `document_inventory`, `apply_tags`, `remove_tags`, `list_tagged`, `sync_fs_metadata`, `normalize_filename` | -| `ledgerr_review` | classification and human-review workflows | `run_rule`, `classify_ingested`, `query_flags`, `classify_transaction`, `reconcile_excel_classification` | +| `ledgerr_review` | classification and human-review workflows | `run_rule`, `classify_ingested`, `query_flags`, `classify_transaction`, `reconcile_excel_classification`, `query_transactions`, `batch_classify`, `bulk_resolve_flags`, `apply_mapping_bulk`, `fetch_work_queue` | | `ledgerr_reconciliation` | staged totals/postings guardrails | `validate`, `reconcile`, `commit` | | `ledgerr_workflow` | lifecycle/HSM orchestration plus relocated plugin ops | `status`, `transition`, `resume`, `plugin_info` | | `ledgerr_audit` | append-only event and audit-log views | `event_history`, `event_replay`, `query_audit_log` |