Skip to content

fix(repo): prevent daemon write replay after ack loss - #3843

Open
KooshaPari wants to merge 364 commits into
tailcallhq:mainfrom
KooshaPari:safety/daemon-ack-loss-20260813
Open

fix(repo): prevent daemon write replay after ack loss#3843
KooshaPari wants to merge 364 commits into
tailcallhq:mainfrom
KooshaPari:safety/daemon-ack-loss-20260813

Conversation

@KooshaPari

Copy link
Copy Markdown

Summary

  • distinguish daemon unavailability before a request from indeterminate post-send outcomes
  • return an explicit error instead of replaying post-send failures through the direct repository
  • cover a daemon-recorded request whose ACK is lost

Safety contract

Direct fallback remains available only after initial connect/spawn failure. DbClient::send transport failures, Response::Error, and unexpected responses are explicit indeterminate errors, preventing duplicate writes.

Verification

  • cargo test -p forge_repo
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo +1.96 fmt --check
  • git diff --check

KooshaPari and others added 30 commits July 6, 2026 18:10
Terminal-Forge scanline + mint-cursor identity demo.
5s loop rendered via playwright + ffmpeg from CSS-animated SVG.

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
… addition) (#86)

Upstream fork annotation: this is a Phenotype-org addition. It is
NOT present in tailcallhq/forgecode.

Adds `crates/forge_display/src/theme.rs` with the Terminal-Forge
family palette per the vision-pillar L96 lock-in:

  tf-deep-charcoal   #0d1117  (panel / background)
  tf-deep-charcoal-2 #161b22  (nested panel / surface)
  tf-amber-crt       #ffb454  (forgecode dominant)
  tf-synthwave       #ff7edb  (accent)
  tf-mint-prompt     #7ee787  (success / prompt)

Exports:
- `TerminalForgePalette` (struct with hex-string fields, Copy)
- `terminal_skin_from_theme(&TerminalForgePalette) -> MadSkin`
  helper that wires the palette into termimad's MadSkin so
  MarkdownFormat (and downstream consumers) inherit Terminal-Forge
  identity without per-call-site color literals.

Wires `pub mod theme;` into forge_display/src/lib.rs and re-exports
the public symbols.

Tests (+4):
- terminal_forge_palette_matches_tokens_css_family_3: pins the L96
  decision (any drift must come from coordinated tokens.css update)
- parse_hex_accepts_canonical_terminal_forge_tokens: 5 hex inputs
- parse_hex_rejects_malformed_input: 4 negative cases
- terminal_skin_from_theme_produces_termimad_skin: smoke-test
  MadSkin wire-up

Local gate: cargo test -p forge_display → 29 tests pass, 0 fail
(was 25 before this PR).

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
…#91)

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
* feat(packaging): forge-dev binary + install guide (T18)

Add a feature-gated forge-dev [[bin]] target alongside the existing
forge binary so operators can install the Phenotype build side-by-side
with the upstream release. The forge-dev target is opt-in via the
empty dev-binary feature flag, keeping the default cargo install
behavior unchanged.

- crates/forge_main/Cargo.toml: declare [features] dev-binary = []
  and a new [[bin]] name = "forge-dev" with required-features =
  ["dev-binary"]. The shared src/main.rs path produces the documented
  dual-target cargo warning, which is expected.
- docs/forge-dev-install.md: 2-paragraph install guide covering the
  side-by-side rationale, the --features dev-binary gate, and the
  cargo install command from the git fork.

cargo check -p forge_main defaults to building only the forge
bin (no warning). cargo check -p forge_main --features dev-binary
builds both forge and forge-dev bins and finishes clean.

Refs: docs/packaging/FORGE_DEV_PACKAGING.md §2.1, §6.5.

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

* audit(v38): forgecode C03 scorecard — Agent Readiness L30.1-L30.12

Authored by parent (not codex) because the codex standalone dispatch stalled at the read-evidence phase (log 161KB of source-file reads, no file written, no proc visible after 3 minutes idle). Same pattern as the earlier Tracera failure.

DEBUG: every pillar cites real file:line refs (AGENTS.md:1-246, CLAUDE.md:1-133, 2888 #[test] markers, etc.).
OPTIMIZE: 12 pillars × ~10 lines each ≈ 120 lines total.
ENRICH: every gap has explicit effort (S/M) for follow-up.

CLUSTER_TOTAL score=18/36 pct=50% grade=D

* audit(v38): forgecode C05 scorecard — 5/30 F

* audit(v38): forgecode C06 scorecard — 12/24 C

* audit(v38): forgecode C07 scorecard — 16/30 C

* audit(v38): forgecode C04 scorecard — Security (18/30)

* audit(v38): forgecode C08 scorecard — Eval Coverage (8/30 )

* audit(v38): forgecode C09 scorecard — Accessibility+UX (23/42 )

* audit(v38): forgecode C10 scorecard ()

* audit(v38): forgecode C09 scorecard (soft_goal_delta: friction capture is not yet instrumented18/42 )

* audit(v38): forgecode C10 scorecard (10/33 )

* audit(v38): forgecode  scorecard (audit/.lane-c11/C11.md:7/30 )

Parent-authored (continuation of v38 scorecard sweep).

* audit(v38): forgecode C03.md refinement (25/36 )

Re-scan refinement with additional evidence. CLUSTER_TOTAL marker preserved.

* audit(v38): forgecode C05.md refinement (5/30 )

Re-scan refinement with additional evidence. CLUSTER_TOTAL marker preserved.

---------

Co-authored-by: ForgeCode Bot <forgecode-bot@users.noreply.github.com>
Co-authored-by: ForgeCode <noreply@forgecode.dev>
Co-authored-by: Phenotype Agent <agent@phenotype.ai>
…se policy (#92)

* renames(helioslite): add canonical binary + publish-surface metadata + provenance docs

* renames(helioslite): update channel + doctor banner + packaging matrix + landing/Caddy

* ci(helioslite): add main branch-protection config (file-only)

* renames(helioslite): redirect banner + env-var legacy fallback + tombstone

* docs(helioslite): add redirect-chain + install-time tombstone sections
…glob_pattern (#93)

3 utility modules adapted from the substrate gateway library (L123 + L131)
into forge_infra. These primitives are useful for forge's existing retry /
watcher / tool-pattern code paths without depending on the substrate
workspace.

  - backoff: Fixed / Linear / Exponential retry schedule capped at max.
    4 unit tests including capped-at-max regression guard. Suitable for
    MCP server retries and provider endpoint backoff.

  - cyclic_check: CRC-8 (poly 0x07), CRC-16-CCITT (poly 0x1021),
    CRC-32-IEEE (poly 0xEDB88320). 4 unit tests with the standard
    '123456789' known-vector vectors. Useful for file integrity checks
    on tool output + JSON RPC framing.

  - glob_pattern: ASCII glob matcher with * ? [abc] [!abc]. 8 unit
    tests. Useful for file include/exclude lists, watcher path filters,
    and tool-pattern allowlists across the MCP and tool-macro layers.

All three registered as  in crates/forge_infra/src/lib.rs. cargo
test -p forge_infra shows 16 new tests passing.

Ref: l133-forgecode-utility-cross-pollination

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
- get_all_provider_models now gracefully handles individual provider
  failures instead of failing the entire /models endpoint when one
  provider returns a 500. Individual errors are logged as warnings;
  the operation only fails if every configured provider fails.

- Added /providers remove TUI command (AppCommand::ProviderRemove)
  that lets users interactively select and remove a configured
  provider from the REPL, matching the behavior of the existing
  /logout command.
Re-lands Primary3090/Legacy1080 lane intent lost during GH restore. Includes WSL and Windows llama.cpp CVD profile adapters for pheno-harness.
Pin workflow actions, tighten token permissions, fix trufflehog install, narrow cargo-deny to source checks, and address rustfmt/clippy/build failures.

Co-Authored-By: ForgeCode <noreply@forgecode.dev>
Use a resolvable Swatinem/rust-cache commit SHA so nextest and lint jobs can start.

Co-Authored-By: ForgeCode <noreply@forgecode.dev>
Replace go install with the official pinned TruffleHog action because v3.91.0 cannot be installed as a Go tool due upstream replace directives.

Co-Authored-By: ForgeCode <noreply@forgecode.dev>
Use resolvable commit SHAs for install-action, cache, SLSA, and release-drafter pins; verify all pinned action refs through the GitHub commits API.

Co-Authored-By: ForgeCode <noreply@forgecode.dev>
Use the TruffleHog Docker tag format expected by the pinned composite action.

Co-Authored-By: ForgeCode <noreply@forgecode.dev>
Run cargo-deny source checks only and install cargo-nextest explicitly via pinned install-action.

Co-Authored-By: ForgeCode <noreply@forgecode.dev>
Install Zig in Rust workspace CI lanes so forge_daemon build scripts can run during clippy, nextest, coverage, and advisory autofix.

Co-Authored-By: ForgeCode <noreply@forgecode.dev>
Skip the Zig daemon C core unless explicitly requested so normal workspace builds and Linux CI do not fail on Zig/libc translation issues. Keep dispatch failure explicit when the core is not enabled and fix forge_tui clippy output formatting.
Make proc-stat CPU parsing return 0.0 on malformed data instead of using ? in an f64-returning helper, and mark the Linux sysconf extern block unsafe for Rust 2024 workspace builds.
Co-Authored-By: ForgeCode <noreply@forgecode.dev>
Co-Authored-By: ForgeCode <noreply@forgecode.dev>
# Conflicts:
#	crates/forge_gpu/Cargo.toml
#	crates/forge_gpu/src/lib.rs
KooshaPari and others added 23 commits August 9, 2026 17:27
heliosdoctor --integrity-only runs a fast PRAGMA integrity_check on both
the write and legacy databases without COUNT queries. Plain output prints
a dedicated 'integrity check' block; porcelain/json add write_db/legacy_db
lines. Includes two CLI parse tests.

Also fixes the pre-existing forge_app test-gate compile break (E0046 from
split-DB EnvironmentInfra extension): database_stats default impls added
to test mocks in changed_files, command_generator, orch_runner,
terminal_context, and user_prompt.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* fix(ci): repair Rust 1.96 quality gates

* fix(ci): refresh release workflow and safe snapshot hashing

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

---------

Co-authored-by: KooshaPari <koosha@example.com>
Co-authored-by: ForgeCode <noreply@forgecode.dev>
…h test, dedupe mock

- forge_embed: normalize CRLF->LF at template registration so rendered
  output (and insta snapshots) is identical on Windows and Linux; git
  stores templates as LF, autocrlf checkouts were leaking CRLF into
  snapshots (command_generator, compact).
- workspace_status: gate test_file_statuses with #[cfg(unix)] - the
  POSIX absolute-path semantics differ on Windows, matching the pattern
  established for fd.rs/path.rs tests.
- orch_runner: drop duplicate database_stats left by the origin/main
  merge (E0201).
- fmt: apply rustfmt to feature files (api, forge_api, command_generator,
  services, user_prompt, env, ui, app_config, forge_embed).

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
release build of 6c98c8c installed to Programs\heliosLite + Programs\Forge; version 2.10.7 confirmed; doctor/export results.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
test_file_statuses asserts Unix-rendered absolute paths (/workspace/...) and was never runnable on Windows; the forge_app test target did not compile here until the test-build blocker fixes. Same class as the fd.rs/path.rs cfg(unix) gates.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…o, forge_main

- database_stats mock impls: use async fn syntax (field_reassign / async_fn_in_trait)
- env.rs: struct-update init for HeliosdoctorDbStats, collapse nested if-lets
- conversation_repo: collapse if-lets, needless borrows, allow dead_code on
  QueryableByName ExportRow field
- executor.rs: drop needless borrows in CRLF-tolerant comparisons
- provider_repo / openai_responses: async fn database_stats mocks
- ui.rs: remove unused std::fs import in tests

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
lib+bin split (lib exposes client+protocol so forge_repo can depend on it); daemon executes real upsert/update/delete SQL against the split-DB write path (single writer connection, batching kept); Windows named-pipe transport alongside the Unix socket; DELETE keys on the conversation_id PK (workspace predicate could silently no-op when cwd hashing diverges); JSON frames; drop unused bincode dep.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…-in)

Environment gains dbd_enabled() (FORGE_DBD_ENABLED) and dbd_socket_path() (FORGE_DBD_SOCKET); DaemonConversationRepository routes upsert/upsert_ref/update_parent_id/delete through forge_dbd with direct-diesel fallback on any daemon failure (trait surface unchanged, reads stay direct); ForgeRepo wires it when enabled — off by default, zero behavior change otherwise.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
test_create_with_nonexistent_absolute_path used a Unix-only "/this/..." fixture; is_absolute() is false for prefix-less paths on Windows, so canonicalize-fallback bailed and unwrap() panicked. Gate the Unix fixture and add a drive-qualified Windows twin (test-only change).

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Daemon (server.rs): exits cleanly after the last client disconnects and the idle timeout (default 300s) elapses, draining the write queue and unlinking the socket; active-connection tracking on both the Unix-socket and Windows named-pipe transports; new_with_idle for tests.

Client (daemon_repo.rs): on the first routed write that cannot connect, spawns forge_dbd exactly once per process (FORGE_DBD_BIN or PATH lookup, inheriting FORGE_WRITE_DB_PATH), polls the socket ~2s, then falls back to the direct diesel path; a second failure never respawns.

Environment (env.rs): dbd_bin_path() reads FORGE_DBD_BIN, mirroring the existing env-var pattern.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
ToolDescription reads description .md files at compile time via
fs::read_to_string; on Windows autocrlf checkouts those carry CRLF while
committed snapshots are LF, breaking snapshot determinism. Normalize to
authored LF bytes, matching the forge_embed template fix.

Verified: forge_repo --lib 369 passed (incl. catalog snapshot test).

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
heliosdoctor --integrity-only is PRAGMA-only at the forge_infra layer,
but the runtime services infra is ForgeRepo<ForgeInfra>, whose
EnvironmentInfra impl forwarded database_stats only. database_integrity
therefore fell back to the trait default (full COUNT stats), so
porcelain/json output under --integrity-only surfaced db_total counts
instead of the cheap probe. ForgeServices had the same gap.

Forward database_integrity in both wrappers and add a regression test
that constructs ForgeRepo over a mock infra with distinguishable
database_stats/database_integrity results.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
ForgeRepo/ForgeServices now forward database_integrity so
heliosdoctor --integrity-only stays PRAGMA-only at runtime.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* fix(helioslite): keep default home separate from Forge

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

* fix(snapshot): match current Forge conversation schema

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

* fix(snapshot): reuse equivalent later exports

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

* fix(snapshot): recover matching publish races

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

* fix(helioslite): route published destinations to verifier

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

* fix(ci): repair strict workspace quality gates

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

* fix(ci): satisfy strict workspace lint

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

* fix(helioslite): block symlinked snapshot destinations

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

---------

Co-authored-by: KooshaPari <koosha@example.com>
Co-authored-by: ForgeCode <noreply@forgecode.dev>
Co-authored-by: KooshaPari <koosha@example.com>
Co-authored-by: KooshaPari <koosha@example.com>
* fix(provider): retry transient OpenAI server errors

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

* fix(provider): preserve OpenAI stream error classification

Co-Authored-By: ForgeCode <noreply@forgecode.dev>

---------

Co-authored-by: KooshaPari <koosha@example.com>
Co-authored-by: ForgeCode <noreply@forgecode.dev>
Co-Authored-By: ForgeCode <noreply@forgecode.dev>
Copilot AI lite review requested due to automatic review settings August 14, 2026 00:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions github-actions Bot added type: fix Iterations on existing features or infrastructure. type: provider Updates provider.json configuration. labels Aug 14, 2026
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

KooshaPari and others added 2 commits August 13, 2026 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix Iterations on existing features or infrastructure. type: provider Updates provider.json configuration.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants