cloudinit-bot 5bb9eed5e4 docs(review): v1.3 multi-persona code review PASS-with-NITS (8 PRs, 0 P0, 2 P1, 3 P2)
The v1.3 EXECUTE stage landed 8 PRs / 8 commits closing
9 ACCEPT candidates. The multi-persona review covered the
full diff (12 files, 1441 insertions, 26 deletions — the
1415-line surplus is in the .ciagent/ governance files:
v1.3-candidates.md 646 lines, 01-PLAN-v1.3.md 334 lines,
v1.3-PHASE1-REPORT.md 178 lines, REQUIREMENTS.md v1.3
section 140 lines, ROADMAP.md v1.3 ideation block 34 lines;
the actual source-tree delta is the remaining 26 lines
across 7 files: docs/, scripts/, .env.example, .gitea/).

Pass 1 (P0 sweep) — 0 P0 issues found.

The 2 P0 candidates (T1.1 cto-inboxos closure, T1.2
ci-pr test wiring) were pre-reviewed by the EXECUTE-
stage impl per the v1.1 P0 sweep precedent (commits
7c20d5d, d530921). No new P0 issues surfaced in the
review pass: the cto-inboxos pair is fully closed in
docs/gitea-actions.md + scripts/setup_gitea_secrets.sh
(grep returns empty in source-tree scope); the ci-pr
wiring is correct (5 hard-fail + 1 deferred-runtime
with continue-on-error: true; YAML parses cleanly;
9 test invocations verified).

Pass 2 (P1/P2 sweep) — 2 P1, 3 P2 issues found.

P1 issues:
- P1-V1.3-01: docs/operations-runbook.md:509 still says
  "see §6.2 for the procedure" but the §6.2 (renumbered
  from §6.4) is the right pointer; the fix is correct.
  No action — the P1 was created and closed in the same
  T2.5 commit.
- P1-V1.3-02: The 4 cross-ref updates in runbook (lines
  509, 625, 767, 790) were landed in the T2.5 commit but
  the verify report's structural check 6 only verifies
  the heading order, not the cross-ref consistency. The
  verify report's recommendation §7 for AUDIT should add
  a "no stale §6.4 cross-refs" check. Filed for v1.4+
  in the AUDIT recommendations.

P2 issues (filed for v1.4+ in §10 lessons):
- P2-V1.3-01: 1 of the 5 new ci-pr test invocations uses
  the heredoc-style pattern (historical_pipeline offline
  fast-subset at lines 106-134) while the other 5 use the
  single-line pattern. The 5 new tests follow the
  precedent of the 3 pre-existing fast-tests (single-line
  python pipelines/_tests/test_X.py). Cosmetic; the
  single-line pattern is the v1.0 / v1.1 standard for
  tests that don't need env-var setup. No action.
- P2-V1.3-02: The 5 new ci-pr test invocations are not
  wrapped in a matrix (the historical-pipeline fast-subset
  is a single heredoc with 7 sub-tests). A matrix
  strategy would be cleaner. Cosmetic; deferred to a
  future ci-pr refactor.
- P2-V1.3-03: The 5 new ci-pr test invocations are not
  marked with a comment noting which v1.x cycle added
  the test. The 6 tests are v1.1 (REQ-INB-19, 20, 21,
  22, 23, 25). Cosmetic; a "Source: REQ-INB-N" comment
  in each step would help future audits. Deferred.

Verdict: PASS-with-NITS, confidence high. 0 P0 fixes
auto-applied (none needed). 2 P1 + 3 P2 items filed
for v1.4+ in the runbook + ci-pr refactor backlog.

The v1.3 inboxos milestone is ready for the AUDIT stage.

---ci---
project: inboxos
phase: 1
milestone: v1.3
status: review
review:
  verdict: PASS-with-NITS
  confidence: high
  p0_fixes: 0
  p0_commits: []
  p1_issues: 2
  p1_detail:
    - id: P1-V1.3-01
      summary: "T2.5 §6.2 cross-ref (line 509) is the correct post-renumber pointer; P1 was created and closed in the same commit"
      status: closed-in-execute
    - id: P1-V1.3-02
      summary: "verify report's §6 cross-ref consistency check is not in the structural check; filed for v1.4+ in audit recommendations"
      status: filed-for-v1.4+
  p2_issues: 3
  p2_detail:
    - id: P2-V1.3-01
      summary: "5 new ci-pr tests use single-line pattern (v1.0/v1.1 standard); 1 pre-existing uses heredoc-style; cosmetic"
      status: filed-for-v1.4+
    - id: P2-V1.3-02
      summary: "5 new ci-pr test invocations are not wrapped in a matrix; cosmetic; deferred to a future ci-pr refactor"
      status: filed-for-v1.4+
    - id: P2-V1.3-03
      summary: "5 new ci-pr test invocations lack a 'Source: REQ-INB-N' comment; cosmetic; deferred"
      status: filed-for-v1.4+
  audit_trail_only: true
  source_tree_changes: 0
  notes:
    - "Pass 1 P0 sweep: 0 fixes (the 2 P0 candidates T1.1 + T1.2 were pre-reviewed by the EXECUTE-stage impl)"
    - "Pass 2 P1/P2 sweep: 5 quality items (1 in-scope closed-in-execute, 4 pre-existing/not-blocking)"
    - "Audit-trail only — no source-tree changes in the review pass (the 5 P1/P2 items are filed for v1.4+ in the runbook + ci-pr refactor backlog)"
---/ci---
2026-06-08 23:34:13 +00:00

InboxOS

Self-hosted personal ERP / CRM pipeline. A single Gmail inbox, polled over IMAP, archived to SeaweedFS, classified and extracted by a local LLM (Ollama), and written to NocoDB as structured records. Curated attachments are mirrored to Papra. No third-party SaaS touches PII.

Where to start

  • Operations runbook — docs/operations-runbook.md. System overview, service inventory, workflow operations, observability, failure modes, security, cost, glossary. The first thing to read on day 1 of incident response.
  • Extraction contract — docs/extraction-contract.md. How a raw email becomes a NocoDB record. Source of truth for the inboxos:classify + inboxos:extract-<module> prompt family.
  • NocoDB schema — docs/schemas.md. The four module tables (finance, crm, intel, promotions) and the Message-ID idempotency contract.
  • Gitea Actions setup — docs/gitea-actions.md. Runner provisioning (including the second runner for live + historical parallelism), repo secrets, the Basic Auth model.
  • Pipelines — pipelines/README.md. Flow diagrams, idempotency model, rollback procedure for the live and historical pipelines.
  • Papra write policy — docs/papra-write-policy.md. When the pipeline writes to Papra (attachments + selected bodies), and why the first ship is dry-run.

Quick layout

inboxos/
├── README.md                     # this file
├── .env.example                  # placeholder env (no real secrets)
├── docker/
│   └── docker-compose.yml        # self-hosted stack: gitea, runners, nocodb, seaweedfs, papra, ollama
├── .gitea/workflows/
│   ├── live-pipeline.yml         # cron */5 * * * *, polls IMAP
│   ├── historical-pipeline.yml   # workflow_dispatch, streams .mbox
│   └── ci-pr.yml                 # fast-tests + 100MB e2e + live Ollama smoke
├── pipelines/                    # shared Python: common.py, live_pipeline.py, historical_pipeline.py, mbox_stream.py
├── .opencode/commands/           # version-controlled extraction prompts (prompt-as-code)
├── config/                       # n8n config (legacy, no longer in use)
└── docs/                         # this runbook + schemas + contracts + reports

Status

Phase 5 — Full Deployment. Parent goal: INB-1. Current phase issue: INB-7. The runbook in docs/operations-runbook.md is the canonical reference for ongoing operation.

Historical archive (Google Takeout .mbox)

The full Google Takeout .mbox export lives in SeaweedFS at the canonical S3 URI:

s3://inboxos/eml/historical/all-mail.mbox

That is the value to pass as the mbox_object_key workflow_dispatch input to historical-pipeline.yml. To verify it exists, run from any host with mc configured against the inboxos bucket:

mc ls --recursive inboxos/inboxos/ | grep '\.mbox$'

The historical pipeline streams this object message-by-message, UPSERTs each into NocoDB on Message-ID, and writes the raw .eml backup under s3://inboxos/eml/historical/<yyyy>/<mm>/<dd>/<Message-ID>.eml. See docs/operations-runbook.md §3.2 for the dispatch recipe and §4.4 for the full bucket layout.

S
Description
InboxOS — self-hosted personal ERP/CRM pipeline. Prompts-as-code, Gitea Actions, NocoDB, Ollama, SeaweedFS, Papra.
Readme 1.8 MiB
Languages
Python 90.3%
Shell 9.7%