Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
45 changes: 39 additions & 6 deletions .github/workflows/strix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ on:
description: Optional pull request head SHA for trusted PR-scope evidence
required: false
type: string
strix_llm:
description: Optional Strix model override for manual evidence runs
required: false
default: openai/openai/gpt-4.1
type: string

concurrency:
group: strix-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
Expand All @@ -31,6 +36,7 @@ concurrency:
permissions:
actions: read
contents: read
models: read

jobs:
strix:
Expand Down Expand Up @@ -109,12 +115,23 @@ jobs:
- name: Gate Strix secrets
id: gate
env:
STRIX_MODEL: ${{ secrets.STRIX_LLM || 'vertex_ai/gemini-3.1-pro-preview-customtools' }}
STRIX_MODEL: ${{ github.event.inputs.strix_llm || 'openai/openai/gpt-4.1' }}
STRIX_OPENAI_API_KEY: ${{ secrets.STRIX_OPENAI_API_KEY }}
STRIX_VERTEX_CREDENTIALS: ${{ secrets.GCP_SA_KEY }}
GITHUB_MODELS_TOKEN: ${{ github.token }}
run: |
strix_model="$(printf '%s' "$STRIX_MODEL" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
case "$strix_model" in
openai/openai/*)
echo 'enabled=true' >> "$GITHUB_OUTPUT"
echo 'provider_mode=github_models' >> "$GITHUB_OUTPUT"
sanitized_github_models_token="$(printf '%s' "$GITHUB_MODELS_TOKEN" | tr -d '\r\n')"
trimmed_github_models_token="$(printf '%s' "$sanitized_github_models_token" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
if [ -z "$trimmed_github_models_token" ]; then
echo '::error::github.token is required for GitHub Models Strix scans.'
exit 1
fi
;;
gpt-5.[4-9]* | gpt-5.[1-9][0-9]* | gpt-[6-9]* | gpt-[1-9][0-9]* | \
openai/gpt-5.[4-9]* | openai/gpt-5.[1-9][0-9]* | openai/gpt-[6-9]* | openai/gpt-[1-9][0-9]*)
echo 'enabled=true' >> "$GITHUB_OUTPUT"
Expand All @@ -137,7 +154,7 @@ jobs:
fi
;;
*)
echo '::error::STRIX_LLM must select direct OpenAI GPT-5.4 or newer, or an approved organization Vertex AI model.'
echo '::error::STRIX_LLM must select GitHub Models openai/openai/*, direct OpenAI GPT-5.4 or newer, or an approved organization Vertex AI model.'
exit 1
;;
esac
Expand All @@ -152,7 +169,7 @@ jobs:
- name: Mask LLM API key
if: steps.gate.outputs.enabled == 'true'
env:
LLM_API_KEY: ${{ steps.gate.outputs.provider_mode == 'openai_direct' && secrets.STRIX_OPENAI_API_KEY || '' }}
LLM_API_KEY: ${{ steps.gate.outputs.provider_mode == 'github_models' && github.token || steps.gate.outputs.provider_mode == 'openai_direct' && secrets.STRIX_OPENAI_API_KEY || '' }}
run: |
# Sanitize CR/LF before masking to prevent broken ::add-mask::
# commands and potential workflow command injection.
Expand All @@ -168,11 +185,15 @@ jobs:
- name: Prepare LLM API key input file
if: steps.gate.outputs.enabled == 'true'
env:
LLM_API_KEY_SECRET: ${{ steps.gate.outputs.provider_mode == 'openai_direct' && secrets.STRIX_OPENAI_API_KEY || '' }}
LLM_API_KEY_SECRET: ${{ steps.gate.outputs.provider_mode == 'github_models' && github.token || steps.gate.outputs.provider_mode == 'openai_direct' && secrets.STRIX_OPENAI_API_KEY || '' }}
PROVIDER_MODE: ${{ steps.gate.outputs.provider_mode }}
run: |
sanitized="$(printf '%s' "$LLM_API_KEY_SECRET" | tr -d '\r\n')"
trimmed="$(printf '%s' "$sanitized" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
if [ -z "$trimmed" ] && [ "$PROVIDER_MODE" = "github_models" ]; then
echo '::error::github.token is required for GitHub Models Strix scans.'
exit 1
fi
if [ -z "$trimmed" ] && [ "$PROVIDER_MODE" = "openai_direct" ]; then
echo '::error::STRIX_OPENAI_API_KEY is required for Strix OpenAI Platform scans.'
exit 1
Expand All @@ -182,6 +203,14 @@ jobs:
printf '%s' "$sanitized" > "$llm_api_key_file"
echo "LLM_API_KEY_FILE=$llm_api_key_file" >> "$GITHUB_ENV"

- name: Prepare GitHub Models API base
if: steps.gate.outputs.provider_mode == 'github_models'
run: |
umask 077
llm_api_base_file="$RUNNER_TEMP/llm_api_base.txt"
printf '%s' 'https://models.github.ai/inference' > "$llm_api_base_file"
echo "LLM_API_BASE_FILE=$llm_api_base_file" >> "$GITHUB_ENV"

- name: Prepare Vertex AI credentials
if: steps.gate.outputs.provider_mode == 'vertex_ai'
env:
Expand Down Expand Up @@ -213,12 +242,15 @@ jobs:
- name: Prepare Strix model input file
if: steps.gate.outputs.enabled == 'true'
env:
STRIX_MODEL: ${{ secrets.STRIX_LLM || 'vertex_ai/gemini-3.1-pro-preview-customtools' }}
STRIX_MODEL: ${{ github.event.inputs.strix_llm || 'openai/openai/gpt-4.1' }}
run: |
umask 077
strix_llm_file="$RUNNER_TEMP/strix_llm.txt"
strix_model="$(printf '%s' "$STRIX_MODEL" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
case "$strix_model" in
openai/openai/*)
printf '%s' "$strix_model" > "$strix_llm_file"
;;
openai/*)
printf '%s' "$strix_model" > "$strix_llm_file"
;;
Expand All @@ -229,7 +261,7 @@ jobs:
printf '%s' "$strix_model" > "$strix_llm_file"
;;
*)
echo '::error::STRIX_LLM must select direct OpenAI GPT-5.4 or newer, or an approved organization Vertex AI model.'
echo '::error::STRIX_LLM must select GitHub Models openai/openai/*, direct OpenAI GPT-5.4 or newer, or an approved organization Vertex AI model.'
exit 1
;;
esac
Expand All @@ -245,6 +277,7 @@ jobs:
working-directory: ${{ runner.temp }}/trusted-workspace
env:
STRIX_LLM_FILE: ${{ env.STRIX_LLM_FILE }}
LLM_API_BASE_FILE: ${{ env.LLM_API_BASE_FILE }}
STRIX_LLM_DEFAULT_PROVIDER: ${{ steps.gate.outputs.provider_mode == 'vertex_ai' && 'vertex_ai' || 'openai' }}
LLM_API_KEY_FILE: ${{ env.LLM_API_KEY_FILE }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ env.GOOGLE_APPLICATION_CREDENTIALS }}
Expand Down
28 changes: 16 additions & 12 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@
single files if that makes real repo modules look missing.
- Prefer upgrading or removing vulnerable dependencies over downgrading patched
packages unless compatibility evidence is recorded in the PR.
- Strix Security Scan must not route through GitHub Models, `github.token`,
generic `LLM_API_KEY`, GPT-4o, or GPT-4.1. The current organization-secret
route is `STRIX_LLM` with `GCP_SA_KEY`;
`vertex_ai/gemini-3.1-pro-preview-customtools` is the default approved Vertex
model now that organization-secret visibility is available, with
`vertex_ai/gemini-2.5-flash` allowed only as an explicit legacy selection.
Expose Google/Vertex credentials only for Vertex provider mode. Direct OpenAI
GPT-5.4-or-newer scans remain supported only when selected explicitly with
- Strix Security Scan uses GitHub Models by default through `github.token`,
`models: read`, `STRIX_LLM=openai/openai/gpt-4.1`, and
`LLM_API_BASE_FILE` pointing at a trusted file containing
`https://models.github.ai/inference`. Keep the GitHub Models endpoint in a
trusted input file and pass the token only through the
provider-scoped Strix child-process key path. Legacy `STRIX_LLM` secrets must
not override PR, push, or scheduled Strix defaults. Vertex remains available
only for manual `workflow_dispatch` evidence when the `strix_llm` input
explicitly selects `vertex_ai/gemini-3.1-pro-preview-customtools` or
`vertex_ai/gemini-2.5-flash` with `GCP_SA_KEY`; expose Google/Vertex
credentials only for Vertex provider mode. Direct OpenAI GPT-5.4-or-newer
scans remain supported only for manual `strix_llm` selections with
`STRIX_OPENAI_API_KEY`. Do not silently fall back between providers, and
do not treat timeout-class provider infrastructure failures as clean PR
evidence even when Strix printed zero vulnerabilities before failing. Disable
Expand All @@ -39,7 +43,7 @@
Strix in one scanner invocation; do not split changed files into separate
scanner runs because that breaks Strix's required whole-context contract. Keep
architecture docs and reusable Strix gate tests aligned with this rule so
stale GitHub Models, OpenAI-only, unavailable-model, blanket-warning, or
stale Vertex-default, OpenAI-only, unavailable-model, blanket-warning, or
generic-key examples cannot re-enter copied workflow guidance.
- HMAC fallback sessions are local/control-plane compatibility credentials, not
authoritative workspace-membership evidence. Sensitive tenant security posture
Expand Down Expand Up @@ -208,9 +212,9 @@
responses must include `Referrer-Policy`, and `target="_blank"` links must
use explicit `rel="noopener noreferrer"`.
- When robot review cites an obsolete Strix provider policy, update the docs and
tests to the current secret contract before accepting a rollback suggestion;
do not reintroduce generic `LLM_API_KEY`, GitHub Models, or cross-provider
credential forwarding while trying to satisfy old comments.
tests to the current GitHub Models default contract before accepting a
rollback suggestion; do not reintroduce generic `LLM_API_KEY` or
cross-provider credential forwarding while trying to satisfy old comments.
- When reviews find inert navigation/dead-space controls, either wire them to an
implemented workspace route/API or remove the control; do not leave
high-traffic drawer/sidebar entries as permanent `준비 중` copy.
Expand Down
20 changes: 13 additions & 7 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,19 @@ request branch scripts in the privileged Strix job.

The gate fails closed when a changed PR-head blob cannot be validated or copied;
it must never fall back to scanning trusted-base content for a modified PR path.
Pull request scans split scoped changed files into small bounded batches before
the timeout-driven rebalance path, so large PRs do not spend the whole required
check budget on one oversized Strix invocation. Strix remains a required
Medium-or-higher gate. The workflow uses only the explicit
`STRIX_OPENAI_API_KEY` OpenAI Platform credential with an OpenAI
GPT-5.4-or-newer model, rejects GitHub Models routing and `github.token` LLM
credentials, and fails closed when direct credentials are missing or exhausted.
Pull request scans present the generated PR-head scope to Strix in one
whole-context invocation, rather than splitting changed files into separate
scanner runs. Strix remains a required Medium-or-higher gate. The workflow
defaults to GitHub Models with
`models: read`, the workflow `github.token`, `STRIX_LLM=openai/openai/gpt-4.1`,
and `LLM_API_BASE_FILE` pointing at a trusted file containing
`https://models.github.ai/inference`, while keeping the token and API base
isolated to trusted input files and the Strix child-process environment. Legacy
`STRIX_LLM` secrets do not override PR, push, or scheduled
Strix defaults; explicit Vertex and direct OpenAI routes remain supported only
through manual `workflow_dispatch` `strix_llm` selections and their
provider-scoped credential paths. Provider infrastructure errors still fail
closed.
Merge-gate governance for Strix, CodeRabbit, and required review evidence is
documented in `docs/development/merge-gate-policy.md`.

Expand Down
41 changes: 24 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,32 @@ mail/calendar/file systems.
open-source observability.
- PR automation is metadata-only and uses current-head robot-review evidence plus
required checks. Human approval is not awaited by default under repo policy.
- Strix PR/security evidence uses the organization-secret provider selected by
`STRIX_LLM` with `GCP_SA_KEY`; missing `STRIX_LLM` defaults to the approved
`vertex_ai/gemini-3.1-pro-preview-customtools` Vertex route now that
organization-secret visibility is available. Direct OpenAI GPT-5.4-or-newer
remains supported only with an explicit `STRIX_OPENAI_API_KEY`. The workflow
fails closed rather than falling back to GitHub Models, `github.token`,
generic `LLM_API_KEY`, GPT-4-era models, or timeout-class provider
infrastructure failures. Known third-party Strix/Pydantic serializer warnings
are filtered narrowly instead of allowing Warn-class logs into passing
evidence, and runtime scan-budget variables are not listed as visible
timeout-named workflow `env:` entries. PR-scope scan budgets leave room for
report finalization after Strix emits completion events; workflow PR evidence
uses `STRIX_TARGET_PATH=__PR_SCOPE__` so the scanner target is the generated
- Strix PR/security evidence defaults to GitHub Models through
`STRIX_LLM=openai/openai/gpt-4.1`, `models: read`, `github.token`, and
`LLM_API_BASE_FILE` pointing at a trusted file containing
`https://models.github.ai/inference`. The workflow keeps that endpoint in a
trusted input file and passes the token only through the
provider-scoped Strix child-process key path. Legacy `STRIX_LLM` secrets do
not override PR, push, or scheduled Strix defaults. Vertex remains available
only for manual `workflow_dispatch` evidence when `strix_llm` explicitly
selects `vertex_ai/gemini-3.1-pro-preview-customtools` or
`vertex_ai/gemini-2.5-flash` with `GCP_SA_KEY`; direct OpenAI
GPT-5.4-or-newer remains supported only for manual `strix_llm` selections
with `STRIX_OPENAI_API_KEY`. The workflow fails closed rather than using generic
`LLM_API_KEY`, silently falling back across providers, or treating
timeout-class provider infrastructure failures as clean evidence. Known
third-party Strix/Pydantic serializer warnings are filtered narrowly instead
of allowing Warn-class logs into passing evidence, and runtime scan-budget
variables are not listed as visible timeout-named workflow `env:` entries.
PR-scope scan budgets leave room for report finalization after Strix emits
completion events; workflow PR evidence uses
`STRIX_TARGET_PATH=__PR_SCOPE__` so the scanner target is the generated
PR-head scope, not the trusted base checkout. Strix receives that complete
PR-head scope in one scanner invocation because its analysis contract depends
on the whole changed-file context. Scanner child processes disable
npm, pnpm, yarn, and bun lifecycle scripts while inspecting PR scope data.
Wrapper timeout output is failed evidence. Pending CodeRabbit or check
evidence is a wait state, not a hard blocker.
on the whole changed-file context. Scanner child processes disable npm, pnpm,
yarn, and bun lifecycle scripts while inspecting PR scope data. Wrapper
timeout output is failed evidence. Pending CodeRabbit or check evidence is a
wait state, not a hard blocker.
- Security governance is source-backed through signed
`/api/security/access-surface`. The endpoint reads scoped WebDAV, CalDAV, and
connector evidence plus durable `security_audit_events`, reuses the deny-first
Expand Down
13 changes: 9 additions & 4 deletions backend/tests/test_release_governance.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,21 +187,26 @@ def test_compose_log_scanner_exists_for_warning_policy() -> None:
assert "unexpected_count" in scanner


def test_strix_workflow_uses_configured_vertex_model_and_narrow_warning_filter() -> (
def test_strix_workflow_uses_github_models_default_and_narrow_warning_filter() -> (
None
):
workflow = read_repo_text(".github/workflows/strix.yml")
gate_script = read_repo_text("scripts/ci/strix_quick_gate.sh")

assert "models: read" not in workflow
assert "provider_mode=github_models" not in workflow
assert "models: read" in workflow
assert "provider_mode=github_models" in workflow
assert "strix_llm:" in workflow
assert "github.event.inputs.strix_llm || 'openai/openai/gpt-4.1'" in workflow
assert "secrets.STRIX_LLM ||" not in workflow
assert "https://models.github.ai/inference" in workflow
assert "LLM_API_BASE_FILE" in workflow
assert "github.token is required for GitHub Models Strix scans" in workflow
assert "vertex_ai/gemini-3.1-pro-preview-customtools" in workflow
assert (
"secrets.STRIX_LLM == 'vertex_ai/gemini-3.1-pro-preview-customtools' "
"&& 'vertex_ai/gemini-2.5-flash'"
not in workflow
)
assert "secrets.STRIX_LLM || 'vertex_ai/gemini-3.1-pro-preview-customtools'" in workflow
assert 'STRIX_FAIL_ON_PROVIDER_SIGNAL: "1"' in workflow
assert 'STRIX_VERTEX_FALLBACK_MODELS: ""' in workflow
assert (
Expand Down
10 changes: 5 additions & 5 deletions docs/plans/2026-05-19-north-star-gap-closure.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ connector, and PR governance is metadata-only.
the exact `Strix Security Scan` workflow, runs a trusted-base governance script,
separates pending/waiting states from failures, and updates an idempotent marker
comment instead of posting duplicates.
- [x] Strix provider hardening: the workflow fails closed instead of routing
scanner traffic through GitHub Models, `github.token`, generic `LLM_API_KEY`,
GPT-4o, or GPT-4.1. The current approved default is the validated
org-secret Vertex AI model, while direct OpenAI GPT-5.4+ remains
explicit-only through `STRIX_OPENAI_API_KEY`.
- [x] Strix provider hardening: the workflow now defaults to GitHub Models via
`models: read`, `github.token`, and a trusted `LLM_API_BASE` input file while
still failing closed on generic `LLM_API_KEY`, cross-provider fallback, and
provider infrastructure failures. Vertex and direct OpenAI remain
explicit-only alternate provider paths.
- [x] CalDAV source registry: `/api/calendar/writeback-intent` now resolves
DB-backed `calendar_writeback_sources` rows with opaque `source_uid` values
instead of exposing sequential CalDAV account ids or accepting browser-supplied
Expand Down
3 changes: 2 additions & 1 deletion docs/plans/2026-05-27-apm-connector-operational-signals.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ exist yet.

- No IMAP/SMTP/CalDAV/WebDAV provider execution.
- No Naruon-hosted mailbox/storage claim.
- No GitHub Models routing for Strix or security scans.
- No generic LLM credentials or cross-provider fallback for Strix or security
scans.
- No queue-depth, provider-throttling, sync-lag, or writeback-conflict
execution events until source-backed connector jobs emit them.

Expand Down
12 changes: 6 additions & 6 deletions docs/plans/2026-05-27-self-sent-webdav-materialization-intent.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ Browser evidence to inspect:

## Governance

- Strix follows the current provider governance contract: the approved default
is the validated org-secret Vertex AI model `vertex_ai/gemini-2.5-flash`,
while direct OpenAI GPT-5.4+ remains explicit-only through
`STRIX_OPENAI_API_KEY`.
- GitHub Models, `github.token`, generic `LLM_API_KEY`, arbitrary
Gemini/Vertex fallback, GPT-4o, and GPT-4.1 are not valid Strix routes.
- Strix follows the current provider governance contract: GitHub Models is the
default via `models: read`, `github.token`, and a trusted `LLM_API_BASE`
input file, while Vertex and direct OpenAI remain explicit-only provider
paths.
- Generic `LLM_API_KEY`, arbitrary Gemini/Vertex fallback, and cross-provider
credential forwarding are not valid Strix routes.
Loading
Loading