Commit Graph

13 Commits

Author SHA1 Message Date
firat.sertgoz
9ac7b476cd [codex] Add hosted single-tenant Postgres profile (#5081)
* Add hosted single-tenant Postgres profile

* Persist hosted extension state under tenant storage

* fix(reborn): bound filesystem event tail reads

* fix(reborn): reduce hosted postgres read amplification

* fix(reborn): batch filesystem thread history reads

* fix(filesystem): avoid postgres prefix scans

* fix(reborn): harden hosted postgres bootstrap

* fix(webui): advance empty projection cursors

* fix(reborn): batch llm secret metadata reads

* perf(webui): back off idle stream polling

* perf(turns): cache fresh filesystem snapshots for reads

* fix(reborn): authorize extension lifecycle catalog mounts

* fix(reborn): time out wedged turn drivers

* fix(reborn): bound stuck heartbeat calls

* refactor: split postgres PR hot path helpers

* reborn: address hosted postgres review feedback

* turns: move test module after production items

* reborn: fix hosted postgres review feedback

* reborn: fix projection ci regressions

* tests: relax reborn harness heartbeat

* tests: widen reborn harness heartbeat

* ci: harden cargo network fetches

* reborn: fix hosted runtime gate diagnostic

* tests: wait for budget gate materialization

* reborn: fix hosted postgres review and ci issues

* reborn: tighten hosted postgres review fixes

* reborn: keep nearai bootstrap outcome local

* reborn: clarify hosted local-runtime seams

* fix(reborn): address CodeRabbit review feedback (#5081)

* test(reborn): stabilize runtime no-gateway failure check

* fix(ci): update test secret metadata expiry plumbing

* fix(threads): make postgres message acceptance atomic

* fix(filesystem): retry postgres migration connect

* fix(reborn): lower default postgres pool size

* fix(reborn): allow postgres pool cap override

* fix(filesystem): extend postgres startup retry window

* fix(railway): disable reborn deployment overlap

* fix(reborn): serve startup health before postgres runtime

* fix(reborn): harden startup and inbound accept paths

* fix(ci): restore reborn bootstrap build

* fix(ci): stabilize reborn harness heartbeat

* fix(reborn): collapse repeated auto-approve lookups

* fix(reborn): suppress noisy debug logs in hosted serve

* fix(reborn): raise hosted-single-tenant postgres pool to 16

The hosted profile shared a single deadpool across every Postgres-backed
subsystem (turns, threads, messages, events, secrets), and every filesystem
op checks out a connection. With pool_max_size=2 a single turn's reads plus
an open transaction monopolize both connections, so the runner heartbeat and
webui block indefinitely on pool.get() (no get() timeout), the 90s lease
expires, and the turn wedges with failure_category=lease_expired.

The cap was lowered to fit a managed session-pool limit during blue-green
deploy overlap; that overlap is resolved, so restore a healthy pool (16, the
prior default). Runtime override via IRONCLAW_REBORN_POSTGRES_POOL_MAX_SIZE
is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* perf(reborn): cache prepared statements + bound postgres pool checkout

Two latency/deadlock fixes for the Postgres-backed root filesystem, which
backs every Reborn subsystem (turns, threads, messages, events, secrets) and
checks out a pooled connection per op.

Caching: every fixed-SQL read/write went through `client.query_opt(sql, ..)`
with a string, so tokio_postgres issued a fresh `Parse` (prepare) on every
call — ~2.77ms RTT to remote Postgres measured from production logs, ~48% of
each read, and a monotonically growing set of server-side prepared statements
(s1625, s1626, ... never reused). Route the deadpool `Object` (not the
deref'd `Client`) through new `cached_query_opt`/`cached_query`/
`cached_query_one`/`cached_execute` helpers that use deadpool's per-connection
`prepare_cached`. The Parse round-trip is now paid once per connection per
distinct statement; the pooled connection is held for ~half as long per op,
which is what relieves the pool contention behind the lease-expiry wedge.
Dynamic SQL (filter `query`, index DDL, create_dir_all's txn) stays uncached
to keep the cache bounded. Helpers return `tokio_postgres::Error` so existing
`db_error` mapping at call sites is unchanged.

Deadlock guard: the pool was built with no checkout timeout, so `Pool::get()`
blocks forever once all connections are busy — an unbounded wait wedges the
runner heartbeat and webui until the 90s lease expires. Add 30s
wait/create/recycle timeouts (well under the lease) so a saturated pool
surfaces a retryable error instead of hanging the process.

Verified: `cargo clippy` clean and `cargo check` pass for ironclaw_filesystem,
ironclaw_reborn_event_store, and ironclaw_reborn_composition with
postgres[,webui-v2-beta]. Live Postgres behavior + latency delta verified via
PR CI and Railway (no local live-pg test / Docker).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(reborn): size hosted postgres pool for the Supabase pooler (10)

The reference hosted deployment fronts Postgres with the Supabase Supavisor
session pooler (default pool size ~15), so the shared app pool must stay under
that cap. 16 could exceed it; 10 covers runtime concurrency (heartbeat, webui,
trigger poller, turn driver reads + open txn) with headroom for migrations and
admin sessions. Runtime override IRONCLAW_REBORN_POSTGRES_POOL_MAX_SIZE still
wins over this file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 02:07:11 +03:00
Josh Ford
041a465dcc Document Reborn serve/WebUI testing flow + add run-reborn-webui.sh launcher (#4652)
* Document Reborn serve/WebUI testing flow in reborn-binary.md

The doc still listed "web gateway/UI startup" under "does not yet
support", but `serve` now starts the WebChat v2 web UI (behind
`--features webui-v2-beta`). It also omitted several shipped commands and
gave no provider-agnostic setup path for testers.

- Correct the stale "does not yet support" claim; note serve's WebUI is a
  feature-gated beta surface.
- Add a "Running with the WebUI (serve)" walkthrough: provider-neutral
  quick start, the required IRONCLAW_REBORN_WEBUI_* auth env vars, the /v2
  UI path, a table of common startup errors (missing token/user-id,
  identity-owner mismatch, workspace/skill-root overlap) with fixes, and a
  curl API smoke test.
- Add a "Choose your model provider" table (NEAR AI, OpenAI, Anthropic,
  Ollama) with each provider's set-provider id, key env var, and default
  model, plus how to discover any provider's env var via `models status`
  (default.api_key_env) and `models list --verbose`.
- Document the workspace-root-overlap gotcha: serve/run/repl use the cwd
  as the workspace root, so IRONCLAW_REBORN_HOME must live outside it.
- Add command sections for onboard, repl, serve, and models set-provider;
  correct the models status field list to match actual output; list the
  new commands (and the contributor-only traces tree) in current status.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Clarify local-dev skill-root paths in overlap gotcha

Address review feedback on the workspace-overlap note. The overlap
validation guards the flat/default storage roots (/skills ->
<reborn-home>/local-dev/skills, /tenant-shared/skills, /system/skills,
/system/extensions), which is what the error message names. Make that
precise, and add that resolved per-user skills actually live under the
tenant-scoped path (<reborn-home>/local-dev/tenants/default/users/<owner>/skills),
into which the legacy flat root is backfilled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Address review: required-key startup failure, shell-safe quick start

Incorporate Codex and Copilot review feedback on reborn-binary.md:

- Required-key providers (openai/anthropic, api_key_required=true) fail at
  startup during LLM resolution when the key env var is missing
  ("llm provider '<id>' requires API key env var '<VAR>'"), not "later at
  turn time". Document this; keyless providers (ollama) and NEAR AI's
  session flow (api_key_required=false) boot without the key. (Codex P2)
- Replace shell-breaking <provider>/<PROVIDER_API_KEY> placeholders in the
  quick-start block with a concrete nearai example; unquoted angle brackets
  are parsed as redirections and break copy/paste. (Codex P3)
- Note set-provider writes no api_key_env for keyless providers like ollama,
  in both the provider table intro and the command section. (Copilot)
- Clarify that the home-outside-cwd rule is specific to serve/run/repl,
  which use the cwd as the local-dev workspace root. (Copilot)
- Note the WEBUI auth var NAMES are defaults, overridable via
  [webui].env_token_var / env_user_id_var. (Copilot)
- Note models status field names are the text output; --json nests under
  default with raw struct fields (provider_id, not provider). (Copilot)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add scripts/run-reborn-webui.sh launcher

A one-command wrapper around the serve/WebUI quick start that handles the
setup footguns documented in reborn-binary.md:

- keeps IRONCLAW_REBORN_HOME outside the repo and refuses an in-repo home
  (which would trip the workspace/skill-root overlap validation);
- runs `models set-provider` for the chosen provider (PROVIDER/MODEL env);
- discovers the credential env var via `models status` and warns if unset;
- generates the WebUI bearer token and matches the WebUI user to the
  identity owner so serve doesn't refuse to start;
- prints the login token + /v2 URL, then execs serve.

PROVIDER/MODEL/HOST/PORT/IRONCLAW_REBORN_HOME are overridable. Referenced
from the "Running with the WebUI (serve)" section as the shortcut path.

Verified end to end: the script configures the route, binds the WebChat v2
listener on 127.0.0.1:3000, and /v2 + /api/health respond.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Reject PORT=0 in run-reborn-webui.sh launcher

The launcher prints a login URL for a browser, so a kernel-assigned port
(PORT=0) produces an unusable http://HOST:0/v2. Reject PORT=0 early with a
clear message pointing at the raw `serve --port 0` test-harness form,
rather than advertising an onboarding URL that can't be opened.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Address review: onboard flag, port-0 config, status base_url

Second Copilot review pass on reborn-binary.md:

- Add `onboard --import-history` to the current-status command list; it is
  a real flag (onboard.rs) documented later but omitted up top.
- Clarify that `--port 0` (ephemeral) is the CLI flag only; serve rejects
  `[webui].listen_port = 0` from config (serve.rs).
- Add `default.base_url` to the `models status` text field list; it is
  printed conditionally when the route configures a base URL (models.rs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Address review: derive WebUI owner from config, clarify async timeline

- run-reborn-webui.sh now reads [identity].default_owner from the home's
  config.toml (after set-provider seeds it) and uses it for the WebUI user,
  falling back to reborn-cli. Previously it only defaulted to reborn-cli, so
  a home with a custom owner would still hit the owner-mismatch error the
  header comment claimed to prevent. Comment reworded to match. (Copilot)
- Smoke-test snippet: clarify the single timeline GET is not a loop — turn
  execution is async, so re-run until an assistant message reaches
  status "finalized". (Copilot)

The third comment (${!key_env:-} tripping set -u) was a false positive:
verified on bash 3.2 that the :- form returns empty for an unset referenced
var and does not abort; only the form without :- aborts. Code unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Address review: HOST/zsh collision, path canonicalization, doc clarifications

Incorporate Firat and Copilot review feedback.

run-reborn-webui.sh:
- Rename HOST/PORT -> REBORN_HOST/REBORN_PORT. A bare HOST collides with
  zsh's auto-set $HOST (machine hostname); a zsh user without an explicit
  HOST would bind serve to a non-loopback interface and expose the bearer
  token over plain HTTP. (Firat, Security/Medium)
- Canonicalize the home and repo root (resolve `..`/symlinks via the parent
  dir's `pwd -P`) before the overlap prefix check, so a valid sibling home
  like `../reborn-home` is no longer falsely rejected. (Copilot)
- Escape the literal dot in the sed key-env extraction. (Firat, Bug/Low)

docs/reborn-binary.md:
- Annotate `onboard --import-history` in the status command list as parsed
  but not-yet-wired, and note `serve` is only compiled with the feature.
  (Firat, Conventions/Low)
- State explicitly that the `serve` subcommand is compiled behind
  `--features webui-v2-beta` and is absent from `--help` without it
  (verified: #[cfg(feature = "webui-v2-beta")] on the Serve variant). (Copilot)
- Update launcher override vars to REBORN_HOST/REBORN_PORT.

Verified: launcher binds on a custom REBORN_PORT, overlap guard accepts
`../reborn-home` and rejects in-repo homes, REBORN_PORT=0 rejected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 01:35:12 +03:00
Robert Yan
0ff90518e2 Make Reborn production runtime launchable (#4645)
* Wire Reborn production Postgres storage config

* Fix Reborn production secret master key config

* Make Reborn production runtime launchable

* fix(reborn): fail closed when production hooks are enabled

* style(reborn): tidy production hooks regression test attributes

* fix(reborn): address production runtime review feedback

* fix(reborn): update runtime test harness wiring

* test(reborn): align production hook fixture with sandbox policy

---------

Co-authored-by: serrrfirat <f@nuff.tech>
2026-06-10 01:27:08 +03:00
firat.sertgoz
5e31a5afbe Seed Reborn config.toml on first runtime start (#4517)
* feat(reborn): seed first-run config toml

* fix(reborn): tighten first-run config seeding

* fix(reborn): keep first-run seed profile safe

* fix(reborn): address henrypark133 review - seed repl config (#4517)
2026-06-08 11:05:20 +03:00
firat.sertgoz
0017805e84 Add Reborn extension lifecycle CLI (#4099) 2026-05-27 04:13:47 +03:00
firat.sertgoz
d2d43ee2a6 Wire Reborn CLI skills list (#4095)
* Wire Reborn CLI skills list

* fix: address reborn skills review findings
2026-05-27 03:47:24 +03:00
firat.sertgoz
10663d7cc0 Add local-dev trusted host access audit
Add durable audit coverage for local-dev trusted laptop access and resolve review feedback for PR #4007.
2026-05-26 00:16:53 +03:00
serrrfirat
01be65f2df feat(reborn): route binary repl through planned agent loop 2026-05-17 00:19:59 +02:00
Henry Park
c9995bf3e1 arch(ws-17): prove product live planned-runtime cutover (#3653)
* arch(ws-17): prove product live planned-runtime cutover

Squash of #3653 (8 commits) onto reborn-integration stack.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* arch(ws-17): address PR review (debug log, cancel-path proof, fail-closed gates)

Resolve reviewer feedback on #3653:

- zmanian: add `debug!` on the default `is_product_cancellation_observed`
  Ok(false) so on-call has a breadcrumb when a factory is not product-live.
- zmanian: replace remaining `.unwrap()` with typed `.expect("planned
  default profile resolver")` in WS-14/WS-16/WS-17 reborn tests.
- serrrfirat #1: remove the manual `request_product_cancellation`
  backdoor from the product-live cancellation proof. Wire a
  `CompositeTurnRunWakeNotifier` in `build_default_planned_runtime` so
  `coordinator.cancel_run` fans out to both the worker wake channel and
  `RunCancellationFactory::notify_run_wake`. The cancellation contract
  test now drives observation purely from `cancel_run` and polls until
  the retained run handle flips.
- henrypark133 #1-3: extend the product-live readiness gate with
  fail-closed checks for `ModelPolicyGuard`, `ModelBudgetAccountant`,
  and `SafetyContext`. Adds matching `DefaultPlannedRuntimeParts`
  fields, three new `ProductLiveRuntimeReadinessComponent` variants,
  builder wiring on `RebornLoopDriverHostFactory`, and three new
  regression tests asserting each missing component is rejected.

Item #4 (`production_readiness` gate invocation from a startup entry
point) and serrrfirat #2 (tool-use canary) remain deferred per the
PR description — both are part of the composition-root flip, which
zmanian's review tagged for a separate PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* arch(ws-17): tidy review nits (typed probe error, probe lifetime doc, test helpers)

- runtime: re-type ProductLiveRuntimeBuildError::Probe.reason
  String -> source: AgentLoopHostError. Strongly-typed per
  .claude/rules/types.md, carries kind + diagnostic_ref, and Error::source
  now returns the underlying probe failure for chain inspectors.
- cancellation_port: doc-comment RunCancellationFactory::notify_run_wake
  with the sync/non-blocking contract that CompositeTurnRunWakeNotifier
  relies on; doc-comment ProductLiveCancellationProbe with the
  ephemeral-handle contract.
- inbound_turn_contract / loop_driver_host tests: make the test
  ReadyRunCancellationProbe own its RunCancellationHandle directly
  (was leaking one entry into the factory handles map on every
  readiness verify); add local turn_state_store_dyn() and
  test_safety_context() helpers and route the duplicated cast +
  InstructionSafetyContext::new("policy:test", ...) call sites
  through them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 20:57:05 -07:00
firat.sertgoz
70e394deda feat(reborn-cli): add inspection command surfaces (#3528)
* feat(reborn-cli): add inspection command surfaces

* fix(reborn-cli): align inspection output helpers
2026-05-13 13:44:36 +03:00
firat.sertgoz
c8f68ce83b feat(reborn-cli): add config path command (#3518) 2026-05-12 14:33:04 +03:00
serrrfirat
8d86d22b4b Add Reborn CLI completion command 2026-05-11 18:24:14 +02:00
serrrfirat
0a7fed00b1 docs(reborn): document standalone binary release status 2026-05-11 18:06:02 +02:00