Skip to content

feat(agent): show readiness and capabilities before delegation - #2957

Open
BradGroux wants to merge 6 commits into
block:mainfrom
BradGroux:agent/agent-capability-readiness
Open

feat(agent): show readiness and capabilities before delegation#2957
BradGroux wants to merge 6 commits into
block:mainfrom
BradGroux:agent/agent-capability-readiness

Conversation

@BradGroux

@BradGroux BradGroux commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Closes #2931.

What this fixes

Buzz currently makes an owner infer whether an agent is ready for local delegation by cross-referencing the agent editor, managed-runtime state, presence, and ACP observer logs. Missing evidence can look like unsupported behavior, while requested and effective permission modes are not visible together.

The important pre-delegation questions should be answerable in one place: is this local process healthy, which runtime and model are active, which features and tools were actually reported, how risky are those tools, and is the evidence from the current process and session?

What changes

The owner-only Runtime tab now includes a readiness and capability manifest built from four existing evidence sources:

  • the ACP runtime catalog for installation, authentication, adapter, and static runtime facts;
  • managed lifecycle state for the current process and community connection;
  • current presence;
  • the encrypted owner observer stream for ACP initialize, session configuration, commands, tools, model, protocol, and permission evidence.

The card shows:

  • installation, authentication, process, community, presence, and observer readiness;
  • runtime, version, ACP protocol, requested model, applied model, and provider;
  • prompt and output features with explicit reported, unavailable, or unknown states;
  • runtime commands, MCP source names, tool descriptors, and tool risk classes;
  • requested and effective permission modes, their evidence source, and any divergence;
  • the newest evidence time, process-scoped freshness, and known runtime limitations.

The reducer treats absent or malformed evidence as unknown. Evidence is retained independently of the capped raw transcript, but it is invalidated across process and session boundaries. A stopped process, failed lifecycle, offline presence, closed observer, or initialize event from an older process cannot produce a ready state.

Trust boundary

This is local owner evidence, not a public capability, safety, or reputation claim. The UI says “Ready locally” and identifies the owner-and-machine scope.

The harness projects only MCP server names and permission semantics. It does not forward MCP commands, arguments, environment values, credentials, executable paths, raw lifecycle errors, or config values.

Desktop parsing is strict and bounded. Older Desktop backends that do not report the new static fields remain compatible and render those facts as unknown. A non-owner E2E regression test verifies that neither the Runtime tab nor the manifest is exposed.

Verification

  • The three commits were rebased without content changes onto current main at 6da45ac5cf90fa0768a98256e2200708d219ddfc; git range-diff reports all three commits as patch-equivalent. The current PR head is ccd194bbc9c54608fba18faaafcf00ab75038393.
  • bin/just ci at the current head passed workspace Rust formatting and Clippy, Desktop/web static checks and builds, the repository Rust unit suites, 3,739 Desktop tests, and 1,815 Tauri tests plus 3 mixer diagnostics. The gate then reached 861 passing mobile tests with one skipped and stopped on keeps follow mode off while a tall newest message stays visible. That same focused test fails identically on clean current main at 6da45ac5cf90fa0768a98256e2200708d219ddfc; this PR does not change mobile files.
  • The prior full just ci run passed at 08de676d34ba47ad872b55599ba74308094ce5f5, including workspace Rust formatting and Clippy, full Rust package tests, 3,739 Desktop tests, 1,818 Tauri tests and diagnostics, web build, and 824 mobile tests.
  • cargo test -p buzz-acp passed 628 tests.
  • Focused owner and non-owner Playwright coverage passed 2 tests against the E2E build.
  • Desktop typecheck, production build, E2E build, Tauri checks, and file-size ratchets passed.
  • The rendered local-readiness card was inspected and updated screenshots are posted on this PR.

Non-goals

  • No public or portable capability attestation.
  • No observation receipt, capability digest, or shareable claim envelope.
  • No third-party reputation or protocol integration.
  • No arbitrary wall-clock TTL; freshness is bound to the current healthy process, observer connection, session, presence, and community evidence.
  • No automatic delegation or permission-policy change.
  • No storage of secrets, full runtime configuration, or raw observer payloads.

@BradGroux
BradGroux requested a review from a team as a code owner July 26, 2026 07:02
BradGroux added a commit to BradGroux/buzz that referenced this pull request Jul 26, 2026
@BradGroux

BradGroux commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

Updated screenshots

Readiness and runtime evidence

The owner can see the six readiness gates alongside runtime, ACP protocol, requested model, applied model, provider evidence, and the explicit local-only trust boundary.

Readiness and runtime evidence

Capabilities, permissions, and tools

Reported, unavailable, and unknown states remain distinct. Requested and effective permission modes are shown with their evidence source, followed by commands, MCP source names, and tool risk classes.

Capabilities, permissions, and tools

Complete manifest

The full card uses “Ready locally” and states that the evidence is for this owner and machine, not a public safety or reputation claim.

Complete agent capability manifest

@BradGroux

Copy link
Copy Markdown
Contributor Author

Feedback review and current-main refresh

The external feedback was posted on the linked issue, #2931, rather than in a PR review thread. I rechecked the suggestion against the issue scope and the current implementation.

The central point was valid: local runtime readiness must not be presented as a portable safety, reputation, or third-party delegation claim. The existing branch already incorporates the supported parts:

  • The card says “Ready locally” and scopes the evidence to this owner, machine, running process, observer connection, community, and ACP session.
  • Requested and effective permission modes are separate, with the policy source identified.
  • Model evidence distinguishes requested, applied, reported, and configured state.
  • Missing evidence remains unknown rather than being treated as unsupported or safe.
  • MCP output is limited to redacted source names and explicit runtime-provided descriptors; commands, arguments, environment values, credentials, prompts, paths, and tool content are excluded.

I did not add runtime_observation_id, capability_set_digest, a portable claim_scope, or an arbitrary wall-clock freshness window. Those require a separately specified authenticated receipt contract with issuer, verifier, expiry, and replay semantics. Adding the labels here would imply portability that this owner-local evidence does not have. The detailed original disposition remains in the issue follow-up.

I have now refreshed this PR onto current main:

  • New head: ccd194bbc9c54608fba18faaafcf00ab75038393
  • Current base: 6da45ac5cf90fa0768a98256e2200708d219ddfc
  • git range-diff reports all three rebased commits as patch-equivalent; there are no new feature-code changes.

bin/just ci at the new head passed workspace Rust formatting and Clippy, Desktop/web checks and builds, the repository Rust unit suites, 3,739 Desktop tests, and 1,815 Tauri tests plus 3 mixer diagnostics. The mobile suite reached 861 passing tests with one skipped and stopped on keeps follow mode off while a tall newest message stays visible. The same focused test fails identically on clean current main at 6da45ac5cf90fa0768a98256e2200708d219ddfc, and this PR changes no mobile files.

The refreshed head is mergeable. GitHub checks are running again against the new commit.

@BradGroux BradGroux changed the title Show agent readiness and capabilities before delegation feat(agent): show readiness and capabilities before delegation Jul 29, 2026
@BradGroux
BradGroux force-pushed the agent/agent-capability-readiness branch from ccd194b to 3173cf4 Compare July 30, 2026 14:37
@BradGroux

Copy link
Copy Markdown
Contributor Author

Rebased this branch onto current block/buzz main at c55e421a0 and adapted it to current repository limits.

Head moved from ccd194bbc to 3173cf4dd. The agent contributor rules retain the newly landed shared-agent access rule and place this PR's evidence-only capability-manifest rule after it. The runtime capability fields were also split into focused Rust and TypeScript modules so the branch satisfies the current base-tree file-size ratchet without weakening that gate; the serialized IPC keys remain unchanged.

Verification:

  • Full buzz-acp suite passed: 643 library tests and 9 pool tests.
  • Strict Clippy passed for buzz-acp with all targets and warnings denied.
  • Tauri compile check passed.
  • Tauri tests passed: 1,878 library tests plus 3 mixer diagnostics; 14 keychain/relay-dependent tests remained explicitly ignored.
  • Strict Tauri Clippy passed with all targets and warnings denied.
  • Desktop Biome, file-size, text-size, and pubkey-truncation checks passed.
  • The full Desktop test suite, TypeScript typecheck, and production Vite build passed on the final rebased branch.
  • git diff --check, DCO trailer checks, and the direct merge-base audit passed.

GitHub checks are rerunning on the new head.

@BradGroux

Copy link
Copy Markdown
Contributor Author

Current-main refresh and permission-boundary follow-up

I reviewed the new enforcement-boundary feedback on linked issue #2931 and refreshed this branch onto current main.

The architecture decision is that AcpClient::handle_permission_request is Buzz's narrow generic cooperative seam, not a universal enforcement or containment boundary. This PR therefore remains scoped to readiness and evidence display; it does not add attestation or policy-enforcement code. The detailed boundary response is on the linked issue.

Rebase update:

  • Current head: 278151c48ca17c908c1123a1d57c18122c1b727f
  • Current base: b1b283cd4c7f926e12eeee8ae1f38c7471922b16
  • Current main moved preset runtime capability defaults into a separate module. The refreshed branch restores the missing default capability facts to preset runtime entries so the readiness manifest retains the expected evidence after the rebase.
  • GitHub reports the refreshed head mergeable and waiting on required review.

Verification on the refreshed head:

  • Desktop: 3,903 tests, typecheck, and production build passed.
  • buzz-acp: 664 library tests and 9 pool-lifecycle tests passed.
  • Tauri: 2,048 library tests plus 3 mixer diagnostics passed.
  • Affected formatting, Clippy, compile-check, typecheck, and build gates passed.
  • just ci passed every earlier stage before the unchanged mobile suite failed on ChannelDetailPage keeps follow mode off while a tall newest message stays visible. A full mobile retry reproduced the failure, and this PR has no mobile diff.
  • DCO, Semgrep OSS, and zizmor are green on the live head.

The remaining limitation is unchanged: any future policy at session/request_permission would govern only cooperative operations that cross that request. Direct runtime filesystem, subprocess, network, and MCP paths remain outside that guarantee.

@BradGroux
BradGroux force-pushed the agent/agent-capability-readiness branch from 278151c to 0a79898 Compare August 4, 2026 20:36
@BradGroux

Copy link
Copy Markdown
Contributor Author

Rebased onto block/buzz main at ce3cf3cd2591f132f286fbc0a42a9e6699d0b08d and re-audited the linked-issue feedback, current capability-policy work, and the branch's local trust boundary.

The feedback remains partially valid: local runtime readiness must not be presented as portable attestation, third-party reputation, or a universal permission-enforcement boundary. This branch already applies that constraint. The UI says “Ready locally,” scopes evidence to this owner, machine, process, observer connection, community, and ACP session, keeps missing evidence unknown, and separates requested from effective permission state. I did not add portable digests, observation receipts, arbitrary expiry semantics, or policy enforcement because those require a separately specified authenticated contract. #4066, #4540, and #4333 cover adjacent permission, onboarding, and Guardian policy work; none supplies this owner-local evidence surface. The PR therefore remains valid and was not closed.

The rebase required manual integration in managed-runtime types, the profile Runtime tab, and the Tauri API boundary. It preserves the newer config-diff, model-tuning, trading-card, media, and runtime-catalog fields already on main, including token, context-limit, and round-limit metadata. The capability facts remain in focused modules so the current file-size ratchet stays intact.

Exact-head verification on 0a798985a2cebb1e7efc1e319b7dd7b121eb2291:

  • Full buzz-acp suite passed with the ambient lazy-pool override removed: 671 library tests and 9 pool-lifecycle tests, 0 failures.
  • Root Rust formatting passed, and strict buzz-acp Clippy passed with all targets, all features, and warnings denied.
  • Desktop policy/static checks, the full JavaScript suite, typecheck, production build, and E2E build passed.
  • Focused owner and non-owner Playwright coverage passed: 2 tests, including verification that the manifest is not exposed to a non-owner.
  • Tauri formatting and cargo check passed.
  • Full Tauri suite passed: 2,205 library tests plus 3 mixer diagnostics, 0 failures; 13 library tests and the native latency gate remained explicitly ignored.
  • Strict Tauri Clippy passed with all targets and warnings denied.
  • git diff --check, conflict-marker scan, merge-base audit, and required DCO trailers passed.

The remaining boundary is deliberate: cooperative ACP permission requests are observable evidence, not proof that direct runtime filesystem, subprocess, network, or MCP paths are contained. This PR does not automate delegation or change permission policy.

@BradGroux
BradGroux force-pushed the agent/agent-capability-readiness branch from 0a79898 to 8fc6962 Compare August 5, 2026 22:26
@BradGroux

Copy link
Copy Markdown
Contributor Author

Review and rebase summary

Reviewed the PR for accuracy against current block/buzz main at d42d60d64 and rebased the branch onto that commit. This rebase required manual conflict resolution — the previous head was CONFLICTING with main.

What this PR does

Adds a capability readiness manifest to the agent profile panel: an owner-only "Runtime" tab that surfaces six readiness gates (community, observer, runtime catalog, ACP protocol, model, permissions) alongside the runtime's tool sources, permission mode, and model application status. The manifest is populated from three evidence streams: the static runtime catalog, lifecycle observer events, and session_config_captured observer frames. A capabilityManifest field is added to the session_config_captured observation, carrying a safe projection of model application, tool sources, and permission mode — no MCP commands, arguments, env vars, paths, or credentials enter it.

Accuracy review

  • The build_session_config_observation function correctly distinguishes requested vs. effective permission mode, including the buzzHarness fallback (perToolAutoDecision) when no runtime mode was applied. This is honest about what the harness actually does rather than claiming the runtime's built-in mode is known.
  • The apply_model_switch and apply_permission_mode functions now return Result<bool, AcpError> instead of Result<(), AcpError>, so session_config_captured can report whether the model switch actually applied vs. silently falling back. Transport errors remain fatal; application errors return false.
  • The set_observer_session_id method attaches the session ID immediately after session/new so later model/mode calls cannot be mistaken for evidence from a prior session.
  • The desktop AcpRuntimeCatalogEntry type now carries AcpRuntimeCapabilityFacts (via #[serde(flatten)]) with supports_acp_native_config, supports_acp_model_switching, and mcp_hooks. The refactor into runtime_catalog.rs and tauriAcpRuntimeCatalog.ts keeps the file under the 1000-line limit.
  • The E2E test verifies the owner sees the manifest and a non-owner does not get the "Runtime" tab.
  • No unwrap() or expect() in production paths. No new dependencies.

Conflict resolution

Seven files conflicted during rebase. The main-line changes that caused conflicts were:

  1. pool.rsmain changed the permission-mode comment from "auto-approves via handle_permission_request" to "rejects interactive permission requests." The PR's let permission_mode_applied = if ... pattern and build_session_config_observation function were preserved; the comment was updated to match main's wording.
  2. types.rs, discovery.rs, agent_discovery.rs, presets.rsmain added a max_parallelism field to AcpRuntimeCatalogEntry. The PR's refactor moved the struct to runtime_catalog.rs and used AcpRuntimeCapabilityFacts for the capability fields. Resolution: kept the PR's module split, added max_parallelism to the moved struct, and used capabilities: runtime.into() / capabilities: Default::default() at construction sites alongside max_parallelism.
  3. tauri.ts, types.ts — same split: the RawAcpRuntimeCatalogEntry type and fromRawAcpRuntimeCatalogEntry function were moved to tauriAcpRuntimeCatalog.ts; max_parallelism was added to both the raw type and the mapping function. The AcpRuntimeCatalogEntry TS type now intersects AcpRuntimeCapabilityFacts and carries maxParallelism.

Rebase result

Head moved from 0a798985a to 8fc6962ae. Five commits, all cleanly rebased. The PR is now MERGEABLE (previously CONFLICTING).

CI

DCO passes. Semgrep OSS and zizmor were pending at the time of this comment.

@BradGroux
BradGroux force-pushed the agent/agent-capability-readiness branch from 8fc6962 to db61837 Compare August 7, 2026 21:03
@BradGroux

Copy link
Copy Markdown
Contributor Author

Rebase and accuracy review (2026-08-07)

Rebased onto current main (2b873cf20). Conflict resolved — 52 commits applied, 1 file conflicted.

Branch state: db61837d6 (was 8fc6962ae) Mergeable: ✅ MERGEABLE · BLOCKED (branch protection — awaiting maintainer review)

Conflict resolution

desktop/src/features/agents/AGENTS.md — main added the owner-only-access build capability paragraph (item 11), while the branch added a new item 12 for capability manifest evidence semantics. Resolution: kept both items in order — main's item 11 (owner-only-access) followed by the branch's item 12 (capability manifests project evidence). No content lost.

During the rebase, the second and third commits in the series also had minor AGENTS.md conflicts in the test-enforcement section. These were resolved by taking the branch version (adding the new test entries for capabilityManifest.test.mjs and AgentCapabilityManifestCard.render.test.mjs).

Accuracy review

The PR adds a capability/readiness manifest system that projects KnownAcpRuntime facts, managed-agent lifecycle, presence, and the encrypted owner observer stream into an owner-facing UI. The evidence model is sound: missing fields are unknown, explicit false is unavailable, and only a supplied fact is reported. Manifest projection is allowlist-only — no raw config, commands, env vars, or credentials are surfaced.

The 5-commit series is well-structured: initial feature, evidence hardening, catalog checks, file-limit refactor, and a final preset fix. Tests cover evidence semantics, staleness, permission divergence, safe tool projection, and observation ordering. No unwrap()/expect() in production paths. No new dependencies.

Scope is broad (21 files, ~3100 insertions) but cohesive — the module split into tauriAcpRuntimeCatalog.ts and the runtime_catalog.rs refactor are clean.

@wolfyy970

Copy link
Copy Markdown

I think this should be the agent-session half of #5060. The local evidence boundary is right: a Project connection being healthy does not prove it was applied to this agent.

Rather than build another readiness surface, I would join the existing pieces here:

The missing seam is a non-secret binding identity and generation in the launch observation. That would let the UI distinguish Configured, Ready at Project, Applied to agent, and Observed in session without exposing endpoints or credentials.

I will keep the portable-agent side limited to desired capability requirements and let this surface own applied and observed evidence.

@BradGroux

Copy link
Copy Markdown
Contributor Author

Response to the four-stage binding model

You're right that this PR is the agent-session half of #5060. The four-stage split — Configured, Ready at Project, Applied to agent, Observed in session — is the right way to think about the evidence chain, and the local boundary is exactly what this PR enforces: a healthy Project connection does not prove the agent received those tools.

What this PR covers today

The manifest currently handles stages three and four from the session side:

  • Applied to agent: build_session_config_observation in pool.rs emits capabilityManifest.toolSources from ctx.mcp_servers — the resolved MCP servers that were injected at session/new. The names come from the McpServer.name field, sorted and deduped, with no commands, arguments, env vars, or credentials.
  • Observed in session: the desktop reducer folds agent_initialized, session_config_captured, and available_commands_update into durable evidence, invalidated across process and session boundaries. A green readiness state requires a healthy process, open observer, online presence, and community connection — not just a successful Project probe.

The missing seam you identified

The gap is the binding identity and generation. Today toolSources in the manifest carries only a name. There is no non-secret correlation key linking a tool source in the session observation back to a specific Project connection from #4588. So the UI can show that the session received "github" and "playwright" as MCP sources, but it cannot show which Project connection generation each one came from, or whether a connection that passed initialize and tools/list in #4588 was actually included in this launch.

Why the binding identity belongs with the launch spec

The McpServer struct in buzz-acp currently carries name, command, args, and env — no connection reference. #4164 introduces the structured LaunchSpec that gives each MCP source a stable name and preserves resolved configuration. That is the natural place to carry a non-secret connection binding (connection ID + generation) from #4588 through launch into the session observation, because:

Adding the binding identity here without #4164's launch document would mean inventing a correlation key in McpServer that has no upstream source. Once #4164 lands, the LaunchSpec can carry the connection generation, build_session_config_observation can project it into capabilityManifest.toolSources as {name, kind, connectionId, generation}, and the desktop manifest can render the full chain: Configured (#4588) → Ready at Project (#4588) → Applied to agent (this PR + #4164 binding) → Observed in session (this PR).

Proposed path

  1. This PR merges as the session-observation surface — it already distinguishes requested from effective permission, applied from reported model, and reports only safe tool-source names.
  2. When buzz-acp: add structured MCP server configuration #4164 lands, add the non-secret connectionId and generation to the structured launch document and project them through build_session_config_observation into the manifest.
  3. The desktop UI then renders the four-stage state per connection without exposing endpoints or credentials.

If you would rather see the binding identity field added to this PR now — as an optional field that stays null until #4164 populates it — I can do that. It would be a small addition to capabilityManifest.toolSources entries and the TS parser. Let me know which way you prefer.

@wolfyy970

Copy link
Copy Markdown

Your sequencing is right. I would not add nullable binding fields yet; #4588 and #4164 need to define the binding ID and immutable revision first.

I reviewed the current head. Before merge, I think the card needs narrower language in three places:

  • “Ready locally” currently proves runtime, process, community, presence, and observer health—not that this agent’s required capabilities are ready. “Runtime ready” would be accurate.
  • toolSources comes from ctx.mcp_servers after session/new. That proves “Included in session launch,” not Project readiness, successful MCP startup, available tools, or use.
  • Buzz can hold several channel sessions plus heartbeat for one agent, but the reducer collapses session evidence into one latest value. The UI should identify the session and channel it is describing rather than present that as global agent state.

I would also split “runtime checked” from “session observed” time. Actual tool use should remain a later tool-call receipt, not something inferred here. With those boundaries, this becomes a useful and truthful session-evidence surface that #4588 and #4164 can connect to without reworking it later.

BradGroux and others added 2 commits August 8, 2026 07:47
Co-authored-by: Brad Groux <bradgroux@hotmail.com>
Signed-off-by: Brad Groux <bradgroux@hotmail.com>
Co-authored-by: Brad Groux <bradgroux@hotmail.com>
Signed-off-by: Brad Groux <bradgroux@hotmail.com>
BradGroux and others added 3 commits August 8, 2026 07:47
Co-authored-by: Brad Groux <bradgroux@hotmail.com>
Signed-off-by: Brad Groux <bradgroux@hotmail.com>
Co-authored-by: Brad Groux <bradgroux@hotmail.com>
Signed-off-by: Brad Groux <bradgroux@hotmail.com>
Co-authored-by: Brad Groux <bradgroux@hotmail.com>
Signed-off-by: Brad Groux <bradgroux@hotmail.com>
@BradGroux
BradGroux force-pushed the agent/agent-capability-readiness branch from db61837 to a3a699e Compare August 8, 2026 12:47
@BradGroux

Copy link
Copy Markdown
Contributor Author

This is the third recurring review + rebase pass for the open BradGroux PRs on block/buzz.

What this PR does

Enhances the agent delegation flow to show readiness and capabilities before an owner delegates work to an agent. The PR adds:

  1. Session ID attachment: set_observer_session_id attaches the ACP session ID immediately after session/new so model/mode calls and session_config_captured observations are correctly attributed to the current session, not a prior one.

  2. Model switch return value: apply_model_switch now returns Result<bool, AcpError>true only when the runtime acknowledges the switch. Application errors return false so downstream evidence doesn't claim the configured model was applied. Transport errors remain fatal.

  3. Capability manifest: build_session_config_observation adds a capabilityManifest to the session_config_captured observation, projecting:

    • modelApplication: requested vs applied model
    • toolSources: sorted, deduplicated MCP server names (names only — no commands, args, env vars, or credentials)
    • permissionMode: requested, effective, and source (runtime or buzzHarness)
  4. Permission mode tracking: apply_permission_mode now returns Result<bool, AcpError> and the observation reports whether the mode was applied by the runtime or defaults to the harness's perToolAutoDecision.

Correctness

  • The capability manifest projection is safe: the test capability_manifest_projection_exposes_names_not_mcp_secrets explicitly verifies that commands, args, and env var values (credential canaries) do not appear in the manifest.
  • The session ID is attached at the earliest possible point (right after session/new response), preventing misattribution.
  • Model switch and permission mode both distinguish transport errors (fatal) from application errors (non-fatal, return false).
  • The permission mode source attribution correctly distinguishes runtime-applied, runtime-advertised, and harness-default modes.
  • No new dependencies. No unwrap/expect in production paths.

Rebase result

Already based on current main (02f640bc4). No rebase needed — 0 commits behind.

  • Head SHA: a3a699e8ef3b260502720f59cdccb026a1f5b364 (unchanged)
  • Mergeable: ✅ MERGEABLE
  • CI: DCO ✅

No code changes were made — this was a review + rebase pass only.

…anguage

Fold wolfyy970's feedback on block#5311 and block#2957 into the readiness manifest:

Credential persistence readiness check (new):
- Rust CredentialPersistence enum: KeyringVerified, InlineFallback,
  Missing, Unavailable
- credential_persistence_for_agent() probes the keyring read-only via
  SecretStore::probe() and combines with inline key state
- ManagedAgentSummary carries credential_persistence (Option, skipped
  when None for backward compatibility with older frontends)
- TypeScript CredentialPersistence type and ManagedAgent field
- New readiness check positioned after authentication: keyring_verified
  and inline_fallback → ready, missing → attention, unavailable → unknown
- 6 new test cases covering all four states plus null/default and
  array positioning

Language narrowing (wolfyy970 items 1-4):
- 'Ready locally' → 'Runtime ready' in card, AGENTS.md, E2E test
- Tool sources label 'Sources' → 'Included in session launch'
- Session/channel identity shown in manifest header
- 'Never verified' → 'Not yet observed' for time labels

Co-authored-by: Brad Groux <bradgroux@hotmail.com>
Signed-off-by: Brad Groux <bradgroux@hotmail.com>
@BradGroux

Copy link
Copy Markdown
Contributor Author

Thanks for the review @wolfyy970 — all four language items and the credential persistence check are now folded into this PR.

Language narrowing (your items 1–4):

  1. "Ready locally" → "Runtime ready" in the card, AGENTS.md, and E2E test.
  2. Tool sources label changed from "Sources" to "Included in session launch," with matching empty-state text.
  3. Session and channel identity now shown in the manifest header. A ManifestSessionIdentity type carries sessionId and channelId from the observer event fields, so the card identifies which session and channel the evidence describes rather than presenting it as global agent state.
  4. "Never verified" → "Not yet observed" for the time label.

Credential persistence readiness check:

Added a new credential_persistence readiness check positioned after authentication:

  • Rust: CredentialPersistence enum with KeyringVerified, InlineFallback, Missing, Unavailable. Derived via credential_persistence_for_agent(), which probes the keyring read-only through SecretStore::probe() and combines with the inline key state. No secrets are loaded — probe() only checks entry presence.
  • Transport: ManagedAgentSummary carries credential_persistence: Option<CredentialPersistence> with skip_serializing_if = "Option::is_none" for backward compatibility with older frontends.
  • TypeScript: CredentialPersistence type on ManagedAgent, mapped to readiness status: keyring_verified → ready, inline_fallback → ready (detail notes inline storage), missing → attention, unavailable → unknown.
  • Tests: 6 new test cases covering all four states plus null/default (older backend) and array positioning.

As you noted, the mismatched case (keyring entry exists but its value doesn't derive the agent's pubkey) is not covered here — that would require loading the actual secret, which this check deliberately avoids. That gap is called out in the Rust doc comment.

The "runtime checked" vs "session observed" time split you suggested is partially addressed: lastVerifiedAt already takes the newest of initialize, session config, commands, catalog, and runtime timestamps. Fully splitting those into separate displayed timestamps would be a larger UI change and could follow in a subsequent PR if you'd like.

All 4,559 desktop tests pass. DCO, Semgrep, and zizmor checks pass on the latest push.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show what each agent can do and whether it is ready before delegation

2 participants