Files
molecule-ai-workspace-runtime/.gitea/workflows/consumer-drift.yml
T
hongming-ceo-delegated f17798cd82
ci / obs-smoke (pull_request) Successful in 4s
lint-infisical-extractor / lint-infisical-extractor (pull_request) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
ci / lint (pull_request) Successful in 17s
ci / build (pull_request) Successful in 35s
ci / smoke-install (pull_request) Successful in 1m7s
ci / unit-tests (pull_request) Successful in 1m40s
ci / responsiveness-e2e (pull_request) Successful in 1m53s
Replace AST comm-contract guard with offline schema-conformance gate
Retire the cross-repo AST drift-checker
(scripts/check_platform_comm_contract.py + its tests) and replace it with an
in-repo, offline payload-vs-schema conformance gate that validates the REAL
register / heartbeat / A2A-envelope payloads the runtime puts on the wire
against the SSOT JSON-Schema (draft 2020-12) promoted into
molecule-contracts/workspace-comms.

Why this is strictly stronger than the AST guard:
- Validates the actual produced bytes (driven through the real
  register_with_platform POST site, HeartbeatLoop._send_heartbeat body builder,
  and build_message_send_params), not a code structure a refactor could satisfy
  while still emitting a non-conformant body.
- Runs fully offline in the normal unit-test lane: no cross-repo clone, no
  GITEA_TOKEN, and it never silently SKIPs (the AST step skipped whenever the
  Infisical bootstrap creds were absent).

Details:
- tests/test_workspace_comms_conformance.py: 3 positive (real-payload) + 4
  negative (anti-vacuous: type-keyed A2A part #2345, missing workspace_id, bad
  kind enum, non-allowlisted extra field) + schema-canonicality tripwires.
- tests/fixtures/workspace_comms/*.schema.json: byte-identical SSOT mirror of
  molecule-contracts/workspace-comms (see PROVENANCE.md); $id tripwire guards
  against silent drift.
- The runtime layers a documented runtime-only diagnostic (platform_mcp_diag,
  server-ignored, deliberately absent from the SSOT request schema) via
  identity_gate_payload(); the gate strips ONLY that explicit allowlist before
  validating, so every other field is still strictly checked
  (additionalProperties:false).
- jsonschema added to a [test] extra; ci.yml unit-tests installs .[test].
- consumer-drift.yml: drop the retired AST-checker step (kept the consumer
  source-vendoring check). test_workflow_no_token_in_url.py: drop the removed
  script from the GIT_ASKPASS expected set.

A sibling conformance gate lands in molecule-ai-sdk.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 23:21:54 -07:00

102 lines
5.6 KiB
YAML

name: consumer-drift
on:
push:
branches: [main]
schedule:
- cron: "17 10 * * *"
workflow_dispatch:
permissions:
contents: read
jobs:
runtime-ssot-consumers:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
# CI bot-token consolidation (RFC: Gitea-Actions-secrets -> Infisical/KMS,
# mirrors #971 / #3274): source the molecule-runtime-release-bot token from
# the Infisical SSOT (/shared/runtime-bot, key RUNTIME_BOT_TOKEN) via the CI
# machine identity, instead of the per-repo Gitea Actions secret
# DISPATCH_TOKEN. The fetched value is exported to $GITHUB_ENV under
# GITEA_TOKEN — the exact env var name the consumer step below
# (check_consumer_runtime_drift.py) already reads — so nothing downstream
# changes.
#
# ABSENT -> SKIP DEGRADE PRESERVED (runtime#83): a missing token is a config
# gap, not a runtime regression. If the bootstrap INFISICAL_CI_* creds are
# absent (the genuine config-gap scenario), this step warns and exports
# nothing, so the downstream `[ -z "${GITEA_TOKEN:-}" ]` checks SKIP the
# cross-repo work rather than painting runtime main red. But when the creds
# ARE present, Infisical is AUTHORITATIVE: a broken/empty/404 fetch
# hard-fails here so a broken migration can never masquerade as a green skip.
- name: Fetch RUNTIME_BOT_TOKEN from Infisical SSOT
id: runtime_bot_token
env:
INFISICAL_CI_CLIENT_ID: ${{ secrets.INFISICAL_CI_CLIENT_ID }}
INFISICAL_CI_CLIENT_SECRET: ${{ secrets.INFISICAL_CI_CLIENT_SECRET }}
INFISICAL_PROJECT_ID: ${{ secrets.INFISICAL_CI_PROJECT_ID }}
run: |
set -uo pipefail
if [ -z "${INFISICAL_CI_CLIENT_ID:-}" ] || [ -z "${INFISICAL_CI_CLIENT_SECRET:-}" ] || [ -z "${INFISICAL_PROJECT_ID:-}" ]; then
echo "::warning::INFISICAL_CI_* bootstrap creds absent; cannot fetch RUNTIME_BOT_TOKEN. Skipping cross-repo consumer-drift checks (config gap, runtime#83) rather than failing red. Provision INFISICAL_CI_CLIENT_ID/_CLIENT_SECRET/_PROJECT_ID to enable."
exit 0
fi
BASE="https://key.moleculesai.app"
TOK=$(curl -fsS -X POST "$BASE/api/v1/auth/universal-auth/login" \
-H 'Content-Type: application/json' \
-d "{\"clientId\":\"$INFISICAL_CI_CLIENT_ID\",\"clientSecret\":\"$INFISICAL_CI_CLIENT_SECRET\"}" \
| python3 -c 'import sys,json;d=json.load(sys.stdin);v=d.get("accessToken");print(v if isinstance(v,str) and v else "")')
if [ -z "${TOK}" ]; then
echo "::error::Infisical universal-auth login returned no accessToken -- creds present but auth failed; this is a real infra fault, failing loudly instead of skipping." >&2
exit 1
fi
read_secret() {
curl -fsS "$BASE/api/v3/secrets/raw/$1?workspaceId=$INFISICAL_PROJECT_ID&environment=prod&secretPath=$2" \
-H "Authorization: Bearer $TOK" \
| python3 -c 'import sys,json;d=json.load(sys.stdin);v=(d.get("secret") or {}).get("secretValue");print(v if isinstance(v,str) and v else "")'
}
RUNTIME_BOT_TOKEN=$(read_secret RUNTIME_BOT_TOKEN %2Fshared%2Fruntime-bot)
if [ -z "${RUNTIME_BOT_TOKEN}" ]; then
echo "::error::Infisical returned empty for RUNTIME_BOT_TOKEN at /shared/runtime-bot (prod) -- creds present but authoritative fetch failed; failing loudly so a broken migration cannot masquerade as a green skip." >&2
exit 1
fi
echo "::add-mask::$RUNTIME_BOT_TOKEN"
# Export under GITEA_TOKEN — the name both consumer steps + scripts expect.
echo "GITEA_TOKEN=$RUNTIME_BOT_TOKEN" >> "$GITHUB_ENV"
echo "RUNTIME_BOT_TOKEN loaded from Infisical /shared/runtime-bot (non-empty, len=${#RUNTIME_BOT_TOKEN})"
- name: Check consumers do not vendor runtime source
env:
GITEA_TOKEN: ${{ env.GITEA_TOKEN }}
run: |
# runtime#83: a missing token is a config gap, not a runtime
# regression. Without the token we cannot clone the private consumer
# repos, so this cross-repo check is SKIPPED with a loud warning rather
# than painting runtime main red. When the token is present (now sourced
# from the Infisical SSOT /shared/runtime-bot by the fetch step above and
# exported to $GITHUB_ENV as GITEA_TOKEN), run it for real and let real
# drift fail the job.
if [ -z "${GITEA_TOKEN:-}" ]; then
echo "::warning::RUNTIME_BOT_TOKEN unavailable (Infisical fetch skipped on absent bootstrap creds); skipping cross-repo consumer drift check. Provision INFISICAL_CI_* to enable it (runtime#83)."
else
python scripts/check_consumer_runtime_drift.py
fi
# NOTE: the cross-repo platform-communication-contract AST guard
# (scripts/check_platform_comm_contract.py) was RETIRED — replaced by an
# in-repo, offline schema-conformance gate that validates the REAL
# register/heartbeat/A2A wire payloads against the SSOT JSON-Schema
# (molecule-contracts/workspace-comms), run as part of the normal unit-test
# lane (tests/test_workspace_comms_conformance.py in ci.yml). That gate is
# strictly stronger (real bytes vs code structure), needs no cross-repo
# clone or token, and never silently SKIPs. The SDK side carries a sibling
# conformance test in molecule-ai-sdk.