合并 staging,并把长报告缓存目录登记进自行清理名单
与最新 origin/staging 合并。report_reference_cache 写入 OFFLINE_SCRATCH_NAMES。清理仍由每次读取前删掉两天前的文件完成,两个缓存模块的行为没改。 自测:test_api_scratch_retention 10、test_report_reference_perf 15、test_consult_card_full_source 12,共 37 通过。 Co-Authored-By: Grok (agent loop)
This commit is contained in:
+18007
-17827
File diff suppressed because it is too large
Load Diff
@@ -451,6 +451,8 @@ Prevention: 引擎/上游同步类任务必须 fetch 后核对 `origin/main`,
|
||||
|
||||
Prevention: 引擎/打分路径的性能任务书开工前先查这两份清单;动到其中任何文件,即使输出不变,也要把「按研究协议重新冻结 sealed holdout / reported offset 记录」写进任务分解,否则不要合入。同机 A/B 是必要证据,但不能代替重新冻结。关联 BUG-1047、BUG-985。
|
||||
|
||||
2026-10-14:校正打分提速(BUG-1323~1325、BUG-1345)改了 `event_probes.py`、`dasha_transition_proximity.py`、`active_rectification_event_engine.py`、`api_service.py`。与 `ephemeris_nutation_2026_10_08` 对照输出不变后,另存标签 `scoring_perf_2026_10_13`。nutation 那四份文件没有改。
|
||||
|
||||
## ERR-111 | Shadbala 特征指纹随 PYTHONHASHSEED 变化,同一输入跨进程 `feature_hash` 不同 | observed 2026-09-26
|
||||
|
||||
同一台机器、同一份代码、同一虚构请求连跑两次 `score_candidates`:`candidate_feature_snapshot.features[*].fingerprints.shadbala` / `static` 与 `feature_hash` 每次都不同;固定 `PYTHONHASHSEED=0` 后两次逐字节一致。说明 Shadbala 结果里有依赖集合 / 哈希顺序的结构进入了指纹。打分分数本身未见变化(未系统核对)。
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"record_version": "reported-offset-native-candidate-date-v3",
|
||||
"frozen_at_utc": "2026-10-13T17:45:35.555216+00:00",
|
||||
"ayanamsa": "raman",
|
||||
"node_mode": "mean",
|
||||
"radii_minutes": [
|
||||
15,
|
||||
30,
|
||||
60
|
||||
],
|
||||
"offsets_minutes": [
|
||||
-30,
|
||||
-20,
|
||||
-15,
|
||||
-10,
|
||||
-8,
|
||||
-5,
|
||||
-3,
|
||||
0,
|
||||
3,
|
||||
5,
|
||||
8,
|
||||
10,
|
||||
15,
|
||||
20,
|
||||
30
|
||||
],
|
||||
"minute_step": 1,
|
||||
"dataset": "references/real_case_calibration/minute_rectification_holdout_v3.json",
|
||||
"dataset_sha256": "45aa76ab79dfc6c6404b6252083e1aa5c7e2e2b7de811fc11042a8ad2da3f0ea",
|
||||
"dataset_benchmark_id": "minute_rectification_fact_ranker_v4_holdout_v3",
|
||||
"implementation_sha256": "1c146bf5273edf871d885e9e2e68ee1c8a2f71759b54b4b878f63e771f44197c",
|
||||
"implementation_sha256_prefix": "1c146bf5273edf87",
|
||||
"historical_artifacts_manifest_sha256": "6102a26a840be207b5858b3a4c0509274468ae9071e86d308cbbac7371d6864e",
|
||||
"production_scoring_files": [
|
||||
"scripts/active_rectification_event_engine.py",
|
||||
"scripts/active_rectification_events.py",
|
||||
"scripts/ashtakavarga.py",
|
||||
"scripts/dasha_analyzer.py",
|
||||
"scripts/divisional_charts_extended.py",
|
||||
"scripts/domain_calculation_service.py",
|
||||
"scripts/functional_benefics.py",
|
||||
"scripts/jaimini.py",
|
||||
"scripts/minute_rectification_fact_ranker_v4.py",
|
||||
"scripts/minute_rectification_feature_facts_v4.py",
|
||||
"scripts/narayana_dasha.py",
|
||||
"scripts/rectification/api_service.py",
|
||||
"scripts/rectification/candidate_contrast.py",
|
||||
"scripts/rectification/candidate_window.py",
|
||||
"scripts/rectification/case_holdout.py",
|
||||
"scripts/rectification/contracts.py",
|
||||
"scripts/rectification/dasha_transition_proximity.py",
|
||||
"scripts/rectification/decision_policy.py",
|
||||
"scripts/rectification/event_probes.py",
|
||||
"scripts/rectification/refinement_packet.py",
|
||||
"scripts/rectification/scoring_service.py",
|
||||
"scripts/shadbala.py",
|
||||
"scripts/varga.py"
|
||||
],
|
||||
"production_scoring_sha256": "89c146df190e8902731ea8111d1aff490fede00c919f529c7cf4c3e629a75579",
|
||||
"research_files": [
|
||||
"scripts/research/reported_offset_sweep.py",
|
||||
"scripts/research/cluster_width_lib.py",
|
||||
"scripts/research/probe_supply_after_six.py",
|
||||
"scripts/research/sealed_holdout_rerun.py",
|
||||
"scripts/minute_rectification_blind_eval.py",
|
||||
"scripts/minute_rectification_fact_blind_eval_v4.py",
|
||||
"scripts/minute_rectification_holdout_validator.py"
|
||||
],
|
||||
"research_implementation_sha256": "085ca37ab70e1da18e6941161868618b22c9c9f09c043d0195de7f5650363453",
|
||||
"file_sha256": {
|
||||
"scripts/active_rectification_event_engine.py": "96c537d221a84680ddaaba74e3335162c44b5bbd9a60d10e69550a2095910d98",
|
||||
"scripts/active_rectification_events.py": "03e333ccf1103caf685dfe50fe890ab1793e945037085f50ce834a4a3b232222",
|
||||
"scripts/ashtakavarga.py": "9bfc0b8a06af6122fa6c3881706e64f28b9ba58b53d98ff55957d4741d820f3f",
|
||||
"scripts/dasha_analyzer.py": "5e53b1b4d4c7414c08dd0e7716f120a63c70ec3428ec93547f64d55c580da0e1",
|
||||
"scripts/divisional_charts_extended.py": "e9820e80f14fddc86ab5495d11455d16c2d3c9502a9a242fcf9efc41186e0d11",
|
||||
"scripts/domain_calculation_service.py": "66923a2bc69daf65c965d2973c4b9234edbec5147909eaf3609b6b377ce3c7ca",
|
||||
"scripts/functional_benefics.py": "cbaac3b8c09b97f8724b5300e9a402cbf77089af6c7db8788550d40fd35ac57b",
|
||||
"scripts/jaimini.py": "6b88658da5404da9b136686d92a04be462d61a39da6e8de4255021e2ed2d1173",
|
||||
"scripts/minute_rectification_blind_eval.py": "07aa30d8bad3278669495d5fea8be937aaf6367c8af980ff4f2fe9aa84ccc6ff",
|
||||
"scripts/minute_rectification_fact_blind_eval_v4.py": "bdf460e3467208e8b87345c5beb2128f3e22de7eeffd68f72b281b3ad9affc92",
|
||||
"scripts/minute_rectification_fact_ranker_v4.py": "f1a0d8d2482cd754d2e7f253a9606b0373519435a2bf58cfc3753e2b9ae0fb76",
|
||||
"scripts/minute_rectification_feature_facts_v4.py": "3d899a2cdd4825b8e32062443d487edcd2173a4ea55a36eb9f3abe587c0faf0f",
|
||||
"scripts/minute_rectification_holdout_validator.py": "b60b1c752e58672beaee8b36eb3b2348169726cda070ec969db0f13e7ed715af",
|
||||
"scripts/narayana_dasha.py": "c7aaefd4b7b7ea98a5b94e0f7798e5d0139c7423d10ce4ebfff258a460d4456f",
|
||||
"scripts/rectification/api_service.py": "089730097d3872a4f7b5d7dd5574bb7e9ab4d2e246d4a380800bc824d7979b95",
|
||||
"scripts/rectification/candidate_contrast.py": "eee7da71c0574a08876404b78ca111153fa95fb83ace82b9fdca141d1992e273",
|
||||
"scripts/rectification/candidate_window.py": "2fbc5058b12049b15fca375cdc125b8283e19f9f3e4bedcc291e344501891bef",
|
||||
"scripts/rectification/case_holdout.py": "fe0e699b617d9e216acdfeff87af4221c1d6f4c101bf33e1dbf14e2bcd75a8b5",
|
||||
"scripts/rectification/contracts.py": "c6dc6bd230e38f9f2126c224aae9ddbd6415304c15340f8c7cd3f06f6ef3160f",
|
||||
"scripts/rectification/dasha_transition_proximity.py": "5ce4ed27b0f06c681abc34e5fd998fafb10c153a0070aa36c99ddfa869a2cbf2",
|
||||
"scripts/rectification/decision_policy.py": "80e8de4680d19a052213bb821d2a9c94143a2962235aeb27f6ad81374d2e60d5",
|
||||
"scripts/rectification/event_probes.py": "f5ca9d54501f67a1546fcf5b01da0c1277dec2e2c6df481884e8900d14909a7c",
|
||||
"scripts/rectification/refinement_packet.py": "dbeea5aa780889785ce850f3881e8b7f67bb44594e9bc382c65b2e730884a2f4",
|
||||
"scripts/rectification/scoring_service.py": "fa056fa30d9e6ffa4b75295fc49c793e35b26ebeca64ca843d26c8abef3050f2",
|
||||
"scripts/research/cluster_width_lib.py": "1d8f2ffa7795d62069deebb2de8e16749317037d4ed3f24a2c0092676e5cfcc6",
|
||||
"scripts/research/probe_supply_after_six.py": "098a5b4398d6f8d996917d809c2fc922ad64031d3b70660f8ef7c876aba92438",
|
||||
"scripts/research/reported_offset_sweep.py": "bdcaac92ece761dbcbd35d5a8f751e6b4b11f8475ef8152a5ea4d36ceb38356a",
|
||||
"scripts/research/sealed_holdout_rerun.py": "27904b39a64ff5f1b95ae3c8fc65ca0f3a8b4d8e3f4b88fbbf5d85ffeb53db0d",
|
||||
"scripts/shadbala.py": "334dc9d8e4292f0c95d40fd4c29285aa89b9e49d4f187fb9498f4bb0ad93bdfc",
|
||||
"scripts/varga.py": "c1f06967c3d4d214edadff139c24aa31e59fb628477174235abe14f799a99076"
|
||||
},
|
||||
"hash_scope": "explicit_identity_file_sets_not_a_transitive_dependency_lock",
|
||||
"scorer": "native_event_contribution_matrix_not_shadow_fact_ranker",
|
||||
"delivery": "initial_signature_clusters_peak_gap_lt_8_envelope_no_answers_no_elimination",
|
||||
"rank": "score_desc_then_sha256(benchmark_id:case_id:candidate_time)",
|
||||
"grid": "every_minute_inclusive_not_production_two_minute_sampling",
|
||||
"cross_midnight": "date_aware_candidates_distance_and_native_single_matrix",
|
||||
"evaluator_sha256": "bdcaac92ece761dbcbd35d5a8f751e6b4b11f8475ef8152a5ea4d36ceb38356a",
|
||||
"replay_revision": "native_candidate_date_v3",
|
||||
"supersedes": "candidate_date_grouped_v2_identity_and_path_not_assumed_numerically_wrong",
|
||||
"is_blind_evaluation": false,
|
||||
"truth_hidden_from_ranker": true,
|
||||
"official_valid_independent_blind": false,
|
||||
"official_blind_trial_count": 0,
|
||||
"results_previously_seen": true,
|
||||
"must_not_use_for_tuning": true
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"record_version": "exposed-v3-fixed-protocol-cross-midnight-rerun-v2",
|
||||
"extended_identity": {
|
||||
"historical_artifacts_manifest_sha256": "6102a26a840be207b5858b3a4c0509274468ae9071e86d308cbbac7371d6864e",
|
||||
"production_scoring_files": [
|
||||
"scripts/active_rectification_event_engine.py",
|
||||
"scripts/active_rectification_events.py",
|
||||
"scripts/ashtakavarga.py",
|
||||
"scripts/dasha_analyzer.py",
|
||||
"scripts/divisional_charts_extended.py",
|
||||
"scripts/domain_calculation_service.py",
|
||||
"scripts/functional_benefics.py",
|
||||
"scripts/jaimini.py",
|
||||
"scripts/minute_rectification_fact_ranker_v4.py",
|
||||
"scripts/minute_rectification_feature_facts_v4.py",
|
||||
"scripts/narayana_dasha.py",
|
||||
"scripts/rectification/api_service.py",
|
||||
"scripts/rectification/candidate_contrast.py",
|
||||
"scripts/rectification/candidate_window.py",
|
||||
"scripts/rectification/case_holdout.py",
|
||||
"scripts/rectification/contracts.py",
|
||||
"scripts/rectification/dasha_transition_proximity.py",
|
||||
"scripts/rectification/decision_policy.py",
|
||||
"scripts/rectification/event_probes.py",
|
||||
"scripts/rectification/refinement_packet.py",
|
||||
"scripts/rectification/scoring_service.py",
|
||||
"scripts/shadbala.py",
|
||||
"scripts/varga.py"
|
||||
],
|
||||
"production_scoring_sha256": "89c146df190e8902731ea8111d1aff490fede00c919f529c7cf4c3e629a75579",
|
||||
"research_files": [
|
||||
"scripts/research/reported_offset_sweep.py",
|
||||
"scripts/research/cluster_width_lib.py",
|
||||
"scripts/research/probe_supply_after_six.py",
|
||||
"scripts/research/sealed_holdout_rerun.py",
|
||||
"scripts/minute_rectification_blind_eval.py",
|
||||
"scripts/minute_rectification_fact_blind_eval_v4.py",
|
||||
"scripts/minute_rectification_holdout_validator.py"
|
||||
],
|
||||
"research_implementation_sha256": "085ca37ab70e1da18e6941161868618b22c9c9f09c043d0195de7f5650363453",
|
||||
"file_sha256": {
|
||||
"scripts/active_rectification_event_engine.py": "96c537d221a84680ddaaba74e3335162c44b5bbd9a60d10e69550a2095910d98",
|
||||
"scripts/active_rectification_events.py": "03e333ccf1103caf685dfe50fe890ab1793e945037085f50ce834a4a3b232222",
|
||||
"scripts/ashtakavarga.py": "9bfc0b8a06af6122fa6c3881706e64f28b9ba58b53d98ff55957d4741d820f3f",
|
||||
"scripts/dasha_analyzer.py": "5e53b1b4d4c7414c08dd0e7716f120a63c70ec3428ec93547f64d55c580da0e1",
|
||||
"scripts/divisional_charts_extended.py": "e9820e80f14fddc86ab5495d11455d16c2d3c9502a9a242fcf9efc41186e0d11",
|
||||
"scripts/domain_calculation_service.py": "66923a2bc69daf65c965d2973c4b9234edbec5147909eaf3609b6b377ce3c7ca",
|
||||
"scripts/functional_benefics.py": "cbaac3b8c09b97f8724b5300e9a402cbf77089af6c7db8788550d40fd35ac57b",
|
||||
"scripts/jaimini.py": "6b88658da5404da9b136686d92a04be462d61a39da6e8de4255021e2ed2d1173",
|
||||
"scripts/minute_rectification_blind_eval.py": "07aa30d8bad3278669495d5fea8be937aaf6367c8af980ff4f2fe9aa84ccc6ff",
|
||||
"scripts/minute_rectification_fact_blind_eval_v4.py": "bdf460e3467208e8b87345c5beb2128f3e22de7eeffd68f72b281b3ad9affc92",
|
||||
"scripts/minute_rectification_fact_ranker_v4.py": "f1a0d8d2482cd754d2e7f253a9606b0373519435a2bf58cfc3753e2b9ae0fb76",
|
||||
"scripts/minute_rectification_feature_facts_v4.py": "3d899a2cdd4825b8e32062443d487edcd2173a4ea55a36eb9f3abe587c0faf0f",
|
||||
"scripts/minute_rectification_holdout_validator.py": "b60b1c752e58672beaee8b36eb3b2348169726cda070ec969db0f13e7ed715af",
|
||||
"scripts/narayana_dasha.py": "c7aaefd4b7b7ea98a5b94e0f7798e5d0139c7423d10ce4ebfff258a460d4456f",
|
||||
"scripts/rectification/api_service.py": "089730097d3872a4f7b5d7dd5574bb7e9ab4d2e246d4a380800bc824d7979b95",
|
||||
"scripts/rectification/candidate_contrast.py": "eee7da71c0574a08876404b78ca111153fa95fb83ace82b9fdca141d1992e273",
|
||||
"scripts/rectification/candidate_window.py": "2fbc5058b12049b15fca375cdc125b8283e19f9f3e4bedcc291e344501891bef",
|
||||
"scripts/rectification/case_holdout.py": "fe0e699b617d9e216acdfeff87af4221c1d6f4c101bf33e1dbf14e2bcd75a8b5",
|
||||
"scripts/rectification/contracts.py": "c6dc6bd230e38f9f2126c224aae9ddbd6415304c15340f8c7cd3f06f6ef3160f",
|
||||
"scripts/rectification/dasha_transition_proximity.py": "5ce4ed27b0f06c681abc34e5fd998fafb10c153a0070aa36c99ddfa869a2cbf2",
|
||||
"scripts/rectification/decision_policy.py": "80e8de4680d19a052213bb821d2a9c94143a2962235aeb27f6ad81374d2e60d5",
|
||||
"scripts/rectification/event_probes.py": "f5ca9d54501f67a1546fcf5b01da0c1277dec2e2c6df481884e8900d14909a7c",
|
||||
"scripts/rectification/refinement_packet.py": "dbeea5aa780889785ce850f3881e8b7f67bb44594e9bc382c65b2e730884a2f4",
|
||||
"scripts/rectification/scoring_service.py": "fa056fa30d9e6ffa4b75295fc49c793e35b26ebeca64ca843d26c8abef3050f2",
|
||||
"scripts/research/cluster_width_lib.py": "1d8f2ffa7795d62069deebb2de8e16749317037d4ed3f24a2c0092676e5cfcc6",
|
||||
"scripts/research/probe_supply_after_six.py": "098a5b4398d6f8d996917d809c2fc922ad64031d3b70660f8ef7c876aba92438",
|
||||
"scripts/research/reported_offset_sweep.py": "bdcaac92ece761dbcbd35d5a8f751e6b4b11f8475ef8152a5ea4d36ceb38356a",
|
||||
"scripts/research/sealed_holdout_rerun.py": "27904b39a64ff5f1b95ae3c8fc65ca0f3a8b4d8e3f4b88fbbf5d85ffeb53db0d",
|
||||
"scripts/shadbala.py": "334dc9d8e4292f0c95d40fd4c29285aa89b9e49d4f187fb9498f4bb0ad93bdfc",
|
||||
"scripts/varga.py": "c1f06967c3d4d214edadff139c24aa31e59fb628477174235abe14f799a99076"
|
||||
},
|
||||
"hash_scope": "explicit_identity_file_sets_not_a_transitive_dependency_lock"
|
||||
},
|
||||
"production_identity_scope": "context_only_shadow_scorer_does_not_call_transition_proximity",
|
||||
"frozen_at_utc": "2026-10-13T17:44:49.007680+00:00",
|
||||
"dataset_path": "references/real_case_calibration/minute_rectification_holdout_v3.json",
|
||||
"dataset_sha256": "45aa76ab79dfc6c6404b6252083e1aa5c7e2e2b7de811fc11042a8ad2da3f0ea",
|
||||
"algorithm_version": "birth-time-event-fact-ranker-v4-shadow",
|
||||
"implementation_sha256": "1c146bf5273edf871d885e9e2e68ee1c8a2f71759b54b4b878f63e771f44197c",
|
||||
"files": [
|
||||
"scripts/active_rectification_event_engine.py",
|
||||
"scripts/active_rectification_events.py",
|
||||
"scripts/ashtakavarga.py",
|
||||
"scripts/dasha_analyzer.py",
|
||||
"scripts/divisional_charts_extended.py",
|
||||
"scripts/domain_calculation_service.py",
|
||||
"scripts/jaimini.py",
|
||||
"scripts/minute_rectification_fact_ranker_v4.py",
|
||||
"scripts/minute_rectification_feature_facts_v4.py",
|
||||
"scripts/narayana_dasha.py",
|
||||
"scripts/shadbala.py",
|
||||
"scripts/varga.py"
|
||||
],
|
||||
"historical_frozen_sha256": "f41c298dd6cdcebe7a93e632f7191954be7987f6012ca2a34cecb6e447fbf196",
|
||||
"evaluator_sha256": "27904b39a64ff5f1b95ae3c8fc65ca0f3a8b4d8e3f4b88fbbf5d85ffeb53db0d",
|
||||
"ayanamsa": "raman",
|
||||
"node_mode": "mean",
|
||||
"candidate_radius_minutes": [
|
||||
10
|
||||
],
|
||||
"minute_step": 1,
|
||||
"release_metrics": {
|
||||
"top_1_rate_minimum": 0.6,
|
||||
"top_3_rate_minimum": 0.85,
|
||||
"mean_absolute_minute_error_maximum": 2.0,
|
||||
"false_confirmation_rate_maximum": 0.05,
|
||||
"correct_insufficient_evidence_rejection_rate_minimum": 0.9
|
||||
},
|
||||
"results_previously_seen": true,
|
||||
"official_valid_independent_blind": false,
|
||||
"must_not_use_for_tuning": true,
|
||||
"tie_breaker": "sha256(benchmark_id:case_id:candidate_time); published minute is never passed to the ranker",
|
||||
"metric_rank_definition": "competition_rank_1_plus_strictly_higher_scores_legacy_protocol",
|
||||
"extra_metric_rank_definition": "score_desc_then_existing_opaque_sha256_total_order"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
# PROGRESS · API 磁盘缓存留存(2026-10-14)
|
||||
|
||||
- 分支:`codex/api-disk-cache-retention-20261013`
|
||||
- 任务书基线写的是 `77057a819`。本分支从当时的 `origin/staging` `66cd60081f37a57680274633fcb3fb942d01bb2f` 拉出。A/B 的父提交用的是这个 SHA,不是任务书里的旧基线。
|
||||
- 接口文件行数:10946(验收口径 ≤ 10970)。类方法数和伪造点没有增加。
|
||||
|
||||
## 做了什么
|
||||
|
||||
- T1:新增 `scripts/api_scratch_retention.py`。启动时清理全部已登记目录,并按 `JYOTISH_SCRATCH_PRUNE_INTERVAL_SECONDS`(默认 1800,0 表示不启后台线程)周期清理。排盘缓存新文件改为仅本人可读,先写临时文件再换上。`prune_expired_async_jobs` 只留同名薄包装。
|
||||
- T2:`VEDASTRO_WRITE_AUDIT_ARTIFACTS` 默认关。关掉时不写审计文件,`artifact_path` 为 `None`。打开时写紧凑 JSON,仅本人可读,先写临时文件再换上。成功快照仍用原 TTL;失败、不完整、被挡住的用短 TTL,默认 300 秒,并且不超过成功 TTL。旧缓存没有 `negative` 标记时仍按成功的长期限读。状态接口改报含回落的成功期限,并多报失败期限。`.env.cn.example` 只加了注释,两个 604800 没改。
|
||||
- 成功的判据:`available is True` 且 `status == "ok"`。`partial` 即使 `available` 为真也算失败缓存。
|
||||
- T3:年月日能整除才收成整数,不截断 1990.5。时分秒和经纬度、时区能解析成有限数字就收成浮点,不四舍五入。解析不了的保持原值。日期取前 10 位,空值仍是空值。缓存格式版本 5 → 6。快速排盘和完整排盘仍是两把键。
|
||||
- T4:前台快照、负缓存、网关任务、分盘段都进了登记表。只删符合原文件名的过期文件。网关排队中和进行中的不删。读写逻辑和键没改。
|
||||
- T5:脚本在 `scripts/research/api_disk_cache_ab.py`,逐字节比较在 `scripts/research/api_chart_cache_byte_diff.py`。记录在 `docs/testing/api-disk-cache-retention-ab-20261013.md`。
|
||||
- T6:没有改咨询卡片缓存。数字用任务书 §2.5,没有重测:未命中构建 1.9 秒;文件 5097751 字节;命中时解析中位 68.5 毫秒;整次命中 82.5 毫秒;两天大约每个活跃用户 10 MB。可选方向仍是两条:按领域切片只读需要的部分;清理改为每隔几分钟一次,而不是每次读取都扫全目录。没有做进程内已解析包缓存。
|
||||
- T7:BUG-1330、BUG-1331、BUG-1332。变更说明一句。任务索引改为待验收。没有改界面说明。
|
||||
|
||||
## 命令和结果
|
||||
|
||||
| 检查 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 新留存、异步任务、增长合同 | `pytest tests/test_api_scratch_retention.py tests/test_api_async_job_contract.py tests/test_api_server_growth_contract.py -q` | 26 通过 |
|
||||
| 安全缓存 | `pytest tests/test_api_server_security.py -q -k cache` | 6 通过 |
|
||||
| 任务书列出的 VedAstro / 咨询套件 | 见任务书 §8 那一条 | 4 失败,见下。其余通过 |
|
||||
| 需要审计文件的执行器测试 | `pytest tests/test_vedastro_service_adapter_executor.py::test_vedastro_range_scan_records_hashes_and_artifact_path -q` | 1 通过 |
|
||||
| 逐字节比较与 A/B | `python scripts/research/api_disk_cache_ab.py` | 退出码 0。命中率 B/A = 1.333。七天后 B 剩 40 个文件,等于当天键数。审计文件 0。负缓存剩 1。一万个文件的清理 20.174 秒 |
|
||||
| 接口行数 | 按换行计数 | 10946 |
|
||||
|
||||
既有断言改动只有一处,在 `tests/test_vedastro_service_adapter_executor.py`:原值是子进程沿用进程环境;新值是显式打开审计落盘;原因是默认关闭后这条测试仍要检查文件存在。这是测试前置,不是放宽断言。
|
||||
|
||||
## 未达到的目标(目标不改)
|
||||
|
||||
- 混合写法再重复 3 次时,命中率只是 A 的 1.333 倍,不是 2.5 倍。重复本身已经让 A 命中三分之二。
|
||||
- 一万个过期文件的清理用了 20.174 秒,不是 2 秒内。清理不在请求线程。默认间隔和失败短期限没有因此改掉。
|
||||
|
||||
## 本机套件里原先就会红的三条
|
||||
|
||||
- `tests/test_vedastro_gateway.py` 要求原始响应文件权限是 0600。Windows 报出来的是可写,不是 0600。这条断言没改。新测试在 Linux 上仍检查 0600,Windows 上只检查文件写出来了。
|
||||
- `tests/test_vedastro_runtime_ops.py` 要求已安装的 VedAstro 是 1.23.25,本机是 1.23.30。与这次缓存改动无关。
|
||||
- `tests/test_three_engine_parity_runner.py` 的公开盘回放把 PyJHora 记成 raw_imported,不是 structured_captured,同时在下载星历。运行器没改。
|
||||
|
||||
## 环境缺口
|
||||
|
||||
- 生产和测试环境里成功缓存的实际秒数,这份仓库读不到。部署后看状态接口的两个期限数字即可。
|
||||
- 生产卷上已经堆了多少文件,这里不知道。
|
||||
- 主测量挡住了 VedAstro 导入。本机有 SDK,官方端口能连通。不挡 SDK 的探针仍关闭外网取数,一次完整排盘 4.167 秒,没有报错,没有拉真实快照。
|
||||
|
||||
## 未做
|
||||
|
||||
- 没有改部署文件、生产环境变量、数据库,也没有手工清生产卷。
|
||||
- 没有把咨询卡片缓存并进周期清理。
|
||||
@@ -0,0 +1,70 @@
|
||||
# PROGRESS · 流式回答时侧栏不再跟着每帧重画(issue #59)
|
||||
|
||||
- 分支:`codex/home-sidebar-rerender-20261013`
|
||||
- 实际基线:`origin/staging` `66cd60081f37a57680274633fcb3fb942d01bb2f`
|
||||
- 任务书基线写成 `77057a819`,计划评论里的 base 是 `2994588ad4d858dead4835943e5883c5aa2b03f8`。开工时远端 staging 已是上面的 `66cd6008`。A/B 就跑在这个提交上,没有另开只读工作树(本轮不能离开当前工作树)。方向没有改,不需要拍板。
|
||||
- `docs/BUG_HISTORY.md` 在这个基线上停在 BUG-1322。BUG-1323~1328、1345、1346 属于还没合入的别的分支,本单只用 BUG-1329。
|
||||
- 未改 `page.tsx`。没有运行时开关。没有启用 React Compiler。Skill 版本不变。浏览器 A/B 未跑。
|
||||
|
||||
## 做了什么
|
||||
|
||||
外壳拿到的点击函数不再每次渲染换新,点下去仍执行首页刚渲染的那一版。注册只在数据变了才发给侧栏:会话行要逐条还是同一个对象才算没变,没变就不重建行。可见会话按当前人物记忆。侧栏自己的上下文对象也不再每次新建。卸载首页时仍会清掉注册。
|
||||
|
||||
## 断言三栏
|
||||
|
||||
| 位置 | 原值 | 新值 | 原因 |
|
||||
| --- | --- | --- | --- |
|
||||
| `frontend/tests/session-list-lifecycle.test.tsx` 外壳「打开资料」函数 | `assert.notEqual(onOpenProfile, initialCallback)` | `assert.equal(...)`;再改一版后仍是同一个函数,调用记录从 `[1]` 加强到 `[1, 2]` | 包装函数身份稳定。调用必须落到最新一次渲染,不能只删掉「不相等」 |
|
||||
|
||||
`HomeProbe` 仍是每次渲染新回调、新数组,没有改成常量。
|
||||
|
||||
## 基线失败(改代码之前,同一测试,3 次,退出码都是 1)
|
||||
|
||||
失败停在 `assert.equal(duringFrames.registers, 0)`,实际是 60。60 帧里侧栏提交也是 60。换当前项、改标题、换人各注册 1 次;只改回调版本也会再注册 1 次。剔除函数后的内容摘要:
|
||||
|
||||
| 档 | 60 帧注册 | 60 帧提交 | 60 帧耗时三次(毫秒) | 中位 | 内容摘要 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 30 条虚构会话 | 60 | 60 | 2774.964 / 2778.961 / 4202.085 | 2778.961 | `b18f05a3d83be5b41584787b7c0495f1fcec8ef7b8ecfbdbb3c083c40796c103` |
|
||||
| 100 条虚构会话 | 60 | 60 | 10530.828 / 11799.253 / 12284.103 | 11799.253 | `cef0a63d6f3fe72e541f9ac882b8eaf305b6933fdd07ca3002e8cd03bb139d25` |
|
||||
|
||||
更早一次探针把注册函数也做成每次渲染新建,60 帧数到 120 次注册、60 次提交。那是清理函数跟着新函数又清了一次,不是产品路径。交付用的测试和生产一样,用提供者给出的稳定注册函数,所以改前是 60 而不是 120。
|
||||
|
||||
## 改后(同一测试,3 次,退出码都是 0)
|
||||
|
||||
| 档 | 60 帧注册 | 60 帧提交 | 60 帧耗时中位 | 换当前项 | 改标题 | 只改回调版本 | 换人 | 内容摘要 |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| 30 | 0 | 0 | 0 | 注册 1、提交 1 | 注册 1,标题更新 | 注册 0,调用记到第 4 版 | 注册 1,列表换成另一人 | 与改前相同 |
|
||||
| 100 | 0 | 0 | 0 | 注册 1、提交 1 | 注册 1,标题更新 | 注册 0,调用记到第 4 版 | 注册 1,列表换成另一人 | 与改前相同 |
|
||||
|
||||
三次摘要都与上表相同。门槛达到:60 帧内注册 0、侧栏提交 0,内容摘要逐字节一致。
|
||||
|
||||
## 自测
|
||||
|
||||
| 检查 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 类型 | `node frontend/node_modules/typescript/bin/tsc --noEmit -p frontend` | 退出码 0 |
|
||||
| 规范 | `npm run lint --prefix frontend` | 0 error,126 条原有 warning。本单文件没有新增 warning,没有 `eslint-disable` |
|
||||
| 定向测试 | `tsx --test` 下表 10 个文件 | tests 94,pass 94,fail 0,cancelled 0 |
|
||||
| 数据库 | 未跑 | 本单不碰数据库 |
|
||||
| 浏览器 | 未跑 | 浏览器 A/B 未跑。步骤在 `docs/testing/home-sidebar-rerender-20261013.md` |
|
||||
| 隐私标记 | `.venv\Scripts\python.exe -m pytest tests/test_repo_privacy_markers.py -q` | 通过 |
|
||||
|
||||
定向文件:`home-sidebar-rerender`、`session-list-lifecycle`、`session-list-provider`、`sidebar-contract`、`sidebar-state`、`secondary-page-entry`、`account-dialog-inert-20260918`、`home-shell-growth-contract`、`home-streaming-render-split`、`chat-profile-picker`。
|
||||
|
||||
全量 `npm test`、`next build`、Python 快速门未跑,留给验收。
|
||||
|
||||
## 2026-10-14 修复单
|
||||
|
||||
按修复单合并了最新 `origin/staging`。只改了 `frontend/tests/chat-navigation-a11y-contract.test.ts` 里账户菜单「充值」那一条源码断言,改成认稳定包装的写法,仍然要求打开 billing 且来源是 `account-menu`。业务代码没有改。
|
||||
|
||||
又搜了一遍 `onOpenProfile`、`onOpenGeneral`、`onOpenLogout`、`onNewChat`、`onSelectSession`、`onLoadMore`。测试里其余命中的是侧栏组件自己的入口,或校正点数不足时打开充值,不是这条旧写法,没有改。
|
||||
|
||||
和上一版 `63509431` 比,网页业务目录里多出来的只有合并测试线带入的校正提速(`engine-client.ts`),不是这单写的。这单自己的提交不碰 `frontend/src`。
|
||||
|
||||
| 检查 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 类型 | `tsc --noEmit -p frontend` | 通过,退出码 0 |
|
||||
| 规范 | `npm run lint`(在 frontend) | 0 error,125 条原有 warning。本单改的测试文件没有新增 warning |
|
||||
| 这条旧检查 | `tsx --test tests/chat-navigation-a11y-contract.test.ts` | 13 通过,0 失败,0 取消 |
|
||||
|
||||
全量 `npm test` 仍留给验收。
|
||||
@@ -0,0 +1,73 @@
|
||||
# 进度 · 服务器内存与数据库往返(2026-10-13)
|
||||
|
||||
issue #58。分支 `codex/node-runtime-resources-20261013`。
|
||||
|
||||
2026-10-14 按修复单把往返对照脚本从 `frontend/scripts/bench-local-pg-roundtrips.ts` 挪到 `frontend/tests/bench-local-pg-roundtrips.ts`。文件名不是 `.test.ts`,全量测试不会自动收进去。业务代码没有改,对照数字没有重跑。原任务书里的旧路径保持不动。
|
||||
|
||||
任务书基线写的是 `77057a819`,计划评论里的基线是 `2994588ad4d858dead4835943e5883c5aa2b03f8`。本分支实际从当时的 `origin/staging` `66cd60081f37a57680274633fcb3fb942d01bb2f` 拉出。没有因此停下来问产品,改动仍按任务书做。
|
||||
|
||||
## 做了什么
|
||||
|
||||
- 报告工人的等待:计时器到点就摘掉取消监听。引导打分里同一段等待也摘掉。空转不再往进程上堆监听。
|
||||
- 本地数据库:列、主键、函数签名缓存 300 秒;设置角色和两条身份合成一条语句。开始和提交仍分开。两个开关默认打开,写成 `off` 时语句顺序与改前一致。
|
||||
- 三张内存表:交付记录超过 60 秒删除,最多 1 万条;重算记录超过 6 小时删除,最多 5 千条;限流按见过的最大窗口清理已出窗的键。
|
||||
- 登录读缓存:只有 `IDENTITY_SESSION_COOKIE_CACHE=on` 才缓存 300 秒。默认关闭。
|
||||
|
||||
## 不做的
|
||||
|
||||
只读、又没有身份时省掉事务:不做。那种做法只能用会话级角色,归还连接前再清。往返数不降,而且一旦没清掉,下一次请求会带着上一次的角色。违反「连接还回池子时不能带着角色或身份」。
|
||||
|
||||
`begin` 没有并进一条多语句查询。
|
||||
|
||||
## 语义变化
|
||||
|
||||
同一道校正题、同一份证据,6 小时后或因为超过 5 千条被挤出后,可能再重算一次。这比「进程重启后才会再算」更收敛。60 秒内的交付去重、窗口内的限流允许或拒绝,都没有改。
|
||||
|
||||
## 基线失败
|
||||
|
||||
修之前的等待写法,在第 200 次空转时取消信号上还有 199 个监听。同形脚本输出:`listenersAt200=199`,`assertion failed: 199 !== 0`。修之后的测试断言是 0,并且通过。
|
||||
|
||||
## 登录读取的调用点
|
||||
|
||||
敏感,每次跳过缓存:
|
||||
|
||||
- 改密码:`frontend/src/app/api/account/password/route.ts`
|
||||
- 注销账户:`frontend/src/app/api/account/deletion/route.ts`
|
||||
- 全部后台入口:`frontend/src/lib/admin/auth.ts`
|
||||
|
||||
其余业务接口走 `createServerSupabaseClient()`,不带跳过参数。开关打开后,这些普通读取可以走 300 秒缓存。
|
||||
|
||||
改邮箱、两步验证、后台插件自带的敏感入口本来就会重新读库,这次没改。咨询里检查「正在注销」的那次调用,以及后台查封禁的语句,都没有改成缓存。
|
||||
|
||||
## 对照结论
|
||||
|
||||
详见 `docs/testing/node-runtime-resources-ab-20261013.md`。两个数据库开关一起:往返 49 → 32(低于 70%),耗时中位数 75.84 → 36.48 毫秒(下降 51.9%),返回内容一致。`npm run test:db` 开关关、开关开各一轮,都是 81 项、通过 68、失败 13、取消 0。失败名称与 `tools/agent-loop/windows-known-failures.txt` 的 13 条相同,没有多出来的。运行器因此退出码是 1,这 13 条是 Windows 上原有的。两个数据库开关默认打开。
|
||||
|
||||
登录读缓存的查库次数在测试里从 3 降到 1,但没有对真实身份库做耗时对照,默认保持关闭。要打开,把 `IDENTITY_SESSION_COOKIE_CACHE` 设成 `on`。
|
||||
|
||||
网页容器已经用 env 文件读环境变量,所以这三个名字不必改 Compose。
|
||||
|
||||
## 自测
|
||||
|
||||
| 检查 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 类型 | `tsc --noEmit -p frontend` | 通过,退出码 0 |
|
||||
| 规范 | `npm run lint`(在 frontend) | 0 error,125 条原有 warning,未改 |
|
||||
| 本单测试 | `tsx --test` 任务书点名的文件加登录缓存测试 | 134 通过,0 失败,0 取消 |
|
||||
| 真库身份 | `database-local-postgres-session-setup.test.ts` | 1 通过。事务内角色和身份生效,连接归还后再借出时身份已空 |
|
||||
| 数据库套件 | `npm run test:db`,两开关先关后开 | 各 81 / 通过 68 / 失败 13 / 取消 0,名称与已知清单一致 |
|
||||
| 往返对照 | `tests/bench-local-pg-roundtrips.ts`(按修复单从 `scripts/` 挪来) | 见上,`payloadMismatch` false。数字未重跑 |
|
||||
|
||||
没有跑前端全量 `npm test`、Python 快速门、`next build`。生产内存曲线要等部署后看。真机两台设备改密码的步骤在 `docs/testing/node-runtime-resources-20261013.md`,登录缓存默认关着,那份清单的第 2 步要先把开关打开才看得到。
|
||||
|
||||
## 2026-10-14 修复单
|
||||
|
||||
按 `docs/tasks/TASK-node-runtime-resources-fix-20261014.md`:先合并最新 `origin/staging`,再把对照脚本挪进测试目录。业务代码没有改。对照数字没有重跑。
|
||||
|
||||
和上一版 `4c3485bc` 比,网页业务目录里多出来的只有合并进来的校正提速改动(`frontend/src/lib/rectification-agentic/v9/engine-client.ts`),不是这单写的。这单自己的提交不碰 `frontend/src`。
|
||||
|
||||
| 检查 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 类型 | `tsc --noEmit -p frontend` | 通过,退出码 0 |
|
||||
| 规范 | `npm run lint`(在 frontend) | 0 error,125 条原有 warning,未改 |
|
||||
| 镜像导入守卫 | `tsx --test tests/runtime-sources-no-test-imports.test.ts` | 2 通过,0 失败,0 取消 |
|
||||
@@ -0,0 +1,97 @@
|
||||
# 校正打分提速进度(2026-10-14)
|
||||
|
||||
结论:两小时窗口的打分大约快到原来的 38%,结果不变。11 个场景的规范化输出与基线逐字节相同。密封重跑 20 例的 trials、metrics 与历史比较和 2026-10-08 那份记录逐字节相同,`changed_trial_count` 仍是 8。报偏移 900 例的核对写在文末。
|
||||
|
||||
## 基线
|
||||
|
||||
| 项 | 值 |
|
||||
| --- | --- |
|
||||
| 任务书基线 | `77057a819` |
|
||||
| 计划评论里的 base | `2994588ad` |
|
||||
| 本分支实际起点 | `74384be0243b16e7a261c2afdea2ca12bab92285`(当时的 `origin/staging`) |
|
||||
| 冻结文件相对 `77057a819` | `git diff --stat` 为空,所以计时和逐字节对照仍用这份基线 |
|
||||
|
||||
机器:13th Gen Intel Core i5-13400F,16 逻辑处理器,Windows。同一进程里先跑基线 5 次再跑新代码 5 次,取中位数。`PYTHONHASHSEED=0`。绝对秒数比任务书写的 3.8–4.8 秒高,因为那组数字不是这台机器测的。下面的比例以这次同机对照为准。
|
||||
|
||||
## 同机耗时(5 次中位数)
|
||||
|
||||
| 窗口 | 候选 | 基线 | 现在 | 相对基线 | 目标 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 12:00–12:20 | 21 | 0.5359 s | 0.3185 s | 59% | 不慢于基线 +5% |
|
||||
| 11:45–12:15 | 31 | 1.9700 s | 0.8696 s | 44% | — |
|
||||
| 11:00–13:00 | 121 | 10.6181 s | 4.0695 s | 38% | ≤ 45% |
|
||||
| 全天 `block_scan` 步长 10 | 144 | 6.7187 s | 3.8025 s | 57% | 不慢于基线 |
|
||||
|
||||
121 候选分段(中位数,秒):
|
||||
|
||||
| 段 | 基线 | 现在 | 相对 |
|
||||
| --- | --- | --- | --- |
|
||||
| `guided_collect_windows` | 4.8700 | 0.6116 | 13%(目标 ≤ 25%) |
|
||||
| `merge_transition_proximity` | 1.7124 | 0.4497 | 26%(目标 ≤ 35%) |
|
||||
| `get_current_narayana_dasha` | 0.7562 | 0.0387 | 探针路径仍会调用,打分循环为 0 |
|
||||
| `derive_functional_benefic_malefic` | 0.3295 | 0.0081 | 一次打分 121 次,每个候选 1 次 |
|
||||
| `build_candidate_static_context` | 0.9830 | 1.0625 | 这里多算了两份缓存,总时间仍下降 |
|
||||
|
||||
121 候选默认响应的规范化字节:基线 2,071,995(响应里带着矩阵),现在 930,631(约 0.89 MB)。目标 ≤ 0.96 MB。
|
||||
|
||||
## 11 个场景 sha256
|
||||
|
||||
两边都用 `PYTHONHASHSEED=0`,`sort_keys=True`,去掉 `column_compare_ms`。打分场景打开 `include_internal=True`。诊断场景另外去掉 `candidate_decision_receipt`,因为新诊断不再重复那份内部回执。基线工作树是一次性检出 `77057a819`,比完已删除。
|
||||
|
||||
| 场景 | sha256 | 字节 | 相同 |
|
||||
| --- | --- | --- | --- |
|
||||
| 12:00–12:20 | `2bc6c777ac4957ce99277649879f7f8ded5c8f246361d73cf18454a3ac7466b0` | 429250 | 是 |
|
||||
| 11:45–12:15 | `f886afac4b27a8a1f36c771bfdf1565e8df1f4f579d19e73288b0549a9544bda` | 597372 | 是 |
|
||||
| 11:00–13:00 | `2d5dcb5cd6e92664bba692d59f75eabdc4b55f822817b7a6f5106c89fd8c8708` | 2071995 | 是 |
|
||||
| 23:20–00:40 | `73aeb9b7a4d0a3a2b5643aff5e2ef779f15e2e765eefc60aa3985b347ca4b9c1` | 1255752 | 是 |
|
||||
| declined relationship+career | `9e48c7cf4b21c133bb52b85e73b0ab7891826a0125a5ef428f6a280503585ee8` | 1082766 | 是 |
|
||||
| refresh probes + column times | `7c977c19c48448e92a7845225ba04897359f29bbaf92e4ff2c69a83e7b070b1a` | 932456 | 是 |
|
||||
| 10:00–13:00 步长 2 | `e03adc5cd88e4df144186afc88cead358b67db37784717e8331f256507357cdc` | 1405125 | 是 |
|
||||
| block_scan 全天步长 10 | `38b27ab49744a7a8036017d10e919f2b8b8baa58fd53590e4b0a35d9689eb1e9` | 394426 | 是 |
|
||||
| block_scan 10:00–14:00 步长 5 | `6c13482afd5b5de9545185b3c92145f40629550556b2f0e83b009e690d933133` | 129483 | 是 |
|
||||
| 记忆化测试的公开请求 | `e0eb1c449a2a42cd081b15af5dece3f97fcffae627ab605d9514b413617964a7` | 90384 | 是 |
|
||||
| diagnostics 11:00–13:00 | `5a9d9ad7304ac01419ba85b6a24c23d1bc9b00ec1df417a7bb9385ce8dfea83b` | 456088 | 是 |
|
||||
|
||||
## 计数与等价
|
||||
|
||||
- 引导窗口:一次调用里 `_context_time` ≤ 16 × 候选数。121 与 21 的次数比不超过 (121/21)×1.2。输出与基线函数副本四种形状相同。
|
||||
- 换段邻近:一次调用里 `_vim_start_dates` ≤ 2 × 候选数,`_narayana_start_dates` ≤ 1 × 候选数。先按年份 1–9999 算全表,再按事件年份过滤。`event_probes.py` 里这两个函数只在年份落在窗口内时追加,空结果不依赖窗口,所以过滤后的列表与原来在窗口里现算相同。跨午夜矩阵也相同。
|
||||
- 功能吉凶:一次 121 候选打分调用 121 次。放在静态上下文顶层,不进 `feature`,`feature_hash` 不变。
|
||||
- 那罗延子运:打分循环(`_candidate_row`)里 `get_current_narayana_dasha` 为 0。0 到 120 岁、步长 0.01 年,缓存查找与现算相同。探针路径 `event_probes._score_year` 仍不接收这张表,所以整次打分里这个函数不是 0。这是任务书明确不改的偏差。
|
||||
- 候选上限:240 和 241 通过;242 和全天步长 1 在排盘前 50 毫秒内拒绝。步长 2、5、10 的产品窗口通过。全天 `block_scan` 在没给步长时自己改成 10,不触发上限。研究脚本里的回放半径到 120 正好 241,不超限。冻结重跑不经过 `score_candidates`,上限不影响那 900 例。
|
||||
|
||||
超过上限时 HTTP 400,正文含 `too_many_candidates`。API 入口文件没有改,所以错误码仍是 `ERR_BAD_REQUEST`。前端把这种 400 当成坏请求,不按服务忙重试。
|
||||
|
||||
## 三栏
|
||||
|
||||
| 位置 | 原值 | 新值 | 原因 |
|
||||
| --- | --- | --- | --- |
|
||||
| `tests/test_rectification_engine_memoization.py` 缓存键 | 4 个 | 6 个,加上功能吉凶和那罗延子运表 | BUG-1324 |
|
||||
| `tests/test_rectification_v5_services.py` 矩阵断言 | 默认响应里有矩阵 | 默认没有;`include_internal=True` 才有 | BUG-1325 |
|
||||
| 同文件回执读取 | `candidate_decision_receipt` | `decision_receipt` | BUG-1325 |
|
||||
| 两份研究脚本的 `FREEZE` / `REPORT` | `ephemeris_nutation_2026_10_08` | `scoring_perf_2026_10_13` | BUG-1323~1325 改了冻结身份文件,输出不变,ERR-110 另存新记录 |
|
||||
| 密封合同当前指针 | nutation 记录 | `scoring_perf_2026_10_13`;nutation 放进该对象里的 `previous_*` | 同上 |
|
||||
| `tests/test_sealed_holdout_contract_freshness.py` 排除前缀 | 到 nutation | 再排除两份新记录 | 同上 |
|
||||
| `frontend/tests/rectification-confirmation-gate.test.ts` 冻结路径 | nutation 报告 | `sealed_holdout_rerun_scoring_perf_2026_10_13.json` | 同上 |
|
||||
| `tests/test_repo_privacy_markers.py` 时钟集合行号 | 1182、1190 | 1195、1203 | BUG-1325 的三栏注释把原集合下移,钟点没变 |
|
||||
|
||||
## 冻结核对
|
||||
|
||||
标签 `scoring_perf_2026_10_13`。nutation 四份文件没有改。
|
||||
|
||||
密封重跑:trials 规范化 JSON 与 `sealed_holdout_rerun_ephemeris_nutation_2026_10_08.json` 逐字节相同,metrics 相同,`historical_comparison` 相同,`changed_trial_count` 仍是 8。新报告 sha256 `25e2e59ecab81b528f0f27369a8638a907ea551f57fdd8572db00fe25a139641`。冻结记录 sha256 `1ce7f7ac67221e10bb4d176f5e8af9299fbae7586717d83048b7e3c124e43e7c`。当前树遗留 12 文件哈希 `1c146bf5273edf871d885e9e2e68ee1c8a2f71759b54b4b878f63e771f44197c`(`active_rectification_event_engine.py` 在这 12 个文件里,所以这份哈希变了,输出没变)。
|
||||
|
||||
报偏移 900 例:trials 规范化 JSON、summary、`historical_comparison` 都与 `reported_offset_ephemeris_nutation_2026_10_08.json` 相同。`changed_trial_count` 仍是 581。这份报告没有 `metrics` 键,旧报告也没有。新报告 sha256 `9466cf3945a63621104157fb34291cb23205ddb045effa7e70f3c35647516443`。冻结记录 sha256 `1560f24ffea19116c904272907ff9cce24904960406676f3aada3c8c174cf98a`。重跑从 `2026-10-13T17:45:36Z` 到 `2026-10-13T18:02:16Z`。
|
||||
|
||||
## 本单不做
|
||||
|
||||
- 探针路径的大运用的是请求日期,并且不接收那罗延子运表。
|
||||
- 候选特征快照瘦身要动前端契约。
|
||||
- 引导窗口和换段邻近共用同一张大运起点表。
|
||||
|
||||
## 自测
|
||||
|
||||
- `tests/test_rect_scoring_perf_20261013.py` 与任务书点名的校正测试、`tests/test_rectification_*.py`(当时尚未改指针的完整性门除外)退出码 0。
|
||||
- 指针改完后 `tests/test_sealed_holdout_contract_freshness.py` 退出码 0。
|
||||
- 前端 `tsc --noEmit` 退出码 0,`npm run lint` 0 error。`rectification-v9-engine-contract.test.ts` 18 通过、0 失败、0 取消。`rectification-confirmation-gate.test.ts` 8 通过、0 失败、0 取消。
|
||||
- 没有跑前端全量,也没有跑 Python 快速门。
|
||||
@@ -38,3 +38,7 @@
|
||||
|
||||
- `JYOTISH_REPORT_RENDER_FAST` 默认关。字节一致,内存还降了约 12%,但端到端没到 35%。
|
||||
- `JYOTISH_REPORT_REFERENCE_CACHE` 默认开。命中与未命中字节一致,命中中位约 0.06 秒。版本号缺失或是 `unknown` 时不缓存。
|
||||
|
||||
## 第 1 次打回
|
||||
|
||||
合并最新 `origin/staging` 后,把 `report_reference_cache` 登记进 `OFFLINE_SCRATCH_NAMES`。清理逻辑没改:这个目录仍由 `consult_full_data_cache.get_or_build` 在每次调用时删掉两天前的文件。没有改两个缓存模块的行为。
|
||||
|
||||
@@ -467,12 +467,16 @@
|
||||
|
||||
| 任务书 | 进度 | 主题 | 状态 | 落点 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `TASK-rect-scoring-perf-20261013.md` | — | 校正打分提速:引导窗口平方扫描、候选不变量重复算、响应带无读取点字段、候选数上限 241(BUG-1323~1325、1345) | 待领取 | `codex/rect-scoring-perf-20261013` |
|
||||
| `TASK-node-runtime-resources-20261013.md` | — | 报告 worker abort 监听泄漏、本地 PG 适配层往返与元数据缓存、无上限内存表、用户端会话读缓存(BUG-1326~1328、1346,PG 与缓存部分 A/B) | 待领取 | `codex/node-runtime-resources-20261013` |
|
||||
| `TASK-home-sidebar-rerender-20261013.md` | — | 流式回答时侧栏每帧整栏重渲染(BUG-1329,A/B) | 待领取 | `codex/home-sidebar-rerender-20261013` |
|
||||
| `TASK-api-disk-cache-retention-20261013.md` | — | API 磁盘缓存只进不出、VedAstro 审计文件留存出生资料、失败快照久缓存、缓存键规范化(BUG-1330~1332,A/B) | 待领取 | `codex/api-disk-cache-retention-20261013` |
|
||||
| `TASK-rect-scoring-perf-20261013.md` | `PROGRESS-rect-scoring-perf-20261013.md` | 校正打分提速:引导窗口平方扫描、候选不变量重复算、响应带无读取点字段、候选数上限 241(BUG-1323~1325、1345) | 待验收 | `codex/rect-scoring-perf-20261013` |
|
||||
| `TASK-node-runtime-resources-20261013.md` | `PROGRESS-node-runtime-resources-20261013.md` | 报告 worker abort 监听泄漏、本地 PG 适配层往返与元数据缓存、无上限内存表、用户端会话读缓存(BUG-1326~1328、1346,PG 与缓存部分 A/B) | 待验收 | `codex/node-runtime-resources-20261013` |
|
||||
| `TASK-node-runtime-resources-fix-20261014.md` | `PROGRESS-node-runtime-resources-20261013.md` | **#58 第 1 次打回**:`4c3485bc` 其余全过;压测脚本放在 `frontend/scripts/` 却从 `frontend/tests/` 导入,镜像构建会失败(BUG-1140 形状,任务书指定的路径有误)。挪到 `frontend/tests/` 下非 `.test` 文件名 | 待验收 | `codex/node-runtime-resources-20261013` |
|
||||
| `TASK-home-sidebar-rerender-20261013.md` | `PROGRESS-home-sidebar-rerender-20261013.md` | 流式回答时侧栏每帧整栏重渲染(BUG-1329,A/B) | 待验收 | `codex/home-sidebar-rerender-20261013` |
|
||||
| `TASK-home-sidebar-rerender-fix-20261014.md` | `PROGRESS-home-sidebar-rerender-20261013.md` | **#59 第 1 次打回**:`63509431` 其余全过;`chat-navigation-a11y-contract` 按源码文本断言 `onOpenBilling` 旧写法未跟改(§7.8) | 待验收 | `codex/home-sidebar-rerender-20261013` |
|
||||
| `TASK-api-disk-cache-retention-20261013.md` | `PROGRESS-api-disk-cache-retention-20261013.md` | API 磁盘缓存只进不出、VedAstro 审计文件留存出生资料、失败快照久缓存、缓存键规范化(BUG-1330~1332,A/B) | 待验收 | `codex/api-disk-cache-retention-20261013` |
|
||||
| `TASK-report-reference-perf-20261013.md` | `PROGRESS-report-reference-perf-20261013.md` | 长报告出稿提速:术语替换命中预检、哈希单次遍历、同盘复用(BUG-1335~1336,A/B) | 待验收 | `codex/report-reference-perf-20261013` |
|
||||
| `TASK-report-reference-perf-fix-20261014.md` | `PROGRESS-report-reference-perf-20261013.md` | **#61 第 1 次打回**:`69c739fb` 本单全过;与清理规则合并后,长报告缓存目录补进自行清理名单 | 待验收 | `codex/report-reference-perf-20261013` |
|
||||
| `TASK-consult-prep-parallel-20261013.md` | — | 普通对话发问前准备步骤并行、模型版本短缓存、多领域并发开关(BUG-1337~1339,A/B) | 待领取 | `codex/consult-prep-parallel-20261013` |
|
||||
| `TASK-consult-prep-parallel-fix-20261014.md` | — | **#62 第 1 次打回**:`a0e223e2` 业务逻辑通过;两条源码文本断言未跟改(§7.8)、A/B 脚本从 `frontend/tests` 导入(BUG-1140) | 待领取 | `codex/consult-prep-parallel-20261013` |
|
||||
| `TASK-frontend-dead-code-20261013.md` | — | 前端死代码 17 文件与无调用方接口删除,含未登录重计算接口(BUG-1342) | 待领取 | `codex/frontend-dead-code-20261013` |
|
||||
| `TASK-api-chart-subprocess-gate-20261013.md` | — | 合盘不带 skip 串行排盘、报告无效子进程、名额轻重混用(只模拟)(BUG-1333~1334,A/B) | 待领取(排队:api-disk-cache-retention + report-reference-perf) | `codex/api-chart-subprocess-gate-20261013` |
|
||||
| `TASK-answer-effort-ab-20261013.md` | — | 答题步推理强度开关 + A/B(需模型 key) | 待领取(排队:consult-prep-parallel) | `codex/answer-effort-ab-20261013` |
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# TASK · 发问准备并行修复单(issue #62,第 1 次打回)
|
||||
|
||||
- 日期:2026-10-14
|
||||
- 原任务书:`docs/tasks/TASK-consult-prep-parallel-20261013.md`
|
||||
- 被验 SHA:`a0e223e20cebcce3479accb60f6aec44d1caadda`(`codex/consult-prep-parallel-20261013`)
|
||||
- 执行方:Grok,同一分支续做(先 merge 最新 `origin/staging`,不改写已推历史)
|
||||
- BUG 编号:沿用 BUG-1337~1339
|
||||
|
||||
## 1. 验收结论:业务逻辑通过;前端全量多出 3 条真失败
|
||||
|
||||
| 检查 | 结果 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 开关全关时的顺序 | 通过 | `turn-prep.ts` 串行分支与原 `route.ts` 的 401→423→400→503→404→409→409→503 逐条同序 |
|
||||
| 开关开时 | 通过 | 删号判定仍最先返回、在任何写库扣点之前;审核结论在 `beforeReserve` 内等齐,被拦不 reserve |
|
||||
| `readVersion` 缓存 | 通过 | 只缓存成功结果,`invalidateLanguageModelCatalog` 同时清;默认 TTL 0 |
|
||||
| tsc / lint | 通过 | 0 错 / 0 error |
|
||||
| 前端全量 `npm test`(与 staging 逐名比对) | **未通过:新增 3 条** | 见下 |
|
||||
|
||||
1. `frontend/tests/chat-session-authority.test.ts`「consult POST on a rectification session is 409, a missing id is 404」:第 65 行在 `route.ts` 源码里找 `/if \(!chatSession\) \{[\s\S]*status: 404/`——这段判定挪进了 `frontend/src/lib/consult/turn-prep.ts`(`sessionMissing()`),断言没跟着挪。
|
||||
2. `frontend/tests/consultation-workflow-contract.test.ts`「consultation plans are server-owned and bounded」:第 160 行找 `/beforeReserve: \(\{ consultationMode \}\) => createConsultationPlan\(\{/`,第 161 行找 `reserve: () => reserveConsultationModel(`——两处都改成了 `async` 函数体。
|
||||
3. `frontend/tests/runtime-sources-no-test-imports.test.ts`:`frontend/scripts/research/consult-prep-parallel-ab.mts` 第 9 行从 `../../tests/support/stub-server-only.mjs` 导入。web 镜像不复制 `frontend/tests`,推上 staging 后镜像构建会失败(BUG-1140;#58 刚因同一形状打回过一次)。
|
||||
|
||||
原任务书 §5 第 7 条已经列出要先 grep 的源码文本断言;这次漏的两条不在那份清单里,但属于同一类(AGENTS.md §7.8)。
|
||||
|
||||
## 2. 修法要求
|
||||
|
||||
1. **1、2 两条**:按 §7.3 写「原值 / 新值 / 原因」三栏改断言,**意图不得放宽**:
|
||||
- 1:改为在 `turn-prep.ts` 里锁「查不到会话 → 404」「类型不是 consultation → 409 `session_not_consultation`」,并保留第 70 行那条「不得合并成一个判断」的反向断言(针对新文件)。
|
||||
- 2:改为锁「`beforeReserve` 里调用 `createConsultationPlan`」「`beforeReserve` 在 `reserve` 之前」「`reserve` 调用 `reserveConsultationModel`」,允许 `async` 写法,但不得只查函数名存在。
|
||||
2. **第 3 条**:把 `consult-prep-parallel-ab.mts` 挪到 `frontend/tests/` 下(文件名不得以 `.test.ts` / `.test.tsx` 结尾),导入改相对路径;同步改 PROGRESS 与 `docs/testing/consult-prep-parallel-ab-20261013.md` 里的命令路径。`frontend/scripts/research/` 下其它新增文件同样检查。
|
||||
3. 再 grep 一遍 `route.ts` 被挪走 / 改写的语句在 `frontend/tests`、`tests` 里还有没有按源码文本断言的:`grep -rn "chatSession\.session_type\|getUser()\|refuseWhenAccountDeletionPending\|resolveSessionLanguageModel(\|reserveConsultationModel(\|createConsultationPlan(" frontend/tests tests`,命中的逐条确认。
|
||||
4. 业务代码不改;三个开关默认值不变。
|
||||
|
||||
## 3. 验收标准
|
||||
|
||||
- 前端全量 `npm test` 失败清单与 staging 基线逐名相同(本机另有 Docker 类失败,以基线为准);
|
||||
- `git diff a0e223e2..<新 SHA> -- frontend/src` 为空。
|
||||
|
||||
## 4. 让步顺序
|
||||
|
||||
无。第 1 次打回。
|
||||
@@ -0,0 +1,36 @@
|
||||
# TASK · 侧栏重渲染修复单(issue #59,第 1 次打回)
|
||||
|
||||
- 日期:2026-10-14
|
||||
- 原任务书:`docs/tasks/TASK-home-sidebar-rerender-20261013.md`
|
||||
- 被验 SHA:`63509431529d212c7847371e7717660d823b40e6`(`codex/home-sidebar-rerender-20261013`)
|
||||
- 执行方:Grok,同一分支续做(落后 staging 时用 merge,不改写已推历史)
|
||||
- BUG 编号:沿用 BUG-1329
|
||||
|
||||
## 1. 验收结论:一项未通过,其余全部通过
|
||||
|
||||
| 检查 | 结果 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 前端全量 `npm test`(与 staging 基线逐名比对) | **未通过:新增 1 条失败** | `frontend/tests/chat-navigation-a11y-contract.test.ts`「in-app destinations navigate client-side so the chat survives the round trip」:`The input did not match the regular expression /onOpenBilling: \(\) => openAccountDialog\("billing", \{ source: "account-menu" \}\)/` |
|
||||
| T1 稳定包装 + 比较后发布 | 通过 | 逐行看过:`latestRef` 在无依赖 effect 里写,发布 effect 在其后;未冻结首次闭包;`HomeProbe` 的故意不稳定输入未改 |
|
||||
| T2 `visibleSessions` 记忆化 | 通过 | — |
|
||||
| T3 `SidebarProvider` context 记忆化 | 通过 | — |
|
||||
| 改既有断言 | 通过 | `session-list-lifecycle` 三栏齐全,且加强了(再改一版后仍调到最新) |
|
||||
| tsc / lint | 通过 | 0 错 / 0 error |
|
||||
|
||||
**根因**:`use-home-shell-registration.ts` 把 `onOpenBilling` 从 `() => openAccountDialog("billing", { source: "account-menu" })` 改成了 `() => { latestRef.current?.openAccountDialog("billing", { source: "account-menu" }); }`,而 `chat-navigation-a11y-contract.test.ts` 第 42 行按源码文本断言旧写法(AGENTS.md §7.8:改写语句前要 grep 按源码文本断言的合同测试,同一轮跟着改)。
|
||||
|
||||
## 2. 修法要求
|
||||
|
||||
1. 只改 `frontend/tests/chat-navigation-a11y-contract.test.ts` 第 42 行这条断言,按 §7.3 写「原值 / 新值 / 原因」三栏。新正则要**仍然锁住意图**:账户菜单里的「充值」打开 billing 且 `source: "account-menu"`。例如匹配 `onOpenBilling: \(\) => \{ latestRef\.current\?\.openAccountDialog\("billing", \{ source: "account-menu" \}\); \}`;不得放宽成只查 `"billing"`。
|
||||
2. 再 grep 一遍:`grep -rn "onOpenProfile\|onOpenGeneral\|onOpenLogout\|onNewChat\|onSelectSession\|onLoadMore" frontend/tests`,有按旧写法断言源码文本的同样处理(本次全量里只红了这一条,但要确认)。
|
||||
3. 业务代码不改。先把最新 `origin/staging` 合并进分支(用 merge)。
|
||||
4. PROGRESS 末尾记一行。
|
||||
|
||||
## 3. 验收标准
|
||||
|
||||
- 前端全量 `npm test` 失败清单与 staging 基线逐名相同;
|
||||
- `git diff 63509431..<新 SHA> -- frontend/src` 为空。
|
||||
|
||||
## 4. 让步顺序
|
||||
|
||||
无。第 1 次打回;再打回会停下等产品负责人。
|
||||
@@ -0,0 +1,39 @@
|
||||
# TASK · 服务器内存与数据库往返修复单(issue #58,第 1 次打回)
|
||||
|
||||
- 日期:2026-10-14
|
||||
- 原任务书:`docs/tasks/TASK-node-runtime-resources-20261013.md`
|
||||
- 被验 SHA:`4c3485bc2352e8f9de097d81d9979092ee2bb280`(`codex/node-runtime-resources-20261013`)
|
||||
- 执行方:Grok,同一分支续做(落后 staging 时用 merge,不改写已推历史)
|
||||
- BUG 编号:沿用 BUG-1326~1328、1346
|
||||
|
||||
## 1. 验收结论:一项未通过,其余全部通过
|
||||
|
||||
| 检查 | 结果 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 前端全量 `npm test`(与 staging 基线逐名比对) | **未通过:新增 1 条真实失败** | `runtime-sources-no-test-imports.test.ts`「files copied into the web image never import from frontend/tests」:`actual: ['scripts/bench-local-pg-roundtrips.ts']` |
|
||||
| 同上,另一条新增 | 环境缺口(不算未通过) | `database-local-postgres-session-setup.test.ts` 报 `spawnSync docker ENOENT`,本机无 Docker;以 Grok 的 test:db 回报为准 |
|
||||
| T1 报告 worker 摘监听 / T1b | 通过 | 代码与新测试逐行看过 |
|
||||
| T2 元数据缓存 + 合并身份设置 | 通过 | 角色仍只来自构造函数白名单;只缓存表结构;`off` 走原语句顺序;A/B 记录 49→32 往返、中位数降 51.9%、逐字节一致 |
|
||||
| T3 三张内存表 | 通过 | — |
|
||||
| T6 登录读缓存 | 通过(默认关,理由成立) | 改密码 / 注销 / 后台三处已强制绕过;默认关是因为没有身份库真实耗时对照,符合原任务书门槛 |
|
||||
| tsc / lint / next build | 通过 | 0 错 / 0 error / `/` 仍 Static |
|
||||
| 越界 / 隐私 | 通过 | — |
|
||||
|
||||
**根因**:`frontend/scripts/bench-local-pg-roundtrips.ts` 第 16 行 `import { startPostgresFixture } from "../tests/helpers/postgres-fixture.ts";`。web 镜像只复制 `frontend/src` 与 `frontend/scripts`,不复制 `frontend/tests`,而 `next build` 会类型检查 `frontend/` 下所有 `.ts`——推上 staging 后镜像构建会失败(BUG-1140,同一形状)。**这条路径是原任务书 T4 指定的,错在任务书,不是执行偏差。**
|
||||
|
||||
## 2. 修法要求
|
||||
|
||||
1. 把脚本挪到 `frontend/tests/bench-local-pg-roundtrips.ts`(文件名**不得**以 `.test.ts` 结尾,避免被 `npm test` 自动收进去),导入改成 `./helpers/postgres-fixture.ts`;脚本头注释里的运行命令改成 `npx tsx tests/bench-local-pg-roundtrips.ts`。
|
||||
2. 同步改引用:`docs/tasks/PROGRESS-node-runtime-resources-20261013.md`、`docs/testing/node-runtime-resources-ab-20261013.md`。原任务书不改(历史记录),在 PROGRESS 里写一行「按修复单挪位置」。
|
||||
3. 不改任何业务代码;A/B 数字不用重跑。
|
||||
4. 先把最新 `origin/staging` 合并进分支(用 merge)。
|
||||
|
||||
## 3. 验收标准
|
||||
|
||||
- `frontend/tests/runtime-sources-no-test-imports.test.ts` 通过;
|
||||
- 前端全量 `npm test` 的失败清单只剩 staging 基线那 24 条 + 本单新增的 Docker 测试(无 Docker 时);
|
||||
- `git diff 4c3485bc2..<新 SHA> -- frontend/src` 为空(业务代码一字未动)。
|
||||
|
||||
## 4. 让步顺序
|
||||
|
||||
无。这是第 1 次打回;再打回会停下等产品负责人。
|
||||
@@ -0,0 +1,36 @@
|
||||
# TASK · 长报告提速修复单(issue #61,第 1 次打回)
|
||||
|
||||
- 日期:2026-10-14
|
||||
- 原任务书:`docs/tasks/TASK-report-reference-perf-20261013.md`
|
||||
- 被验 SHA:`69c739fbee3f5af6deed911482d82e49ed429bf7`(`codex/report-reference-perf-20261013`)
|
||||
- 执行方:Grok,同一分支续做(先 merge 最新 `origin/staging`,不改写已推历史)
|
||||
- BUG 编号:沿用 BUG-1335、1336
|
||||
|
||||
## 1. 验收结论:本单自身全部通过;与 #60 合并后一条合同测试红
|
||||
|
||||
| 检查 | 结果 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 与最新 staging 合并后的定向测试 | **未通过** | `tests/test_api_scratch_retention.py::test_new_scratch_local_dirs_are_registered_or_whitelisted`:`AssertionError: ['report_reference_cache']` |
|
||||
| 逐字节一致(Claude 在 Linux、屏蔽 PyJHora 复跑 A/B) | 通过 | 四张虚构盘 A / B 未命中 / B 命中 / 缓存首算的五个字段 sha 全部相同;`format=json`、`edition=reference` 两条 sha 相同 |
|
||||
| 耗时 | 与回报一致 | 未命中中位数 21.1→15.6 s(day)等,降约 22–26%,未到 35% 门槛 → 渲染提速默认关正确;命中 0.02–0.03 s |
|
||||
| 缓存键含 `today` | 通过 | `_high_rigor_birth_payload` 在缺省时把当天日期写进 `birth`,跨天不会命中 |
|
||||
| `GITHUB_SHA` | 通过 | 部署编排已传入;缺失或 `unknown` 时不缓存 |
|
||||
| `jyotish_api_server.py` | 通过 | 零改动 |
|
||||
|
||||
**根因**:#60(BUG-1330~1332,已在 staging)新增了合同测试:`scripts/` 里写 `scratch/local/<子目录>` 的地方,必须登记在 `scripts/api_scratch_retention.py` 的 `REGISTRY`(服务器周期清理)或 `OFFLINE_SCRATCH_NAMES`(自己会清理的缓存)里。本单新增的 `scratch/local/report_reference_cache/` 两边都没登记。两单各自都对,合在一起才红——这不是你的疏漏,是两单同时在做。
|
||||
|
||||
## 2. 修法要求
|
||||
|
||||
1. 合并最新 `origin/staging`(含 #60)。
|
||||
2. 在 `scripts/api_scratch_retention.py::OFFLINE_SCRATCH_NAMES` 加 `"report_reference_cache"`,旁边写一行注释:它与 `consult_full_data_cache` 同走 `consult_full_data_cache.get_or_build`,每次调用先 `prune_cache(name=…)` 删两天前的文件,自己会清;含出生资料,保留期 2 天。
|
||||
3. 不改两个模块的任何逻辑。
|
||||
4. PROGRESS 末尾记一行。
|
||||
|
||||
## 3. 验收标准
|
||||
|
||||
- `python -m pytest tests/test_api_scratch_retention.py tests/test_report_reference_perf.py tests/test_consult_card_full_source.py -q` 全绿;
|
||||
- Claude 全量 pytest 与 staging 基线逐条比对无新增。
|
||||
|
||||
## 4. 让步顺序
|
||||
|
||||
无。第 1 次打回。
|
||||
@@ -0,0 +1,66 @@
|
||||
# 磁盘缓存留存 A/B(2026-10-14)
|
||||
|
||||
对照的是本分支的父提交 `66cd60081f37a57680274633fcb3fb942d01bb2f`(建分支时的 `origin/staging`)。任务书里写的 `77057a819` 已经不是当前测试线头。A 用 `git show` 把父提交的接口文件载入同一进程,并把它的仓库路径指回本工作树,否则临时副本找不到引擎。B 是本分支。
|
||||
|
||||
演练用虚构盘,不写真实出生资料。文件都在系统临时目录,不写工作树里的 `scratch/`。
|
||||
|
||||
主测量挡住了 `jhora` 和 `vedastro` 的导入。本机装了 VedAstro SDK,并且能连上官方端口;另有一组不挡 SDK、但仍关闭外网取数,见文末。
|
||||
|
||||
## 命令
|
||||
|
||||
```powershell
|
||||
.venv\Scripts\python.exe scripts\research\api_chart_cache_byte_diff.py
|
||||
.venv\Scripts\python.exe scripts\research\api_disk_cache_ab.py
|
||||
.venv\Scripts\python.exe scripts\research\api_disk_cache_ab.py --with-sdk --sdk-probe
|
||||
```
|
||||
|
||||
## 命中率
|
||||
|
||||
20 张虚构盘 × 3 种写法 × 快速/完整 × 7 天 × 每种重复 3 次 = 2520 次取键。取键用的是真实缓存键函数,没有把 2520 次都做成完整排盘。
|
||||
|
||||
| | 改前 A | 改后 B | 变化 |
|
||||
| --- | --- | --- | --- |
|
||||
| 不同缓存键 | 840 | 280 | 少 560 |
|
||||
| 命中次数 | 1680 | 2240 | 多 560 |
|
||||
| 命中率 | 0.6667 | 0.8889 | B / A = 1.333 |
|
||||
|
||||
目标是混合写法下 B 至少为 A 的 2.5 倍。按任务书规定的「重复 3 次」算,没有达到:A 自己靠重复就已经有三分之二命中,写法合并只能再抬到约 89%。若不算这 3 次重复、只看三种写法各问一次,A 的命中率是 0,B 是 0.6667。目标数字不改。
|
||||
|
||||
## 七天后的文件
|
||||
|
||||
留存演练写的是短记录,用来数文件,不是完整盘面。期限 900 秒,只有当天的键还没过期。
|
||||
|
||||
| | 改前 A | 改后 B |
|
||||
| --- | --- | --- |
|
||||
| 清理前文件数 | 840 | 280 |
|
||||
| 清理前字节 | 109200 | 36400 |
|
||||
| 清理后文件数 | 840(旧代码没有这份清理) | 40 |
|
||||
| 当天仍有效的键 | 120 | 40 |
|
||||
|
||||
B 清理后的文件数等于当天有效键数,达到「不超过当天活跃键」的目标。
|
||||
|
||||
审计文件:B 在默认关闭时写出 0 个。达到目标。
|
||||
|
||||
负缓存:种入当天和前一天各一份,清理后剩 1 份(当天)。达到目标。
|
||||
|
||||
## 清理耗时
|
||||
|
||||
| 场景 | 结果 |
|
||||
| --- | --- |
|
||||
| 预置 10000 个已过期排盘缓存后,整次清理 | 20.174 秒,排盘目录 20170.902 毫秒,删掉 10000,剩下 0 |
|
||||
| 上面七天演练里的排盘目录 | 370.161 毫秒 |
|
||||
|
||||
目标是 10000 个文件在 2 秒内、且不在请求线程。本次在后台函数里测,不在请求线程;耗时没有进 2 秒。这是 Windows 上逐个读文件再删除的实测,目标不改。默认清理间隔仍是 1800 秒,失败快照短期限仍是 300 秒,不因为这次没进 2 秒就改默认值。
|
||||
|
||||
## 排盘耗时(一次虚构盘,快速排盘,外网关闭)
|
||||
|
||||
| | 中位数 |
|
||||
| --- | --- |
|
||||
| 未命中 3 次 | 23.036 毫秒 |
|
||||
| 命中 3 次 | 5.249 毫秒 |
|
||||
|
||||
## 响应是否还是同一张盘
|
||||
|
||||
数值等价的写法(小时 12 / 12.0 / "12",纬度数字和字符串,时区 5.5 和 "5.5",秒缺省和 0)在快速排盘下去掉 `runtime_cache` 后逐字节相同。完整排盘只差官方快照缓存上的写入时刻和到期时刻,盘面没有别的差异。父提交和本分支对同一张快速排盘、去掉 `runtime_cache` 后逐字节相同。因此这些字段可以合并进同一把缓存键。
|
||||
|
||||
不挡 SDK 的一组:本机有 VedAstro SDK,官方端口能连通。探针仍关闭外网取数。一次完整排盘 4.167 秒,没有报错。没有拉取真实快照。
|
||||
@@ -0,0 +1,12 @@
|
||||
# 真机走查 · 回答生成时侧栏不再跟着闪(BUG-1329,issue #59)
|
||||
|
||||
浏览器 A/B 未跑。部署到 staging 后,在 `https://staging.jyotisha.chat` 登录一个没有真实会话内容需要露出的账号,按顺序看:
|
||||
|
||||
1. 电脑浏览器打开首页。左侧会话列表的样子、顺序、分组和以前一样。
|
||||
2. 发一个普通问题,等回答一个字一个字出来。这段时间左侧列表不跟着闪、不跟着整栏重画。回答本身仍是逐字出现。
|
||||
3. 回答过程中点另一条会话,能打开那一条。点当前这条的菜单,改名、置顶、分享、删除仍可用,改的是刚刚点的那一条。
|
||||
4. 右上角账户菜单仍能打开资料、通用、账单和退出。
|
||||
5. 换一个人物后,左侧列表换成那个人的会话,不串到别人的。
|
||||
6. 手机宽度再看一遍第 2 步。侧栏抽屉的开关和以前一样。
|
||||
|
||||
任何一步不对,在 issue #59 里写是哪一步、哪台设备,并把标签改回 `agent/待规划`。不要贴出真实会话内容。
|
||||
@@ -0,0 +1,18 @@
|
||||
# A/B · 回答生成时侧栏重画(BUG-1329,issue #59)
|
||||
|
||||
同一测试 `frontend/tests/home-sidebar-rerender.test.tsx`,同一输入。A 是改代码前的 `66cd60081f37a57680274633fcb3fb942d01bb2f`(任务书写的 `77057a819` 已被后续提交盖过)。B 是分支 `codex/home-sidebar-rerender-20261013`。各跑 3 次。会话都是虚构的「Synthetic session N」。没有真实会话内容。
|
||||
|
||||
度量是 60 帧里的注册次数、侧栏提交次数、这 60 帧的 Profiler 耗时合计。内容用剔除函数字段后的 SHA-256 比较。
|
||||
|
||||
| 档 | A 注册 / 提交 / 耗时中位 | B 注册 / 提交 / 耗时中位 | 内容 |
|
||||
| --- | --- | --- | --- |
|
||||
| 30 条 | 60 / 60 / 2778.961 毫秒 | 0 / 0 / 0 | 两边都是 `b18f05a3d83be5b41584787b7c0495f1fcec8ef7b8ecfbdbb3c083c40796c103` |
|
||||
| 100 条 | 60 / 60 / 11799.253 毫秒 | 0 / 0 / 0 | 两边都是 `cef0a63d6f3fe72e541f9ac882b8eaf305b6933fdd07ca3002e8cd03bb139d25` |
|
||||
|
||||
A 的三次 30 条耗时:2774.964、2778.961、4202.085。100 条:10530.828、11799.253、12284.103。B 的三次都是 0。
|
||||
|
||||
正确性:换当前项后 B 注册 1 次,外壳看到新的当前项。改一行标题后标题更新。换成另一人的会话后列表换掉。只改回调版本不再注册,点「打开会话」和「改名」记到的都是第 4 版。A 在只改回调版本时还会再注册 1 次;B 不注册,但调用结果相同。
|
||||
|
||||
判定:B 在 60 帧内注册 0、侧栏提交 0,内容摘要一致,`session-list-lifecycle` 全绿。可以交付。
|
||||
|
||||
浏览器 A/B 未跑。
|
||||
@@ -0,0 +1,13 @@
|
||||
# 真机清单 · 登录缓存与长时间运行(2026-10-13)
|
||||
|
||||
对应 BUG-1326、BUG-1346。在 staging 上用两个浏览器(或一台电脑、一台手机)登录同一个测试账号。不要把账号、口令或页面原文记进仓库。
|
||||
|
||||
本轮代码里,登录读缓存默认关闭。要做下面第 2–4 步,服务器环境变量 `IDENTITY_SESSION_COOKIE_CACHE` 必须是 `on`。未设置或其它值时,改密码后另一台设备会马上要求重新登录,第 2 步不会出现「还能浏览大约 5 分钟」。
|
||||
|
||||
| 步 | 怎么做 | 通过标准 |
|
||||
| --- | --- | --- |
|
||||
| 1 | 两台设备都登录,各自打开首页并翻一两页 | 都能正常看到自己的会话,不要求反复登录 |
|
||||
| 2 | 设备 A 修改密码。5 分钟内用设备 B 只浏览首页、会话列表和星盘,不要改密码、不要注销 | 设备 B 在这 5 分钟里仍能浏览 |
|
||||
| 3 | 仍在这 5 分钟内,用设备 B 尝试修改密码或申请注销账户 | 被拒绝,不能拿旧登录做这两件事 |
|
||||
| 4 | 等到改密码已超过 5 分钟,再用设备 B 刷新 | 被要求重新登录 |
|
||||
| 5 | 用新密码在设备 B 重新登录,再浏览一次 | 能进入,会话列表还在 |
|
||||
@@ -0,0 +1,21 @@
|
||||
# 本地数据库往返对照(2026-10-14)
|
||||
|
||||
环境:Windows,Docker 29.8.0,Node v22.23.2。脚本 `frontend/tests/bench-local-pg-roundtrips.ts`(2026-10-14 按修复单从 `frontend/scripts/` 挪来,数字未重跑)。库是测试用的临时 Postgres,数据是虚构用户。每组 50 遍,重复 3 组,先各热身 1 遍。往返数是每组平均值的中位数。耗时中位数是三组中位数的中位数。p95 是全部 150 遍的单遍耗时。
|
||||
|
||||
判定用第二次运行(输出里带三组原始数)。第一次运行同样是 49 降到 32,中位数 89.51 毫秒降到 32.70 毫秒,内容一致,方向相同。
|
||||
|
||||
| 模式 | 开关 | 往返 | 中位数(毫秒) | p95(毫秒) | 三组(往返 / 中位数毫秒) |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| A | 两个都关 | 49 | 75.84 | 88.25 | 49 / 82.51;49 / 75.84;49 / 73.81 |
|
||||
| B | 两个都开 | 32 | 36.48 | 39.47 | 32 / 36.66;32 / 36.48;32 / 35.71 |
|
||||
| B1 | 只开元数据缓存 | 40 | 40.54 | 44.37 | 40 / 41.56;40 / 40.54;40 / 39.86 |
|
||||
| B2 | 只开合并身份设置 | 41 | 67.83 | 72.75 | 41 / 68.46;41 / 66.47;41 / 67.83 |
|
||||
|
||||
- 往返:32 ≤ 49 的 70%(34.3)。通过。
|
||||
- 耗时:下降 (75.84 − 36.48) / 75.84 = 51.9%,不低于 15%。通过。
|
||||
- 四种模式的业务返回逐字节一致(`payloadMismatch` 为 false)。通过。
|
||||
- 只开其中一个时,往返都还高于 70% 那一刀;只合并身份设置时,这一次耗时只降了约 10.6%。两个一起才过门槛,所以两个都默认打开。写成 `off` 仍走改前的语句顺序。
|
||||
|
||||
登录读缓存没有放进这次真库计时。内存里的登录测试看到普通读取的查库次数从 3 降到 1,但那不是身份库的耗时对照,所以 `IDENTITY_SESSION_COOKIE_CACHE` 保持默认关闭。
|
||||
|
||||
`npm run test:db` 两轮都是 81 项、通过 68、失败 13、取消 0。失败名称与 `tools/agent-loop/windows-known-failures.txt` 的 13 条逐条相同,没有多出来的。因此两个数据库开关默认打开。
|
||||
Reference in New Issue
Block a user