cloudinit-bot 63c0f59ad1 docs(milestone): complete v1.2 (InboxOS 0/1 disposition — REQ-INB-26 rejected as out-of-domain)
---ci---
project: inboxos
phase: 0
milestone: v1.2
status: complete
requirements:
  covered: []
  partial: []
  rejected: [REQ-INB-26]
ship:
  milestone: v1.2
  tag: v1.2.0
  release_note_summary: |
    InboxOS v1.2 closes on a 0/1 disposition: 0 candidates accepted
    for inboxos execution, 1 candidate (REQ-INB-26) rejected as
    out-of-domain. The single Gitea issue assigned to cloudinit-bot
    (INB-183, opencode-local adapter PATH append) targets the opencode
    monorepo (paperclip/), not inboxos; a polite-rejection comment was
    posted to INB-183 on 2026-06-08 with a pointer to the upstream
    executor. No inboxos code, test, schema, or doc files were
    modified; v1.2.0 is a no-feature delta over v1.1.0 and ships as
    the audit-trail-closing event for the 0/1 disposition.
  ship_pattern: |
    FF-merge from milestone/v1.2-initial to main, push tag v1.2.0,
    push milestone branch, create Gitea release. Same pattern as
    v1.0.0 (tag on main) and v1.1.0 (tag on main, milestone
    branch pushed but main protected on remote).
milestone:
  name: v1.2
  type: feature (no executed phases; close on 0/1 disposition)
  tag: v1.2.0
  version_progression: |
    v1.1.0 -> v1.2.0 (no executed phases, no source-tree changes;
    the v1.2 milestone is the audit-trail-closing event for the
    0/1 disposition).
  ship_target_branch: main
  ship_target_tag: v1.2.0
  ship_target_release: 'Gitea release for v1.2.0 (auto-generated from CI-LOG + ROADMAP + REQUIREMENTS + ideation/v1.2-candidates.md §8 + verify/v1.2-PHASE1-REPORT.md)'
files_touched:
  modified:
    - .ciagent/inboxos/REQUIREMENTS.md (v1.2 section annotated with milestone close + REQ-INB-26 [REJECTED] verdict)
    - .ciagent/inboxos/ROADMAP.md (v1.2 ideation block [executed 2026-06-08 — 0/1 disposition], +acceptance gate, +tag, +artifacts list)
    - .ciagent/inboxos/CI-LOG.md (v1.2 section appended: ideation/plan/execute/verify/review/audit/close/post_hoc_review/lessons)
  unchanged:
    - docs/requirements.md (CPO-owned, not modified, byte-identical to v1.1)
    - docs/roadmap.md (CPO-owned, not modified, byte-identical to v1.1)
    - all inboxos code/test/schema/doc files (v1.2 is audit-trail-only)
    - /root/workspace/paperclip/ (operator directive: no ad-hoc changes)
verification:
  type: milestone_close
  note: v1.2 milestone closes on the 0/1 disposition. Tag v1.2.0, release notes, FF-merge to main. Audit-trail-only milestone; the deliverable is the consistent rejection state + the Gitea comment on INB-183.
---/ci---
2026-06-08 22:33:03 +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%