Skip to content

feat(gateway): land remaining durable-approvals stack and repair main gates#104837

Merged
steipete merged 3 commits into
mainfrom
codex/durable-approval-registry
Jul 12, 2026
Merged

feat(gateway): land remaining durable-approvals stack and repair main gates#104837
steipete merged 3 commits into
mainfrom
codex/durable-approval-registry

Conversation

@steipete

@steipete steipete commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Lands the remainder of the durable-approvals stack plus the main-CI gate repairs. #103912 (native clients), #103921 (ancestor propagation), and #103932 (fail-closed gates) were squash-merged into this branch; this PR carries them to main together with three gate repairs that fail on plain current main.

Why This Change Was Made

User Impact

Approvals raised by an agent in any channel can be reviewed and resolved from iPhone, Apple Watch, or Android with first-answer-wins semantics; sessions observe their approvals live with replay after reconnect; plugin-gated node commands deny instead of proceeding when their approval prompt cannot be rendered.

Evidence

  • tsgo core lane 0 errors, madge 0 cycles at this head; approval suites green locally (operator-approvals e2e first-answer-wins, session-events, node-invoke fail-closed 56/56, exec-approval-manager, approval methods 64/64).
  • Prior chain state validated on Blacksmith Testbox: build green with plugin-sdk declaration graph 5,014,292/5,050,000 bytes; tsgo core/test/extensions and import-cycles green (tbx_01kx9sjheam1zb2h5dg27dfhfj).
  • Gate repairs verified: agent-model-discovery 2/2, control-ui-i18n check clean, docs map regenerated.

@steipete
steipete requested a review from a team as a code owner July 12, 2026 00:49
@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime scripts Repository scripts size: XL maintainer Maintainer-authored PR labels Jul 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e9e7c377f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/gateway/server-methods/approval.ts Outdated
// Ambiguous verdicts consume the first-answer slot as a denial. Leaving
// the approval retryable would let a later surface release authority.
const forceMalformedDeny = !validParams || !kindMatches || !decisionAllowed;
const forceMalformedDeny = !validParams || !decisionAllowed;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Preserve v4 approval.resolve callers

When a still-supported v4 client sends the previous approval.resolve payload with the formerly required kind field, validateApprovalResolveParams now rejects it because the schema only allows id and decision; this line then treats that as forceMalformedDeny, permanently denying the pending approval instead of letting the user approve it. Since the protocol version/minimum were not bumped, existing paired clients generated from the prior schema can still connect but their approval buttons will fail closed until every client is upgraded; either keep accepting the old field during v4 or reject older protocol versions explicitly.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jul 12, 2026
@clawsweeper

clawsweeper Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Codex review: stale review; fresh review needed.

Summary
The latest durable ClawSweeper review was for head 94f7ad0dacb298eebb38d409ef3361d5f8b10d23, but the PR head is now 66db18f9ea8d19c20d10a0a438a6ce42ceb54d7d. Its old verdict and PR readiness labels are no longer current.

Next step
Run or wait for a fresh ClawSweeper review on the current PR head.

Review history (20 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-12T04:56:06.344Z sha 9611c2a :: needs real behavior proof before merge. :: [P1] Restore SQLite snapshot verification | [P2] Fail when the WAL checkpoint is busy
  • reviewed 2026-07-12T05:27:43.583Z sha 9ff4362 :: needs real behavior proof before merge. :: [P1] Restore SQLite snapshot verification | [P2] Fail when the WAL checkpoint is busy | [P1] Keep the agent database schema version monotonic | [P2] Serialize workspace compare-and-swap writes | [P1] Read terminal transcript freshness from SQLite | [P2] Honor structured context-overflow failures
  • reviewed 2026-07-12T05:52:14.768Z sha 58f366b :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-12T06:11:04.143Z sha b967905 :: needs real behavior proof before merge. :: [P2] Align approval stream auth with method dispatch
  • reviewed 2026-07-12T06:33:22.061Z sha df85f64 :: needs real behavior proof before merge. :: [P2] Align approval stream auth with method dispatch | [P1] Honor timeoutBehavior through the deprecation window
  • reviewed 2026-07-12T06:56:36.220Z sha 3b110a4 :: needs real behavior proof before merge. :: [P2] Align approval stream auth with method dispatch | [P1] Honor timeoutBehavior through the deprecation window | [P2] Pass canonical decisions to embedded approvals
  • reviewed 2026-07-12T08:29:28.631Z sha 9a2dbdc :: needs real behavior proof before merge. :: [P2] Align approval stream auth with method dispatch | [P1] Honor timeoutBehavior through the deprecation window | [P2] Pass canonical decisions to embedded approvals
  • reviewed 2026-07-12T09:14:15.366Z sha e155a0a :: needs real behavior proof before merge. :: [P1] Honor timeoutBehavior through the deprecation window | [P2] Pass canonical decisions to embedded approvals | [P2] Align approval stream auth with method dispatch

@steipete
steipete force-pushed the codex/durable-approval-registry branch from e9e7c37 to 2a40d95 Compare July 12, 2026 01:23
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jul 12, 2026
@openclaw-barnacle openclaw-barnacle Bot added the agents Agent runtime and tooling label Jul 12, 2026
@steipete
steipete force-pushed the codex/durable-approval-registry branch from d7c734e to daa4565 Compare July 12, 2026 02:16
@steipete steipete changed the title fix(gateway): approval registry hardening and protocol-surface follow-ups test(agents): keep model discovery hermetic from provider policy artifacts Jul 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed app: web-ui App: web-ui gateway Gateway runtime scripts Repository scripts labels Jul 12, 2026
@steipete steipete changed the title test(agents): keep model discovery hermetic from provider policy artifacts feat(gateway): land remaining durable-approvals stack and repair main gates Jul 12, 2026
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. and removed rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. labels Jul 12, 2026
@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Security-sensitive guard cleared

This PR no longer has blocked security-sensitive file changes. A future security-sensitive change requires a fresh /allow-security-sensitive-change comment after the guard blocks that new head SHA.

  • Current SHA: 66db18f9ea8d19c20d10a0a438a6ce42ceb54d7d

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9611c2a364

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/commands/backup-verify.ts Outdated
}

/** Verify a backup archive, including snapshot shape and canonical SQLite integrity checks. */
/** Verify a backup archive without extracting payload files to disk. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Restore SQLite snapshot verification

When a backup contains state or agent SQLite snapshots, this new non-extracting verifier returns ok after only manifest and hardlink checks; it never opens the *.sqlite payloads or runs integrity/role validation. A truncated or corrupt state/openclaw.sqlite that is present in the manifest now passes openclaw backup verify and therefore backup create --verify, leaving operators with a "verified" archive that may not restore OpenClaw state.

Useful? React with 👍 / 👎.

}

function checkpointTruncate(database: DatabaseSync): void {
database.exec("PRAGMA wal_checkpoint(TRUNCATE);");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Check WAL checkpoint busy result

When another OpenClaw process or reader still has the session DB open, PRAGMA wal_checkpoint(TRUNCATE) reports a nonzero busy result instead of throwing; this helper discards that row, so doctor --session-sqlite compact can report success while the WAL was not truncated and the DB was compacted under a live connection. Please read the checkpoint result and fail closed on busy != 0, as the previous shared compaction helper did.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac39e9e759

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/state/openclaw-agent-db.ts Outdated
// change is folded in structure-gated (migrateMemoryIndexSourcesIdentity), so
// v2 main DBs and pre-merge v4 flip DBs both converge on this schema.
export const OPENCLAW_AGENT_SCHEMA_VERSION = 6;
export const OPENCLAW_AGENT_SCHEMA_VERSION = 4;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Keep agent DB schema version monotonic

If a user has an agent database created by the immediately previous code (it wrote PRAGMA user_version = 6), lowering the supported version to 4 makes assertSupportedAgentSchemaVersion treat that DB as a future schema and refuse to open it. There is no migration/doctor path accepting v5/v6 here, so updating to this commit can strand existing agent state until the version is restored or the older shapes are explicitly handled.

Useful? React with 👍 / 👎.

});
return undefined;
}
await workspaceRoot.write(browserPath, content, { encoding: "utf8" });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Serialize CAS writes before saving workspace files

When two sessions.files.set requests for the same file and expectedHash arrive concurrently, both can pass the handler’s hash check before reaching this write, and then the later write overwrites the earlier one while both calls report success. The API and UI still present this as hash-based CAS/conflict detection, so the check and write need to be serialized (as the removed update queue did) or made atomic to avoid lost edits between two gateway clients.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9ff43627b1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/sessions/lifecycle.ts Outdated
Comment on lines +266 to +267
const sessionFile = resolveSessionFilePath(check.sessionId, params.entry, pathOptions);
const stats = fs.statSync(sessionFile);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Read terminal transcript freshness from SQLite

For SQLite-backed sessions, this now stats the legacy transcript file instead of reading the transcript rows, so a terminal main session whose SQLite transcript advanced after its registry row looks not-newer whenever the JSONL file is missing or stale. The callers in src/auto-reply/reply/session.ts, src/agents/command/session.ts, and src/gateway/server-methods/agent.ts treat false as permission to reuse the terminal main session, so new work can be admitted into a closed session instead of rotating or recovering; keep this gate on the SQLite transcript stats used before.

Useful? React with 👍 / 👎.

!isBilling &&
((isFailoverError(err) && err.reason === "context_overflow") ||
isLikelyContextOverflowError(message));
const isContextOverflow = !isBilling && isLikelyContextOverflowError(message);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Honor structured context-overflow failover

When a provider or CLI layer throws a structured FailoverError with reason: "context_overflow" but a generic message such as provider rejected the request payload, this line no longer classifies it as context overflow because it only string-matches the message. That skips the dedicated context-overflow recovery copy below and surfaces a generic pre-reply failure instead, even though the typed reason is the dependency contract used by FailoverError.

Useful? React with 👍 / 👎.

const isTransientHttp =
isTransientHttpError(message) ||
(isFailoverError(err) && (err.reason === "timeout" || err.reason === "server_error"));
const isTransientHttp = isTransientHttpError(message);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Keep retrying structured transient failovers

Structured FailoverError timeouts and server errors no longer reach the transient retry path unless their message happens to match isTransientHttpError. Several callers, for example the CLI watchdog errors in src/agents/cli-runner/execute.ts, throw reason: "timeout" with messages like CLI produced no output... that do not contain HTTP status tokens, so this skips the once-only retry block below and immediately fails recoverable turns.

Useful? React with 👍 / 👎.

Comment on lines 272 to 276
WatchHeroCard(
label: "Clear",
title: "No approvals waiting",
subtitle: self.store.lastExecApprovalOutcomeText ?? "You are caught up",
accessory: "Ready")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Don’t show clear state while approval details load

When the iPhone app snapshot reports pendingApprovalCount > 0 but the approval snapshot has not arrived yet, activeExecApproval is nil while approvalCount is still positive. This branch now renders the clear-state hero during loading or unavailable states, so a watch user can be told there is nothing to review even though the paired iPhone has already reported a pending approval; keep the previous loading/not-loaded branch for approvalCount > 0.

Useful? React with 👍 / 👎.

break
fi
done < <(git -C .candidate for-each-ref --format='%(refname)' 'refs/tags/v*')
done < <(git -C .candidate for-each-ref --format='%(refname)' refs/tags/v)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Match version tags during SHA provenance checks

In the exact-SHA path this now asks Git for the literal ref refs/tags/v, not the v* tag namespace; checked git for-each-ref behavior shows refs/tags/v only returns a tag named exactly v, while normal release tags such as v2026... require refs/tags/v*. A workflow dispatched with target_ref equal to the candidate SHA will therefore reject a SHA trusted only by its release tag, and the same replacement appears in the later revalidation step.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 58f366b05b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (!key) {
return;
}
if (p.includeApprovals === true && !canReviewOperatorApproval(client)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Align approval stream auth with method dispatch

When a paired approval client connects with only operator.approvals (the new handler test covers that exact scope set), this branch would accept includeApprovals, but live Gateway dispatch rejects the request before the handler because sessions.messages.subscribe is still registered as operator.read in src/gateway/methods/core-descriptors.ts:180. That makes approval-only clients unable to use the new session.approval replay/stream despite the handler and error text advertising approval-scope access; make the method dynamic/read+approvals-aware or require/read-test operator.read consistently.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b9679054ab

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (!approval) {
return undefined;
}
warnDeprecatedApprovalTimeoutBehavior(approval);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Honor timeoutBehavior through deprecation

When a shipped plugin still sets requireApproval.timeoutBehavior: "allow" and no reviewer answers before the approval times out, this path now only logs a deprecation warning; both approval wait paths then fall through to the timed_out blocked result. Since the field remains in the public PluginHookBeforeToolCallResult API and the docs deprecate rather than remove it, existing plugins that intentionally allowed low-risk tools during approval outages will start blocking until they are rewritten; keep honoring the field through the deprecation window or make the breaking fail-closed contract explicit.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df85f64d5b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const approval = params.approval;
const timeoutMs = resolvePluginToolApprovalTimeoutMs(approval);
const gatewayTimeoutMs = resolvePluginToolApprovalGatewayTimeoutMs(timeoutMs);
const allowedDecisions = resolveCanonicalPluginApprovalRequestAllowedDecisions(approval);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Pass canonical decisions to embedded approvals

When an embedded-mode plugin sets requireApproval.allowedDecisions without deny (for example ['allow-once']), this canonicalized set is only used to classify the result; the embedded broker request below still carries the original list. The embedded TUI renders its selector from request.allowedDecisions and its cancel path only denies when deny is present, so these prompts become allow-only/dismiss-only even though the new fail-closed contract and broker resolution logic treat deny as valid. Please send the canonical allowedDecisions into the embedded request as the gateway path does.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94f7ad0dac

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

true,
{
subscribed: true,
key: canonicalKey,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Preserve the agent scope in approval subscribe responses

When a global-scope session is subscribed through an agent-scoped key such as agent:work:main, this handler subscribes the connection to agent:work:global and replays approvals for that exact stream, but the response still tells the client the key is just global. A client that follows the returned key when later calling sessions.messages.unsubscribe will resolve global against the default agent and unsubscribe agent:main:global, leaving the agent:work:global approval subscription active until disconnect; this is newly sensitive with includeApprovals because it can keep delivering approval events after the UI believes it unsubscribed. Return the scoped subscription key (or enough agent metadata) for this response path so unsubscribe can target the same stream.

Useful? React with 👍 / 👎.

steipete added 3 commits July 12, 2026 05:36
Squash-rebased #103921 segment onto the native-clients tip on current main.
Session-scoped approval events publish sanitized pending/terminal
transitions to opted-in session audiences, with authoritative pending
replay on stream subscribe and durable-expiry reconciliation through the
owning manager. SessionApprovalEvent/Replay wire types export from the
approvals owner module; Swift models regenerated.

(cherry picked from commit 2d1dcf9747044710111d0c730fc46ba6013a165c)
(cherry picked from commit ccf88efd56b513d07599ffcee997bf0cddaf9adc)
(cherry picked from commit 8eb33f59f00ec9ee4625259b76bd7ae60d2cd480)
(cherry picked from commit c297cbc93c8401e9c79c20f242245a194f5dd236)
(cherry picked from commit 93d68f28601ff37d863da4db009504993a22533a)
(cherry picked from commit d285ccd8b2f212bb57e814107e7709c896e96b7d)
(cherry picked from commit 5c536982231402b1b58d1683794ea9948b32d077)
(cherry picked from commit 1646e5b6dc4dd20de54e10f110a5909be18d7d50)
(cherry picked from commit 35cf1b705b247fb282f4d56ffe74bd2fb238221f)
(cherry picked from commit 4f8ef36)
(cherry picked from commit 74fbdcc99d5fff062d67760a51dba4ee9e84479b)
(cherry picked from commit 222b285502681d2be14b1819798e9ee5555f431e)
(cherry picked from commit b9e744951f676b600e7c5322bfd04b0e99797c07)
(cherry picked from commit 9e904ef)
(cherry picked from commit 678f238)
(cherry picked from commit 72842e5)
(cherry picked from commit be74c25)
(cherry picked from commit 93ba8c4)
(cherry picked from commit 8f23761)
Squash-rebased #103932 segment onto the ancestor-propagation tip on
current main. Plugin node.invoke approvals claim a one-shot allow-once
decision before handing execution authority to the policy, so observation
or retry cannot replay a consumed approval; sibling tool gates bind
approval ids to their originating reviewer identity.

(cherry picked from commit 122df0d75281f572c012b6484ed5daf085d1d577)
(cherry picked from commit f23d8ac240a8dcf2a42c4daaae962263975a0ae8)
(cherry picked from commit 8632fb6436a224dac7a9a9ef0216884530de2c24)
(cherry picked from commit d9fe2dd5c53665e5732f5f3da5ed1907a686ade8)
(cherry picked from commit bb139f2c8aa36ddad70413e1ef79ff491a6f2ecd)
(cherry picked from commit 9b3e056b68ea515c7d4baef269289b6670570480)
(cherry picked from commit b11e66b59a7af1f3b08712de06864aed64d349e4)
(cherry picked from commit a12916ee592d03dfa35e86a2aaede4476a5d4e5d)
(cherry picked from commit d699de840fc8346892b9ae244fe3c3e8c4413032)
(cherry picked from commit 9b7e5a9)
(cherry picked from commit 4b507593f1b2f10b4496984c84a2803b853e5c5e)
(cherry picked from commit 56408a186733c4eeb5aa76bd5907cde7b0cd3d5b)
(cherry picked from commit a4051d6d8353d39d6fa0b5d69c36e06c3cd3e796)
(cherry picked from commit 7682980)
(cherry picked from commit a8b493f)
(cherry picked from commit aceb990)
(cherry picked from commit a29b0e7)
(cherry picked from commit 2e3be08)
(cherry picked from commit c9ae3d7)
- android: capture createdAtMs on the pending exec-approval write at
  registration; canonical readback after a refresh that already replaced
  the visible rows was dropping the approval instead of surfacing the
  still-pending reconciliation message (#104913 merged without this)
- android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest
- agents: hermetic model-discovery test via the plugins/provider-runtime
  boundary (lazy plugin-runtime resolution hangs vitest workers since #104770)
- cli: usage-cost settle-budget test asserts the budget bound on every call
  instead of pinning the poll count (fast hosts fit a second poll in 50ms)
- protocol coverage: allowlist session.approval for ios/android (native
  review rides exec.approval push/nudge delivery)
- docs map, native i18n inventory, plugin-sdk api baseline regenerated
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: android App: android app: web-ui App: web-ui cli CLI command changes docs Improvements or additions to documentation extensions: codex gateway Gateway runtime maintainer Maintainer-authored PR P1 High-priority user-facing bug, regression, or broken workflow. plugin: file-transfer scripts Repository scripts size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant