Commit Graph
249 Commits
Author SHA1 Message Date
Jesse_ChenandClaude Opus 5 e4788dfc00 docs(tasks): 换掉两条增长冻结口径 + page.tsx 状态下沉第一簇 + C1 提前
产品 2026-09-15 三项拍板,落成两份新单与两处既有单的修订:

- 新增 TASK-freeze-metric-change-20260915(无 BUG 号,后面两单的前置):
  两条冻结余量已用完(page.tsx 1951/1951 余 0;api server 11334/11363 余 29),
  冻结从「逼新代码往外走」退化成拦路。实证:page.tsx 行数砍 59% 但 Home()
  的 useState 从 56 涨到 66;api server 225 个类方法只有 12 处真碰 HTTP。
  主门换成耦合指标,行数降为粗护栏;同时推翻 §6「参数式 hook 内部保持
  0 个 React hook」——那正是状态搬不走的原因。
- 新增 TASK-home-state-lowering-20260915(无 BUG 号):先搬 rectification*
  那 15 个 state 进已经是 dynamic 子树的校正面,Home() useState 66 → ≤53。
  零行为变化;串行在 freeze-metric-change + C2 + R3 之后。
- 修订 TASK-consultation-external-evidence-cache-20260915:依赖反转,C1 排在
  API server 拆解之前(它动模块级函数,拆解动类方法);补「不得新增类方法、
  行数余量仅 29」的硬红线。
- 修订 TASK-api-server-decomposition-20260916:串行依赖加 C1 与
  freeze-metric-change;__new__ 计数按 grep 的 4 计(原文 3 是文件数);
  阶段 4 收尾口径改写;基线 11,314 → 11,334。

纯文档推送,不触发门禁、不发布镜像、不部署。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-15 23:15:37 +00:00
Jesse_ChenandClaude Opus 5 11893c7f97 docs(tasks): 普通聊天审计三单(外网缓存 / 记忆三缺口 / 对话上限)
只读审计 origin/staging @ 6b3248bf 后出的三份任务书,含产品 2026-09-15
拍板的三项口径:

- external-evidence-cache(BUG-727/728,Python,串行在 api-server-decomposition
  之后):每轮每域同步等 api.vedastro.org,cProfile 前三名全是 TLS 往返,本地
  swisseph 只占 0.022 s;前台 1.5 s / 后台 8 s / 2 个 worker 且超时不 cancel。
  定案按「出生数据+岁差+交点+UTC 日期」缓存,与引擎内部同键;不许「干脆不调」,
  那会重开 BUG-301。另 western_evidence_packet 122 KB 无人读。
- context-memory(BUG-729/730/731,TS,可并行):droppedCount 算了没人读、
  摘要阈值与预算脱钩(窗口 < 70,667 即每轮静默丢)、写满时不继承摘要。
  定案静默继承,摘要文本永不由客户端提供。
- session-capacity(BUG-732,一份迁移,可并行):200,000 额度一半被思考文本
  吃掉,约 19 轮即写满。定案思考文本不计入,另设按整条 JSON 计的物理上限。

纯文档推送,不触发门禁、不发布镜像、不部署。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-15 22:47:55 +00:00
Jesse_ChenandClaude Opus 5 a8d29d1b6c docs(tasks): 记录产品两项决定(分类用会话模型 / 年份采样不改)
产品 2026-09-15 对审计单里挂着的两个待拍板项给出结论,两项都是「不改」:

- 意图分类继续用会话选定的模型,不引入便宜快模型,模型目录不新增
  「工具模型」角色。failure-attribution 单 §4.6 立为决策记录,§10 从
  「待产品拍板后另开单」改为已决定不做;本单只改归因,不改用哪个模型。
- 只给年份的事件继续采满 12 个月,降采样不做、研究单也不立。
  engine-memoization 单 §4.2 / §11 同步,并写明后续不得以性能为由重提。

两条都加了「要重提必须先拿到产品新的授权」,避免下一轮被当成遗漏又提一次。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-15 17:17:29 +00:00
Jesse_ChenandClaude Opus 5 e4f9f3ee0f docs(tasks): 校正链路审计四单(引擎记忆化 / 故障归因 / 渲染拆分 / 档案缓存)
只读审计 origin/staging @ 6b3248bf 后出的四份任务书:

- engine-memoization(BUG-721,纯 Python 可并行):一次重算 45% CPU 在重复
  算同一份 Shadbala,过境盘按候选算了 2196 次(应 36),鉴别探针算两遍,
  _cached_rows 是死代码。本机等价实验 3358 → 1604 ms,candidate_scores 与
  decision_receipt 逐字相同。只做记忆化,不改算法。
- failure-attribution(BUG-722/723/724,独占 route.ts):分类器失败被说成
  用户说不清且丢证据;引擎 429 被当成引擎坏、不重试不打日志(复发自
  BUG-715);attempt 210s × 2 > maxDuration 240s(复发自 BUG-059)。
- settled-render-split(BUG-725,前端可并行):校正会话流式每帧重渲整条
  对话并重跑已结算消息的 Markdown;BUG-473 的咨询面拆分没有跟过来。
- request-dossier-cache(BUG-726,串行在 failure-attribution 之后):一轮
  取 3.44 次整份 Case 档案,改成写即失效的请求作用域缓存,零调用点改动。

纯文档推送,不触发门禁、不发布镜像、不部署。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-15 17:13:52 +00:00
jesse-ux 6b3248bf53 fix(vedastro): pin SDK at install and cap free-tier wait
Independent Staging Quality Gate / validate (push) Successful in 9m36s
Independent Staging Quality Gate / publish (push) Successful in 18m18s
Image build patches vedastro.check_for_update to a no-op after pip install so import cannot hit pypi or upgrade the pin. Free-tier queue waits are capped to VEDASTRO_TIMEOUT_SECONDS and fail fast as free_tier_rate_limited. Gateway status exposes runtime mode as booleans without secrets. BUG-719 resolved; BUG-720 stays investigating until production env is filled in.
2026-09-16 00:25:15 +08:00
jesse-ux 62be52dacf fix(chart): skip VedAstro on chart-page first paint
Independent Staging Quality Gate / validate (push) Canceled after 2m16s
Independent Staging Quality Gate / publish (push) Canceled after 0s
The natal /api/chart request from the chart page now sends skip_vedastro_main_entry_overview, matching the ephemeris page. Mapper and contract never read that evidence. BUG-718 recurs from BUG-161. Tests lock both foreground natal paths.
2026-09-16 00:22:00 +08:00
Jesse_ChenandClaude Fable 5 ce1939b074 docs(tasks): 星盘页与 VedAstro 外网调用脱钩 + 运行期真相两单
星盘页首屏那一发 /api/chart 没传 skip_vedastro_main_entry_overview,
本机实测冷算 0.40–0.66 秒里约 0.36 秒是 VedAstro 空转(连 endpoint 都
没配的情况下);带标志的同一调用是 5 毫秒。生产 env 开着 network 与
fanout,等于首屏同步等 24 个外部请求加 3 次领域扫描,而前端 mapper 与
contract 根本不读这份证据。BUG-718,复发自 BUG-161。

运行期单记录两条新发现:官方 vedastro==1.23.25 其实是 REST 客户端,
且 import 时请求 pypi 并 pip install --upgrade 自升级(实测 pin 装完
一 import 即变 1.23.26);无 key 时免费层排队是同步 sleep 加进程级
全局锁,24 个请求约 4.8 分钟堵住前台线程。台账补 ERR-107 / ERR-108,
生产 env 核对清单交产品负责人执行。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 15:47:32 +00:00
jesse-ux 69ede4367f fix(ci): migrate staging automatically before deploy
Independent Staging Quality Gate / validate (push) Successful in 10m6s
Independent Staging Quality Gate / publish (push) Successful in 4m18s
Quality gate now dispatches Migrate Staging Database, waits for success, then dispatches Deploy staging. Automatic migrate attests the in-progress gate run so the two jobs cannot deadlock. Manual migrate is unchanged. Staging schema changes must stay backward-compatible with the currently deployed app.
2026-09-15 23:36:09 +08:00
jesse-ux 1a73f64ecd fix(ci): let staging migration resolve the latest gated SHA
Independent Staging Quality Gate / validate (push) Successful in 9m38s
Independent Staging Quality Gate / publish (push) Successful in 2m7s
Leave Migrate Staging Database deploy_sha empty (or type latest) to use the newest successful backend-quality-gate push. Filled 40-hex still takes the original path. Production workflows stay required.
2026-09-15 23:19:44 +08:00
Jesse_ChenandClaude Fable 5 9bf13df023 docs(tasks): auto-migrate staging before deploy instead of a manual button
今天 backend-quality-gate 通过后自动 dispatch deploy-staging,但
deploy-staging.yml 里一次都没提到迁移——忘点 Migrate Staging Database 就让
新代码跑在旧 schema 上,没有任何东西会拦。这已经靠人记着(见
PROGRESS-consultation-context-and-cache-20260906「部署前须先 Migrate」)。

判据是现成的:db-migrate.mjs 的 check 模式有挂起返 3、无挂起返 0,还顺带查
checksum 漂移。而且迁移本身靠 migration.schema_migrations 台账幂等,无挂起时
天然 no-op——所以不必先检测再决定跑不跑,直接每次都跑,少一个分支。两个
workflow 又共用 concurrency group staging-mutation,链式触发不会互相踩。

新顺序:gate 通过 → 触发迁移并等它成功 → 才 dispatch 部署。迁移失败不部署。

这条顺序引入一个以前不存在的纪律:迁移完成到镜像替换之间,旧代码会短暂跑在
新 schema 上。所以 staging 迁移必须对当前已部署的代码向后兼容,破坏性变更要
拆成"先加、发代码、再删"两轮。以前迁移窗口由人控制所以不需要这条,自动化后
它是硬约束,必须同轮写进 AGENTS.md §7.6——不写就是埋雷。

回滚部署不自动迁移(迁移不会因镜像回退而撤销)。生产两个 workflow 一行不碰:
restore_verified 本质上是人对恢复点的担保,不可自动化。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 15:14:21 +00:00
Jesse_ChenandClaude Fable 5 de47c06d97 docs(tasks): stop making the product owner hand-copy a 40-hex SHA
migrate-staging-database 的 deploy_sha 挡的是「迁移必须钉在真正过了门禁的
修订上」:格式校验、查该 SHA 有没有成功的 backend-quality-gate 运行、与
staging head 比对后把纯文档前进的判定交给背书过的 controller。这三条不能丢。

但产品手填的那个值,恰恰就是「最新一个过了门禁的 staging 提交」——机器能
自己算,而且需要的 API 查询在同一步里已经写好了。改成:留空即自动解析,
填了就完全走原路径(回滚与迁移到更早修订的唯一手段)。解析出来后仍然照常
跑一遍全部校验,两条路径共用同一套门。

范围比看上去小:Deploy Staging 在门禁通过后由 backend-quality-gate 自动
dispatch,正常根本不用点;真正每次都要手填的只有 Migrate Staging Database
一个按钮。

生产两个按钮保持手填。它们额外要 allow_rollback / recovery_reference /
restore_verified,设计意图就是逼人说清楚要发什么;在生产省掉这步不是便利,
是拆护栏。

AGENTS.md §2.7 禁止代理改 workflow,产品本次明确授权,已写进决策记录,
否则执行方会拒改;授权范围仅限本单点名的文件与改动。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 15:07:08 +00:00
Jesse_ChenandClaude Fable 5 ebd6175b40 docs(tasks): give the title repair a button — move it into a migration
BUG-699 / 704 的数据修补写成了 repair-rectification-session-titles.mjs,要
SCHEMA_DATABASE_URL。但 deploy/run-staging-migration.sh 只做三件事:跑
002-ensure-business-compatibility-roles.sql、compose --profile migration run
--rm migrator 应用 frontend/supabase/migrations/ 下的 SQL、打印已应用清单,
不执行任意 Node 脚本。其余 workflow 也都不跑它。于是一个已经验收的修复卡在
"没有按钮"上,用户的历史会话名字还全是错日期。

脚本里 TITLE_MATCH_SQL / TITLE_APPLY_SQL 和活跃时间回填本来就是纯 SQL,
Node 只负责连库和打印。搬进一次性迁移就能复用产品已经会用的
Migrate Staging Database 按钮,不用 SSH、不用口令。

生产安全性已核实:7b620c7a 没有 use-rectification-surface.ts,标题是固定的
「生时校正」也不写库,where 在生产上自然匹配 0 行,天然 no-op。

红线:SQL 逐字照搬不许优化;不得动 workflow 或 compose;用户手写标题不碰;
必须幂等;两段 update 各要 RAISE NOTICE 打行数——那是产品唯一看得到数字的
地方。脚本降级为只读核对工具,不删。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 15:01:30 +00:00
jesse-ux 5a8328e591 fix(web): paint the chart page shell before engine calls
Independent Staging Quality Gate / validate (push) Successful in 27m22s
Independent Staging Quality Gate / publish (push) Canceled after 47s
BUG-715/716/717: typed engine failures with logs and split copy, natal-only open, on-demand tabs, 10s timeout, in-memory cache, no speed-promise eyebrow.
2026-09-15 22:51:15 +08:00
Jesse_ChenandClaude Fable 5 8caa2a2b4c docs(tasks): P1 — the chart page blocks the whole document on five engine calls
先排除了两个嫌疑,都有实测:本机起 6.9.16 引擎,按 chart-view-load 的同一
套参数逐个计时,/api/chart 0.60s、chara 0.00s、varga_full(17 分盘) 0.00s、
western 0.00s、qizheng 0.15s,合计 0.75 秒;把这五个真实响应喂给
buildChartView 跑 13 种形态(四种 birthTimeStatus、三种 ayanamsa、缺
placeLabel/timezoneId/name,以及 chara/varga/western/qizheng 分别为 null),
13 种全部 status=ok,一次没抛。引擎不慢,mapper 不抛。

瓶颈是结构:/chart 在构建里是 ƒ Dynamic,而 c6ecb86f 把侧栏入口从
router.push 改成 window.location.assign,于是点一下就整文档重载,服务端
SSR 里 await 完 1 串 4 并才开始画,浏览器在此之前什么都没有;engineTimeoutMs
是 45 秒,maxDuration 60,白屏能真跑满 45 秒(BUG-716)。

失败又不可诊断:postEngine 的 !response.ok 与 catch{} 把 429、500、超时、
坏 JSON 全碾成同一个 null,零日志;chart-view-load 末尾还有一个 catch{}。
「引擎忙等一下会好」和「这张盘有 bug 等多久都不会好」共用一句「过一会儿
再打开」(BUG-715)。

开页还并行打 /api/western 与 /api/qizheng——两个都在 HEAVY_COMPUTE_PATHS
里、配额只有 2,一次开页吃满整台容器的重计算配额,而这两路只喂给用户
可能根本不点的两个 tab;cache: "no-store" 且无服务端缓存。eyebrow
「直接计算 · 打开即有 · 不消耗点数」在失败分支也印一遍,正压在「算不出来」
上面(BUG-717)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 14:13:59 +00:00
jesse-ux a38a941522 fix(qizheng): pass school options into the vendored chart and stabilize gates
Independent Staging Quality Gate / validate (push) Failing after 8m1s
Independent Staging Quality Gate / publish (push) Skipped
BUG-710: call getSevenGovernorsChart with ketuMode/siderealMode so
calculation.ketu_mode is the engine school, not the request echo.
BUG-711: stop forbidding /ephemeris in the sidebar contract.
BUG-712: compare ephemeris event longitudes at 6 decimals and fail
closed when the golden is missing.
2026-09-15 17:54:20 +08:00
jesse-ux 6bb892b826 fix(chat): keep page.tsx at the 1951-line freeze after lookup wiring
Independent Staging Quality Gate / validate (push) Failing after 6m40s
Independent Staging Quality Gate / publish (push) Skipped
Move BUG-705 bootstrap selection + session lookup into
resolveLookupBootstrap so Home only awaits once. The 1951 cap in
chart-view-route.test.ts is unchanged.
2026-09-15 17:40:17 +08:00
Jesse_ChenandClaude Opus 5 fadb64fbcf docs(tasks): accept the three read-only page briefs and file the fixes
Re-ran the checks independently rather than taking the progress notes at
their word. Most red lines hold: the api server sits at 11334 of 11363,
vendor/** is gated, the image installs nodejs and copies vendor, NOTICE
carries the Apache-2.0 attribution, the forbidden CLI subcommands are
blocked, neither new BFF imports billing or mastra, vedic-chart-svg did
not move, tsc is clean and lint has no errors.

Three findings. The qizheng adapter validates ketu_mode and
sidereal_mode, echoes them into calculation.*, and never passes them to
the engine: asking for descending-node returns 200 with a chart still
computed on the apogee school and no warning. The ephemeris brief
asserted that app-sidebar must not mention /ephemeris, which contradicts
the chart-page brief that was told to add both entries, so staging is
red. The ephemeris_events golden compares full-precision floats and
regenerates itself when missing.

Staging also still reports deployment.gitCommit 2d7698ea, six commits
behind, with gated paths changed in between.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-15 09:35:49 +00:00
Jesse_ChenandClaude Fable 5 4161222b2b docs(tasks): accept f51e494c and file the page.tsx growth-freeze fix
六条缺陷(BUG-699/704/705/706/708/709)全部实现,实现方式与任务书一致:
lookup 三分支(found/missing/unavailable,5xx 不宣告删除也不清 ?c=)、
交付卡保留而只置灰采用、按钮判据用 vargaStyleFollowupRenderable 复用
buildChoiceCard 的同一套门而不是复制条件、「相对支持度」进 MACHINE_VOICE_
LEXICON。文档齐全,生产 7b620c7a 受影响面也核对过了(不受影响)。

Linux 门禁:tsc 0 错;lint 0 error / 119 warning;本轮 8 个合同套件 130 项
全绿;build exit 0、/ 仍 ○ Static;首屏 gzip +0.13%。全量失败 父提交
d3a2c48b 32 → f51e494c 33。

多的一条是 page.tsx 从 1951 涨到 1964 行,撞了 chart-view-route.test.ts 的
<= 1951 上限,即 AGENTS.md §6 的增长冻结。d3a2c48b 绿、f51e494c 红,各跑
两次稳定复现。逻辑本身已经在 lib 里,超的只是十来行接线,搬出去即可,
不得放宽上限。

连带:staging 的 deployment.gitCommit 停在 2d7698ea,其后 6 个含门禁路径的
提交未部署,这条红很可能是原因之一。修好前产品没有环境可以实测。

另记两条无自动化覆盖的欠账:本轮动了数据库结构(新增触发器与函数)但
test:db 没跑,而门禁 workflow 里也不跑 DB 套件;标题与 updated_at 的修补
脚本在 staging 未执行,损坏面数字还空着。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 09:23:30 +00:00
jesse-ux f51e494c5a fix(chat): keep rectification sessions findable and keep the delivery card
Independent Staging Quality Gate / validate (push) Failing after 6m45s
Independent Staging Quality Gate / publish (push) Skipped
Rectification answers now advance chat_sessions.updated_at (BUG-704).
A ?c= id missing from the loaded page is fetched before anyone may call
it deleted (BUG-705). The range card no longer has a post-card tie-break
button; live questions leave the card visible with adopt locked
(BUG-706/708). Spoken copy bans 相对支持度 (BUG-709).

Task docs assigned 700-704; qizheng already took 700-703.
2026-09-15 17:10:53 +08:00
jesse-ux d3a2c48ba5 feat(web): add read-only /ephemeris page
Independent Staging Quality Gate / validate (push) Failing after 7m30s
Independent Staging Quality Gate / publish (push) Skipped
2026-09-15 16:40:56 +08:00
jesse-ux 830799fafb feat(chart): add a read-only natal chart page
Independent Staging Quality Gate / validate (push) Canceled after 5m23s
Independent Staging Quality Gate / publish (push) Canceled after 0s
Open /chart from the sidebar without billing or a model. Five tabs; Western and Qizheng stay unavailable until those endpoints land. Ephemeris nav points at /ephemeris (404 until that page ships).
2026-09-15 16:27:50 +08:00
jesse-ux a3dbbde4a3 docs(tasks): record qizheng staging SHA e776cf9d 2026-09-15 16:24:33 +08:00
jesse-ux e776cf9d83 fix(qizheng): copy vendored stem-branch files from local upstream checkout
Independent Staging Quality Gate / validate (push) Canceled after 4m51s
Independent Staging Quality Gate / publish (push) Canceled after 0s
Read G:/Ferti/yinduzhanxing-codex-add-birth-time-rectification-skill (a911c890) and copy the listed vendor files by content. Rebuild the adapter from the 168-line CLI wrapper, then apply school parameters, boundary rewrite, and sanitized errors.
2026-09-15 16:21:04 +08:00
jesse-ux 25851dd338 feat(qizheng): vendor stem-branch and expose three read-only chart APIs
Add Apache-2.0 @4n6h4x0r/stem-branch 0.8.0, a seven-governors adapter,
and POST /api/qizheng, /api/western, /api/ephemeris_events.

BUG-700 remains blocked (do not call --pillars). BUG-701 and BUG-702 are
resolved. BUG-703 is investigating (panchanga Lahiri). Skill is not bumped.
2026-09-15 16:10:21 +08:00
Jesse_ChenandClaude Fable 5 3e58e85f8f docs(tasks): P0 — tie-break entry destroys the delivery card; session list lies about rectification
两组缺陷,分两单。

会话列表单追加 BUG-700/701:全仓只有 append_consultation_question 这个
咨询 RPC 写 chat_sessions.updated_at,校正的 turn 走自己的表从不推进,于是
校正会话的 updated_at 冻结在创建时刻——连着几小时答题也不动位置。叠加
BUG-699 的改名,列表变成「名字是今天、排序是旧日期」。而 resolveBootstrap-
SessionSelection 的 ?c= 只比对当前已加载那一页(SESSION_PAGE_SIZE = 40),
翻不到就判 missing、打「该对话不存在或已被删除」并清掉 URL。查过了没有任何
删除路径被触发,会话大概率仍在库里。

新单 BUG-702~704:applyLiveCandidateOffer 遇到任何未答的 choice/collect_spoken
就把 candidateOffer 从每一条消息上剥掉,而 requestTieBreak 必然写入这样一道题
——点卡上的按钮必然丢卡。按钮亮不亮看 tieBreakPersonalityAvailable(只看
followup),题能不能画成选择题看 buildChoiceCard 的 styleOptions.ok /
canRenderYearlessChoice,两个判据不一致,于是按钮亮着、点开是裸题,卡又没了,
两条路都断。交付旁白还写了 VOICE 明令禁止的「相对支持度」,并在自称不再问
分盘题的同一屏提供分盘题入口。

产品重申 BUG-686 的原意:卡上不要参考题按钮,出卡前收集完,以卡结算。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 07:44:40 +00:00
Jesse_ChenandClaude Opus 5 4cacea8eb1 docs(tasks): brief the api server decomposition
The line-count cap is nearly spent (11314 of 11363), but counting lines
misreads the problem. Three call sites outside the HTTP layer reach the
business logic by doing JyotishAPIHandler.__new__ on an uninitialised
handler — consultation_workflow_service twice, which is what MCP calls,
plus the golden capture and the offline accuracy report. The declared
"shared boundary" module imports back into the monolith, so the
dependency arrow points the wrong way and new logic has nowhere to land
except that class.

Four phases: remove the __new__ backdoor, extract the remaining methods
over 150 lines, replace the 72-branch elif dispatch with a table, then
re-freeze the baseline with a 50-line allowance instead of 300. Pure
relocation; the 3841-line security suite is the safety net and none of
its assertions may change. Serial after the qizheng brief, which owns
the file until it merges.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-15 07:19:05 +00:00
Jesse_ChenandClaude Opus 5 6f74aa6704 docs(tasks): brief the read-only chart and ephemeris pages
Splits the remaining work into three briefs that own disjoint files so
agents can run them in parallel. The qizheng brief is widened to own
scripts/jyotish_api_server.py outright and register all three read-only
endpoints (/api/qizheng, /api/western, /api/ephemeris_events), because
the chart page needs a tropical natal route that no path exposes today
and the ephemeris page needs ingress/station scanning that /api/transit
does not provide.

The chart-page brief owns app-sidebar.tsx and adds both nav entries; the
ephemeris-page brief owns only its own route. Checking the tree changed
one plan: vedic-chart-svg.tsx is also imported by rectification-board, so
the component stays where it is instead of moving to a shared layer.

BUG ranges are pre-allocated per brief to keep parallel work from
colliding, and the panchanga Lahiri/Raman split found while prototyping
is filed as investigating rather than fixed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-15 07:09:23 +00:00
Jesse_ChenandClaude Opus 5 b3ccef4cbb docs(tasks): brief the native qizheng chart integration
Upstream branch codex/add-birth-time-rectification-skill a911c890 vendors
@4n6h4x0r/stem-branch 0.8.0 (Apache-2.0) and adds a seven-governors chart
adapter. Brief scopes the intake: vendored archival plus NOTICE, Node
runtime in the API image, vendor/** in gated-paths, a parameterised
adapter, and a thin /api/qizheng registration under the 11363-line cap.

Three defects were reproduced locally before filing: the four-pillars
hour branch is derived from the UTC wall clock (BUG-700, out of scope and
red-lined), ketuMode is pinned to the apogee school with no request
parameter (BUG-701), and the adapter boundary claims star spirits and
dignities that come back empty or unclosed (BUG-702).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-15 06:59:47 +00:00
jesse-ux 2d7698ead3 fix(chat): keep stored rectification titles on open
Independent Staging Quality Gate / validate (push) Successful in 11m43s
Independent Staging Quality Gate / publish (push) Successful in 2m3s
Opening a saved birth-time session no longer restamps the title or updatedAt from the wall clock. Occupies BUG-699, recurrence of BUG-553.
2026-09-15 14:48:03 +08:00
Jesse_ChenandClaude Fable 5 224244c014 docs(tasks): P0 brief — opening a stored rectification session renames and re-sorts it
openRectificationCase 构造 merged 时无条件 title: resolveSessionTitle(…) 与
updatedAt: timestamp()。同一个对象里 pinned 和 archivedAt 是从 existing 继承
的,说明作者知道这条路径会跑在已存在的会话上,只是漏了这两个字段。
resolveSessionTitle 的日期来自 new Date(),于是 9/12 建的会话被改名成
「9月15日 · 生时校正」,同名时再追加时:分。

两种损坏持久性不同,修复时要分开:persistSession 的 update 分支写 title
但不写 updated_at(BUG-553 的正确遗产),所以标题是永久写坏服务端,排序
只坏在客户端 state、刷新自行恢复。已坏的历史标题按 created_at 修回,取不到
就退回不带日期的中性标题,不猜。

复发自 BUG-553——它的防复发「updatedAt 只由对话活动推进」只是 Bug 记录里
的一句话,没有任何测试执行,且当时只覆盖元数据 PATCH 与五条客户端路径,
漏了当时就存在的校正 open 路径。本单要求把那句话变成测试。

咨询侧三处 resolveSessionTitle 都有 messages.length === 0 && 通用标题的守卫,
不受影响,明令不得顺手改。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 06:25:18 +00:00
jesse-ux ff5023a282 test(chat): restore two-layer markdown contract counts
Independent Staging Quality Gate / validate (push) Successful in 9m19s
Independent Staging Quality Gate / publish (push) Successful in 11m32s
Spoken and report layers each keep a message-markdown shell and both must call renderProse; login hard-jumps drop from 4 to 3 after the onboarding suggestion effect went away. No product code.
2026-09-15 13:27:17 +08:00
Jesse_ChenandClaude Fable 5 ca5ecafc1a docs(tasks): accept the two UI rounds and file the contract-test fix
Linux 上补了执行方在 Windows 上做不到的两项:全量 npm test 与 next build。

通过:tsc 0 错;lint 0 error / 120 既有 warning;测试总数 3214 → 3232;
next build exit 0、/ 仍是 ○ Static;首屏 JS gzip-9 585,246 → 583,660 B,
-1,586 B / -0.27%(口径同 09-02、09-06)。任务书逐条对照,删除范围与保留
范围都对,guided_topic 枚举保留、录入链路未被误删、复制仍走全文。

未通过 2 条,同一类——契约测试跟着代码漂了没更新,不是产品回归:
chat-bundle-splitting-contract 断言 message-markdown 包裹恰好 1 个,两层
可见性后是 2 个(同一 test 里 plainParagraphs(spoken) 字面量也已不存在);
chat-navigation-a11y-contract 断言 window.location.assign("/login") 恰好
4 处,删建议问题入口带走一处变成 3。基线 27 条失败与改后逐条一致,新增
的就是这两条。

执行方把全量测试记成 Windows 环境缺口(SKILL.md symlink EPERM、CRLF),
判断对他们的机器成立,也因此没机会看到这两条。修复单只改测试、禁止碰
frontend/src,要求失败数回到 27。

顺带澄清:PROGRESS 里记的 membership-page「login redirects」CRLF 失败在
Linux 上通过,不是回归。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 05:14:43 +00:00
Jesse_ChenandClaude Fable 5 4c002a084e docs(tasks): brief the settings dialog size recurrence and the nav emphasis bar
BUG-698 复发自 BUG-554。四个分区确实都映射到 .settings-modal,CSS 里
width 与 height 也都写了——但 .settings-modal 的 height/max-height 只用
dvh,没有 vh 回退。不支持 dvh 时整条声明作废,height 退回 auto,高度改由
内容决定,正是「切分区就立马缩小」。全文件 18 处 dvh 只有 sidebar-provider
那一处配了回退,本仓自己知道这个写法。

BUG-554 的防复发「设置弹窗必须同时声明 width 与 height」拦不住这次:它
检查声明存在性,不检查声明是否生效;守它的断言也只是一句 CSS 文本匹配。
本单把防线换成「height 用 dvh 必须先写 vh 回退」的全文件契约测试。

首要嫌疑不等于已证实——本会话没有浏览器。任务 1.1 要求执行方先量四个分区
的 getBoundingClientRect 并确认 height 是否被划掉,量不出来就转 investigating
交回产品,不得盲改。

另去掉设置分区菜单的左侧强调条(移动端下边框同理)。删之前必须先拆开选中态
与悬停态——它们共用同一条声明,色条是当前唯一的区分。左侧会话列表的 2px 色条
本轮保留,口径暂时不一致已授权。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 04:56:45 +00:00
jesse-ux 6c748d86b0 fix(ui): 44px coarse hits and align CSS breakpoints
Independent Staging Quality Gate / validate (push) Failing after 8m53s
Independent Staging Quality Gate / publish (push) Skipped
Touch-screen message actions get a 44x44 hit once gap and bottom margin open to 20px; fine-pointer geometry stays 27x34. Tablet CSS cuts at 1023 to match sidebarViewportForWidth. Report centre/reader join the 767 mobile cut; TOC keeps 860. Occupies BUG-695/696/697.
2026-09-15 12:46:59 +08:00
jesse-ux 8144fca27d fix(chat): fold natal reports and drop homepage topic cards
Independent Staging Quality Gate / validate (push) Failing after 9m47s
Independent Staging Quality Gate / publish (push) Skipped
Homepage no longer waits on /api/onboarding for six starter questions.
Natal answers show the spoken layer first; the Level 2 skeleton sits in a
collapsed 完整分析 block. Wide tables scroll sideways on a phone. Form
inputs are 16px so iOS does not zoom on focus.
2026-09-15 12:27:16 +08:00
Jesse_ChenandClaude Fable 5 899f955d4b docs(tasks): fold two mobile blockers into the reading-load round, brief touch targets and breakpoints
2026-09-15 的 UI 走查(web + 移动端)结果落盘。

并入 TASK-chat-reading-load:折叠层里的四列表在窄屏没有重排规则
(767 的卡片化只认三列,width:100% 又让 overflow-x 永不触发),它是
折叠能不能落地的前置;全局 input/select 是 14px,iOS 聚焦会把整页放大,
命中整条注册与资料录入漏斗。

新单 TASK-mobile-touch-and-breakpoints(BUG-695~697):消息操作按钮
命中区 27×34 且相邻只隔 1px;CSS 平板上限 900px 与 sidebar-state.ts 的
1024 不一致,901–1023 是混合态;报告域 720/760/860 三刀互不对齐,
761–860 目录已塌、正文还是桌面。含断点白名单契约测试作为防复发。

另加 docs/testing/ios-keyboard-composer-20260915.md:html/body overflow
hidden + 100dvh 外壳 + sticky 输入框 + interactiveWidget 只有 Android 认,
是键盘遮挡的风险形状,但代码断不了真假,交真机确认后再决定是否立单。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 04:02:50 +00:00
Jesse_ChenandClaude Fable 5 4147326115 docs(tasks): brief the homepage topic-card removal and the two-layer answer fold
首页「从一个主题开始」整段下线,连同它背后 /api/onboarding 的 LLM 取数
链路和 bootstrapPrepareReady 的揭幕闸门;聊天回答改成两层可见性——口语层
默认展开,第一个 H2 起的骨架进默认收起的「完整分析」折叠块。内容一字不
删,只改默认可见性与口语层形状。

记下与待验收项 BUG-630 的冲突:主题卡就是 guided_topic 的唯一发出点,
入口下线后该项走查不可执行,枚举值保留供历史会话读回。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 03:18:22 +00:00
Jesse_ChenandClaude Opus 5 ebd5ba68a2 docs: clear the timezone gap and record what actually keeps the gate red
验收 8d56d0ab:字面量锁经变异法确认(加 **.generated_by 只红这一条,恢复即
绿),生产代码零改动。timezone 那条查下来不是缺口,是验收机少装了已声明的
timezonefinder>=6.5;装上后快速门 pytest 段 740 passed / 0 failed,BLOCKED.md
该条划掉。真正让门停在 exit=1 的是 npm test 的 27 条无 Docker 失败,另记一节
并写明本机「快速门通过」的口径。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-15 02:50:56 +00:00
jesse-ux 8d56d0ab0b test(report): lock binding exclusion allowlist literals (BUG-694)
Independent Staging Quality Gate / validate (push) Successful in 9m52s
Independent Staging Quality Gate / publish (push) Successful in 2m6s
Contract-test the D2 exclusion tuples so widening them cannot silently pass. Record the timezonefinder quality-gate gap in BLOCKED.md.
2026-09-15 10:41:10 +08:00
Jesse_ChenandClaude Opus 5 10b463b9e8 docs(tasks): lock the binding exclusion list and record the timezone gap
BUG-693/694 实现(1d2aeffa)验收通过:三次 CLI 加三个 PYTHONHASHSEED 哈希
全同,变异法验证覆盖 33/40 顶层键,耗时中位数 2737 ms(修复前 2769 ms)。
补漏单处理两个没被机制挡住的洞:排除集的「只能三类」靠的是生产者、质量门、
测试引用同一对常量,加第四类会自动放行,改为把字面量钉进合同测试;快速门
必红的 timezone inference 依赖缺口记进 BLOCKED.md(修复前同样红,非回归)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-15 02:34:37 +00:00
jesse-ux 1d2aeffaef fix(report): bind professional report hash to the delivered packet (BUG-693, BUG-694)
Independent Staging Quality Gate / validate (push) Successful in 9m45s
Independent Staging Quality Gate / publish (push) Successful in 2m14s
Rebind after sanitize, write an explicit binding_scope, and make the quality gate recompute coverage. Wall-clock fields stay in the packet but out of the hash.
2026-09-15 10:09:26 +08:00
jesse-ux 039b0a2608 fix(rectification): say 这两分钟 only when two candidates remain (BUG-692)
Independent Staging Quality Gate / validate (push) Successful in 9m43s
Independent Staging Quality Gate / publish (push) Successful in 8m50s
Count-aware closed-pool invite, catch the five stale contract assertions, and mark M1b V1/V2 as not_measured.
2026-09-15 09:43:51 +08:00
Jesse_ChenandClaude Opus 5 416b9a693c docs(tasks): bind the professional report receipt to what is actually delivered
上游 2026-09-14 的 4 个新提交里 SKILL.md 与校正代码零改动,核"要不要抄
它的 PL9 绑定投影"时量出我们自己两个问题:result_binding 绑的是中间态包
(18/36 个顶层键、6.24 MB,交付 10.04 MB),质量门只比自洽所以恒 passed;
被哈希的载荷含墙钟 elapsed_seconds,同一输入两次跑出不同 result_hash。
任务书写末尾按交付对象重绑、排除集显式进回执、质量门补覆盖校验;上游那条
投影优化实测收益 < 0.1 秒,记为不抄。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-15 01:29:00 +00:00
Jesse_ChenandClaude Fable 5 81f8183cc2 docs(tasks): fix the invite copy count and the five stale assertions
验收 a266b6b7 / c5fbee56:tsc、lint、新套件全绿,但 npm test 由 27 涨到 32——
4 条 exit 断言的短语表没加新交付文案、1 条公开字段深比较没加 birth_time_source,
都不是行为回归但违反红线。另有用户可见的数字矛盾:邀请语硬编码「这两分钟」,
同段话却写着「还剩 4 个候选」。本单修文案按候选数出话、两处断言跟上,并给精度
研究 M1b 追加勘误:V1/V2 三档数字与 V0 完全相同且作者自承采集走错路径,判定
作废改为未测(V3 结论保留)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-15 01:20:37 +00:00
jesse-ux dfb572fc7f docs(research): measure precision-adaptive probe gates; no variant clears the bar
Independent Staging Quality Gate / validate (push) Failing after 13m3s
Independent Staging Quality Gate / publish (push) Skipped
20 public AA cases, raman/mean. Lowering MIN_BOUNDARY_DAYS narrows ±10 from
15 to 11 minutes but drops top-1 0.80→0.75; wider radii get wider ranges.
Varga sensitivity weights (V1/V2) match production; D60 (V3) hurts ±10.
Day-precision events offset ±7 never squeeze the true minute out. Production
45/30 gate and equal varga weights stay unchanged.
2026-09-15 09:04:03 +08:00
Jesse_ChenandClaude Fable 5 d92a696768 docs(tasks): record wins by default when it falls outside the rectified range
产品 2026-09-14 拍板:用户有医院记录而校正区间不含那一分钟时,记录优先、分歧
如实呈现。依据写进任务书:holdout 上六题后头名命中只有 0.80/0.55/0.35,不足以
推翻书面记录;但医院记录也确有抄录误差,所以不能反过来否定校正结果。行为上
「记录优先」已经成立(不点采用就继续用填报时间),本单只做文案与入口:冲突时
校正区间标成证据倾向,采用按钮改成「改用校正结果」,并禁止任何「记录不准」
或「校正无效」的表述。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-14 15:24:58 +00:00
jesse-ux c5fbee56a6 fix(rectification): label declared birth time as record or estimate (BUG-690)
Independent Staging Quality Gate / validate (push) Failing after 8m55s
Independent Staging Quality Gate / publish (push) Skipped
Hospital records, family estimates and period-only windows now keep distinct copy on the board and range card. Scoring still uses the reported clock as the search-window centre. Hospital minutes outside the current range are stated with the offset and no preference.
2026-09-14 23:20:15 +08:00
jesse-ux a266b6b727 fix(rectification): invite another dated event instead of saying the pool is closed (BUG-689)
Independent Staging Quality Gate / validate (push) Failing after 10m16s
Independent Staging Quality Gate / publish (push) Skipped
When the seven collect lines are closed, the range card still appears, but the copy asks for one more exact-day event of any kind instead of saying the questions are finished. A new dated event after delivery stales the snapshot so the session does not stay delivered.
2026-09-14 22:56:01 +08:00
Jesse_ChenandClaude Fable 5 b56147e524 docs(tasks): varga sensitivity weighting, and birth-time provenance labels
与上游流程对照补两处。①精度研究单加 M1b:上游有一张分盘分钟敏感度表
(D60=2 / D30=4 / D24=5 / D9=13.3 / D1=120 分钟换一次上升),而本仓 11 张分盘
等权再除以 22(且没有 D60)——20 分钟窗里 D30 和 D2 同分量,分辨率最高的盘被
稀释。测 V1 反比配权 / V2 按窗宽选盘 / V3 加 D60,并报过拟合风险。
②新任务书 BUG-690:录入已收 birth_time_source 三类,但校正链只用过一次,
推算值与医院记录等同对待、输出直称「你的出生时间」。接进投影并按来源分档措辞;
医院记录与校正结果冲突时怎么说挂给产品。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-14 14:44:15 +00:00
Jesse_ChenandClaude Fable 5 749c7541ad docs(tasks): research the precision-adaptive probe gate, and ask for exact dates
出生时间每差 1 分钟,Vimshottari 边界只平移约 1.1 天;而 _boundary_windows 用固定
45 天(刷新 30 天)闸门,且全文不读证据精度。20 分钟窗内候选边界全挤在三周内被
整批丢掉——这就是「六题之后引擎出不来题」的算术原因。研究单量闸门按年/月/日分档
的收益,必测 ±3/±7/±14 天记错时真值是否被挤出(挤出即不推荐)。v4 实测有 59 件日
精度事件可用。BUG-689 的邀请文案同步加 D1b:优先请用户说记得确切日期的事,但不得
承诺能定到分钟。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-14 14:36:10 +00:00