Conversation
Retarget publish-images.yml at ghcr.io/cartridge-gg/centaur on GitHub-hosted runners with docker buildx (this fork has no Depot project), add the release/c7e-centaur-overlay* branch glob and contrib/chart/** path trigger, and auto-dispatch the c7e overlay deploy when canonical-branch images publish. Add tag-release.yml: durable c7e-<upstream-base>-<counter> tags cut from main, so deployed commits can never be orphaned by history rewrites. Gate release-chart.yml's tag minting to the upstream repo so the fork cannot mint colliding centaur-* tags. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ough
Console: add a github_app grant to the broker-credential registry. The
console holds the App private key (client_secret, stored encrypted) and
mints short-lived installation tokens via an RS256 App JWT, rotating
them like any other brokered credential. An idempotent seed migration
provisions the credential from GITHUB_APP_ID / GITHUB_APP_INSTALLATION_ID /
GITHUB_APP_PRIVATE_KEY_B64 when set; the chart wires those env vars into
the console from the shared infra Secret.
api-rs: let a tool's pyproject declare where an HTTP secret's value
comes from (source = {type = "token_broker", credential_id = ...}) and
forward the table verbatim into the generated iron-proxy fragment:
tool_discovery parses it, centaur-perms mirrors it, iron-control accepts
typed sources at startup. Falls back to the {placeholder: <secret_ref>}
shape when no source table is given.
Together these let a tool (the deployment's github_auth_headers) ride
broker-rotated GitHub App tokens: raw tokens never enter sandboxes and
no out-of-band CronJob rotates a shared secret.
Pending upstream as paradigmxyz#793 + companion.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 3ccdd79)
The tag-fetch step adds an upstream remote to the checkout, so gh resolved the base repo to paradigmxyz/centaur and the release step failed with "tag has not been pushed" (c7e-0.1.110-2 needed a manual gh release create). GH_REPO pins resolution to this repository. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Chat SDK's event dispatch drops file events (file_shared,
file_change) before any callback fires, so nothing today can react to a
file being created or edited. Add a raw-body sidecar (the
channel_created / lateSlackFiles pattern) that, when enabled, creates a
durable workflow run via POST /api/workflows/runs for matching file
events.
Deployment-neutral and default-off: the target workflow name, event
types, channel allowlist, and files.info title-keyword filter all come
from env config (SLACKBOTV2_FILE_EVENT_*). The bot stays timer-free —
any settle/debounce behavior belongs in the target workflow, which can
sleep durably. Per-edit event storms collapse at spawn time via the
idempotency key slack-file-event:{workflow}:{file_id} (optionally
time-bucketed); the dispatch task never throws into the webhook path.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Allow the company-context reader role to see company-scoped memory notes when public Slack context is enabled, while keeping other c7e_memory document types and user-scoped notes hidden. The embeddings policy delegates to the document policy, so the vector search lane follows without a separate change. Rebase note (upstream dafff4c): renumbered the fork migration from 0053 to 0055 because upstream owns 0053 and 0054. Production databases that already applied the fork migration as version 53 must reconcile/delete that _sqlx_migrations row before api-rs boots, then apply upstream 0053/0054 and the fork's 0055 in order; the policy DDL is idempotent.
…lete (#43) Three gaps in the calendar surface, found while exercising the tool against a real calendar. No way to create a Meet. calendar_create_event built a plain event body and called events().insert() without conferenceDataVersion, so an agent could book the slot but not the meeting. Meet is minted through the conferencing subresource: the body carries a createRequest with a fresh requestId and the call must opt in with conferenceDataVersion=1, or Calendar drops conferenceData and returns an event with no link. Create and update now take `conference`, return `meet_link`, and re-fetch once when Calendar answers before the mint settles. On update the flag only adds a conference to an event that lacks one; leaving conferenceDataVersion at its 0 default elsewhere is what keeps an existing Meet intact on an ordinary update. Edits reached attendees as silence. calendar_update_event passed sendUpdates="all" only when add_attendees was set, so moving an event, renaming it, or changing where it happens notified nobody: attendees' copies moved, their invite emails did not. Verified against a real event -- the reschedule produced no mail at all. `notify` now defaults to notifying when the event has attendees and the edit is material: when, where, what it is called, who else is coming, or a Meet just added. Description-only edits stay quiet on purpose, so the notices that land keep meaning something. Materiality is deliberately narrow. The field tests are truthiness, matching how the function applies them -- it writes a field only when the value is truthy, so `location=""` edits nothing and must not send mail. Attendee notification keys off whether the merge actually appended somebody, not whether a list was passed, so re-inviting an existing guest stays quiet. That merge also now records the emails it appends, so a repeated address in one call is added once rather than duplicated. No way to cancel. calendar_delete_event is new; the tool could create and update events but never delete one. It notifies by default, since a cancellation nobody hears about just leaves the meeting on every calendar. Submitted upstream as paradigmxyz#1522; the calendar functions, CLI commands, and tests here are byte-identical to that submission. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011nvUztTAb5Kvkb9PhCnCbT
… recovery One row per TestFlight submission the Cartridge overlay's feedback pipeline has seen: the parsed inbox comment (tester text, screenshots, device), where the inbox comment and the Slack post live, and the triage state the overlay's recovery scan queries by (status, attempts, the failure reason and its timestamps, the dispatch that last claimed it). The overlay writes the row at ingest and on every triage state save; its recovery scan (`c7e_dango_feedback_recovery_scan`, agent#379) reads it with one query instead of walking progress records and state documents. The per-submission state document in company_context_documents stays as the claim's lock target and what the shared readers use. The migration backfills a row per existing state document so earlier failures are visible the moment api-rs starts with it. Fork-only migration, like 0055. No upstream table changes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NCk4NGNcLa52UfFKAYevtH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The Cartridge overlay's TestFlight recovery scan (cartridge-gg/agent#379) needs one query for stranded submissions and the parsed submission content to re-dispatch a triage without a GitHub read. The overlay's own migration mechanism needs a manual
psqlapply; a fork migration ships with the base image and api-rs applies it at startup (RUN_MIGRATIONS).What
services/api-rs/crates/centaur-session-sqlx/migrations/0056_c7e_testflight_submissions.sql: one table, one index, one backfill.c7e_testflight_submissions: one row per submission with the parsed inbox comment (tester text, screenshots, device, tester id), the inbox comment and Slack post provenance, and the triage state (status,attempts,reason,run_id,dispatch_id,claimed_at,first_failed_at,last_failed_at,verdict,issue_url,issue_urls) plus the scan'slast_dispatched_at. Index on(status, updated_at desc).company_context_documentsrows withsource_type = 'testflight_feedback_state',ON CONFLICT DO NOTHING, so earlier failures are visible the moment the migration runs. Backfilled rows carry no tester text or screenshots; the overlay re-reads their inbox comment.Fork-only, like 0055. No upstream table is touched. Every statement is idempotent (
if not exists,on conflict do nothing).Validation
The overlay's
scripts/check-testflight-submissions-sqlapplies this file twice against a throwaway local PostgreSQL 17 with a stubcompany_context_documents, checks the backfilled rows, and prepares and executes every statement the overlay runs against the table. It passes..github/scripts/check-migration-order.sh origin/mainpasses.Rollout
After merge,
publish-imagesbuildssha-<short>images frommain. BumpCENTAUR_BASE_IMAGE_SHA,CENTAUR_BASE_IMAGE_TAG, andCENTAUR_BASE_REFin cartridge-gg/agent and dispatchoverlay-image.yml; api-rs applies 0056 at startup and the overlay's scan stops reportingno_table.🤖 Generated with Claude Code
https://claude.ai/code/session_01NCk4NGNcLa52UfFKAYevtH