docs(linkedin): apply consultant audit feedback, reorder by wave schedule, and sync NocoDB status
Deploy / build (push) Successful in 32s

This commit is contained in:
hoelee committed 2026-10-27 19:09:56 +08:00
1 parent 6f474b76e9
commit bef57cbabb
15 files changed
+661 -715

No files matched your search

+312 -394
View File
@@ -1,12 +1,11 @@
# 外部顾问审阅全景资料包:blog.hoelee.com 候选文章改写与 LinkedIn 发布审核(第二批新选文章)
# 外部顾问审阅全景资料包:blog.hoelee.com 候选文章改写与 LinkedIn 发布审核(第二批新选文章 - 已审阅已排期)
> **文档目标**:本资料包汇总了从技术博客 `blog.hoelee.com` 精选改写的 10 篇高价值技术动态文案,专门用于 LinkedIn 个人品牌与高端技术雇佣定位。这批内容**此前从未在 LinkedIn 上发布过**。
>
> 请外部顾问在审阅这批动态时,**严格对照以下【核心业务目标】与【铁律前置约束】**进行综合评估。如发现口吻偏颇、过度商业化、技术表述不严密或违规词汇,请直接在各篇文章末尾的【意见回填栏】给出批注与修改建议。审核通过后,我们将按批次排期发布至 LinkedIn。
> **文档状态**:外部技术品牌与高端招聘顾问**已全量逐字审阅完毕**。
> **处理进展**:所有 10 篇候选文案均已按顾问诊断意见完成微调与求职红线脱敏,并正式录入 **NocoDB**(Base: `Hoelee Career Agent`)草稿箱(`status = APPROVED`),进入 5 周平稳排期发布阶段。
---
## 一、 战略背景与核心业务目标
## 一、 战略背景与核心业务目标(顾问审阅基准)
博客网站 `blog.hoelee.com` 与 LinkedIn 个人主页是作者(Lee Teong Hoe)技术实力与职业品牌的双核阵地。所有发布到 LinkedIn 的内容必须精准协同以下两大核心目标:
@@ -22,284 +21,36 @@
---
## 二、 必须严格遵循的限制规则与铁律清单
## 二、 顾问核心诊断与修订落实总览
### 1. 核心人设与语调纯洁性(杜绝业余爱好者/玩具化口吻)
- ❌ **绝对禁用词**:`homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `四台全中`, `玩票`。
- ✅ **标准专业替代词**:
- 英文:`the infrastructure I manage`, `my self-hosted production nodes`, `on-premise dedicated server`, `production host`.
- 中文:“我管理的私有基础设施”、“自托管生产节点”、“企业级自建网关”、“生产服务器”。
- **作者第一人称单数**:统一使用第一人称单数(`I` / `我`),杜绝含糊不清或虚张声势的复数(`we` / `我们`),强化架构师个人对系统与代码的掌控力和责任感。
- **杜绝自嘲与“草台班子”话术**:坚决清除如“靠胶带勉强粘在一起 (held together with duct tape)”、“粗糙应付”等业余自嘲表达,统一升级为“受控的受试会话”、“严格边界下的容错设计”。
### 2. 事实真相与数据严密性(不可伪造、杜绝夸大)
- **严禁捏造未经测量的虚假数字**:LinkedIn 动态中引用的所有性能倍数、内存开销、提交代码量、故障排查用时,必须与博客源文章及底层真实终端日志、Git Commit 历史完全一致。
- **严密区分“耗时减少比例”与“吞吐加速倍数”**:
- 例如:耗时从 352s 缩短至 218s,是**耗时减少 38%**,对应的**吞吐加速倍数是 1.61×**(352/218)。绝对不能将 38% 偷换混淆为“提速 38 倍”或“速度提升 38%”。
- **物理与时间戳边界**:
- 视频与音频处理对齐不可妄称“微秒级精确”,物理帧率上限(如 30fps 单帧 33.3ms)是严格的边界。
### 3. 生产安全与隐私脱敏(OPSEC 安全边界)
- **严禁泄露内部私密路径**:绝不在文案或展示片段中出现本地绝对路径(如 `D:/dev/...` 或 `C:/Users/...`),统一抽象为通用项目路径。
- **严禁泄露真实内网 IP 与生产资产标识**:内网 IP(如 `192.168.1.x`)一律替换为规范内网域名(如 `node.internal`),公网 IP 统一脱敏为 RFC 5737 文档保留地址(`203.0.113.x`)。
- **凭据与令牌严格脱敏**:任何涉及认证的命令保持变量引用形式(如 `Bearer $TOKEN`),严禁携带真实密钥。
### 4. LinkedIn 平台受众交互与传播适配
- **字符上限严格控制**:LinkedIn 单条动态上限为 3,000 字符。本批文案严格控制在 1,700 - 2,200 字符区间,兼顾技术推导深度与阅读耐受度。
- **开篇高对比度切入(Hook)**:开篇直击生产反直觉现象、故障矛盾或技术误区,拒绝空洞行业吹捧。
- **结尾深度互动引导**:结尾抛出面向资深工程师与技术管理者的思辨互动问题,并附带对应博客深度长文的权威溯源链接:`Write-up: https://blog.hoelee.com/posts/<slug>/`。
| 槽位 | 系统标识 Key | 拟发日期 | 顾问结论 | 核心修改与落地要点 |
|:---:|---|:---:|:---:|---|
| **01** | `when-smart-says-healthy-but-your-raid-is-corrupting-data` | 2026-10-29 (Thu) | **通过** (首发标杆) | 硬核存储取证标杆之作,CRC32C 零块推导严密,零违规,第一顺位标杆发布。 |
| **02** | `slashing-agent-context-with-a-code-graph` | 2026-11-03 (Tue) | **通过** | 零违规,数据边界清晰,展现一流 AI 平台架构功底,直接排期发布。 |
| **03** | `running-production-infrastructure-solo` | 2026-11-05 (Thu) | **通过(已微调)** | 调整第 2 段表述,将无团队/不用 PaaS 转化为高密度单位经济效益与架构严谨度。 |
| **04** | `the-single-writer-rule-for-coding-agents` | 2026-11-10 (Tue) | **通过(已微调)** | 优化倒数第三段逻辑,强调“结构性消除 Git 锁竞争与合并前捕获 100% 幻觉回归”。 |
| **05** | `how-i-built-the-digikedai-telegram-bot` | 2026-11-12 (Thu) | **需微调(已更新)** | 消除电商副业色彩,强化 B2B 多租户权限开通与高可靠网关架构定位。 |
| **06** | `your-disk-full-alert-is-lying` | 2026-11-17 (Tue) | **需微调(已更新)** | 纠正人称复数 our -> my,统一 PromQL 指标为 avail_bytes,规范字节表达式。 |
| **07** | `jpa-version-field-lost-update` | 2026-11-19 (Thu) | **需微调(已更新)** | 补充 JPA 托管实体自动覆盖版本号的深坑解析,展现 Senior 代码审查功底。 |
| **08** | `stop-writing-agent-prompts-for-deterministic-work` | 2026-11-24 (Tue) | **需微调(已更新)** | 补充挂载调度器背景与 125 行包含重试/去重/退避逻辑,立住工程克制力形象。 |
| **09** | `why-telegram-bot-notifications-die` | 2026-11-26 (Thu) | **需微调(已更新)** | 补齐文末思辨提问;明确 extra_hosts 属于应急止血手段,展现网络协议排障能力。 |
| **10** | `self-healing-digital-goods-entitlements` | 2026-12-01 (Tue) | **需微调(已更新)** | 脱敏数字商品电商词汇,全面升级为企业级多租户订阅与受控存储网关 IAM 授权架构。 |
---
## 三、 顾问审阅开刀维度与反馈指引
## 三、 10 篇最终修订版文案全文(已入库 NocoDB 排期)
请顾问重点对以下四个核心维度进行严苛诊断,并在每篇文章末尾的【意见回填栏】提供结论:
1. **【职业形象与求职契合度】**:这篇动态读起来像一个可独当一面的 Senior 全栈/DevOps 架构师吗?是否不小心流露出了“做生意/小公司老板”而影响雇主录用的倾向?
2. **【技术严密性与逻辑自洽】**:技术判断是否准确?数据与因果链条是否经得起推敲?有无前后矛盾或夸大其词?
3. **【人设纯洁性与表达去油】**:是否存在业余玩家(homelab/折腾/玩具)的口吻残留?英语母语表达是否自然地道、干练硬核?
4. **【具体修改意见与优化稿】**:若当前文案存在问题,请给出具体的修改批注或建议的优化润色版本。
---
## 四、 本批 10 篇候选新文章文案与审阅明细
### 1. Running Production Infrastructure Solo: 162 Containers Across Three Hosts
- **系统标识 Key**:`running-production-infrastructure-solo`
- **所属分类**:`case-studies`
- **博客源文章**:https://blog.hoelee.com/posts/running-production-infrastructure-solo/
- **入选理由与受众定位**:Top-tier proof of Senior DevOps/Platform reliability: 162 containers across 3 hosts, single operator, multi-host network routing, zero cloud lock-in.
- **正文字符数**:2155 chars (符合 < 3,000 字符限制)
- **当前发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
#### LinkedIn 拟发布动态正文:
```text
I run 162 Docker containers across three self-managed production hosts with 78 compose stacks — serving public client applications, mail infrastructure, workflow automation, and CI/CD pipelines.
No multi-person ops team. No managed cloud PaaS swallowing thousands a month.
When you manage an estate of that density solo, you learn quickly that conventional dashboard metrics are dangerous. Two real-world production failures changed how I audit my systems:
1. The silent database dashboard disconnect
My analytics dashboard (NocoDB) was happily displaying rows and answering HTTP 200. Downstream, the background replication worker had dropped its database socket four hours earlier. The UI was serving cached metadata from memory while live mutations stalled. A green dashboard is not health; transactional read-after-write verification is health.
2. The zero-config daemon lockup
A credential management container hung on startup after a routine patch. Docker health checks passed because PID 1 stayed alive, but reverse-proxy requests timed out with HTTP 504. The culprit? An empty GPG keyring directory in a newly mounted volume triggered a blocking interactive entropy prompt inside the daemon. Health checks that probe process existence rather than live application handshakes will always deceive you.
My operational rules for running production infrastructure solo:
• Segregate workloads by isolation boundary: public ingress and edge routing live on a dedicated VPS; core storage and identity live behind private gateways.
• Telemetry must be completely decoupled from application runtimes.
• If an alert is based on an arbitrary percentage ratio instead of absolute time-to-exhaustion, delete it.
When you operate both the codebase and the host it runs on, there is no finger-pointing between the developer and the infrastructure provider. You own the transport layer as completely as the application layer.
For those running dense container footprints: what is your primary watchdog test to catch a service that is technically "running" but practically dead?
Write-up: https://blog.hoelee.com/posts/running-production-infrastructure-solo/
```
#### 顾问审阅意见回填栏:
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(求职合规性)**:
- **2. 技术真实性与逻辑推导**:
- **3. 语言地道度与禁用词检查**:
- **4. 优化修改建议(如有)**:
---
### 2. Architecting a 24/7 AI Support & Entitlement Bot Without Human-in-the-Loop
- **系统标识 Key**:`how-i-built-the-digikedai-telegram-bot`
- **所属分类**:`case-studies`
- **博客源文章**:https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/
- **入选理由与受众定位**:Demonstrates Senior AI Full-Stack engineering: TypeScript/grammY, Hono, LiteLLM gateway, 3-tier hybrid retrieval, deterministic state machines, 175 unit tests.
- **正文字符数**:2069 chars (符合 < 3,000 字符限制)
- **当前发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
#### LinkedIn 拟发布动态正文:
```text
Deploying an LLM as a customer-facing bot is easy. Building one that autonomously provisions production account entitlements without hallucinating or handing out unauthorized access is an entirely different engineering challenge.
I built a 24/7 customer support and instant trial-provisioning bot across Telegram and WhatsApp. The stack: TypeScript + Node 20, grammY in webhook mode behind a Hono HTTP server, a self-hosted LiteLLM gateway, and PostgreSQL for persistent state.
Three architectural boundaries keep it reliable in production:
1. Three-Tier Retrieval Over Context Stuffing
Dumping an entire product catalog into system prompts guarantees hallucinated specifications and prompt injection risks. Instead, the bot resolves intent through a strict hierarchy:
• Deterministic SKU regex token matching (`/\b[A-Z]{2,}\d{2,}\b/gi`)
• Normalized keyword metadata filtering
• Targeted semantic retrieval with bounded context injection
2. State Machines Over Prompt Engineering
An LLM is fantastic at natural language disambiguation and terrible at transactional state. Actions that touch data — trial provisioning, license issuance, verification — run on deterministic TypeScript state machines. The LLM only parses intent; it never touches the business transaction directly.
3. The Webhook Timeout Trap
Telegram will aggressively re-deliver webhook updates if your server does not respond within a tight timeout. If your LLM generation takes 4 seconds, Telegram re-fires the webhook, spawning duplicate LLM calls and cascading into an infinite reply storm. The fix: immediately acknowledge the incoming payload with HTTP 200, dispatch the generation to an async worker queue, and enforce idempotency locks on the `update_id`.
The system runs autonomously with a suite of ~175 unit tests verifying state transitions, retrieval precision, and payload contracts.
How do you separate deterministic business logic from probabilistic model output in your production agent workflows?
Write-up: https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/
```
#### 顾问审阅意见回填栏:
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(求职合规性)**:
- **2. 技术真实性与逻辑推导**:
- **3. 语言地道度与禁用词检查**:
- **4. 优化修改建议(如有)**:
---
### 3. The Single-Writer Rule: Orchestrating AI Coding Agents Without Multi-Agent Chaos
- **系统标识 Key**:`the-single-writer-rule-for-coding-agents`
- **所属分类**:`case-studies`
- **博客源文章**:https://blog.hoelee.com/posts/the-single-writer-rule-for-coding-agents/
- **入选理由与受众定位**:High-demand topic: AI multi-agent orchestration patterns. Contrasts naive swarm coding with isolated single-writer + adversarial reviewer architecture.
- **正文字符数**:1984 chars (符合 < 3,000 字符限制)
- **当前发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
#### LinkedIn 拟发布动态正文:
```text
When teams experiment with AI coding agents, the intuitive next move is almost always multi-agent parallelism: if one agent writes a feature in ten minutes, spawning four agents in parallel should ship the milestone in three.
In production, the exact opposite happens.
Unbounded multi-agent swarms writing to the same repository produce three immediate points of failure:
1. The Telephone Game: Orchestrators summarizing requirements to subagents introduce semantic loss at every layer.
2. Architectural Drift: Agent A builds a UI container using one state pattern; Agent B builds the underlying logic using another.
3. Git Collision Hell: Concurrent file patches create merge conflicts that LLMs resolve by silently dropping recently written code or entering infinite compiler repair loops.
The fix that works reliably: The Single-Writer Architecture.
I decouple agentic software development into three strictly segregated roles:
• The Exclusive Single Writer: The ONLY process with access to write tools (`patch`, `write_file`) and git staging. It maintains monotonic awareness of every mutation.
• Parallel Read-Only Workers: Specialized subagents running documentation indexing, schema validation, and test harness runs in parallel — strictly forbidden from touching repository files.
• Adversarial Reviewer: Once the Single Writer passes local unit tests, the raw `git diff` is handed to a fresh-context reviewer agent whose sole job is finding edge-case regressions, security oversights, and unnecessary token churn.
Across 5 full-stack tasks in a 50,000-line codebase, this architecture eliminated 100% of git lock collisions and reduced hallucinated regressions to zero while preserving development velocity.
Parallelize cognition and discovery, but strictly serialize mutations.
How is your engineering team preventing autonomous agents from stepping on each other in shared codebases?
Write-up: https://blog.hoelee.com/posts/the-single-writer-rule-for-coding-agents/
```
#### 顾问审阅意见回填栏:
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(求职合规性)**:
- **2. 技术真实性与逻辑推导**:
- **3. 语言地道度与禁用词检查**:
- **4. 优化修改建议(如有)**:
---
### 4. Slashing Agent Context and Token Churn With an AST Code Graph
- **系统标识 Key**:`slashing-agent-context-with-a-code-graph`
- **所属分类**:`ai`
- **博客源文章**:https://blog.hoelee.com/posts/slashing-agent-context-with-a-code-graph/
- **入选理由与受众定位**:Deep AI systems engineering: contrasts raw ripgrep/embeddings with compiler AST symbol graphs, slashing agent token consumption by ~80%.
- **正文字符数**:1975 chars (符合 < 3,000 字符限制)
- **当前发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
#### LinkedIn 拟发布动态正文:
```text
When you prompt an AI coding agent to modify a 50,000-line codebase, its default instinct is brute force: grep directories and recursively dump dozens of files into context.
The result is instant token bankruptcy:
• Reading 25 files to trace one dependency consumes 40,000+ tokens in a single turn.
• High-context saturation triggers cognitive degradation — models start hallucinating method signatures and missing subtle type contracts.
I tested three conventional fixes, and all of them failed under real development conditions:
1. Ripgrep keyword filtering: Zero semantic awareness. A search for `processOrder` matches comments, test mocks, and logging across 60 files. The agent still had to open 15 files just to find the implementation.
2. Vector RAG embeddings: Excellent for fuzzy concepts, useless for deterministic code trees. Vector similarity regularly misses internal helper functions (like `_verifyNonce`), leading agents to generate patches with nonexistent signatures.
3. File outline skeletons: Lacks parameter types and caller hierarchies, forcing speculative full-file reads anyway.
The durable fix: A pre-indexed AST Code Knowledge Graph.
Before the agent touches the code, an external parser extracts the repository's Abstract Syntax Tree into a symbol graph of callers, callees, definitions, and interface implementations.
• When the agent needs to inspect a function, it queries the graph and receives an exact 140-token node (signature, parameter types, caller list).
• Instead of dumping 3,000 lines of code across 5 files, the agent targets its read exclusively to the specific 25 lines that require mutation.
Across 20 production tickets, AST code graphs reduced agent context overhead by ~80% and eliminated 100% of signature hallucination errors.
Are you still using vector search for code intelligence, or have you transitioned to deterministic AST graphs?
Write-up: https://blog.hoelee.com/posts/slashing-agent-context-with-a-code-graph/
```
#### 顾问审阅意见回填栏:
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(求职合规性)**:
- **2. 技术真实性与逻辑推导**:
- **3. 语言地道度与禁用词检查**:
- **4. 优化修改建议(如有)**:
---
### 5. Stop Writing Agent Prompts for Deterministic Work
- **系统标识 Key**:`stop-writing-agent-prompts-for-deterministic-work`
- **所属分类**:`notes`
- **博客源文章**:https://blog.hoelee.com/posts/stop-writing-agent-prompts-for-deterministic-work/
- **入选理由与受众定位**:SRE & Agentic discipline: explains why prompting LLMs for deterministic string/version comparisons introduces unnecessary failure modes.
- **正文字符数**:1858 chars (符合 < 3,000 字符限制)
- **当前发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
#### LinkedIn 拟发布动态正文:
```text
One of my automated background jobs failed 29 times in a row without sending an alert.
The job was trivial: query npm for the latest published version of a CLI tool, compare it with the currently installed version, and send a notification if a newer version exists.
Two strings and a version inequality. That was the entire task.
Yet I had initially architected it as an AI agent job, because that was the hammer in my hand at the time. Every cycle, an LLM parsed the script output and decided whether to alert. It ran fine until an upstream model routing change occurred. The agent framework recorded a model mismatch, triggered a silent drift skip, and exited cleanly without error.
The fix was not a more defensive prompt. It was deleting the LLM from the loop entirely.
The rule I enforce across all automated pipelines now:
**If the exit condition is a deterministic comparison — a string, a number, a status code — putting a model in that loop only adds failure modes.**
There is zero judgment required in `currentVersion < latestVersion`. Wrapping it in an LLM adds:
• Network latency and provider downtime
• Model drift and prompt deprecation risks
• Non-deterministic output formatting
• Continuous token billing
I replaced the agent loop with 125 lines of Python featuring explicit branch exit codes. It has run cleanly ever since.
Of the eleven automated operations loops I manage today, eight contain zero AI models in their execution path. The remaining three use LLMs exclusively where human ambiguity cannot be expressed as code: ranking unstructured emails, evaluating qualitative risk, and flagging stalled project contexts.
Where in your workflows are you using prompt engineering where a 10-line script would be infinitely more resilient?
Write-up: https://blog.hoelee.com/posts/stop-writing-agent-prompts-for-deterministic-work/
```
#### 顾问审阅意见回填栏:
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(求职合规性)**:
- **2. 技术真实性与逻辑推导**:
- **3. 语言地道度与禁用词检查**:
- **4. 优化修改建议(如有)**:
---
### 6. When SMART Says Healthy and Your RAID Is Silently Corrupting Data
### 槽位 01. When SMART Says Healthy and Your RAID Is Silently Corrupting Data
- **系统标识 Key**:`when-smart-says-healthy-but-your-raid-is-corrupting-data`
- **所属分类**:`devops`
- **博客源文章**:https://blog.hoelee.com/posts/when-smart-says-healthy-but-your-raid-is-corrupting-data/
- **入选理由与受众定位**:Hardcore storage systems debugging: Btrfs checksum verification, CRC32C forensics (0x8941f998 zero-block), and queued async TRIM corruption.
- **排期规划**:Wave 1 (立威期) | 拟发布时间: `2026-10-29 (Thu)`
- **顾问审阅结论**:`通过` — 硬核存储取证标杆之作,CRC32C 零块推导严密,零违规,第一顺位标杆发布。
- **NocoDB 映射**:Candidate Key `cand:when-smart-says-healthy-but-your-raid-is-corrupting-data` / Draft Key `cand:when-smart-says-healthy-but-your-raid-is-corrupting-data:v1` (`status = APPROVED`)
- **正文字符数**:1935 chars (符合 < 3,000 字符限制)
- **当前发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
#### LinkedIn 拟发布动态正文:
#### LinkedIn 拟发布动态最终修订稿:
```text
Every hardware handbook gives you the same advice: monitor SMART attributes, inspect dmesg, and trust your drive controller.
@@ -327,67 +78,294 @@ How do you detect silent data corruption in your storage arrays before customer
Write-up: https://blog.hoelee.com/posts/when-smart-says-healthy-but-your-raid-is-corrupting-data/
```
#### 顾问审阅意见回填栏:
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(求职合规性)**:
- **2. 技术真实性与逻辑推导**:
- **3. 语言地道度与禁用词检查**:
- **4. 优化修改建议(如有)**:
---
### 槽位 02. Slashing Agent Context and Token Churn With an AST Code Graph
- **系统标识 Key**:`slashing-agent-context-with-a-code-graph`
- **所属分类**:`ai`
- **博客源文章**:https://blog.hoelee.com/posts/slashing-agent-context-with-a-code-graph/
- **排期规划**:Wave 1 (立威期) | 拟发布时间: `2026-11-03 (Tue)`
- **顾问审阅结论**:`通过` — 零违规,数据边界清晰,展现一流 AI 平台架构功底,直接排期发布。
- **NocoDB 映射**:Candidate Key `cand:slashing-agent-context-with-a-code-graph` / Draft Key `cand:slashing-agent-context-with-a-code-graph:v1` (`status = APPROVED`)
- **正文字符数**:1995 chars (符合 < 3,000 字符限制)
#### LinkedIn 拟发布动态最终修订稿:
```text
When you prompt an AI coding agent to modify a 50,000-line codebase, its default instinct is brute force: grep directories and recursively dump dozens of files into context.
The result is instant token bankruptcy:
• Reading 25 files to trace one dependency consumes 40,000+ tokens in a single turn.
• High-context saturation triggers cognitive degradation — models start hallucinating method signatures and missing subtle type contracts.
I tested three conventional fixes, and all of them failed under real development conditions:
1. Ripgrep keyword filtering: Zero semantic awareness. A search for `processOrder` matches comments, test mocks, and logging across 60 files. The agent still had to open 15 files just to find the implementation.
2. Vector RAG embeddings: Excellent for fuzzy concepts, useless for deterministic code trees. Vector similarity regularly misses internal helper functions (like `_verifyNonce`), leading agents to generate patches with nonexistent signatures.
3. File outline skeletons: Lacks parameter types and caller hierarchies, forcing speculative full-file reads anyway.
The durable fix: A pre-indexed AST Code Knowledge Graph.
Before the agent touches the code, an external parser extracts the repository's Abstract Syntax Tree into a symbol graph of callers, callees, definitions, and interface implementations.
• When the agent needs to inspect a function, it queries the graph and receives an exact 140-token node (signature, parameter types, caller list).
• Instead of dumping 3,000 lines of code across 5 files, the agent targets its read exclusively to the specific 25 lines that require mutation.
Across 20 production tickets, AST code graphs reduced agent context overhead by ~80% and eliminated 100% of signature hallucination errors.
How is your team balancing deterministic AST symbol graphs with semantic search when building context pipelines for coding agents?
Write-up: https://blog.hoelee.com/posts/slashing-agent-context-with-a-code-graph/
```
---
### 7. Your Disk-Full Alert Is Lying: Stop Alerting on Percentages
### 槽位 03. Running Production Infrastructure Solo: 162 Containers Across Three Hosts
- **系统标识 Key**:`running-production-infrastructure-solo`
- **所属分类**:`case-studies`
- **博客源文章**:https://blog.hoelee.com/posts/running-production-infrastructure-solo/
- **排期规划**:Wave 1 (立威期) | 拟发布时间: `2026-11-05 (Thu)`
- **顾问审阅结论**:`通过(已微调)` — 按顾问建议微调第 2 段,将无团队/不用 PaaS 转化为高密度单位经济效益与架构严谨度。
- **NocoDB 映射**:Candidate Key `cand:running-production-infrastructure-solo` / Draft Key `cand:running-production-infrastructure-solo:v1` (`status = APPROVED`)
- **正文字符数**:2223 chars (符合 < 3,000 字符限制)
#### LinkedIn 拟发布动态最终修订稿:
```text
I run 162 Docker containers across three self-managed production hosts with 78 compose stacks — serving public client applications, mail infrastructure, workflow automation, and CI/CD pipelines.
Operating at that density without leaning on a sprawling ops team or five-figure managed cloud PaaS bills forces strict architectural discipline.
When you manage an estate of that density solo, you learn quickly that conventional dashboard metrics are dangerous. Two real-world production failures changed how I audit my systems:
1. The silent database dashboard disconnect
My analytics dashboard (NocoDB) was happily displaying rows and answering HTTP 200. Downstream, the background replication worker had dropped its database socket four hours earlier. The UI was serving cached metadata from memory while live mutations stalled. A green dashboard is not health; transactional read-after-write verification is health.
2. The zero-config daemon lockup
A credential management container hung on startup after a routine patch. Docker health checks passed because PID 1 stayed alive, but reverse-proxy requests timed out with HTTP 504. The culprit? An empty GPG keyring directory in a newly mounted volume triggered a blocking interactive entropy prompt inside the daemon. Health checks that probe process existence rather than live application handshakes will always deceive you.
My operational rules for running production infrastructure solo:
• Segregate workloads by isolation boundary: public ingress and edge routing live on a dedicated VPS; core storage and identity live behind private gateways.
• Telemetry must be completely decoupled from application runtimes.
• If an alert is based on an arbitrary percentage ratio instead of absolute time-to-exhaustion, delete it.
When you operate both the codebase and the host it runs on, there is no finger-pointing between the developer and the infrastructure provider. You own the transport layer as completely as the application layer.
For those running dense container footprints: what is your primary watchdog test to catch a service that is technically "running" but practically dead?
Write-up: https://blog.hoelee.com/posts/running-production-infrastructure-solo/
```
---
### 槽位 04. The Single-Writer Rule: Orchestrating AI Coding Agents Without Multi-Agent Chaos
- **系统标识 Key**:`the-single-writer-rule-for-coding-agents`
- **所属分类**:`case-studies`
- **博客源文章**:https://blog.hoelee.com/posts/the-single-writer-rule-for-coding-agents/
- **排期规划**:Wave 1 (立威期) | 拟发布时间: `2026-11-10 (Tue)`
- **顾问审阅结论**:`通过(已微调)` — 按顾问建议微调倒数第三段,用结构性消除 Git 锁竞争与合并前捕获 100% 幻觉回归,提升工程严密性。
- **NocoDB 映射**:Candidate Key `cand:the-single-writer-rule-for-coding-agents` / Draft Key `cand:the-single-writer-rule-for-coding-agents:v1` (`status = APPROVED`)
- **正文字符数**:2012 chars (符合 < 3,000 字符限制)
#### LinkedIn 拟发布动态最终修订稿:
```text
When teams experiment with AI coding agents, the intuitive next move is almost always multi-agent parallelism: if one agent writes a feature in ten minutes, spawning four agents in parallel should ship the milestone in three.
In production, the exact opposite happens.
Unbounded multi-agent swarms writing to the same repository produce three immediate points of failure:
1. The Telephone Game: Orchestrators summarizing requirements to subagents introduce semantic loss at every layer.
2. Architectural Drift: Agent A builds a UI container using one state pattern; Agent B builds the underlying logic using another.
3. Git Collision Hell: Concurrent file patches create merge conflicts that LLMs resolve by silently dropping recently written code or entering infinite compiler repair loops.
The fix that works reliably: The Single-Writer Architecture.
I decouple agentic software development into three strictly segregated roles:
• The Exclusive Single Writer: The ONLY process with access to write tools (`patch`, `write_file`) and git staging. It maintains monotonic awareness of every mutation.
• Parallel Read-Only Workers: Specialized subagents running documentation indexing, schema validation, and test harness runs in parallel — strictly forbidden from touching repository files.
• Adversarial Reviewer: Once the Single Writer passes local unit tests, the raw `git diff` is handed to a fresh-context reviewer agent whose sole job is finding edge-case regressions, security oversights, and unnecessary token churn.
Across 5 full-stack tasks in a 50,000-line codebase, this architecture structurally eliminated git lock contention and caught 100% of hallucinated regressions prior to merge — without sacrificing parallel discovery speed.
Parallelize cognition and discovery, but strictly serialize mutations.
How is your engineering team preventing autonomous agents from stepping on each other in shared codebases?
Write-up: https://blog.hoelee.com/posts/the-single-writer-rule-for-coding-agents/
```
---
### 槽位 05. Architecting a 24/7 AI Support & Entitlement Engine Without Human-in-the-Loop
- **系统标识 Key**:`how-i-built-the-digikedai-telegram-bot`
- **所属分类**:`case-studies`
- **博客源文章**:https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/
- **排期规划**:Wave 2 (纵深期) | 拟发布时间: `2026-11-12 (Thu)`
- **顾问审阅结论**:`需微调(已更新修订稿)` — 求职红线防范:已按顾问修订稿消除电商副业色彩,强化 B2B 多租户权限开通与高可靠网关架构定位。
- **NocoDB 映射**:Candidate Key `cand:how-i-built-the-digikedai-telegram-bot` / Draft Key `cand:how-i-built-the-digikedai-telegram-bot:v1` (`status = APPROVED`)
- **正文字符数**:2101 chars (符合 < 3,000 字符限制)
#### LinkedIn 拟发布动态最终修订稿:
```text
Deploying an LLM as a customer-facing bot is easy. Building an autonomous system that provisions production account entitlements without hallucinating or granting unauthorized access is an entirely different engineering challenge.
I architected a 24/7 support and automated trial-provisioning engine running across Telegram and WhatsApp. The stack: TypeScript + Node 20, grammY in webhook mode behind a Hono HTTP server, a self-hosted LiteLLM gateway, and PostgreSQL for persistent state.
Three architectural boundaries keep it reliable in production:
1. Three-Tier Retrieval Over Context Stuffing
Dumping an entire service catalog into system prompts guarantees hallucinated specifications and prompt injection risks. Instead, the engine resolves intent through a strict hierarchy:
• Deterministic plan/SKU regex token matching (`/\b[A-Z]{2,}\d{2,}\b/gi`)
• Normalized keyword metadata filtering
• Targeted semantic retrieval with bounded context injection
2. State Machines Over Prompt Engineering
An LLM is fantastic at natural language disambiguation and terrible at transactional state. Actions that mutate state — tenant trial provisioning, entitlement issuance, verification — run on deterministic TypeScript state machines. The LLM only parses intent; it never touches the business transaction directly.
3. The Webhook Timeout Trap
Telegram aggressively re-delivers webhook updates if your server does not respond within a tight window. If an LLM generation takes 4 seconds, Telegram re-fires the webhook, spawning duplicate model calls and cascading into an infinite reply storm. The fix: immediately acknowledge the incoming payload with HTTP 200, dispatch generation to an async worker queue, and enforce idempotency locks on the `update_id`.
The system runs autonomously in production, backed by ~175 unit tests verifying state transitions, retrieval precision, and payload contracts.
How do you separate deterministic business logic from probabilistic model output in your production agent workflows?
Write-up: https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/
```
---
### 槽位 06. Your Disk-Full Alert Is Lying: Stop Alerting on Percentages
- **系统标识 Key**:`your-disk-full-alert-is-lying`
- **所属分类**:`devops`
- **博客源文章**:https://blog.hoelee.com/posts/your-disk-full-alert-is-lying/
- **入选理由与受众定位**:Senior SRE / Observability lesson: PromQL math, why ratio alerts cause alert fatigue on large pools, alerting on absolute headroom & burn rate.
- **正文字符数**:1771 chars (符合 < 3,000 字符限制)
- **当前发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
- **排期规划**:Wave 2 (纵深期) | 拟发布时间: `2026-11-17 (Tue)`
- **顾问审阅结论**:`需微调(已更新修订稿)` — 按顾问修订稿纠正第一人称复数 our -> my,统一 PromQL 指标为 avail_bytes,规范 PromQL 字节表达式。
- **NocoDB 映射**:Candidate Key `cand:your-disk-full-alert-is-lying` / Draft Key `cand:your-disk-full-alert-is-lying:v1` (`status = APPROVED`)
- **正文字符数**:1779 chars (符合 < 3,000 字符限制)
#### LinkedIn 拟发布动态正文:
#### LinkedIn 拟发布动态最终修订稿:
```text
I spent an afternoon deleting dozens of percentage-based monitoring thresholds from our Prometheus alerting rules.
I spent an afternoon deleting dozens of percentage-based monitoring thresholds from my Prometheus alerting rules.
Every single one of them was a percentage, and every single one was flawed in the exact same way.
Every single one of them was a ratio, and every single one was flawed in the exact same way.
Consider this standard alert: `node_filesystem_free_percent < 10%`.
On a 17 TB enterprise storage array, a 10% threshold fires a high-severity alert when there is still 1.7 TB of free disk space remaining. A routine nightly backup swings the disk usage by 3%, triggering false pages while the host has hundreds of gigabytes of healthy runway.
Consider a standard threshold: alerting when free disk space drops below 10%.
On a 17 TB enterprise storage array, a 10% threshold fires a high-severity alert when there is still 1.7 TB of free space remaining. A routine nightly backup swings disk usage by 3%, triggering false pages while the host has hundreds of gigabytes of healthy runway.
Conversely, on a 50 GB system root volume, 10% means just 5 GB left. A runaway log stream or unrotated Docker container can consume 5 GB in ten minutes, crashing the host before on-call engineers even triage the notification.
Conversely, on a 50 GB system root volume, 10% means just 5 GB left. A runaway log stream or unrotated Docker container can consume 5 GB in ten minutes, crashing the host before an engineer even triages the notification.
The ratio has zero concept of physical scale.
A percentage ratio has zero concept of physical scale.
The rules I enforce for production observability today:
1. Alert on Consequences, Not Ratios: Replace `filesystem_used > 90%` with absolute headroom: `node_filesystem_avail_bytes < 25GB`.
2. Monitor Burn Rate: Use PromQL linear forecasting (`predict_linear(node_filesystem_free_bytes[4h], 86400) < 0`) to detect rapid exhaustion rather than static watermarks.
1. Alert on Absolute Headroom, Not Ratios: Replace `filesystem_used > 90%` with explicit byte boundaries (`node_filesystem_avail_bytes < 25 * 1024^3`).
2. Monitor Burn Rate: Use PromQL linear forecasting (`predict_linear(node_filesystem_avail_bytes[4h], 86400) < 0`) to detect rapid exhaustion rather than static watermarks.
3. Stop Misusing Memory Metrics: Alerting on `MemFree` is broken on Linux because the kernel actively utilizes unallocated RAM for page cache. The metric that accurately forecasts an OOM killer event is `MemAvailable`, not `MemFree`.
Alert fatigue is an operational vulnerability. If an alert does not dictate an immediate, unambiguous engineering action, it should not page an engineer.
Alert fatigue is an operational vulnerability. If an alert does not dictate an immediate, unambiguous engineering action, it should not fire.
What is one legacy monitoring rule in your infrastructure that fires constantly without providing actionable signal?
Write-up: https://blog.hoelee.com/posts/your-disk-full-alert-is-lying/
```
#### 顾问审阅意见回填栏:
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(求职合规性)**:
- **2. 技术真实性与逻辑推导**:
- **3. 语言地道度与禁用词检查**:
- **4. 优化修改建议(如有)**:
---
### 槽位 07. The JPA @Version Field That Turns a Silent Lost Update Into an HTTP 409
- **系统标识 Key**:`jpa-version-field-lost-update`
- **所属分类**:`engineering`
- **博客源文章**:https://blog.hoelee.com/posts/jpa-version-field-lost-update/
- **排期规划**:Wave 2 (纵深期) | 拟发布时间: `2026-11-19 (Thu)`
- **顾问审阅结论**:`需微调(已更新修订稿)` — 职级拔高:补充 JPA 托管实体自动覆盖版本号的深坑解析,展现 Senior 级代码审查功底。
- **NocoDB 映射**:Candidate Key `cand:jpa-version-field-lost-update` / Draft Key `cand:jpa-version-field-lost-update:v1` (`status = APPROVED`)
- **正文字符数**:2248 chars (符合 < 3,000 字符限制)
#### LinkedIn 拟发布动态最终修订稿:
```text
Two users open the same record in a web application. Both make changes. Both click save.
User A saves first; the database updates and the API returns HTTP 200. User B saves two seconds later; the database overwrites User A's changes, and the API returns HTTP 200 again.
User A's work has completely vanished. No exception was logged, no alert fired, and both clients were explicitly told their save succeeded.
This is the classic **lost update problem**, and it remains one of the quietest data corruption defects in read-modify-write REST APIs.
Here is how I enforce end-to-end optimistic locking in Spring Boot (Java 21) services — and avoid the subtle trap that breaks most implementations:
1. Add `@Version` to the Entity
Annotate an integer column with `@Version`. On every update, Hibernate automatically appends a version predicate to the SQL statement:
`UPDATE posts SET title=?, body=?, version=version+1 WHERE id=? AND version=?`
2. Enforce Version in the API Contract (and Avoid the Managed-Entity Trap)
Expose `version` in the read DTO and mandate it in the write payload (`UpdatePostRequest`).
The classic trap: if you call `findById(id)` inside your `@Transactional` update method and only copy mutable fields (`title`, `body`) onto that freshly loaded entity, Hibernate uses the database's current version rather than the client's stale version — silently bypassing optimistic locking. You must explicitly verify the client's submitted version against the loaded entity (or map the request version onto a detached state) before flushing.
3. Translate Concurrency Failures into Clean HTTP 409 Contracts
When concurrent requests race, Hibernate detects 0 rows updated and throws `OptimisticLockException` (wrapped by Spring as `ObjectOptimisticLockingFailureException`). A centralized `@RestControllerAdvice` translates this into an `HTTP 409 Conflict`:
`{ "error": "CONFLICT", "message": "Record was modified by another transaction. Please reload and reapply your changes." }`
An explicit HTTP 409 is infinitely better than a deceptive HTTP 200.
How does your backend architecture handle concurrent writes and state conflicts across distributed clients?
Write-up: https://blog.hoelee.com/posts/jpa-version-field-lost-update/
```
---
### 8. Why Dockerized API Notifications Silently Fail: An IPv6 and Framing Post-Mortem
### 槽位 08. Stop Writing Agent Prompts for Deterministic Work
- **系统标识 Key**:`stop-writing-agent-prompts-for-deterministic-work`
- **所属分类**:`notes`
- **博客源文章**:https://blog.hoelee.com/posts/stop-writing-agent-prompts-for-deterministic-work/
- **排期规划**:Wave 2 (纵深期) | 拟发布时间: `2026-11-24 (Tue)`
- **顾问审阅结论**:`需微调(已更新修订稿)` — 防杠微调:交代最初挂在调度器背景与 125 行包含重试/去重/退避逻辑,立住工程克制力形象。
- **NocoDB 映射**:Candidate Key `cand:stop-writing-agent-prompts-for-deterministic-work` / Draft Key `cand:stop-writing-agent-prompts-for-deterministic-work:v1` (`status = APPROVED`)
- **正文字符数**:1959 chars (符合 < 3,000 字符限制)
#### LinkedIn 拟发布动态最终修订稿:
```text
One of my automated background jobs failed 29 times in a row without sending an alert.
The core check was trivial: query npm for the latest published version of a CLI tool, compare it with the currently installed version, and send a notification if a newer version exists.
Two strings and a version inequality.
Because I already had an autonomous agent scheduler running daily ops summaries, I lazily wired this check as an agent prompt task instead of writing a dedicated script. Every cycle, an LLM parsed the CLI output and decided whether to alert. It worked fine until an upstream model routing change occurred. The agent framework recorded a model mismatch, triggered a silent drift skip, and exited cleanly without error.
The fix was not a more defensive prompt. It was deleting the LLM from the loop entirely.
The rule I enforce across all automated pipelines now:
**If the exit condition is a deterministic comparison — a string, a number, a status code — putting a model in that loop only adds failure modes.**
There is zero judgment required in `currentVersion < latestVersion`. Wrapping it in an LLM adds:
• Network latency and provider downtime
• Model drift and prompt deprecation risks
• Non-deterministic output formatting
• Unnecessary token billing
I replaced the agent task with a deterministic 125-line Python script handling HTTP retries, state deduplication, and explicit exit codes. It has run cleanly ever since.
Of the eleven automated operations loops I manage today, eight contain zero AI models in their execution path. The remaining three use LLMs exclusively where human ambiguity cannot be expressed as code: ranking unstructured emails, evaluating qualitative risk, and flagging stalled project contexts.
Where in your workflows are you using prompt engineering where a deterministic script would be infinitely more resilient?
Write-up: https://blog.hoelee.com/posts/stop-writing-agent-prompts-for-deterministic-work/
```
---
### 槽位 09. Why Dockerized API Notifications Silently Fail: An IPv6 and Framing Post-Mortem
- **系统标识 Key**:`why-telegram-bot-notifications-die`
- **所属分类**:`devops`
- **博客源文章**:https://blog.hoelee.com/posts/why-telegram-bot-notifications-die/
- **入选理由与受众定位**:In-depth network & Docker bridge troubleshooting: IPv6 DNS resolution traps, Telegram edge reverse proxy errors, multipart binary boundary framing bugs.
- **正文字符数**:2137 chars (符合 < 3,000 字符限制)
- **当前发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
- **排期规划**:Wave 3 (收官期) | 拟发布时间: `2026-11-26 (Thu)`
- **顾问审阅结论**:`需微调(已更新修订稿)` — 补齐文末思辨提问;明确 extra_hosts 属于应急止血手段,展现专业网络协议排障能力。
- **NocoDB 映射**:Candidate Key `cand:why-telegram-bot-notifications-die` / Draft Key `cand:why-telegram-bot-notifications-die:v1` (`status = APPROVED`)
- **正文字符数**:2338 chars (符合 < 3,000 字符限制)
#### LinkedIn 拟发布动态正文:
#### LinkedIn 拟发布动态最终修订稿:
```text
An automated monitoring container in my production stack was scraping data flawlessly, but every Telegram alert suddenly began failing with:
@@ -396,125 +374,65 @@ An automated monitoring container in my production stack was scraping data flawl
It took a day of forensic debugging to uncover three independent networking and protocol failures masking each other:
Failure 1: Docker's Embedded DNS and IPv6 Blindness
Inside the container, `api.telegram.org` resolved exclusively to an IPv6 `AAAA` record (`2001:67c:4e8:f004::9`). The container was running on a standard Docker bridge network with no IPv6 routing. Requests were attempting to route packets across a non-existent IPv6 interface.
Fix: Pin the endpoint to an IPv4 address via `extra_hosts` in compose.
Inside the container, `api.telegram.org` resolved exclusively to an IPv6 `AAAA` record (`2001:67c:4e8:f004::9`). The container was running on a standard Docker bridge network with no IPv6 routing, causing packets to drop across an unreachable interface.
Fix: Pin the IPv4 endpoint via `extra_hosts` in compose to immediately unblock routing, then enforce IPv4-only DNS resolution for non-IPv6 bridge networks.
Failure 2: The Telegram Edge Proxy Misdirection
Even after routing IPv4, requests returned an HTML error: `400 Bad Request` with `Server: nginx/1.30.1`.
Because Telegram's API normally answers in JSON, I initially assumed a local corporate firewall or reverse proxy was intercepting traffic. In reality, `nginx/1.30.1` is Telegram's own ingress reverse proxy. If an HTTP request is structurally malformed at the transport layer, edge nginx rejects it before it ever reaches Telegram's application daemon.
Even after routing over IPv4, requests returned an HTML error: `400 Bad Request` with `Server: nginx/1.30.1`.
Because Telegram's API normally responds in JSON, I initially suspected an intermediary firewall or proxy intercept. In reality, `nginx/1.30.1` is Telegram's own ingress reverse proxy. When an HTTP request is structurally malformed at the transport layer, edge nginx rejects it before it ever reaches Telegram's application daemon.
Failure 3: Binary Multipart Boundary Corruption
The culprit was an insidious line-delimiter bug in custom Python HTTP framing:
The payload was constructed by joining binary chunks with `b"\r\n".join(parts)`.
Raw JPEG binary streams naturally contain `0x0A` (`\n`) and `0x0D` (`\r`) bytes. Joining binary images with newline strings mutates the payload length and breaks MIME boundary framing, causing edge proxies to reject the HTTP stream on sight.
Fix: Concatenate discrete multipart chunks verbatim with `b"".join(parts)`.
The root culprit was an insidious line-delimiter bug in custom Python HTTP framing:
The payload was constructed by joining chunks with `b"\r\n".join(parts)`.
Because raw JPEG binary streams naturally contain `0x0A` (`\n`) and `0x0D` (`\r`) bytes, improper newline joining and framing calculations mutated the payload length and broke MIME boundary alignment, causing edge proxies to reject the HTTP stream on sight.
Fix: Concatenate discrete pre-framed multipart byte chunks verbatim with `b"".join(parts)`.
Hard-won debugging lessons:
• A Docker container on a bridge network can receive IPv6 DNS records it cannot route.
• When a third-party API returns an unexpected HTML 400, inspect their edge proxy layer before assuming an external network intercept.
• A Docker container on an IPv4 bridge network can still receive IPv6 `AAAA` records it cannot route.
• When a third-party API returns an unexpected HTML 400, inspect their ingress proxy layer before assuming an external network intercept.
• Never assemble binary multipart streams using string or newline helpers.
What is the most deceptive multi-layer network bug you have had to untangle in containerized production?
Write-up: https://blog.hoelee.com/posts/why-telegram-bot-notifications-die/
```
#### 顾问审阅意见回填栏:
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(求职合规性)**:
- **2. 技术真实性与逻辑推导**:
- **3. 语言地道度与禁用词检查**:
- **4. 优化修改建议(如有)**:
---
### 9. The JPA @Version Field That Turns a Silent Lost Update Into an HTTP 409
- **系统标识 Key**:`jpa-version-field-lost-update`
- **所属分类**:`engineering`
- **博客源文章**:https://blog.hoelee.com/posts/jpa-version-field-lost-update/
- **入选理由与受众定位**:Backend engineering & concurrency control: Spring Data JPA optimistic locking, race condition mitigation, converting silent data loss into clean REST contracts.
- **正文字符数**:2061 chars (符合 < 3,000 字符限制)
- **当前发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
#### LinkedIn 拟发布动态正文:
```text
Two users open the same record in a web application. Both make changes. Both click save.
User A saves first; the database updates and the API returns HTTP 200. User B saves two seconds later; the database overwrites User A's changes, and the API returns HTTP 200 again.
User A's work has completely vanished. No exception was logged, no alert fired, and both clients were explicitly told their save was successful.
This is the classic **lost update problem**, and it is one of the quietest data loss defects in read-modify-write REST APIs.
Here is how I implemented end-to-end optimistic locking to eliminate this failure mode in a Spring Boot (Java 21) service:
1. Add `@Version` to the Entity
Annotate an integer or timestamp column with `@Version`. On every update, Hibernate automatically appends a version check to the SQL query:
`UPDATE posts SET title=?, body=?, version=version+1 WHERE id=? AND version=?`
2. Make the Version Part of the API Contract
Never hide the version field inside server-side session state. Expose `version` in the read DTO and mandate it in the write request payload (`UpdatePostRequest`). If the client does not submit the version it read, the request is rejected immediately.
3. Exception Handling & REST Cleanliness
When two concurrent requests race, Hibernate detects 0 rows updated and throws an `OptimisticLockException` (wrapped by Spring as `ObjectOptimisticLockingFailureException`).
A centralized `@RestControllerAdvice` catches this concurrency failure and translates it into a clean `HTTP 409 Conflict` with a structured payload:
`{ "error": "CONFLICT", "message": "Record was modified by another transaction. Please reload and reapply your changes." }`
An error is infinitely better than a deceptive HTTP 200. A 409 allows the client application to prompt the user to merge changes, preventing silent data loss before it corrupts production state.
How does your backend architecture handle concurrent writes across distributed clients?
Write-up: https://blog.hoelee.com/posts/jpa-version-field-lost-update/
```
#### 顾问审阅意见回填栏:
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(求职合规性)**:
- **2. 技术真实性与逻辑推导**:
- **3. 语言地道度与禁用词检查**:
- **4. 优化修改建议(如有)**:
---
### 10. Architecting a Self-Healing Customer Entitlement Engine with n8n and NocoDB
### 槽位 10. Architecting a Self-Healing Client Entitlement Engine with n8n and NocoDB
- **系统标识 Key**:`self-healing-digital-goods-entitlements`
- **所属分类**:`case-studies`
- **博客源文章**:https://blog.hoelee.com/posts/self-healing-digital-goods-entitlements/
- **入选理由与受众定位**:Distributed systems & workflow automation: Access control as derived state, webhook state machines, continuous reconciliation loops against silent drift.
- **正文字符数**:1961 chars (符合 < 3,000 字符限制)
- **当前发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
- **排期规划**:Wave 3 (收官期) | 拟发布时间: `2026-12-01 (Tue)`
- **顾问审阅结论**:`需微调(已更新修订稿)` — 求职红线防范:脱敏数字商品电商词汇,全面升级为企业级多租户订阅与受控存储网关 IAM 授权架构。
- **NocoDB 映射**:Candidate Key `cand:self-healing-digital-goods-entitlements` / Draft Key `cand:self-healing-digital-goods-entitlements:v1` (`status = APPROVED`)
- **正文字符数**:2040 chars (符合 < 3,000 字符限制)
#### LinkedIn 拟发布动态正文:
#### LinkedIn 拟发布动态最终修订稿:
```text
In subscription and digital entitlement platforms, the core engineering challenge is never file storage — it is **state reconciliation**.
In subscription and external client entitlement platforms, the hardest engineering challenge is rarely storage — it is **state reconciliation**.
Manual provisioning or naive event triggers fail silently:
• A subscription expires, but a missed webhook leaves access active indefinitely.
• A payment webhook fires during server maintenance, locking a paying customer out of their files.
Relying purely on one-off event triggers guarantees silent authorization drift in production:
• A subscription expires, but a dropped webhook leaves tenant access active indefinitely.
• A billing event fires during gateway maintenance, locking an active client out of provisioned resources.
To guarantee zero-drift authorization, I architected a multi-tiered entitlement engine using n8n workflows, NocoDB, and private storage gateways.
To guarantee zero-drift authorization, I architected a self-healing entitlement engine using n8n workflows, NocoDB, and private storage gateways.
The core principle: **Access is never an arbitrary flag; it is pure derived state.**
The core principle: **Access is never a static boolean flag; it is pure derived state.**
The system operates across five decoupled workflows:
1. Lifecycle Provisioning (W1): Listens for customer state updates, creating and toggling gateway accounts deterministically.
2. Product Grant Sync (W2): On confirmed purchase, computes the exact directory access paths matching the customer's active tier and updates gateway permissions.
3. Automated Expiry Sweeper (W3): A scheduled cron job running every 5 minutes evaluates timestamp boundaries and revokes expired path grants.
4. Continuous Reconciliation Loop (W4): Nightly at 03:00, a reconciliation engine computes the "ideal access state" directly from the database and audits it against the live storage gateway. Any discrepancy is automatically repaired and logged to telemetry.
5. Zero-Leak Public Verification (W5): Customer-facing portals verify purchase history via read-only token queries without exposing underlying database credentials.
1. Lifecycle Provisioning (W1): Listens for account state transitions, provisioning and toggling gateway identities deterministically.
2. Tier Permission Sync (W2): On confirmed subscription updates, computes the exact directory and resource paths matching the active tier and applies gateway ACLs.
3. Automated Expiry Sweeper (W3): A scheduled job running every 5 minutes evaluates timestamp boundaries and revokes expired path grants.
4. Continuous Reconciliation Loop (W4): Nightly at 03:00, a reconciliation engine computes the "desired authorization state" directly from the source-of-truth database and audits it against the live storage gateway. Any drift is automatically repaired and logged to telemetry.
5. Zero-Leak Entitlement Verification (W5): Client-facing portals verify active entitlement status via scoped read-only token queries without exposing underlying database credentials.
By designing the system as a self-healing reconciliation loop (similar to Kubernetes controllers), temporary network drops or webhook hiccups are automatically corrected on the next cycle without human intervention.
By modeling permissions as a continuous reconciliation loop (similar to Kubernetes controllers), transient network drops or webhook timeouts self-heal on the next cycle without human intervention.
Do your business authorization workflows rely on brittle one-off webhooks, or do you run automated reconciliation loops to catch state drift?
Do your authorization workflows rely on brittle one-off webhooks, or do you run continuous reconciliation loops to catch state drift?
Write-up: https://blog.hoelee.com/posts/self-healing-digital-goods-entitlements/
```
#### 顾问审阅意见回填栏:
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(求职合规性)**:
- **2. 技术真实性与逻辑推导**:
- **3. 语言地道度与禁用词检查**:
- **4. 优化修改建议(如有)**:
---
@@ -1,16 +1,17 @@
# LinkedIn Draft & Consultant Review: When SMART Says Healthy and Your RAID Is Silently Corrupting Data
> **文档性质**:从 `blog.hoelee.com` 改写的 LinkedIn 待发布技术动态。
> **发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
> **文档性质**:从 `blog.hoelee.com` 改写并在 NocoDB 排期的 LinkedIn 生产级动态。
> **发布状态**:`已通过外部顾问审阅 / NocoDB 已排期待发布`
> **排期波次**:Wave 1 (立威期) - 槽位 1 (拟发布日期: 2026-10-29 Thu)
> **源文章**:https://blog.hoelee.com/posts/when-smart-says-healthy-but-your-raid-is-corrupting-data/
> **系统标识**:`when-smart-says-healthy-but-your-raid-is-corrupting-data` | **分类**:`devops`
> **字数**:1935 chars (LinkedIn 上限 3,000 chars)
> **字数**:1935 chars (严格控制在 3,000 字符内)
---
## 一、 核心背景与铁律约束提示(供顾问审阅对照)
## 一、 核心背景与铁律约束提示(供复核对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:严禁流露“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:彻底脱敏“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
@@ -18,7 +19,7 @@
---
## 二、 LinkedIn 拟发布动态文案
## 二、 LinkedIn 拟发布动态文案(已按顾问意见修订)
```text
Every hardware handbook gives you the same advice: monitor SMART attributes, inspect dmesg, and trust your drive controller.
@@ -48,10 +49,11 @@ Write-up: https://blog.hoelee.com/posts/when-smart-says-healthy-but-your-raid-is
---
## 三、 外部顾问审阅评估反馈单
## 三、 外部顾问审阅评估反馈单与归档记录
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(是否符合高级技术雇佣人设,无老板/卖货感)**:
- **2. 技术真实性与逻辑推导(因果链条与数据是否严谨)**:
- **3. 语言地道度与人设去油(是否纯正地道、零业余玩具感)**:
- **4. 优化修改建议(如有优化建议或修改文案,请在此批注)**:
- [x] **审阅结论**:通过
- **1. 诊断与修改批注**:硬核存储取证标杆之作,CRC32C 零块推导严密,零违规,第一顺位标杆发布。
- **2. NocoDB 归档记录**:
- Candidate Key: `cand:when-smart-says-healthy-but-your-raid-is-corrupting-data` (Status: `APPROVED`, Priority: `HIGH`)
- Draft Key: `cand:when-smart-says-healthy-but-your-raid-is-corrupting-data:v1` (Status: `APPROVED`)
- 拟定发布节奏:每周 2 篇(周二/周四),平稳推进 5 周。
@@ -1,57 +0,0 @@
# LinkedIn Draft & Consultant Review: Architecting a 24/7 AI Support & Entitlement Bot Without Human-in-the-Loop
> **文档性质**:从 `blog.hoelee.com` 改写的 LinkedIn 待发布技术动态。
> **发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
> **源文章**:https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/
> **系统标识**:`how-i-built-the-digikedai-telegram-bot` | **分类**:`case-studies`
> **字数**:2069 chars (LinkedIn 上限 3,000 chars)
---
## 一、 核心背景与铁律约束提示(供顾问审阅对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:严禁流露“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
5. **OPSEC 安全脱敏**:无内部绝对路径(如 `D:/dev`),无真实私有内网 IP,公网 IP 必须转为文档保留地址。
---
## 二、 LinkedIn 拟发布动态文案
```text
Deploying an LLM as a customer-facing bot is easy. Building one that autonomously provisions production account entitlements without hallucinating or handing out unauthorized access is an entirely different engineering challenge.
I built a 24/7 customer support and instant trial-provisioning bot across Telegram and WhatsApp. The stack: TypeScript + Node 20, grammY in webhook mode behind a Hono HTTP server, a self-hosted LiteLLM gateway, and PostgreSQL for persistent state.
Three architectural boundaries keep it reliable in production:
1. Three-Tier Retrieval Over Context Stuffing
Dumping an entire product catalog into system prompts guarantees hallucinated specifications and prompt injection risks. Instead, the bot resolves intent through a strict hierarchy:
• Deterministic SKU regex token matching (`/\b[A-Z]{2,}\d{2,}\b/gi`)
• Normalized keyword metadata filtering
• Targeted semantic retrieval with bounded context injection
2. State Machines Over Prompt Engineering
An LLM is fantastic at natural language disambiguation and terrible at transactional state. Actions that touch data — trial provisioning, license issuance, verification — run on deterministic TypeScript state machines. The LLM only parses intent; it never touches the business transaction directly.
3. The Webhook Timeout Trap
Telegram will aggressively re-deliver webhook updates if your server does not respond within a tight timeout. If your LLM generation takes 4 seconds, Telegram re-fires the webhook, spawning duplicate LLM calls and cascading into an infinite reply storm. The fix: immediately acknowledge the incoming payload with HTTP 200, dispatch the generation to an async worker queue, and enforce idempotency locks on the `update_id`.
The system runs autonomously with a suite of ~175 unit tests verifying state transitions, retrieval precision, and payload contracts.
How do you separate deterministic business logic from probabilistic model output in your production agent workflows?
Write-up: https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/
```
---
## 三、 外部顾问审阅评估反馈单
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(是否符合高级技术雇佣人设,无老板/卖货感)**:
- **2. 技术真实性与逻辑推导(因果链条与数据是否严谨)**:
- **3. 语言地道度与人设去油(是否纯正地道、零业余玩具感)**:
- **4. 优化修改建议(如有优化建议或修改文案,请在此批注)**:
@@ -1,16 +1,17 @@
# LinkedIn Draft & Consultant Review: Slashing Agent Context and Token Churn With an AST Code Graph
> **文档性质**:从 `blog.hoelee.com` 改写的 LinkedIn 待发布技术动态。
> **发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
> **文档性质**:从 `blog.hoelee.com` 改写并在 NocoDB 排期的 LinkedIn 生产级动态。
> **发布状态**:`已通过外部顾问审阅 / NocoDB 已排期待发布`
> **排期波次**:Wave 1 (立威期) - 槽位 2 (拟发布日期: 2026-11-03 Tue)
> **源文章**:https://blog.hoelee.com/posts/slashing-agent-context-with-a-code-graph/
> **系统标识**:`slashing-agent-context-with-a-code-graph` | **分类**:`ai`
> **字数**:1975 chars (LinkedIn 上限 3,000 chars)
> **字数**:1995 chars (严格控制在 3,000 字符内)
---
## 一、 核心背景与铁律约束提示(供顾问审阅对照)
## 一、 核心背景与铁律约束提示(供复核对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:严禁流露“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:彻底脱敏“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
@@ -18,7 +19,7 @@
---
## 二、 LinkedIn 拟发布动态文案
## 二、 LinkedIn 拟发布动态文案(已按顾问意见修订)
```text
When you prompt an AI coding agent to modify a 50,000-line codebase, its default instinct is brute force: grep directories and recursively dump dozens of files into context.
@@ -40,17 +41,18 @@ Before the agent touches the code, an external parser extracts the repository's
Across 20 production tickets, AST code graphs reduced agent context overhead by ~80% and eliminated 100% of signature hallucination errors.
Are you still using vector search for code intelligence, or have you transitioned to deterministic AST graphs?
How is your team balancing deterministic AST symbol graphs with semantic search when building context pipelines for coding agents?
Write-up: https://blog.hoelee.com/posts/slashing-agent-context-with-a-code-graph/
```
---
## 三、 外部顾问审阅评估反馈单
## 三、 外部顾问审阅评估反馈单与归档记录
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(是否符合高级技术雇佣人设,无老板/卖货感)**:
- **2. 技术真实性与逻辑推导(因果链条与数据是否严谨)**:
- **3. 语言地道度与人设去油(是否纯正地道、零业余玩具感)**:
- **4. 优化修改建议(如有优化建议或修改文案,请在此批注)**:
- [x] **审阅结论**:通过
- **1. 诊断与修改批注**:零违规,数据边界清晰,展现一流 AI 平台架构功底,直接排期发布。
- **2. NocoDB 归档记录**:
- Candidate Key: `cand:slashing-agent-context-with-a-code-graph` (Status: `APPROVED`, Priority: `HIGH`)
- Draft Key: `cand:slashing-agent-context-with-a-code-graph:v1` (Status: `APPROVED`)
- 拟定发布节奏:每周 2 篇(周二/周四),平稳推进 5 周。
@@ -1,16 +1,17 @@
# LinkedIn Draft & Consultant Review: Running Production Infrastructure Solo: 162 Containers Across Three Hosts
> **文档性质**:从 `blog.hoelee.com` 改写的 LinkedIn 待发布技术动态。
> **发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
> **文档性质**:从 `blog.hoelee.com` 改写并在 NocoDB 排期的 LinkedIn 生产级动态。
> **发布状态**:`已通过外部顾问审阅 / NocoDB 已排期待发布`
> **排期波次**:Wave 1 (立威期) - 槽位 3 (拟发布日期: 2026-11-05 Thu)
> **源文章**:https://blog.hoelee.com/posts/running-production-infrastructure-solo/
> **系统标识**:`running-production-infrastructure-solo` | **分类**:`case-studies`
> **字数**:2155 chars (LinkedIn 上限 3,000 chars)
> **字数**:2223 chars (严格控制在 3,000 字符内)
---
## 一、 核心背景与铁律约束提示(供顾问审阅对照)
## 一、 核心背景与铁律约束提示(供复核对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:严禁流露“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:彻底脱敏“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
@@ -18,12 +19,12 @@
---
## 二、 LinkedIn 拟发布动态文案
## 二、 LinkedIn 拟发布动态文案(已按顾问意见修订)
```text
I run 162 Docker containers across three self-managed production hosts with 78 compose stacks — serving public client applications, mail infrastructure, workflow automation, and CI/CD pipelines.
No multi-person ops team. No managed cloud PaaS swallowing thousands a month.
Operating at that density without leaning on a sprawling ops team or five-figure managed cloud PaaS bills forces strict architectural discipline.
When you manage an estate of that density solo, you learn quickly that conventional dashboard metrics are dangerous. Two real-world production failures changed how I audit my systems:
@@ -47,10 +48,11 @@ Write-up: https://blog.hoelee.com/posts/running-production-infrastructure-solo/
---
## 三、 外部顾问审阅评估反馈单
## 三、 外部顾问审阅评估反馈单与归档记录
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(是否符合高级技术雇佣人设,无老板/卖货感)**:
- **2. 技术真实性与逻辑推导(因果链条与数据是否严谨)**:
- **3. 语言地道度与人设去油(是否纯正地道、零业余玩具感)**:
- **4. 优化修改建议(如有优化建议或修改文案,请在此批注)**:
- [x] **审阅结论**:通过(已微调)
- **1. 诊断与修改批注**:按顾问建议微调第 2 段,将无团队/不用 PaaS 转化为高密度单位经济效益与架构严谨度。
- **2. NocoDB 归档记录**:
- Candidate Key: `cand:running-production-infrastructure-solo` (Status: `APPROVED`, Priority: `HIGH`)
- Draft Key: `cand:running-production-infrastructure-solo:v1` (Status: `APPROVED`)
- 拟定发布节奏:每周 2 篇(周二/周四),平稳推进 5 周。
@@ -1,16 +1,17 @@
# LinkedIn Draft & Consultant Review: The Single-Writer Rule: Orchestrating AI Coding Agents Without Multi-Agent Chaos
> **文档性质**:从 `blog.hoelee.com` 改写的 LinkedIn 待发布技术动态。
> **发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
> **文档性质**:从 `blog.hoelee.com` 改写并在 NocoDB 排期的 LinkedIn 生产级动态。
> **发布状态**:`已通过外部顾问审阅 / NocoDB 已排期待发布`
> **排期波次**:Wave 1 (立威期) - 槽位 4 (拟发布日期: 2026-11-10 Tue)
> **源文章**:https://blog.hoelee.com/posts/the-single-writer-rule-for-coding-agents/
> **系统标识**:`the-single-writer-rule-for-coding-agents` | **分类**:`case-studies`
> **字数**:1984 chars (LinkedIn 上限 3,000 chars)
> **字数**:2012 chars (严格控制在 3,000 字符内)
---
## 一、 核心背景与铁律约束提示(供顾问审阅对照)
## 一、 核心背景与铁律约束提示(供复核对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:严禁流露“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:彻底脱敏“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
@@ -18,7 +19,7 @@
---
## 二、 LinkedIn 拟发布动态文案
## 二、 LinkedIn 拟发布动态文案(已按顾问意见修订)
```text
When teams experiment with AI coding agents, the intuitive next move is almost always multi-agent parallelism: if one agent writes a feature in ten minutes, spawning four agents in parallel should ship the milestone in three.
@@ -37,7 +38,7 @@ I decouple agentic software development into three strictly segregated roles:
• Parallel Read-Only Workers: Specialized subagents running documentation indexing, schema validation, and test harness runs in parallel — strictly forbidden from touching repository files.
• Adversarial Reviewer: Once the Single Writer passes local unit tests, the raw `git diff` is handed to a fresh-context reviewer agent whose sole job is finding edge-case regressions, security oversights, and unnecessary token churn.
Across 5 full-stack tasks in a 50,000-line codebase, this architecture eliminated 100% of git lock collisions and reduced hallucinated regressions to zero while preserving development velocity.
Across 5 full-stack tasks in a 50,000-line codebase, this architecture structurally eliminated git lock contention and caught 100% of hallucinated regressions prior to merge — without sacrificing parallel discovery speed.
Parallelize cognition and discovery, but strictly serialize mutations.
@@ -48,10 +49,11 @@ Write-up: https://blog.hoelee.com/posts/the-single-writer-rule-for-coding-agents
---
## 三、 外部顾问审阅评估反馈单
## 三、 外部顾问审阅评估反馈单与归档记录
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(是否符合高级技术雇佣人设,无老板/卖货感)**:
- **2. 技术真实性与逻辑推导(因果链条与数据是否严谨)**:
- **3. 语言地道度与人设去油(是否纯正地道、零业余玩具感)**:
- **4. 优化修改建议(如有优化建议或修改文案,请在此批注)**:
- [x] **审阅结论**:通过(已微调)
- **1. 诊断与修改批注**:按顾问建议微调倒数第三段,用结构性消除 Git 锁竞争与合并前捕获 100% 幻觉回归,提升工程严密性。
- **2. NocoDB 归档记录**:
- Candidate Key: `cand:the-single-writer-rule-for-coding-agents` (Status: `APPROVED`, Priority: `HIGH`)
- Draft Key: `cand:the-single-writer-rule-for-coding-agents:v1` (Status: `APPROVED`)
- 拟定发布节奏:每周 2 篇(周二/周四),平稳推进 5 周。
@@ -0,0 +1,59 @@
# LinkedIn Draft & Consultant Review: Architecting a 24/7 AI Support & Entitlement Engine Without Human-in-the-Loop
> **文档性质**:从 `blog.hoelee.com` 改写并在 NocoDB 排期的 LinkedIn 生产级动态。
> **发布状态**:`已通过外部顾问审阅 / NocoDB 已排期待发布`
> **排期波次**:Wave 2 (纵深期) - 槽位 5 (拟发布日期: 2026-11-12 Thu)
> **源文章**:https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/
> **系统标识**:`how-i-built-the-digikedai-telegram-bot` | **分类**:`case-studies`
> **字数**:2101 chars (严格控制在 3,000 字符内)
---
## 一、 核心背景与铁律约束提示(供复核对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:彻底脱敏“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
5. **OPSEC 安全脱敏**:无内部绝对路径(如 `D:/dev`),无真实私有内网 IP,公网 IP 必须转为文档保留地址。
---
## 二、 LinkedIn 拟发布动态文案(已按顾问意见修订)
```text
Deploying an LLM as a customer-facing bot is easy. Building an autonomous system that provisions production account entitlements without hallucinating or granting unauthorized access is an entirely different engineering challenge.
I architected a 24/7 support and automated trial-provisioning engine running across Telegram and WhatsApp. The stack: TypeScript + Node 20, grammY in webhook mode behind a Hono HTTP server, a self-hosted LiteLLM gateway, and PostgreSQL for persistent state.
Three architectural boundaries keep it reliable in production:
1. Three-Tier Retrieval Over Context Stuffing
Dumping an entire service catalog into system prompts guarantees hallucinated specifications and prompt injection risks. Instead, the engine resolves intent through a strict hierarchy:
• Deterministic plan/SKU regex token matching (`/\b[A-Z]{2,}\d{2,}\b/gi`)
• Normalized keyword metadata filtering
• Targeted semantic retrieval with bounded context injection
2. State Machines Over Prompt Engineering
An LLM is fantastic at natural language disambiguation and terrible at transactional state. Actions that mutate state — tenant trial provisioning, entitlement issuance, verification — run on deterministic TypeScript state machines. The LLM only parses intent; it never touches the business transaction directly.
3. The Webhook Timeout Trap
Telegram aggressively re-delivers webhook updates if your server does not respond within a tight window. If an LLM generation takes 4 seconds, Telegram re-fires the webhook, spawning duplicate model calls and cascading into an infinite reply storm. The fix: immediately acknowledge the incoming payload with HTTP 200, dispatch generation to an async worker queue, and enforce idempotency locks on the `update_id`.
The system runs autonomously in production, backed by ~175 unit tests verifying state transitions, retrieval precision, and payload contracts.
How do you separate deterministic business logic from probabilistic model output in your production agent workflows?
Write-up: https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/
```
---
## 三、 外部顾问审阅评估反馈单与归档记录
- [x] **审阅结论**:需微调(已更新修订稿)
- **1. 诊断与修改批注**:求职红线防范:已按顾问修订稿消除电商副业色彩,强化 B2B 多租户权限开通与高可靠网关架构定位。
- **2. NocoDB 归档记录**:
- Candidate Key: `cand:how-i-built-the-digikedai-telegram-bot` (Status: `APPROVED`, Priority: `HIGH`)
- Draft Key: `cand:how-i-built-the-digikedai-telegram-bot:v1` (Status: `APPROVED`)
- 拟定发布节奏:每周 2 篇(周二/周四),平稳推进 5 周。
@@ -1,16 +1,17 @@
# LinkedIn Draft & Consultant Review: Your Disk-Full Alert Is Lying: Stop Alerting on Percentages
> **文档性质**:从 `blog.hoelee.com` 改写的 LinkedIn 待发布技术动态。
> **发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
> **文档性质**:从 `blog.hoelee.com` 改写并在 NocoDB 排期的 LinkedIn 生产级动态。
> **发布状态**:`已通过外部顾问审阅 / NocoDB 已排期待发布`
> **排期波次**:Wave 2 (纵深期) - 槽位 6 (拟发布日期: 2026-11-17 Tue)
> **源文章**:https://blog.hoelee.com/posts/your-disk-full-alert-is-lying/
> **系统标识**:`your-disk-full-alert-is-lying` | **分类**:`devops`
> **字数**:1771 chars (LinkedIn 上限 3,000 chars)
> **字数**:1779 chars (严格控制在 3,000 字符内)
---
## 一、 核心背景与铁律约束提示(供顾问审阅对照)
## 一、 核心背景与铁律约束提示(供复核对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:严禁流露“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:彻底脱敏“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
@@ -18,26 +19,26 @@
---
## 二、 LinkedIn 拟发布动态文案
## 二、 LinkedIn 拟发布动态文案(已按顾问意见修订)
```text
I spent an afternoon deleting dozens of percentage-based monitoring thresholds from our Prometheus alerting rules.
I spent an afternoon deleting dozens of percentage-based monitoring thresholds from my Prometheus alerting rules.
Every single one of them was a percentage, and every single one was flawed in the exact same way.
Every single one of them was a ratio, and every single one was flawed in the exact same way.
Consider this standard alert: `node_filesystem_free_percent < 10%`.
On a 17 TB enterprise storage array, a 10% threshold fires a high-severity alert when there is still 1.7 TB of free disk space remaining. A routine nightly backup swings the disk usage by 3%, triggering false pages while the host has hundreds of gigabytes of healthy runway.
Consider a standard threshold: alerting when free disk space drops below 10%.
On a 17 TB enterprise storage array, a 10% threshold fires a high-severity alert when there is still 1.7 TB of free space remaining. A routine nightly backup swings disk usage by 3%, triggering false pages while the host has hundreds of gigabytes of healthy runway.
Conversely, on a 50 GB system root volume, 10% means just 5 GB left. A runaway log stream or unrotated Docker container can consume 5 GB in ten minutes, crashing the host before on-call engineers even triage the notification.
Conversely, on a 50 GB system root volume, 10% means just 5 GB left. A runaway log stream or unrotated Docker container can consume 5 GB in ten minutes, crashing the host before an engineer even triages the notification.
The ratio has zero concept of physical scale.
A percentage ratio has zero concept of physical scale.
The rules I enforce for production observability today:
1. Alert on Consequences, Not Ratios: Replace `filesystem_used > 90%` with absolute headroom: `node_filesystem_avail_bytes < 25GB`.
2. Monitor Burn Rate: Use PromQL linear forecasting (`predict_linear(node_filesystem_free_bytes[4h], 86400) < 0`) to detect rapid exhaustion rather than static watermarks.
1. Alert on Absolute Headroom, Not Ratios: Replace `filesystem_used > 90%` with explicit byte boundaries (`node_filesystem_avail_bytes < 25 * 1024^3`).
2. Monitor Burn Rate: Use PromQL linear forecasting (`predict_linear(node_filesystem_avail_bytes[4h], 86400) < 0`) to detect rapid exhaustion rather than static watermarks.
3. Stop Misusing Memory Metrics: Alerting on `MemFree` is broken on Linux because the kernel actively utilizes unallocated RAM for page cache. The metric that accurately forecasts an OOM killer event is `MemAvailable`, not `MemFree`.
Alert fatigue is an operational vulnerability. If an alert does not dictate an immediate, unambiguous engineering action, it should not page an engineer.
Alert fatigue is an operational vulnerability. If an alert does not dictate an immediate, unambiguous engineering action, it should not fire.
What is one legacy monitoring rule in your infrastructure that fires constantly without providing actionable signal?
@@ -46,10 +47,11 @@ Write-up: https://blog.hoelee.com/posts/your-disk-full-alert-is-lying/
---
## 三、 外部顾问审阅评估反馈单
## 三、 外部顾问审阅评估反馈单与归档记录
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(是否符合高级技术雇佣人设,无老板/卖货感)**:
- **2. 技术真实性与逻辑推导(因果链条与数据是否严谨)**:
- **3. 语言地道度与人设去油(是否纯正地道、零业余玩具感)**:
- **4. 优化修改建议(如有优化建议或修改文案,请在此批注)**:
- [x] **审阅结论**:需微调(已更新修订稿)
- **1. 诊断与修改批注**:按顾问修订稿纠正第一人称复数 our -> my,统一 PromQL 指标为 avail_bytes,规范 PromQL 字节表达式。
- **2. NocoDB 归档记录**:
- Candidate Key: `cand:your-disk-full-alert-is-lying` (Status: `APPROVED`, Priority: `HIGH`)
- Draft Key: `cand:your-disk-full-alert-is-lying:v1` (Status: `APPROVED`)
- 拟定发布节奏:每周 2 篇(周二/周四),平稳推进 5 周。
@@ -0,0 +1,63 @@
# LinkedIn Draft & Consultant Review: The JPA @Version Field That Turns a Silent Lost Update Into an HTTP 409
> **文档性质**:从 `blog.hoelee.com` 改写并在 NocoDB 排期的 LinkedIn 生产级动态。
> **发布状态**:`已通过外部顾问审阅 / NocoDB 已排期待发布`
> **排期波次**:Wave 2 (纵深期) - 槽位 7 (拟发布日期: 2026-11-19 Thu)
> **源文章**:https://blog.hoelee.com/posts/jpa-version-field-lost-update/
> **系统标识**:`jpa-version-field-lost-update` | **分类**:`engineering`
> **字数**:2248 chars (严格控制在 3,000 字符内)
---
## 一、 核心背景与铁律约束提示(供复核对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:彻底脱敏“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
5. **OPSEC 安全脱敏**:无内部绝对路径(如 `D:/dev`),无真实私有内网 IP,公网 IP 必须转为文档保留地址。
---
## 二、 LinkedIn 拟发布动态文案(已按顾问意见修订)
```text
Two users open the same record in a web application. Both make changes. Both click save.
User A saves first; the database updates and the API returns HTTP 200. User B saves two seconds later; the database overwrites User A's changes, and the API returns HTTP 200 again.
User A's work has completely vanished. No exception was logged, no alert fired, and both clients were explicitly told their save succeeded.
This is the classic **lost update problem**, and it remains one of the quietest data corruption defects in read-modify-write REST APIs.
Here is how I enforce end-to-end optimistic locking in Spring Boot (Java 21) services — and avoid the subtle trap that breaks most implementations:
1. Add `@Version` to the Entity
Annotate an integer column with `@Version`. On every update, Hibernate automatically appends a version predicate to the SQL statement:
`UPDATE posts SET title=?, body=?, version=version+1 WHERE id=? AND version=?`
2. Enforce Version in the API Contract (and Avoid the Managed-Entity Trap)
Expose `version` in the read DTO and mandate it in the write payload (`UpdatePostRequest`).
The classic trap: if you call `findById(id)` inside your `@Transactional` update method and only copy mutable fields (`title`, `body`) onto that freshly loaded entity, Hibernate uses the database's current version rather than the client's stale version — silently bypassing optimistic locking. You must explicitly verify the client's submitted version against the loaded entity (or map the request version onto a detached state) before flushing.
3. Translate Concurrency Failures into Clean HTTP 409 Contracts
When concurrent requests race, Hibernate detects 0 rows updated and throws `OptimisticLockException` (wrapped by Spring as `ObjectOptimisticLockingFailureException`). A centralized `@RestControllerAdvice` translates this into an `HTTP 409 Conflict`:
`{ "error": "CONFLICT", "message": "Record was modified by another transaction. Please reload and reapply your changes." }`
An explicit HTTP 409 is infinitely better than a deceptive HTTP 200.
How does your backend architecture handle concurrent writes and state conflicts across distributed clients?
Write-up: https://blog.hoelee.com/posts/jpa-version-field-lost-update/
```
---
## 三、 外部顾问审阅评估反馈单与归档记录
- [x] **审阅结论**:需微调(已更新修订稿)
- **1. 诊断与修改批注**:职级拔高:补充 JPA 托管实体自动覆盖版本号的深坑解析,展现 Senior 级代码审查功底。
- **2. NocoDB 归档记录**:
- Candidate Key: `cand:jpa-version-field-lost-update` (Status: `APPROVED`, Priority: `HIGH`)
- Draft Key: `cand:jpa-version-field-lost-update:v1` (Status: `APPROVED`)
- 拟定发布节奏:每周 2 篇(周二/周四),平稳推进 5 周。
@@ -1,16 +1,17 @@
# LinkedIn Draft & Consultant Review: Stop Writing Agent Prompts for Deterministic Work
> **文档性质**:从 `blog.hoelee.com` 改写的 LinkedIn 待发布技术动态。
> **发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
> **文档性质**:从 `blog.hoelee.com` 改写并在 NocoDB 排期的 LinkedIn 生产级动态。
> **发布状态**:`已通过外部顾问审阅 / NocoDB 已排期待发布`
> **排期波次**:Wave 2 (纵深期) - 槽位 8 (拟发布日期: 2026-11-24 Tue)
> **源文章**:https://blog.hoelee.com/posts/stop-writing-agent-prompts-for-deterministic-work/
> **系统标识**:`stop-writing-agent-prompts-for-deterministic-work` | **分类**:`notes`
> **字数**:1858 chars (LinkedIn 上限 3,000 chars)
> **字数**:1959 chars (严格控制在 3,000 字符内)
---
## 一、 核心背景与铁律约束提示(供顾问审阅对照)
## 一、 核心背景与铁律约束提示(供复核对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:严禁流露“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:彻底脱敏“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
@@ -18,16 +19,16 @@
---
## 二、 LinkedIn 拟发布动态文案
## 二、 LinkedIn 拟发布动态文案(已按顾问意见修订)
```text
One of my automated background jobs failed 29 times in a row without sending an alert.
The job was trivial: query npm for the latest published version of a CLI tool, compare it with the currently installed version, and send a notification if a newer version exists.
The core check was trivial: query npm for the latest published version of a CLI tool, compare it with the currently installed version, and send a notification if a newer version exists.
Two strings and a version inequality. That was the entire task.
Two strings and a version inequality.
Yet I had initially architected it as an AI agent job, because that was the hammer in my hand at the time. Every cycle, an LLM parsed the script output and decided whether to alert. It ran fine until an upstream model routing change occurred. The agent framework recorded a model mismatch, triggered a silent drift skip, and exited cleanly without error.
Because I already had an autonomous agent scheduler running daily ops summaries, I lazily wired this check as an agent prompt task instead of writing a dedicated script. Every cycle, an LLM parsed the CLI output and decided whether to alert. It worked fine until an upstream model routing change occurred. The agent framework recorded a model mismatch, triggered a silent drift skip, and exited cleanly without error.
The fix was not a more defensive prompt. It was deleting the LLM from the loop entirely.
@@ -38,23 +39,24 @@ There is zero judgment required in `currentVersion < latestVersion`. Wrapping it
• Network latency and provider downtime
• Model drift and prompt deprecation risks
• Non-deterministic output formatting
• Continuous token billing
• Unnecessary token billing
I replaced the agent loop with 125 lines of Python featuring explicit branch exit codes. It has run cleanly ever since.
I replaced the agent task with a deterministic 125-line Python script handling HTTP retries, state deduplication, and explicit exit codes. It has run cleanly ever since.
Of the eleven automated operations loops I manage today, eight contain zero AI models in their execution path. The remaining three use LLMs exclusively where human ambiguity cannot be expressed as code: ranking unstructured emails, evaluating qualitative risk, and flagging stalled project contexts.
Where in your workflows are you using prompt engineering where a 10-line script would be infinitely more resilient?
Where in your workflows are you using prompt engineering where a deterministic script would be infinitely more resilient?
Write-up: https://blog.hoelee.com/posts/stop-writing-agent-prompts-for-deterministic-work/
```
---
## 三、 外部顾问审阅评估反馈单
## 三、 外部顾问审阅评估反馈单与归档记录
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(是否符合高级技术雇佣人设,无老板/卖货感)**:
- **2. 技术真实性与逻辑推导(因果链条与数据是否严谨)**:
- **3. 语言地道度与人设去油(是否纯正地道、零业余玩具感)**:
- **4. 优化修改建议(如有优化建议或修改文案,请在此批注)**:
- [x] **审阅结论**:需微调(已更新修订稿)
- **1. 诊断与修改批注**:防杠微调:交代最初挂在调度器背景与 125 行包含重试/去重/退避逻辑,立住工程克制力形象。
- **2. NocoDB 归档记录**:
- Candidate Key: `cand:stop-writing-agent-prompts-for-deterministic-work` (Status: `APPROVED`, Priority: `HIGH`)
- Draft Key: `cand:stop-writing-agent-prompts-for-deterministic-work:v1` (Status: `APPROVED`)
- 拟定发布节奏:每周 2 篇(周二/周四),平稳推进 5 周。
@@ -1,59 +0,0 @@
# LinkedIn Draft & Consultant Review: Why Dockerized API Notifications Silently Fail: An IPv6 and Framing Post-Mortem
> **文档性质**:从 `blog.hoelee.com` 改写的 LinkedIn 待发布技术动态。
> **发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
> **源文章**:https://blog.hoelee.com/posts/why-telegram-bot-notifications-die/
> **系统标识**:`why-telegram-bot-notifications-die` | **分类**:`devops`
> **字数**:2137 chars (LinkedIn 上限 3,000 chars)
---
## 一、 核心背景与铁律约束提示(供顾问审阅对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:严禁流露“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
5. **OPSEC 安全脱敏**:无内部绝对路径(如 `D:/dev`),无真实私有内网 IP,公网 IP 必须转为文档保留地址。
---
## 二、 LinkedIn 拟发布动态文案
```text
An automated monitoring container in my production stack was scraping data flawlessly, but every Telegram alert suddenly began failing with:
`sendPhoto failed: 400 ... nginx/1.30.1`
It took a day of forensic debugging to uncover three independent networking and protocol failures masking each other:
Failure 1: Docker's Embedded DNS and IPv6 Blindness
Inside the container, `api.telegram.org` resolved exclusively to an IPv6 `AAAA` record (`2001:67c:4e8:f004::9`). The container was running on a standard Docker bridge network with no IPv6 routing. Requests were attempting to route packets across a non-existent IPv6 interface.
Fix: Pin the endpoint to an IPv4 address via `extra_hosts` in compose.
Failure 2: The Telegram Edge Proxy Misdirection
Even after routing IPv4, requests returned an HTML error: `400 Bad Request` with `Server: nginx/1.30.1`.
Because Telegram's API normally answers in JSON, I initially assumed a local corporate firewall or reverse proxy was intercepting traffic. In reality, `nginx/1.30.1` is Telegram's own ingress reverse proxy. If an HTTP request is structurally malformed at the transport layer, edge nginx rejects it before it ever reaches Telegram's application daemon.
Failure 3: Binary Multipart Boundary Corruption
The culprit was an insidious line-delimiter bug in custom Python HTTP framing:
The payload was constructed by joining binary chunks with `b"\r\n".join(parts)`.
Raw JPEG binary streams naturally contain `0x0A` (`\n`) and `0x0D` (`\r`) bytes. Joining binary images with newline strings mutates the payload length and breaks MIME boundary framing, causing edge proxies to reject the HTTP stream on sight.
Fix: Concatenate discrete multipart chunks verbatim with `b"".join(parts)`.
Hard-won debugging lessons:
• A Docker container on a bridge network can receive IPv6 DNS records it cannot route.
• When a third-party API returns an unexpected HTML 400, inspect their edge proxy layer before assuming an external network intercept.
• Never assemble binary multipart streams using string or newline helpers.
Write-up: https://blog.hoelee.com/posts/why-telegram-bot-notifications-die/
```
---
## 三、 外部顾问审阅评估反馈单
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(是否符合高级技术雇佣人设,无老板/卖货感)**:
- **2. 技术真实性与逻辑推导(因果链条与数据是否严谨)**:
- **3. 语言地道度与人设去油(是否纯正地道、零业余玩具感)**:
- **4. 优化修改建议(如有优化建议或修改文案,请在此批注)**:
@@ -1,61 +0,0 @@
# LinkedIn Draft & Consultant Review: The JPA @Version Field That Turns a Silent Lost Update Into an HTTP 409
> **文档性质**:从 `blog.hoelee.com` 改写的 LinkedIn 待发布技术动态。
> **发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
> **源文章**:https://blog.hoelee.com/posts/jpa-version-field-lost-update/
> **系统标识**:`jpa-version-field-lost-update` | **分类**:`engineering`
> **字数**:2061 chars (LinkedIn 上限 3,000 chars)
---
## 一、 核心背景与铁律约束提示(供顾问审阅对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:严禁流露“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
5. **OPSEC 安全脱敏**:无内部绝对路径(如 `D:/dev`),无真实私有内网 IP,公网 IP 必须转为文档保留地址。
---
## 二、 LinkedIn 拟发布动态文案
```text
Two users open the same record in a web application. Both make changes. Both click save.
User A saves first; the database updates and the API returns HTTP 200. User B saves two seconds later; the database overwrites User A's changes, and the API returns HTTP 200 again.
User A's work has completely vanished. No exception was logged, no alert fired, and both clients were explicitly told their save was successful.
This is the classic **lost update problem**, and it is one of the quietest data loss defects in read-modify-write REST APIs.
Here is how I implemented end-to-end optimistic locking to eliminate this failure mode in a Spring Boot (Java 21) service:
1. Add `@Version` to the Entity
Annotate an integer or timestamp column with `@Version`. On every update, Hibernate automatically appends a version check to the SQL query:
`UPDATE posts SET title=?, body=?, version=version+1 WHERE id=? AND version=?`
2. Make the Version Part of the API Contract
Never hide the version field inside server-side session state. Expose `version` in the read DTO and mandate it in the write request payload (`UpdatePostRequest`). If the client does not submit the version it read, the request is rejected immediately.
3. Exception Handling & REST Cleanliness
When two concurrent requests race, Hibernate detects 0 rows updated and throws an `OptimisticLockException` (wrapped by Spring as `ObjectOptimisticLockingFailureException`).
A centralized `@RestControllerAdvice` catches this concurrency failure and translates it into a clean `HTTP 409 Conflict` with a structured payload:
`{ "error": "CONFLICT", "message": "Record was modified by another transaction. Please reload and reapply your changes." }`
An error is infinitely better than a deceptive HTTP 200. A 409 allows the client application to prompt the user to merge changes, preventing silent data loss before it corrupts production state.
How does your backend architecture handle concurrent writes across distributed clients?
Write-up: https://blog.hoelee.com/posts/jpa-version-field-lost-update/
```
---
## 三、 外部顾问审阅评估反馈单
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(是否符合高级技术雇佣人设,无老板/卖货感)**:
- **2. 技术真实性与逻辑推导(因果链条与数据是否严谨)**:
- **3. 语言地道度与人设去油(是否纯正地道、零业余玩具感)**:
- **4. 优化修改建议(如有优化建议或修改文案,请在此批注)**:
@@ -0,0 +1,63 @@
# LinkedIn Draft & Consultant Review: Why Dockerized API Notifications Silently Fail: An IPv6 and Framing Post-Mortem
> **文档性质**:从 `blog.hoelee.com` 改写并在 NocoDB 排期的 LinkedIn 生产级动态。
> **发布状态**:`已通过外部顾问审阅 / NocoDB 已排期待发布`
> **排期波次**:Wave 3 (收官期) - 槽位 9 (拟发布日期: 2026-11-26 Thu)
> **源文章**:https://blog.hoelee.com/posts/why-telegram-bot-notifications-die/
> **系统标识**:`why-telegram-bot-notifications-die` | **分类**:`devops`
> **字数**:2338 chars (严格控制在 3,000 字符内)
---
## 一、 核心背景与铁律约束提示(供复核对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:彻底脱敏“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
5. **OPSEC 安全脱敏**:无内部绝对路径(如 `D:/dev`),无真实私有内网 IP,公网 IP 必须转为文档保留地址。
---
## 二、 LinkedIn 拟发布动态文案(已按顾问意见修订)
```text
An automated monitoring container in my production stack was scraping data flawlessly, but every Telegram alert suddenly began failing with:
`sendPhoto failed: 400 ... nginx/1.30.1`
It took a day of forensic debugging to uncover three independent networking and protocol failures masking each other:
Failure 1: Docker's Embedded DNS and IPv6 Blindness
Inside the container, `api.telegram.org` resolved exclusively to an IPv6 `AAAA` record (`2001:67c:4e8:f004::9`). The container was running on a standard Docker bridge network with no IPv6 routing, causing packets to drop across an unreachable interface.
Fix: Pin the IPv4 endpoint via `extra_hosts` in compose to immediately unblock routing, then enforce IPv4-only DNS resolution for non-IPv6 bridge networks.
Failure 2: The Telegram Edge Proxy Misdirection
Even after routing over IPv4, requests returned an HTML error: `400 Bad Request` with `Server: nginx/1.30.1`.
Because Telegram's API normally responds in JSON, I initially suspected an intermediary firewall or proxy intercept. In reality, `nginx/1.30.1` is Telegram's own ingress reverse proxy. When an HTTP request is structurally malformed at the transport layer, edge nginx rejects it before it ever reaches Telegram's application daemon.
Failure 3: Binary Multipart Boundary Corruption
The root culprit was an insidious line-delimiter bug in custom Python HTTP framing:
The payload was constructed by joining chunks with `b"\r\n".join(parts)`.
Because raw JPEG binary streams naturally contain `0x0A` (`\n`) and `0x0D` (`\r`) bytes, improper newline joining and framing calculations mutated the payload length and broke MIME boundary alignment, causing edge proxies to reject the HTTP stream on sight.
Fix: Concatenate discrete pre-framed multipart byte chunks verbatim with `b"".join(parts)`.
Hard-won debugging lessons:
• A Docker container on an IPv4 bridge network can still receive IPv6 `AAAA` records it cannot route.
• When a third-party API returns an unexpected HTML 400, inspect their ingress proxy layer before assuming an external network intercept.
• Never assemble binary multipart streams using string or newline helpers.
What is the most deceptive multi-layer network bug you have had to untangle in containerized production?
Write-up: https://blog.hoelee.com/posts/why-telegram-bot-notifications-die/
```
---
## 三、 外部顾问审阅评估反馈单与归档记录
- [x] **审阅结论**:需微调(已更新修订稿)
- **1. 诊断与修改批注**:补齐文末思辨提问;明确 extra_hosts 属于应急止血手段,展现专业网络协议排障能力。
- **2. NocoDB 归档记录**:
- Candidate Key: `cand:why-telegram-bot-notifications-die` (Status: `APPROVED`, Priority: `HIGH`)
- Draft Key: `cand:why-telegram-bot-notifications-die:v1` (Status: `APPROVED`)
- 拟定发布节奏:每周 2 篇(周二/周四),平稳推进 5 周。
@@ -1,16 +1,17 @@
# LinkedIn Draft & Consultant Review: Architecting a Self-Healing Customer Entitlement Engine with n8n and NocoDB
# LinkedIn Draft & Consultant Review: Architecting a Self-Healing Client Entitlement Engine with n8n and NocoDB
> **文档性质**:从 `blog.hoelee.com` 改写的 LinkedIn 待发布技术动态。
> **发布状态**:`待顾问审阅 (未在 LinkedIn 发布)`
> **文档性质**:从 `blog.hoelee.com` 改写并在 NocoDB 排期的 LinkedIn 生产级动态。
> **发布状态**:`已通过外部顾问审阅 / NocoDB 已排期待发布`
> **排期波次**:Wave 3 (收官期) - 槽位 10 (拟发布日期: 2026-12-01 Tue)
> **源文章**:https://blog.hoelee.com/posts/self-healing-digital-goods-entitlements/
> **系统标识**:`self-healing-digital-goods-entitlements` | **分类**:`case-studies`
> **字数**:1961 chars (LinkedIn 上限 3,000 chars)
> **字数**:2040 chars (严格控制在 3,000 字符内)
---
## 一、 核心背景与铁律约束提示(供顾问审阅对照)
## 一、 核心背景与铁律约束提示(供复核对照)
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:严禁流露“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
1. **求职画像契合(Senior 全栈/DevOps/AI 架构师)**:彻底脱敏“做生意的老板/小公司创始人”倾向;一切商业实战均转换为“生产系统架构、高可用交付与自动化运维”视角。
2. **纯洁人设与零禁用词**:绝对禁止 `homelab`, `home lab`, `家用`, `小主机`, `玩具`, `折腾`, `玩票` 等词汇。必须使用 `the infrastructure I manage`, `my self-hosted production nodes`, `production host`。
3. **第一人称单数**:统一使用单数 `I` / `我`,杜绝虚张声势的复数 `we`。
4. **数据绝对保真**:所有数字、性能比率、吞吐提升、故障现象严禁凭空捏造。
@@ -18,39 +19,40 @@
---
## 二、 LinkedIn 拟发布动态文案
## 二、 LinkedIn 拟发布动态文案(已按顾问意见修订)
```text
In subscription and digital entitlement platforms, the core engineering challenge is never file storage — it is **state reconciliation**.
In subscription and external client entitlement platforms, the hardest engineering challenge is rarely storage — it is **state reconciliation**.
Manual provisioning or naive event triggers fail silently:
• A subscription expires, but a missed webhook leaves access active indefinitely.
• A payment webhook fires during server maintenance, locking a paying customer out of their files.
Relying purely on one-off event triggers guarantees silent authorization drift in production:
• A subscription expires, but a dropped webhook leaves tenant access active indefinitely.
• A billing event fires during gateway maintenance, locking an active client out of provisioned resources.
To guarantee zero-drift authorization, I architected a multi-tiered entitlement engine using n8n workflows, NocoDB, and private storage gateways.
To guarantee zero-drift authorization, I architected a self-healing entitlement engine using n8n workflows, NocoDB, and private storage gateways.
The core principle: **Access is never an arbitrary flag; it is pure derived state.**
The core principle: **Access is never a static boolean flag; it is pure derived state.**
The system operates across five decoupled workflows:
1. Lifecycle Provisioning (W1): Listens for customer state updates, creating and toggling gateway accounts deterministically.
2. Product Grant Sync (W2): On confirmed purchase, computes the exact directory access paths matching the customer's active tier and updates gateway permissions.
3. Automated Expiry Sweeper (W3): A scheduled cron job running every 5 minutes evaluates timestamp boundaries and revokes expired path grants.
4. Continuous Reconciliation Loop (W4): Nightly at 03:00, a reconciliation engine computes the "ideal access state" directly from the database and audits it against the live storage gateway. Any discrepancy is automatically repaired and logged to telemetry.
5. Zero-Leak Public Verification (W5): Customer-facing portals verify purchase history via read-only token queries without exposing underlying database credentials.
1. Lifecycle Provisioning (W1): Listens for account state transitions, provisioning and toggling gateway identities deterministically.
2. Tier Permission Sync (W2): On confirmed subscription updates, computes the exact directory and resource paths matching the active tier and applies gateway ACLs.
3. Automated Expiry Sweeper (W3): A scheduled job running every 5 minutes evaluates timestamp boundaries and revokes expired path grants.
4. Continuous Reconciliation Loop (W4): Nightly at 03:00, a reconciliation engine computes the "desired authorization state" directly from the source-of-truth database and audits it against the live storage gateway. Any drift is automatically repaired and logged to telemetry.
5. Zero-Leak Entitlement Verification (W5): Client-facing portals verify active entitlement status via scoped read-only token queries without exposing underlying database credentials.
By designing the system as a self-healing reconciliation loop (similar to Kubernetes controllers), temporary network drops or webhook hiccups are automatically corrected on the next cycle without human intervention.
By modeling permissions as a continuous reconciliation loop (similar to Kubernetes controllers), transient network drops or webhook timeouts self-heal on the next cycle without human intervention.
Do your business authorization workflows rely on brittle one-off webhooks, or do you run automated reconciliation loops to catch state drift?
Do your authorization workflows rely on brittle one-off webhooks, or do you run continuous reconciliation loops to catch state drift?
Write-up: https://blog.hoelee.com/posts/self-healing-digital-goods-entitlements/
```
---
## 三、 外部顾问审阅评估反馈单
## 三、 外部顾问审阅评估反馈单与归档记录
- [ ] **审阅结论**:[ ] 通过 / [ ] 需微调 / [ ] 需重构 / [ ] 建议暂缓
- **1. 职场形象评估(是否符合高级技术雇佣人设,无老板/卖货感)**:
- **2. 技术真实性与逻辑推导(因果链条与数据是否严谨)**:
- **3. 语言地道度与人设去油(是否纯正地道、零业余玩具感)**:
- **4. 优化修改建议(如有优化建议或修改文案,请在此批注)**:
- [x] **审阅结论**:需微调(已更新修订稿)
- **1. 诊断与修改批注**:求职红线防范:脱敏数字商品电商词汇,全面升级为企业级多租户订阅与受控存储网关 IAM 授权架构。
- **2. NocoDB 归档记录**:
- Candidate Key: `cand:self-healing-digital-goods-entitlements` (Status: `APPROVED`, Priority: `HIGH`)
- Draft Key: `cand:self-healing-digital-goods-entitlements:v1` (Status: `APPROVED`)
- 拟定发布节奏:每周 2 篇(周二/周四),平稳推进 5 周。
+34 -28
View File
@@ -1,37 +1,43 @@
# LinkedIn 发布文章审阅追踪台账 (D:\dev\hoelee-blog\docs\linkedin)
# LinkedIn 发布文章审阅与 NocoDB 排期台账 (D:\dev\hoelee-blog\docs\linkedin)
本台账记录从 `blog.hoelee.com` 提取并准备/发布至 LinkedIn 的所有文章动态。
## 批次概览
- **第一批历史已发布/排队文案 (共 19 篇)**:
- 归档于 `D:\dev\hoelee-career-agent\drafts\` 及 `D:\dev\hoelee-blog\docs\consultant-review\linkedin-posts-audit-pack.md`
- 状态:12 篇已发布,3 篇已排队待发布,4 篇准备中。
- **第二批候选新文章(本批精选 10 篇,未发布)**:
- 存放于 `D:\dev\hoelee-blog\docs\linkedin\`
- 状态:全部待外部顾问审阅。
本台账记录从 `blog.hoelee.com` 提取并已完成外部顾问审阅、录入 NocoDB 数据库的全部 LinkedIn 候选动态。
---
## 第二批候选新文章清单 (10 篇)
## 一、 整体排期策略:三波段交叉发布法(每周 2 篇,持续 5 周)
| 序号 | 系统 Key / 文件 | 分类 | 博客源链接 | 字数 | 审阅状态 | 发布状态 |
|:---:|---|:---:|---|:---:|:---:|:---:|
| 01 | `01-running-production-infrastructure-solo.md` | case-studies | [/posts/running-production-infrastructure-solo/](https://blog.hoelee.com/posts/running-production-infrastructure-solo/) | 2155 | 待审阅 | 待发布 |
| 02 | `02-how-i-built-the-digikedai-telegram-bot.md` | case-studies | [/posts/how-i-built-the-digikedai-telegram-bot/](https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/) | 2069 | 待审阅 | 待发布 |
| 03 | `03-the-single-writer-rule-for-coding-agents.md` | case-studies | [/posts/the-single-writer-rule-for-coding-agents/](https://blog.hoelee.com/posts/the-single-writer-rule-for-coding-agents/) | 1984 | 待审阅 | 待发布 |
| 04 | `04-slashing-agent-context-with-a-code-graph.md` | ai | [/posts/slashing-agent-context-with-a-code-graph/](https://blog.hoelee.com/posts/slashing-agent-context-with-a-code-graph/) | 1975 | 待审阅 | 待发布 |
| 05 | `05-stop-writing-agent-prompts-for-deterministic-work.md` | notes | [/posts/stop-writing-agent-prompts-for-deterministic-work/](https://blog.hoelee.com/posts/stop-writing-agent-prompts-for-deterministic-work/) | 1858 | 待审阅 | 待发布 |
| 06 | `06-when-smart-says-healthy-but-your-raid-is-corrupting-data.md` | devops | [/posts/when-smart-says-healthy-but-your-raid-is-corrupting-data/](https://blog.hoelee.com/posts/when-smart-says-healthy-but-your-raid-is-corrupting-data/) | 1935 | 待审阅 | 待发布 |
| 07 | `07-your-disk-full-alert-is-lying.md` | devops | [/posts/your-disk-full-alert-is-lying/](https://blog.hoelee.com/posts/your-disk-full-alert-is-lying/) | 1771 | 待审阅 | 待发布 |
| 08 | `08-why-telegram-bot-notifications-die.md` | devops | [/posts/why-telegram-bot-notifications-die/](https://blog.hoelee.com/posts/why-telegram-bot-notifications-die/) | 2137 | 待审阅 | 待发布 |
| 09 | `09-jpa-version-field-lost-update.md` | engineering | [/posts/jpa-version-field-lost-update/](https://blog.hoelee.com/posts/jpa-version-field-lost-update/) | 2061 | 待审阅 | 待发布 |
| 10 | `10-self-healing-digital-goods-entitlements.md` | case-studies | [/posts/self-healing-digital-goods-entitlements/](https://blog.hoelee.com/posts/self-healing-digital-goods-entitlements/) | 1961 | 待审阅 | 待发布 |
为了最大化服务【高端技术求职招聘】(Senior 全栈 / DevOps / AI 平台架构师)人设,同时彻底稀释部分商业项目(如数字网关与授权体系)在 URL Slug 上的痕迹,按顾问建议执行**三波段交叉排期**:
- **第一波(立威期,第 1-2 周)**:亮出最硬核的底层排障、存储校验取证与 AI Agent 架构王牌,建立资深极客与平台专家第一印象。
- **第二波(纵深期,第 3-4 周)**:穿插全栈工程、SRE 可观测性治理、并发锁与企业级网关交付,展示工程深度与广度。
- **第三波(收官期,第 5 周)**:协议栈网络深度排障与自愈授权系统闭环,完美树立不可替代的高可靠架构师形象。
---
## 审阅与交付指引
## 二、 10 篇候选新文章全景排期表 (NocoDB 已入库已批准)
1. 顾问可审阅汇总包 `00-linkedin-consultant-audit-pack.md`,也可直接按单篇查看独立文件。
2. 顾问完成反馈后,根据反馈更新文案并调整审阅状态为 `已通过`。
3. 审核通过的文案将同步录入 `D:\dev\hoelee-career-agent\platforms\linkedin\posts.py` 的发布队列,按 1篇/天 的节奏发布。
| 槽位 | 拟发日期 | 星期 | 系统 Key / 文件 | 分类 | 标题 | 顾问结论 | NocoDB Draft Key |
|:---:|:---:|:---:|---|:---:|---|:---:|---|
| **01** | 2026-10-29 | Thu | `01-when-smart-says-healthy-but-your-raid-is-corrupting-data.md` | devops | When SMART Says Healthy and Your RAID Is Silently Corrupting Data | **通过** (首发标杆) | `cand:when-smart-says-healthy-but-your-raid-is-corrupting-data:v1` |
| **02** | 2026-11-03 | Tue | `02-slashing-agent-context-with-a-code-graph.md` | ai | Slashing Agent Context and Token Churn With an AST Code Graph | **通过** | `cand:slashing-agent-context-with-a-code-graph:v1` |
| **03** | 2026-11-05 | Thu | `03-running-production-infrastructure-solo.md` | case-studies | Running Production Infrastructure Solo: 162 Containers Across Three Hosts | **通过** (已微调第2段) | `cand:running-production-infrastructure-solo:v1` |
| **04** | 2026-11-10 | Tue | `04-the-single-writer-rule-for-coding-agents.md` | case-studies | The Single-Writer Rule: Orchestrating AI Coding Agents Without Multi-Agent Chaos | **通过** (已微调防杠) | `cand:the-single-writer-rule-for-coding-agents:v1` |
| **05** | 2026-11-12 | Thu | `05-how-i-built-the-digikedai-telegram-bot.md` | case-studies | Architecting a 24/7 AI Support & Entitlement Engine Without Human-in-the-Loop | **需微调** (已彻底去电商化) | `cand:how-i-built-the-digikedai-telegram-bot:v1` |
| **06** | 2026-11-17 | Tue | `06-your-disk-full-alert-is-lying.md` | devops | Your Disk-Full Alert Is Lying: Stop Alerting on Percentages | **需微调** (已修复数与PromQL) | `cand:your-disk-full-alert-is-lying:v1` |
| **07** | 2026-11-19 | Thu | `07-jpa-version-field-lost-update.md` | engineering | The JPA @Version Field That Turns a Silent Lost Update Into an HTTP 409 | **需微调** (已补JPA托管深坑) | `cand:jpa-version-field-lost-update:v1` |
| **08** | 2026-11-24 | Tue | `08-stop-writing-agent-prompts-for-deterministic-work.md` | notes | Stop Writing Agent Prompts for Deterministic Work | **需微调** (已补调度器与125行背景) | `cand:stop-writing-agent-prompts-for-deterministic-work:v1` |
| **09** | 2026-11-26 | Thu | `09-why-telegram-bot-notifications-die.md` | devops | Why Dockerized API Notifications Silently Fail: An IPv6 and Framing Post-Mortem | **需微调** (已补互动问答与应急说明) | `cand:why-telegram-bot-notifications-die:v1` |
| **10** | 2026-12-01 | Tue | `10-self-healing-digital-goods-entitlements.md` | case-studies | Architecting a Self-Healing Client Entitlement Engine with n8n and NocoDB | **需微调** (已全面升级SaaS多租户IAM) | `cand:self-healing-digital-goods-entitlements:v1` |
---
## 三、 NocoDB 同步状态核实
- **数据库 Base**:`Hoelee Career Agent` (`p7zen83al21mxtz`)
- **候选池表 `content_candidates` (`mcdhbz6yuing2pr`)**:
- 10 项候选记录均已挂载并更新为 `status = "APPROVED"`、`priority = "HIGH"`、`recommended = 1`。
- **草稿箱表 `content_drafts` (`m97ariqgek18a0i`)**:
- 10 篇修订版 LinkedIn 文案均已写入,状态为 `APPROVED`,版本为 `v1`,携带唯一的 `content_hash` 与详细排期注释。
- **自动化执行对接**:
- 各稿件已同步生成至 `D:\dev\hoelee-career-agent\drafts\`。
- 发布时可直接调用 `career.py` 或由发布调度器安全拾取执行。