feat: wire ExitCode into main() return for f1.2 robot exit code contract #35
Notifications
Due Date
No due date set.
Blocks
#44 test: F1.2 robot exit-code + JSON envelope contract regression suite
terraphim/agent-tasks
Reference: terraphim/agent-tasks#35
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem Statement
Specification
terraphim-agent-session-search-spec.mdsection F1.2 Exit Codes mandates that every CLI invocation propagates one of eight standardised exit codes (0=SUCCESS through 7=ERROR_TIMEOUT) so that AI orchestrators can treatterraphim-agentas a deterministic Unix tool.Code review confirms the enum already exists at
crates/terraphim_agent/src/robot/exit_codes.rswithTermination,Display,From<u8>, andFrom<ExitCode> for std::process::ExitCodeimpls -- but the entire module is gated behind#[allow(dead_code)]andpub use exit_codes::ExitCodeis#[allow(unused_imports)]. Greppingcrates/terraphim_agent/src/main.rsandcrates/terraphim_agent/src/repl/forExitCode,process::exit, orfrom_errorreturns zero hits. Subcommand doc-comments (e.g.Command::Searchlines 702-704) advertise the exit-code contract, butfn main()returnsResult<()>and falls through to anyhow's default panic-style exit, so robot consumers always observe code 0 on success and code 1 on any failure.A working branch
task/860-f1-2-exit-codesexists in the working tree but has no Gitea tracking issue (the#860reference points to the now-confirmed phantomterraphim-airepo on this Gitea instance). This issue creates the paper trail and acceptance criteria for that work.Acceptance Criteria
fn main()returnsResult<terraphim_agent::robot::ExitCode, ...>(or equivalentTerminationimpl) so the process exit value is the numericExitCode.ExitCode::from_error(&anyhow::Error) -> ExitCode(or equivalent) that maps idiomatic error types to spec values:clap::Error::kind() == InvalidSubcommand|UnknownArgument->ErrorUsage(2)terraphim_persistence::Error::NotFoundstyle ->ErrorIndexMissing(3)--fail-on-empty(already onCommand::Searchline 720) ->ErrorNotFound(4)terraphim_*::Error::Auth->ErrorAuth(5)reqwest::Error/ connection refused ->ErrorNetwork(6)tokio::time::error::Elapsed->ErrorTimeout(7)anyhow::Error->ErrorGeneral(1)Command::*arm inmain.rsreturns the appropriateExitCode, threaded through the existingRobotConfigso that--robotmode also writes the matchingmeta.exit_codeJSON field defined inrobot/schema.rs.#[allow(dead_code)]and#[allow(unused_imports)]onpub mod exit_codes;andpub use ExitCode;incrates/terraphim_agent/src/robot/mod.rs.crates/terraphim_agent/tests/exit_codes.rsthat runs the binary viaassert_cmd(already a dev-dep) and asserts:terraphim-agent search "" --fail-on-empty-> exit 4terraphim-agent --bogus-flag-> exit 2terraphim-agent search "valid query"against an unconfigured persistence -> exit 3cargo test -p terraphim_agentpasses.cargo clippy -p terraphim_agent -- -D warningspasses.Proposed Approach
ExitCodethe binary'sTerminationtype (already implemented; just remove dead-code gates and changemain's return).impl ExitCode { pub fn from_error(err: &anyhow::Error) -> Self { ... } }usingerr.downcast_ref::<...>()chains for each spec category. Keep mappings cheap and ordered specific -> general.Command::*handler to returnResult<ExitCode>instead ofResult<()>, so--fail-on-emptyand similar flags can returnExitCode::ErrorNotFoundwithout manufacturing fake errors.--robotmode, populate themeta.exit_codefield ofRobotResponsebefore final serialisation so JSON consumers do not have to inspect$?separately.Affected crates:
terraphim_agent(main.rs, robot/mod.rs, every subcommand handler).Affected types/functions to modify:
fn main()incrates/terraphim_agent/src/main.rspub mod exit_codesandpub use exit_codes::ExitCodeincrates/terraphim_agent/src/robot/mod.rsExitCode::from_error()incrates/terraphim_agent/src/robot/exit_codes.rscrates/terraphim_agent/tests/exit_codes.rsintegration testDependencies
None. The
ExitCodeenum,RobotResponse.meta, andRobotConfigalready exist; this issue solely wires them together.Verification
Scope
Single PR, ~250-350 LOC including tests. The
Terminationimpl, error mapping, and per-command threading all live interraphim_agent; no other crate is touched. Existing branchtask/860-f1-2-exit-codescan be retargeted at this issue.spec-validator Verdict: FAIL
F1.2 Exit Codes specification validation complete. Detailed report:
reports/spec-validation-20260426.mdSummary
The F1.2 specification for typed exit codes (0-7) is clearly defined and the supporting infrastructure exists (ExitCode enum, classify_error(), Termination trait). However, the critical integration gap prevents the spec contract from being fulfilled:
Spec Compliance: 28%
Robot consumers observe exit codes 0 and 1 only; codes 2-7 are not reliably returned.
Blockers
Before merge:
Recommendations
Verdict: NO-GO for merge until integration gaps closed.
Full analysis in:
reports/spec-validation-20260426.mdThemis Roadmap Scoring -- 2026-04-27 (Run 29)
Note: Scoring against
terraphim/agent-tasks(authoritative).terraphim/terraphim-airemains phantom on Gitea (404 for the API; documented in product-owner runs 09+).Essentialism Filter (5/25 Rule)
Top 5 vital few:
Avoid this cycle (the 20): #20, #23, #28, #33, #34, #36 (composite -- decompose), #37, #38, #39, #40, #42, #25, #22, #24, #17, #13, #29, #30, #32, #6.
Not doing this cycle: new feature breadth (clustering, timelines, exports, watchers, connectors) is explicitly sacrificed until F1.x robot contracts (#35, #31), F5 capture safety (#41, #26), and G1 perf gates (#43) are locked in.
Compound-RICE Scores
This issue (#35) ranks #1 with score 760 -- the highest-leverage unblocker in the entire backlog this cycle.
Lead Measures (4DX)
Completing #35 unblocks:
Trade-off statement
Doing #35 now means explicitly NOT shipping #36 (composite robot subcommand surface) yet -- F1.2 is a precondition for its dependants. That sacrifice is the essentialism principle: foundation before breadth.
Acceptance reminder
Spec section F1.2 mandates eight standardised exit codes (0=SUCCESS through 7=ERROR_TIMEOUT). The implementation should expose these as a typed
ExitCodeenum and wire it throughmain()sostd::process::ExitCodecarries the contract value. New issue #44 will lock this contract in CI once #35 lands.Themis product-owner cycle, run 29 -- full report at
/opt/ai-dark-factory/reports/roadmap-20260427-0700.mdThemis Roadmap Scoring -- 2026-04-27 (Run 33)
Vital Few (5/25 Rule)
This cycle's TOP 5 by Compound-RICE:
Trade-offs Named
Doing #35+#44+#26+#36+#42 means NOT doing this cycle:
Lead Measures (4DX)
Dependency Edges Wired This Cycle
7 new edges added to seed PageRank (was 0.0 fleet-wide):
#33<-#26,#34<-#26,#37<-#42,#40<-#42,#30<-#36,#31<-#36,#32<-#36Verdict on New Issue Creation
NO_NEW_ISSUES_NEEDED — backlog at saturation; spec coverage ~99%. Energy this cycle goes to shipping, not scoping.
Marketing Hint (for product launches log when WIG-A ships)
Themis product-owner cycle Run 33 — full report at
/opt/ai-dark-factory/reports/roadmap-20260427-1103.md. Compound-RICE + 5/25 + WIG alignment + dependency seeding.Themis Roadmap Scoring -- 2026-04-27
Cycle outcome
terraphim/agent-tasks(terraphim-ai404, phantom override applied)WIGs (canonical draft)
Essentialism Filter (5/25 Rule)
Top 5 (vital few):
AVOID this cycle (37 distractions): #1, #2, #3, #5, #6, #7, #8, #9, #11, #12, #13, #14, #15, #16, #17, #18, #19, #20, #21, #22, #23, #25, #28, #29, #30, #31, #32, #33, #34, #36, #37, #38, #39, #40, #41, #42, #43
Compound-RICE Scores
Ranked Top 3 (with trade-offs)
Lead Measures (4DX)
Sacrifices Named
Marketing hint (for the launches log)
Once #35 + #44 ship: announce "terraphim-agent Robot Mode is now contract-locked: 8 standardised exit codes, structured stdout JSON, regression-guarded in CI -- ready for orchestrator adoption."
Recommendation to human owner
Persist canonical WIG-A/B/C to
progress.mdor wiki so future Themis cycles stop re-deriving them from issue prose. Treat as TODO for next low-saturation window.Themis cycle (Compound-RICE + 5/25 Essentialism + WIG alignment + UAT discipline) -- full report at
/tmp/themis-out/roadmap-20260427-1104.mdThemis Roadmap Scoring -- 2026-05-07 (Run 34)
Cycle outcome: 7th consecutive saturated cycle. Backlog 44 open. Verdict: NO_NEW_ISSUES_NEEDED.
Stalled-issue flag: This issue (#35) has been unmoved for 10 days (last update 2026-04-27) and remains the highest-Compound-RICE item in the entire backlog (760.0). Foundation precedes everything else. Recommend assignment in the next ADF coordinator sweep.
Vital Few (5/25 Rule)
Avoid this cycle (the 39)
#1, #2, #3, #5, #6, #7, #8, #9, #12-#25, #28-#34, #36-#43, #45, #46. Explicitly sacrificed: feature breadth (clustering, timelines, exports, connectors, watchers, Quickwit logging epic duplication, G1 bench suite). Foundation before breadth.
Lead Measures (4DX)
WIG taxonomy reconciliation (process note)
progress.md(canonical, Q2 2026) defines WIG-1..4. The agent-tasks backlog is overwhelmingly WIG-3 territory. WIG-1/2/4 ships throughterraphim/terraphim-aigit history (recent: #1275 meta_coordinator, #1260 server feature, #1245 test timeout) which remains 404 to product-owner. Two-universe drift is the persistent process gap; recommendation from Run 33 to persist canonical operational WIGs toprogress.mdis still pending.Marketing hint (for the launches log)
Themis Run 34. Compound-RICE + 5/25 Essentialism + WIG alignment. Full report:
/opt/ai-dark-factory/reports/roadmap-20260507-0100.md. Weigh, decide, ship.Themis Roadmap Scoring -- 2026-05-07
Essentialism Filter (5/25 Rule)
TOP 5 vital few:
NOT DOING THIS CYCLE: #34, #33, #25, #23, #22, #18, #17, #16, #15, #14, #13, #12, #11, #9, #8, #7, #5, #4, #3, #28, #36, #32, #31, #30, #38. Choosing the F1.2 contract over breadth across F3.x and F4.x. One solid contract beats five half-finished surfaces.
Compound-RICE Scores
Ranked Top 3
Lead Measures (4DX)
New Issue Created
Gap Flagged
WIG-2 (Tauri/server parity from progress.md) has zero overlap with the agent-tasks backlog. If desktop/server parity is genuinely a Q2 WIG, issues need to land in the desktop tracker -- not here.
Themis product-owner cycle -- full report at
/opt/ai-dark-factory/reports/roadmap-20260507-0404.mdThemis Roadmap Scoring -- 2026-05-07
This issue is rank #1 in this cycle's Compound-RICE analysis. Scoring summary below.
Ranked Top 3 (Compound-RICE)
Compound-RICE breakdown for #35
Lead Measures (4DX)
Cycle Trade-off
Doing #35 this cycle means explicitly NOT doing F4/F5 session intelligence (clustering #23, cross-session learning #42, concept traversal #12, roleTerraphim-graph weighting #37) -- those are speculative analytics built on an unstable foundation.
New Issues Created This Cycle
Both compound with #35 -- #49 protects the contract in CI, #50 closes the structured-error gap that blocks the v1 announcement (#47/#48).
Themis product-owner cycle 2026-05-07 -- full report:
/opt/ai-dark-factory/reports/roadmap-20260507-0506.mdThemis Roadmap Scoring -- 2026-05-17
This issue scored as the rate-limiting keystone of the F1.2 robot-mode contract cluster.
Essentialism Filter (5/25 Rule)
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
Themis / 5-25 Rule -- 2026-05-17 12:58 CEST
TOP 5 (vital few)
#35 feat: wire ExitCode into main() return for F1.2 robot exit code contract
Foundational. Without correct exit codes, every downstream CI gate, wrapper script, and orchestrator that calls
terraphim-agentis flying blind. Blocks #44 and #49. Serves WIG-3 + WIG-4.#50 feat: emit JSON error envelope on robot-mode failures
Completes the robot mode surface contract. A robot mode that returns unstructured stderr on failure is not a robot mode -- it is a broken CLI. Direct dependency of the regression suite. Serves WIG-3.
#51 feat: install SIGTERM/SIGPIPE signal handlers in robot mode
Production reliability gate. Unhandled signals produce corrupted JSON streams and orphaned processes in CI and orchestrator contexts. Cannot ship robot mode to WIG-4 release pipeline without this. Serves WIG-3 + WIG-4.
#44 test: F1.2 robot exit-code + JSON envelope contract regression suite
The test harness that validates #35, #50, #51 actually hold under regression. Without this, any future change silently breaks the contract. Prerequisite for #49. Serves WIG-4.
#29 feat: wildcard/relaxed query fallback when primary search returns zero results
The only WIG-1 issue with immediate user-visible impact. Zero-result searches are the primary trust-breaker for local-first search. All ranking work is irrelevant if queries return nothing. Serves WIG-1.
AVOID AT ALL COST (dangerous distractions this cycle)
#5 Tantivy session index -- full index replacement mid-cycle; high blast radius, zero WIG alignment now
#7 Wire BudgetEngine -- token economy is premature; no budget model agreed
Compound-RICE Scores
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
Themis Scoring — Compound-RICE
Note on #50: the issue body states
confidence=8andsynergy=9, which violates the defined scales (confidence 0.1–1.0; synergy 1.0–2.0+). I have re-normalised toconfidence=0.85andsynergy=1.8based on the problem description. The author should update the issue body.SCORES
RANKED TOP 3
Themis Roadmap Scoring -- 2026-05-18
Essentialism Filter (5/25 Rule)
TOP 5 (vital few) -- the F1.2 robot-contract cluster:
Compound-RICE Scores
Ranked Top 3
Lead Measures (4DX)
Dependency chain: #35 -> #50 -> #51 -> #44 -> #49
Recommended sequencing: #35 today (effort=1), #50 + #51 in parallel (effort=2 each), then #44, then #49.
Not Doing This Cycle (Essentialism)
Sacrificed: #47 (announcement -- premature until CI-enforced), #46 (Quickwit logging epic), #43 (benchmarks -- measures wrong thing before contract stable), #42/#40/#39/#37 (F4/F5 features), #38/#34/#33/#32/#31/#30 (ergonomics + capabilities surface -- premature without F1.2 floor).
Issue Creation
NO_NEW_ISSUES_NEEDED -- backlog is sufficient. The 2 candidate gaps (envelope schema, exit-code table) overlap with #36 + #47 and would fragment the vital chain.
Themis product-owner cycle -- full report at
/opt/ai-dark-factory/reports/roadmap-20260518-0702.mdThemis Roadmap Scoring -- 2026-05-18
Repo Pivot Note
Configured repo
terraphim/terraphim-aireturns HTTP 404 on git.terraphim.cloud. Cycle executed againstterraphim/agent-tasks(43 open issues). Per Themis essentialism: literal-env-var literalism that produces an empty cycle was rejected in favour of real product-strategy value against the visible active repo.Essentialism Filter (5/25 Rule)
TOP 5 (F1.2 Robot Mode contract chain) — all serve WIG-3/WIG-4:
exit_codes.rsbut is#[allow(dead_code)];main()returnsResult<()>, so orchestrators see only 0/1. Everything else in F1.2 depends on this.?and emit nothing.Avoid at all cost this cycle (38 issues): all session-search Phase 2/3 expansion (#28/#29/#30/#32/#33/#34/#36), F5.3 learning extraction (#37/#42), criterion benches (#43), session/import polish (#38/#39/#40/#41/#26/#25/#24/#31), and the ADF Quickwit logging epic (#46). These are real, valuable items — but every one of them ships on top of an un-versioned, un-regression-tested CLI contract until F1.2 lands.
NOT DOING THIS CYCLE: Phase 2/3 session-search expansion, F5.3 learning extraction, benchmarks, and the logging epic are explicitly sacrificed to hold the line on F1.2 contract closure. Robot Mode is the structural foundation — downstream features gain durable testability only once F1.2 is CI-locked.
Compound-RICE Scores
Formula
(R × I × C × S) / (E × M)— critical band ≥30.All five carry Synergy ≥ 1.8 — the chain is genuinely compound, not just adjacent.
Ranked Top 3
Lead Measures (4DX)
Marketing Hint
When #35 + #44 + #47 land together: announce Robot Mode F1.2 Contract v1 — terraphim-agent as a deterministic Unix tool with 8 standardised exit codes and a parseable JSON error envelope; orchestrators can rely on it the way they rely on
greporjq.Issue Creation Verdict
NO_NEW_ISSUES_NEEDED. The bottleneck is delivery, not discovery. Vital 5 already exists with explicit acceptance criteria. 3rd consecutive cycle pointing at the same chain — discipline this cycle is RESTRAINT.
Themis product-owner cycle -- full report at
/opt/ai-dark-factory/reports/roadmap-20260518-0957.mdThemis Roadmap Scoring -- 2026-05-18T09:02:27Z
Essentialism Filter (5/25 Rule)
TOP 5 (vital few -- will be scored):
#35: Wire ExitCode into main() -- foundational F1.2 contract; every downstream robot issue (#50/#51/#44/#49) is blocked until main() returns a meaningful exit code (WIG-3)
#50: Emit JSON error envelope on robot failures -- completes the error-path contract so agents can parse failures deterministically; prerequisite for the regression suite (WIG-3)
#44: Robot exit-code + JSON envelope regression suite -- turns the contract into an executable specification; without tests the contract is aspiration not fact (WIG-4)
#49: CI enforcement of robot-contract regression job on every PR -- gates the entire pipeline against contract regressions; highest PageRank in the repo (WIG-4)
#29: Wildcard/relaxed query fallback when primary search returns zero results -- zero-result search is a silent user-facing failure; no other WIG-1 item appears in this list (WIG-1)
AVOID AT ALL COST (dangerous distractions this cycle):
#47: Announce/CHANGELOG/ADR for F1.2 -- never market before the contract is gated in CI; this is a lagging artefact, not a leading one
#46: Quickwit logging epic -- large new integration surface with no WIG alignment; opens scope while core stability is unresolved
#43: Criterion benchmark suite -- performance measurement belongs after correctness is enforced; benchmarking a broken contract produces meaningless numbers
#42: Lesson extractor (F5.3) -- future-layer capability; F1 contract must close first or this learns from undefined behaviour
#37: Rolegraph session-frequency edge weighting -- advanced ML feature with no path to any current WIG
#28: OpenCode/Codex JSONL connectors -- new source integrations before existing robot contract is stable adds untested surface area
#34: /sessions timeline command -- session UX browsing; zero WIG alignment this cycle
#33: /sessions export command -- session sharing; same reasoning as #34
#38: Load LearningCaptureConfig from TOML -- configuration ergonomics that blocks nothing on the critical path
#25: Custom command aliases -- UX polish; addressed after the contract foundation is proven
NOT DOING THIS CYCLE: All session-management (F4), cross-session learning (F5), robot API surface polish (F3.1-F3.3), and UX ergonomics (F2.2-F2.3) work is explicitly sacrificed because layering new capabilities onto an unverified execution contract produces compounding technical debt, not progress.
Compound-RICE Top 3 (this is cycle 4 of the F1.2 chain)
Execution Order
#35 -> (#50 || #44 in parallel) -> #49 -> #29 (independent)Decision
NO_NEW_ISSUES_NEEDED (4th consecutive cycle)
The five tracked issues (#35, #50, #44, #49, #29) form a complete sequenced chain covering WIG-1, WIG-3, WIG-4. WIG-2 (Tauri parity) produced no candidate meeting all six creation criteria. Creating issues for it now would dilute focus from the unfinished robot-contract foundation.
Not doing this cycle (essentialism): all session-management (F4), cross-session learning (F5), robot API surface polish (F3.1-F3.3), and UX ergonomics (F2.2-F2.3) work is explicitly sacrificed.
Themis product-owner cycle 4 -- full report at
/opt/ai-dark-factory/reports/roadmap-20260518-1102.mdThemis Roadmap Scoring -- 2026-05-30
Essentialism Filter (5/25 Rule)
TOP 5 vital few (F1.2 robot contract chain -- unchanged 7+ cycles):
Compound-RICE Scores
Ranked Top 3
Lead Measures (4DX)
Execution Order
NOT DOING THIS CYCLE (essentialism)
All session features (F4.x: #34, #33), learning capture enhancements (F5.x: #42, #41, #40, #38, #37), KG routing (#52), and Quickwit logging epic (#46) are explicitly sacrificed. The only path that turns WIG-3 and WIG-4 from aspirations into locked-in guarantees is shipping the tested, CI-enforced robot contract chain.
Stall Watch
The F1.2 chain has been the top-5 vital few for 7+ consecutive cycles without movement. To break the loop, two new issues were created this cycle:
Recommendation
Assign #35 to a developer agent now. It is a single-file change (
main.rsExitCode plumbing) with explicit spec reference (F1.2 interraphim-agent-session-search-spec.md). Effort=2. There is no remaining ambiguity; the chain stalls because the head is unowned, not because it is hard.Themis product-owner cycle -- full report at
/opt/ai-dark-factory/reports/roadmap-20260530-1104.mdThemis Roadmap Scoring -- 2026-05-31 (Cycle 7+)
Essentialism Filter (5/25 Rule)
TOP 5 (vital few): #53, #54, #35, #52, #50
Avoid at all cost (sacrificed): #46 (umbrella), #42/#43 (premature), #34/#33/#31/#30/#29/#28 (polish), #17/#18 (observability NTH), #14/#15/#16 (session UX), #40/#41/#21/#36/#37/#51 (deps on F1.2 landing first).
Not doing this cycle: All session-UX polish (F4.x), all observability nice-to-haves, all forward-looking benchmarks. Choosing to fix orchestration stall over add polish on top of a stalled pipeline.
Compound-RICE Scores
Ranked Top 3 (with trade-offs)
Lead Measures (4DX)
Stagnation Escalation (Cycle 7+)
The F1.2 chain has remained the top-ranked unactioned cluster for 6+ consecutive Themis cycles. Per #53's own definition, this IS the chain-stall condition.
Themis recommends -- human decision required:
Marketing hint when #35 lands: "terraphim-agent now returns standardised exit codes -- AI orchestrators get deterministic CI/CD integration."
Themis cycle 7+ -- full report at
/opt/ai-dark-factory/reports/roadmap-20260531-0758.mdRepo: terraphim/agent-tasks (pivot from terraphim-ai 404)