Skip to content

test(console): cover GitHub App proxy sync refresh - #18

Open
tarrencev wants to merge 11 commits into
release/c7e-centaur-overlayfrom
fix/github-app-expiring-proxy-snapshots
Open

tarrencev wants to merge 11 commits into
release/c7e-centaur-overlayfrom
fix/github-app-expiring-proxy-snapshots

Conversation

@tarrencev

@tarrencev tarrencev commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • keep proxy sync snapshots on the existing base PrincipalSyncConfigSnapshot::TTL path
  • add regression coverage that GitHub App-backed proxy sync rebuilds after that base TTL and returns a fresh full payload

Why this is enough

GitHub App installation tokens expire after about an hour, and Centaur's GithubAppInstallationToken cache already refreshes them 15 minutes before expiry. The existing proxy sync snapshot TTL is 10 minutes, so we do not need a special github_app/expiring-source classification or a shorter TTL.

The important behavior to preserve is that a warm iron-proxy eventually receives a changed config_hash and a full refreshed payload instead of continuing to use the same inline token forever. This test documents that the existing base snapshot TTL provides that refresh path for github_app sources.

Validation

  • git diff --check origin/release/c7e-centaur-overlay...HEAD
  • ASDF_RUBY_VERSION=3.4.8 ruby -c services/console/test/controllers/api/v1/proxy_sync_controller_test.rb

Not run

  • ASDF_RUBY_VERSION=3.4.8 bin/rails test test/controllers/api/v1/proxy_sync_controller_test.rb is blocked in this local sandbox by Postgres auth: 127.0.0.1:5432 failed: fe_sendauth: no password supplied.

tarrencev and others added 11 commits June 25, 2026 15:37
Expose centaur's durable, thread-keyed session control plane behind an
Anthropic Messages-compatible POST /v1/messages so any Anthropic SDK client
or `claude -p` (via ANTHROPIC_BASE_URL) can drive a fully-configured centaur
thread (tools, sandbox, durability).

- Thread continuity via X-Centaur-Thread-Key (absent -> api:<uuid>).
- Honors `model` and `system` (first-request-wins), threading them into the
  sandbox harness env (CLAUDE_MODEL, CENTAUR_EXTRA_SYSTEM_PROMPT).
- Streaming (SSE) and non-streaming responses via an AnthropicTranslator that
  maps harness output to Anthropic content blocks. Handles both harness event
  shapes: claude (Anthropic-shaped) and codex, including the deployed Rust
  harness-server's slash-method/params events (item/agentMessage/delta,
  item/reasoning/textDelta, item/completed).
- Drives the turn off the last user message so clients (e.g. Claude Code) that
  append a trailing system-role message in messages[] are handled.

Validated end-to-end against the c7e deployment with `claude -p`: basic
replies, tool use (inner agent runs shell commands), and model selection
(requested model lands as CLAUDE_MODEL in the spawned sandbox).
Under repo-cache overlay delivery the sandbox CENTAUR_OVERLAY_DIR was
never set, so the entrypoint's overlay branches (.agents/skills,
services/sandbox/SYSTEM_PROMPT.md) were skipped. api-rs now injects
CENTAUR_OVERLAY_DIR=/home/agent/github/<repo> into the sandbox env
(ClaudeCode/codex workloads) from the overlay repo slug, which the chart
derives from the first $overlaySources entry (upstream's overlays.sources
model) -- no separate overlay.repo value.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Build/publish centaur images under ghcr.io/tarrencev/centaur for the
c7e (Latitude) deployment: trigger on release/c7e-centaur-overlay-*
branches and on contrib/chart/** changes, and point IMAGE_NAMESPACE at
the fork so the release branch publishes to the namespace c7e pulls its
base images from.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Expose Centaur's durable, thread-keyed session control plane behind an OpenAI
Responses-compatible POST /v1/responses, the wire API the Codex CLI speaks, so
`codex` (via a custom model_provider base_url) or any Responses client can drive
a fully-configured Centaur thread.

Mirrors the Anthropic /v1/messages ingress: same SessionRuntime flow, thread
continuity via X-Centaur-Thread-Key, model + instructions (system) threaded into
the sandbox harness env, tools accepted but decorative (Centaur owns in-sandbox
tools). A ResponsesTranslator maps harness output to Responses streaming events
(response.created -> output_item/content_part -> output_text.delta -> completed),
handling both harness shapes (claude content blocks; codex dotted and
slash-method events). The terminal usage carries total_tokens, which the Codex
CLI requires. Drives the turn off the last user message in `input`.
A codex turn can contain several agentMessages (the agent narrates between tool
calls). emit_replacement_text dedupped item.completed against the GLOBAL accumulated
text, so every completed message failed the prefix check and re-emitted its whole
text -> the client rendered duplicated/'stuttering' output. Track each item's
streamed deltas separately and dedup the completed text against that. Adds a
multi-message regression test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The agent emits its narration and final answer as distinct agentMessages (it
narrates before/after each tool call). The translators concatenated them into one
output_text with no separator, gluing e.g. '...previous snapshot.Current
deployments: ...'. Insert a blank line when a new agentMessage starts after prior
output, in both the Responses and Messages translators.

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

Key each Thinking card by `itemId#summaryIndex` instead of `itemId`, so a
turn's reasoning renders as one card per summary section — separate bullets
that interleave chronologically with command executions, matching native
codex — instead of one card concatenating all sections with blank lines.

- Deltas still accumulate per section, so the per-delta card-explosion fix
  stays intact; this only splits a handful of sections, not raw deltas.
- Cards insert when their first delta arrives, restoring interleaving with
  command cards that previously rendered after the merged reasoning blob.
- When summaryIndex is absent (Claude/Anthropic normalized path, content_index
  0) the key collapses to itemId, so that path keeps one card per item.
- On item.completed, every section card of the item completes, reconciling
  each section's text from the sealed summary parts when they align 1:1.

Tests cover per-section split, interleaving with a command, and sealing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 6955dc4)
After the canonical release/c7e-centaur-overlay branch builds its base
images, fire a repository_dispatch (base-images-published) at the c7e
overlay (cartridge-gg/agent) with the new image sha/tag, so it auto-rolls
out instead of needing a manual repo-var bump. The overlay deploy still
gates on its `latitude` environment.

Requires an OVERLAY_DISPATCH_TOKEN secret (PAT with repo access to
cartridge-gg/agent) on this repo, and the matching overlay-side change
(repository_dispatch trigger) to be merged first.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…tartup

The api-rs startup reconcile (register_role -> source_from_secret) only accepted
placeholder/token_broker sources and crash-looped on a tool declaring
`source = { type = "github_app", ... }`. Port the typed-source pass-through from
centaur_perms::translate::http_source so the startup path matches the perms CLI.

Squashes the /v1 ingress + client-tools passthrough + harness MCP-bridge
exploration (added in #15, reverted in #17): the net surviving change is this
github_app startup fix. The orchestrator now lives as a skill in the overlay,
and the local<->sandbox unification will be prompt-native, so no /v1 persona
honoring or in-sandbox MCP bridge remains here.

[skip ci]

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tarrencev
tarrencev force-pushed the fix/github-app-expiring-proxy-snapshots branch from bdd3348 to 406c035 Compare June 26, 2026 16:36
@tarrencev tarrencev changed the title fix(console): refresh expiring proxy sync snapshots test(console): cover GitHub App proxy sync refresh Jun 26, 2026
tarrencev added a commit that referenced this pull request Jun 26, 2026
…l, tests)

Squashed: GitHub App installation-token minting + proxy-sync refresh (console
+ centaur-perms + tool_discovery), iron-control startup support for the typed
github_app secret source (registry::source_from_secret), and proxy-sync
controller test coverage (PR #18).

[skip ci]
@tarrencev

Copy link
Copy Markdown
Collaborator Author

Folded into the squashed github-app commit on release/c7e-centaur-overlay (history cleanup). Closing.

@tarrencev
tarrencev force-pushed the release/c7e-centaur-overlay branch from 0a344cb to 7080a81 Compare June 26, 2026 16:51
@tarrencev tarrencev closed this Jun 26, 2026
@tarrencev tarrencev reopened this Jun 26, 2026
@tarrencev
tarrencev force-pushed the release/c7e-centaur-overlay branch 6 times, most recently from 84b654a to d59c54e Compare July 1, 2026 16:07
@tarrencev
tarrencev force-pushed the release/c7e-centaur-overlay branch from bce0ddc to f6ad15b Compare July 8, 2026 23:58
@tarrencev
tarrencev force-pushed the release/c7e-centaur-overlay branch from 1807424 to 45e350a Compare July 16, 2026 17:25
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.

1 participant