fix(ci): close docker_smoke.sh's stdin-before-drain race #155
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
| # Conformance with the upstream codebase-intelligence identity contract. | |
| # | |
| # Cortex resolves that server three ways (release asset, marketplace install, | |
| # PATH lookup) and validates the resolved command against a security allowlist. | |
| # Those names used to be hardcoded in five modules; when upstream renamed its | |
| # binary, only some copies were updated and every ingest failed with "Command | |
| # not in allowed list" (CHANGELOG 3.14.11). The 2026-08 rename to | |
| # ai-architect-mcp-codebase repeated it: the marketplace key filter matched | |
| # nothing, so the AST layer disappeared with no error at all. | |
| # | |
| # The names now live in mcp_server/infrastructure/upstream_identity.py. This | |
| # job proves that module still agrees with what upstream publishes, so a future | |
| # rename fails here instead of silently degrading a user's session. | |
| # | |
| # The contract URL is pinned to a full commit SHA, not a tag: the producer's | |
| # README is explicit that tags can be moved. | |
| name: Upstream identity | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| schedule: | |
| # Weekly: catches a revocation published between our commits. | |
| - cron: "23 6 * * 1" | |
| permissions: | |
| contents: read | |
| jobs: | |
| contract: | |
| name: agree with the upstream identity contract | |
| runs-on: ubuntu-latest | |
| env: | |
| CONTRACT_URL: https://raw.githubusercontent.com/cdeust/ai-architect-mcp-codebase/37728cc5747cebe39ea9d4011b7424de90f0a57b/mcp-contract.json | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.12" | |
| - name: Fetch the pinned contract | |
| run: | | |
| set -euo pipefail | |
| # Outside the working tree: the contract lists revoked prefixes, and | |
| # a scan of the repo must not find them in a file we just wrote. | |
| curl --fail --location --silent --show-error \ | |
| --connect-timeout 5 --max-time 30 --retry 2 \ | |
| "$CONTRACT_URL" -o "$RUNNER_TEMP/contract.json" | |
| - name: upstream_identity must match the contract | |
| run: | | |
| set -euo pipefail | |
| python - "$RUNNER_TEMP/contract.json" <<'PY' | |
| import json, sys | |
| from mcp_server.infrastructure import upstream_identity as u | |
| contract = json.load(open(sys.argv[1], encoding="utf-8")) | |
| if contract["schema_version"] != 1: | |
| sys.exit(f"unsupported contract schema_version: {contract['schema_version']}") | |
| plugin = contract["claude_plugin"] | |
| marketplace = contract["claude_marketplace"] | |
| derived = f"mcp__plugin_{plugin}_{contract['mcp_server']}__" | |
| if derived != contract["claude_tool_prefix"]: | |
| sys.exit("contract is internally inconsistent") | |
| problems = [] | |
| if u.CANONICAL_PLUGIN != plugin: | |
| problems.append(f"CANONICAL_PLUGIN={u.CANONICAL_PLUGIN!r} != {plugin!r}") | |
| if u.CANONICAL_MARKETPLACE != marketplace: | |
| problems.append(f"CANONICAL_MARKETPLACE={u.CANONICAL_MARKETPLACE!r} != {marketplace!r}") | |
| if u.CANONICAL_PLUGIN_KEY != f"{plugin}@{marketplace}": | |
| problems.append(f"CANONICAL_PLUGIN_KEY={u.CANONICAL_PLUGIN_KEY!r}") | |
| if u.CANONICAL_BINARY != contract["distribution"]: | |
| problems.append(f"CANONICAL_BINARY={u.CANONICAL_BINARY!r} != {contract['distribution']!r}") | |
| # The canonical name must be first everywhere it is offered as a | |
| # candidate: a legacy install must never win over a current one. | |
| if u.BINARY_NAMES[0] != u.CANONICAL_BINARY: | |
| problems.append("BINARY_NAMES does not lead with the canonical binary") | |
| if u.PLUGIN_KEY_BINARIES[0][0] != u.CANONICAL_PLUGIN_KEY: | |
| problems.append("PLUGIN_KEY_BINARIES does not lead with the canonical key") | |
| # A legacy entry that equals the canonical one is a silent no-op | |
| # fallback — the shape this module exists to prevent. | |
| if u.CANONICAL_BINARY in u.LEGACY_BINARIES: | |
| problems.append("LEGACY_BINARIES duplicates the canonical binary") | |
| if u.CANONICAL_PLUGIN_KEY in u.LEGACY_PLUGIN_KEYS: | |
| problems.append("LEGACY_PLUGIN_KEYS duplicates the canonical key") | |
| if u.CANONICAL_BINARY not in u.ALLOWED_UPSTREAM_COMMANDS: | |
| problems.append("the canonical binary is not in the security allowlist") | |
| if problems: | |
| sys.exit("upstream_identity drifted from the contract:\n " + "\n ".join(problems)) | |
| print(f"upstream_identity agrees with the contract: {plugin} / {u.CANONICAL_BINARY}") | |
| PY | |
| - name: No revoked tool prefix anywhere in the tree | |
| run: | | |
| set -euo pipefail | |
| status=0 | |
| while read -r revoked; do | |
| # -e carries the pattern: `--` would end option parsing and turn | |
| # the --exclude-dir flags into path operands. | |
| hits=$(grep -rn --binary-files=without-match \ | |
| --exclude-dir=.git --exclude-dir=.github \ | |
| -e "$revoked" . \ | |
| | grep -v 'identity-allow-legacy' || true) | |
| if [ -n "$hits" ]; then | |
| echo "::error::revoked upstream prefix present: $revoked" | |
| printf '%s\n' "$hits" | |
| status=1 | |
| fi | |
| done < <(python -c 'import json,sys;[print(p) for p in json.load(open(sys.argv[1]))["revoked_claude_tool_prefixes"]]' "$RUNNER_TEMP/contract.json") | |
| exit $status |