Skip to content

feat(forge_main,forge_domain,forge_api,forge_app,forge_tracker): graceful provider model fetch#3691

Open
KooshaPari wants to merge 121 commits into
tailcallhq:mainfrom
KooshaPari:fix/models-graceful-provider-failure
Open

feat(forge_main,forge_domain,forge_api,forge_app,forge_tracker): graceful provider model fetch#3691
KooshaPari wants to merge 121 commits into
tailcallhq:mainfrom
KooshaPari:fix/models-graceful-provider-failure

Conversation

@KooshaPari

Copy link
Copy Markdown

Summary

Previously, a single broken provider (auth failure, network error, malformed response) would abort /model enumeration and lock the user out of switching models on healthy providers. This change introduces partial-success semantics so that:

  • Successful providers continue to surface their models.
  • Failed providers are reported inline with their per-provider error message.
  • The aggregated ProviderModelsResult carries both halves so the UI can render /models with warnings instead of aborting.

Files touched

  • forge_domain/src/provider.rs — adds ProviderFetchError + ProviderModelsResult
  • forge_api/src/api.rs — threads the aggregated result through
  • forge_api/src/forge_api.rs — small type adjustment
  • forge_app/src/app.rs — collects per-provider failures
  • forge_main/src/ui.rs — renders partial-failure warnings
  • forge_main/src/update.rs — propagates through state machine
  • forge_tracker/src/log.rs — structured log for failed fetches

Test plan

  • Local build succeeds
  • Cargo clippy clean

KooshaPari and others added 30 commits May 1, 2026 20:06
- Bootstrap deny.toml with license allowlist + advisory ignores
- Add license = MIT to workspace.package (was missing)
- Add license.workspace = true to all 27 crate manifests
- Ignore transitive unmaintained (bincode, yaml-rust, paste, rustls-pemfile)
- Ignore transitive vulns (hickory-proto, rustls-webpki) via aws-sdk/reqwest

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Phenotype Agent <agent@phenotype.ai>
Pin all action refs to immutable SHAs across workflow files:
- checkout@v4 → @11bd71901bbe5b1630ceea73d27597364c9af683
- checkout@v6 → @de0fac2e4500dabe0009e67214ff5f5447ce83dd
- setup-node@v4/v5, setup-python@v4/v5, setup-go@v5
- upload-artifact@v4/v7, download-artifact@v4
- cache@v3/v4, github-script@v7
- configure-pages@v5/v6, deploy-pages@v4/v5
- upload-pages-artifact@v3/v5, dependency-review-action@v4

Fixes version-tag normalization (add v4/v5 tags where missing).
Fixes double-SHA corruption artifacts from prior patching rounds.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Reduce README from 1124 to 169 lines (-85%).
Keep: project name, description, quickstart, usage examples, why forge,
installation, community, documentation link.
Add fork disclaimer pointing to upstream tailcallhq/forgecode.
Preserve all upstream content via pointer comment.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Reduce README from 1124 to 169 lines (-85%).
Keep: project name, description, quickstart, usage examples, why forge,
installation, community, documentation link.
Add fork disclaimer pointing to upstream tailcallhq/forgecode.
Preserve all upstream content via pointer comment.

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Phenotype Agent <agent@phenotype.ai>
Verified resolved upstream; advisory no longer triggers.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…nale

- Add 4 ignore entries for bincode 1.x (RUSTSEC-2025-0141), paste
  (2024-0436), rustls-pemfile (2025-0134), yaml-rust (2024-0320) — all
  transitive via upstream forgecode workspace deps; resolution depends on
  upstream tailcallhq/forgecode bumps.
- Pre-existing fork-specific RUSTSEC-2026-* ignores preserved.
- cargo deny check advisories: PASS.
…nale (#8)

- Add 4 ignore entries for bincode 1.x (RUSTSEC-2025-0141), paste
  (2024-0436), rustls-pemfile (2025-0134), yaml-rust (2024-0320) — all
  transitive via upstream forgecode workspace deps; resolution depends on
  upstream tailcallhq/forgecode bumps.
- Pre-existing fork-specific RUSTSEC-2026-* ignores preserved.
- cargo deny check advisories: PASS.

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
Root cause: crossterm's cursor position CSI query times out (2s) when
multiple concurrent sessions are running or terminal is under load.

Fix:
- Add error::is_cursor_timeout_error() to detect cursor position errors
- Add terminal::get_cursor_position_with_retry() with backoff
- Suppress cursor errors during shutdown in Ui::shutdown()
- Add comprehensive tests for cursor error detection

Fixes session crashes where user sees:
  'cursor position could not be read within a normal duration'
  'Resource temporarily unavailable (os error 35)'

Tested: 337 tests pass (333 existing + 4 new cursor error tests)
Add summarization feature with:
- llm_summarizer: Async LLM-based summarization service
- adaptive_eviction: Importance-based eviction strategies
- metrics: Summarization metrics tracking
- prefilter: Pre-summarization filtering
- Updated compaction config and strategy

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…p-go

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Restore the workspace members array by listing all crate directories
present on disk, removing invalid glob patterns.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add [bans] section with recommended warnings
- Update GitHub workflow files (trufflehog, stale, labels, release)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
KooshaPari and others added 27 commits June 29, 2026 17:16
…#68)

PolicyEngine previously returned Permission::Confirm (prompt user) when no
policies were configured or no rule matched an operation. This is a
default-allow posture: any unconfigured operation could proceed after a
single user confirmation, with no explicit allowlist required.

forge_tracker previously enabled PostHog telemetry by default (opt-out via
FORGE_TRACKER=false) and transmitted raw CLI args and Prompt event content
(user-supplied text) in every telemetry event.

Changes (Phenotype-org security hardening, audit issue #58):
- PolicyEngine: return Permission::Deny (not Confirm) when the policy list is
  empty or when no rule matches the requested operation. An explicit allowlist
  is now required to permit any operation.
- tracking_enabled(): invert default from opt-out to opt-in. FORGE_TRACKER
  must be explicitly set to 'true' to enable telemetry; absent or any other
  value disables it.
- redact_event_value(): replace Prompt and Error event content with
  '<redacted>' before any collector.collect() call so user-typed text and
  stack traces are never sent to PostHog.
- redact_args(): replace positional CLI arg values with '<redacted>' at cache
  time; flag names (--foo) are kept for diagnostics but inline =values are
  stripped.

Regression tests added in both crates (failing-first verified manually):
- test_policy_engine_default_deny_when_no_policies
- test_policy_engine_default_deny_when_no_rule_matches
- test_tracking_disabled_by_default_when_env_absent
- test_tracking_enabled_only_when_explicitly_true
- test_prompt_event_value_is_redacted
- test_error_event_value_is_redacted
- test_non_sensitive_event_value_is_not_redacted
- test_redact_args_replaces_positional_values
- test_redact_args_keeps_flag_names_strips_inline_values

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
Conv-list used SELECT * loading multi-MB context blobs for all
2585 convos. Lite metadata-only query + lazy context load.

- ConversationSummary domain struct (metadata only, no context blob)
- ConversationRecordLite Diesel struct with .select() on (id,title,
  created_at,updated_at,message_count,cwd,parent_id,workspace_id)
- get_parent_conversations_lite() on all layers (repo→service→API)
- ConversationSelector::select_conversation now returns ConversationId
  (callers lazy-load full Conversation only on open)
- Users of get_parent_conversations() for list views switched to lite

See docs/sessions/20260629-forgedev-ram/RAM_INVESTIGATION.md

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
Co-authored-by: forge-dev <forge-dev@phenotype.ai>
Add comprehensive packaging specification for KooshaPari/forgecode fork.
Covers Cargo binary rename (forge -> forge-dev), config directory rename
(~/.forge -> ~/.forge-dev), shell plugin updates, per-OS installer
formats (macOS .app, Windows MSI, Linux AppImage), universal CLI install
script, side-by-side collision validation, and a 12-PR implementation plan.

This is a spec-only PR with no code changes.

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
…uency to Daily (#74)

Profiling across 3 regimes showed the update-informer GitHub API call
(update_informer::new(registry::GitHub, ...).check_version()) is synchronous
and blocks every forge invocation for ~220ms when UpdateFrequency=Always
(the previous default).

Measured impact:
  forge info normal:           ~300ms
  forge info (Never/agent):     ~72ms
  M=32 parallel (with update): wall 1049ms -> throughput ~30 agents/s plateau
  M=64 parallel (with update): wall 2094ms -> throughput ~30 agents/s (flat)

Two fixes:
1. Default UpdateFrequency from `Always` (0s interval = network on every run)
   to `Daily` (86400s interval; update_informer caches result, subsequent runs
   pay 0ms). Interactive users still get update prompts, just once per day.
2. is_non_interactive() guard in on_update(): skip the check entirely when
   stdin is not a TTY or CI/FORGE_NON_INTERACTIVE/FORGE_AGENT_MODE env vars
   are set. Agent fleets spawn hundreds of short-lived forge processes; the
   ~220ms per-spawn network tax is pure waste in that context.

Remaining per-invocation cost breakdown (no update check):
  dyld + tokio + jemalloc init: ~47ms (irreducible without daemon pooling)
  SQLite pool open + PRAGMA:     ~5-25ms
  Total non-LLM startup:         ~72ms

Regime 3 scaling plateau root cause (separate from update check):
  M=32: each forge proc spawns ~18 OS threads (tokio rt-multi-thread default)
  At M=32: 576 total OS threads -> macOS scheduler contention
  Throughput peaks at ~30-35 agents/s then falls super-linearly.
  Fix is a long-running daemon/pool pattern (future work; see Zig plan below).

Zig hot-path candidates (not implemented this pass — ranked by impact):
  1. Daemon socket: single forge process accepting tasks over Unix socket
     eliminates the ~47ms dyld+tokio-init overhead for all but the first
     spawn. Zig `posix_spawn` + kqueue IPC dispatcher is the right layer.
  2. Spawn pool: pre-fork N forge workers, assign tasks via lock-free SPSC
     ring. Zig std.os.linux.io_uring or kqueue on macOS. This is the
     density multiplier — removes the 576-thread storm at M=32.
  3. WAL checkpointer (already in Rust in checkpoint.rs) — stays Rust.
     SQLite open at M=32 costs only 53ms wall (scales fine); not the limit.

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
…ilcallhq#2532) (#75)

jemalloc on macOS ARM64 triggers upstream bug tailcallhq#2532: HPA probes every 4KB
page, causing 14s cold init vs 25ms baseline (20x regression, measured PR#74).

- Workspace Cargo.toml: move tikv-jemallocator to Linux-only; add mimalloc
- forge_main/Cargo.toml: platform-conditional allocator deps
- main.rs: cfg-gated #[global_allocator] (jemalloc on Linux, mimalloc on macOS)

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

~13,053 conversations with is_compressed=0 left ~2.9GB of plain JSON context
on disk. New idempotent maintenance command compresses them in-place without
modifying titles, timestamps, or any queryable columns.

- ConversationRepository trait: add compress_uncompressed_contexts()
- ConversationRepositoryImpl: raw SQL batch read + per-row zstd encode +
  UPDATE context_zstd / clear context / set is_compressed=1
- Wired through forge_repo -> forge_services -> forge_app -> forge_api
- CLI: 'forge maintenance compress' subcommand with spinner + row counts
- 2 unit tests: basic round-trip and idempotency

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

Adds the forge-daemon density lever (forgecode#74 root cause: dyld+tokio init
~47ms×M + thread storm 18 OS threads×M = 576 threads at M=32).

Architecture (Zig core + Rust orchestration, per feedback_zig_for_lowlevel):
- forge-daemon/: Zig 0.16 project → two artifacts:
    libforge_daemon_core.a (C-ABI staticlib, consumed by Rust build.rs)
    forge-daemon binary (standalone Unix-socket daemon)
  Modules: kqueue_loop.zig (macOS kqueue, no EV_SET macro, std.c-based),
           socket.zig (Unix SOCK_STREAM, u32-LE length-prefix protocol),
           worker.zig (posix_spawn pool, nanosleep shutdown),
           ring.zig (lock-free SPSC task ring, RING_CAP=256),
           protocol.zig (JSON request/response parse),
           lib.zig (C-ABI exports: forge_daemon_start/stop/is_running/
                    socket_path/dispatch),
           main.zig (kqueue event loop, env-var config, multi-client)

- crates/forge_daemon/: Rust orchestration (build.rs invokes zig build,
  links libforge_daemon_core.a).  Exposes:
    DaemonDispatch::dispatch() — in-process C-ABI hot path (no socket)
    DaemonClient — async Unix-socket client (run/ping/shutdown)
    DaemonGuard — spawn/manage the standalone daemon binary

- benchmarks/forge_daemon_bench/: M=8/16/32 daemon vs fork+exec benchmark.

REAL BENCHMARK RESULTS (M=8/16/32, iters=5, /usr/bin/true, aarch64 macOS):
  M=8:  fork+exec 3.1ms  2581 a/s → daemon 0.5ms  14904 a/s  5.77× faster
  M=16: fork+exec 5.4ms  2952 a/s → daemon 1.1ms  14763 a/s  5.00× faster
  M=32: fork+exec 9.2ms  3461 a/s → daemon 1.9ms  16497 a/s  4.77× faster

The ~5× speedup is measured on process-launch overhead only (true binary, no
LLM wait). Real forge workloads carry an additional ~47ms dyld+tokio init per
spawn that the daemon eliminates entirely (measured in #74).  The in-process
DaemonDispatch path using posix_spawn via C-ABI also avoids tokio thread-storm
(daemon uses one kqueue thread vs 18 OS threads per forge invocation).

Tests: 2 Rust tests (daemon_not_running_initially, daemon_start_stop_lifecycle)
       + 1 Zig test (ring submit/consume round-trip) — all green.

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
Adds forge_repo_map crate — a tree-sitter-based module that walks a
repository, parses source files with tree-sitter, and builds a compact
symbol/structure map (files -> top-level functions, types, imports) that
an agent can use as repo context.

Supports Rust, TypeScript, JavaScript, Python, Go with tree-sitter
grammars. gitignore-aware file walking via ignore crate. Builder API
with max_files cap, configurable cwd, and stable text output format.

Adds 19 tests covering:
- Language detection (6 langs, fallback)
- Rust: function, struct, enum, trait, type alias, impl, use import, unsafe
- TypeScript: function, interface, class, type alias, enum, import
- Python: function, class, import
- Go: function, struct, interface, method, type alias, import
- Builder: file discovery, gitignore respect, max_files, stable ordering,
  unsupported extension filtering, empty directory, text output format

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

Adds benchmarks/perf_harness which spawns forge (or a long-running placeholder)
under three regimes (warmup=1, sustained=8, burst=32) and captures peak RSS,
idle CPU, and proc stats into docs/perf/baseline-2026-07-02.json.  macOS path
uses /bin/ps; Linux path uses /proc/<pid>/{status,stat,fd}.

Also fixes a pre-existing compile break in crates/forge_main/src/ui.rs:1044
where spinner.stop() was called with 0 args but the API takes Option<String>.
This blocks building forge_main on toolchain 1.95, so the harness can't
measure anything until it lands.

Scorecard (commit 6f8f80a, macOS aarch64, tokio 10 workers):
  warmup   workers= 1  forge_cold=9760 KiB  mean_cpu=0.70%  dur=406ms
  sustained workers= 8  mean_rss=1120 KiB   mean_cpu=0.19%  dur=549ms
  burst    workers=32  mean_rss=1121 KiB   mean_cpu=0.59%  dur=582ms

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
- forgecode: deleted 4 stale feat/* local branches (merged or >30 days old)
- forgecode: pruned 40 stale remote-tracking refs via git remote prune origin
- KooshaPari/phenodag: closed 2 stale PRs (#16, #17) — 8 days old, CI failing or blocked by branch protection

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
…only impl (#79)

* feat(repo-map): tree-sitter repository structure map

Adds forge_repo_map crate — a tree-sitter-based module that walks a
repository, parses source files with tree-sitter, and builds a compact
symbol/structure map (files -> top-level functions, types, imports) that
an agent can use as repo context.

Supports Rust, TypeScript, JavaScript, Python, Go with tree-sitter
grammars. gitignore-aware file walking via ignore crate. Builder API
with max_files cap, configurable cwd, and stable text output format.

Adds 19 tests covering:
- Language detection (6 langs, fallback)
- Rust: function, struct, enum, trait, type alias, impl, use import, unsafe
- TypeScript: function, interface, class, type alias, enum, import
- Python: function, class, import
- Go: function, struct, interface, method, type alias, import
- Builder: file discovery, gitignore respect, max_files, stable ordering,
  unsupported extension filtering, empty directory, text output format

* test(dispatch): add ENV_LOCK mutex for parallel test isolation

feat(forge3d): add clap + tracing-subscriber workspace deps

* chore(sbom): add CycloneDX SBOM artifacts + session docs

* feat(forge3d,similarity): forge3d CLI entry + hash-only similarity impl

---------

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
Co-authored-by: Phenotype Agent <agent@phenotype.ai>
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 Bot <forgecode-bot@users.noreply.github.com>
Co-authored-by: ForgeCode <noreply@forgecode.dev>
…ommands (T57) (#82)

- Add version = env!("CARGO_PKG_VERSION") to #[command(...)].
- Add long_about describing the full daemon startup sequence (pidfile
  acquisition, drift detector init, JSON-RPC socket bind), the
  already-running delegate-ping behaviour, and graceful shutdown.
- Expand field doc comments: drift_dir notes writable-directory
  requirement; socket_path explains stale-socket cleanup; pidfile_dir
  describes flock semantics; forge3_client clarifies both the
  daemon-running and daemon-not-running paths.

Co-authored-by: KooshaPari <koosha@example.com>
* chore(deps): update rust crate config to v0.15.25 (tailcallhq#3574)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @ai-sdk/google-vertex to v5.0.1 (tailcallhq#3575)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency ai to v7.0.3 (tailcallhq#3576)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update rust crate posthog-rs to v0.14.2 (tailcallhq#3577)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @ai-sdk/google-vertex to v5.0.2 (tailcallhq#3578)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency ai to v7.0.4 (tailcallhq#3579)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update rust crate open to v5.3.6 (tailcallhq#3587)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update rust crate indicatif to v0.18.5 (tailcallhq#3589)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update rust crate posthog-rs to 0.15.0 (tailcallhq#3590)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @ai-sdk/google-vertex to v5.0.3 (tailcallhq#3593)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency ai to v7.0.6 (tailcallhq#3594)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @ai-sdk/google-vertex to v5.0.4 (tailcallhq#3601)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency ai to v7.0.8 (tailcallhq#3597)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update rust crate posthog-rs to v0.15.1 (tailcallhq#3602)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore:  Claude Sonnet 5 to all providers (tailcallhq#3604)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* chore(deps): update dependency @ai-sdk/google-vertex to v5.0.5 (tailcallhq#3605)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency ai to v7.0.9 (tailcallhq#3606)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update rust crate clap_complete to v4.6.6 (tailcallhq#3607)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix: Neuralwatt provider (tailcallhq#3608)

* chore(deps): update rust crate console to v0.16.4 (tailcallhq#3609)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @ai-sdk/google-vertex to v5.0.7 (tailcallhq#3612)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency ai to v7.0.11 (tailcallhq#3613)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @ai-sdk/google-vertex to v5.0.8 (tailcallhq#3617)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update rust crate clap_complete to v4.6.7 (tailcallhq#3618)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update rust crate ignore to v0.4.27 (tailcallhq#3610)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update rust crate indicatif to v0.18.6 (tailcallhq#3619)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update rust crate rand to v0.10.2 (tailcallhq#3621)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update rust crate posthog-rs to 0.17.0 (tailcallhq#3620)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency csv-parse to v7.0.1 (tailcallhq#3625)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency tsx to v4.22.5 (tailcallhq#3626)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @ai-sdk/google-vertex to v5.0.10 (tailcallhq#3627)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency ai to v7.0.14 (tailcallhq#3628)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(sync): regenerate Cargo.lock after upstream merge (resolves cleanly)

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Amit Singh <amitksingh1490@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: KooshaPari <koosha@example.com>
Replace the old gh-workflows-generated release.yml (forge binary, manual release trigger)
with a cargo-dist-style pipeline that:
- Triggers on tag push (v*)
- Builds forge-dev binary for mac/linux/windows (5 targets)
- Generates install.sh with cross-platform detection
- Creates GitHub Release with binaries + installers

Adds 'Install forge-dev' section to README with one-line curl install command.

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

Phenotype-org addition (not present in upstream tailcallhq/forgecode).

- New assets/brand/forgecode-icon.svg (1024x1024, hand-authored Terminal-Forge mark)
  Palette: deep-charcoal #0e0e10, deep-charcoal-2 #1c1c1f, amber-crt #f5a623,
  synthwave-magenta #d946a8, mint-prompt #6ee7b7. Stylized terminal window
  with traffic-light dots, amber-CRT 'F>' prompt, magenta spark glow (the AI
  hint), mint echo line. Subtle CRT scanlines for retro feel.
- Rendered iconset: assets/icons/forgecode.iconset/ — 12 PNGs covering
  Apple's required sizes (16/32/48/64/128/256/512/1024 + @2x variants for
  16/32/128/256). Sourced from the SVG via rsvg-convert.
- Windows .ico (assets/icons/forgecode.ico) — multi-res 16/32/48/64/128/256
  packed via ImageMagick 'convert'.
- Linux 256x256.png (assets/icons/forgecode-256x256.png) — standalone.
- Wire [package.metadata.bundle] in crates/forge_main/Cargo.toml pointing
  at the iconset (consumed by tauri/icns bundlers). Marked as
  Phenotype-org addition per fork CLAUDE.md.
- assets/brand/README.md documents palette, family position (distinct from
  Tracera/MelosViz/Backbone-2/Lab-Coat), and regen snippet.
- crates/forge_main/tests/iconset.rs — 11 integration cases covering file
  presence, palette cohesion, viewBox 1024, Apple sizes + @2x variants,
  .ico magic bytes, bundle metadata block, AND palette-isolation
  assertion (no Backbone-2 / Tracera / Lab-Coat hex leaks). 11/11 pass.

No AI footer. GPG opt-out.

Refs: visual-identity L96 (forgecode 7/36 -> ~17/36)
      Terminal-Forge palette proposed 2026-07-06 (vision-pillar)
      fork-conformant per Phenotype Org Cross-Project Reuse Protocol

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
Phase 3 visual polish — surface the brand icon at the top of README.md
so the canonical visual identity is the first thing renderers see.

- substrate: assets/brand/substrate-icon.svg (Backbone-2 golden icon set
  shipped via PR tailcallhq#221)
- forgecode: assets/brand/forgecode-icon.svg (Terminal-Forge golden icon
  set shipped via PR #87)

Additive only — existing prose preserved. No code, no tokens.css edits.

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
- Add <repo>-icon-animated.svg (SMIL, no JS, 3.5-5s seamless loop)
- Append Motion variant section to brand README
- Static icon unchanged
- Companion to L96 static golden icon set

vision-pillar L101 (Tier-3 polish)

Co-authored-by: Phenotype Agent <agent@phenotype.ai>
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>
…eful provider model fetch

Previously, a single broken provider (auth failure, network error, malformed
response) would abort `/model` enumeration and lock the user out of
switching models on healthy providers. This change introduces partial-success
semantics so that:

  * Successful providers continue to surface their models.
  * Failed providers are reported inline with their per-provider error
    message (e.g. "provider X is down, here is why").
  * The aggregated `ProviderModelsResult` carries both halves so the UI
    can render `/models` with warnings instead of aborting.

Files touched:
  * forge_domain/src/provider.rs   — adds ProviderFetchError + ProviderModelsResult
  * forge_api/src/api.rs           — threads the aggregated result through
  * forge_api/src/forge_api.rs     — small type adjustment
  * forge_app/src/app.rs           — collects per-provider failures
  * forge_main/src/ui.rs           — renders partial-failure warnings
  * forge_main/src/update.rs       — propagates through state machine
  * forge_tracker/src/log.rs       — structured log for failed fetches

WIP preserved from local development.
@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.

@github-actions github-actions Bot added type: feature Brand new functionality, features, pages, workflows, endpoints, etc. type: provider Updates provider.json configuration. labels Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feature Brand new functionality, features, pages, workflows, endpoints, etc. type: provider Updates provider.json configuration.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants