Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
8497953
feat: run workflow agents in parallel (#1420)
mslipper Aug 18, 2026
be75196
fix(slack): omit default upload comments (#1422)
decofe Aug 18, 2026
b28604b
feat(githubbot): ack review-feedback turns with reactions on the revi…
oponder Aug 18, 2026
7bc72e7
feat: allow workflows to select principals (#1423)
mslipper Aug 18, 2026
98fba26
fix(sentry): expose read-only client commands through the CLI (#1419)
oponder Aug 18, 2026
2514c4e
feat: add an option to configure OpenAI base URL (#1370)
pyoxa Aug 18, 2026
31620b5
chore(deps): bump the api-rs-dependencies group across 1 directory wi…
dependabot[bot] Aug 18, 2026
c05693f
chore(deps): bump the github-actions group with 3 updates (#1405)
dependabot[bot] Aug 18, 2026
0a3e82c
feat: add githubkit workflow dependency (#1426)
mslipper Aug 18, 2026
300b760
fix(slack): stop injecting ETL token in CLI (#628)
decofe Aug 18, 2026
e24bacf
fix(slack): send DMs without im:write scope (#1145)
ribeirojose Aug 19, 2026
46363a0
fix(mcp): include tool-host correlation context in errors (#992)
Osraka Aug 19, 2026
e084069
fix(chart): allow explicit Console service hosts (#1144)
ribeirojose Aug 19, 2026
80450d0
docs: drop dead secret keys; fix stale proxy-fallback comment (#998)
akandic47 Aug 19, 2026
25bf7e2
fix(chart): roll repo-cache when its GitHub token secret changes (#1322)
kreplik Aug 19, 2026
b6bea3b
docs: document access-token broker credential bootstrap (#997)
akandic47 Aug 19, 2026
ae185c2
fix(sandbox): seed brokered Codex auth for Hermes (#1368)
jamalavedra Aug 19, 2026
fdd8727
fix(attio): harden CRM mutations and pagination (#1306)
decofe Aug 19, 2026
80f19cf
refactor: remove vestigial thread key helpers (#1427)
mslipper Aug 19, 2026
0357221
feat(console): add Slack channel autocomplete (#1408)
gorried Aug 19, 2026
80f69e4
fix(workflows): Linear searchIssues takes `term`, not `query` (#1335)
aadityakbh Aug 19, 2026
a48f2f7
ci: skip Cloudflare deploy without credentials (#1428)
mslipper Aug 19, 2026
453eb82
chore(deps): bump the ruby-dependencies group across 1 directory with…
dependabot[bot] Aug 19, 2026
4fdbc48
feat: customize workflow Slack messages (#1401)
vijith-reddy Aug 19, 2026
c133ee7
feat: support Standard Webhooks authentication (#1380)
ecejas Aug 19, 2026
93115cf
fix(slack): upgrade API emulator (#1152)
ribeirojose Aug 19, 2026
86b14a0
chore(deps): bump rails-paradedb from 0.7.0 to 0.9.0 in /services/con…
dependabot[bot] Aug 19, 2026
9d287f7
refactor(slack): own nanocodex rollout policy (#1437)
mslipper Aug 19, 2026
d13b7e5
fix(figma): align credential contract (#1146)
ribeirojose Aug 19, 2026
16e6a9b
Support custom Codex providers (#1410)
Zygimantass Aug 19, 2026
cafc4e4
fix(api-rs): authorize githubbot for all its session key families (#1…
oponder Aug 19, 2026
19606f9
chore(deps): bump compatible harness-server dependencies (#1429)
dependabot[bot] Aug 19, 2026
cb541d4
fix(granola): resolve shared meeting links (#1434)
decofe Aug 20, 2026
bdc84ad
feat(workflows): resolve principals by OID (#1439)
mslipper Aug 20, 2026
666e129
fix: retain stale Slack channel catalog (#1441)
mslipper Aug 20, 2026
bc72622
fix: retry transient Slack sync failures (#1443)
svc-paradigm Aug 20, 2026
91dad0a
sync fork with upstream 2026-08-20
oponder Aug 20, 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
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ updates:
prefix: chore
include: scope
open-pull-requests-limit: 5
ignore:
# rails-paradedb 0.10+ requires ParadeDB 0.25+, while Console runs 0.23.
- dependency-name: rails-paradedb
versions:
- ">= 0.10.0"
groups:
ruby-dependencies:
patterns:
Expand Down Expand Up @@ -59,6 +64,11 @@ updates:
prefix: chore
include: scope
open-pull-requests-limit: 5
ignore:
# Starlark 0.13 uses hashbrown 0.14, which allocative 0.3.6+ no longer supports.
- dependency-name: allocative
versions:
- ">= 0.3.6"
groups:
harness-server-dependencies:
patterns:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ jobs:
with:
persist-credentials: false

- uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1
with:
toolchain: stable
components: rustfmt, clippy
Expand Down Expand Up @@ -183,7 +183,7 @@ jobs:
working-directory: services/console
bundler-cache: true

- uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1
with:
toolchain: stable
components: rustfmt, clippy
Expand Down Expand Up @@ -322,7 +322,7 @@ jobs:
with:
python-version: "3.11"

- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: true
prune-cache: true
Expand Down Expand Up @@ -354,7 +354,7 @@ jobs:
with:
python-version: "3.11"

- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: true
prune-cache: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/close-stale-draft-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
timeout-minutes: 5
steps:
- name: Close inactive draft pull requests
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const inactivityCutoff = Date.now() - 14 * 24 * 60 * 60 * 1000;
Expand Down
6 changes: 1 addition & 5 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,8 @@ jobs:
- name: Build docs
run: npm run build

- name: Skip Cloudflare deploy
if: ${{ env.CLOUDFLARE_ACCOUNT_ID == '' || env.CLOUDFLARE_API_TOKEN == '' }}
run: echo "Cloudflare credentials are not configured; docs build completed without deployment."

- name: Deploy
if: github.event_name != 'pull_request'
if: ${{ github.event_name != 'pull_request' && env.CLOUDFLARE_ACCOUNT_ID != '' && env.CLOUDFLARE_API_TOKEN != '' }}
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion contrib/chart/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v2
name: centaur
description: Helm chart for the trusted Centaur control plane
type: application
version: 0.1.119
version: 0.1.124
appVersion: "0.1.0"
dependencies:
- name: connect
Expand Down
11 changes: 9 additions & 2 deletions contrib/chart/templates/apirs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,6 @@ spec:
{{- end }}
- name: RUN_MIGRATIONS
value: {{ .Values.apiRs.runMigrations | quote }}
- name: SESSION_CODEX_NANOCODEX_ROLLOUT_PERCENT
value: {{ .Values.apiRs.codexNanocodexRolloutPercent | quote }}
- name: IRON_CONTROL_SYNC_INFRA_SECRETS
value: {{ .Values.apiRs.syncInfraSecrets | quote }}
- name: RUST_LOG
Expand Down Expand Up @@ -429,6 +427,12 @@ spec:
value: {{ .Values.sandbox.codexAuthMode | quote }}
- name: CLAUDE_CODE_AUTH_MODE
value: {{ .Values.sandbox.claudeCodeAuthMode | quote }}
{{- if .Values.codex.customProviders }}
# Shared provider catalog: api-rs derives hostname-scoped proxy
# credentials from the same JSON sandboxes use for Codex config.
- name: CODEX_CUSTOM_PROVIDERS
value: {{ .Values.codex.customProviders | toJson | quote }}
{{- end }}
# Which harness's auth fragment iron-proxy registers (and therefore
# which placeholder credential lands in the sandbox env). Must agree
# with the harness the sandbox image CMD actually runs.
Expand All @@ -447,6 +451,9 @@ spec:
{{- if not (hasKey .Values.sandbox.extraEnv "COMPANY_CONTEXT_EMBEDDINGS_MODEL") }}
{{- $sandboxEnvList = append $sandboxEnvList (dict "name" "COMPANY_CONTEXT_EMBEDDINGS_MODEL" "value" $companyContextEmbeddingsModel) }}
{{- end }}
{{- if .Values.codex.customProviders }}
{{- $sandboxEnvList = append $sandboxEnvList (dict "name" "CODEX_CUSTOM_PROVIDERS" "value" (.Values.codex.customProviders | toJson)) }}
{{- end }}
{{- range $k, $v := .Values.sandbox.extraEnv }}
{{- $sandboxEnvList = append $sandboxEnvList (dict "name" $k "value" ($v | toString)) }}
{{- end }}
Expand Down
8 changes: 8 additions & 0 deletions contrib/chart/templates/console.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ spec:
name: {{ $secretEnv }}
key: {{ printf "%sSLACK_BOT_TOKEN" $prefix }}
optional: true
{{- if .Values.codex.customProviders }}
- name: CODEX_CUSTOM_PROVIDERS
value: {{ .Values.codex.customProviders | toJson | quote }}
{{- end }}
{{- range $name := tuple "CLAUDE_MODEL" "CODEX_MODEL" }}
{{- if hasKey $.Values.sandbox.extraEnv $name }}
# Mirror the deployer's harness default-model override
Expand Down Expand Up @@ -186,6 +190,10 @@ spec:
- name: CENTAUR_CONSOLE_PUBLIC_URL
value: {{ $console.publicUrl | quote }}
{{- end }}
{{- with $console.allowedHosts }}
- name: CENTAUR_CONSOLE_ALLOWED_HOSTS
value: {{ join "," . | quote }}
{{- end }}
{{- with $console.sentryDsn }}
- name: SENTRY_DSN
value: {{ . | quote }}
Expand Down
4 changes: 4 additions & 0 deletions contrib/chart/templates/githubbot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ spec:
# final flush + exit still fit before the pod is force-killed.
- name: GITHUBBOT_SHUTDOWN_DRAIN_MS
value: {{ mul (sub (int .Values.githubbot.terminationGracePeriodSeconds) 10) 1000 | quote }}
{{- if .Values.codex.customProviders }}
- name: CODEX_CUSTOM_PROVIDERS
value: {{ .Values.codex.customProviders | toJson | quote }}
{{- end }}
{{- range $name, $value := .Values.githubbot.extraEnv }}
- name: {{ $name }}
value: {{ $value | quote }}
Expand Down
4 changes: 4 additions & 0 deletions contrib/chart/templates/linearbot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ spec:
key: {{ printf "%sDATABASE_URL" .Values.secretManager.envPrefix }}
- name: LINEARBOT_USER_NAME
value: {{ .Values.linearbot.userName | quote }}
{{- if .Values.codex.customProviders }}
- name: CODEX_CUSTOM_PROVIDERS
value: {{ .Values.codex.customProviders | toJson | quote }}
{{- end }}
{{- range $name, $value := .Values.linearbot.extraEnv }}
- name: {{ $name }}
value: {{ $value | quote }}
Expand Down
4 changes: 4 additions & 0 deletions contrib/chart/templates/repo-cache.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ spec:
{{ include "centaur.componentSelectorLabels" (dict "root" . "component" "repo-cache") | nindent 6 }}
template:
metadata:
{{- if $repoCacheHasGithubToken }}
annotations:
checksum/github-token: {{ include "centaur.secretResourceVersion" (dict "root" . "name" (include "centaur.repoCacheGithubTokenSecretName" .)) | sha256sum }}
{{- end }}
labels:
{{ include "centaur.componentSelectorLabels" (dict "root" . "component" "repo-cache") | nindent 8 }}
spec:
Expand Down
9 changes: 7 additions & 2 deletions contrib/chart/templates/slackbotv2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ spec:
- name: CENTAUR_API_URL
value: {{ printf "http://%s:%v" $apiRsName .Values.apiRs.port | quote }}
# New threads without an explicit --claude/--amp/--codex/
# --nanocodex flag run the deployment's default harness. api-rs
# applies any configured Codex/Nanocodex rollout.
# --nanocodex flag run the deployment's default harness.
- name: SLACKBOTV2_DEFAULT_HARNESS
value: {{ .Values.sandbox.harnessEngine | quote }}
- name: SLACKBOTV2_CODEX_NANOCODEX_ROLLOUT_PERCENT
value: {{ .Values.slackbotv2.codexNanocodexRolloutPercent | quote }}
- name: SLACK_BOT_TOKEN
valueFrom:
secretKeyRef:
Expand Down Expand Up @@ -122,6 +123,10 @@ spec:
- name: SLACKBOTV2_CHANNEL_DEFAULTS
value: {{ .Values.slackbotv2.channelDefaults | toJson | quote }}
{{- end }}
{{- if .Values.codex.customProviders }}
- name: CODEX_CUSTOM_PROVIDERS
value: {{ .Values.codex.customProviders | toJson | quote }}
{{- end }}
{{- range $name := tuple "CLAUDE_MODEL" "CODEX_MODEL" "CODEX_MODEL_REASONING_EFFORT" }}
{{- if and (hasKey $.Values.sandbox.extraEnv $name) (not (hasKey $.Values.slackbotv2.extraEnv $name)) }}
# Mirror the deployer's harness default override (sandbox.extraEnv)
Expand Down
30 changes: 30 additions & 0 deletions contrib/chart/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
"properties": {
"replicaCount": { "type": "integer" },
"publicUrl": { "type": "string" },
"allowedHosts": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
},
"sentryDsn": { "type": "string" },
"railsEnv": { "type": "string" },
"image": {
Expand Down Expand Up @@ -193,6 +198,26 @@
}
}
},
"codex": {
"type": "object",
"properties": {
"customProviders": {
"type": "object",
"propertyNames": { "pattern": "^[a-z][a-z0-9_-]*$" },
"additionalProperties": {
"type": "object",
"properties": {
"name": { "type": "string", "minLength": 1 },
"baseUrl": { "type": "string", "pattern": "^https://" },
"apiKeyEnv": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]*$" },
"defaultModel": { "type": "string", "minLength": 1 }
},
"required": ["name", "baseUrl", "apiKeyEnv"],
"additionalProperties": false
}
}
}
},
"sandbox": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -403,6 +428,11 @@
"type": "object",
"properties": {
"mcpPublicUrl": { "type": "string" },
"codexNanocodexRolloutPercent": {
"type": "integer",
"minimum": 0,
"maximum": 100
},
"responseMetadataMode": {
"type": "string",
"enum": ["first", "always", "never"]
Expand Down
27 changes: 23 additions & 4 deletions contrib/chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ console:
# When set, the slackbotv2 deployment also links the first assistant message
# in a Slack thread to the Console session view; leave empty to omit the link.
publicUrl: ""
# Additional exact Host headers accepted by Rails Host Authorization. Use for
# service DNS names that differ from the chart's short in-cluster URL;
# publicUrl and the short service host are already included.
allowedHosts: []
# Optional Sentry DSN for Console web requests and background jobs. Empty by
# default, so the Sentry SDK remains disabled unless explicitly configured.
sentryDsn: ""
Expand Down Expand Up @@ -267,6 +271,21 @@ overlays:
# toolsSubdir: ""
# skillsSubdir: ""

codex:
# Operator-defined OpenAI-compatible Responses providers. Each provider is
# added to sandbox Codex config, exposed through `--provider <id>`, and given
# a hostname-scoped iron-proxy bearer-token replacement. `apiKeyEnv` names a
# field in the configured secret source; sandboxes receive only a placeholder.
# Example:
# customProviders:
# private_responses:
# name: Private Responses
# baseUrl: https://inference.example.com/v1
# apiKeyEnv: PRIVATE_RESPONSES_API_KEY
# # Optional; callers must pass --model when omitted.
# defaultModel: example-model
customProviders: {}

sandbox:
controller: pod
image:
Expand Down Expand Up @@ -396,10 +415,6 @@ apiRs:
tag: latest
pullPolicy: Always
port: 8080
# Sticky percentage of session requests for Codex assigned to Nanocodex.
# The API hashes the thread key once and persists the resolved harness on the
# session. Set to 0 to keep new Codex requests on Codex.
codexNanocodexRolloutPercent: 50
# Public/local MCP endpoint advertised through OAuth protected-resource
# metadata. Empty falls back to slackbotv2.mcpPublicUrl.
mcpPublicUrl: ""
Expand Down Expand Up @@ -485,6 +500,7 @@ apiRs:
activitySummary:
enabled: false
model: gpt-5.4-nano
# Deprecated compatibility fallback. Prefer OPENAI_BASE_URL in apiRs.extraEnv.
openaiBaseUrl: https://api.openai.com/v1
minIntervalSecs: 20
timeoutSecs: 5
Expand Down Expand Up @@ -531,6 +547,9 @@ slackbotv2:
# Join newly-created public channels after subscribed channel_created events.
# Requires the Slack app to grant channels:read and channels:join.
autoJoinCreatedChannels: false
# Sticky percentage of otherwise-default Codex Slack threads assigned to
# Nanocodex. A non-default model selection bypasses the rollout.
codexNanocodexRolloutPercent: 0
# Append model, harness, and reasoning effort to the first live streamed
# Slack assistant response, every response, or no responses. Independent of
# the optional Console link below.
Expand Down
14 changes: 6 additions & 8 deletions contrib/scripts/bootstrap-k8s-secrets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ Console bootstrap:
initial admin email (default admin@centaur.local)
The initial password, API key, the three ActiveRecord encryption keys, and
SECRET_KEY_BASE are auto-generated when absent (never rotated in place).

Note: harness access-token modes (sandbox.codexAuthMode / claudeCodeAuthMode
set to access_token) also need a console broker credential (openai-codex /
anthropic-claude) created out of band with `centaur-perms broker create`;
without it api-rs fails registration at startup. This script cannot seed it.
See the Codex/Claude Auth Modes sections in docs/pages/deploying-in-production.mdx.
EOF
}

Expand Down Expand Up @@ -198,12 +204,6 @@ if secret_exists centaur-infra-env; then
if [[ -n "${OP_CONNECT_TOKEN:-}" ]]; then
patch_data+=("\"OP_CONNECT_TOKEN\":\"$(printf '%s' "$OP_CONNECT_TOKEN" | base64 | tr -d '\n')\"")
fi
# Top-up IRON_BROKER_TOKEN for clusters bootstrapped before iron-token-broker
# support landed. Only generated when absent so we don't rotate it out from
# under cached iron-proxy access tokens on every script run.
if ! secret_key_present IRON_BROKER_TOKEN; then
patch_data+=("\"IRON_BROKER_TOKEN\":\"$(rand_hex | base64 | tr -d '\n')\"")
fi
# GITHUB_TOKEN for the repo-cache DaemonSet. Set whenever present so it can be
# rotated; harmless when repoCache is disabled.
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
Expand Down Expand Up @@ -315,8 +315,6 @@ else
secret_args=(
-n "$NAMESPACE" create secret generic centaur-infra-env
--from-literal=IRON_MANAGEMENT_API_KEY="$(rand_hex)"
--from-literal=IRON_BROKER_TOKEN="$(rand_hex)"
--from-literal=SANDBOX_SIGNING_KEY="$(rand_hex)"
--from-literal=OP_SERVICE_ACCOUNT_TOKEN="$OP_SERVICE_ACCOUNT_TOKEN"
--from-literal=OP_VAULT="$OP_VAULT"
--from-literal=SLACK_BOT_TOKEN="$SLACK_BOT_TOKEN"
Expand Down
Loading