Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
c97e5bd
fix(db): enable TCP_NODELAY for SQLx connections
XuPeng-SH Oct 23, 2026
a83de29
perf(runtime): reduce synchronous turn persistence
XuPeng-SH Oct 23, 2026
383ee5d
perf(runtime): remove unused remote checkpoint index projection
XuPeng-SH Oct 23, 2026
9433da4
refactor(runtime): unify turn finalization and canonical settlement
XuPeng-SH Oct 23, 2026
7339bf5
refactor(inference): admit prepared requests in one transaction
XuPeng-SH Oct 23, 2026
2437a1d
perf(runtime): admit root turns in the run creation transaction
XuPeng-SH Oct 23, 2026
019b952
perf(runtime): reuse run authority for agent inference
XuPeng-SH Oct 23, 2026
94a3d6e
perf(services): batch admission partition repair and credit updates
XuPeng-SH Oct 23, 2026
572e9b4
perf(memory): finalize session memory from canonical context
XuPeng-SH Oct 23, 2026
cfb2adc
test(runtime): decouple behavior proofs from retired inference ledgers
XuPeng-SH Oct 23, 2026
a48a4b3
perf(runtime): simplify chat admission and observation persistence
XuPeng-SH Oct 23, 2026
aca09f5
perf(runtime): remove transcript projection and synchronous tool prog…
XuPeng-SH Oct 23, 2026
8a19d39
perf(runtime): remove duplicate chat diagnostics and input settlement…
XuPeng-SH Oct 23, 2026
f179dbe
perf(runtime): retire legacy prompt history and stored run display mi…
XuPeng-SH Oct 23, 2026
5a75fe5
fix(harness): report probe interruptions and test canonical chat
XuPeng-SH Oct 23, 2026
dec0d0d
perf(runtime): defer agent recovery and retire chat quota mirrors
XuPeng-SH Oct 24, 2026
a26eff7
refactor(runtime): checkpoint run-owned context migration
XuPeng-SH Oct 24, 2026
1f5b1b4
perf(runtime): bound chat SQL and retire execution slots
XuPeng-SH Oct 24, 2026
3542d11
refactor(runtime): retire unused inference WAL and history tools
XuPeng-SH Oct 24, 2026
01e6ab0
fix(models): bound selection cache and coalesce fills safely
XuPeng-SH Oct 24, 2026
4a461a9
refactor(runs): capture input independently of Context grants
XuPeng-SH Oct 24, 2026
d287ec8
fix(runtime): preserve the frozen MOI conflict contract
XuPeng-SH Oct 24, 2026
6da4994
perf(context): inline immutable payloads and bound session reads
XuPeng-SH Oct 24, 2026
b468740
docs(storage): document measured chat budget and remaining scans
XuPeng-SH Oct 24, 2026
7f91b87
fix(auth): bound retained cache allocation under churn
XuPeng-SH Oct 24, 2026
aa9d5e5
docs(models): clarify bounded execution admission freshness
XuPeng-SH Oct 24, 2026
c70c68b
test(harness): wait for complete lifecycle pid files
XuPeng-SH Oct 24, 2026
46a9372
fix(runtime): converge failed runs through canonical settlement
XuPeng-SH Oct 24, 2026
382e34f
fix(cli): preserve canonical failed run observations
XuPeng-SH Oct 24, 2026
bd8d3a5
fix(cli): preserve failed run facts and retire accounting polling
XuPeng-SH Oct 24, 2026
50f90b3
fix(harness): verify tool execution from canonical trace
XuPeng-SH Oct 24, 2026
200b410
fix(harness): prove replies without duplicate send mirrors
XuPeng-SH Oct 24, 2026
2fe2e4d
fix(runtime): preserve Work and trace ownership across turns
XuPeng-SH Oct 24, 2026
26d6a44
fix(web): recover opening-only runs through canonical streams
XuPeng-SH Oct 25, 2026
7928342
fix(web): recover accepted inputs from canonical run listings
XuPeng-SH Oct 25, 2026
7565e31
fix(runtime): bound selected-session conversation recovery
XuPeng-SH Oct 25, 2026
4fb538e
fix(web): preserve message ownership during chat recovery
XuPeng-SH Oct 25, 2026
471851f
fix(runtime): bound conversation reads and fence session updates
XuPeng-SH Oct 25, 2026
8fa9beb
test(web): cover metadata ABA and creation acknowledgements
XuPeng-SH Oct 25, 2026
060545b
test(harness): check observed cache reuse and canonical fanout comple…
XuPeng-SH Oct 25, 2026
b0144d1
fix(cli): make native collaborator capacity explicit
XuPeng-SH Oct 25, 2026
f11bfdf
fix(tools): preserve execution routing in compact schemas
XuPeng-SH Oct 25, 2026
87c4a58
fix(harness): align tool count diagnostics with budget checks
XuPeng-SH Oct 25, 2026
670f7ab
fix(harness): stream complete judgments and preserve action scope
XuPeng-SH Oct 25, 2026
0490393
fix(tools): diagnose the selected tagged schema variant
XuPeng-SH Oct 25, 2026
f188ac5
fix(orchestration): align child guidance with completion ownership
XuPeng-SH Oct 25, 2026
06d23a5
fix(orchestration): deliver complete child results within the shared …
XuPeng-SH Oct 25, 2026
417dcb4
test(orchestration): verify complete child output on the public stream
XuPeng-SH Oct 25, 2026
de99afe
fix(tools): clarify compact delegation contracts
XuPeng-SH Oct 25, 2026
7a1d0f5
refactor(tools): defer explicit runtime observation
XuPeng-SH Oct 25, 2026
10aecf6
test(runtime): select explicit observation contracts
XuPeng-SH Oct 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,15 @@ ASTRA_RUNTIME_ROOT_SECRET=your-runtime-root-secret-min-32-characters-change-me
# Provider admission scope/window/cleanup and run admission timeout are runtime
# policy, not deployment knobs.

# The built-in Work admission judge runs concurrently with each primary turn
# by default, then is awaited only at a durable/effectful boundary. This keeps
# tracked requests from silently becoming untracked tool calls without adding
# judge latency to the ordinary primary path. `capacity_aware` keeps this
# correctness boundary enabled while provider admission accounts for its
# quota; unrelated optional judges remain capacity-gated. Under Auto,
# The default `boundary_only` starts Work judgment at a typed effect/topology
# boundary that consumes its result. Ordinary chat skips optional user
# observation, skill auto-routing and proactive pre-turn LLM compaction;
# explicit skills and reactive context-pressure handling remain available.
# Opt into `capacity_aware` for capacity-gated optional auxiliary calls. Under Auto,
# `disabled` makes semantic admission unavailable and therefore fails closed;
# clients that deliberately omit classification must request FixedDefault.
# Use `always` to ignore capacity gating for all eligible auxiliary features.
#ASTRA_AUX_LLM_POLICY=capacity_aware
#ASTRA_AUX_LLM_POLICY=boundary_only

# ── Memoria (Memory Service) ──────────────────────────────────────────────
# Memoria provides persistent semantic memory (store/retrieve/search).
Expand Down Expand Up @@ -232,6 +231,8 @@ MEMORIA_EMBEDDING_BASE_URL=
# ── CLI Overrides (optional) ──────────────────────────────────────────────
# Override CLI defaults for local development. These only affect the `astra` CLI,
# not the API server.
# Native external agent runtimes are opt-in; ordinary Server-model turns skip them.
#ASTRA_NATIVE_COLLABORATORS=false # true requires native capacity readiness before chat
#ASTRA_CLI_USER_ID= # User ID for local task/session ownership metadata
#ASTRA_CLI_SESSION_ID= # Resume or pin the CLI to a specific session UUID
#ASTRA_CLI_SESSION_NAME= # Human-friendly session name when starting a new session
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/harness-manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,18 @@ jobs:
preflight["failure"] = {"model": failure["model"], "stage": stage}
code = failure.get("exit_code")
preflight["failure"]["exit_code"] = code if type(code) is int and -255 <= code <= 255 else None
state = failure.get("final_state")
state = state if (stage == "execution" and isinstance(state, str)
and state in ("completed", "interrupted", "failed")) else None
preflight["failure"]["final_state"] = state
kind = failure.get("interruption_kind")
preflight["failure"]["interruption_kind"] = kind if (state == "interrupted"
and isinstance(kind, str) and kind in (
"budget_exhausted", "empty_completion", "token_budget_exceeded",
"rate_limited", "cooldown_rejected", "user_cancelled", "context_overflow",
"auth_failure", "critical_verdict", "approval_rejected", "server_overload",
"stream_transport", "stream_idle", "provider_deadline", "harness_blocked",
"harness_paused", "interrupted", "execution_incomplete", "executor_dropped")) else None
for key in ("error_kind", "error_code"):
value = failure.get(key)
preflight["failure"][key] = value if (isinstance(value, str) and 0 < len(value) <= 128
Expand Down
4 changes: 0 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,6 @@ contract and its tests live in [`scripts/ci/`](scripts/ci/).
The frozen MOI consumer compatibility test runs independently of this routing
on every Test Suite run. The required online core aggregate also requires that
fresh-database journey to pass; see the testing guide for its exact scope.
The Terminal-Bench fresh-database contract derives admission gate names and
cardinality from the source-owned partition count and scope formatter. It
requires the exact ordered gate inventory; missing, duplicate, legacy or
unknown rows and unsupported source declarations fail closed.

CLI tests build and run all library/binary unit tests plus the offline
`cli_pipe`, `process_supervisor`, `shell_execution_boundaries`, and
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,6 @@ strip = "symbols"
# Local startup-query prototype; see vendor/crossterm/ASTRA-PATCH.md.
[patch.crates-io]
crossterm = { path = "vendor/crossterm" }
# Restore TCP_NODELAY omitted by SQLx 0.9.0. Remove this pin when a release
# contains https://github.com/launchbadge/sqlx/pull/4336.
sqlx-core = { git = "https://github.com/launchbadge/sqlx", rev = "6e57d05490859f31aa364ca69fcb379f3a2995e6" }
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,7 @@ mod tests {
#[test]
fn server_loop_admission_excludes_client_owned_conversation_authority() {
let prepared = json!({
"conversation_authority": {"execution_grant": "client-owned-capability"},
"completion_checks": {
"stop": [{"label": "root", "command": "make check", "working_dir": null,
"depends_on": [], "timeout_secs": null, "authoritative": true}],
Expand Down
8 changes: 7 additions & 1 deletion crates/astra-cli/src/cli/chat_stream/sse_loop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ async fn stream_chat_sse_inner(
callback_client_detached: false,
remote_cancel_run_id: None,
last_physical_run_id: None,
failed_run_terminal: None,
turn_evaluation: None,
last_error_code: None,
last_error_metadata: None,
Expand Down Expand Up @@ -881,7 +882,10 @@ async fn stream_chat_sse_inner(
qualified_usage: state.qualified_usage,
usage_attribution,
tool_calls_count,
llm_rounds: Some(state.llm_rounds_completed),
llm_rounds: state
.remote_summary
.as_ref()
.map(|summary| summary.llm_rounds),
token_usage_coverage: state.token_usage_coverage(),
tool_outcomes: Some(tool_outcomes),
applied_user_intents: state
Expand Down Expand Up @@ -911,6 +915,8 @@ async fn stream_chat_sse_inner(
server_admission_not_dispatched: false,
last_heavy_checkpoint: state.stall.last_heavy_checkpoint.take(),
partial_text: std::mem::take(&mut state.final_text),
partial_text_model_item_id: state.final_text_model_item_id.take(),
failed_run_terminal: host.failed_run_terminal.take(),
run_transcript_messages: state.take_run_transcript_capture(),
remote_cancel_required: host.remote_cancel_required,
callback_client_detached: host.callback_client_detached,
Expand Down
14 changes: 10 additions & 4 deletions crates/astra-cli/src/cli/chat_stream/sse_loop/remote_turn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ impl RemoteTurnState {
session_id,
self.session_turn.max(1),
checkpoint,
None,
) {
self.stall.last_heavy_checkpoint = Some(checkpoint);
}
Expand Down Expand Up @@ -390,7 +389,8 @@ pub(super) async fn consume_remote_turn(
} else {
if let Err(error) = &result {
state.step_recorder.end_turn(false);
if state.interruption.is_none()
if host.failed_run_terminal.is_none()
&& state.interruption.is_none()
&& error.kind != astra_core::ErrorKind::Cancelled
&& let Some((kind, action)) =
astra_turn_core::interruption::interruption_from_error_kind(error.kind)
Expand Down Expand Up @@ -588,8 +588,15 @@ async fn consume_remote_turn_inner(
consecutive_context_window_errors: &mut state.consecutive_context_window_errors,
},
);
state.qualified_usage = turn.core.accounted_usage();
if turn.core.has_authoritative_failed_terminal()
&& !host.remote_cancel_required
&& !host.callback_client_detached
&& host.output_transport_failure.is_none()
{
host.failed_run_terminal = turn.core.run_terminal.take();
}
state.capture_appended_messages(start);
state.qualified_usage = turn.core.qualified_usage;
state.llm_rounds_completed = turn
.core
.server_execution_summary
Expand Down Expand Up @@ -702,7 +709,6 @@ async fn finalize_remote_trace(state: &mut RemoteTurnState) {
first_budget_pressure: &mut state.telemetry.first_budget_pressure,
pending_context_assembly_trace: &mut state.telemetry.pending_context_assembly_trace,
observability_session: state.telemetry.observability_session.clone(),
persistence: None,
})
.await;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ pub(crate) struct CliServerAdmissionHost<'a> {
/// Latest immutable physical SSE owner, retained through final-output
/// delivery and durable cancellation.
pub last_physical_run_id: Option<String>,
pub failed_run_terminal: Option<astra_turn_core::chat_turn_sse_dispatch::DurableRunTerminal>,
pub turn_evaluation: Option<astra_services::session_journal::JournalEvent>,
/// Structured admission failure metadata retained after the accumulator is
/// moved into the shared loop. These facts drive user-facing recovery and
Expand Down Expand Up @@ -1203,7 +1204,9 @@ impl CliServerAdmissionHost<'_> {
.extend(turn_result.core.explain_analyze_events.iter().cloned());
state.telemetry.explain_analyze_degraded |= turn_result.core.explain_analyze_degraded;

if turn_result.core.server_loop_terminal {
if turn_result.core.server_loop_terminal
|| turn_result.core.has_authoritative_failed_terminal()
{
// Server-owned runs execute their tools remotely, so the thin
// client has no local ToolCallRecord ledger to re-evaluate at the
// final boundary. Receipt closure is the terminal integrity fact;
Expand Down
2 changes: 1 addition & 1 deletion crates/astra-cli/src/cli/cli_config/cli_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,7 @@ pub(crate) enum SessionCmd {

#[derive(Args, Debug)]
pub(crate) struct SessionJudgeArgs {
/// JudgmentRequest JSON with shared evidence and typed questions (no agent task)
/// JudgmentRequest JSON with shared evidence and typed questions; use - to read stdin
#[arg(short, long)]
pub message: String,
/// Active Server model selector
Expand Down
Loading
Loading