diff --git a/.secrets.baseline b/.secrets.baseline index b5eeff6b..0dcca99a 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -171,7 +171,7 @@ { "type": "Secret Keyword", "filename": "yuqei-ai-platform/services/ai-platform-api/tests/test_platform_data.py", - "hashed_secret": "944e39e8ed4859e0901b7ca0830067a935c1587d", + "hashed_secret": "f8843a16172173b7829ae8e358969e604e792eab", "line_number": 165, "is_secret": false, "audit_reason": "Synthetic OCR secret reference used by a unit test." @@ -190,7 +190,7 @@ "type": "Secret Keyword", "filename": "yuqei-ai-platform/services/ai-platform-api/tests/test_provider_flow.py", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", - "line_number": 55, + "line_number": 67, "is_secret": false, "audit_reason": "Synthetic provider key used by a mocked unit test." }, @@ -198,7 +198,7 @@ "type": "Secret Keyword", "filename": "yuqei-ai-platform/services/ai-platform-api/tests/test_provider_flow.py", "hashed_secret": "dfd7a37d1dc759fc860644d608aa5d8ad9b53c96", - "line_number": 201, + "line_number": 213, "is_secret": false, "audit_reason": "Synthetic environment secret reference used by a unit test." } @@ -228,7 +228,7 @@ "type": "Basic Auth Credentials", "filename": "yuqei-contract-platform/services/contract-api/.env.example", "hashed_secret": "7205a0abf00d1daec13c63ece029057c974795a9", - "line_number": 17, + "line_number": 30, "is_secret": false, "audit_reason": "Production example uses the explicit CHANGE_ME placeholder." } @@ -251,6 +251,14 @@ "line_number": 808, "is_secret": false, "audit_reason": "Contract template identifier in a test request path." + }, + { + "type": "Secret Keyword", + "filename": "yuqei-contract-platform/services/contract-api/tests/test_contract_workflow.py", + "hashed_secret": "3e3a880564d6961104d8ca9e82190ef682b3d11a", + "line_number": 2397, + "is_secret": false, + "audit_reason": "Synthetic AI service key asserted by a mocked review worker test." } ], "yuqei-contract-platform/services/contract-api/tests/test_health.py": [ @@ -284,7 +292,7 @@ "type": "Secret Keyword", "filename": "yuqei-contract-platform/services/contract-api/tests/test_identity_management.py", "hashed_secret": "2585823c3e56d65632eff0c1eb7f8fffa0736cb3", - "line_number": 188, + "line_number": 189, "is_secret": false, "audit_reason": "Synthetic invite password used by an identity test." }, @@ -292,7 +300,7 @@ "type": "Secret Keyword", "filename": "yuqei-contract-platform/services/contract-api/tests/test_identity_management.py", "hashed_secret": "d26b0b74aaf44561a94d607e9d73e4dc6b95fe3d", - "line_number": 241, + "line_number": 242, "is_secret": false, "audit_reason": "Synthetic tenant-owner password used by an identity test." }, @@ -300,7 +308,7 @@ "type": "Secret Keyword", "filename": "yuqei-contract-platform/services/contract-api/tests/test_identity_management.py", "hashed_secret": "42f6c37f356183f42a67d9e0ae515bb51d7590cf", - "line_number": 280, + "line_number": 281, "is_secret": false, "audit_reason": "Synthetic old-password fixture used by a reset test." }, @@ -308,7 +316,7 @@ "type": "Secret Keyword", "filename": "yuqei-contract-platform/services/contract-api/tests/test_identity_management.py", "hashed_secret": "a55a3986a699ba4d2b29b2057811322bf076abd0", - "line_number": 299, + "line_number": 300, "is_secret": false, "audit_reason": "Synthetic new-password fixture used by a reset test." } @@ -318,7 +326,7 @@ "type": "Basic Auth Credentials", "filename": "yuqei-infra/compose/.env.example", "hashed_secret": "964a0c3a014c640b82d5ab59c4665a323d20a880", - "line_number": 22, + "line_number": 24, "is_secret": false, "audit_reason": "Documented local compose credentials." } @@ -328,7 +336,7 @@ "type": "Basic Auth Credentials", "filename": "yuqei-infra/compose/.env.production.example", "hashed_secret": "7205a0abf00d1daec13c63ece029057c974795a9", - "line_number": 24, + "line_number": 63, "is_secret": false, "audit_reason": "Production example uses explicit CHANGE_ME placeholders." } @@ -338,7 +346,7 @@ "type": "Basic Auth Credentials", "filename": "yuqei-infra/compose/docker-compose.yml", "hashed_secret": "964a0c3a014c640b82d5ab59c4665a323d20a880", - "line_number": 78, + "line_number": 83, "is_secret": false, "audit_reason": "Documented local compose fallback credentials." } @@ -348,10 +356,68 @@ "type": "Basic Auth Credentials", "filename": "yuqei-infra/scripts/deploy-v2-smoke-docker.ps1", "hashed_secret": "f3ae48aa9b0d4eaec403d0f4b9cf89527def9aec", - "line_number": 340, + "line_number": 354, "is_secret": false, "audit_reason": "Isolated smoke-only database credentials generated by the deploy script." } + ], + "yuqei-infra/tests/test_production_release_tools.py": [ + { + "type": "Secret Keyword", + "filename": "yuqei-infra/tests/test_production_release_tools.py", + "hashed_secret": "53dc84fccc33570defe1f39cf9612ce69ac7424a", + "line_number": 48, + "is_secret": false, + "audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test." + }, + { + "type": "Secret Keyword", + "filename": "yuqei-infra/tests/test_production_release_tools.py", + "hashed_secret": "05d90b39f109a93348186597904cd4f49152d061", + "line_number": 50, + "is_secret": false, + "audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test." + }, + { + "type": "Secret Keyword", + "filename": "yuqei-infra/tests/test_production_release_tools.py", + "hashed_secret": "a5e7de418383e7e8471cc9a21992ce0daafab40f", + "line_number": 51, + "is_secret": false, + "audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test." + }, + { + "type": "Secret Keyword", + "filename": "yuqei-infra/tests/test_production_release_tools.py", + "hashed_secret": "b5631d35d843013925a520542e7955d954e6b153", + "line_number": 52, + "is_secret": false, + "audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test." + }, + { + "type": "Secret Keyword", + "filename": "yuqei-infra/tests/test_production_release_tools.py", + "hashed_secret": "25c5fef49509171e38e408bc6dacd86b50a890e5", + "line_number": 53, + "is_secret": false, + "audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test." + }, + { + "type": "Secret Keyword", + "filename": "yuqei-infra/tests/test_production_release_tools.py", + "hashed_secret": "5653faf32e2d189e6b2ee91e022735727a89ba7b", + "line_number": 54, + "is_secret": false, + "audit_reason": "Synthetic production-preflight secret placeholder used by an infrastructure test." + }, + { + "type": "Basic Auth Credentials", + "filename": "yuqei-infra/tests/test_production_release_tools.py", + "hashed_secret": "2aeae636ff10256fe811ae406cc7aba633b55626", + "line_number": 55, + "is_secret": false, + "audit_reason": "Synthetic PostgreSQL URL with a placeholder password used by an infrastructure test." + } ] } } diff --git a/project-docs/V2-rc-freeze-2026-07-20.md b/project-docs/V2-rc-freeze-2026-07-20.md index ad870900..606a371c 100644 --- a/project-docs/V2-rc-freeze-2026-07-20.md +++ b/project-docs/V2-rc-freeze-2026-07-20.md @@ -2,7 +2,7 @@ ## Decision -The current candidate is frozen for release review under tag `v2-rc-20260720.1`. +The current candidate is frozen for release review under tag `v2-rc-20260720.2`. After the tag is created, only blocking bug fixes, tests, deployment configuration, and release documentation may be added. New product features and schema changes are outside this RC. @@ -25,10 +25,11 @@ deployment/backup/health-check tooling, AI Provider acceptance tooling, authenti review-worker integration, ambient-proxy isolation for internal AI Platform calls, and per-key single-flight protection for Contract API read-cache misses. -Tag `v2-rc-20260720.1` supersedes `v2-rc-20260720`. The original tag remains -immutable; the only follow-up change pins the CI pip index to the same mirror already -validated by the smoke deployment, preventing official-PyPI throughput from blocking -the Python and security jobs before tests begin. +Tag `v2-rc-20260720.2` supersedes `v2-rc-20260720.1` and `v2-rc-20260720`. +The earlier tags remain immutable. This follow-up fixes a cross-platform source-scan +gap by forcing the detect-secrets subprocess to read UTF-8 on Windows, and refreshes +the reviewed baseline from the complete Linux-equivalent scan. It also adds a focused +regression test so files containing non-GBK text cannot be silently skipped. ## Verification evidence @@ -39,7 +40,7 @@ the Python and security jobs before tests begin. | AI Platform schema-check | Pass; only the intentional smoke `provider_runtime` warning | `project-docs/qa-artifacts/v2-release-quality-gate/2026-07-20T18-20-08/ai_platform_api-schema-check.json` | | Release quality gate | Pass | `project-docs/qa-artifacts/v2-release-quality-gate/2026-07-20T18-20-08` | | Remote core user flow | Pass; browser console errors 0 | `project-docs/qa-artifacts/v2-core-regression/2026-07-20-smoke-pass2/core-user-flow-summary.json` | -| Source secret scan | Pass; 15 reviewed candidates, 0 new findings | `project-docs/qa-artifacts/v2-source-secret-scan/2026-07-20T18-40-00/source-secret-scan-summary.json` | +| Source secret scan | Pass; 46 reviewed candidates, 0 new findings, 0 stale baseline entries | `project-docs/qa-artifacts/v2-source-secret-scan/2026-07-20T21-07-30/source-secret-scan-summary.json` | | Security scan | Pass; npm 0, Bandit 0, pip-audit 0 | `project-docs/qa-artifacts/v2-security-scan/2026-07-20T18-45-00` | Local verification also passed the complete Contract API suite, AI Platform API, diff --git a/yuqei-infra/scripts/run-source-secret-scan.py b/yuqei-infra/scripts/run-source-secret-scan.py index c144e396..f7808ca9 100644 --- a/yuqei-infra/scripts/run-source-secret-scan.py +++ b/yuqei-infra/scripts/run-source-secret-scan.py @@ -2,6 +2,7 @@ from __future__ import annotations import argparse import json +import os import subprocess import sys from datetime import datetime @@ -112,6 +113,9 @@ def _run_detect_secrets(include_untracked: bool) -> dict[str, Any]: capture_output=True, text=True, encoding="utf-8", + # detect-secrets opens source files with the process locale; keep Windows scans + # equivalent to the UTF-8 Linux CI scan instead of silently skipping files. + env={**os.environ, "PYTHONUTF8": "1"}, ) if completed.returncode != 0: raise RuntimeError(completed.stderr.strip() or "detect-secrets failed without diagnostic output") diff --git a/yuqei-infra/tests/test_source_secret_scan.py b/yuqei-infra/tests/test_source_secret_scan.py new file mode 100644 index 00000000..5566b38b --- /dev/null +++ b/yuqei-infra/tests/test_source_secret_scan.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +import importlib.util +import json +import sys +from pathlib import Path +from types import ModuleType, SimpleNamespace + + +REPO_ROOT = Path(__file__).resolve().parents[2] + + +def load_script(name: str, relative_path: str) -> ModuleType: + path = REPO_ROOT / relative_path + spec = importlib.util.spec_from_file_location(name, path) + assert spec and spec.loader + module = importlib.util.module_from_spec(spec) + sys.modules[name] = module + spec.loader.exec_module(module) + return module + + +source_scan = load_script( + "yuqei_source_secret_scan", + "yuqei-infra/scripts/run-source-secret-scan.py", +) + + +def test_source_secret_scan_forces_utf8_for_detect_secrets(monkeypatch) -> None: + captured: dict[str, object] = {} + + def fake_run(command, **kwargs): + captured["command"] = command + captured.update(kwargs) + return SimpleNamespace( + returncode=0, + stdout=json.dumps({"results": {}}), + stderr="", + ) + + monkeypatch.setattr(source_scan.subprocess, "run", fake_run) + + assert source_scan._run_detect_secrets(False) == {"results": {}} + assert captured["env"]["PYTHONUTF8"] == "1"