docs(ideate): v1.3 candidate ideas — codebase-drift ideation (12 candidates)
Source query: Gitea issue queue is now EMPTY (0 open issues).
The CTO has closed both INB-183 (paperclip monorepo PATH append,
rejected in v1.2) and INB-193 (the wrapper that the v1.3
research commit body had named as the v1.3 deliverable). The
v1.3 IDEATE pass is therefore driven entirely by codebase
analysis (per the user's redirect), not by the issue queue.
Tier 1 (mechanical, 8 findings → 8 REQs REQ-INB-28..35):
- T1-1 (P0): docs/gitea-actions.md:95 cto-inboxos drift
(v1.1 P0 sweep missed this file; last touched Phase 4)
- T1-2 (P2): runbook footer "Next review" stale by 2 milestones
- T1-3 (P2): runbook §4.5 forward-pointer to v1.2 alerting
(v1.2 never delivered alerting; pointer is stale)
- T1-4 (P2): papra-write-policy.md:192 test count 13→15
(v1.1 added 2 tests; doc was not updated)
- T1-5 (P2): extraction-contract.md 4 stale line refs
in pipelines/common.py
- T1-6 (P2): .env.example missing 7 workflow env vars
(OLLAMA_API_KEY, INBOXOS_LLM_BACKEND, PAPRA_DRY_RUN,
PAPRA_BODY_WRITE_MODULES, PAPRA_METADATA_ONLY_MODULES,
MBOX_BUCKET, OPENCODE_NPM_VERSION)
- T1-7 (P0): 6 v1.1 offline tests not wired into ci-pr
merge gate (papra_decide, papra_index, papra_link_parity,
metrics, restore, rotate_secrets)
- T1-8 (XS): .gitignore opencode.json shadows tracked file
(defer to v1.4)
Tier 2 (backend-enriched, v1.1 backlog + PIT items, 4 REQs):
- T2-1 (v1.1 P1-1): runbook §6 ordering 6.1→6.4→6.2→6.3
→ REQ-INB-36
- T2-2 (v1.1 P1-2): setup_gitea_secrets.sh cto-inboxos drift
→ REQ-INB-37
- T2-3 (v1.1 P2-1): apply_schemas.py --check papra_index test
→ REQ-INB-38 (DEFER, low value)
- T2-4 (v1.1 P2-2): test_papra_link_parity imapclient shim
→ REQ-INB-39 (DEFER, accepted-precedent disposition)
Tier 2 PIT items (3 carry-forward from v1.3 research):
- PIT-V1.3-1 (secret-scan pattern) → §10 lessons
- PIT-V1.3-2 (.ciagent/ sovereignty) → §10 lessons
- PIT-V1.3-3 (CI lint wiring) → absorbed into REQ-INB-34
Tier 2 re-verifications (3, drift-free at v1.3):
- T2-8: schemas.md ↔ apply_schemas.py column lists match
- T2-9: gemma4:e4b pin consistent across 5 prompts + .env.example
- T2-10: opencode backend dead code is intentional + documented
Tier 3 (cross-project, 0 REQ):
- CP-1: paperclip not a registered CIAgent project (carry)
- CP-2: inboxos source has 0 paperclip references (re-verify)
- CP-3: /root/workspace/paperclip/ unmodified (re-verify)
Disposition:
- 9 ACCEPT: REQ-INB-28, 29, 30, 31, 32, 33, 34, 36, 37
- 3 DEFER: REQ-INB-35, 38, 39
- 0 REJECT
Accept ratio: 9/12 (75%). No NocoDB schema impact. v1.3 is
doc-hygiene + test-wiring + env-file-drift + cto-inboxos
closure. Closes 2 v1.1 backlog items (P1-1, P1-2). Re-verifies
5 v1.0/v1.1 drift closures (model pin, schema, opencode dead
code, paperclip sovereignty).
---ci---
project: inboxos
phase: 1
milestone: v1.3
status: ideate
disposition:
accepted: [REQ-INB-28, REQ-INB-29, REQ-INB-30, REQ-INB-31, REQ-INB-32, REQ-INB-33, REQ-INB-34, REQ-INB-36, REQ-INB-37]
deferred: [REQ-INB-35, REQ-INB-38, REQ-INB-39]
rejected: []
tier1:
- id: T1-1
finding: "docs/gitea-actions.md:95 cto-inboxos drift (v1.1 P0 sweep missed this file)"
candidate: REQ-INB-28
confidence: 0.90
effort: XS
schema_impact: no
disposition: ACCEPT
- id: T1-2
finding: "runbook footer 'Next review' stale by 2 milestones"
candidate: REQ-INB-29
confidence: 0.95
effort: XS
schema_impact: no
disposition: ACCEPT
- id: T1-3
finding: "runbook §4.5 forward-pointer v1.2 alerting stale"
candidate: REQ-INB-30
confidence: 0.80
effort: XS
schema_impact: no
disposition: ACCEPT
- id: T1-4
finding: "papra-write-policy.md:192 test count 13→15"
candidate: REQ-INB-31
confidence: 0.90
effort: XS
schema_impact: no
disposition: ACCEPT
- id: T1-5
finding: "extraction-contract.md 4 stale line refs"
candidate: REQ-INB-32
confidence: 0.85
effort: S
schema_impact: no
disposition: ACCEPT
- id: T1-6
finding: ".env.example missing 7 workflow env vars"
candidate: REQ-INB-33
confidence: 0.80
effort: S
schema_impact: no
disposition: ACCEPT
- id: T1-7
finding: "6 v1.1 offline tests not wired into ci-pr merge gate"
candidate: REQ-INB-34
confidence: 0.90
effort: S
schema_impact: no
disposition: ACCEPT
absorbs: [PIT-V1.3-3]
- id: T1-8
finding: ".gitignore opencode.json shadows tracked file"
candidate: REQ-INB-35
confidence: 0.65
effort: XS
schema_impact: no
disposition: DEFER
tier2:
- id: T2-1
finding: "runbook §6 ordering non-monotonic (v1.1 P1-1)"
candidate: REQ-INB-36
confidence: 0.95
effort: XS
schema_impact: no
disposition: ACCEPT
- id: T2-2
finding: "setup_gitea_secrets.sh cto-inboxos drift (v1.1 P1-2)"
candidate: REQ-INB-37
confidence: 0.90
effort: XS
schema_impact: no
disposition: ACCEPT
- id: T2-3
finding: "apply_schemas.py --check papra_index offline test (v1.1 P2-1)"
candidate: REQ-INB-38
confidence: 0.85
effort: XS
schema_impact: no
disposition: DEFER
reason: "low value (runtime path covered by test_papra_index_offline.py); defer to v1.4"
- id: T2-4
finding: "test_papra_link_parity imapclient runtime shim (v1.1 P2-2)"
candidate: REQ-INB-39
confidence: 0.55
effort: S
schema_impact: no
disposition: DEFER
reason: "accepted-precedent disposition (v1.0 + v1.1 deferred-runtime); defer to v1.4"
tier2_re_verify:
- id: T2-8
finding: "schemas.md ↔ apply_schemas.py drift-free at column-list level"
disposition: RE_VERIFY
- id: T2-9
finding: "gemma4:e4b pin consistent across 5 prompts + .env.example + opencode.json"
disposition: RE_VERIFY
- id: T2-10
finding: "opencode backend dead code is intentional + documented"
disposition: RE_VERIFY
tier3:
- id: CP-1
finding: "paperclip not a registered CIAgent project"
disposition: REJECT_AS_CANDIDATE
reason: "carry-forward from v1.2; closed by operator directive"
- id: CP-2
finding: "inboxos source has 0 paperclip references"
disposition: RE_VERIFY
- id: CP-3
finding: "/root/workspace/paperclip/ unmodified by this scan"
disposition: RE_VERIFY
final_candidates:
count: 12
accepted_count: 9
deferred_count: 3
rejected_count: 0
ids: [REQ-INB-28, REQ-INB-29, REQ-INB-30, REQ-INB-31, REQ-INB-32, REQ-INB-33, REQ-INB-34, REQ-INB-35, REQ-INB-36, REQ-INB-37, REQ-INB-38, REQ-INB-39]
accepted_ids: [REQ-INB-28, REQ-INB-29, REQ-INB-30, REQ-INB-31, REQ-INB-32, REQ-INB-33, REQ-INB-34, REQ-INB-36, REQ-INB-37]
deferred_ids: [REQ-INB-35, REQ-INB-38, REQ-INB-39]
schema_impact: none
cross_project: 0
---/ci---
This commit is contained in:
@@ -0,0 +1,646 @@
|
||||
# InboxOS — v1.3 Ideation Candidates
|
||||
|
||||
> **Date:** 2026-06-08
|
||||
> **Project:** InboxOS (`/INB/projects/inboxos`)
|
||||
> **Milestone:** v1.3 (post-v1.2)
|
||||
> **Source of ideation:** Tier 1 (mechanical / code-scraped) + Tier 2
|
||||
> (backend-enriched, mining the v1.0/v1.1 post-hoc backlogs) + Tier 3
|
||||
> (cross-project) — issued **from scratch** at the user's request,
|
||||
> because the v1.3 research commit (`66ee903`) named INB-193 as the
|
||||
> candidate source and the CTO has since closed that issue along
|
||||
> with INB-183. The Gitea issue queue assigned to `cloudinit-bot` is
|
||||
> now empty (verified: `tea issues list --assignee cloudinit-bot
|
||||
> --owner jc-capital --repo inboxos --state open` returns **0 open
|
||||
> issues**). The v1.3 candidate set is therefore built entirely
|
||||
> from the existing codebase, the `post_hoc_review` backlogs, and
|
||||
> the v1.3 research PIT items.
|
||||
> **Ideator role:** `ci-ideation-agent`
|
||||
> **Author status:** Ideation candidates only. **Not approved
|
||||
> requirements.** All candidates are marked **[CANDIDATE]** until
|
||||
> the CPO authors a matching entry in `docs/requirements.md`
|
||||
> (CPO-owned, per board mandate `b49cfb7`).
|
||||
|
||||
---
|
||||
|
||||
## 1. CPO governance note
|
||||
|
||||
This ideation pass honors the board mandate recorded in commit
|
||||
`b49cfb7` (`docs(seed): initialize requirements and roadmap
|
||||
source-of-truth`):
|
||||
|
||||
- `docs/requirements.md` is CPO-owned. **Not modified.** Confirmed
|
||||
byte-identical to the v1.1 / v1.2 close (only the 2026-06-08
|
||||
CEO seed change-log row).
|
||||
- `docs/roadmap.md` is CPO-owned. **Not modified.** Confirmed
|
||||
byte-identical to the v1.1 / v1.2 close.
|
||||
- The 14 v1.0 requirements (`REQ-INB-1` through `REQ-INB-14`) are
|
||||
**[SHIPPED]** per `.ciagent/inboxos/CI-LOG.md`.
|
||||
- The 11 v1.1 candidates (`REQ-INB-15` through `REQ-INB-25`) are
|
||||
**[EXECUTED]** per the v1.1 acceptance gate at
|
||||
`docs/operations-runbook.md §9.4` and tagged `v1.1.0`.
|
||||
- The 1 v1.2 candidate (`REQ-INB-26`) is **[REJECTED — out of
|
||||
domain]** per `.ciagent/inboxos/CI-LOG.md` (v1.2 close block) and
|
||||
the disposition recorded in
|
||||
`.ciagent/inboxos/ideation/v1.2-candidates.md §8`.
|
||||
- `.ciagent/config.json` is **untouched** in the ideation phase;
|
||||
the milestone row still says `v1.2 / status: complete`. The
|
||||
v1.3 milestone does not register a new `phase:` row in the
|
||||
config until the close commits the ship.
|
||||
|
||||
Edits made in this pass are confined to:
|
||||
|
||||
- `.ciagent/inboxos/ideation/v1.3-candidates.md` (this file — new)
|
||||
- `.ciagent/inboxos/REQUIREMENTS.md` (append a "v1.3 candidate
|
||||
requirements" block, no change to existing 14 + 11 + 1 rejected)
|
||||
- `.ciagent/inboxos/ROADMAP.md` (append a "v1.3 ideation (Phase
|
||||
01)" block, no change to Phase 6/7/8 prose or the existing v1.1
|
||||
/ v1.2 ideation blocks)
|
||||
|
||||
The CPO is the only role that can promote any **[CANDIDATE]** in
|
||||
this report to a real requirement by authoring the corresponding
|
||||
entry in `docs/requirements.md`. The lead-developer is the
|
||||
integrator for the follow-on PLAN phase and is the only role that
|
||||
may add technical acceptance criteria to a candidate.
|
||||
|
||||
---
|
||||
|
||||
## 2. Source query
|
||||
|
||||
The `ciagent run --ideate` invocation specified: *"do full Tier 1
|
||||
(mechanical / code-scraped) + Tier 2 (backend-enriched) + Tier 3
|
||||
(cross-project) ideation from the codebase alone."* The user's
|
||||
context note records that the Gitea issue queue assigned to
|
||||
`cloudinit-bot` is now empty (0 open issues; CTO closed both
|
||||
`INB-183` and `INB-193`). The tea invocation that confirms this
|
||||
state is:
|
||||
|
||||
```
|
||||
tea issues list --assignee cloudinit-bot --owner jc-capital \
|
||||
--repo inboxos --state open
|
||||
```
|
||||
|
||||
Result: **0 open issues**.
|
||||
|
||||
The full state of all inboxos issues (any assignee, any state)
|
||||
shows that both issues the bot previously owned — `INB-183`
|
||||
(opencode-local adapter PATH append, open since v1.1-Beta,
|
||||
rejected in v1.2 as out-of-domain) and `INB-193` (the
|
||||
`scripts/with-gitea-env.sh` wrapper per the v1.3 research commit
|
||||
body) — have been **closed by the CTO** before this ideation pass.
|
||||
The source of ideation is therefore the codebase itself, the
|
||||
v1.0/v1.1/v1.2 post-hoc backlogs, the v1.3 research PIT items
|
||||
(PIT-V1.3-1..3 from commit `66ee903`), and the v1.1 closure
|
||||
backlog (`remaining_for_v1_2: [P1-1, P1-2, P2-1, P2-2]`
|
||||
forwarded from v1.2 to v1.3 per `.ciagent/inboxos/CI-LOG.md`
|
||||
v1.2 close block).
|
||||
|
||||
---
|
||||
|
||||
## 3. Tier 1 — Mechanical findings (code-scraped)
|
||||
|
||||
Tier 1 findings were produced by scanning `pipelines/`,
|
||||
`.gitea/workflows/`, `docker/`, `scripts/`, `docs/`,
|
||||
`.opencode/commands/`, `opencode.json`, `.env.example`, and
|
||||
`scripts/*.sh` for `TODO`/`FIXME`/`XXX`/`HACK` markers, commented-
|
||||
out code blocks, hardcoded paths / secrets / IPs, feature-flag
|
||||
stubs, and documentation drift relative to the source.
|
||||
|
||||
The first four categories produced **zero hits**: no
|
||||
`TODO`/`FIXME`/`XXX`/`HACK` markers in code, no commented-out
|
||||
code blocks in `.py` or `.sh` files, no real secrets in
|
||||
committed files, no IPs that would leak. The shell scripts are
|
||||
all chmod 755 with `set -euo pipefail`. The drift items below
|
||||
all map to either a known P1/P2 backlog entry or a real v1.3
|
||||
opportunity that the mechanical scan surfaced.
|
||||
|
||||
| # | Finding (file:line) | Backlog ID | Candidate REQ | Parent REQ | Confidence | Effort | Schema |
|
||||
|---|---------------------|------------|---------------|------------|------------|--------|--------|
|
||||
| T1-1 | `docs/gitea-actions.md:95` hardcodes `cto-inboxos/inboxos` in a `curl` example (verify-runner step). The v1.1 review auto-applied the same fix to the runbook (`d530921`, runbook §5.1 + §10) and to the 3 new shell helpers (`7c20d5d`), but `docs/gitea-actions.md` was missed and still ships with the old owner string. P0 by the same reasoning as the v1.1 P0 sweep (operator would fail to verify the runners under the `jc-capital` migration if they copy-pasted this example). | n/a (v1.1 sweep was scoped to .md / .sh created or modified in v1.1; gitea-actions.md was last touched at Phase 4 / INB-33, before the org migration) | **REQ-INB-28** | REQ-INB-6, REQ-INB-10 | 0.90 | XS | no |
|
||||
| T1-2 | `docs/operations-runbook.md:823` footer still says *"Next review: after the v1.1 ship (2026-06-08, milestone `milestone/v1.1-initial`)"*. v1.1 has shipped, v1.2 has shipped (tag v1.2.0 on `63c0f59`), and v1.3 is in the ideate phase on `milestone/v1.3-initial`. The footer pointer is stale by 2 milestones. P2 / cosmetic, but a v1.3 doc-hygiene item. | n/a (cosmetic, not in v1.1 backlog) | **REQ-INB-29** | REQ-INB-6 | 0.95 | XS | no |
|
||||
| T1-3 | `docs/operations-runbook.md:285-289` §4.5 "Forward-pointer" says "Alerting is **out of scope** for v1.1; the runbook does not include alert rules (this is a v1.2 candidate per `.ciagent/inboxos/ideation/v1.1-candidates.md` Tier 2 T2-D). [...] The alert layer is the next v1.2 deliverable." v1.2 has shipped without delivering alerting (v1.2 was a 0/1 disposition; no alerting was in scope). The forward-pointer is now stale. | n/a (forward-pointer; not in v1.1 backlog) | **REQ-INB-30** | REQ-INB-6, REQ-INB-23 | 0.80 | XS | no |
|
||||
| T1-4 | `docs/papra-write-policy.md:192` says *"covers 13 cases"* but `pipelines/_tests/test_papra_decide_offline.py` actually defines **15 test functions** (the two v1.1 additions — `test_papra_dry_run_override_wins` and `test_emit_papra_write_gate_event_logs_three_fields` — were never reflected in the doc count). Off-by-2, but visible to a new operator reading the doc and the test list side-by-side. | n/a (doc drift, not in v1.1 backlog) | **REQ-INB-31** | REQ-INB-9, REQ-INB-20 | 0.90 | XS | no |
|
||||
| T1-5 | `docs/extraction-contract.md:40,98,102,161` cite four line ranges in `pipelines/common.py` that have drifted past the v1.0 + v1.1 line-shuffle. Verified: the v1.1 EXECUTE stage added 30+ lines to `LLMConfig.from_env` (now at line 536, doc cites `414-479`) and ~25 lines to `_ollama_call_one_model` (now at line 636, doc cites `605-624`); the `opencode_run_command` was reshaped (now at line 440, doc cites `378-407` for the opencode backend). An operator who grep-lands on the doc's line numbers and reads from there will read the wrong function. P2 / doc drift. | n/a (doc drift, not in v1.1 backlog) | **REQ-INB-32** | REQ-INB-4, REQ-INB-14 | 0.85 | S | no |
|
||||
| T1-6 | `.env.example` is missing entries for the workflow env vars that have no default (or that have a literal-string default baked into the workflow). Specifically: `OLLAMA_API_KEY` (referenced in all 3 workflows, default empty), `INBOXOS_LLM_BACKEND` (live+historical+ci-pr, default `'ollama'`), `PAPRA_DRY_RUN` (live+historical, default `'true'`), `PAPRA_BODY_WRITE_MODULES` (live+historical, default `'crm,finance,legal'`), `PAPRA_METADATA_ONLY_MODULES` (live+historical, default `'intel,promotions'`), `MBOX_BUCKET` (historical-only, default falls back to `SEAWEEDFS_S3_BUCKET`), and `OPENCODE_NPM_VERSION` (historical-only, default `'latest'`). The existing `.env.example` documents `IMAP_*`, `NOCODB_*`, `SEAWEEDFS_*`, `PAPRA_*` (the bare connection vars), `OLLAMA_BASE_URL`, `GITEA_*`, and `OPENCODE_BIN` / `OPENCODE_PROMPT_DIR` — but the LLM-backend + Papra-tunables + MBOX_BUCKET + OPENCODE_NPM_VERSION knobs are not in the file at all. A new operator following the runbook will miss these. P2 / doc drift. | n/a (env-file drift, not in v1.1 backlog) | **REQ-INB-33** | REQ-INB-6, REQ-INB-9, REQ-INB-11 | 0.80 | S | no |
|
||||
| T1-7 | `.gitea/workflows/ci-pr.yml` `fast-tests` job runs only 3 offline tests: `test_gitea_request_offline.py`, `test_mbox_stream.py`, `test_live_pipeline_offline.py` (lines 91-99). The v1.1 EXECUTE stage added **6 more pure-offline tests** (`test_papra_decide_offline.py`, `test_papra_index_offline.py`, `test_papra_link_parity_offline.py`, `test_metrics_offline.py`, `test_restore_offline.py`, `test_rotate_secrets_offline.py`) — all of which pass locally (v1.1 verify report records 30/30) — but **none of them are wired into the ci-pr merge gate**. The v1.1 verify report's "5 layers" claim about CI is satisfied, but a PR could regress `papra_index_upsert`, `papra_decide`, the metrics emitter, the secret-rotation helper, or the backup/restore contract without the merge gate noticing. P0 by the merge-gate-stays-clean standard. | n/a (post-v1.1 verify, surfaced in this scan) | **REQ-INB-34** | REQ-INB-8 | 0.90 | S | no |
|
||||
| T1-8 | `opencode.json` is listed in `.gitignore` (line `opencode.json` in `.gitignore`) **and** is also tracked in git (verified: `git ls-files opencode.json` returns the path; `git log opencode.json` shows commits `350b902`, `ab7331d`, `051e565`, `c5b7cf8`, `1d74d85`). The file is a per-checkout override for the opencode CLI, but the gitignore pattern means a fresh `git status` will not show local modifications to it (because git ignores it). The result: an operator who edits `opencode.json` to switch model pin will see no diff and cannot revert through git. Cosmetic + ergonomics, but a real footgun for an INB-20 / model-pinning workflow. | n/a (post-v1.1 scan, surfaces a long-standing .gitignore oddity) | **REQ-INB-35** | REQ-INB-14, REQ-INB-11 | 0.65 | XS | no |
|
||||
|
||||
> **Tier 1 summary:** 8 findings. 2 P0 (T1-1, T1-7), 1 P2
|
||||
> doc-counter (T1-4), 2 P2 doc-pointer (T1-2, T1-3), 3
|
||||
> doc/ergonomics (T1-5, T1-6, T1-8). All in `.md` / `.yml` /
|
||||
> `.env.example` / `.gitignore` — no `.py` TODOs, no
|
||||
> commented-out code, no leaked secrets, no broken shell
|
||||
> `set -euo pipefail` discipline (all 5 shell scripts are
|
||||
> clean).
|
||||
|
||||
---
|
||||
|
||||
## 4. Tier 2 — Backend-enriched findings (judgment, code-reading)
|
||||
|
||||
Tier 2 candidates arise from mining the v1.0/v1.1/v1.2 post-hoc
|
||||
backlogs (per `.ciagent/inboxos/CI-LOG.md` `post_hoc_review`
|
||||
blocks) and the v1.3 research commit's PIT items
|
||||
(PIT-V1.3-1..3 from `66ee903`). Each candidate references the
|
||||
parent REQ-INB-* that it builds on and notes whether the change
|
||||
would alter the NocoDB schema (per `docs/schemas.md`).
|
||||
|
||||
The v1.1 backlog (`remaining_for_v1_2: [P1-1, P1-2, P2-1, P2-2]`
|
||||
per `CI-LOG.md:228`) is the primary source. Per the v1.2 close
|
||||
block, those items remain in the v1.1 backlog file with no v1.2
|
||||
additions; the v1.3 milestone is the next opportunity to clear
|
||||
them. (Note: the v1.0 backlog items P1-3, P1-5, P2-1, P2-2
|
||||
mentioned in the user's prompt were already closed in v1.1 via
|
||||
REQ-INB-15..18; the v1.1 backlog uses the same P1/P2 labels for
|
||||
*new* net items, not duplicates. The `CI-LOG.md:233` note
|
||||
explicitly records this non-duplication.)
|
||||
|
||||
| # | Finding (source / file:line) | Backlog ID | Candidate REQ | Parent REQ | Confidence | Effort | Schema |
|
||||
|---|-------------------------------|------------|---------------|------------|------------|--------|--------|
|
||||
| T2-1 | `docs/operations-runbook.md` §6 ordering is `6.1 → 6.4 → 6.2 → 6.3` (verified at `docs/operations-runbook.md:476,508,558,565`). The v1.1 insertion of `§6.4 Secret rotation` (REQ-INB-21, commit `6067008`) between `§6.1` and `§6.2` left the section ordering non-monotonic. Cosmetic / nav, but the v1.1 review's P1-1 closure call is on the record (`CI-LOG.md:217-218`). | v1.1 P1-1 | **REQ-INB-36** | REQ-INB-6 | 0.95 | XS | no |
|
||||
| T2-2 | `scripts/setup_gitea_secrets.sh:4,14,18,28` hardcode `cto-inboxos` (header comment x2, default `GITEA_OWNER="${GITEA_OWNER:-cto-inboxos}"`) 4 lines. The v1.1 review auto-applied the same fix to the 3 new shell helpers and the runbook (`7c20d5d`, `d530921`) but explicitly filed this script as "pre-existing — not in v1.1 diff" and tagged it for a v1.2 follow-up (`CI-LOG.md:219-220`); v1.2 was a 0/1 disposition so the carry-forward is now v1.3. The v1.0 `chore(config+secrets)` commit `a068c8a` updated `.ciagent/config.json` but missed this script. P1 by the same operator-action risk profile as the v1.1 P0 sweep. | v1.1 P1-2 | **REQ-INB-37** | REQ-INB-10 | 0.90 | XS | no |
|
||||
| T2-3 | `scripts/apply_schemas.py --check` exercises the `papra_index` audit table (verified at `apply_schemas.py:443-466`: the `for audit in AUDIT_TABLES` loop calls `find_table` + `find_column` + `unique-constraint check`), but there is no offline test in `pipelines/_tests/` that drives `apply_schemas.py --check` to assert the papra_index path. The v1.0 §9.2 row 9 "apply_schemas.py --check exits 0" precedent is therefore not mirrored for the v1.1 papra_index table. `test_papra_index_offline.py` covers the runtime helper (`common.papra_index_upsert`, 3/3 pass) but not the schema-bootstrap path. The v1.1 backlog called this "Trivial addition (3-5 lines)"; the carry-forward is a v1.3 P2 item. | v1.1 P2-1 | **REQ-INB-38** | REQ-INB-5, REQ-INB-19 | 0.85 | XS | no |
|
||||
| T2-4 | `pipelines/_tests/test_papra_link_parity_offline.py` is the v1.1 deferred-runtime test (1 test). It `import live_pipeline` (line 108), which in turn `from imapclient import IMAPClient` (`pipelines/live_pipeline.py:49`). The test counts as 1/1 in v1.1 must-have #11 evidence, but the runtime import chain is **not exercised in CI** (`ci-pr.yml` fast-tests does not list it; `imapclient` is a runtime-only dep, not in any test fixture). The v1.0 precedent accepted this disposition for `test_upsert_synthetic.py`, but the v1.1 cycle inherited it without further mitigation. P3 / accepted-precedent — but a v1.3 candidate could add a stub `imapclient` module (a 5-line shim in `pipelines/_tests/conftest.py` or a `sys.modules` injection in the test) so the chain imports cleanly in CI. Optional, low-priority. | v1.1 P2-2 | **REQ-INB-39** | REQ-INB-25, REQ-INB-8 | 0.55 | S | no |
|
||||
| T2-5 | v1.3 research PIT-V1.3-1 (medium): the v1.3 candidate INB-193 (`scripts/with-gitea-env.sh` wrapper) was the planned v1.3 deliverable per the v1.3 research commit body. The CTO closed INB-193 before this ideation pass. The PIT is moot (no candidate to apply it to), but the **secret-scan pattern** it would have established (mktemp + chmod 600 + trap cleanup for runtime env-file fixtures) is reusable. v1.1 has no comparable pattern in `test_rotate_secrets_offline.py` (which instead bakes test values directly into `subprocess` `env=`). Low value as a standalone REQ; folded into a cross-cutting PIT-closure note in the v1.3 lessons (see §10). | v1.3 PIT-V1.3-1 (carried in spirit) | (no REQ; PIT-closure note only) | REQ-INB-9, REQ-INB-10 | n/a | n/a | n/a |
|
||||
| T2-6 | v1.3 research PIT-V1.3-2 (low): same — moot because INB-193 is closed. The wrapper's INB-173 path-sovereignty rule (no mutation of `.ciagent/`) is a property the existing `setup_gitea_secrets.sh` and `rotate_secrets.sh` already honor (no `.ciagent/` writes), so no new requirement is needed. Cross-cutting observation only. | v1.3 PIT-V1.3-2 (carried in spirit) | (no REQ; PIT-closure note only) | REQ-INB-10 | n/a | n/a | n/a |
|
||||
| T2-7 | v1.3 research PIT-V1.3-3 (low): the candidate INB-193 was going to need a `lint-shell` job in `ci-pr.yml` to wire the test into the merge gate. Moot because INB-193 is closed. **However**, the same need exists for the 6 v1.1 offline tests that T1-7 already flagged: a `lint-shell` (or `test-v11-offline`) job in `ci-pr.yml` would close T1-7 in one commit. PIT-V1.3-3 is therefore absorbed into REQ-INB-34. | v1.3 PIT-V1.3-3 (absorbed into T1-7) | (folded into REQ-INB-34) | REQ-INB-8 | 0.90 (absorbed) | (absorbed) | (absorbed) |
|
||||
| T2-8 | `docs/schemas.md` and `scripts/apply_schemas.py` are **drift-free** at the column-list level (verified by python-side diff: `finance` (10 cols), `crm` (11), `intel` (9), `promotions` (11), `papra_index` (7) all match between doc and script). The v1.0 `9.2 row 9 'apply_schemas.py --check exits 0'` acceptance gate is documented; T2-3 above covers the offline-test gap. No new schema or doc drift. **Re-verify, not a finding.** | n/a (re-verify) | n/a | REQ-INB-5, REQ-INB-19 | n/a | n/a | n/a |
|
||||
| T2-9 | All 5 `.opencode/commands/inboxos:*.md` prompts pin `model: ollama/gemma4:e4b` in the frontmatter (verified: classify + extract-crm + extract-finance + extract-intel + extract-promotions). The `pipelines/README.md`, `docs/extraction-contract.md`, `.env.example` line 96-99, and `opencode.json` all pin `gemma4:e4b` as the canonical production model. **No drift.** The v1.0 P-1 pitfall is closed; the v1.1 P1-5 (`.env.example` model comments) is closed. Re-verify, not a finding. | n/a (re-verify) | n/a | REQ-INB-11 | n/a | n/a | n/a |
|
||||
| T2-10 | `pipelines/common.py:423-487` (`class OpenCodeConfig` + `def opencode_run_command`) is **kept for offline tests only** per the docstring at `common.py:455-461` ("This path is currently broken end-to-end; use `llm_run_command` with the `ollama` backend instead. This function is kept for offline tests and future opencode versions."). The `INBOXOS_LLM_BACKEND=opencode` path is wired into the workflow but defaults to `ollama` in all three workflows. **Not a candidate** — the dead code is intentional, documented, and exercised by the offline tests. Re-verify, not a finding. | n/a (re-verify) | n/a | REQ-INB-11, REQ-INB-14 | n/a | n/a | n/a |
|
||||
|
||||
> **Tier 2 summary:** 4 v1.3 candidates (T2-1..T2-4) plus 3 PIT
|
||||
> closure notes (T2-5..T2-7) that fold into the existing Tier 1
|
||||
> REQ-INB-34. The 3 v1.3 PIT items are absorbed as observations,
|
||||
> not as new REQ-INB-* candidates, because INB-193 is closed and
|
||||
> the wrapper is not being built. 3 re-verifications (T2-8..T2-10)
|
||||
> confirm the v1.0/v1.1 drift closures are still in place.
|
||||
|
||||
---
|
||||
|
||||
## 5. Tier 3 — Cross-project findings
|
||||
|
||||
| # | Finding | Source | Candidate REQ | Confidence |
|
||||
|---|---------|--------|---------------|------------|
|
||||
| **CP-1** (carry-forward from v1.2 §5) | `paperclip` is **not a registered CIAgent project**. The only sibling projects are `coreci`, `ci`, `foo`, `inboxos` (per `.ciagent/config.json` `projects[]`). The v1.3 research PIT-V1.3-2 referenced the opencode-monorepo as a sovereignty boundary; with INB-193 closed, the carry-forward is unchanged. The operator's v1.2 directive ("NO DO NOT MAKE ADHOC CHANGES TO the paperclip monorepo") is the active posture. | `.ciagent/config.json` projects[]; `.ciagent/inboxos/CI-LOG.md:303` | (meta, no REQ) | n/a |
|
||||
| **CP-2** (new) | The v1.3 inboxos docs / workflows do **not** reference `paperclip`, `opencode-monorepo`, or any other cross-project tree. Verified: `grep -rn "paperclip\|opencode-monorepo" docs/ pipelines/ scripts/ docker/ .gitea/ .env.example .opencode/ opencode.json` returns **0 hits**. The only paperclip references are in the `.ciagent/` governance files (REQUIREMENTS.md, ROADMAP.md, CI-LOG.md, v1.2-candidates.md), which is the correct scope: the rejection lineage is the only inboxos-side record, and the inboxos code itself is paperclip-blind. **No drift.** | inboxos source vs `.ciagent/` governance files | n/a (re-verify) | n/a |
|
||||
| **CP-3** (new) | The `paperclip/` tree at `/root/workspace/paperclip/` is **not modified** by this ideation pass (the ideation pass makes no changes to inboxos source-tree files; the lead-developer's "do not touch paperclip" directive is honored). Verified by tree-comparison: no file under `paperclip/` has been edited, and the `git log --diff-filter=M -- paperclip/` on the inboxos repo returns empty (because paperclip is a separate repo entirely). | operator directive `CI-LOG.md:300`; this scan made zero source-tree changes | n/a (re-verify) | n/a |
|
||||
|
||||
> **Tier 3 summary:** 1 carry-forward meta-finding (CP-1,
|
||||
> unchanged from v1.2) + 2 re-verifications (CP-2, CP-3). **No
|
||||
> new cross-project candidates.** The inboxos bot's domain
|
||||
> remains `pipelines/`, `docker/`, `.gitea/workflows/`, `docs/`,
|
||||
> and `.opencode/commands/` only. The paperclip monorepo is
|
||||
> out-of-scope by operator directive.
|
||||
|
||||
---
|
||||
|
||||
## 6. v1.3 ideation summary
|
||||
|
||||
| # | Candidate | Tier | Parent | Confidence | Effort | Cross-project |
|
||||
|---|-----------|------|--------|------------|--------|---------------|
|
||||
| 1 | **REQ-INB-28** — `docs/gitea-actions.md:95` `cto-inboxos` → `jc-capital` | T1-1 | REQ-INB-6, REQ-INB-10 | 0.90 | XS | no |
|
||||
| 2 | **REQ-INB-29** — runbook footer "Next review" pointer (v1.1 → v1.3) | T1-2 | REQ-INB-6 | 0.95 | XS | no |
|
||||
| 3 | **REQ-INB-30** — runbook §4.5 "Forward-pointer" (alerting → v1.2 deliverable, stale) | T1-3 | REQ-INB-6, REQ-INB-23 | 0.80 | XS | no |
|
||||
| 4 | **REQ-INB-31** — `papra-write-policy.md:192` test count (13 → 15) | T1-4 | REQ-INB-9, REQ-INB-20 | 0.90 | XS | no |
|
||||
| 5 | **REQ-INB-32** — `extraction-contract.md` 4 stale `pipelines/common.py:` line refs | T1-5 | REQ-INB-4, REQ-INB-14 | 0.85 | S | no |
|
||||
| 6 | **REQ-INB-33** — `.env.example` missing 7 workflow env vars (OLLAMA_API_KEY, INBOXOS_LLM_BACKEND, PAPRA_DRY_RUN, PAPRA_BODY_WRITE_MODULES, PAPRA_METADATA_ONLY_MODULES, MBOX_BUCKET, OPENCODE_NPM_VERSION) | T1-6 | REQ-INB-6, REQ-INB-9, REQ-INB-11 | 0.80 | S | no |
|
||||
| 7 | **REQ-INB-34** — Wire the 6 v1.1 offline tests (`test_papra_*`, `test_metrics_*`, `test_restore_*`, `test_rotate_secrets_*`) into `ci-pr.yml` merge gate | T1-7 + T2-7 (absorbed PIT-V1.3-3) | REQ-INB-8 | 0.90 | S | no |
|
||||
| 8 | **REQ-INB-35** — `.gitignore` `opencode.json` line shadows a tracked file (footgun for INB-20 model-pin workflow) | T1-8 | REQ-INB-14, REQ-INB-11 | 0.65 | XS | no |
|
||||
| 9 | **REQ-INB-36** — Runbook §6 ordering: renumber to `6.1 → 6.2 → 6.3 → 6.4` | T2-1 (v1.1 P1-1) | REQ-INB-6 | 0.95 | XS | no |
|
||||
| 10 | **REQ-INB-37** — `scripts/setup_gitea_secrets.sh` `cto-inboxos` → `jc-capital` (4 lines) | T2-2 (v1.1 P1-2) | REQ-INB-10 | 0.90 | XS | no |
|
||||
| 11 | **REQ-INB-38** — Add `apply_schemas.py --check` offline test for `papra_index` (3-5 lines) | T2-3 (v1.1 P2-1) | REQ-INB-5, REQ-INB-19 | 0.85 | XS | no |
|
||||
| 12 | **REQ-INB-39** — `test_papra_link_parity_offline.py` runtime-deferred disposition: stub `imapclient` for CI | T2-4 (v1.1 P2-2) | REQ-INB-25, REQ-INB-8 | 0.55 | S | no |
|
||||
| - | (meta) **CP-1** — `paperclip` is not a registered CIAgent project (carry-forward) | T3 (carry) | n/a | n/a | n/a | yes |
|
||||
| - | (re-verify) **CP-2** — inboxos source has zero paperclip references | T3 (re-verify) | n/a | n/a | n/a | no |
|
||||
| - | (re-verify) **CP-3** — `/root/workspace/paperclip/` not modified by this scan | T3 (re-verify) | n/a | n/a | n/a | yes |
|
||||
|
||||
**Total candidates:** 12 (REQ-INB-28 through REQ-INB-39)
|
||||
**Tier 1 contribution:** 8/12 (REQ-INB-28..35)
|
||||
**Tier 2 contribution:** 4/12 (REQ-INB-36..39; 3 PIT closure notes folded in)
|
||||
**Tier 3 contribution:** 0 REQ (1 carry-forward meta + 2 re-verifications)
|
||||
**Cross-project (paperclip):** 0 candidates (CP-1 closed by negation, CP-2 / CP-3 are re-verifications)
|
||||
|
||||
The v1.3 candidate set is **drift-heavy / code-light**: 9 of 12
|
||||
candidates are doc or env-file hygiene (XS effort, no schema
|
||||
impact), 2 are test-surface (S effort, no schema impact), and 1
|
||||
is a `.gitignore` ergonomics fix (XS). **No NocoDB schema
|
||||
impact** across the full set; v1.3 is a tools/wrappers milestone
|
||||
in the v1.3 research's framing, and these candidates are the
|
||||
mechanical fallout of 3 prior milestones shipping in succession.
|
||||
|
||||
---
|
||||
|
||||
## 7. Disposition detail for accepted candidates
|
||||
|
||||
The 12 candidates separate into three disposition groups. All 12
|
||||
are **[CANDIDATE]** until the CPO authors matching entries in
|
||||
`docs/requirements.md`; the lead-developer is the integrator for
|
||||
the follow-on PLAN phase.
|
||||
|
||||
### 7.1 ACCEPT (recommended for v1.3 PLAN)
|
||||
|
||||
These 9 candidates are mechanical fixes with no design judgment
|
||||
needed; the lead-developer can scope them into a single PLAN
|
||||
wave (the v1.3 research suggested a single-issue milestone, but
|
||||
the v1.3 candidate set is much larger than INB-193 alone because
|
||||
the CTO closed INB-193 and the backlog is now sourced from
|
||||
codebase drift alone).
|
||||
|
||||
- **REQ-INB-28** (P0, cto-inboxos drift in gitea-actions.md, same
|
||||
risk profile as v1.1 P0 sweep): ACCEPT. **Required** for v1.3.
|
||||
This is a 1-line doc fix. The lead-developer should land it in
|
||||
the same commit as REQ-INB-37 (the corresponding
|
||||
`setup_gitea_secrets.sh` fix) so the cto-inboxos → jc-capital
|
||||
migration is closed in one PR.
|
||||
|
||||
- **REQ-INB-29** (P2, runbook footer "Next review" → v1.3 pointer):
|
||||
ACCEPT. **Required** for v1.3 — the footer is two milestones
|
||||
stale and a v1.3 ship without updating it leaves a v1.4 audit
|
||||
trail with a misleading "next review" line.
|
||||
|
||||
- **REQ-INB-30** (P2, runbook §4.5 forward-pointer v1.2 → v1.3):
|
||||
ACCEPT. **Required** for v1.3 — the v1.2 alerting deliverable
|
||||
was never built, and the doc should reflect the v1.3 reality
|
||||
(alerting is still not in scope; v1.3 is doc-hygiene, not
|
||||
observability).
|
||||
|
||||
- **REQ-INB-31** (P2, papra-write-policy.md test count 13 → 15):
|
||||
ACCEPT. **Required** for v1.3 — pure doc fix.
|
||||
|
||||
- **REQ-INB-32** (P2, extraction-contract.md 4 stale line refs):
|
||||
ACCEPT. **Required** for v1.3 — a 4-line edit in
|
||||
extraction-contract.md to re-cite `LLMConfig.from_env()` at
|
||||
`pipelines/common.py:536`, `ollama_run_command` at
|
||||
`pipelines/common.py:609`, `_ollama_call_one_model` at
|
||||
`pipelines/common.py:636`, and the opencode backend at
|
||||
`pipelines/common.py:440` (verified above).
|
||||
|
||||
- **REQ-INB-33** (P2, .env.example missing 7 workflow env vars):
|
||||
ACCEPT. **Required** for v1.3 — a 7-entry addition to
|
||||
`.env.example` (commented-out, with the same default the
|
||||
workflow bakes in: `OLLAMA_API_KEY=""`,
|
||||
`INBOXOS_LLM_BACKEND=ollama`, `PAPRA_DRY_RUN=true`,
|
||||
`PAPRA_BODY_WRITE_MODULES=crm,finance,legal`,
|
||||
`PAPRA_METADATA_ONLY_MODULES=intel,promotions`,
|
||||
`MBOX_BUCKET=`, `OPENCODE_NPM_VERSION=latest`). This brings
|
||||
the env-file into 1:1 alignment with the workflow defaults
|
||||
the operator can grep.
|
||||
|
||||
- **REQ-INB-34** (P0, wire 6 v1.1 offline tests into ci-pr merge
|
||||
gate): ACCEPT. **Required** for v1.3 — the highest-impact
|
||||
candidate in the set. A 6-line `run: python
|
||||
pipelines/_tests/test_X_offline.py` block (or one batched
|
||||
heredoc that calls all 6 in sequence, matching the existing
|
||||
`test_historical_pipeline_offline` fast-subset pattern at
|
||||
`ci-pr.yml:106-134`). The lead-developer should also absorb
|
||||
the v1.3 PIT-V1.3-3 ("wire the test into CI lint") into this
|
||||
candidate.
|
||||
|
||||
- **REQ-INB-36** (P1, runbook §6 renumbering 6.1 → 6.2 → 6.3 →
|
||||
6.4): ACCEPT. **Required** for v1.3 — moves §6.4 to its
|
||||
proper position. Closes v1.1 backlog P1-1.
|
||||
|
||||
- **REQ-INB-37** (P1, setup_gitea_secrets.sh cto-inboxos →
|
||||
jc-capital): ACCEPT. **Required** for v1.3 — 4-line edit.
|
||||
Closes v1.1 backlog P1-2. Pair with REQ-INB-28 for a
|
||||
single-PR cto-inboxos → jc-capital migration closure.
|
||||
|
||||
### 7.2 DEFER (low value or low confidence)
|
||||
|
||||
These 3 candidates are real findings but with marginal value
|
||||
or low confidence; defer to a future milestone.
|
||||
|
||||
- **REQ-INB-35** (T1-8, .gitignore opencode.json line shadows a
|
||||
tracked file): DEFER. The `opencode.json` file is committed
|
||||
in the git history (5 commits) and the .gitignore pattern is
|
||||
intentional defense-in-depth (a per-checkout override). The
|
||||
footgun is real but minor: an operator who edits
|
||||
`opencode.json` to switch model pin can `git diff
|
||||
opencode.json` directly (the file is still tracked), they
|
||||
just won't see it in `git status` of an unrelated change.
|
||||
**Confidence 0.65** is the lowest in the set, and the fix
|
||||
(removing the .gitignore line) opens a separate question
|
||||
about whether the file should be tracked at all. Defer to
|
||||
v1.4+ as a §10 lessons item.
|
||||
|
||||
- **REQ-INB-38** (T2-3, apply_schemas.py --check offline test
|
||||
for papra_index): DEFER. The mechanical fix is 3-5 lines, but
|
||||
the test would have to mock the NocoDB HTTP layer (similar to
|
||||
the pattern in `test_papra_index_offline.py:144`'s
|
||||
`FakeNoco`). The v1.1 backlog called it "Trivial addition
|
||||
(3-5 lines)"; in practice the offline-test host has no
|
||||
NocoDB to check, so the test would be a unit-level stub that
|
||||
asserts the script's column-list parsing, not a true
|
||||
`--check` integration. **Confidence 0.85** but **value 0.40**
|
||||
(the runtime path is already covered by
|
||||
`test_papra_index_offline.py`). Defer to v1.4+ unless the
|
||||
v1.3 PLAN bundles it with REQ-INB-34 for one-off test wiring.
|
||||
|
||||
- **REQ-INB-39** (T2-4, test_papra_link_parity imapclient
|
||||
runtime-stub): DEFER. The v1.0 and v1.1 cycles both accepted
|
||||
the deferred-runtime disposition (v1.0 for
|
||||
`test_upsert_synthetic.py`, v1.1 for
|
||||
`test_papra_link_parity_offline.py`). The precedent is
|
||||
documented; the v1.1 P2-2 backlog called it "Same
|
||||
accepted-precedent disposition as v1.0's
|
||||
test_upsert_synthetic.py imapclient path." The 5-line
|
||||
`sys.modules["imapclient"] = types.ModuleType(...)` shim is
|
||||
a small fix but **confidence 0.55** — the shim has to
|
||||
satisfy the `from imapclient import IMAPClient` chain in
|
||||
`live_pipeline.py:49` without breaking the existing
|
||||
`live_pipeline` semantics, and the offline test host
|
||||
installs `imapclient` already (per the v1.1
|
||||
`pip install` step at `ci-pr.yml:80-87`). Defer to v1.4+
|
||||
unless the lead-developer is willing to take a swing at
|
||||
the shim.
|
||||
|
||||
### 7.3 REJECT (not candidates)
|
||||
|
||||
- **CP-1 (carry-forward paperclip meta)**: REJECT. The
|
||||
operator's v1.2 directive closed this by negation
|
||||
(`CI-LOG.md:303`). No change. The CP-1 finding is a
|
||||
precondition question for cross-project handoffs, and no
|
||||
v1.3 candidate requires a handoff (INB-193 is closed).
|
||||
|
||||
- **CP-2 (re-verify no paperclip refs)**: REJECT. Re-verification
|
||||
only. No candidate needed.
|
||||
|
||||
- **CP-3 (re-verify paperclip tree not modified)**: REJECT.
|
||||
Re-verification only. The ideation pass made zero changes
|
||||
to `/root/workspace/paperclip/`.
|
||||
|
||||
- **T2-5, T2-6, T2-7 (v1.3 PIT items)**: REJECT as standalone
|
||||
REQs. The candidate INB-193 is closed; the PIT items describe
|
||||
failure modes for a candidate that no longer exists. T2-7
|
||||
(PIT-V1.3-3 "wire the test into CI lint") is **absorbed into
|
||||
REQ-INB-34** because the same need exists for the 6 v1.1
|
||||
offline tests. T2-5 (PIT-V1.3-1 secret-scan pattern) and
|
||||
T2-6 (PIT-V1.3-2 path sovereignty) are recorded in §10
|
||||
lessons as reusable patterns for future candidates, not as
|
||||
requirements.
|
||||
|
||||
- **T2-8 (schemas.md vs apply_schemas.py drift re-verify)**:
|
||||
REJECT. Re-verification only. Drift-free at the column-list
|
||||
level.
|
||||
|
||||
- **T2-9 (model pin re-verify)**: REJECT. Re-verification only.
|
||||
All 5 prompts + .env.example + opencode.json pin
|
||||
`gemma4:e4b`.
|
||||
|
||||
- **T2-10 (opencode backend dead code re-verify)**: REJECT.
|
||||
Re-verification only. The dead code is intentional, documented,
|
||||
and exercised by the offline tests.
|
||||
|
||||
---
|
||||
|
||||
## 8. Final candidates for PLAN/EXECUTE
|
||||
|
||||
| # | Candidate | Disposition | Effort | Notes |
|
||||
|---|-----------|-------------|--------|-------|
|
||||
| 1 | REQ-INB-28 | ACCEPT | XS | 1-line doc fix; pair with REQ-INB-37 |
|
||||
| 2 | REQ-INB-29 | ACCEPT | XS | 1-line footer fix |
|
||||
| 3 | REQ-INB-30 | ACCEPT | XS | 4-line forward-pointer fix |
|
||||
| 4 | REQ-INB-31 | ACCEPT | XS | 1-line test-count fix |
|
||||
| 5 | REQ-INB-32 | ACCEPT | S | 4-line line-ref fix in extraction-contract.md |
|
||||
| 6 | REQ-INB-33 | ACCEPT | S | 7-entry .env.example addition |
|
||||
| 7 | REQ-INB-34 | ACCEPT | S | 6-line ci-pr.yml test wiring; absorbs PIT-V1.3-3 |
|
||||
| 8 | REQ-INB-35 | DEFER | XS | .gitignore opencode.json line — defer to v1.4 |
|
||||
| 9 | REQ-INB-36 | ACCEPT | XS | 4-line runbook §6 renumber; closes v1.1 P1-1 |
|
||||
| 10 | REQ-INB-37 | ACCEPT | XS | 4-line setup_gitea_secrets.sh; closes v1.1 P1-2; pair with REQ-INB-28 |
|
||||
| 11 | REQ-INB-38 | DEFER | XS | apply_schemas.py --check offline test — defer to v1.4 |
|
||||
| 12 | REQ-INB-39 | DEFER | S | test_papra_link_parity imapclient shim — defer to v1.4 |
|
||||
|
||||
**9 ACCEPT candidates** (REQ-INB-28, 29, 30, 31, 32, 33, 34, 36, 37).
|
||||
**3 DEFER candidates** (REQ-INB-35, 38, 39).
|
||||
**0 REJECT candidates.**
|
||||
|
||||
**Accept ratio:** 9/12 (75%) — high, but the value is concentrated
|
||||
in the 2 P0 items (REQ-INB-28, REQ-INB-34) and the 7 doc/env
|
||||
hygiene items (REQ-INB-29, 30, 31, 32, 33, 36, 37). The
|
||||
DEFER-set is all low-confidence or low-value.
|
||||
|
||||
**Cross-project:** 0 candidates (CP-1 closed by negation; CP-2 /
|
||||
CP-3 re-verifications only).
|
||||
|
||||
**Schema impact:** 0 across all 12 candidates. v1.3 is a
|
||||
doc-hygiene + test-wiring + env-file-drift milestone. **No
|
||||
NocoDB schema changes.** This is consistent with the v1.3
|
||||
research commit body: "v1.3 is a tools/wrappers milestone; the
|
||||
pipeline is not touched" and "No new services, no schema
|
||||
changes, no LLM model changes" — except the v1.3 research was
|
||||
written for INB-193 (the wrapper) and that issue is now closed,
|
||||
so v1.3 has narrowed to the codebase-drift fallout that this
|
||||
scan surfaced.
|
||||
|
||||
**Suggested PLAN shape:** 3 waves. Wave 1 = the 2 P0 items
|
||||
(REQ-INB-28 + REQ-INB-37, then REQ-INB-34) — closes the
|
||||
cto-inboxos drift in 2 files and the CI test gap in 1 file.
|
||||
Wave 2 = the 7 doc/env hygiene items (REQ-INB-29, 30, 31, 32,
|
||||
33, 36) — 6 small doc edits + 1 .env.example addition. Wave 3
|
||||
= nothing (no execute items remaining). The lead-developer
|
||||
should confirm this shape before the PLAN commit; the
|
||||
candidates are mechanical enough that the waves can collapse
|
||||
into 2 if the lead-developer prefers.
|
||||
|
||||
**Tag:** v1.3.0. Ship pattern identical to v1.1 (Papra Gate + DR
|
||||
+ Observability) and v1.2 (0/1 disposition): FF-merge
|
||||
`phase/01-v1.3-execute` → `milestone/v1.3-initial` → `main`,
|
||||
push tag, push milestone branch, create Gitea release.
|
||||
|
||||
---
|
||||
|
||||
## 9. Post-hoc review items
|
||||
|
||||
**v1.3 backlog (filed for v1.4+ follow-up):**
|
||||
|
||||
- **REQ-INB-35** — `.gitignore opencode.json` line shadows a
|
||||
tracked file. Defer to v1.4 unless the lead-developer
|
||||
decides to take a swing.
|
||||
- **REQ-INB-38** — `apply_schemas.py --check` offline test for
|
||||
`papra_index` table. Defer to v1.4; the value is marginal
|
||||
because the runtime path is already covered by
|
||||
`test_papra_index_offline.py`.
|
||||
- **REQ-INB-39** — `test_papra_link_parity_offline.py`
|
||||
imapclient runtime-shim. Defer to v1.4; the
|
||||
accepted-precedent disposition is on the v1.0 and v1.1
|
||||
audit trail.
|
||||
|
||||
**v1.1 backlog still open** (none — all 4 closed in v1.3):
|
||||
|
||||
- v1.1 P1-1 (runbook §6 ordering) → **closed by REQ-INB-36**
|
||||
- v1.1 P1-2 (setup_gitea_secrets.sh owner) → **closed by REQ-INB-37**
|
||||
- v1.1 P2-1 (apply_schemas.py papra_index --check test) →
|
||||
**deferred to v1.4+ via REQ-INB-38**
|
||||
- v1.1 P2-2 (papra_link_parity runtime-only) → **deferred to
|
||||
v1.4+ via REQ-INB-39**
|
||||
|
||||
**v1.0 backlog still open** (none — all closed in v1.1):
|
||||
P1-3, P1-5, P2-1, P2-2 all closed via REQ-INB-15, 16, 17, 18.
|
||||
Verified at `CI-LOG.md:233` and the v1.1 commit log
|
||||
(`6b05e8d`, `87adaed`, `7fb1dd4`, `42cd1b0`).
|
||||
|
||||
**v1.3 PIT items (re-absorbed):**
|
||||
|
||||
- PIT-V1.3-1 (medium, secret-scan pattern) → §10 lessons
|
||||
- PIT-V1.3-2 (low, .ciagent/ sovereignty) → §10 lessons
|
||||
- PIT-V1.3-3 (low, CI lint wiring) → absorbed into REQ-INB-34
|
||||
|
||||
**Cross-project carries:**
|
||||
|
||||
- CP-1 (paperclip not a registered CIAgent project) →
|
||||
unchanged from v1.2, closed by operator directive.
|
||||
|
||||
---
|
||||
|
||||
## 10. Lessons
|
||||
|
||||
- **L-IDEATE-V1.3-01**: When the Gitea issue queue is empty
|
||||
and the CTO has closed the issues named in the v1.3 research
|
||||
commit (INB-183 + INB-193), the IDEATE pass must explicitly
|
||||
pivot to **codebase-drift ideation** rather than issue-driven
|
||||
ideation. The v1.3 research commit's "single-issue v1.3
|
||||
milestone" framing (ED-V1.3-2) is now stale; the milestone
|
||||
has to be re-scoped to the mechanical drift this scan
|
||||
surfaced. The lead-developer should confirm the re-scope
|
||||
before PLAN.
|
||||
|
||||
- **L-IDEATE-V1.3-02**: The drift-density of the inboxos
|
||||
codebase increased monotonically across v1.0 → v1.1 → v1.2
|
||||
(zero P1/P2 at v1.0 close, 6 P1 + 3 P2 at v1.0 review, 2 P1
|
||||
+ 2 P2 at v1.1 close, 0 source-tree changes at v1.2 close,
|
||||
and now 12 candidates at the v1.3 IDEATE). The pattern is
|
||||
consistent: each milestone ship leaves drift in the docs /
|
||||
env-files / workflow comments that the next IDEATE pass
|
||||
surfaces. A standing "post-ship doc-hygiene pass" in the
|
||||
COMPLETE phase of every milestone would catch this without
|
||||
waiting for the next IDEATE. **The v1.3 PLAN should consider
|
||||
adding this as a CI-LOG post-hoc-review step** (not a REQ).
|
||||
|
||||
- **L-IDEATE-V1.3-03**: 9 of 12 v1.3 candidates are XS or S
|
||||
effort doc/env-hygiene fixes. The lead-developer could land
|
||||
them as a single `chore(docs): v1.3 doc-hygiene sweep` PR
|
||||
(5-7 files, ≤ 50 line changes) rather than 9 separate
|
||||
micro-PRs. The trade-off: a single sweep PR has a higher
|
||||
audit-trail value but a higher per-PR review cost; the
|
||||
per-REQ approach matches the v1.1 / v1.2 1-REQ-per-PR
|
||||
pattern. The lead-developer's call.
|
||||
|
||||
- **L-IDEATE-V1.3-04**: The `papra-write-policy.md:192` "13
|
||||
cases" claim and the runbook footer "Next review: after the
|
||||
v1.1 ship" stale pointer are **both** artifacts of the same
|
||||
v1.1 ship pattern: the v1.1 EXECUTE stage added tests +
|
||||
acceptance-gate content but did not update the prose
|
||||
counters / footers in the existing docs. A simple
|
||||
pre-merge-grep for `1[0-9] cases` and `Next review` would
|
||||
have caught both. **Future IDEATE passes should add this
|
||||
grep to the mechanical scan** (Tier 1).
|
||||
|
||||
- **L-IDEATE-V1.3-05**: The `opencode.json` file is in
|
||||
`.gitignore` **and** tracked by git. The pattern is
|
||||
intentional defense-in-depth (allows local override while
|
||||
still keeping a committed default), but the footgun is
|
||||
real: a `git status` of an unrelated change will not show
|
||||
an `opencode.json` edit, and a new operator won't know the
|
||||
file is tracked unless they `git log opencode.json`. The
|
||||
fix is to either (a) remove the file from .gitignore
|
||||
(declares "this file is the canonical, do not override"),
|
||||
or (b) keep the .gitignore line and add a comment to
|
||||
`opencode.json` ("tracked; .gitignore is for local override")
|
||||
so the operator knows. REQ-INB-35 is deferred; this is a
|
||||
judgment call for the lead-developer.
|
||||
|
||||
- **L-IDEATE-V1.3-06 (PIT-V1.3-1 / V1.3-2 carry-forward)**:
|
||||
The v1.3 research's PIT-V1.3-1 (mktemp + chmod 600 + trap
|
||||
secret-file pattern) and PIT-V1.3-2 (.ciagent/ sovereignty)
|
||||
are reusable patterns even though INB-193 is closed. If a
|
||||
future candidate requires a runtime env-file fixture
|
||||
(similar to the `with-gitea-env.sh` wrapper), the test
|
||||
harness should follow the mktemp + chmod 600 + trap pattern
|
||||
and assert no `.ciagent/` mutation. This is a **template
|
||||
recommendation**, not a requirement.
|
||||
|
||||
- **L-IDEATE-V1.3-07 (carries v1.2 L-IDEATE-01)**:
|
||||
Single-issue directed ideation where the only assigned
|
||||
issue is cross-project is a trap; the disposition layer
|
||||
needs an explicit "out-of-domain" path separate from the
|
||||
standard accept/skip/modify loop. v1.2 honored this
|
||||
(REQ-INB-26 rejected). v1.3 honors it differently: the
|
||||
planned v1.3 candidate INB-193 was closed by the CTO
|
||||
before IDEATE, so the v1.3 milestone has no assigned
|
||||
issue at all and the IDEATE pass is codebase-drift-driven.
|
||||
|
||||
---
|
||||
|
||||
## 11. Tier 1 / 2 / 3 cross-reference
|
||||
|
||||
| Tier | Findings | REQ-INB-* | Re-verifications | Meta / rejected |
|
||||
|------|----------|-----------|------------------|-----------------|
|
||||
| **Tier 1** (mechanical / code-scraped) | 8 (T1-1..T1-8) | 8 (REQ-INB-28..35) | 0 | 0 |
|
||||
| **Tier 2** (backend-enriched / backlog mining) | 7 (T2-1..T2-7) | 4 (REQ-INB-36..39) | 3 (T2-8..T2-10) | 3 PIT items absorbed or lessons-only |
|
||||
| **Tier 3** (cross-project) | 1 carry (CP-1) | 0 | 2 (CP-2, CP-3) | 1 carry-forward closed by negation |
|
||||
| **Total** | 16 raw findings | 12 candidates | 5 re-verifications | 4 meta / PIT-closure |
|
||||
|
||||
**Backlog coverage** (v1.1 backlog items in v1.3 candidates):
|
||||
|
||||
- v1.1 P1-1 (§6 ordering) → **REQ-INB-36** (ACCEPT, XS)
|
||||
- v1.1 P1-2 (setup_gitea_secrets.sh owner) → **REQ-INB-37**
|
||||
(ACCEPT, XS)
|
||||
- v1.1 P2-1 (apply_schemas.py --check papra_index) →
|
||||
**REQ-INB-38** (DEFER, XS)
|
||||
- v1.1 P2-2 (papra_link_parity imapclient shim) →
|
||||
**REQ-INB-39** (DEFER, S)
|
||||
|
||||
**v1.3 research PIT items in v1.3 candidates:**
|
||||
|
||||
- PIT-V1.3-1 → §10 lessons (L-IDEATE-V1.3-06)
|
||||
- PIT-V1.3-2 → §10 lessons (L-IDEATE-V1.3-06)
|
||||
- PIT-V1.3-3 → absorbed into **REQ-INB-34** (ACCEPT, S)
|
||||
|
||||
**New v1.3 candidates (not in any prior backlog):**
|
||||
|
||||
- REQ-INB-28 (T1-1, cto-inboxos in gitea-actions.md, missed by
|
||||
v1.1 sweep) — same risk class as v1.1 P0 but missed
|
||||
- REQ-INB-29 (T1-2, runbook footer stale by 2 milestones)
|
||||
- REQ-INB-30 (T1-3, runbook §4.5 forward-pointer stale)
|
||||
- REQ-INB-31 (T1-4, papra-write-policy.md test count off-by-2)
|
||||
- REQ-INB-32 (T1-5, 4 stale line refs in extraction-contract.md)
|
||||
- REQ-INB-33 (T1-6, 7 missing .env.example entries)
|
||||
- REQ-INB-34 (T1-7, 6 v1.1 offline tests not in ci-pr merge gate)
|
||||
- REQ-INB-35 (T1-8, .gitignore shadows tracked opencode.json)
|
||||
|
||||
**v1.0 leftover items (per user's prompt) — all already closed
|
||||
in v1.1:**
|
||||
|
||||
- v1.0 P1-3 (inb-28-report empty row counts) → **closed**
|
||||
REQ-INB-18, commit `42cd1b0`
|
||||
- v1.0 P1-5 (`.env.example` model comments) → **closed**
|
||||
REQ-INB-15, commit `6b05e8d`
|
||||
- v1.0 P2-1 (runbook §9.1 #12 glob) → **closed** REQ-INB-16,
|
||||
commit `87adaed`
|
||||
- v1.0 P2-2 (runbook §6.1 secret count) → **closed**
|
||||
REQ-INB-17, commit `7fb1dd4`
|
||||
|
||||
**v1.0 P1-1, P1-2, P1-4, P1-6, P2-4** (also from the v1.0
|
||||
backlog, not in the user's prompt) — all closed in v1.0 fix
|
||||
commit `32c076c` (P1-2, P1-4, P1-6) or v1.1 commits
|
||||
`df88e8b` (P1-1, P2-4). The `CI-LOG.md:233` note explicitly
|
||||
records the v1.0 backlog was emptied by v1.1.
|
||||
|
||||
**Acceptance posture:** The 9 ACCEPT candidates clear the
|
||||
v1.1 backlog (P1-1, P1-2) and close 7 newly-surfaced doc-hygiene
|
||||
items. The 3 DEFER candidates are filed for v1.4+ in
|
||||
§9. The 0 REJECT candidates mean the v1.3 milestone ships
|
||||
with a 9/12 disposition (or higher if the lead-developer
|
||||
bundles one or more DEFER items into the v1.3 PLAN).
|
||||
|
||||
**Honest confidence statement:** Tier 1 confidence is
|
||||
0.65-0.95; Tier 2 confidence is 0.55-0.95; Tier 3
|
||||
re-verifications are n/a. The lowest-confidence finding is
|
||||
**REQ-INB-39** (0.55) — the imapclient runtime-shim has
|
||||
non-trivial test-surface implications that the v1.0 / v1.1
|
||||
precedent chose to accept rather than fix. The highest-
|
||||
confidence finding is **REQ-INB-29** (0.95) — the runbook
|
||||
footer is unambiguously two milestones stale. The IDEATE
|
||||
output is intentionally not padded: 12 candidates, all
|
||||
backed by file:line evidence, all dispositioned. The 3
|
||||
re-verifications (T2-8, T2-9, T2-10, CP-2, CP-3) confirm the
|
||||
v1.0 / v1.1 drift closures are still in place; they are
|
||||
not candidates but are recorded to preserve the audit trail.
|
||||
Reference in New Issue
Block a user