Repository navigation
Reconcile Gitea main into GitHub main (#342) + RLM fixes (#349) - #39
Conversation
…sufficiency path' (#44) from task/2721-insufficient-kg-propagation into main
…-role flag' (#45) from task/2723-rust-engineer-role-fix into main
…nrichment to CI' (#49) from task/2171-ci-enrichment-feature into main
…OR on KG calls' (#51) from task/48-impl into main
Mirror the GitHub CI enrichment steps in the Gitea native-ci workflow: - cargo clippy -p terraphim_sessions --features enrichment -- -D warnings - cargo test -p terraphim_sessions --features enrichment --lib --no-fail-fast All 67 tests pass locally including the 3 enrichment tokio tests and 2 concept unit tests that were silently skipped before.
…nrichment to Gitea native CI' (#52) from task/2171-gitea-ci-enrichment-feature into main
Adds an explicit, named CI guard for the silent zero-chunk regression documented in terraphim/terraphim-ai#3025 / #4325. A default-feature build of terraphim_grep must return non-zero chunks for a matching query; the test fails loudly if `code-search` is ever removed from the `default` feature set (which would compile search_code() to a no-op stub returning Ok(vec![]) -- success-with-zero-items). - crates/terraphim_grep/tests/default_feature_smoke.rs: new integration test. Distinct from no_thesaurus_cli.rs (KG-absent fallback) -- this test's single purpose is the default-feature contract. - .github/workflows/ci.yml: named, visible smoke-test step after the workspace test run (functional gating already existed via `cargo test --workspace`; this makes it explicit and documented). Verified bi-directionally this session (real binaries, no mocks): - default features (code-search on): chunks_returned=1 -> PASS - code-search removed from default: chunks_returned=0 -> FAIL with the named regression message -> revert -> PASS again. Gates: fmt clean; clippy -p terraphim_grep --all-targets -D warnings 0; full crate test suite green. Refs terraphim/terraphim-ai#4325 (cross-repo: terraphim_grep lives in terraphim-clients, extracted via #1910). Co-Authored-By: Claude <noreply@anthropic.com>
…-feature zero-chunk smoke test' (#59) from task/4325-grep-default-smoke-echo into main
…o crates.io' (#60) from task/58-impl into main
…45, #49, #51, #52, #59, #60 - PR #44: Insufficient KG propagation (#2721) - PR #45: rust-engineer shortname fix (#2723) - PR #49: CI enrichment feature (#2171) - PR #51: thesaurus NotFound ERROR suppress (#48) - PR #52: Gitea CI enrichment feature (#2171) - PR #59: grep default-feature smoke test (#4325) - PR #60: terraphim_grep crates.io publishable metadata (#58) Also refreshes Cargo.lock to register env_logger as a terraphim_agent runtime dependency introduced by PR #51 (Cargo.lock had drifted from Cargo.toml since the merge). Refs #108
…ubcommands Refs #1899 Add top-level command wrapping the eight-stage agentic memory lifecycle behind a single discoverable CLI surface. Subcommands: - capture (routes to learn hook) - validate (rubric scorer stub) - distill (routes to learn compile) - retire (learned-rules stub) - scope (role/project boundaries) - rubric (6-dimension diagnostic) - provenance (routes to sessions) - second-run (token delta) - retrieve (routes to search) - apply (routes to terraphim_hooks) Seven subcommands are routing stubs delegating to existing handlers. Three (validate, rubric, second-run) are placeholder stubs for net-new code to be wired in subsequent steps. Implemented in crates/terraphim_agent/src/main.rs following existing Command/Subcommand enum pattern (Memory variant in Command enum, MemorySub enum with clap derive, run_memory_command async handler). Tests: cargo check passes, 246 lib tests pass, all 10 subcommands respond to --help and execute their handler stubs.
…st/show/export/scope Refs #1899 Add terraphim_agent_evolution v1.20.2 from terraphim registry as dependency. Implement real memory lifecycle operations backed by AgentEvolutionSystem: - capture: write MemoryItem to evolution store with provenance tags - list: enumerate memory items with optional item_type filter - show: display full details of a memory item or lesson by ID - export: dump memory items + lessons as JSON or markdown - scope: show role/project KG boundaries from ~/.config/terraphim/kg capture/scope are now real implementations instead of routing stubs. Three new subcommands (list, show, export) added for evolution inspection. Tests: 246 lib tests pass. cargo check clean with 0 warnings.
… README Refs #1899 Implement all remaining memory lifecycle components: Rubric subcommand: - 6-dimension rule-based scorer: faithfulness, scope, provenance, actionability, decay, risk - Composite score with weighted average (faithfulness 0.30, actionability 0.25, scope 0.15, provenance 0.10, decay 0.10, risk 0.10 inverted) - Markdown readout with dimension table, top-3 offenders, recommended retirements - RubricScore struct + score_memory_item/scoring helpers Validate subcommand: - Scores all, specific, or most recent memory items - Per-item scores with composite average Retire subcommand: - Writes retirement proposals to ~/.config/terraphim/ (learned-rules-retirements.md) with CTO approval flag Second-run subcommand: - Reads ADF artefact directory (~/.cache/terraphim/adf-artefacts/) - Finds JSON run metrics files per Gitea issue - Computes token delta, retry delta, wall-time delta - Emits structured JSON with interpretation MEMORY_POLICY.md: - Public commons vs permissioned memory boundary - Storage location table - Enforcement via memory scope --check README: - Full memory command reference (13 subcommands documented) - Link to MEMORY_POLICY.md Tests: 246 lib tests pass. cargo check clean.
…fs #1899 Add load_evolution()/save_evolution() helpers that persist AgentEvolutionSystem state as JSON to: ~/.config/terraphim/evolution/cli-agent.json - MemoryState and LessonsState are serialized/deserialized - Captured items survive CLI invocations - List/show/export/rubric consume persisted state - save_evolution() called after every capture mutation Verified: capture → list shows item, capture → rubric scores, capture → export produces markdown. All 246 tests pass.
…edup scoring Refs #1899
P1: Capture now stores provenance_tag as a tag, not as content.
Content gets a descriptive string. Tags field receives
'provenance:<tag>' entries. Help text updated accordingly.
P2: Extract compute_decay() and compute_risk() shared functions
to eliminate duplicate scoring logic between score_memory_item
and the rubric retirement filter. Add TERRAPHIM_ADF_ARTEFACTS_DIR
env var override for second-run artefact path.
The rebase of task/1899-memory-lifecycle-cli onto current main d54f28f left several files in a non-compiling state due to upstream renames (terraphim_update, terraphim_automata 1.21.0 borrows &Thesaurus, thesaurus registry pins from Refs #112). - crates/terraphim_grep/Cargo.toml: drop the path-dep duplicate left by the rebase; keep the Refs #112 registry-bearing entry. - crates/terraphim_grep/src/hybrid_searcher.rs: - bind the kg_concepts result of search_kg (was dropped by an orphan semicolon); - pass &thesaurus to find_matches (1.21.0 borrows it); - iterate over all search_paths, apply boost_chunks_with_kg before truncating, so KG-ranked chunks survive the candidate cut. - crates/terraphim_grep/src/main.rs: restore the function signatures that the conflict resolution collapsed (push_unique_candidate, discover_project_thesaurus) and add the missing #[test] attributes on the two post-resolution tests. - crates/terraphim_update/src/signature.rs: remove an orphan closing brace left after the conflict on get_embedded_public_keys. Verified locally: cargo check --workspace --all-features, cargo clippy --workspace --all-features --all-targets -- -D warnings, and cargo test on the affected crates (terraphim_grep, terraphim_update, terraphim_sessions) all pass. Pre-existing Refs #113 failures in cross_mode_consistency_test, mcp_server integration tests, and terraphim_update::test_resolve_asset_url_against_local_manifest are unchanged. Refs #1899
PR #61 added UpdaterConfig::with_repo and called it from agent + grep with the constructor's own default values (terraphim/terraphim-clients). The packaged_install_graph_regression test (cargo package + cargo install --path) resolves terraphim_update from the terraphim registry, where the published 1.20.2 lacks with_repo, so the install failed to compile. The design's own rollback plan says to revert with_repo if no consumer uses it functionally. Here every caller passed the same value the constructor already sets, so the calls were no-ops; the method had no real consumer and would have required a registry publish to keep CI green. Reverting restores install-graph correctness and aligns the branch with main's updater API. Refs #1899
Captures the 8 native-ci steps, gitea native-ci status check, traceability matrix for Refs #1899 / #95 / #62 / #112, and the defect register (the with_repo rollback plus two rebase-fallout defects resolved before merge). Refs #1899
Acceptance criteria trace from Refs #1899 / #95 / #62 / #112, performance and security review notes, defect register (the three closed defects from the verification report plus follow-ups). Refs #1899
…ability Rubric Refs terraphim/terraphim-ai#1899' (#61) from task/1899-memory-lifecycle-cli into main
…xisting failures exposed by --all-targets
Refs #84, closes part of #108 (campaign summary)
Findings (full report in .quality/pr-84-{verification,validation}.md):
- 57 unique test failures surface on Linux CI when --all-targets replaces --lib
- 37 are pre-existing (also fail on macOS main baseline); 20 are Linux-only
- Pre-existing failures are tracked by #113 (PR #135 in progress) and
separately by the missing docs/src/kg fixture path bug
- PR's empirical claim 'does not destabilise the pipeline' does not hold on
the Gitea runner because is_ci_environment() does not recognise the runner
(no CI=true / GITHUB_ACTIONS / dockerenv / root)
- Recommendation: do not merge PR #84 as-is; merge PR #135 first or extend
PR #84 with env: CI: true plus minimal #[ignore] for the MCP server-binary
tests, plus fix the wrong <workspace>/docs/src/kg path in replace_feature_tests
…lease-artifacts-sync
…s' (#323) from task/322-stage-only-release-artifacts into main Merge exact reviewed stage-only release producer after isolated-runner exact-head native CI success.
…cers' (#331) from task/248-integrated-packaging into main
Immutable v1.21.15 run 35413858762 attempt 5 built all six binaries and passed Linux staging, then failed three downstream jobs on two producer portability defects: * create-universal-macos called `lipo -verify_arch x86_64 arm64 FILE`; Xcode 16.4 lipo requires the input file before the -verify_arch command/arch flags and parsed FILE as an architecture. Use `lipo FILE -verify_arch x86_64 arm64` and pin the exact safe order in the release-binaries workflow contract (with mutation coverage). * Ubuntu 24.04 /usr/bin/rpm2cpio emits absolute member names for nFPM 2.47 RPMs, so `rpm2cpio | cpio -idmv` returned nonzero and could write toward the host's real /usr, with stderr discarded. Every RPM payload extraction (build-client-packages.sh host and Docker branches, native gate host and Docker branches, strip-test SHA-binding probes) now uses `cpio --no-absolute-filenames`, keeps extraction private, fails closed on any nonzero status, and surfaces the rpm2cpio/cpio diagnostics on failure. New hermetic regression tests drive real cpio through verify_rpm with an absolute-member newc archive and assert both the safe extraction and the failure diagnostics; a static contract fails if any RPM extraction consumer drops the safe option. Bump release metadata 1.21.15 -> 1.21.16 (workspace version, the seven workspace-locked crate entries in Cargo.lock, and the release identity asserted by the workflow contract). Protocol activation thresholds and historical 1.21.15 fixtures are intentionally unchanged; no dependency-source changes.
…argo lanes PR #332 CI run 33975 / web run 537, job 68638: the broad cargo test --workspace --all-targets lane runs packaged_install_graph_regression, whose nested `cargo package` regenerates the packaged lockfile and resolves private terraphim_command_runtime from the terraphim registry. Cargo authenticates that registry only via CARGO_REGISTRIES_TERRAPHIM_TOKEN; the terraphim-gitea-runner inherits GITEA_TOKEN but applies neither workflow job env nor step env, so the nested fetch failed with HTTP 401. Run 33980 / web run 538, job 68643 confirmed the wiring reached the nested Cargo but the registry still answered "the token does not include an authentication scheme" and HTTP 401: the Gitea sparse registry requires the token value to carry the Bearer scheme. Run 33984 / web run 539, job 68647 disproved the prior coverage assumption: the `cargo llvm-cov nextest --workspace --all-targets` coverage lane also re-executes packaged_install_graph_regression under cargo-llvm-cov's runner and needs the same Bearer-schemed alias. Without it the coverage lane is the lone failure (2020 tests: 2019 passed; only the packaged graph fails), so the alias must extend to all three lanes that exercise the private registry. Wire the runner-inherited token through the only mechanism the runner honors -- leading VAR=value assignments, which its policy strips token-wise before the allowlist check (the same mechanism the coverage lane already uses for the SSL vars) -- with the exact schemed value: CARGO_REGISTRIES_TERRAPHIM_TOKEN="Bearer $GITEA_TOKEN" applied to exactly three lanes: the broad --workspace --all-targets lane, the focused packaged_install_graph_regression lane, and the cargo llvm-cov nextest --workspace --all-targets coverage lane. The coverage lane's existing SSL_CERT_FILE/SSL_CERT_DIR/TERRAPHIM_SERVER_BIN leading assignments and runner policy are preserved. No literal token and no secrets interpolation in the workflow text, no credentials.toml, and no weakening of the packaged graph gate. The ci_guards.rs contracts require the Bearer scheme on all three (and only three) lanes and reject raw/wrong-scheme/missing/continuation/off-lane aliases, while preserving documentation comments.
…332) from fix/1.21.16-producer-portability into main
8a245e5 wired CARGO_REGISTRIES_TERRAPHIM_TOKEN="Bearer $GITEA_TOKEN" as an unconditional leading assignment on the three registry-resolving lanes. That form works on host-mode runners (which inherit GITEA_TOKEN into the step shell) but expands EMPTY on the Firecracker-VM runners -- vm_executor POSTs each step as {code, working_dir} with no env payload (#328) -- so cargo sends 'Authorization: Bearer' and the Gitea sparse registry answers 401 'Failed to authenticate user'. The nested cargo package in packaged_install_graph_regression therefore failed (runs #541/#542) and main has been red since 09-19. The alias is now applied conditionally as the first line of each guarded run block: test -z "$GITEA_TOKEN" || export CARGO_REGISTRIES_TERRAPHIM_TOKEN="Bearer $GITEA_TOKEN" Host runners export the alias; VM runners skip it and cargo falls back to the baked CARGO_HOME credentials.toml (scheme-qualified -- validated locally: raw token 401s, 'Bearer <tok>' packages cleanly), which is what made runs #527/#529 green. test/export are allowlisted; first token of each block is 'test'. ci_guards validate_native_ci_token_aliases rewritten to enforce the conditional form (exact alias line immediately above each guarded command; unconditional single-line and raw forms are regressions; mutation coverage updated).
…nners have no step env)' (#336) from task/335-vm-safe-registry-token-alias into main
…b/ and scripts/ trees (Refs #342)' (#344) from task/342-sync-github-trees into main
…native lane Main red since 2026-10-01 (Gitea run 36153): the coverage_tool_pinning_matches_local_toolchain ci_guard parses .github/workflows/ci.yml for a 'tool:' line that #342 removed with the GH coverage lane. Fix (not remove): re-point the guard at the sole remaining pin source, .gitea/workflows/native-ci.yml. Refs #313 (original drift-test rationale), #342 (trigger). Co-Authored-By: Meiko (Terraphim agent)
…tive-ci.yml pins Phase 2 of fix-coverage-pinning-guard: swap the deleted GH 'tool:'-block contract for the surviving canonical pin site (.gitea/workflows/ native-ci.yml 'cargo install --version' lines), update stale comments/step names, add parser unit tests. Versions unchanged. Validation artefact N/A (verification-only change). Co-Authored-By: Meiko (Terraphim agent)
…tive-ci.yml pins
#342 removed the GitHub coverage lane and its taiki-e 'tool:' block, but
the drift guard still parsed .github/workflows/ci.yml for that line and
hard-failed ('ci.yml has no tool: line') — main red since 2026-10-01
(Gitea runs 36153, 36127).
Fix, not remove: the guard's #313 invariant (coverage-tool install pins
must equal runner-local installs so lcov ABI cannot drift) survives with
a single lane and a single pin site. The guard now extracts the pins from
the canonical source — the 'cargo install <tool> --version <v> --locked'
lines in .gitea/workflows/native-ci.yml — via a new fail-closed helper:
- no pin line / no --version / no --locked / non-numeric version /
divergent duplicate pins all panic with an actionable message
- optional 'run:' prefix tolerated (block-scalar run blocks)
- token-boundary matching so cargo-llvm-coverage cannot satisfy a
cargo-llvm-cov query
native-ci.yml comments and step names now declare the pins canonical
instead of claiming to mirror the deleted GH block. Versions unchanged
(cargo-llvm-cov 0.8.5, cargo-nextest 0.9.144).
Verified locally: cargo fmt clean; clippy -p terraphim_agent --test
ci_guards -D warnings clean; all 14 ci_guards tests pass (9 new parser
unit tests + the re-pointed guard against the real native-ci.yml with
local tools at the pins).
Refs #313 (original drift-test rationale), #342 (GH lane removal)
Co-Authored-By: Meiko (Terraphim agent)
…ning-guard Phase 4 evidence: 14/14 ci_guards tests, 9/9 parser branches, fmt/clippy clean, integration against the real native-ci.yml. Defect register records the run:-prefix parse bug found and fixed in Phase 3 (D002) and its regression test (D003). Validation N/A per approved design. Co-Authored-By: Meiko (Terraphim agent)
Research: PASS 4.7/5 avg. Design: CONDITIONAL PASS 4.5/5 avg (non-blocking recommendations: enumerate parser-branch tests from the panic contract; state real-file key prefixes in fixtures). Neither blocks the phase transitions already approved. Co-Authored-By: Meiko (Terraphim agent)
The comment rewrite in 6c4b4e2 declared the native pins canonical, but the step rename in the same change was lost to a tooling race and never committed — the steps still claimed 'pinned to GH ci.yml version'. Caught by structural review of PR #345 (round 1, P2). Co-Authored-By: Meiko (Terraphim agent)
…native-ci.yml pins (#313, #342)' (#345) from task/fix-coverage-pinning-guard into main
…nings Reasoning models (e.g. DeepSeek V4 Flash) spend tokens on chain-of-thought reasoning before emitting content. The previous 2000-token cap was routinely exhausted by the reasoning phase alone, leaving content:null in the response. The parser silently converted this to an empty string, AnswerSignature::parse failed, and answer:None was returned with no error surfaced to the user. - Raise max_tokens from 2000 to 8000, configurable via TERRAPHIM_GREP_MAX_TOKENS - Extract extract_content() in openrouter_client.rs; log tracing::warn! when the LLM returns empty content, including finish_reason and whether reasoning tokens were present - Log tracing::warn! in lib.rs when answer parsing fails on the RLM response Refs #349
Reset all crate source to gitea/main versions as part of #342 reconciliation. The -X theirs merge strategy produced inconsistent hunks when mixing GitHub-only refactoring with Gitea code evolution. Refs #342
…nings Reasoning models (e.g. DeepSeek V4 Flash) spend tokens on chain-of-thought reasoning before emitting content. The previous 2000-token cap was routinely exhausted by the reasoning phase alone, leaving content:null in the response. The parser silently converted this to an empty string, AnswerSignature::parse failed, and answer:None was returned with no error surfaced to the user. - Raise max_tokens from 2000 to 8000, configurable via TERRAPHIM_GREP_MAX_TOKENS - Extract extract_content() in openrouter_client.rs; log tracing::warn! when the LLM returns empty content, including finish_reason and whether reasoning tokens were present - Log tracing::warn! in lib.rs when answer parsing fails on the RLM response Refs #349
Complete the #342 reconciliation by syncing tests/ alongside src/. Resolves duplicate hermetic_learnings_dir from mixed merge. Refs #342
Structural Review Statuspi-rust structural review could not be executed — no API keys are configured for any supported pi provider (openai-codex, anthropic, openai all return "No API key found"). Manual review of new code (the only non-merge changes)The PR contains 324 reconciliation commits from Gitea main (previously reviewed) plus one new cherry-picked fix (#349, 172 insertions across 2 files): crates/terraphim_grep/src/lib.rs:
crates/terraphim_grep/src/openrouter_client.rs:
FindingsNo P0/P1 issues identified. The changes are additive (logging) and a token limit increase. BlockerThe pi-rust review should be re-run once provider credentials are available, before merging. The 267-file reconciliation is a merge of previously reviewed Gitea commits; the only new code is the #349 fix above. |
P1: sufficiency_explanation unconditionally claimed 'the answer was synthesised' even when AnswerSignature::parse failed (answer: None), producing a self-contradictory JSON contract. Now emits an accurate explanation on the parse-failure path. P2: cap TERRAPHIM_GREP_MAX_TOKENS at 32k to prevent a typo from becoming an unbounded cost multiplier; defensive fallback when the below-thresholds vector is unexpectedly empty. Refs #349, review by pi-rust (kimi-for-coding/k2p5)
SummaryThis PR raises the RLM synthesis Key changes:
What was done well: the test suite is a standout — the What remains problematic: the final Confidence Score: 3/5
Important Files Changed
Diagram%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["search(query, options)"] --> B{"options.force_rlm?"}
B -->|yes| C["search_with_rlm: hybrid search + judge_with_metrics"]
B -->|no| D["hybrid_searcher.search"]
D --> E["judge_with_metrics -> (Sufficiency, SufficiencyMetrics)"]
E --> F{"Sufficiency verdict"}
F -->|Sufficient| G["search_only_result + explanation<br/>(coverage/KG/diversity vs thresholds)"]
F -->|NeedsSynthesis| H{"rlm_requested()?<br/>(--answer / --force-rlm)"}
F -->|NeedsExpansion| H2{"rlm_requested()?"}
F -->|Insufficient| I["RlmInsufficient + explanation<br/>(truthful chunks_returned / kg_hits)"]
H -->|no| J["SearchOnly + below-thresholds explanation"]
H2 -->|no| J2["SearchOnly + low-coverage explanation"]
H -->|yes| K["search_with_rlm_fallback"]
H2 -->|yes| K
C --> K
K --> L{"llm_client configured?"}
L -->|no| M["SearchOnly + 'no LLM client' explanation"]
L -->|yes| N["chat_completion(max_tokens = rlm_max_tokens())<br/>env: TERRAPHIM_GREP_MAX_TOKENS"]
N --> O["extract_content() in OpenRouterClient<br/>warn! if empty (finish_reason, has_reasoning)"]
O --> P{"options.include_answer?"}
P -->|yes| Q{"AnswerSignature.parse(llm_response)"}
Q -->|Ok| R["AnswerWithCitations + 'synthesised in Nms' explanation"]
Q -->|Err| S["warn! + answer: None<br/>⚠️ explanation still claims synthesis — P1"]
P -->|no| T["RlmSynthesis, answer: None"]
style S fill:#f8d7da,stroke:#dc3545
style J fill:#d4edda,stroke:#28a745
style J2 fill:#d4edda,stroke:#28a745
style M fill:#d4edda,stroke:#28a745
Inline FindingsP1 crates/terraphim_grep/src/lib.rs, line 444: Unconditional "answer was synthesised" explanation contradicts the contract on the parse-failure path When sufficiency_explanation: format!(
"Found {} chunks (coverage {:.2}, KG confidence {:.2}); the answer was \
synthesised by the LLM in {}ms.",
...
),
sufficiency: SufficiencyState::RlmSynthesis,The emitted JSON then self-contradicts: Suggested fix: let explanation = if answer.is_some() {
format!(
"Found {} chunks (coverage {:.2}, KG confidence {:.2}); the answer was \
synthesised by the LLM in {}ms.",
chunks.len(), metrics.coverage, metrics.kg_confidence, rlm_latency_ms,
)
} else {
format!(
"Found {} chunks (coverage {:.2}, KG confidence {:.2}); the LLM responded \
in {}ms but the response could not be parsed into an answer (see logs). \
The chunks below are the unmodified search results.",
chunks.len(), metrics.coverage, metrics.kg_confidence, rlm_latency_ms,
)
};Optionally also consider a distinct P2 crates/terraphim_grep/src/lib.rs, line 822: Replacement The deleted test asserted the P2 crates/terraphim_grep/src/lib.rs, line 129:
P2 crates/terraphim_grep/src/lib.rs, line 143: The P2 crates/terraphim_grep/src/lib.rs, line 247: The let reason = if below.is_empty() {
"multiple metrics below their thresholds".to_string()
} else {
below.join(", ")
};Comments Outside Diff (1)
FooterLast reviewed commit: 8bc9fd8 | Reviews (1) |
P1 + P2 Fixes Applied (commit 9e1092e)All findings from the pi-rust structural review have been addressed: P1 fixed: P2 fixed: P2 deferred (pre-existing code, not introduced by this PR):
All 87 tests pass. Clippy clean. rustfmt clean. |
Summary
Reconciles the diverged Gitea and GitHub main lines (#342) and applies the RLM reasoning-model fixes (#349).
#342 Reconciliation
src/andtests/directories to gitea/main versions (the evolved code line).github/orscripts/— GitHub CI is fully intact#349 RLM Fixes (cherry-picked from e672f13)
TERRAPHIM_GREP_MAX_TOKENSextract_content()withtracing::warn!when LLM returns empty contenttracing::warn!when answer parsing failsResult
terraphim_grepnow has: the #81 RLM opt-in gate, the #349 max_tokens fix, and all GitHub CI — everything needed to cut a proper v1.21.17 release.Test plan
cargo check --workspacepassescargo test --workspace— all 967 tests pass (1 flaky under parallel load, passes individually)Refs #342, #349