docs: finance/books/ledger boundary contracts + proposals#119
docs: finance/books/ledger boundary contracts + proposals#119chitcommit wants to merge 6 commits into
Conversation
|
@coderabbitai review Please evaluate:
|
📝 WalkthroughWalkthroughThis PR adds architectural contracts and proposals to establish clear boundaries and integration patterns for the ChittyFinance system. It clarifies API routing conventions, documents ownership between ChittyBooks and ChittyFinance, defines Mercury tenant isolation requirements, revises the connector plan to use real services, and proposes a naming-collision resolution for ChittyLedger. ChangesSystem Architecture Contracts and Proposals
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Docs-only PR adding boundary contracts and proposals from a goal audit of the finance/books/ledger surfaces. No runtime or schema changes. Clarifies the /api/v1 prefix convention in CLAUDE.md, retires the fake books.chitty.cc live-API assumption, flags a schema gap for legal_person_chittyid on accounts, and proposes a rename plan for the legacy CHITTYOS/chittyledger repo.
Changes:
- Adds four new docs under
docs/contracts/anddocs/proposals/describing the engine/UI boundary, Mercury multitenant model, API prefix resolution, connector revisions, and naming plan. - Updates one line in
CLAUDE.mdto clarify resource routes (/api/<resource>) vs meta routes (/api/v1/*).
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| CLAUDE.md | Clarifies /api/v1 is meta-only; resource routes are unprefixed. |
| docs/contracts/chittybooks-chittyfinance.md | Defines ChittyBooks↔ChittyFinance engine/UI boundary and source-of-truth table. |
| docs/contracts/mercury-multitenant.md | Documents tenant + Legal Person isolation; flags missing legal_person_chittyid column. |
| docs/proposals/api-v1-prefix-fix.md | Resolves /api/v1/* 404 report as non-issue; proposes one-line CLAUDE.md note. |
| docs/proposals/ch1tty-connector-revision.md | Proposes routing through real services and gating dead CHITTYBOOKS_URL. |
| docs/proposals/chittyledger-naming-plan.md | Plan to rename CHITTYOS/chittyledger → -evidence-legacy. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Code Review — PR #119: docs: finance/books/ledger boundary contracts + proposalsScope: Docs-only — 5 new markdown files + 1 CLAUDE.md line edit. No runtime risk. OverviewThis PR documents the architecture audit of the finance/books/ledger surfaces. The research is thorough, the evidence is cited with file paths and line numbers, and the schema gap discovery is a genuine catch. The deploy-gate checklists and "not decided here" discipline are well-executed. FindingsBug / Correctness
Naming / Style
Tracking / Process
Minor
Summary
Recommendation: Open a GitHub issue for the |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/contracts/chittybooks-chittyfinance.md`:
- Line 12: The table row that lists "ChittyLedger (legacy fork)" currently
references the wrong repository identifier `CHITTYOS/chittybooks`; update that
repo string to `CHITTYOS/chittyledger` so the legacy ledger entry points to the
correct repository (look for the row containing "ChittyLedger (legacy fork)" and
replace the `CHITTYOS/chittybooks` token with `CHITTYOS/chittyledger`), and make
the same fix for the duplicate occurrence noted around the other mentioned line.
In `@docs/contracts/mercury-multitenant.md`:
- Around line 14-22: Add a language tag to the fenced diagram block that begins
with "Person (P-Legal, e.g. "IT CAN BE LLC")" so it stops triggering
markdownlint MD040; update the opening triple-backtick to include a language
identifier (e.g., ```text) for that diagram block.
In `@docs/proposals/chittyledger-naming-plan.md`:
- Around line 16-25: The fenced code block that begins with ``` has no language
identifier causing markdownlint MD040; update that opening fence to include a
language such as text (e.g., change ``` to ```text or ```plaintext) so the block
is explicitly labeled and the linter warning is resolved.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: aebb8db2-8511-4478-aed5-12b5c9fc1c30
📒 Files selected for processing (6)
CLAUDE.mddocs/contracts/chittybooks-chittyfinance.mddocs/contracts/mercury-multitenant.mddocs/proposals/api-v1-prefix-fix.mddocs/proposals/ch1tty-connector-revision.mddocs/proposals/chittyledger-naming-plan.md
| | ChittyFinance (engine) | `CHITTYAPPS/chittyfinance` | Hono on CF Workers at `finance.chitty.cc` | `200 ok` | | ||
| | ChittyBooks (UI/app) | `CHITTYAPPS/chittybooks` | Python Flask, `main.py`, Dockerfile, `.replit` → `cloudrun` | **Not deployed**. `books.chitty.cc` does not resolve. | | ||
| | ChittyLedger (substrate) | `CHITTYFOUNDATION/chittyledger` | Worker at `ledger.chitty.cc` | `200 ok` | | ||
| | ChittyLedger (legacy fork) | `CHITTYOS/chittybooks` | Express + React, in-memory, not deployed | n/a — DUPLICATE, candidate for retirement or repurpose as ChittyLedger-Evidence seed | |
There was a problem hiding this comment.
Incorrect legacy repo identifier for ChittyLedger.
The contract points to CHITTYOS/chittybooks, but this proposal set describes the legacy ledger collision as CHITTYOS/chittyledger. Keeping this as-is can send follow-up actions to the wrong repo.
Suggested fix
-| ChittyLedger (legacy fork) | `CHITTYOS/chittybooks` | Express + React, in-memory, not deployed | n/a — DUPLICATE, candidate for retirement or repurpose as ChittyLedger-Evidence seed |
+| ChittyLedger (legacy fork) | `CHITTYOS/chittyledger` | Express + React, in-memory, not deployed | n/a — DUPLICATE, candidate for retirement or repurpose as ChittyLedger-Evidence seed |
...
-- [ ] `CHITTYOS/chittybooks` legacy fork is renamed, archived, or repurposed as ChittyLedger-Evidence — do not let it shadow the canonical surface.
+- [ ] `CHITTYOS/chittyledger` legacy fork is renamed, archived, or repurposed as ChittyLedger-Evidence — do not let it shadow the canonical surface.Also applies to: 84-84
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/contracts/chittybooks-chittyfinance.md` at line 12, The table row that
lists "ChittyLedger (legacy fork)" currently references the wrong repository
identifier `CHITTYOS/chittybooks`; update that repo string to
`CHITTYOS/chittyledger` so the legacy ledger entry points to the correct
repository (look for the row containing "ChittyLedger (legacy fork)" and replace
the `CHITTYOS/chittybooks` token with `CHITTYOS/chittyledger`), and make the
same fix for the duplicate occurrence noted around the other mentioned line.
| ``` | ||
| Person (P-Legal, e.g. "IT CAN BE LLC") | ||
| │ legal_person_chittyid | ||
| └── Account (Mercury account #1, #2, ...) | ||
| │ tenant_id | ||
| └── Transaction (mercury txn rows) | ||
| │ metadata.mercury_kind, mercury_id | ||
| └── Allocation → Property/Lease (Business surface) | ||
| ``` |
There was a problem hiding this comment.
Add a language tag to the fenced diagram block.
This fenced block is missing a language identifier and triggers markdownlint MD040.
Suggested fix
-```
+```text
Person (P-Legal, e.g. "IT CAN BE LLC")
│ legal_person_chittyid
└── Account (Mercury account `#1`, `#2`, ...)
│ tenant_id
└── Transaction (mercury txn rows)
│ metadata.mercury_kind, mercury_id
└── Allocation → Property/Lease (Business surface)</details>
<details>
<summary>🧰 Tools</summary>
<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>
[warning] 14-14: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
</details>
</details>
<details>
<summary>🤖 Prompt for AI Agents</summary>
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @docs/contracts/mercury-multitenant.md around lines 14 - 22, Add a language
tag to the fenced diagram block that begins with "Person (P-Legal, e.g. "IT CAN
BE LLC")" so it stops triggering markdownlint MD040; update the opening
triple-backtick to include a language identifier (e.g., ```text) for that
diagram block.
</details>
<!-- fingerprinting:phantom:triton:hawk -->
<!-- This is an auto-generated comment by CodeRabbit -->
| ``` | ||
| ChittyLedger (substrate) — CHITTYFOUNDATION/chittyledger — ledger.chitty.cc | ||
| ├── ChittyLedger-Finance — projection (tables in substrate DB; surface via ChittyFinance) | ||
| │ schema doc: docs/chittyledger-finance-design.md (already canon) | ||
| │ writer: ChittyFinance via /entries | ||
| │ reader: ChittyFinance, ChittyBooks (read-only via ChittyFinance aggregators) | ||
| └── ChittyLedger-Evidence — projection (tables in substrate DB; surface via ChittyEvidence) | ||
| writer: ChittyTrace + ChittyEvidence via /entries | ||
| reader: ChittyCases, ChittyResolution | ||
| ``` |
There was a problem hiding this comment.
Add a language identifier to the fenced code block.
Line 16 opens a fenced block without a language, which triggers markdownlint MD040. Use text (or plaintext) to satisfy linting.
Suggested diff
-```
+```text
ChittyLedger (substrate) — CHITTYFOUNDATION/chittyledger — ledger.chitty.cc
├── ChittyLedger-Finance — projection (tables in substrate DB; surface via ChittyFinance)
│ schema doc: docs/chittyledger-finance-design.md (already canon)
│ writer: ChittyFinance via /entries
│ reader: ChittyFinance, ChittyBooks (read-only via ChittyFinance aggregators)
└── ChittyLedger-Evidence — projection (tables in substrate DB; surface via ChittyEvidence)
writer: ChittyTrace + ChittyEvidence via /entries
reader: ChittyCases, ChittyResolution</details>
<details>
<summary>🧰 Tools</summary>
<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>
[warning] 16-16: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
</details>
</details>
<details>
<summary>🤖 Prompt for AI Agents</summary>
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @docs/proposals/chittyledger-naming-plan.md around lines 16 - 25, The fenced
code block that begins with has no language identifier causing markdownlint MD040; update that opening fence to include a language such as text (e.g., change to text or plaintext) so the block is explicitly labeled and
the linter warning is resolved.
</details>
<!-- fingerprinting:phantom:triton:hawk -->
<!-- This is an auto-generated comment by CodeRabbit -->
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b5a1ff248b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| | `/api/allocations` | Allocation rules + history | | ||
| | `/api/classification` | COA assignments + audit trail | |
There was a problem hiding this comment.
Document the mounted allocation/classification endpoints
The code mounts allocation handlers only under /api/allocations/rules, /api/allocations/preview, /api/allocations/execute, and /api/allocations/runs, and classification handlers under subpaths plus /api/coa; there is no base GET/POST /api/allocations or base /api/classification handler. Because this table is labeled “verified mounted” and defines what ChittyBooks should consume, clients following it will hit 404s. Please list the actual mounted paths or explicitly mark these as prefixes.
Useful? React with 👍 / 👎.
| - `GET /api/transactions?source=mercury` — Mercury txns scoped to caller's tenant | ||
| - `GET /api/transactions?source=wave` — Wave txns scoped to caller's tenant | ||
| - `GET /api/transactions?source=stripe` — Stripe charges scoped to caller's tenant | ||
| - `GET /api/reports/reconciliation?tenant_id=...&period=...` — three-way diff (Mercury ↔ Wave ↔ Stripe) |
There was a problem hiding this comment.
Don't advertise an unmounted reconciliation route
The repo does not mount /api/reports/reconciliation; server/routes/reports.ts currently exposes only GET /api/reports/consolidated under /api/reports. If ChittyBooks implements this contract for the Mercury/Wave/Stripe diff, the documented request will 404. Either add the reconciliation route before publishing this contract or point the doc at an existing endpoint.
Useful? React with 👍 / 👎.
|
|
||
| ## API Surface ChittyBooks consumes | ||
|
|
||
| All paths are under `https://finance.chitty.cc`. Auth: ChittyAuth Bearer token. Tenant: `X-Tenant-ID` header (server-side enforces from JWT claims; path param is not trusted). |
There was a problem hiding this comment.
Document an auth mode the API accepts
server/middleware/auth.ts only treats an Authorization: Bearer ... header as the service token (CHITTY_AUTH_SERVICE_TOKEN); ChittyAuth JWTs are accepted via the session cookie path, not as bearer tokens. If ChittyBooks sends a ChittyAuth Bearer token as this contract specifies, protected routes will return 401 before tenant resolution. Please document service-token auth plus the required caller header, or the cookie/JWT flow that actually works.
Useful? React with 👍 / 👎.
| | ChittyFinance (engine) | `CHITTYAPPS/chittyfinance` | Hono on CF Workers at `finance.chitty.cc` | `200 ok` | | ||
| | ChittyBooks (UI/app) | `CHITTYAPPS/chittybooks` | Python Flask, `main.py`, Dockerfile, `.replit` → `cloudrun` | **Not deployed**. `books.chitty.cc` does not resolve. | | ||
| | ChittyLedger (substrate) | `CHITTYFOUNDATION/chittyledger` | Worker at `ledger.chitty.cc` | `200 ok` | | ||
| | ChittyLedger (legacy fork) | `CHITTYOS/chittybooks` | Express + React, in-memory, not deployed | n/a — DUPLICATE, candidate for retirement or repurpose as ChittyLedger-Evidence seed | |
There was a problem hiding this comment.
Point the legacy ledger row at the ledger repo
This row labels CHITTYOS/chittybooks as the legacy ChittyLedger fork, while the companion naming plan identifies CHITTYOS/chittyledger as the collision and rename target. Since the deploy gate later tells operators to rename/archive this legacy fork, following this contract could repurpose the ChittyBooks UI repo instead of the legacy ledger repo.
Useful? React with 👍 / 👎.
| | Bookkeeping reads | ChittyFinance | `GET https://finance.chitty.cc/api/transactions` and `/api/reports/*` | | ||
| | Bookkeeping writes | ChittyFinance | `POST https://finance.chitty.cc/api/transactions`, `/api/allocations`, `/api/classification` — **not** a separate `chittybooks` write API | | ||
| | Credentials | ChittyConnect | `https://connect.chitty.cc` via concierge — never chat-paste | | ||
| | Ledger writes | ChittyLedger | `https://ledger.chitty.cc/entries` (auth-required) | |
There was a problem hiding this comment.
Use the ledger write path Finance exercises
ChittyFinance's ledger client and its test post ledger entries to ${base}/api/entries, but this proposal tells the follow-up ChittyCommand work to write to https://ledger.chitty.cc/entries. If that connector follows this doc, its ledger writes will use a different path than the existing Finance integration and can fail against the currently exercised contract.
Useful? React with 👍 / 👎.
| - `GET /api/transactions?source=mercury` — Mercury txns scoped to caller's tenant | ||
| - `GET /api/transactions?source=wave` — Wave txns scoped to caller's tenant | ||
| - `GET /api/transactions?source=stripe` — Stripe charges scoped to caller's tenant |
There was a problem hiding this comment.
Don't promise transaction source filters
GET /api/transactions currently reads only the optional limit query and calls storage.getTransactions(tenantId, limit), which filters by tenant but not by source. In reconciliation contexts that use ?source=mercury, ?source=wave, or ?source=stripe as documented here, the API will return the full tenant transaction feed instead of the requested source-specific set.
Useful? React with 👍 / 👎.
| |---|---|---| | ||
| | Mercury read API | `https://api.mercury.com/api/v1` (direct, OAuth tokens scoped per tenant) | Token issued per `(tenant_id, legal_person_chittyid)` via ChittyConnect | | ||
| | Mercury write API | `mercury-proxy` on `chittyserv-dev` (IP-allowlisted by Mercury) | `X-Mercury-Token` per request; proxy is stateless re tenancy | | ||
| | Mercury webhooks | `/api/webhooks/mercury` on `finance.chitty.cc` | Per-business HMAC secret, resolves to `tenant_id` + `legal_person_chittyid` before write | |
There was a problem hiding this comment.
Use the native Mercury webhook URL for HMAC
The HMAC-verified Mercury receiver is mounted at POST /api/webhooks/mercury/:tenantId; the base POST /api/webhooks/mercury path is the legacy ChittyConnect-normalized receiver authenticated only by service token. Registering Mercury webhooks against the base URL as documented here will bypass the per-tenant HMAC flow and fail for native Mercury event payloads.
Useful? React with 👍 / 👎.
* refactor(server): split routes into books vs accounting concerns Introduce a structural books/accounting boundary with no behavior change. Books writes facts (ingest, categorize, journal); accounting derives meaning (chart of accounts, reporting, tax, allocations). - move transactions/import/webhooks -> server/books/ - move accounts/reports/tax/allocations -> server/accounting/ - add concern-boundary READMEs for each tree - classification.ts stays in routes/ (straddles both); note added - fix import paths in app.ts and __tests__ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(deps): resolve @chittyos/schema lockfile drift Revert PR #103's refactor that introduced an unresolvable file: dependency. Root cause: PR #103 swapped the self-contained local scope-projector for a thin adapter over `@chittyos/schema`, declared as `file:../../CHITTYFOUNDATION/chittyschema`. That sibling-repo path only exists on the dev VM. In CI it cannot resolve, and worse, pnpm 10 refuses to record file: directory links in the lockfile importer block at all — so `pnpm install --frozen-lockfile` always sees a specifier mismatch ("1 dependencies were added: @chittyos/schema@file:..."), failing the Dependency Audit (High+) gate on every PR (#119, #120). No clean dependency form resolves in CI: the package is unpublished (npm 404), its dist/ is gitignored in the sibling repo (so a github: dep ships no build), and it has no prepare script. Fix: restore the pre-#103 self-contained implementation of server/lib/central-workflows.ts (175 lines, uses @neondatabase/serverless which is already a dependency) and drop the @chittyos/schema dependency. Public API (scopeLog, SCOPE_TYPES, ScopeStatus, etc.) is unchanged, so callers in workflows.ts and reports.ts are unaffected. Regenerated lockfile. Verified in a clean checkout (sibling repo absent, pnpm 10): pnpm install --frozen-lockfile -> exit 0 pnpm audit --prod --audit-level high ... -> exit 0 npm run check (tsc) -> exit 0 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…1 prefix fix proposal Three artifacts for /goal "ChittyFinance + ChittyBooks as finance/bookkeeping surface over ChittyLedger". All evidence-grounded — no invented schemas, no deploys. - docs/contracts/chittybooks-chittyfinance.md: engine/UI boundary, source-of-truth table, deploy decision (recommend retire chittybooks.chitty.cc, fold UI into ChittyFinance) with reconciled Charter/repo mismatch flagged - docs/contracts/mercury-multitenant.md: tenant_id + legal_person_chittyid binding rules, Wave mapping requirement, ChittyBooks reconciliation surface, explicit out-of-scope for direct Mercury calls - docs/proposals/api-v1-prefix-fix.md: finance.chitty.cc /api/v1/* 404 is a docs↔code mismatch (only /api/v1/documentation exists; data routes are /api/*). Verified ChittyCommand consumer already uses /api/* — Option 1 (fix docs) has zero downstream breakage.
- ch1tty-connector-revision.md: names the dead CHITTYBOOKS_URL endpoint in chittycommand's mercury-chittybooks plan + booksClient at integrations.ts:618, routes all bookkeeping reads/writes through real finance.chitty.cc paths - chittyledger-naming-plan.md: substrate (FOUNDATION/chittyledger) + projections (Finance, Evidence). Plan to rename CHITTYOS/chittyledger → -evidence-legacy, clean nested noise, add disambiguation banners.
…d schema gap, resolve api-v1 as non-issue
- contracts/chittybooks-chittyfinance.md: DECISION (was Recommendation) with
6-row repo-file proof table — Python+cloudrun+no wrangler+no DNS+engine already
in chittyfinance+tenant boundary at finance schema
- contracts/mercury-multitenant.md: CRITICAL adversarial finding —
legal_person_chittyid column absent from accounts schema; remediation paths
A/B; tenant_id NOT NULL defense-in-depth verified OK
- proposals/api-v1-prefix-fix.md: resolved as non-issue; /api/v1/{status,
metrics,documentation} are real meta routes (server/routes/health.ts:21,38),
resource routes correctly at /api/<resource>. Single CLAUDE.md sentence added.
- CLAUDE.md: clarify route mount split (meta under /api/v1, resources under /api)
…deploy choice as operator gate
b5a1ff2 to
e15f239
Compare
|
@coderabbitai review Please evaluate:
|
🧩 Analysis chain🏁 Script executed: #!/bin/bash
echo "=== CLAUDE.md relevant section ==="
grep -n "api\|v1\|route\|mount" CLAUDE.md | head -30
echo "=== docs/contracts/chittybooks-chittyfinance.md ==="
cat docs/contracts/chittybooks-chittyfinance.md
echo "=== docs/contracts/mercury-multitenant.md ==="
cat docs/contracts/mercury-multitenant.md
echo "=== docs/proposals/api-v1-prefix-fix.md ==="
cat docs/proposals/api-v1-prefix-fix.md
echo "=== docs/proposals/ch1tty-connector-revision.md ==="
cat docs/proposals/ch1tty-connector-revision.md
echo "=== docs/proposals/chittyledger-naming-plan.md ==="
cat docs/proposals/chittyledger-naming-plan.md
echo "=== Check for secrets/tokens/keys in docs ==="
rg -i "(api.?key|secret|password|token|bearer|credential|private.?key|access.?key|webhook.?secret)" docs/ -n
echo "=== Check for hardcoded URLs with auth ==="
rg "https?://[^@\s]*:[^@\s]*@" docs/ -n
echo "=== Check for any package changes ==="
git diff origin/main --name-only | head -30
echo "=== Check for dependency file changes ==="
git diff origin/main -- package.json package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null | head -50Length of output: 40420
Security Implications
Credential Exposure RiskNone found in the 5 new files.
Dependency Supply Chain ConcernsNone. No Breaking API ChangesNone. No source code was changed. The SummaryThis PR is safe to merge from a security standpoint with one actionable recommendation:
Additionally, the ✅ Actions performedReview triggered.
|
Code Review — PR #119: docs: finance/books/ledger boundary contracts + proposalsSummary: Docs-only PR (267 additions, 1 deletion) that introduces 5 new contract/proposal files and a 1-line OverviewThis PR does good forensic work — verifying deployed surfaces, naming collisions, and dead code paths against actual DNS/file evidence rather than assumptions. The verification methodology (citing exact file paths, line numbers, What's Good
IssuesCRITICAL (Blocker)
MEDIUMFilename typo: This breaks Cross-repo line number references will go stale.
Line numbers in other repos drift immediately on the next commit. Since these are proposals (not contracts), consider citing symbols/function names instead of line numbers where possible, or add a "Verified at" date so readers know to re-verify.
The LOW / Nits
SecurityThe Mercury multitenancy model is correctly reasoned:
The Summary
The underlying analysis is solid and this docs infrastructure is useful. The blocker is the missing issue tracker entry for the schema gap — docs-only blockers get lost. The filename typo should be fixed before merge. Everything else is addressable in follow-up. Reviewed by Claude Sonnet 4.6 via Claude Code |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e15f239ed8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| 1. **`tenant_id` required on every Mercury-derived record.** No row, webhook event, or queue message lacks it. Cross-tenant reads are server-side blocked, not client-trusted. | ||
| 2. **Legal Person ChittyID binding required.** Every Mercury account maps to exactly one Legal Person (`P-Legal` entity), recorded as `legal_person_chittyid` on the account row. Account ↔ Legal Person is many-to-one (one LLC can have many accounts). | ||
| 3. **Wave business mapping required.** Each `(tenant_id, legal_person_chittyid)` pair has at most one Wave business; the mapping lives in `integration_account_links` (source = `wave`, target = `mercury`). Unmapped Mercury accounts produce reconciliation conflicts, not silent omission. |
There was a problem hiding this comment.
Do not point Wave mapping at a nonexistent table
This contract makes integration_account_links the required persistence point for the Wave↔Mercury mapping, but a repo-wide search only finds that name in this new document and database/system.schema.ts defines integrations without any link table. Until a real table/metadata field is named or added, implementers cannot satisfy the non-negotiable mapping requirement and reconciliation work will be built against a storage object that does not exist.
Useful? React with 👍 / 👎.
| - `GET /api/transactions?source=wave` — Wave txns scoped to caller's tenant | ||
| - `GET /api/transactions?source=stripe` — Stripe charges scoped to caller's tenant | ||
| - `GET /api/reports/reconciliation?tenant_id=...&period=...` — three-way diff (Mercury ↔ Wave ↔ Stripe) | ||
| - `GET /api/integrations/status` — per-source connection health + last-sync timestamps |
There was a problem hiding this comment.
Narrow the integration status contract
The mounted GET /api/integrations/status handler in server/routes/integrations.ts only returns per-provider configured booleans derived from environment variables; it does not read tenant integration rows or include lastSynced values. A ChittyBooks reconciliation UI following this contract will expect connection health and last-sync timestamps that the API never returns, so either the docs should describe the current shape or the endpoint should be extended before consumers depend on it.
Useful? React with 👍 / 👎.
| | `/api/tenants` | List tenants the caller can read | | ||
| | `/api/properties` | Property list | | ||
| | `/api/accounts` | Account list + balances | | ||
| | `/api/transactions` | Transaction feed (filter by date, account, tenant) | |
There was a problem hiding this comment.
Do not promise unsupported transaction filters
GET /api/transactions currently reads only the optional limit query before calling storage.getTransactions(tenantId, limit), so date or account filters documented here will be silently ignored and the full tenant feed will be returned. If ChittyBooks builds list views or exports around these filters, users can see unrelated transactions for the selected date/account context; either document the current query shape or add the filters before advertising them.
Useful? React with 👍 / 👎.
| |---|---|---| | ||
| | Mercury read API | `https://api.mercury.com/api/v1` (direct, OAuth tokens scoped per tenant) | Token issued per `(tenant_id, legal_person_chittyid)` via ChittyConnect | | ||
| | Mercury write API | `mercury-proxy` on `chittyserv-dev` (IP-allowlisted by Mercury) | `X-Mercury-Token` per request; proxy is stateless re tenancy | | ||
| | Mercury webhooks | `/api/webhooks/mercury` on `finance.chitty.cc` | Per-business HMAC secret, resolves to `tenant_id` + `legal_person_chittyid` before write | |
There was a problem hiding this comment.
Do not claim webhooks resolve legal persons
The native Mercury webhook implementation is keyed only by :tenantId and reads webhook:mercury:secret:${tenantId}, then resolves at most a local account by Mercury account ID; it never derives or persists legal_person_chittyid. For tenants with more than one Mercury-backed legal person, this documented per-business resolution cannot happen, so downstream reconciliation would lose the legal-person binding even if the tenant is identified.
Useful? React with 👍 / 👎.
|
|
||
| ## ChittyLedger projection paths (read-only) | ||
|
|
||
| ChittyBooks reads ChittyLedger-Finance projection tables via `ChittyFinance` aggregator endpoints — it does not query ChittyLedger directly. This preserves the substrate boundary: ChittyLedger does not know about ChittyBooks. |
There was a problem hiding this comment.
Define the projection aggregator endpoints before relying on them
This says ChittyBooks reads ChittyLedger-Finance projection tables through ChittyFinance aggregator endpoints, but a route search only finds the current finance resources (/api/reports/consolidated, classification/allocation routes, MCP resources) and no mounted endpoint for financial_documents, financial_facts, or reconciliation_conflicts. A ChittyBooks UI built against this contract has no API path for the promised read-only projection data, so the contract should name existing endpoints or gate this section until the aggregators are implemented.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
♻️ Duplicate comments (2)
docs/contracts/chittybooks-chittyfinance.md (1)
12-12:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winIncorrect legacy repo identifier for ChittyLedger.
The contract points to
CHITTYOS/chittybooks, but based on the chittyledger naming plan in this proposal set, the legacy ledger collision isCHITTYOS/chittyledger.Suggested fix
-| ChittyLedger (legacy fork) | `CHITTYOS/chittybooks` | Express + React, in-memory, not deployed | n/a — DUPLICATE, candidate for retirement or repurpose as ChittyLedger-Evidence seed | +| ChittyLedger (legacy fork) | `CHITTYOS/chittyledger` | Express + React, in-memory, not deployed | n/a — DUPLICATE, candidate for retirement or repurpose as ChittyLedger-Evidence seed |Also applies to: 84-84
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/contracts/chittybooks-chittyfinance.md` at line 12, Update the legacy repo identifier in the ChittyLedger table entry: replace the incorrect string `CHITTYOS/chittybooks` with the correct identifier `CHITTYOS/chittyledger` in the table row that currently reads "ChittyLedger (legacy fork) | `CHITTYOS/chittybooks`"; ensure the same replacement is applied to the duplicate occurrence noted (also at the second location mentioned).docs/proposals/chittyledger-naming-plan.md (1)
16-25:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd a language identifier to the fenced code block.
The fenced code block is missing a language identifier, which triggers markdownlint MD040. Add
textorplaintextto the opening fence.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/proposals/chittyledger-naming-plan.md` around lines 16 - 25, The fenced code block containing the ChittyLedger tree should include a language identifier to satisfy markdownlint MD040; update the opening fence (the line starting with ```) to include a language token such as "text" or "plaintext" so it reads ```text (or ```plaintext) above the ChittyLedger block to silence the linter.
🧹 Nitpick comments (1)
docs/proposals/api-v1-prefix-fix.md (1)
21-21: ⚡ Quick winCapitalize "GitHub" for correctness.
The proper capitalization is "GitHub" with a capital "H".
📝 Proposed fix
-- All 5 in-repo references to `/api/v1` (`.github/workflows/register.yml`, `deploy/registration/chittyfinance.registration.json`, `client/src/pages/Landing.tsx:342`, `.claude/commands/quick-deploy.md:28`, plans) point at real endpoints. **Nothing to fix.** +- All 5 in-repo references to `/api/v1` (`.GitHub/workflows/register.yml`, `deploy/registration/chittyfinance.registration.json`, `client/src/pages/Landing.tsx:342`, `.claude/commands/quick-deploy.md:28`, plans) point at real endpoints. **Nothing to fix.**🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/proposals/api-v1-prefix-fix.md` at line 21, The document text "GitHub" is not capitalized correctly; locate the sentence that reads "All 5 in-repo references to `/api/v1` (...) point at real endpoints. **Nothing to fix.**" and any nearby mention of "Github" or "GitHub", and update the word to the correct capitalization "GitHub" (ensure every occurrence in this proposal line and surrounding notes uses "GitHub").
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@docs/contracts/chittybooks-chittyfinance.md`:
- Line 12: Update the legacy repo identifier in the ChittyLedger table entry:
replace the incorrect string `CHITTYOS/chittybooks` with the correct identifier
`CHITTYOS/chittyledger` in the table row that currently reads "ChittyLedger
(legacy fork) | `CHITTYOS/chittybooks`"; ensure the same replacement is applied
to the duplicate occurrence noted (also at the second location mentioned).
In `@docs/proposals/chittyledger-naming-plan.md`:
- Around line 16-25: The fenced code block containing the ChittyLedger tree
should include a language identifier to satisfy markdownlint MD040; update the
opening fence (the line starting with ```) to include a language token such as
"text" or "plaintext" so it reads ```text (or ```plaintext) above the
ChittyLedger block to silence the linter.
---
Nitpick comments:
In `@docs/proposals/api-v1-prefix-fix.md`:
- Line 21: The document text "GitHub" is not capitalized correctly; locate the
sentence that reads "All 5 in-repo references to `/api/v1` (...) point at real
endpoints. **Nothing to fix.**" and any nearby mention of "Github" or "GitHub",
and update the word to the correct capitalization "GitHub" (ensure every
occurrence in this proposal line and surrounding notes uses "GitHub").
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3d10a2f6-50cc-42a2-9cbb-a414a8acbd92
📒 Files selected for processing (6)
CLAUDE.mddocs/contracts/chittybooks-chittyfinance.mddocs/contracts/mercury-multitenant.mddocs/proposals/api-v1-prefix-fix.mddocs/proposals/ch1tty-connector-revision.mddocs/proposals/chittyledger-naming-plan.md
✅ Files skipped from review due to trivial changes (1)
- CLAUDE.md
Implements step 5 of the chittyledger naming-collision plan (PR #119). Documents ChittyFinance as the writer for the ChittyLedger-Finance projection over the substrate at ledger.chitty.cc. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implements step 3 of the chittyledger naming-collision plan (chittyapps/chittyfinance#119). The nested chittyledger/ directory was working-tree noise from a prior submodule experiment — not an actual submodule (no .gitmodules entry, no .git inside, tracked as plain files). Deletes 104 stray files. No code references this path. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implements step 3 of the chittyledger naming-collision plan (chittyapps/chittyfinance#119). The nested chittyfinance/ directory was working-tree noise from a prior experiment — not a submodule (no .gitmodules), not a nested git repo, tracked as plain files. The canonical ChittyFinance repo lives at CHITTYAPPS/chittyfinance. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Docs-only branch from /goal audit of finance/books/ledger surfaces. No code or runtime changes.
Five new docs:
docs/contracts/chittybooks-chittyfinance.md— engine/UI boundary, source-of-truth table, API surface, deploy decision (retires the fakebooks.chitty.cclive-API assumption only; actual deploy choice stays an explicit operator gate)docs/contracts/mercury-multitenant.md— tenant_id + legal_person_chittyid + Wave mapping rules. Flags critical schema gap:legal_person_chittyidis not onaccountsindatabase/system.schema.tsdocs/proposals/api-v1-prefix-fix.md— resolves the/api/v1/*404 as a non-issue (meta routes are intentionally under/api/v1, resource routes under/api/<resource>). One-sentenceCLAUDE.mdclarification only.docs/proposals/ch1tty-connector-revision.md— names the deadCHITTYBOOKS_URLendpoint inchittycommand/docs/plans/2026-02-23-mercury-chittybooks-plan.md:168andchittycommand/src/lib/integrations.ts:618; routes bookkeeping reads/writes through realfinance.chitty.ccpathsdocs/proposals/chittyledger-naming-plan.md— substrate (FOUNDATION/chittyledger) + Finance/Evidence projections; plan to renameCHITTYOS/chittyledger→-evidence-legacyValidation
financeClientverified to call/api/accountsnot/api/v1/accounts→ docs-only path-prefix clarification has zero consumer breakage./api/v1/documentationenumerated: 9 paths, only/healthand/api/v1/{status,metrics,documentation}under/api/v1; resource paths at/api/*.SystemStorageenforces tenancy viatenant_id NOT NULLschema column + 117tenantIdreferences.Followups (not in this PR)
CHITTYOS/chittycommand): lazy-disablebooksClient— PR-ready, awaiting owner approvalCHITTYOS/chittyledgerrename: org-owner action🤖 Generated with Claude Code
Summary by CodeRabbit