From 8fb6b65b01b7f0064fe11e024ead4ba696fcf8bc Mon Sep 17 00:00:00 2001 From: Jesse Date: Mon, 10 Aug 2026 17:57:06 +0800 Subject: [PATCH] wip: local BUG-139/BUG-140 fixes before syncing origin/main - pre_work_check.py: prefer repo .venv Python >=3.11, strict JYOTISH_PRE_WORK_PYTHON override, fail closed - tests/test_pre_work_check.py: regression coverage for venv preference / system 3.9 / strict override - globals.css: transient :active pressed feedback for entrypoint cards, hover only under (hover: hover) - consultation-entrypoint.test.ts: sticky-hover regression test - BUG_HISTORY.md: BUG-139 / BUG-140 records - pre_work_error_ledger.md: ERR-078 resolved entry --- docs/BUG_HISTORY.md | 32 +++++ docs/research/pre_work_error_ledger.md | 2 +- frontend/src/app/globals.css | 46 ++++--- .../tests/consultation-entrypoint.test.ts | 16 +++ scripts/pre_work_check.py | 129 +++++++++++++++++- tests/test_pre_work_check.py | 54 ++++++++ 6 files changed, 252 insertions(+), 27 deletions(-) diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index cbf194cf..ad7f0d2c 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -2384,3 +2384,35 @@ - 相关记录:BUG-134、BUG-137、ERR-097、ERR-100、ERR-101 - 复发自:无 - 修复版本:`6c1dcbe857006ec6ae7463b57b2b7d5947da4851` + +## BUG-139 | 系统 Python 启动预检时重复使用不兼容解释器 + +- 状态:resolved +- 首次发现:2026-08-07 +- 最近更新:2026-08-07 +- 影响面:`scripts/pre_work_check.py`、开工预检、碎片扫描与聚焦治理测试 +- 用户现象:每次执行文档规定的 `python3 scripts/pre_work_check.py ...`,碎片扫描都会因 Python 3.9 不支持项目使用的 PEP 604 类型注解而退出,聚焦测试同时报 `/usr/bin/python3: No module named pytest`。 +- 触发条件:macOS 的裸 `python3` 指向 `/usr/bin/python3` 3.9,而仓库 `.venv` 已安装 Python 3.11 与 pytest。 +- 根因:预检脚本把启动自身的 `sys.executable` 固定为全部子命令的解释器,没有验证项目声明的 Python >=3.11,也没有优先使用仓库虚拟环境;`ERR-078` 原防线只要求操作者手动改用 `.venv`,因此文档中的标准命令仍会稳定复发。 +- 修复:预检入口按确定顺序探测项目 `.venv`、当前解释器和可用的 Python 3.11+;只有同时满足 Python >=3.11 与 pytest 可用才执行全部 Python 子检查。报告显式记录选择结果和各候选探测信息;找不到兼容环境时失败闭合并给出安装指引。新增严格的 `JYOTISH_PRE_WORK_PYTHON` 覆盖入口,配置错误时不静默退回其他解释器。 +- 验证:`tests/test_pre_work_check.py` 覆盖虚拟环境优先、系统 3.9 跳过、严格 override 和 runtime failure 状态;使用裸 `/usr/bin/python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45` 完整通过,报告选择仓库 `.venv/bin/python` 3.11 且 focused governance tests 通过。 +- 防复发:预检不得再直接用未经探测的 `sys.executable` 启动项目脚本或 pytest;标准文档命令必须纳入真实系统 Python 启动回归,且 JSON 报告必须保留 `python_runtime_ok` 和实际解释器信息。 +- 相关记录:ERR-011、ERR-014、ERR-078 +- 复发自:无 +- 修复版本:待提交 + +## BUG-140 | 首页入口卡片点击后持续显示灰色交互态 + +- 状态:resolved +- 首次发现:2026-08-07 +- 最近更新:2026-08-07 +- 影响面:首页 `starter-theme-card`、`daily-starlanguage-card` 与共享 `product-entrypoint-card` 交互反馈 +- 用户现象:用户点击首页主题或产品入口卡片后,卡片背景持续处于灰色/选中样式,没有在松开指针后恢复。 +- 触发条件:在触摸设备点击卡片,或在桌面端点击后让指针继续停留在卡片上。 +- 根因:卡片把铺满表面的背景反馈绑定到无设备能力边界的 `:hover`;移动浏览器可能在点击后保留模拟 hover,桌面指针停留也会让一次点击看起来像永久选中。`hover`、短暂按压和真实 disabled 三种状态因此在视觉上混在一起。 +- 修复:将铺灰背景收敛到 `:active`,只在按压期间显示并于释放后恢复;桌面 `@media (hover: hover)` 只保留轻量边框、光泽和箭头位移,不再改变卡片底色;键盘继续使用现有 `focus-visible` 轮廓,真实 disabled 透明度规则保持不变。 +- 验证:`frontend/tests/consultation-entrypoint.test.ts` 新增 sticky-hover 回归;与 `frontend/tests/starter-questions.test.ts` 精确运行 40/40 通过;目标 ESLint 与 `git diff --check` 通过。全量前端尝试中 1457 项通过,16 项因本机缺少 Docker 或 `python` 可执行命令而失败,与本次 CSS 修改无关。 +- 防复发:首页可点击卡片的表面底色只能由短暂 `:active` 或真实业务 disabled 状态改变;hover 视觉必须限制在支持 hover 的设备,且回归测试禁止重新为这些卡片的 hover surface 添加背景色。 +- 相关记录:无 +- 复发自:无 +- 修复版本:待提交 diff --git a/docs/research/pre_work_error_ledger.md b/docs/research/pre_work_error_ledger.md index 20106b5d..d4d50769 100644 --- a/docs/research/pre_work_error_ledger.md +++ b/docs/research/pre_work_error_ledger.md @@ -108,7 +108,7 @@ For large architecture or release work, also read: | ERR-075 | `real_case_calibration_catalog()` unconditionally opened an untracked holdout manifest, so clean installs could silently lose the MCP runtime evidence log. | resolved 2026-07-16 | Missing optional holdout assets return structured `blocked` metadata instead of raising. | | ERR-076 | Fragment/inventory tests required machine-local drafts, workspace residue, or a fixed minimum file count. | resolved 2026-07-16 | Assert count invariants and stable tracked classifications; validate optional local categories only when present. | | ERR-077 | VedAstro request previews serialized the live `x-api-key` header, allowing logs and failed test output to expose credentials. | resolved; credential rotation required 2026-07-16 | Preview/metadata profiles never contain authentication headers. Inject `VEDASTRO_API_KEY` only immediately before network execution; rotate any key exposed before this fix. | -| ERR-078 | On this macOS host, bare `python3` resolves to Python 3.9 without pytest, while the project uses PEP 604 annotations; rerunning with `.venv/bin/python` reaches the tests but `test_preflight_fragment_scan_reports_authority_layers_and_risk_buckets` has a stale `high_value_unpromoted_count >= 1` assertion even when the scanner correctly reports zero. | observed 2026-07-15 | Run the gate with the project venv on this host and do not claim the full pre-work gate passed until the fragment-governance assertion is reconciled with the valid zero-unpromoted state. | +| ERR-078 | On this macOS host, bare `python3` resolves to Python 3.9 without pytest, while the project requires Python >=3.11 and uses PEP 604 annotations. The pre-work launcher previously reused that incompatible interpreter for every child check. | resolved 2026-08-07 | `pre_work_check.py` must probe and prefer the repository `.venv` (Python >=3.11 with pytest), expose the selected runtime in its JSON report, and fail closed with setup guidance if no compatible runtime exists. Keep regression coverage for system-Python launch and strict `JYOTISH_PRE_WORK_PYTHON` override behavior. | | ERR-079 | VedAstro hosted replay and fixed-commit self-host validation cannot run on this host when `VEDASTRO_API_ENDPOINT` / `VEDASTRO_API_KEY` are absent and neither a .NET runtime nor a reachable Docker daemon is available. | observed 2026-07-17 | Keep hosted closure `blocked`; run `vedastro_contract_probe.py --repeats 3` only after injecting credentials through the environment, and build the pinned source in a provisioned Windows/.NET or reachable container environment. Never persist credentials in artifacts or shell history. | ## ERR-080 | Issue link was mistaken for benchmark provenance | mitigated 2026-07-18 diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 6b369c65..09ed9928 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -550,9 +550,11 @@ button:disabled { cursor: default; opacity: .45; } .product-entrypoint-card { position: relative; transition: border-color 120ms ease-out, background-color 120ms ease-out, transform 120ms ease-out; } .product-entrypoint-hitarea { position: absolute; z-index: 2; inset: 0; width: 100%; min-height: 0; padding: 0; border: 0; border-radius: inherit; background: transparent; cursor: pointer; } .product-entrypoint-card > :not(.product-entrypoint-hitarea) { position: relative; z-index: 1; pointer-events: none; } -.product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):hover) { border-color: color-mix(in srgb, var(--color-action) 44%, var(--color-border)); background: var(--color-action-soft); transform: translateY(-1px); } -.product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):active) { transform: translateY(0); } +.product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):active) { border-color: color-mix(in srgb, var(--color-action) 44%, var(--color-border)); background: var(--color-action-soft); transform: translateY(0); } .product-entrypoint-card:has(.product-entrypoint-hitarea:focus-visible) { outline: 3px solid color-mix(in srgb, var(--color-focus) 56%, transparent); outline-offset: 2px; } +@media (hover: hover) { + .product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):hover) { border-color: color-mix(in srgb, var(--color-action) 44%, var(--color-border)); transform: translateY(-1px); } +} .product-entrypoint-card:has(.product-entrypoint-hitarea:disabled) { opacity: .65; } .product-entrypoint-hitarea:disabled { cursor: not-allowed; } .daily-starlanguage-heading { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); } @@ -1119,19 +1121,25 @@ input:disabled, select:disabled { color: var(--color-ink-tertiary); background: pointer-events: none; } -.product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):hover) { +.product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):active) { border-color: transparent; background: color-mix(in srgb, var(--color-action-soft) 58%, var(--color-canvas)); - transform: none; } -.product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):hover)::after { - opacity: .65; - transform: translateX(48%); -} +@media (hover: hover) { + .product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):hover) { + border-color: transparent; + transform: none; + } -.product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):hover) .product-entrypoint-action { - transform: translateX(3px); + .product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):hover)::after { + opacity: .65; + transform: translateX(48%); + } + + .product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):hover) .product-entrypoint-action { + transform: translateX(3px); + } } .product-entrypoint-card:has(.product-entrypoint-hitarea:focus-visible) { @@ -1270,17 +1278,22 @@ input:disabled, select:disabled { color: var(--color-ink-tertiary); background: border-right: 0; } -.starter-theme-card:not(:disabled):hover, -.starter-theme-card:focus-visible { +.starter-theme-card:not(:disabled):active { background: color-mix(in srgb, var(--color-action-soft) 56%, var(--color-canvas)); } -.starter-theme-card:not(:disabled):hover .starter-arrow, -.starter-theme-card:focus-visible .starter-arrow { +.starter-theme-card:not(:disabled):active .starter-arrow { color: var(--color-action); transform: translate(2px, -2px); } +@media (hover: hover) { + .starter-theme-card:not(:disabled):hover .starter-arrow { + color: var(--color-action); + transform: translate(2px, -2px); + } +} + .starter-content { min-width: 0; display: grid; @@ -1438,11 +1451,6 @@ input:disabled, select:disabled { color: var(--color-ink-tertiary); background: border-bottom: 0; } - .starter-theme-card:not(:disabled):hover, - .starter-theme-card:focus-visible { - background: color-mix(in srgb, var(--color-action-soft) 56%, var(--color-canvas)); - } - .starter-content span { max-width: 440px; } diff --git a/frontend/tests/consultation-entrypoint.test.ts b/frontend/tests/consultation-entrypoint.test.ts index 23c35711..93e4f801 100644 --- a/frontend/tests/consultation-entrypoint.test.ts +++ b/frontend/tests/consultation-entrypoint.test.ts @@ -289,6 +289,22 @@ test("homepage entrypoints use two whole-card native actions", () => { assert.doesNotMatch(source, /className="daily-starlanguage-heading">[\s\S]{0,180}