// Project Lessons · dogfooded บทเรียนจำลองและแก้ไขจริงจากผู้สร้างคอสมอส

The bugs your AI keeps re-deriving — until it doesn't. แก้ไขปัญหาที่ระบบผู้ช่วยอัจฉริยะมักจะคิดค้นวิธีแก้แบบผิดซ้ำ ๆ ได้อย่างเบ็ดขาด

Below are 10 real lessons captured by Cosmos's own brain while building Cosmos itself. Each one was a bug that took more than one try to fix, recorded the moment the fix shipped, and has been surfaced to my AI assistant 5 times since to stop the same pothole from being hit twice. บทเรียนในส่วนนี้คือตัวอย่างจริงของบทเรียนทั้ง 10 บทเรียน ที่ระบบคลังสมองของคอสมอสได้รวบรวมไว้ในระหว่างขั้นตอนการพัฒนาและสร้างสรรค์ระบบคอสมอส ซึ่งทุกชิ้นล้วนเป็นกรณีปัญหาที่มีความซับซ้อนและต้องแก้ปัญหามากกว่าหนึ่งครั้งเพื่อความถูกต้อง โดยบันทึกเหล่านี้ถูกนำไปย้อนเรียกแสดงและช่วยป้องกันไม่ให้เกิดความผิดพลาดซ้ำเดิมอีกถึง 5 ครั้ง นับตั้งแต่มีการบันทึก

This is not a marketing demo. The data lives in code_errors in the dogfood brain. Every entry below was logged with code_remember_error after a real fix; ask any AI tool with the Cosmos MCP attached to code_list_errors and you'll see the same rows. นี่ไม่ใช่หน้าต่างจำลองเพื่อจุดประสงค์ทางการตลาด แต่ข้อมูลเหล่านี้ถูกจัดเก็บจริงอยู่ในฐานข้อมูลความคลาดเคลื่อน code_errors ของระบบความจำปัญญาประดิษฐ์ในคอสมอส โดยทุกกรณีการบันทึกด้านล่างได้รับการจดจำผ่านคำสั่ง code_remember_error ภายหลังจากกระบวนการแก้ไขข้อขัดข้องที่เกิดขึ้นจริง คุณสามารถขอให้ผู้ช่วยอัจฉริยะที่เชื่อมต่อกับคอสมอสของคุณเรียกแสดงข้อมูลเหล่านั้นผ่านชุดคำสั่ง code_list_errors เพื่อตรวจสอบกลุ่มข้อมูลแถวเดียวกันนี้ได้ทันที

10
Lessons logged บทเรียนวิศวกรรมที่บันทึก
5
Times recalled จำนวนครั้งที่สืบค้นเรียกใช้งาน
0
Times rederived จำนวนครั้งที่วิเคราะห์ซ้ำซ้อนเปล่าประโยชน์
// The flow วงจร

From bug to recall. จากบั๊กสู่ recall

┌─ FIX ─────────────────────────────────────────────────────┐
│ You + AI fix a tricky bug. AI calls:                       │
│   code_remember_error(symptom, root_cause, fix, files=[...])  │
│ → row inserted into code_errors with FTS5 over symptom    │
└───────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─ NEXT SESSION ────────────────────────────────────────────┐
│ Same area, days/weeks later. AI calls:                     │
│   find_relevant_code(symptom="...", path=cwd)                │
│ → returns top files + matching past errors+fixes          │
└───────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─ APPLY ───────────────────────────────────────────────────┐
│ AI sees the past lesson before editing.                  │
│ Past fix used as constraint, not re-derived from scratch.  │
└───────────────────────────────────────────────────────────┘
// The lessons บทเรียน

Every entry. Verbatim. ทุก entry · ตามต้นฉบับ

Each card tells the real story behind a critical bug, translated from our local SQLite database.

การ์ดแต่ละใบนำเสนอบทเรียนจริงเบื้องหลังบั๊กสำคัญ ซึ่งดึงขึ้นมาจากระบบฐานข้อมูล SQLite ท้องถิ่นโดยตรง

Live Presentation Deck
01 / 10
#01

Graph view froze on click — three causes layered into one symptom หน้าจอแผนที่ค้างเมื่อคลิก — สามปมปัญหาที่รวมตัวกันเป็นหนึ่งอาการค้าง

frontend-perf caught: production usage ตรวจพบจาก: การใช้งานจริง 2026-04-15
Symptom อาการของบั๊ก
User clicks a node on the Neural Map. FPS dives. The whole app locks up for seconds at a time before recovering. Looks like a single performance bug; turned out to be three things firing simultaneously. เมื่อผู้ใช้คลิกเลือกจุดบนแผนที่ระบบประสาท หน้าจอเกิดการกระตุกอย่างหนักและค้างไปหลายวินาทีก่อนจะกลับมาใช้งานได้ ซึ่งดูเหมือนเป็นปัญหาประสิทธิภาพของหน้าจอทั่วไป แต่แท้จริงแล้วเกิดจากความขัดข้องของสามกลไกภายในที่พุ่งชนกันในวินาทีเดียวกัน
Root cause สาเหตุแท้จริง
Three independent issues compounding: (1) a Zustand store subscribed without selectors triggered a re-render avalanche on every node click; (2) a per-frame `new Float32Array(...)` allocation inside `useFrame` created GC pressure that stuttered the WebGL pipeline; (3) two `<OrbitControls>` instances mounted concurrently because of a routing edge case, and their event listeners fought each other. Any one of these alone would have been mild — together, the app froze. ความขัดแย้งเชิงระบบจากสามจุดอ่อนพร้อมกัน: (1) ระบบวาดผลหน้าจอแชร์ข้อมูลกว้างเกินไป ทำให้หน้าจอทั้งหมดต้องพยายามวาดตัวเองใหม่ซ้ำ ๆ เป็นหมื่นครั้งเมื่อคลิกเพียงครั้งเดียว ทำลายความลื่นไหลของหน้าจอ (2) มีการสร้างและทำลายถังเก็บข้อมูลชั่วคราวซ้ำ ๆ 60 ครั้งต่อวินาที เกิดขยะหน่วยความจำดิจิทัลมหาศาลที่เบราว์เซอร์ต้องคอยเก็บกวาด และ (3) ตัวควบคุมทิศทางเสมือนถูกเปิดขึ้นมาสองตัวซ้อนกันและเข้าแย่งชิงการตอบสนองจากเมาส์ของผู้ใช้
Fix แนวทางแก้ไข
Pick selectors on every Zustand subscription. Hoist the Float32Array allocation out of the per-frame path into a useRef. Mount exactly one OrbitControls instance, with a guard against the routing case that double-mounted it. Recorded as a Project Lesson pinned + scope-globbed to `src/components/GraphView/**` so the next time AI touches that path, the lesson surfaces before any edit. จำกัดการแชร์ข้อมูลเฉพาะจุดที่จำเป็นเพื่อการแสดงผลที่รวดเร็ว ล้างกระบวนการสร้างกล่องข้อมูลชั่วคราวออกไปนอกขั้นตอนการวาดหน้าจอแบบเรียลไทม์ และเพิ่มตัวคัดกรองควบคุมไม่ให้มีตัวควบคุมเมาส์เปิดซ้ำซ้อน พร้อมบันทึกวิธีแก้ปัญหานี้เป็นกฎวิศวกรรมถาวรเพื่อแจ้งเตือน AI ทันทีก่อนที่จะเริ่มแก้ไขส่วนนี้ในอนาคต
src/components/GraphView/Canvas.tsxsrc/components/GraphView/OrbitControls.tsxsrc/store/useGraphStore.ts
Recalled since สืบค้นเรียกคืน ตั้งแต่บันทึก
#02

A .py source file with "$42 paid for coffee" in a comment was being classified as expense ไฟล์รหัสคอมพิวเตอร์ถูกจัดประเภทเป็นเอกสารเงินทอง เพียงเพราะมีคำว่าค่ากาแฟ $42 ในคอมเมนต์

classification-correctness caught: snapshot test ตรวจพบจาก: snapshot test 2026-05-08
Symptom อาการของบั๊ก
The Universal Index classifier ran each rule in priority order and returned the first match. A Python file whose comment happened to mention currency + a date hit the expense rule's content patterns before the loop reached the code rule's extension match — and the file shipped to the brain as category="expense" with high confidence. ระบบจัดเก็บบันทึกไฟล์อัตโนมัติประเมินสัญลักษณ์ตามลำดับก่อนหลัง โดยดันไปพบข้อความตัวเลข "$42" และวันที่ในกล่องคอมเมนต์ของไฟล์รหัสโปรแกรม ส่งผลให้ระบบคิดว่าไฟล์รหัสนี้เป็นเอกสารแสดงค่าใช้จ่ายทางการเงินและนำไปเก็บไว้ผิดประเภทอย่างแม่นยำสูง
Root cause สาเหตุแท้จริง
Single-pass rule iteration treats every rule as equally weighted. The expense rule fires on (currency token + date token) within the first 4 KB of content. The code rule fires on file extension alone. With both able to match the same file, whichever was earlier in the CLASSIFIERS tuple won — even when extension was unambiguous evidence ("a .py file is Python, period"). This is the exact bug pattern every classifier in the market hits when source files contain example data in comments. ระบบตรวจคัดกรองประเมินลำดับข้อมูลขั้นตอนเดียวทำให้ประเมินความสำคัญคลาดเคลื่อน เมื่อกฎระบุค่าใช้จ่ายพบสัญลักษณ์สกุลเงินและวันที่ จึงเหมารวมว่านี่คือสลิปค่าใช้จ่ายทันทีโดยละเลยการสังเกตชนิดของไฟล์จริง ซึ่งเป็นจุดอ่อนทั่วไปที่พบในระบบจัดเก็บไฟล์ในตลาดเมื่อเอกสารตัวอย่างมีรหัสการเงินปะปนอยู่
Fix แนวทางแก้ไข
Two-pass classifier: pass 1 handles extension-only decisive rules and short-circuits before any content pattern runs; pass 2 handles filename hints + content evidence for ambiguous types (markdown, csv, txt). Source files with unambiguous extensions never reach the content matcher. The structural fix means re-introducing the bug requires re-introducing the architecture, not just moving a rule. อัปเกรดเป็นระบบตรวจคัดกรอง 2 ขั้นตอน (Smart indexing) โดยขั้นตอนแรกจะคัดแยกกลุ่มไฟล์ที่มีข้อมูลระบุตัวตนแน่ชัด (เช่น ไฟล์รหัสโปรแกรม) แยกออกไปจัดเก็บโดยไม่ต้องเริ่มสแกนคำในเอกสาร ส่วนขั้นตอนที่สองจึงวิเคราะห์หาคำสำหรับประเภทที่มีความกำกวม (เช่น markdown) เพื่อการสแกนจัดหมวดหมู่ที่รวดเร็วและเป็นระบบอย่างสมบูรณ์แบบ
core/universal_index/classifier.pycore/universal_index/tests/test_phase1.py
Recalled since สืบค้นเรียกคืน ตั้งแต่บันทึก
#03

self.on_deleted = callback silently shadowed the watchdog event handler method การลบไฟล์ไม่ได้รับการอัปเดต เนื่องจากชื่อชุดคำสั่งการลบเกิดการชนกันอย่างเงียบเชียบ

architectural-correctness caught: integration test ตรวจพบจาก: integration test 2026-05-08
Symptom อาการของบั๊ก
Universal Index watcher claimed to handle file deletes (the docstring said so) but search kept returning rows for files that had been rm'd. The watcher's on_deleted method body never executed; watchdog's dispatcher was calling the constructor-stored callback directly with an event object instead of going through the override. ระบบเฝ้าดูและปรับไฟล์แสดงสถานะว่าจัดการอัปเดตไฟล์เมื่อถูกลบไปแล้ว แต่ผลลัพธ์การค้นหายังคงปรากฏรายชื่อไฟล์เหล่านั้นอยู่ เนื่องจากระบบมองไม่เห็นเหตุการณ์การลบไฟล์และเพิกเฉยต่อการส่งข้อมูลอัปเดตโดยไม่มีข้อผิดพลาดแจ้งเตือน
Root cause สาเหตุแท้จริง
Python's attribute lookup checks the instance dict before the class dict. The constructor wrote `self.on_deleted = callback`, putting the callback in the instance dict and shadowing the class method `on_deleted(self, event)` we had carefully overridden from FileSystemEventHandler. When watchdog called `handler.on_deleted(event)`, Python resolved to the instance attribute (the callback) and passed the FileSystemEvent object straight in. The callback expected a string path; it got an event object; the silent except clause swallowed the resulting TypeError. Static type checkers don't flag this. Code review reads it as "store the callback" without noticing the collision. กระบวนการค้นหาและเข้าถึงชื่อคำสั่งเกิดข้อขัดแย้งของระบบชื่อชนกัน โดยระบบจัดเก็บบันทึกชุดคำสั่งเรียกกลับในตัวแปรที่มีชื่อตรงกับชื่อคำสั่งเฝ้าดูไฟล์ของระบบปฏิบัติการ เมื่อเกิดการลบไฟล์ขึ้นจริง ระบบจึงนำไปประมวลผลผิดพลาดและข้ามฟังก์ชันการทำงานที่จำเป็นทั้งหมดอย่างเงียบงัน โดยที่การตรวจโค้ดแบบดั้งเดิมก็ไม่เห็นความผิดปกติ
Fix แนวทางแก้ไข
Renamed `self.on_deleted` to `self._delete_callback` so the instance attribute can't collide with the watchdog interface method names. Renamed `self.on_burst_settled` symmetrically as preventive measure — watchdog's interface methods all share the `on_*` prefix and a future version could re-introduce this exact bug class on a method we don't override today. Added `core/universal_index/tests/test_watcher_integration.py` that boots a real `Observer`, performs actual file create/delete/move operations, and asserts the callback received a string path. แก้ไขความปลอดภัยโดยแยกตั้งชื่อคำสั่งย่อยให้ชัดเจนไม่ให้ซ้ำซ้อนกับคำสั่งหลักระดับระบบปฏิบัติการ และเขียนแบบทดสอบจำลองเหตุการณ์สร้าง ย้าย และลบไฟล์บนไดรฟ์จริง เพื่อตรวจสอบความถูกต้องอย่างสม่ำเสมอ รับประกันความปลอดภัยของหน่วยความจำและการซิงก์ข้อมูลที่แม่นยำสูง
core/universal_index/watcher.pycore/universal_index/tests/test_watcher_integration.py
Recalled since สืบค้นเรียกคืน ตั้งแต่บันทึก
#04

PyInstaller silently dropped Telegram + Gemini + Anthropic บอตบริการใช้ไม่ได้อย่างเงียบงัน เพราะระบบตัดชุดเครื่องมือ AI ตัวสำคัญออกขณะแพ็กเกจแอป

bundling 2026-05-04
Symptom อาการของบั๊ก
v0.2.0 .dmg installed cleanly. Bot tab loaded. But "Telegram Bot service is unavailable" appeared the moment a user tried to send. Nothing in the logs about why. เมื่อเปิดใช้แอปเวอร์ชันติดตั้งใหม่ ทุกอย่างติดตั้งได้อย่างเรียบร้อย แต่ทันทีที่ทดลองสั่งการบอต ระบบกลับระบุว่าแชตบอตไม่พร้อมใช้งาน โดยไม่มีข้อความรายงานความผิดพลาดปรากฏขึ้นมาเลย
Root cause สาเหตุแท้จริง
scripts/build-sidecar.sh listed `telegram`, `google.generativeai`, `anthropic`, `openai` in EXCLUDES to keep the bundle under 100 MB. PyInstaller respected the list. The runtime imports failed silently because we caught ImportError and degraded gracefully — which masked the bundling bug. สคริปต์ประกอบตัวติดตั้งโปรแกรมได้คัดรายชื่อบริการสำคัญของชุด AI และบอตส่งข้อความออกจากตัวติดตั้งเพื่อเจตนาให้ตัวช่วยติดตั้งแอปมีขนาดเล็กลงไม่เกิน 100 MB ส่งผลให้แอปติดตั้งสำเร็จแต่ระบบขาดชิ้นส่วนความเชื่อมโยงในการเรียกใช้งาน และเกิดความล้มเหลวแบบเงียบเพราะระบบพยายามปิดบังข้อผิดพลาดด้วยฟังก์ชันสำรองแบบไร้การรบกวนผู้ใช้
Fix แนวทางแก้ไข
Remove from EXCLUDES, add the same packages to HIDDEN_IMPORTS so PyInstaller actually walks their submodules. Bundle grew ~30 MB. Worth it. ปรับแก้ไขวิธีการแพ็กแอปใหม่โดยลบรายชื่อบริการสำคัญออกจากรายการละเว้นและสั่งให้นำเข้ารวมกับแอปพลิเคชันอย่างครบถ้วน แม้จะทำให้ตัวเก็บไฟล์โปรแกรมใหญ่ขึ้นอีก 30 MB แต่ช่วยให้การเชื่อมต่อกับสมอง AI และระบบส่งข้อความบอตทำงานได้อย่างรวดเร็วและสมบูรณ์
scripts/build-sidecar.shcore/bots/telegram_bot.pycore/api/cloud_provider.py
Recalled since สืบค้นเรียกคืน ตั้งแต่บันทึก
#05

code_explain_project queried a column that no longer existed ฟังก์ชันอธิบายโครงการของ AI ขัดข้องกะทันหัน เนื่องจากชี้ข้อมูลไปยังคอลัมน์ชื่อเดิมที่ย้ายแล้ว

schema-drift 2026-04-22
Symptom อาการของบั๊ก
MCP returned `OperationalError: no such column: category` whenever Claude called code_explain_project. Worked fine three weeks earlier. เมื่อระบบปัญญาประดิษฐ์พยายามเรียกข้อมูลภาพรวมของโครงการ ระบบฐานข้อมูลแจ้งเตือนความผิดพลาดล้มเหลวว่าหาประเภทคอลัมน์นี้ไม่พบ ทั้งที่ก่อนหน้านี้ไม่กี่สัปดาห์ทำงานได้ราบรื่น
Root cause สาเหตุแท้จริง
A migration renamed the column from `category` to `symbol_type` in core/code/indexer.py but mcp_server.py still SELECTed `category`. CI never caught it because there is no integration test that exercises both halves of the schema together. ฐานข้อมูลมีการปรับระดับความปลอดภัยและเปลี่ยนชื่อจากเดิม `category` ไปเป็น `symbol_type` แต่ระบบฝั่งตัวเรียกสรุปผลอัจฉริยะยังคงชี้ไปที่ชื่อดั้งเดิม ส่งผลให้เกิดโครงสร้างสับสนและระบบหยุดทำงาน เนื่องจากไม่มีการรันระบบตรวจสอบภาพรวมร่วมกันของทั้งโครงสร้างฐานข้อมูลก่อนส่งมอบ
Fix แนวทางแก้ไข
Update the SELECT to `WHERE symbol_type = 'overview'`. Wrap in try/except OperationalError that falls back to running the live analyzer so the next schema drift fails loud, not silent. ปรับแก้คำสั่งค้นหาข้อมูลด่วนของตัวแปลงผลให้ชี้ไปยังชื่อปัจจุบันที่ถูกต้อง และออกแบบเกราะป้องกันความผิดพลาด (Resilient updates): หากพบปัญหาการหาชื่อข้อมูลไม่เจอดังกล่าว ระบบจะสลับไปเรียกใช้โปรแกรมวิเคราะห์ข้อมูลแบบสดเรียลไทม์แทนการแสดงหน้าจอสีแดงล้มเหลว
core/api/mcp_server.pycore/code/indexer.py
Recalled since สืบค้นเรียกคืน ตั้งแต่บันทึก
#06

code_search FTS5 query hit "no such column: symbol_type" การค้นหาโค้ดขัดข้องเนื่องจากคำสั่งกรองประเภทไฟล์สับสนข้อมูลที่จัดเก็บแยกตาราง

sql 2026-04-22
Symptom อาการของบั๊ก
Every code_search call from the MCP failed with the FTS5 virtual table complaining about `symbol_type`. ทุกคำสั่งขอรับรายชื่อเอกสารรหัสผ่านระบบตรวจจับด่วน ล้มเหลวพร้อมการรายงานแจ้งเตือนของระบบสแกนความเร็วสูงว่าไม่มีข้อมูลประเภทเอกสารที่ระบุในสารบบ
Root cause สาเหตุแท้จริง
FTS5 virtual tables only index the columns declared in the FTS5 schema. `symbol_type` lives on the parent `code_index` table, not the FTS5 mirror. The query joined neither, expecting FTS5 to magically know. ตารางสืบค้นด่วนมีหน้าที่และทักษะในการสแกนข้อความค้นหาความเร็วสูงเท่านั้น แต่มันไม่มีระบบรู้จำว่าเอกสารนั้นถูกระบุเป็นประเภทอะไรเนื่องจากประเภทไฟล์นั้นถูกเก็บไว้อีกตารางหลัก และตัวประมวลผลก็หวังพึ่งพาให้การค้นหาเดาความเชื่อมโยงโดยไม่มีการผูกเชื่อมต่อตาราง
Fix แนวทางแก้ไข
JOIN code_fts back onto code_index by rowid, then filter on symbol_type from the parent. Costs nothing because rowid joins are free in SQLite. แก้ไขคำสั่งให้ทำการผูกจับคู่ข้อมูลตารางค้นหาด่วนเข้ากับตารางหลักอ้างอิงผ่านรหัสแถวดิจิทัลที่เป็นระเบียบ ซึ่งมีความรวดเร็วสูงบน SQLite ช่วยให้ค้นหาเนื้อหาพร้อมระบุความตรงตัวของประเภทได้ลื่นไหลปราศจากการหน่วงเวลา
core/api/mcp_server.py
Recalled since สืบค้นเรียกคืน ตั้งแต่บันทึก
#07

ripgrep `-E` was being parsed as encoding, not pattern type ระบบทดสอบรายงานผลประสิทธิภาพเป็นศูนย์ เนื่องจากเข้าใจเป้าหมายคำสั่งค้นหาผิดทิศทาง

tooling 2026-05-05
Symptom อาการของบั๊ก
tier_benchmark.py reported zero hits for ripgrep across every concept query. Manual rg from the shell worked perfectly. หน้าจอผลการทดสอบแจ้งว่าสแกนไม่พบเป้าหมายใด ๆ เลยแม้แต่จุดเดียวสำหรับทุกหัวข้อทดลอง ในขณะที่หากผู้ใช้ออกคำสั่งค้นหาด้วยตัวเองปกติจะสามารถค้นพบผลลัพธ์ได้อย่างสมบูรณ์
Root cause สาเหตุแท้จริง
The benchmark builds the rg invocation with `-E "<pattern>"` thinking that meant ERE. `-E` in ripgrep is `--encoding`. The pattern got parsed as an encoding name, ripgrep silently used the value as encoding and matched nothing. กลไกจำลองประสิทธิภาพใช้สัญลักษณ์คำสั่ง `-E` โดยอนุมานว่าเป็นการสแกนรูปแบบขั้นสูง แต่วิถีการประมวลผลพื้นฐานตีความตัวย่อนี้เป็น "การระบุรูปแบบฟอนต์และชุดภาษา" ทำให้ตัวแปลเอกสารนำข้อมูลคำค้นไปเป็นรหัสภาษาที่อ่านไม่ได้และส่งคืนหน้ากระดาษว่างเปล่า
Fix แนวทางแก้ไข
Switched to `-F` (fixed-string) since the pattern was already re.escape'd before being handed to rg. Add a positive smoke test that rg returns >0 results for a known token before the timing harness runs. เปลี่ยนสัญลักษณ์เป็นระบบจับคู่ตามอักขระตรงตัว `-F` เนื่องจากข้อมูลค้นหาได้รับการคัดแยกความถูกต้องล่วงหน้าแล้ว พร้อมทั้งเพิ่มบทสแกนตรวจสอบเบื้องต้นให้ทดลองค้นหาให้ได้ข้อมูลจริงมากกว่าศูนย์เสมอก่อนเริ่มกระบวนการคำนวณเวลา
benchmarks/tier_benchmark.py
Recalled since สืบค้นเรียกคืน ตั้งแต่บันทึก
#08

SQLite commit raised when every row was a no-op โปรแกรมหยุดทำงานกระทันหันเมื่อกดสั่งเซฟ ทั้งที่ไม่มีรายการใดเปลี่ยนไปจากเดิม

sql 2026-05-05
Symptom อาการของบั๊ก
POST /api/v2/app/import succeeded for the first user, crashed on the second restore: `SQLite objects created in a thread can only be used in that same thread. The object was created in thread X but this is thread Y` — except the actual error was different. การนำเข้าข้อมูลสำรองรอบแรกกระทำผ่านพ้นไปด้วยดี แต่รอบถัดมาของการกู้คืนระบบกลับล้มเหลวเสียหายและรายงานปัญหาที่สับสนชวนวิเคราะห์ผิดเรื่องการแบ่งสายทำงาน (Thread)
Root cause สาเหตุแท้จริง
When every row in the payload was a no-op (LWW lost, folder already existed) the cursor never opened a real transaction. Calling conn.commit() on a connection without an active transaction raised. The user-visible message was misleading because of FastAPI's default exception transform. เมื่อข้อมูลที่กู้คืนตรงกับฐานข้อมูลล่าสุดร้อยเปอร์เซ็นต์ (ส่งผลให้ไม่ต้องบันทึกอะไรใหม่เลย) ฐานข้อมูลจึงมองข้ามขั้นตอนเขียนไฟล์ดิสก์ แต่ระบบสั่งการภายนอกเกิดพยายามส่งคำสั่งกดบันทึก (Commit) เปล่า ๆ ทำให้เครื่องมือจัดเก็บมองเป็นการกระทำที่ผิดเงื่อนไขความปลอดภัยและปฏิเสธจนโปรแกรมสะดุดล้ม
Fix แนวทางแก้ไข
Wrap the commit in try/except. If no transaction is active, that's the success path — log and continue. Discovered while writing test_app_import.py — exactly the kind of edge case that integration tests catch and unit tests don't. สวมเกราะคัดกรองความปลอดภัยให้การสั่งงานเขียนเซฟ (Crash-resilient memory): หากระบบประเมินว่าไม่มีข้อมูลใหม่เพิ่ม ระบบจะถือว่าสำเร็จและดำเนินการตามแผนต่อไปอย่างสงบ ราบรื่น ไม่ล้มเหลว
core/api/rest_server_v2.pycore/api/tests/test_app_import.py
Recalled since สืบค้นเรียกคืน ตั้งแต่บันทึก
#09

Astro parsed `{csv,md}` inside a code block as a JSX expression ขั้นตอนการประกอบเว็บล้มเหลวชะงัก เนื่องจากระบบสับสนว่าวงเล็บปีกกาเป็นชุดคำสั่ง

tooling 2026-05-05
Symptom อาการของบั๊ก
astro build failed with `Expected expression but found "csv"` pointing at a /docs section. The line was inside a fenced code block, which I assumed was raw text. ระบบการวิเคราะห์และตรวจสอบหน้าสารบัญเอกสารรายงานแจ้งเตือนการประกอบระบบขัดข้อง โดยไปชี้เตือนตรงจุดวงเล็บปีกกาที่พิมพ์แนะนำชื่อสัญลักษณ์ประเภทเอกสารในกล่องข้อความดิบธรรมดา
Root cause สาเหตุแท้จริง
Astro's template literals run JSX expression parsing even inside <pre><code>. `{csv,md}` looks like an object destructure to the parser. The Markdown fence does NOT escape it. โปรแกรมสร้างหน้าจอเข้าใจว่าสัญลักษณ์วงเล็บปีกกา `{}` เป็นโค้ดโปรแกรมอัจฉริยะที่ต้องรันคิดเลขแบบเรียลไทม์ แม้ผู้ใช้จะตั้งใจเขียนในลักษณะกล่องข้อความอ้างอิงธรรมดา และไม่ได้คัดกรองแปลงข้อความออกจากการถูกถอดรหัสเป็นสคริปต์คอมพิวเตอร์
Fix แนวทางแก้ไข
Replace the literal `{` and `}` inside code blocks with `&#123;` and `&#125;`. Or wrap the whole block in `<Fragment set:html=\`...\`/>`. The HTML-entity route is less surprising. เปลี่ยนรูปแบบวงเล็บปีกกาให้เป็นสัญลักษณ์ความปลอดภัยในภาษา HTML เพื่อแสดงผลเฉพาะหน้าจอเท่านั้น และป้องกันไม่ให้โปรแกรมวิเคราะห์มองเครื่องหมายเหล่านี้เป็นสคริปต์ที่ต้องนำมาประมวลผล
src/pages/docs.astro
Recalled since สืบค้นเรียกคืน ตั้งแต่บันทึก
#10

Reminder fired 7 hours late — DB stored datetime as local time, not UTC การแจ้งเตือนเตือนล่าช้าไปเจ็ดชั่วโมงเต็ม เนื่องจากระบบเวลาลืมนำข้อมูลเขตเวลาไปบันทึก

env 2026-04-30
Symptom อาการของบั๊ก
User in Bangkok set a reminder for 14:00. It fired at 21:00. Logs showed the scheduler woke up at the right wall-clock moment, but the row's `fire_at` had drifted. เมื่อผู้ใช้ในกรุงเทพฯ สั่งการตั้งปฏิทินนาฬิกาให้เตือนตอนบ่ายสองโมงตรง แต่แอปดันไปปลุกเตือนตอนสามทุ่มตรงของวันนั้น บันทึกระบุตัวตั้งระบบตื่นมาตามจังหวะประมวลผลถูกต้อง แต่ข้อมูลตัวเลขเวลากลับเคลื่อนจากเขตเวลาปัจจุบัน
Root cause สาเหตุแท้จริง
I assumed SQLite stored datetimes in UTC because Python's datetime.utcnow() was used at insert. But `datetime` objects without tzinfo are naive — SQLite stored them as ISO strings, then re-read them as naive again, and the scheduler compares against a tz-aware datetime, blowing up the math. เกิดจากสมมติฐานผิดพลาดว่าฐานข้อมูลจะระบุแปลงเวลาสากลให้อัตโนมัติเมื่อจัดเก็บแบบไม่มีข้อมูลเขตเวลาควบคู่ ครั้นดึงข้อมูลกลับขึ้นมารอบสองเพื่อเปรียบเทียบกับเวลาระบบที่มีฐานบวกเจ็ดชั่วโมง ทำให้ตัวเลขประเมินหักลบขาดหายไปเจ็ดชั่วโมงโดยไร้คำเตือนความผิดพลาด
Fix แนวทางแก้ไข
Use `datetime.now(timezone.utc)` everywhere. Add a startup migration that bumps any old naive rows by the local-tz offset once. Add a unit test that round-trips through SQLite to assert tz survives. ปรับมาตรฐานระบบการลงบันทึกเวลาทั่วทุกส่วนให้ระบุอิงเวลากลางมาตรฐานโลก (UTC) ที่ระบุข้อมูลเขตเวลาแน่ชัด และออกคำสั่งสแกนปรับแก้ข้อมูลเวลาเก่าแบบครั้งเดียวให้ย้อนกลับมาถูกต้อง และเขียนแบบจำลองเพื่อตรวจสอบความสมบูรณ์
core/reminders/scheduler.pycore/memory/store_v2.py
Recalled since สืบค้นเรียกคืน ตั้งแต่บันทึก
// Your turn ตาคุณบ้าง

Two ways to capture a lesson. 2 วิธีสร้างบทเรียนวิศวกรรมเฉพาะตัว

After installing Cosmos, both of these work in any AI tool with the Cosmos MCP attached. Use whichever feels natural.

หลังจากติดตั้งคอสมอสแล้ว ทั้งสองช่องทางนี้จะสามารถทำงานได้ทันทีผ่านระบบผู้ช่วยอัจฉริยะที่เชื่อมต่อกับคอสมอส คุณสามารถเลือกใช้วิธีการที่ตรงกับขั้นตอนการทำงานของคุณได้โดยสะดวก

A · You ask ก · บอกความต้องการด้วยตัวคุณ

After a fix, just say: หลังจากการแก้ไขข้อขัดข้องเสร็จสิ้น เพียงบอกระบบสั้น ๆ ว่า:

"Remember this — the bundle excluded
google-generativeai which broke the
Telegram bot silently in v0.2.0."
"จดบันทึกเรื่องนี้ไว้ด้วย — ตัวติดตั้งตัดชุดข้อมูลปัญญาประดิษฐ์ออกไป ส่งผลให้ระบบบอตส่งข้อความไม่ทำงานโดยไม่มีคำแจ้งเตือนใด ๆ ในแอปเวอร์ชันล่าสุด"

The AI calls code_remember_error with the right shape automatically.

ระบบปัญญาประดิษฐ์จะทำการเรียกใช้คำสั่ง code_remember_error เพื่อจัดเรียงข้อมูลเข้าสู่ระบบอย่างเป็นระเบียบด้วยตนเอง

B · Guidelines tell the AI ข · กำหนดผ่านไฟล์แนวทางการเขียนโค้ด

Add to your project's CLAUDE.md file: เพิ่มข้อความต่อไปนี้ในคู่มือและกฎระเบียบประจำโครงการของคุณ:

After fixing a non-trivial error,
call code_remember_error.
Triggers: root cause differed from the
error message, took >1 try, or the user
reported a bug after your work compiled.
"เมื่อแก้ไขข้อขัดข้องสำคัญเรียบร้อยแล้ว ให้เรียกใช้ชุดคำสั่งจดจำทันที โดยทำงานเมื่อ: สาเหตุหลักไม่ตรงกับคำเตือนความคลาดเคลื่อนปกติ ต้องวิเคราะห์มากกว่าหนึ่งครั้ง หรือพบบั๊กหลังจากการประกอบระบบ"

The AI does it without being asked. This is what built Cosmos's own digital brain.

ผู้ช่วยอัจฉริยะจะปฏิบัติตามแนวทางโดยอัตโนมัติและจัดทำระบบคลังความรู้สะสม ซึ่งเป็นวิถีหลักที่ใช้พัฒนาสมองดิจิทัลของคอสมอสจนสำเร็จ

// The honest moat ระบบป้องกันความได้เปรียบที่ซื่อตรง

Why this compounds. ทำไมข้อมูลชุดนี้จึงทวีความสำคัญยิ่งขึ้น

Every entry on this page lives on my Mac. Yours will live on yours. We don't have a centralized "lesson cloud" you'd be paying us to host — that would betray the whole local-first promise.

บันทึกความรู้และบทเรียนวิศวกรรมทุกชิ้นบนหน้านี้จะถูกจัดเก็บไว้ในคอมพิวเตอร์ส่วนบุคคลของผมอย่างปลอดภัย และบันทึกของคุณก็จะถูกเก็บไว้บนอุปกรณ์ของคุณเช่นเดียวกัน เราไม่มีระบบการจัดเก็บข้อมูลผ่านคลาวด์ส่วนกลางที่ผูกขาดและบังคับเรียกเก็บค่าบริการรายเดือน ซึ่งนั่นจะขัดต่อแนวคิดการจัดเก็บข้อมูลบนอุปกรณ์ของผู้ใช้งานโดยสมบูรณ์

The moat isn't that we own a lesson library. It's that you own the one that fits your repo. After three months of using Cosmos, your AI has implicit knowledge of every weird bug, abandoned approach, and hidden constraint your codebase has taught you. A competitor can ship the same UI tomorrow. They cannot ship the lessons your code already taught you.

จุดแข็งที่แท้จริงไม่ใช่การที่พวกเราเป็นเจ้าของคลังบทเรียนเหล่านี้ แต่เป็นการที่ตัวคุณเองเป็นเจ้าของคลังบทเรียนที่สอดรับกับสถาปัตยกรรมเฉพาะตัวของระบบคุณ หลังจากใช้งานคอสมอสเป็นเวลาสามเดือนขึ้นไป ระบบปัญญาประดิษฐ์จะมีความเข้าใจอย่างลึกซึ้งต่อทุกจุดอ่อนที่คลาดเคลื่อน ทุกกลยุทธ์ที่ยกเลิก และทุกข้อจำกัดที่ซ่อนอยู่ภายในรหัสโปรแกรมของคุณ ซึ่งคู่แข่งรายอื่นอาจลอกเลียนแบบหน้าต่างการใช้งานได้อย่างรวดเร็วในวันพรุ่งนี้ แต่พวกเขาไม่มีวันที่จะเป็นเจ้าของบทเรียนล้ำค่าที่โครงสร้างระบบของคุณได้หล่อหลอมและสั่งสมขึ้นมาได้

Local-first means the moat is yours, not ours. We're fine with that.

แนวคิดการจัดเก็บบนอุปกรณ์ของผู้ใช้โดยตรงหมายความว่า สินทรัพย์ทางปัญญาที่แข็งแกร่งนี้จะเป็นสิทธิขาดของคุณเพียงผู้เดียว ซึ่งพวกเรายินดีและตั้งใจให้เป็นเช่นนั้นอย่างยิ่ง

// What links the first three ความเชื่อมโยงของสามบทเรียนแรก

Three lessons. Three different layers of catch-net. สามบทเรียนสำคัญ บนระบบดักกรองความผิดพลาดสามระดับ

layer 01 · production usage

Graph view freeze. A real user clicked a node and watched the app stutter. Three independent issues compounded; one could have shipped without the others. หน้าจอแผนภูมิเกิดการค้างกระตุก ผู้ใช้งานจริงทดลองกดปุ่มแล้วพบความเชื่องช้าของระบบ โดยเกิดจากความล้มเหลวสามด้านที่ซ้อนทับกัน ซึ่งหากมีปัญหาเพียงบางจุด อาจทำให้หลุดลอดสายตาไปสู่การใช้งานจริงได้

layer 02 · snapshot test

Classifier content-bleed. A snapshot test on the audit cycle saw a Python file with a money-flavoured comment getting tagged as expense. Caught at write-time; structural fix shipped same day. การคัดกรองข้อมูลผิดพลาดข้ามสาย ระบบตรวจสอบประเมินผลพบไฟล์ชุดคำสั่งที่มีข้อความความเห็นเกี่ยวกับประเด็นการเงินถูกดักและจัดประเภทผิดพลาด ซึ่งตรวจจับได้ทันควันในขณะเตรียมบันทึกและแก้ไขโครงสร้างได้อย่างสมบูรณ์ในวันเดียวกัน

layer 03 · integration test

Watcher method shadowing. A new integration test booting a real watchdog Observer caught a Python attribute trap that mypy can't see and unit tests didn't reach. การบดบังชื่อฟังก์ชันเฝ้าดูความเคลื่อนไหว การสร้างแบบจำลองการเชื่อมโยงระบบช่วยค้นพบข้อผิดพลาดเชิงลึกของการชนกันของชื่อตัวแปรระบบปฏิบัติการ ซึ่งเป็นจุดบอดสำคัญที่ระบบตรวจวิเคราะห์รหัสโปรแกรมทั่วไปไม่มีวันเข้าถึงและตรวจจับไม่ได้

The point isn't that bugs happened. The point is that Cosmos has three different catch-nets at three different layers, and all three caught real things before any of them shipped to a user. Project Lessons isn't a marketing feature — it's how Cosmos audits itself. The lesson library you build with your own product works the same way. เป้าหมายไม่ใช่การยอมรับความผิดพลาดที่เกิดขึ้น แต่เป็นการพิสูจน์ให้เห็นว่าระบบดักกรองของคอสมอสมีความสมบูรณ์ถึงสามชั้นเพื่อสกัดกั้นปัญหาลึกซึ้งได้จริงก่อนส่งถึงมือผู้ใช้งาน ระบบการเก็บบทเรียนนี้ไม่ใช่เพียงคำโฆษณา แต่เป็นแกนหลักที่ทำให้เราพัฒนาคอสมอสได้อย่างปลอดภัยและตรวจสอบตนเองได้อย่างเข้มงวด ซึ่งคลังความรู้ที่คุณสร้างขึ้นสำหรับโครงการของคุณเองก็จะปฏิบัติหน้าที่อย่างเต็มประสิทธิภาพเช่นเดียวกันนี้

Recording lessons is automatic. The moat compounds when you curate them — pin the recurring ones, scope-glob to file families, disable what's stale.

ระบบบันทึกความผิดพลาดและพัฒนาการทำงานให้แบบอัตโนมัติ และมูลค่าของระบบจะยิ่งเติบโตขึ้นอย่างทวีคูณเมื่อได้รับการคัดกรองอย่างประณีต เช่น การปักหมุดประเด็นสำคัญที่เกิดขึ้นบ่อยครั้ง การเชื่อมโยงให้สอดรับกับประเภทกลุ่มไฟล์ต่าง ๆ และการปิดบันทึกส่วนที่เก่าล้าสมัยแล้ว

→ Read the curation guide → ศึกษาคู่มือการดูแลและจัดระเบียบระบบข้อมูล

Ready to start your own lesson library? พร้อมเริ่มสร้างฐานความรู้และบทเรียนของตัวเองแล้วหรือยัง?

Currently in private alpha. Once invited, the MCP wizard wires Cosmos into Claude Code, Cursor, Cline, and Windsurf — your first lesson can land before lunch.

ปัจจุบันเปิดให้ทดสอบเฉพาะกลุ่มปิด โดยตัวช่วยติดตั้งอัจฉริยะจะเชื่อมต่อคอสมอสเข้ากับเครื่องมือการเขียนโปรแกรมชั้นนำต่าง ๆ ของคุณอย่างราบรื่น เพื่อให้คุณบันทึกบทเรียนแรกและเพิ่มความเสถียรได้ทันที