• v1.2.0 63c0f59ad1

    cloudinit-bot released this 2026-06-09 10:12:27 +00:00 | 56 commits to main since this release

    InboxOS v1.2.0

    Released: 2026-06-08
    Tag: v1.2.0
    Milestone branch: milestone/v1.2-initial
    Base: v1.1.0 (no source-tree changes)

    Summary

    InboxOS v1.2.0 closes on a 0/1 disposition (0 candidates accepted
    for inboxos execution, 1 candidate rejected as out-of-domain). The
    single Gitea issue assigned to cloudinit-bot (INB-183, the
    opencode-local adapter $HOME/.local/bin PATH append) targets the
    opencode monorepo (paperclip/), not inboxos. A polite-rejection
    comment was posted to INB-183 on 2026-06-08 pointing the issue at
    the upstream executor (opencode monorepo maintainer), where the fix
    is a real 5-minute change.

    v1.2.0 is a no-feature delta over v1.1.0. No inboxos code, test,
    schema, or doc files were modified in this milestone. The v1.2
    deliverable is the audit trail recording the 0/1 disposition and the
    Gitea rejection comment.

    Disposition

    Candidate Status Rationale
    REQ-INB-26 [REJECTED — out of domain] Fix target is the opencode monorepo (paperclip/packages/adapter-utils/src/server-utils.ts:255), not inboxos. The inboxos bot's domain is pipelines/, docker/, .gitea/workflows/, docs/, and .opencode/commands/ only.
    (none other) n/a v1.2 ideation produced 1 candidate, which was rejected. No other candidates were considered.

    Disposition action

    A polite-rejection comment was posted to INB-183 via
    tea comment 8 -r jc-capital/inboxos on 2026-06-08 22:26. The comment:

    • Acknowledges the spec is clear and the acceptance criteria are tight
      (no criticism of the issue author).
    • Declines the work on the inboxos side, naming the cross-repo nature
      of the fix as the reason.
    • Explains why a cross-project handoff (registering paperclip as a
      sibling project) was rejected: it would expand the bot's scope
      across repo boundaries without a clear executor and muddy ownership
      for future audits.
    • States the inboxos disposition: 0 candidates accepted for v1.2
      inboxos execution, 1 candidate rejected as out-of-domain, no inboxos
      code/test/docs changed for this issue.
    • Suggests the next step: re-target the issue to whichever bot or
      maintainer owns the opencode monorepo, where the upstream
      defaultPathForPlatform change + CHANGELOG.md note is a real
      5-minute fix.

    Commit chain (milestone/v1.2-initial)

    63c0f59 docs(milestone): complete v1.2 (InboxOS 0/1 disposition — REQ-INB-26 rejected as out-of-domain)
    275570d docs(audit): v1.2 milestone audit PASS (5 commits, 24/24 ---ci--- blocks, file/commit discipline clean)
    68c7ed0 docs(review): v1.2 multi-persona code review PASS (audit-trail only, 0 source-tree changes)
    54f59ff docs(verify): v1.2 phase 1 verification PASS (4 layers, 0 must-haves, 0/1 disposition, high confidence)
    5b51dc1 chore(execute): v1.2 phase 1 — no tasks (all candidates rejected; see REQ-INB-26)
    8e10c22 docs(plan): v1.2 phase 1 plans (0 candidates — empty set, REQ-INB-26 rejected)
    7151c19 fix(ideate): REQ-INB-26 REJECTED (out of domain — paperclip monorepo); posted tea comment on INB-183
    b0f099b docs(ideate): v1.2 candidate ideas (1 from Gitea — REQ-INB-26 / INB-183)
    

    Files changed (audit trail only)

    • + .ciagent/inboxos/ideation/v1.2-candidates.md (new, 8 sections, 379 lines)
    • + .ciagent/inboxos/plans/01-PLAN-v1.2.md (new, empty-candidate plan)
    • + .ciagent/inboxos/verify/v1.2-PHASE1-REPORT.md (new, 4-layer PASS)
    • ~ .ciagent/inboxos/REQUIREMENTS.md (v1.2 section annotated with milestone close)
    • ~ .ciagent/inboxos/ROADMAP.md (v1.2 ideation block marked [executed 2026-06-08 — 0/1 disposition])
    • ~ .ciagent/inboxos/CI-LOG.md (v1.2 section appended)

    No code, test, schema, or doc files in pipelines/, docker/,
    .gitea/workflows/, docs/, or .opencode/commands/ were modified.

    Ship pattern (per v1.0 and v1.1 precedent)

    • FF-merge from milestone/v1.2-initial to main: local ✅, remote pending admin push
    • Tag v1.2.0 created locally ✅, push to remote pending
    • Milestone branch milestone/v1.2-initial push to remote pending
    • Gitea release for v1.2.0 created via tea releases create (this release)

    Operators with admin push rights (e.g. via a CI bot PAT with bypass)
    can land the FF on remote main; this repo's cloudinit-bot token
    does not have that scope, so main remains at the v1.1.0 baseline
    locally until the admin push. The local v1.2 chain is on
    milestone/v1.2-initial (locally FF-merged to main) and the
    v1.2.0 tag is on main (63c0f59).

    Lessons learned

    • L-IDEATE-01: A single-issue directed ideation pass where the
      only assigned issue is cross-project is a trap — the mechanical
      translation produces a well-formed candidate that the disposition
      layer has to reject. The disposition layer needs an explicit
      "out-of-domain" path separate from the standard accept/skip/modify
      loop.

    • L-IDEATE-02: The cross-project meta-finding ("register
      paperclip as a sibling project?") is a precondition question, not
      a candidate. The lead-developer should resolve it during the IDEATE
      pass, not during PLAN.

    • L-DISP-01: A polite-rejection comment on the originating Gitea
      issue is a required disposition action for out-of-domain work, not
      an optional nicety. The issue author needs the rejection to be
      visible in the same thread where they filed the issue.

    • L-PLAN-01: An empty plan is a valid plan output. The PLAN file
      is the audit record of "the planner considered the candidate set,
      found no work, and is shipping the empty plan." This is the same
      disposition pattern as an NFR milestone with all fix/chore phases.

    Downloads
  • v1.1.0 341c331148

    cloudinit-bot released this 2026-06-08 22:08:25 +00:00 | 64 commits to main since this release

    InboxOS v1.1.0

    Papra gate, secret rotation, backups, observability.

    What ships

    11 candidates (REQ-INB-15 through REQ-INB-25) executed across 3 waves, 14 task commits:

    • Wave 1 (7 tasks): .env.example model-pin hygiene, runbook §9.1 + §6.1 corrections, papra_index NocoDB table + schema, PapraConfig.dry_run_override + canary gate, rotate_secrets.sh + runbook §6.4, live_pipeline.py Papra_Link parity patch
    • Wave 2 (5 tasks): inb-28-report.md per-table row counts, T1.5 call-site wiring + metrics.jsonl per-run + runbook §4.5, remove obsolete papra-write-policy.md live-pipeline note, P1-1 + P2-4 backlog closure, runbook §8.2 cross-references
    • Wave 3 (2 tasks): backup.sh + restore.sh + runbook §5.7 + §10 (RTO < 4h, RPO < 24h), v1.1 acceptance gate (runbook §9.4, 11 must-haves)

    Verification

    4-layer verification PASS-WITH-NITS, high confidence, 11 of 11 must-haves met:

    • Structural: 24 commits, all with ---ci--- blocks, all files parse
    • Behavioral: 30 of 31 new offline tests pass; 1 deferred-runtime per v1.0 precedent (imapclient only)
    • Security: no token literals in working tree, no external network calls in new scripts
    • Quality: all 6 active personas covered; ml-engineer is review-only per spec

    Code review

    3-pass review PASS-WITH-NITS, high confidence:

    • Pass 1 (P0 sweep): 2 auto-applied fixes (3 new shell scripts + 3 runbook lines had stale cto-inboxos owner refs; replaced with jc-capital and env-var-resolved defaults)
    • Pass 2 (P1/P2 sweep): 4 items filed for v1.2 — runbook §6 ordering non-monotonic (P1-1, v1.1-introduced), scripts/setup_gitea_secrets.sh still defaults cto-inboxos (P1-2, pre-existing), apply_schemas.py --check test for papra_index (P2-1), test_papra_link_parity_offline.py deferred-runtime (P2-2)

    Audit

    3-layer audit PASS, high confidence — reconstruction (24/24 ---ci--- blocks), file discipline (all 11 expected .ciagent/inboxos/ files present), commit discipline (24/24 <type>(<scope>): convention, 23/24 ≤5 files per commit; the 1 over-cap is T2.2 which the plan explicitly grouped as a 7-file PR).

    Backlog filed for v1.2

    • P1-1: Runbook §6 ordering is non-monotonic (6.1 → 6.4 → 6.2 → 6.3) due to v1.1 §6.4 insertion
    • P1-2: scripts/setup_gitea_secrets.sh defaults GITEA_OWNER=cto-inboxos (pre-existing, not in v1.1 diff)
    • P2-1: apply_schemas.py --check mode not yet exercised against the new papra_index table
    • P2-2: test_papra_link_parity_offline.py requires imapclient runtime (accepted per v1.0 precedent)

    Ship

    • Tag: v1.1.0
    • Milestone branch: milestone/v1.1-initial
    • Merge: fast-forward to main (in this repo)
    • Phase: 1 (ideation + plan + execute + verify, all in one)
    • Lead: ciagent (under full autonomy for this milestone per the v1.0 close precedent)
    Downloads
  • v1.0.0 60f940e582

    grimacing released this 2026-06-08 15:01:46 +00:00 | 93 commits to main since this release

    InboxOS v1.0.0 — Full Deployment

    Release date: 2026-06-08
    Milestone: v1.0
    Branch: milestone/v1.0-initial → main
    Tag: v1.0.0

    Summary

    InboxOS v1.0 is a fully 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 (dry-run). No third-party SaaS touches PII.

    This is the v1.0 closure of the Full Deployment milestone
    (INB-7 + sub-issues INB-21, INB-27.a, INB-35, INB-45). All 14
    REQ-INB requirements are checkbox-green per the acceptance gate at
    docs/operations-runbook.md §9.

    What's in this release

    Phases 0-4 (executed upstream, captured in this milestone)

    • Phase 0 — Init (9b4f710): CIAgent registration, vision,
      requirements, architecture, phase breakdown, initial commit.
    • Phase 1 — Live IMAP → NocoDB: 5-minute cron poll over IMAP,
      classify + extract via Ollama, idempotent NocoDB upsert. See
      .gitea/workflows/live-pipeline.yml, pipelines/live_pipeline.py.
    • Phase 2 — Historical backfill: workflow_dispatch stream of
      a local .mbox through the same extract+upsert path. See
      .gitea/workflows/historical-pipeline.yml,
      pipelines/historical_pipeline.py, pipelines/mbox_stream.py.
    • Phase 3 — SeaweedFS archive: raw .eml + attachments
      archive of record. See pipelines/common.py upload helpers,
      docker/docker-compose.yml SeaweedFS containers.
    • Phase 4 — Second Gitea runner (INB-33, PR #3): two
      self-hosted gitea/act_runner containers so live + historical
      can run concurrently. See docker/docker-compose.yml,
      docs/gitea-actions.md §2.

    Phase 5 — Full Deployment (this milestone)

    • Operations runbook (docs/operations-runbook.md)
      — canonical day-1 incident reference; covers system overview,
      service inventory, workflow operations, observability, failure
      modes, security, cost, glossary, and a Phase 5 acceptance gate
      appendix.
    • Extraction contract (docs/extraction-contract.md)
      — describes Ollama as the production LLM caller; opencode
      marked legacy. Includes the live-vs-historical Papra_Link
      asymmetry subsection.
    • Schema freeze (docs/phase-1.1-verification/inb-28-report.md)
      — the historical record of the NocoDB table IDs and column sets
      (referenced by the runbook, now present).
    • Gitea Actions docs (docs/gitea-actions.md)
      — runner provisioning + authoring conventions + v3 pin policy.
    • Papra write policy (docs/papra-write-policy.md)
      — PAPRA_DRY_RUN=true default, papra_decide rules, papra_index
      forward pointer.
    • Pipeline README (pipelines/README.md)
      — developer entry point; per-script purpose, local-run
      instructions, env vars, common.py contract. Canonical
      OLLAMA_BASE_URL form (/v1 suffix).
    • Schemas (docs/schemas.md)
      — four module tables (finance, crm, intel, promotions)
      with full column sets and the Message_ID natural key.
    • Personas (.ciagent/inboxos/PERSONAS.md)
      — 6 active personas (lead-developer, data-engineer,
      backend-engineer, devops-engineer, ml-engineer, security-engineer)
      with territory, frameworks, constraints matched to the actual
      Python + Gitea Actions + NocoDB + Ollama stack.

    Sub-issues closed in this milestone

    • INB-21 (single-model pin, d784fa4): drop the model-escalation
      chain; pin single gemma4:e4b model.
    • INB-27.a (Papra dry-run scaffolding, bad1dba): the pipeline
      emits Papra write intent but does not call the real Papra API.
    • INB-35 (runbook + top-level README, b6224c2):
      docs/operations-runbook.md and README.md are present.
    • INB-45 (pin upload-artifact to v3, 87ac5be): the
      actions/upload-artifact@v3 pin is enforced in both pipeline
      workflows (Gitea 1.x / GHES compatibility).
    • INB-117 (correct documented SeaweedFS bucket and historical
      .mbox key, 034b08f, PR #5): the actual deployment uses bucket
      inboxos (not inboxos-eml) and the .mbox lives at
      eml/historical/all-mail.mbox.
    • INB-120 (surface historical-pipeline early-stop in Gitea
      workflow status, a28cb5c, PR #6): historical_pipeline.main()
      now returns EARLY_STOP_EXIT_CODE=2 on extract_permanent_failure
      so Gitea records the run as failure rather than success.

    Reconciliation closure

    The CIAgent run surfaced 7 doc/code drifts (P-1 through P-7)
    between the live code and the documentation. All were closed:

    Drift Closed by PR
    P-1 — model pin drift (lfm2.5:8b → gemma4:e4b in docs) docs: align pipelines/README + extraction-contract to gemma4:e4b pin #A
    P-2 — extraction contract describes OpenCode, not Ollama docs(extraction-contract): describe Ollama as production LLM caller; opencode marked legacy #B
    P-3 — live-vs-historical Papra_Link asymmetry undocumented docs: document live-vs-historical Papra_Link asymmetry #C
    P-4 — OLLAMA_BASE_URL /v1 suffix inconsistent folded into PR #A #A
    P-5 — INTAKE_EMAILS_IS_ENABLED=true in compose (cancelled) docker: disable Papra catch-all intake #E
    P-6 — state-file field names in runbook drift from code docs(runbook §4.4): correct state-file field names #H
    P-7 — live papra_decide asymmetry no-op (ED-1); the live pipeline already calls papra_decide post-classify at live_pipeline.py:490 —

    P-1 through P-7 are also closed in the review pass commit
    32c076c (docs(review): post-hoc fixes for P1-2, P1-4, P1-6).

    Verification

    4-layer verification (structural, behavioral, security, quality)
    ran on the 20 must-haves in the acceptance gate. All 20 are
    checkbox-green with high confidence.
    See
    .ciagent/inboxos/CI-LOG.md
    for the full report.

    Post-hoc review backlog (filed for Phase 6)

    9 P1/P2 issues identified during review; 3 P1 fixed in milestone
    (P1-2, P1-4, P1-6), 6 deferred to Phase 6:

    • P1-1: T1.3 plan-vs-PR mapping split (PR #C touched 2 files; the 3rd was in PR #B)
    • P1-3: inb-28-report.md "Per-table row counts at freeze" section is empty
    • P1-5: .env.example lines 96-99 have stale lfm2.5:8b / gemma4:12b model comments
    • P2-1: runbook §9.1 #12 glob {live,historical,ci-pr}.yml for upload-artifact@v3 is misleading
    • P2-2: runbook §6.1 prose says 21 distinct secrets; the table has 22 rows (off-by-one)
    • P2-4: plan #19 persona (backend-engineer) is implicit in the runbook renumber

    Upgrade notes

    This is the first v1.0 release — no upgrade path. Operators
    deploying from scratch follow docs/operations-runbook.md.

    Operators with a pre-v1.0 deployment should:

    1. Verify the SeaweedFS bucket is inboxos (not inboxos-eml) —
      the runbook §4.4 and §6.1 are now authoritative.
    2. Verify the historical .mbox key is eml/historical/all-mail.mbox.
    3. Verify the Ollama model pin is gemma4:e4b (not lfm2.5:8b or
      gemma4:12b).
    4. Verify the actions/upload-artifact version is @v3 (not
      @v4) in all workflow YAMLs.
    5. Apply the secrets inventory from the runbook §6.1 (22 rows;
      the GITEA_USER/GITEA_PASS Basic Auth pair is required, not
      a PAT — Gitea 1.x does not surface the plaintext of freshly-issued
      PATs).

    Assets

    No binary distribution packages in v1.0. The deliverable is the
    self-hosted Gitea repository at the v1.0.0 tag; operators pull
    the workflows, the pipelines/ directory, the docker/
    compose file, and the docs/ set.

    Thanks

    InboxOS v1.0 ships because the devops-engineer, ml-engineer,
    data-engineer, security-engineer, and backend-engineer personas
    all delivered the right artifacts to the right boundaries. The
    lead-developer is the integrator.

    — cloudinit-bot, 2026-06-08

    Downloads