四月手记
决定、踩坑、和一些还没想清楚的事
四月上半月干的事太多,不按时间写了,按主题。每段尽量把"发生了什么、踩了什么坑、最后怎么决定的"讲清楚,以后翻回来能用。
卖房
McVay,95127。2022 年 $1.47M 买的,首付 $220K。现在 Zillow 估 $1.44M。四年了,浮亏。
HELOC $360K 挂在 8.77% 浮动利率上,每月烧 $3K。James 四岁,三房不够住,爷爷奶奶来没客房。所以认真考虑卖。
估价
联系了四个 agent:Jing Xue(2022 年的买方 agent),Enrique Medellin,Nancy Reynolds,Barbara Bui。Jing 第一个回,给了 $1.4M 的 CMA,佣金只收 1%(正常 2.5-3%)。Enrique 回了,下周三来看房。Nancy 和 Barbara 还没回。
我不信任单一数据源。Chrome 爬了 95127 近 40 天的 41 套成交,deep-dive 了 5 套同档次 comp。
关键发现:之前用 14705 E Hills($740/sqft)做锚是错的。 那套 vinyl linoleum 地板,fixer 级别。McVay 有 granite countertop、tankless water heater、updated bath、city view——对标的是 5271 Summit($1,441K 成交,$970/sqft),renovated tier。
Zillow 在 95127 准得离谱。 5 套 comp 里 4 套 Zestimate 和成交价误差 <0.5%。唯一的 outlier 是 706 Linda Vista,差了 7.7%。所以 McVay 的 $1,443K Zestimate 可信度高。Jing 的 $1.4M 反而偏保守。
财务分析(踩坑重灾区)
做了四个版本。第一版结论 7.7 年回本,第四版 6 个月。 同一组数据,四个假设错误翻转了结论。逐个记下来:
坑 1:Federal/California 税率混算。 California 不 conform TCJA,mortgage interest deduction 上限是 $1M acquisition debt(Federal $750K)。Property tax 在 California 全额可抵(Federal 被 SALT $10K cap 吃掉)。California standard deduction 只有 ~$11K(Federal $29K)。分开算后,留房的税盾从"看起来很大"变成 $9,646/年。
坑 2:Security deposit 当永久损耗。 $7,500 deposit 不是花掉的钱,是资金占用。正确处理:opportunity cost = $7,500 × 3.29% / 12 ≈ $21/月。
坑 3:Maintenance cost 双重扣减。 净到手 $155K 已经扣了佣金和 closing cost,但 comparison 里又单独列了一遍。
坑 4:Opportunity cost 口径不一致。 SPAXX yield 按 after-tax 算,deposit 按 pre-tax 算。要么全 pre-tax 要么全 after-tax。
最终结论:
- 卖 + 租 $5,500/月 → 月成本 $5,232
- 留 + HELOC refi 到 6.5% → 月成本 $6,284
- 卖房每年省 ~$12,600,一次性搬家成本 $6,500,约 6 个月回本
- 但房子年涨 4% = $57K 增值 >> $12.6K 现金流差
- 决策本质:现金流优化(卖)vs 资产增值押注(留)
HELOC Refi(不管卖不卖都该做)
| CU | 产品 | 利率 |
|---|---|---|
| Star One | Fixed HELOAN 15-20yr | 6.46-6.57% |
| Star One | Fixed-option HELOC | 6.08-6.19% |
| Provident | 5yr Fixed HELOC | 6.00% intro → 7.20%+ APR |
| Meriwest | Fixed HELOAN | 8.50%(没意义) |
Star One 6.5% fixed,年省 $8,172。 远超原来 ≤7.25% 的目标。CLTV 80.4%,卡在好利率的边界上。这周提交申请。
AMZN 减持
4 月 15 日卖了 150 股,$248.80/股,套现 ~$37K → Fidelity SPAXX(3.29%)。
集中度从 41% 降到 33%。健康线 15%,还差一倍。
税务策略
剩 145 股,cost basis $203.64。最早一批(2025-05-15 vest)5 月 15 日转长期资本利得,税率从 ~48% 降到 ~29%。145 股的 gain $6,549,等一个月省 ~$1,244。
516 股 unvested RSU 全部设了 Fidelity vest day "Sell All"。2026 全年 vest $102K,Amazon 默认扣 22% 联邦税,真实边际 ~48%。报税时要补 $20-25K。 必须预留。
QQQ 陷阱
直觉是拿卖股套现的钱买 QQQ 定投。但 QQQ ≈ 50% Top 10 科技股,其中 AMZN 占 ~6%。对一个拿 Amazon 工资、持有 33% AMZN 的人,买 QQQ 是三重科技敞口叠加。正确选择:VTI 或 VOO。
老婆的一万五
吴瑶有 $15K 在低息账户。转 Wealthfront 年化 4%,一年多 $450。没转。她的安全感比 0.7% 的利差重要。 别把家人的存款当需要优化的变量。
求职工具链
一周造了八个工具,零份简历投出去。
工具清单
| 工具 | 干什么 | 技术要点 |
|---|---|---|
~/bin/linkedin-jobs |
LinkedIn 职位搜索 | v2 纯 curl,用 guest API endpoint(/jobs-guest/jobs/api/*),无需 auth/Chrome,1-2s/query |
~/bin/levels-fyi |
薪资校准 | 匿名抓 __NEXT_DATA__ JSON,slug 约定 company-title,零依赖 |
~/bin/job-tracker |
求职 Pipeline 追踪 | SQLite ~/.job-tracker/tracker.db,7 天自动 follow-up 提醒,按 source 漏斗统计 |
company-research skill |
面试前公司情报 | Perplexity + levels-fyi + LinkedIn Jobs 三源交叉 |
outreach-drafter skill |
LinkedIn 私信/冷邮件 | 7 条 anti-AI 规则,输出 2 变体 |
interview-coach-skill |
面试教练 | fork 自 noamseg 1,034 星项目(710KB 参考材料),23 命令,5 维评分 |
build-tailored-resume |
JD→简历 | 7 阶段 pipeline 含 ATS check + humanization pass |
upwork-proposal |
Upwork 提案 | fork 自 resume 架构,含 rate-sanity 拦截 |
LinkedIn Guest API
关键发现:LinkedIn 有一套完整的 guest endpoint 给未登录用户用,在 /jobs-guest/jobs/api/ 下面。搜索、JD 详情都有。v1 用 opencli+Chrome 要 8-10 秒一次查询,v2 纯 curl 1-2 秒。不需要 cookie,不需要 headless browser,不触发反爬。
Search Before Build
interview-coach 是第一次实践"先搜高星开源方案再决定自建还是采纳"。noamseg 的项目 1,034 星、710KB 参考材料、23 个命令覆盖 mock/analyze/stories/prep。自建的话至少两周。采纳只花了一个下午做适配。
Hermai.ai
评估了 hermai.ai 的 schema registry(181 个网站的 endpoint 定义)。结论:当字典用有用,但不能替代逆向工程。 LinkedIn 的 schema 对 auth 的描述就是错的——声称需要登录,实际有 guest endpoint。
cband 崩了
4 月 13 日,cband(claudraband)0.6.1 更新后 stdout 只返回 tool call markers(> Read、+ tool),不返回 assistant text。
迁移
6 个 job 脚本从 cband-run 迁移到 claude -p(/opt/homebrew/bin/claude):
- pa-morning-summary、brightwheel-daily、morning-briefing、pa-uscis-daily、1p3a-watch、interview-digest
- job-runner 的 Phase 2 self-heal 也迁移了
--cwd 是 cband 专有 flag,claude -p 不支持。提示词改为 temp file + cat | claude -p 管道模式。
踩坑:--max-turns 1 的陷阱
Sonnet 处理大输入(~80KB stdin + 复杂 prompt)时,可能先做 tool call 再输出文本,需要 >1 turn。--max-turns 1 会直接报 Error: Reached max turns (1) 退出。Haiku 不受影响。
规则: 简单提取任务 --max-turns 1 够用。大文件合并/结构化输出用 --max-turns 2 起步。别盲目优化到 1。
踩坑:stdin pipe pattern
大文件(>10KB)如果让 claude -p 自己读,--max-turns 的预算会被 CLAUDE.md 读取和文件分段读取吃掉。用 cat "$FILE" | claude -p 把数据直接灌进 prompt,绕过 tool call 开销。
E2E 验证规则(血的教训)
迁移完我说"done"。第二天所有 cron job 全挂了。明明有 Bash 可以跑 job-runner --test,但就是没跑。
从此以后的规则: 任何脚本/工具/cron 改动后,必须跑 job-runner --test <job> 并贴测试结果。不贴 PASS 证据不许说 done。
Chrome 僵尸
检查进程时发现 33 个 chrome-devtools-mcp 僵尸。最老的跑了好几天。三个大的分别 4.7GB、4.5GB、566MB。
原因: 每个 Claude Code session spawn 一个 chrome-devtools-mcp 实例,session 结束后不退出。
修复:
- 集中到共享
chrome-mcp-sharedPM2 服务,端口 9340 - 写
zombie-mcp.js健康检查:自动杀运行 >6h 或 RSS >500MB 的进程 - 接入每小时 system-agent
Effectiveness Benchmark
从 spec 到上线一个 session 搞定。
- 路径:
~/clawd/effectiveness/,Dashboard 在:4000/effectiveness - 四个维度: reliability、speed/resources、zombie detection、ROI
- 数据: SQLite WAL,从
~/jobs/logs/一次性导入 5,940 条历史指标。job-runner post-hook 自动写入新指标 - Build cost 公式:
(total_commits × 0.5h) + (first_week_commits × 0.5h)——粗糙但够用 - AI 评估:
claude -p --model sonnet --max-turns 1批量打分 - 7 天 burn-in: 新工具前 7 天不判 zombie/negative-ROI,因为新东西总是不稳定
发现
ralph-loop:从来没成功跑过。僵尸。interview-digest:75% 失败率。已修。- 4 条替换链自动检测(工具 A 替换了工具 B)。
磁盘
/System/Volumes/Data 持续 85-89%。system-agent 每小时跑清理,每次卡在同一个地方。
三个无法自动解决的大头
| 项 | 大小 | 为什么删不了 |
|---|---|---|
Chrome code_sign_clone |
~14GB+ | Chrome 在运行,lsof 有句柄,CLAUDE.md 禁止杀 Chrome |
/private/var/folders 孤立克隆 |
曾发现 47 个目录 61GB | 需要 Chrome 不在运行时清理 |
| Plex metadata | ~56GB | 在外置 ORICO 盘上,不影响系统盘(这个是误报) |
现状: npm/pip cache 清理只回收几百 MB。docker prune 永远失败(Docker Desktop 没运行)。self-heal cron 陷入西西弗斯循环——每小时检查、发现、尝试、失败、下次再来。
正确解法: 安排 Chrome 离线时段做 code_sign_clone 清理。目前还没做。
零碎但值得记住的
Inkplate e-ink 仪表盘
已上墙。ESP32,1280×720,3-bit grayscale。Deep sleep 模式:90 秒 awake + 9 分钟 sleep。
硬件坑汇总(全是实测踩出来的):
sph_pin是 GPIO 33 直连,不在 pca6416a 扩展器上。配错了只会显示两条竖线。- 显示翻转用
sharp.flip(),不是.flop()。搞反了挂墙上是倒的。 sharp.composite()在.flip()之后执行,overlay 不会跟着翻。解法:把图片嵌进 SVG 的<image>标签,跟整个 SVG 一起翻。- SVG
<image>嵌入的图片必须预先 resize 到目标尺寸——sharp/librsvg 忽略 SVG 的width/height属性,按原始像素渲染。一张微博图 560px 高直接盖住了底部一整行。
OTA 流程(设备大部分时间在 deep sleep,抓不到):
curl 'http://localhost:4000/inkplate/ota?set=1'— 设 OTA flag- 等最多 ~10 分钟设备醒来
esphome upload inkplate-dash.yaml --device inkplate-dash.localcurl 'http://localhost:4000/inkplate/ota?set=0'
Video Server Shuffle 算法
"全部随机"按钮之前只 shuffle 当前目录。重写为分层加权:
- 按父目录分组,组内 Fisher-Yates 随机
- 组间权重 =
remainingCount ^ 0.5(指数 0 = 小目录过度采样,1 = 纯均匀,0.5 = 折中) - 反连续约束:追踪
lastPoolIdx,下一次不能从同一目录选 - 根目录占了 54% 的视频,播放列表尾部不可避免地聚集——这是结构性的,不是 bug
Zillow 租房 Pipeline
4x/天(9/13/17/21)扫 SJ+Milpitas 4+bed SFH/TH ≤$6K。AutoScore 0-100 分,≥70 推飞书。
Zillow 搜索 URL 的 7 个坑:
- 过滤器是排除制——要排除 apartment/condo/multi-family,不能只选 SFH
regionSelection必须带 regionId+regionType,光靠 URL 路径不够- 默认排序
priorityscore会把公寓广告推到前面,要用sort:{value:'days'} - 分页路径是
/rentals/2_p/,不是?page=2 - Chrome 147+ 的 CDP
/json/new必须用 PUT,GET 返回Using unsafe HTTP verb __NEXT_DATA__里的公寓 zpid 是 lat/lng 字符串不是数字,要/^\d+$/.test(zpid)过滤stories字段在搜索结果里几乎永远是 null(82/83 条),要从描述文本推断
评分踩坑:unknown 字段给了满分。 82 条数据 stories 是 null,代码默认给 10/10。一个三层 townhouse 靠缺失数据拿了 77 分推到了飞书。规则:null 给中位分(5/10),永远不给满分。
Kiro CLI 毁了 .zshrc
安装 Kiro CLI 后,它往 .zprofile 和 .zshrc 注入了自己的代码块。结果 .zshrc 看起来被清空了,tmux-main 和 tplay alias 丢失。手动清理,Kiro 已从系统删除。
ESM import() 执行 main()
pre-send-hook.js 底部有 main() 调用,没有 guard。其他三个服务(feishu-proxy、wecom-bot、tel-bot)await import() 它的时候,main() 在它们的进程上下文里执行了。process.argv 没有预期参数 → process.exit(1) → 导入方直接挂了。
ESM 没有 CJS 的 require.main === module。解法:用 import.meta.url 对比 process.argv[1] 做 guard。
JSON config 文件被 Write 覆盖
用 Write 工具往 .mcp.json 加一个 leetcode 条目,结果把整个文件重写了,chrome-browser 条目被吞。花了一整个 session 排查"谁删了我的 MCP 配置"。
规则: 多条目 config 文件必须 Read → Edit(局部替换),不能 Write 整文件。
Stale-While-Revalidate Pattern
Inkplate 的 getWeiboHot() 要 spawn 子进程跑 30-60 秒。直接在 Express handler 里调会挂请求。
解法是模块级缓存 + 后台刷新:
let cache = { data: null, ts: 0, fetching: false };
async function getThing() {
if (cache.data && Date.now() - cache.ts < TTL) return cache.data;
if (!cache.fetching) {
cache.fetching = true;
fetchInner().then(d => {
if (d) { cache.data = d; cache.ts = Date.now(); }
cache.fetching = false;
});
}
return cache.data; // stale or null on first call
}
第一次请求返回 null(skeleton 渲染),后台填充,后续请求秒回。fetching flag 防重复 spawn。
Auto-Reflect
问题:老是忘记跑 /session-reflect,每次还要 2-3 分钟。
方案:com.vigoose.auto-reflect LaunchAgent,每 30 分钟检查有没有已结束的 session。有的话:JSONL 压缩到 25K chars → claude -p sonnet 提取记忆 → 写文件 + session card + git commit。99% 的时候检查完没事做,成本约零。触发时 20-30 秒跑完。
手动的 /session-reflect 还在——热上下文提取质量更高。auto-reflect 是兜底网。
还没决定的事
- 房子: 等 Enrique 下周三的 CMA,再等 Nancy/Barbara。三个估价齐了再做决定。HELOC refi 不等,本周申请。
- 工作: Databricks 是 Tier 1 目标。但还没点 Apply。
- 磁盘: 需要安排 Chrome 离线清理,但一直没排进去。
没有结论。有些事情就是还没想清楚。