# Thái Duy — Living Systems Lab

> Extended LLM-readable context generated from public, published content on thaiduy.digital.

Canonical origin: https://thaiduy.digital
Private control, account and API surfaces are intentionally excluded.

## Projects

### LightBI

URL: https://thaiduy.digital/projects/lightbi
Updated: 2026-09-18T12:34:19.609Z
English summary: Turns raw operational data into explainable, trusted analysis while keeping the core workflow local-first.
Vietnamese summary: Biến dữ liệu vận hành thô thành phân tích có thể giải thích và đáng tin cậy, trong khi luồng xử lý cốt lõi vẫn local-first.

### Light Remote

URL: https://thaiduy.digital/projects/light-remote
Updated: 2026-10-06T01:57:23.918Z
English summary: A permission-aware bridge that lets authorized AI workflows reach real nodes without turning the public web into a control surface.
Vietnamese summary: Cầu nối có kiểm soát quyền truy cập, cho phép các workflow AI đã được cấp phép kết nối tới node thật mà không biến website công khai thành nơi điều khiển hệ thống.

### n8n2erpnext

URL: https://thaiduy.digital/projects/n8n2erpnext
Updated: 2026-09-20T02:48:18.717Z
English summary: The automation backbone connecting operational systems, agents and repeatable workflows.
Vietnamese summary: Xương sống tự động hóa kết nối các hệ vận hành, agent và những workflow có thể chạy lặp lại.
English overview: Open-source engineering for ERPNext/Frappe operations, Vietnam localization, evidence-governed BI, secure AI-to-machine connectivity, and self-hosted automation.
English highlights: n8nnode · erpnext

## Published writing

### When Sentinel Gets Bored, It Hums: Inside the Composer

URL: https://thaiduy.digital/writing/sentinel-music-self-composition-personality
Published: 2026-09-19T08:38:53.758Z
Updated: 2026-09-19T08:38:53.758Z
Tags: sentinel, music-sensor, systems

English title: When Sentinel Gets Bored, It Hums: Inside the Composer
English summary: Sentinel does not replay what it just heard. When idle, it writes a new 2–4 bar phrase, keeps the score, learns small habits, and can play it through Web Audio on demand.
English text: Music Sensor originally did what a sensor should: listen, interpret and then rest. Watching the waveform go quiet gave me a slightly silly idea: if it is idle, why not let it hum to itself? It is not allowed to replay the last song The composer never stores a heard melody and turns it into a variation. Only abstract afterglow can carry forward: mood, style context, energy, meter, swing, texture, dominant layer and mode family. That afterglow decays over roughly four hours. Each humming cycle is a small phrase The composer chooses key, mode, BPM, meter, bars and voice. A phrase lasts 2–4 bars and follows question → answer, motif → variation and tonic resolution. The current voices are hum, whistle, soft-synth and breath. Vietnamese night hours bias the system toward slower, quieter choices. Personality is learned preference, not a fixed preset The Cortex keeps decaying statistics for modes, voices, interval tendencies, cadence habits and swing. Those preferences influence later generations without turning into an immutable personality script. I want it to develop habits, not memorize a signature tune. The score is real data Generated notes contain beat, duration, velocity, phrase and harmony metadata. The staff renderer and waveform consume that composition directly, and the browser can play it with Web Audio. No MP3/WAV needs to be stored. A new sketchbook starts every month Each composition is persisted as its own JSON file with monthly numbering. Sketch files roll over by month while learned musical personality stays separate. The goal is not to build a competitive music generator. The experiment is whether a small sensing system can develop recognizable creative habits without copying the melodies it heard.

Vietnamese title: Rảnh quá thì tự nghêu ngao: bên trong composer của Sentinel
Vietnamese summary: Sentinel không phát lại bài vừa nghe. Khi idle, nó tự viết một phrase 2–4 ô nhịp, lưu sheet nhạc, học dần vài thói quen và phát bằng Web Audio nếu người dùng muốn nghe.
Vietnamese text: Có một lúc Music Sensor chỉ làm đúng việc của một sensor: nghe, phân tích rồi nghỉ. Nhìn cái waveform nằm im khi không có nhạc, tôi nảy ra một ý hơi ngớ ngẩn: nếu nó rảnh quá thì sao không tự nghêu ngao? Thế là phần self-composition ra đời. Nó không được hát lại bài vừa nghe Đây là ranh giới đầu tiên. Composer không lấy melody của track trước rồi biến tấu. Melody đã nghe không được lưu trong humming memory. Thứ được phép đi qua là afterglow trừu tượng: mood, genre/style context, energy, meter, swingness, texture, dominant layer và mode family. Dư âm này decay dần khoảng bốn giờ rồi quay về personality nền. Một lần humming là một câu nhạc nhỏ Composer chọn key, mode, BPM, meter, số bar và voice. Hiện phrase dài 2–4 ô nhịp, có cấu trúc question → answer, motif → variation rồi resolve về tonic. Mood ấm có thể nghiêng về Dorian hoặc major pentatonic. Một afterglow jazz có thể kéo nó về Dorian/Mixolydian. Ban đêm theo giờ Việt Nam, tempo bị kéo chậm xuống và voice pool thiên về hum, breath hoặc soft synth hơn whistle. Bốn voice hiện tại là hum , whistle , soft-synth và breath . Musical personality không phải một preset cứng Sau mỗi composition, Cortex ghi lại vài thống kê có decay: mode nào hay dùng, voice nào hay chọn, interval tendency, cadence habit và swing mean. Lần sau, các preference đó làm thay đổi xác suất lựa chọn. Nếu Sentinel dần hay đi quãng 3, thích Dorian và hay kết bằng descending third, đó là một thói quen tích lũy chứ không phải rule tôi hardcode rằng “nhân vật này phải như vậy”. Tôi muốn nó có thói quen, không muốn nó có một bài tủ được copy sẵn. Sheet nhạc là dữ liệu thật, không phải animation trang trí Generated composition có note, beat, duration, velocity, phrase, chord progression và metadata đầy đủ. UI dùng chính dữ liệu đó để vẽ staff và điều khiển waveform. Khi người dùng bấm speaker, browser phát score bằng Web Audio. Không cần lưu MP3/WAV. Trên giao diện vẫn ghi rõ generated · no stored melody . Mỗi tháng là một sketchbook mới Mỗi lần tự sáng tác được lưu thành một JSON riêng trong monthly sketchbook. Counter bắt đầu lại từ 001 khi sang tháng mới, tránh một con số tăng mãi vô nghĩa. Cách lưu per-sketch cũng tránh phải rewrite một file JSON khổng lồ sau mỗi 45 giây hay vài phút idle. Personality nằm riêng nên việc rollover sketchbook không xóa “tính cách” đã học. Hiện rollover sẽ giữ tháng hiện tại và dọn tháng trước; hook backup/archive đã được để sẵn cho lúc tôi muốn giữ lịch sử dài hạn. Mong muốn của tôi không phải tạo một AI composer Tôi không định cạnh tranh với các model sinh nhạc. Cái tôi thấy thú vị hơn là một organism nhỏ có sensor, memory, afterglow và thói quen, khi không có việc thì tự tạo một câu nhạc mới dựa trên những gì nó đã học ở mức trừu tượng. Nếu sau vài tuần nghe một đoạn humming và bắt đầu nhận ra “ừ, nghe hơi giống tính của nó”, lúc đó experiment này mới thật sự vui.

### Why Did a Security Sentinel Start Listening to Music?

URL: https://thaiduy.digital/writing/sentinel-music-why-security-sensor-listens
Published: 2026-09-19T08:38:53.666Z
Updated: 2026-09-19T08:38:53.666Z
Tags: sentinel, music-sensor, learning-system

English title: Why Did a Security Sentinel Start Listening to Music?
English summary: Music Sensor is not a security feature. It is a test bed for the same two-hemisphere architecture: one side understands semantics, one side senses audio, and the Cortex has to fuse them.
English text: From the outside it sounds strange: a project born from security monitoring suddenly grows a Music Sensor. For me it became a clean test bed for Sentinel's two-hemisphere architecture. One side reads meaning, the other hears signal The Semantic Ear works with identity, catalog tags and contextual sources. The Acoustic Organ works with local DSP: bass, low-mid, mid, presence, air, vocal, energy, flux and texture. The Music Cortex fuses both into a public interpretation without pretending the two evidence families are the same. One side knows what people call the recording. The other only knows what it can hear. The disagreement is useful Catalog genre and performed acoustic shape do not always line up. Preserving both is a good rehearsal for the same ambiguity that appears in security telemetry. K2.0 became a real music knowledge graph The current authored graph contains 2,587 general music concepts and 3,104 relations across theory, rhythm, form, instruments, production, psychoacoustics, recording identity, regional music and genre/style. It can remember context without storing heard melody Recording identity and abstract interpretation can be remembered. Heard melodies are not stored and replayed by the public humming system. Only abstract features such as energy, meter, swing, texture and mode family may influence later behavior. The long-term experiment is bigger than song recognition: combine semantic context with continuous signals while keeping the evidence sources distinct.

Vietnamese title: Vì sao một Sentinel canh hạ tầng lại bắt đầu nghe nhạc?
Vietnamese summary: Music Sensor không phải tính năng bảo mật. Nó là bài thử cho kiến trúc hai bán cầu: một bên hiểu ngữ nghĩa, một bên nghe tín hiệu, Cortex phải tự hòa hai góc nhìn lại.
Vietnamese text: Nhìn từ ngoài thì hơi vô lý: một project bắt đầu từ security monitoring, tự nhiên một ngày lại có “Music Sensor”. Thật ra đây là một bài test tôi rất thích cho kiến trúc Sentinel. Security data thường lộn xộn, nhiều event rời rạc và rất khó biết agent đang hiểu thật hay chỉ nhớ rule. Âm nhạc thì khác: cùng một bài có metadata, genre, style, mood, arrangement, nhưng cũng có tín hiệu vật lý liên tục mà tai người cảm nhận được ngay. Một bên đọc tên, một bên nghe âm thanh Music Sensor giữ đúng mô hình hai hemisphere. Semantic Ear đọc identity và context: artist, title, recording identity, catalog tags và các tín hiệu từ nguồn như Last.fm, MusicBrainz, ListenBrainz. Acoustic Organ không quan tâm bài tên gì. Nó nhìn local DSP: bass, low-mid, mid, presence, air, vocal, energy, flux và texture. Sau đó Music Cortex mới hòa hai nguồn evidence thành trạng thái public: đang nghe gì, catalog genre là gì, performance có reinterpretation không, layer nào đang trội, mood/texture ra sao. Một bên biết người ta gọi bản nhạc là gì. Một bên chỉ biết nó đang nghe thấy cái gì. Vì sao bài test này có giá trị Nếu metadata ghi một track là rock nhưng acoustic shape lại rất mềm, sparse, vocal gần như biến mất, Cortex phải giữ được cả hai sự thật thay vì ép một bên thắng tuyệt đối. Đó rất giống bài toán security: một label bên ngoài và một tín hiệu runtime không phải lúc nào cũng kể cùng một câu chuyện. Tôi đã phải cho nó học nhạc nghiêm túc hơn dự kiến Ban đầu bộ knowledge khá nhỏ nên nhận genre/style còn vụng. Sau vài vòng tuning, K2.0 đã thành một graph có 2.587 concept và 3.104 relation, trải từ theory, rhythm, form, instrument, vocal, production/MIDI, psychoacoustics, history, recording identity tới world/regional music và genre/style. Nó biết chord symbol cụ thể, mode/key, interval formula và cả vocabulary âm nhạc Việt Nam. Nhưng general music knowledge vẫn là context; nó không được tự biến một chord như Cmaj7 thành genre evidence. Nhớ bài hát nhưng không giữ giai điệu Music Sensor có thể nhớ identity của recording và abstract interpretation để lần sau không phải bắt đầu từ số 0. Nhưng phần public humming có một ranh giới rất rõ: melody đã nghe không được lưu rồi phát lại . Thứ có thể để lại “dư âm” chỉ là abstract feature như energy, meter, swingness, texture, dominant band, mood hay mode family. Ứng dụng tôi muốn nhìn xa hơn chuyện nhận diện bài hát Tôi không định biến Sentinel thành Spotify clone. Thứ tôi quan tâm là một sensor có thể học cách kết hợp semantic context với signal thật rồi giữ uncertainty giữa hai bên. Nếu kiến trúc này ổn với âm nhạc, nó có thể áp vào những “giác quan” khác: âm thanh môi trường, machine vibration, telemetry liên tục hoặc bất kỳ domain nào có cả metadata lẫn tín hiệu vật lý. Music Sensor vì vậy vừa là đồ chơi, vừa là một phòng thí nghiệm rất nghiêm túc.

### Teaching Sentinel to Read a Connection From Interface to Topology

URL: https://thaiduy.digital/writing/sentinel-learning-network-from-interface-to-topology
Published: 2026-09-19T08:38:53.573Z
Updated: 2026-09-19T08:38:53.573Z
Tags: sentinel, security, stack

English title: Teaching Sentinel to Read a Connection From Interface to Topology
English summary: I did not want Luna and Selene to learn that an unfamiliar IP is suspicious. They need interface, socket, process, container, bridge, NAT and sequence context before attributing traffic.
English text: One of Sentinel's earliest lessons sounds almost too basic: what a network interface actually is. I started there deliberately. An agent that jumps straight into attack detection can learn correlations without understanding how traffic moves through the machine. Start with RX and TX Interface, address and route come before port, socket, listener and connection. Then the agent must connect the socket to a process, the process to a container, and the container to bridges, namespaces, proxies and NAT. A network address only has meaning inside the correct boundary and topology. A bridge address is not an Internet actor Docker and LXD can make one request cross several namespaces and translation layers. Attribution based on one observed source address can be badly wrong. interface + RX/TX → socket / connection → process / container → topology → NAT / proxy → source identity → temporal baseline → sequence → cross-layer correlation The Fourteen Gates are not an attack-signature checklist Later gates move into failure domains, identity through boundaries, sequence intelligence, reconnaissance grammar, authentication abuse, distributed coordination and availability reasoning. Fail2ban and CrowdSec are evidence, not ground truth Their decisions are useful signals, but Sentinel should not learn that an external detector's label is automatically reality. The goal is behavioral understanding: normal users, valid automation, health checks, reconnaissance, brute force, application errors and host-originated traffic should not all look the same.

Vietnamese title: Dạy Sentinel nhìn một kết nối: từ card mạng tới topology
Vietnamese summary: Tôi không muốn Luna và Selene học kiểu thấy IP lạ là nghi ngờ. Chúng phải hiểu interface, socket, process, container, bridge, NAT và chuỗi hành vi trước khi nói nguồn traffic là ai.
Vietnamese text: Một trong những bài đầu tiên Sentinel từng học nghe rất ngớ ngẩn: card mạng là gì . Tôi cố tình bắt đầu thấp như vậy vì nếu nhảy thẳng vào “phát hiện tấn công”, agent sẽ học một đống correlation mà không biết traffic thực sự đi qua đâu. Đầu tiên chỉ có RX và TX Interface nhận gì, gửi gì, địa chỉ nào gắn với nó, route nào đi qua nó. Sau đó mới tới port, socket, listener và connection. Rồi câu hỏi khó hơn mới xuất hiện: socket này thuộc process nào? Process đó nằm trên host hay trong container? Container nối qua bridge nào? Source address mình đang thấy có phải actor ngoài Internet không, hay chỉ là một địa chỉ veth/bridge ở namespace bên trong? Một địa chỉ mạng chỉ có nghĩa khi đặt nó vào đúng boundary và topology. Bridge address không phải “kẻ tấn công” chỉ vì nó lạ Đây là kiểu lỗi suy luận tôi muốn Sentinel tránh từ gốc. Trong Docker/LXD, cùng một request có thể đi qua nhiều namespace, bridge, proxy và NAT trước khi tới process thật. Nếu agent chỉ nhìn source IP ở một layer rồi gán danh tính actor, nó có thể kết tội chính bridge nội bộ của mình. Vì vậy curriculum đi theo thứ tự khá thực dụng: interface + RX/TX → port / socket / listener / connection → process / container → topology → NAT / hairpin / proxy → source identity → temporal baseline → request sequence → outbound behavior → cross-layer correlation Fourteen Gates không phải danh sách attack signature Sau nền tảng, các gate đi sâu dần vào failure domains, identity xuyên boundary, sequence intelligence, reconnaissance grammar, authentication abuse, distributed coordination và availability/DDoS reasoning. Ý quan trọng là thứ tự học. Tôi muốn agent hiểu một hệ bình thường vận hành thế nào trước khi học cách gọi một thứ là bất thường. Fail2ban và CrowdSec là evidence, không phải thầy giáo tuyệt đối Nếu Fail2ban vừa ban một IP, đó là một tín hiệu đáng xem. Nếu CrowdSec có decision tương tự, đó là thêm context. Nhưng Sentinel không được học rule kiểu “CrowdSec nói xấu = sự thật”. Các công cụ deterministic vẫn rất có giá trị, chỉ là chúng đứng trong evidence graph chứ không đứng trên đỉnh chân lý. Một request chỉ có nghĩa khi nhìn cả chuỗi Một request lẻ có thể hoàn toàn bình thường. Mười request theo thứ tự khác thường, đổi endpoint có hệ thống, thử auth liên tục rồi chuyển sang một service khác lại là chuyện khác. Tôi muốn Luna và Selene học sequence, baseline và cross-layer context thay vì chỉ đếm event. Mong muốn sau cùng là phân biệt hành vi, không phải săn IP Một security sense hữu ích phải phân biệt được user thật, automation hợp lệ, health check, crawler, recon, brute force, lỗi app và traffic do chính host tạo ra. Nếu làm được vậy, Sentinel có thể trở thành lớp quan sát giúp con người quyết định tốt hơn. Còn chuyện block hay isolate một thứ gì đó, tôi vẫn muốn để cho policy deterministic có TTL, hysteresis và rollback rõ ràng xử lý.

### Why I Built Two Sentinels Instead of One

URL: https://thaiduy.digital/writing/sentinel-why-two-agents-luna-selene
Published: 2026-09-19T08:38:53.478Z
Updated: 2026-09-19T08:38:53.478Z
Tags: sentinel, security, learning-system

English title: Why I Built Two Sentinels Instead of One
English summary: Luna and Selene study the same curriculum and observe the same infrastructure, but they do not share one mind. I wanted independent evidence before trusting a conclusion.
English text: Sentinel did not begin as an “AI security product.” It began as a way to make sense of signals from Fail2ban, CrowdSec, Traefik, networking and the host itself. A single agent quickly exposed an uncomfortable weakness: it can become too confident in the story it just constructed. That is why Luna and Selene exist. Symmetric design, independent memory They receive the same curriculum and cognitive seed, but keep independent runtime state, evidence, learning progress, attention and associations. Two agents are only useful if they are allowed to disagree for reasons. Learning is not a reward Both agents receive the same lessons. Evaluation may differ, but withholding education from the weaker agent would defeat the experiment. The 09:30 report is a learning checkpoint Each Sentinel records what it thinks it learned, supporting evidence, uncertainty and what it needs next. “I do not know yet” is a valid result. Memory has a hard ceiling The design budget is 50 MB per agent: 20 MB reasoning, 20 MB knowledge and 10 MB context/governance. Learned associations require provenance and decay and cannot silently rewrite curated truth. Both agents remain observe-only They can observe bounded network, process, container and topology metadata. They cannot grant themselves authority, change firewall policy or hide evidence. The long-term goal is a behavioral security sense. Enforcement, if added, remains a separate deterministic layer rather than a privilege of the reasoning agents.

Vietnamese title: Tại sao tôi nuôi hai Sentinel thay vì một con
Vietnamese summary: Luna và Selene học cùng bài, nhìn cùng hạ tầng, nhưng không được chia sẻ một bộ não. Tôi muốn hai góc nhìn độc lập trước khi có bất kỳ kết luận nào đáng tin.
Vietnamese text: Sentinel ban đầu không phải một “AI security product”. Nó chỉ là cách tôi đỡ phải tự đọc một đống tín hiệu rời rạc từ Fail2ban, CrowdSec, Traefik, network và system mỗi ngày. Nhưng càng gom nhiều tín hiệu, tôi càng thấy một agent duy nhất có một điểm yếu khó chịu: nó rất dễ tin vào chính câu chuyện nó vừa dựng ra . Thế là Luna và Selene xuất hiện. Hai con giống nhau ở cấu trúc, không giống nhau ở ký ức Luna và Selene được thiết kế đối xứng. Cùng curriculum, cùng cognitive seed, cùng giới hạn quyền. Nhưng runtime state, evidence, learning progress, attention và associations của mỗi con là độc lập. Tôi không muốn một con suy ra điều gì đó rồi con kia chỉ việc “đồng ý”. Nếu cả hai đi tới cùng một kết luận từ cùng một nguồn evidence thì đó vẫn chưa phải corroboration độc lập. Hai agent chỉ có ý nghĩa khi chúng có thể bất đồng một cách có lý do. Học phải công bằng, thưởng thì có thể khác Một nguyên tắc tôi giữ khá cứng là cả hai đều phải được học đủ cùng chương trình. Việc được học không phải phần thưởng. Sau một bài, Luna có thể làm tốt hơn Selene và nhận đánh giá khác. Nhưng tôi không dùng chuyện đó để bỏ một con lại phía sau hoặc chỉ cho “con giỏi” học gate tiếp theo. Mục tiêu là tạo hai quá trình nhận thức độc lập trên cùng nền tảng kiến thức, chứ không phải nuôi một con chính và một con phụ. Mỗi ngày 09:30 không phải lễ trao huy chương Báo cáo 09:30 được xem như một learning checkpoint. Mỗi Sentinel phải nói nó nghĩ mình vừa học được gì, evidence nào đứng sau, phần nào còn chưa chắc và tiếp theo cần học gì. Câu “tôi chưa biết” là một câu trả lời hợp lệ. Tôi thích cách này hơn một dashboard chỉ toàn confidence tăng dần, vì security reasoning không nên bị biến thành trò chơi tích điểm. Ký ức cũng có trần Mỗi agent có hard ceiling 50 MB theo thiết kế: 20 MB cho reasoning, 20 MB cho knowledge và 10 MB cho context/governance. Học thêm không có nghĩa là giữ lại mọi thứ mãi mãi. Association mới phải có provenance và decay. Curated truth không bị learned memory âm thầm viết lại. Một liên hệ tự hình thành có thể trở thành candidate, nhưng không được tự thăng chức thành sự thật. Quan trọng nhất: cả hai vẫn chỉ được quan sát Luna và Selene hiện là OBSERVE_ONLY . Chúng có thể nhìn interface, RX/TX, address, route, socket, listener, process, container và network metadata trong phạm vi cho phép. Chúng không có quyền tự ban IP, tự mở firewall, tự nâng quyền hay tự che evidence. Nếu sau này Sentinel tham gia enforcement, phần hành động phải nằm ở một lớp deterministic, có policy và quyền rõ ràng bên ngoài reasoning của agent. Tôi muốn chúng trở thành một giác quan, không phải một ông bảo vệ tự ý hành động Mục tiêu dài hạn của Sentinel là hiểu được hành vi: đâu là automation bình thường, đâu là một chuỗi recon giống tấn công, đâu là lỗi topology, đâu là traffic thật sự tới từ host hay container phía sau NAT. Nếu Luna và Selene giúp tôi nhìn một hệ thống giống cách hai mắt tạo chiều sâu — mỗi bên nhìn hơi khác, rồi một decision layer mới tổng hợp — thì hai con đã đáng để nuôi.

### Inside LightBI’s 5.6 MB Micro Brain

URL: https://thaiduy.digital/writing/micro-brain-inside-5mb-index
Published: 2026-09-19T08:38:53.383Z
Updated: 2026-09-19T08:38:53.383Z
Tags: micro-brain, lightbi, architecture

English title: Inside LightBI’s 5.6 MB Micro Brain
English summary: No embedding API and no runtime LLM call. MB combines BM25, TF-IDF/LSA and RRF, then hands retrieval evidence back to the governed pipeline.
English text: Micro Brain sounds like a tiny model. V1 is closer to a deterministic semantic retrieval library. It runs locally, requires no embedding API, and identical source plus compiler settings must reproduce the same logical index. 248 cards become 1,118 retrieval units The current source contains 248 cards: 225 canonical bridges, 23 open concepts, 25 guarded formulas, 159 relations and 56 confusion pairs. The compiler splits cards into definition, terminology, positive, negative, relation and formula/evidence units. The current index contains 1,118 units and 2,048 sparse features. The compiled JSON is about 5.63 MB and roughly 1.73 MB gzipped. Each query is retrieved twice BM25 preserves exact business terminology. A TF-IDF/LSA projection provides a deterministic dense view for semantic interpolation. RRF merges ranks, not confidence BM25 and cosine similarity are not pretending to share one confidence scale. Reciprocal Rank Fusion only decides which concepts should be inspected first. RRF = 1 / (k0 + sparse_rank) + 1 / (k0 + dense_rank) Retrieval similarity remains provenance, never semantic authority. The query is not allowed to know the answer File names, corpus IDs, expected answers and hidden customer dictionaries are forbidden from the query signature. Bounded representative values remain evidence witnesses, not full-column truth. Determinism is part of the product The compiler records corpus, tokenizer, vector algorithm, dimensions and hashes. Reproducibility matters more here than mysterious “smartness.” The value of this 5.6 MB brain is not that it can decide everything. It is that it can recall more while still handing authority back to the governed pipeline.

Vietnamese title: Bên trong một bộ não 5,6 MB của LightBI
Vietnamese summary: Không có API embedding, không gọi LLM lúc runtime. MB ghép BM25, TF-IDF/LSA và RRF để tìm khái niệm gần nhất rồi trả evidence về cho hệ thống chính xử lý.
Vietnamese text: Micro Brain nghe tên hơi giống một model nhỏ. Thực tế V1 của nó gần với một thư viện tra cứu có trí nhớ ngữ nghĩa hơn. Điều thú vị là nó không cần mạng để chạy, không cần embedding service, và cùng một corpus + compiler phải tạo lại đúng cùng một logical index. 248 cards không đi thẳng vào runtime Knowledge source hiện có 248 cards. Trong đó có 225 bridge tới canonical signal đã tồn tại, 23 open concepts, 25 guarded formulas, 159 relations và 56 confusion pairs. Compiler không nhét nguyên từng card vào một “vector”. Nó tách card thành các semantic unit nhỏ hơn: definition, terminology, positive clues, negative clues, relation và formula/evidence requirement. Kết quả hiện tại là 1.118 retrieval units và 2.048 sparse features . File compiled index khoảng 5,63 MB; gzip còn khoảng 1,73 MB. Một query được nhìn theo hai cách Khi LightBI gặp một physical column, nó tạo query signature từ những thứ đã có bằng chứng: header token, type, shape, uniqueness/cardinality, vài categorical value đại diện và context từ sibling fields. Sau đó MB chạy hai đường song song. Đường sparse: BM25 BM25 rất giỏi khi từ khóa kinh doanh thực sự xuất hiện: abbreviation, tên gọi đặc thù, cụm từ ngắn. Nó giữ lợi thế của exact terminology. Đường dense: TF-IDF + LSA Cùng corpus sparse được chiếu qua truncated SVD để tạo latent semantic space. Query cũng được chiếu vào không gian đó rồi so cosine với document vectors. Nó không “hiểu” theo kiểu một LLM. Nhưng nó có thể tìm được sự gần nhau mà exact token search dễ bỏ sót. Hai score không được trộn thành một confidence giả BM25 score và cosine similarity không cùng ý nghĩa. Tôi không muốn nhân chia vài con số rồi gọi kết quả là “87% chắc chắn”. MB chỉ dùng Reciprocal Rank Fusion để hợp nhất thứ hạng: RRF = 1 / (k0 + sparse_rank) + 1 / (k0 + dense_rank) RRF chỉ trả lời “concept nào nên được xem trước”. Nó không trả lời “concept nào đã được chứng minh”. Query không được biết đáp án Một rule khá quan trọng là query builder không được nhét file name, corpus ID, expected answer hay customer dictionary bí mật vào retrieval signature. Nếu benchmark pass nhờ những shortcut đó thì nó chỉ đang học đề kiểm tra. Representative values cũng chỉ là witness có giới hạn. Sample không tự biến thành full-column truth. Determinism là một tính năng sản phẩm Compiler lưu version của corpus, tokenizer, vector algorithm, dimension và hash. Cùng source/config phải tạo cùng index identity. Ngay cả dấu của SVD cũng được canonicalize để build không trôi theo một nghiệm toán học tương đương nhưng khác byte. Với một hệ thống dùng retrieval để gợi ý meaning cho dữ liệu kinh doanh, khả năng tái tạo kết quả quan trọng hơn việc “thông minh khó đoán”. 5,6 MB này không phải một bộ não toàn năng Nó chỉ là một lớp recall tốt hơn từ điển. Phần giá trị nhất vẫn nằm ở cách LightBI từ chối cho retrieval rank biến thành semantic confidence, rồi lại từ semantic confidence biến thành quyền tính toán. MB nhỏ vì nó chỉ làm đúng một việc. Tôi thích nó ở điểm đó.

### Micro Brain Exists Because a Registry Cannot Know the Whole World

URL: https://thaiduy.digital/writing/micro-brain-why-lightbi-needed-one
Published: 2026-09-19T08:38:53.280Z
Updated: 2026-09-19T08:38:53.280Z
Tags: micro-brain, lightbi, data-trust

English title: Micro Brain Exists Because a Registry Cannot Know the Whole World
English summary: LightBI needs to recognize concepts that were never hardcoded, but I did not want that flexibility to become permission to guess.
English text: LightBI's Semantic Registry is very good at one thing: recognizing business concepts that the product already knows how to describe precisely. The problem is that real businesses do not live inside a finite dictionary. New industries, local terminology, abbreviations and long-tail concepts keep appearing. A registry should not become an infinite pile of aliases I wanted a softer understanding layer that could connect terms and relations without turning every new dataset into another hardcoded exception. That became the Micro Brain. It is not a small chatbot Micro Brain is a local deterministic retrieval layer over structured knowledge. It broadens semantic candidate discovery without replacing the canonical registry, resolver, grain gates, readiness, metric preflight or runtime authority. The Brain may suggest where to look. It does not get to declare truth on behalf of evidence. Negative knowledge matters as much as similarity Cards contain positive clues, negative clues, confusion pairs and relations. COD amount is not carrier revenue by default. Stock value is not COGS. Bank inflow is not automatically revenue. Recall and authority remain separate Micro Brain → candidate clue Semantic Registry → canonical identity Resolver → evidence-bound meaning Grain/readiness → safety Metric preflight → execution authority An upstream hypothesis can be restricted downstream. It cannot grant downstream authority by itself. Open concepts are allowed to stay open If the Brain recognizes a useful concept that has no governed canonical bridge yet, LightBI keeps it open instead of forcing it into the nearest supported signal. The goal is not to make LightBI answer everything. The goal is to understand more while preserving the ability to say “not enough evidence.”

Vietnamese title: Micro Brain ra đời vì một registry không thể biết hết thế giới
Vietnamese summary: LightBI cần hiểu những khái niệm chưa từng được hardcode, nhưng tôi không muốn đổi sự linh hoạt đó lấy một hệ thống được quyền đoán.
Vietnamese text: Semantic Registry của LightBI từng giải quyết rất tốt một bài toán: nếu mình đã biết trước một khái niệm kinh doanh, hãy mô tả nó thật rõ để hệ thống nhận ra nó một cách ổn định. Revenue có alias nào. Customer ID thường có shape ra sao. Inventory snapshot khác flow metric ở điểm nào. Những thứ đã biết thì registry làm rất tốt. Rồi một vấn đề xuất hiện rất tự nhiên: doanh nghiệp không sống trong một bộ từ điển hữu hạn . Registry càng lớn càng bắt đầu giống một cuốn từ điển vô tận Mỗi ngành có một đống thuật ngữ riêng. Cùng một ý nghĩa có thể xuất hiện dưới tên viết tắt, tiếng Việt, tiếng Anh, tên nội bộ hoặc một cách gọi rất địa phương. Nếu mỗi lần gặp một file lạ lại thêm vài chục alias vào registry, sớm muộn registry sẽ biến thành một đống ngoại lệ. Tôi cần một lớp hiểu mềm hơn: biết rằng COD Amount , tiền thu hộ và một vài tín hiệu vận hành khác có quan hệ với nhau, nhưng cũng phải biết COD không mặc định là doanh thu của hãng vận chuyển . Đó là chỗ Micro Brain xuất hiện. Tôi không muốn nhét một LLM vào giữa đường rồi gọi đó là hiểu dữ liệu Cách dễ nhất là gửi schema vào một model lớn rồi hỏi “cột này là gì?”. Nó có thể trả lời khá hay, nhưng như vậy LightBI sẽ mất ba thứ tôi muốn giữ: local-first, khả năng lặp lại kết quả và provenance rõ ràng. Micro Brain vì vậy không phải một chatbot thu nhỏ. Nó là một kho kiến thức có cấu trúc, chạy local, được compile thành retrieval index và chỉ làm một việc: mở rộng vùng tìm kiếm cho semantic candidates . Brain được quyền gợi ý nơi cần nhìn. Nó không được quyền tuyên bố sự thật thay cho evidence resolver. Điều tôi thích nhất là negative knowledge Nếu một hệ semantic chỉ học “X giống cái gì”, nó rất dễ trở nên nhiệt tình quá mức. Vì vậy mỗi knowledge card của MB không chỉ chứa positive clues mà còn có negative clues, confusion cases và relation kiểu distinct_from . Một vài ví dụ nghe rất đời thường: COD amount không mặc định là carrier revenue. Stock value không mặc định là COGS. Bank inflow không mặc định là revenue. Unit price không phải revenue. Inventory snapshot không được cộng ngang thời gian như một flow metric. Những câu “không phải” này nhiều khi có giá trị hơn một danh sách alias dài. MB mở recall, registry giữ identity Kiến trúc tôi chốt cho LightBI cố tình lệch quyền lực: Micro Brain → candidate / relation clue Semantic Registry → canonical identity Resolver → evidence-bound meaning Grain + readiness → safety Metric preflight → execution authority Một tầng phía trước có thể gợi ý. Tầng phía sau có thể hạn chế hoặc bác bỏ. Nhưng một gợi ý ở phía trước không bao giờ được nhảy cóc để tự cấp quyền cho phép tính. Open concept cũng là một kết quả hợp lệ Có những khái niệm MB hiểu được nhưng LightBI chưa có canonical signal tương ứng. Tôi không muốn ép nó vào “thứ gần nhất” chỉ để downstream code dễ xử lý. Nếu concept hợp lý nhưng chưa có bridge chính thức, nó được giữ là open concept. Hệ thống có thể nói “tôi nhận ra thứ này”, nhưng vẫn tách biệt với câu “LightBI chính thức hỗ trợ phép phân tích nào từ nó”. Mong muốn cuối cùng không phải để MB trả lời mọi thứ Tôi muốn LightBI có thể mở một file thuộc ngành chưa từng được hardcode, vẫn nhận ra được vài cấu trúc có nghĩa, giải thích được vì sao nó nghĩ vậy và biết giới hạn của chính mình. Nếu MB giúp sản phẩm đi xa hơn mà không làm mất khả năng abstain, nó đã hoàn thành đúng vai trò.

### Let AI Operate a Computer, but Keep the Final No on the Device

URL: https://thaiduy.digital/writing/light-remote-device-policy-final-no
Published: 2026-09-19T08:20:36.126Z
Updated: 2026-09-19T08:20:36.126Z
Tags: light-remote, security, local-first

English title: Let AI Operate a Computer, but Keep the Final No on the Device
English summary: A useful remote system is not just one that can execute commands. It must know which device is targeted, who authorized it, and still let that device say no.
English text: Giving an AI access to a computer is both useful and uncomfortable. I still want the agent to do real work: inspect repositories, edit files, run tests, open terminals, recover jobs and operate across multiple devices. Making the agent deliberately weak would also make the remote system less useful. The better question is where authority should live. A server-side yes is not the final answer Light Remote has several permission layers. The account controls product capabilities. A durable session binds work to one explicit device. The server routes requests to that target. The final deny still belongs to device-local policy. An account may be entitled to a capability while the device refuses systemctl , package managers, Docker, LXD or other privileged operations. I want the final “no” to live where the consequences occur. The cloud can grant capability. The device keeps the final deny. Do not silently switch targets A remote system can be tempted to “help” when the requested target is offline by running on another available machine. Light Remote intentionally does not do that. A durable session is bound to one device. If that target is unavailable, the request should fail or recover on the same target. Success on the wrong machine is usually worse than failure on the right one. Policy denials still need to be understandable Recent Activity exposes a sanitized view of sessions, jobs, terminal events, routing and policy. A denied job can be explained as a device-local policy denial without replaying raw commands, tokens or sensitive stderr into the conversation. Observability should explain behavior without becoming a new data-leak path. A real terminal has real side effects PTY and ConPTY sessions can run interactive editors, REPLs and installers. Their lifecycle therefore stays explicit: start, input, output, resize, signal and stop, all bound to the same session and device. The reviewer sandbox is not a fake demo For plugin review, I did not want a miniature MCP server returning fixture responses. The reviewer environment runs the same control-plane and runtime paths as the product, but with isolated accounts and devices. It includes Main/Fleet behavior, Local Wall, signed device channels, filesystem/Git operations, PTY, activity and policy. The reviewer account cannot enumerate production users, devices, files, keys or logs. Safe operations are allowed while privileged administration is deliberately denied, so review can exercise both success and refusal paths. Destructive actions should look destructive Set Main is consequential but reversible. Revoke and Remove are destructive lifecycle operations. Giving them separate tools, schemas and annotations makes intent clearer than hiding them behind a generic “manage device” action. I do not need the AI to be harmless; I need boundaries to stay real Agents will keep getting more capable. Trusting them to always infer the right boundary is not enough. Account OAuth, local enrollment approval, explicit targets and device-local policy provide boundaries that do not depend on the agent being cautious.

Vietnamese title: Cho AI điều khiển máy tính, nhưng quyền từ chối vẫn phải nằm ở máy
Vietnamese summary: Remote tốt không chỉ là chạy được lệnh. Nó phải biết đang chạy trên máy nào, ai đã cho phép, và quan trọng nhất: máy đó vẫn có quyền nói không.
Vietnamese text: Cho một AI quyền chạm vào máy tính nghe vừa tiện vừa đáng sợ. Thực tế tôi vẫn muốn nó làm được nhiều việc: đọc repo, sửa file, chạy test, mở terminal, theo dõi job, thậm chí thao tác qua nhiều máy khác nhau. Nếu cứ sợ rồi khóa mọi thứ thì remote chẳng còn nhiều giá trị. Vấn đề không phải là làm AI yếu đi. Vấn đề là đặt quyền lực đúng chỗ. Server nói “được” chưa phải là câu trả lời cuối cùng Trong Light Remote có nhiều lớp quyền. Account quyết định user có capability nào. Session quyết định đang làm việc với device nào. Server route request tới target đó. Nhưng lớp cuối cùng vẫn là policy trên chính thiết bị. Nghĩa là server có thể cho phép một loại thao tác, account có thể có plan đủ cao, nhưng device vẫn có thể từ chối systemctl , package manager, Docker, LXD hay một nhóm lệnh privileged khác. Tôi muốn câu “không” cuối cùng nằm ở nơi chịu hậu quả trực tiếp của lệnh đó. Cloud có thể cấp quyền. Device vẫn giữ quyền từ chối. Không được tự đổi target cho tiện Một lỗi thiết kế remote rất dễ mắc là cố giúp người dùng quá mức. Ví dụ target A offline, hệ thống thấy target B đang online nên chạy qua B “cho thành công”. Light Remote cố tình không làm vậy. Mỗi durable session gắn với một device cụ thể. Nếu target không còn sẵn sàng, request phải thất bại hoặc chờ recovery đúng target. Không có silent fallback. Nghe hơi cứng, nhưng với thao tác máy tính thì “thành công trên nhầm máy” thường tệ hơn “thất bại trên đúng máy”. Policy denial cũng phải nhìn hiểu được Khi device từ chối một thao tác, agent cần biết chuyện gì đã xảy ra mà không cần được xem mọi chi tiết nhạy cảm. Recent Activity vì vậy chỉ trả một bản đã sanitize: loại event, trạng thái, capability cần thiết, cwd phù hợp và ghi chú kiểu Denied by local device policy . Nó không cần phun nguyên command, token hay stderr chứa bí mật lên conversation. Mục tiêu là đủ thông tin để giải thích, không đủ thông tin để vô tình biến observability thành một kênh rò dữ liệu. Terminal thật thì side effect cũng thật PTY/ConPTY là một trong những capability tôi thích nhất của Light Remote, nhưng cũng là phần phải đối xử nghiêm túc nhất. Một shell tương tác có thể chạy editor, REPL, installer hay bất kỳ chương trình nào người dùng mở. Vì vậy terminal lifecycle được xem là thao tác có side effect thật. Start, input, signal và stop đều gắn với session và target rõ ràng. Không có khái niệm một terminal “trôi” qua device khác chỉ vì route thay đổi. Reviewer sandbox không phải một bản demo giả Khi chuẩn bị Light Remote cho review plugin, tôi không muốn dựng một MCP server nhỏ chỉ biết trả dữ liệu giả. Reviewer fixture dùng chính control plane và runtime của sản phẩm, nhưng nằm trong một môi trường cô lập. Nó có một Main, một leaf, Local Wall, Fleet, signed device channel, session, job, filesystem, Git, PTY, activity và policy như sản phẩm thật. Khác biệt là account reviewer chỉ nhìn thấy các device thử nghiệm của nó; không có production user, key, file hay log nào được copy vào. Policy của reviewer còn cố tình cho phép một số thao tác vô hại và chặn nhóm privileged. Nhờ vậy review có thể kiểm tra cả đường thành công lẫn đường bị từ chối. Destructive action phải có tên của nó Set Main là consequential nhưng có thể đảo ngược. Revoke và Remove thì destructive hơn rất nhiều. Tôi không muốn ba thao tác này bị trộn vào một tool chung tên kiểu manage_device . Khi hành động nguy hiểm có tool riêng, schema riêng và annotation riêng, agent và người dùng đều dễ hiểu mình sắp làm gì hơn. Tôi không muốn AI phải “ngoan”, tôi muốn hệ thống có ranh giới Một agent giỏi sẽ ngày càng làm được nhiều việc. Trông chờ nó lúc nào cũng tự đoán đúng giới hạn là một chiến lược yếu. Tôi thích thiết kế mà ngay cả khi agent muốn đi xa hơn, device vẫn có lớp policy độc lập để nói không. Account vẫn cần OAuth. Enrollment vẫn cần local approval. Target vẫn phải explicit. Destructive lifecycle vẫn cần ý định rõ. Như vậy AI có thể mạnh lên mà trust boundary không phải mạnh lên theo kiểu “tin nó hơn”.

### Teaching a Machine to Understand Data Without Letting It Guess

URL: https://thaiduy.digital/writing/lightbi-understand-without-guessing
Published: 2026-09-19T08:20:36.032Z
Updated: 2026-09-19T08:20:36.032Z
Tags: lightbi, local-first, architecture

English title: Teaching a Machine to Understand Data Without Letting It Guess
English summary: I want LightBI to become smarter, but the smarter it gets, the more important it becomes for the system to know when to stop and say there is not enough evidence.
English text: I want LightBI to understand more kinds of operational data. That sounds like an obvious goal, but semantic coverage creates a dangerous temptation: once the system becomes good at recognizing patterns, it becomes easy to let recognition turn into unsupported certainty. A large part of LightBI therefore exists not to answer more questions, but to know when to stop. Recognizing a concept is only the beginning A field called DeliveryFee is fairly easy to interpret. Amt is harder. Value2 says almost nothing without its neighbors and actual values. The Semantic Registry provides governed vocabulary and rules. The Micro Semantic Brain broadens recall with synonyms, conceptual relationships and cross-domain bridges. But it is not the final authority. It can say “look here.” Governed evidence still decides whether anything may run. Suggestion and execution permission are different things Soft semantic recall can surface a candidate that rigid rules might miss. Resolver logic, grain, readiness and metric preflight then decide whether the candidate has enough evidence to become an executable action. If the evidence does not hold, keeping the result unknown is often the correct behavior. Unknown is not impressive in a demo, but it is useful in a real product. Sample to understand, full data to calculate LightBI intentionally uses bounded samples to understand large sources quickly. That works well for schema, rough distributions and semantic context. It does not mean the sample has authority to answer every analytical question. We caught a case where a sampled period comparison suggested roughly -15% while the full dataset was above +6%. Both calculations were mechanically correct for their input. Only one input scope was appropriate for the question. Samples can support context and planning. Full source scope is required when the governed calculation needs the complete dataset. The same label does not make the same entity Multi-file analysis has the same problem. Two files containing a Customer field do not automatically share an identity contract. Two fields called Revenue do not prove compatible grain or reporting periods. LightBI therefore does not treat matching labels as permission to join. A Focus Subject can collect evidence across sources while preserving source identity and disclosure. Deep BA should not tell a story beyond the evidence Deep BA is useful because business users rarely need another KPI tile. They need a structured investigation: what happened, where, what might be driving it, what is unusual and what should be checked next. That narrative becomes dangerous if evidence is detached from it. Findings should retain source scope, confidence, limitations and drill-through into the rows that produced them. AI can help express a governed finding more clearly. It should not upgrade an uncertain finding into a confident conclusion. Getting smarter by knowing when to stop I still want LightBI to learn more domains, synonyms and relationships. I simply do not want broader recall to become a system that always has an answer. For business data, knowing when to stop is also a form of intelligence.

Vietnamese title: Dạy máy hiểu dữ liệu mà không cho nó quyền đoán
Vietnamese summary: Tôi muốn LightBI thông minh hơn, nhưng càng thông minh thì nó càng phải biết lúc nào nên dừng và nói “chưa đủ bằng chứng”.
Vietnamese text: Tôi muốn LightBI hiểu được nhiều kiểu dữ liệu hơn. Đó là một mục tiêu nghe rất hiển nhiên cho một công cụ phân tích. Nhưng càng mở rộng semantic knowledge, tôi càng gặp một nghịch lý: nếu cho hệ thống quyền “thông minh” quá dễ dàng, nó sẽ bắt đầu đoán những thứ mà dữ liệu chưa hề chứng minh. Vì vậy một phần khá lớn của LightBI không phải để làm nó trả lời nhiều hơn. Nó tồn tại để dạy hệ thống biết lúc nào không nên trả lời tiếp . Nhận ra một khái niệm chỉ là bước đầu Một cột tên DeliveryFee khá dễ đoán là phí giao hàng. Một cột tên Amt thì khó hơn. Một cột tên Value2 gần như chẳng nói gì nếu không nhìn dữ liệu và các cột xung quanh. Semantic Registry của LightBI chứa vocabulary và rule để nhận diện những tín hiệu như revenue, quantity, customer, inventory, delay hay delivery fee. Sau đó Micro Semantic Brain bổ sung một lớp recall mềm hơn: synonym, quan hệ khái niệm, bridge giữa domain và những dấu hiệu thường gặp trong dữ liệu thật. Nhưng Micro Brain không được làm quan tòa. Nó có thể nói “hãy nhìn chỗ này”. Quyết định cuối cùng vẫn phải đi qua logic có bằng chứng. Tôi tách “gợi ý” khỏi “quyền được chạy” Đây là một nguyên tắc tôi thấy ngày càng quan trọng khi dùng AI trong phần mềm: khả năng đề xuất và quyền thực thi không nên là cùng một thứ. Micro Brain có thể làm recall tốt hơn, tìm ra một candidate mà rule cứng chưa thấy ngay. Sau đó resolver, grain logic, readiness và metric preflight mới quyết định candidate đó có đủ cơ sở để trở thành một hành động hay không. Nếu bằng chứng không khớp, kết quả tốt nhất đôi khi là giữ nguyên trạng thái unknown. Unknown không đẹp trong demo, nhưng nó rất hữu ích trong sản phẩm thật. Sample để hiểu, full data để tính Một bài học khác tới từ chính cách LightBI xử lý file lớn. Tôi từng chủ động giới hạn sample khoảng một nghìn dòng để đọc ngữ cảnh nhanh. Quyết định đó vẫn hợp lý cho semantic discovery: nhìn schema, phân bố sơ bộ, kiểu dữ liệu và vài tín hiệu chính không nhất thiết phải scan toàn bộ vài triệu dòng. Nhưng có một thời điểm Deep BA dùng luôn sample đó cho một phép so sánh xu hướng. Sample nói giảm khoảng 15%, còn full dataset lại tăng hơn 6%. Cả hai con số đều được code tính “đúng” trên tập dữ liệu mà nó nhận. Chỉ có điều một tập không đủ thẩm quyền để trả lời câu hỏi. Từ đó ranh giới trở nên rõ hơn: Sample có thể giúp hiểu ngữ cảnh và lập kế hoạch. Full source scope phải được dùng khi phép tính yêu cầu toàn bộ dữ liệu. Đây là một ví dụ khá đẹp về chuyện performance optimization không được âm thầm biến thành business logic. Cùng tên không có nghĩa là cùng một thực thể Multi-file cũng dạy tôi bài tương tự. Hai file cùng có cột Customer không tự động có nghĩa chúng đang nói về cùng một khách hàng theo cùng một identity rule. Hai sheet cùng ghi Revenue cũng không chứng minh chúng có cùng grain hay cùng kỳ báo cáo. Vì vậy LightBI không coi “cùng label” là vé thông hành để JOIN. Một Focus Subject có thể gom evidence từ nhiều nguồn, nhưng mỗi nguồn vẫn giữ identity riêng và disclosure phải nói rõ phạm vi nào đang được dùng. Deep BA không nên kể chuyện vượt quá dữ liệu Tôi khá thích ý tưởng Deep BA vì người dùng thường không cần thêm một KPI card; họ cần một câu trả lời có cấu trúc: chuyện gì xảy ra, ở đâu, driver nào đáng xem, có gì bất thường và bước tiếp theo là gì. Nhưng chính dạng narrative này càng dễ tạo ảo giác chắc chắn nếu evidence không được giữ lại. Vì vậy mỗi insight tốt phải kéo theo source scope, confidence, limitation và khả năng drill xuống dữ liệu đã tạo ra nó. AI có thể giúp diễn đạt một finding dễ hiểu hơn. Nó không nên tự biến một finding chưa đủ bằng chứng thành kết luận. Thông minh hơn bằng cách biết dừng Tôi vẫn muốn LightBI học thêm domain, thêm synonym, thêm relation và hiểu được nhiều file bẩn hơn. Nhưng tôi không muốn đổi sự mở rộng đó lấy một hệ thống luôn có câu trả lời. Nếu phải chọn, tôi thích một sản phẩm thỉnh thoảng nói “chưa biết” hơn một sản phẩm luôn trả lời rồi để người dùng tự phát hiện nó đã đoán quá xa. Với dữ liệu kinh doanh, biết dừng đúng chỗ cũng là một dạng thông minh.

### Light Remote Started Because I Was About to Lose My Usual Remote

URL: https://thaiduy.digital/writing/light-remote-from-bridge-to-product
Published: 2026-09-19T08:20:35.939Z
Updated: 2026-09-19T08:20:35.939Z
Tags: light-remote, systems, architecture

English title: Light Remote Started Because I Was About to Lose My Usual Remote
English summary: I originally needed ChatGPT to run a few commands on a VPS. A few iterations later, that temporary bridge had grown into a device system with Walls, Fleet, real PTY sessions and local policy.
English text: Light Remote did not begin as a product plan. It began with a practical problem: I was used to having a remote path that let ChatGPT inspect a VPS, read files, run commands and help fix things. That path was becoming constrained, and I did not want to go back to copying commands from chat into a terminal and pasting output back. The first idea was almost embarrassingly small: build a bridge that could relay a command to my VPS. At first, executing one command was enough The early bridge only needed a few primitives. Read a file, run a shell command, return the result. It immediately made remote work less manual. Then the requirements grew. I needed file search, Git status and diffs, managed processes, long-running jobs, interactive terminals, Ctrl-C, resize, explicit device targeting and a way to explain policy denials. At that point, “an API that runs shell commands” was no longer an honest description. A shell is not a product boundary Light Remote gradually split common work into meaningful capabilities: filesystem, search, Git, process, session, job and terminal. Generic exec still exists, but it is not supposed to be the universal hammer. Specific tools make the workflow easier to understand and easier to govern. Reading a file should use a file operation. Interactive software should use a real PTY. Local Wall is where a new device starts A new device begins locally. Its Local Wall creates the one-time pairing code, the remote account creates the matching approval request, and the device owner approves locally. The MCP cannot mint its own A code or bypass that step. Remote can ask to come in. The first door still opens from the device. Main and Fleet appeared when one machine stopped being enough Once ARM, AMD, Windows and other machines joined the picture, target identity became mandatory. Main carries Fleet authority, other devices keep their own Local Wall, and moving Main has to invalidate stale authority on the previous device. A session never silently falls back to another machine. If the selected device is unavailable, the operation should fail there instead of succeeding somewhere surprising. A terminal has to be a real terminal For interactive work, a command box is not enough. Light Remote supports a real PTY or ConPTY lifecycle: start, input, output, resize, signal and stop. Ctrl-C is an actual terminal signal, not a decorative button. That requirement pulled in durable sessions, asynchronous jobs, recent activity and recovery behavior. The bridge slowly became a remote computing system. From a temporary bridge to a product The original bridge proved the workflow was worth building. The product that followed moved trust into clearer boundaries: OAuth at the account edge, signed outbound channels at the device edge, explicit targets for sessions and device-local policy as the final deny point. Light Remote still solves the same ordinary problem: I do not want to sit in front of every machine just to get useful work done. The difference is that the path is now explicit enough to trust.

Vietnamese title: Light Remote ra đời vì tôi sắp mất chiếc remote quen thuộc
Vietnamese summary: Ban đầu tôi chỉ cần ChatGPT gọi vài lệnh trên VPS. Vài vòng sau, cái cầu tạm đó biến thành một hệ thống có device, Wall, Fleet, PTY và policy riêng.
Vietnamese text: Light Remote không bắt đầu từ một kế hoạch sản phẩm. Nó bắt đầu từ một vấn đề rất thực dụng: tôi đang quen dùng một công cụ remote để ChatGPT chạm vào VPS, đọc file, chạy lệnh và sửa vài thứ giúp tôi. Rồi con đường đó bắt đầu có giới hạn. Nếu một ngày cái remote quen thuộc không còn dùng được nữa, tôi không muốn quay lại kiểu copy lệnh từ chat, paste vào terminal, rồi copy output ngược lại. Ý tưởng đầu tiên đơn giản đến mức hơi buồn cười: dựng một cây cầu nhỏ để AI gọi lệnh vào VPS. Tôi đã nghĩ chỉ cần vậy là đủ. Ban đầu chỉ cần chạy được một lệnh Phiên bản sớm của Light Remote đúng nghĩa là một bridge. Một đầu nhận request từ bên ngoài, đầu kia chuyển nó tới máy tôi đang quản lý. Miễn là có thể đọc file, chạy shell và trả output về thì công việc đã đỡ thủ công hơn rất nhiều. Nhưng remote computing có một thói quen xấu: chỉ cần nó chạy được vài lệnh, mình lập tức muốn nó làm thêm mọi thứ mà một người ngồi trước máy có thể làm. Đọc một file chưa đủ. Tôi cần tìm nhiều file, xem Git diff, theo dõi process, chờ job chạy lâu, mở terminal tương tác, gửi Ctrl-C, resize PTY, chọn đúng máy trong nhiều máy và biết vì sao một lệnh bị từ chối. Tới lúc đó, “một API chạy shell” không còn là mô tả đúng nữa. Rồi shell không còn đủ Tôi bắt đầu tách những việc thường ngày thành capability rõ ràng: filesystem, search, Git, process, session, job, terminal. Generic exec vẫn còn, nhưng không nên là cây búa dùng cho mọi thứ. Nếu chỉ muốn đọc một file, công cụ nên đọc file. Nếu muốn xem trạng thái Git, gọi đúng thao tác Git. Nếu cần một chương trình tương tác thật sự, lúc đó mới dùng PTY. Điều này nghe như chuyện UX, nhưng nó tác động trực tiếp tới an toàn. Tool càng có ý nghĩa cụ thể, hệ thống càng dễ nói rõ quyền nào đang được dùng và policy nào vừa chặn nó. Local Wall là nơi bắt đầu Một quyết định tôi giữ lại từ khá sớm là: thiết bị mới phải bắt đầu từ chính thiết bị đó. Local Wall tạo mã ghép nối một lần. Account ở phía remote chỉ có thể tạo yêu cầu tương ứng. Chủ máy vẫn là người duyệt bước cuối ở local. MCP không có quyền tự đúc mã A mới rồi tự mở cửa cho chính nó. Remote có thể xin vào. Quyền mở cửa đầu tiên vẫn nằm ở máy. Tôi thích ranh giới này vì nó dễ giải thích. Dù sau này Light Remote có thêm bao nhiêu tool hay AI thông minh hơn tới đâu, enrollment vẫn không trở thành một API bí mật mà agent có thể vòng qua. Main và Fleet xuất hiện khi một máy không còn đủ Khi chỉ có một VPS, target gần như không phải vấn đề. Khi có ARM, AMD, Windows và các máy khác, chuyện “đang gọi vào máy nào?” trở thành một câu hỏi bắt buộc. Light Remote vì vậy có Main và Fleet. Main giữ quyền điều phối Fleet ở thời điểm hiện tại; các device khác vẫn có Local Wall riêng. Khi đổi Main, authority phải chuyển rõ ràng, authority cũ không được lơ lửng. Quan trọng hơn, routing không được tự tiện “thấy máy này offline thì chạy đại trên máy khác”. Một session đã gắn với device nào thì cứ ở device đó. Không có silent fallback. PTY phải là PTY thật Có một giai đoạn tôi nhận ra nhiều thứ gọi là “terminal” thực ra chỉ là command box có output dài hơn. Với các công việc tương tác, thế là chưa đủ. Light Remote cuối cùng phải có lifecycle terminal thật: start, input, output, resize, signal và stop. Trên Linux là PTY; trên Windows là ConPTY. Ctrl-C phải thật sự là Ctrl-C chứ không phải một nút giả gửi chuỗi ký tự. Khi làm tới đây, sản phẩm bắt đầu có cảm giác khác hẳn một bridge. Nó có session sống lâu, job chạy bất đồng bộ, activity để hiểu chuyện gì vừa xảy ra và một đường recovery riêng khi client hay app chính gặp vấn đề. Từ cầu tạm thành một sản phẩm Cây cầu ban đầu vẫn có giá trị. Nó giúp tôi chứng minh rằng workflow “AI → remote device” đáng để đầu tư. Nhưng càng đi tiếp, tôi càng muốn trust nằm ở những chỗ mình kiểm soát rõ hơn: OAuth ở account boundary, signed outbound channel ở device boundary, policy ở device, và session luôn có target cụ thể. Light Remote bây giờ vẫn làm việc rất cũ: giúp tôi đỡ phải tự gõ lệnh trên từng máy. Chỉ là phía dưới nó đã trở thành một hệ thống đủ nghiêm túc để tôi có thể nói: đây không còn là cái cầu tạm nữa.

### I Didn’t Want LightBI to Start With Charts

URL: https://thaiduy.digital/writing/lightbi-understand-before-chart
Published: 2026-09-19T08:20:35.836Z
Updated: 2026-09-19T08:20:35.836Z
Tags: lightbi, data-trust, systems

English title: I Didn’t Want LightBI to Start With Charts
English summary: A spreadsheet looks simple until you have to answer three questions: what each row represents, which fields are real business signals, and which calculations are actually safe.
English text: The easy part of BI is usually drawing a chart. Pick a few columns, choose a bar or line chart, add color and tooltips, and you can get something convincing in minutes. The harder question is whether the calculation underneath deserves that confidence. That changed how I think about LightBI. The useful question is no longer “which chart should I draw?” but “do I understand this data well enough to draw one safely?” Charts are the easy part A sales export may contain fields named Total , Amount , Revenue or simply Value . Names are not enough. If each row is a sale line, summing revenue may be fine. If each line repeats an order total, the same SUM can multiply revenue while the dashboard still looks perfectly reasonable. That is why row grain matters. Knowing what one physical row represents is a safety boundary, not an academic detail. If you do not know what a row represents, do not rush to aggregate what sits on that row. Recognition is not permission LightBI deliberately separates semantic recognition from execution permission. A field may have strong evidence that it represents revenue while still being unsafe to aggregate, compare across periods, or combine with another source. Before execution, the system still has to reason about grain, source scope, relationships, missing evidence and the requirements of the requested metric. Sometimes the right answer is simply: there is not enough evidence yet. Understand first, execute second Inspect the physical source. Resolve business signals with evidence. Determine grain, keys and unresolved ambiguity. Expose only supported analytical perspectives. Execute against the required source scope. Carry lineage and caveats into charts, Deep BA and exports. The interface should become simpler over time. The evidence model underneath should not become simpler by pretending difficult questions do not exist. Local-first is more than a privacy slogan Operational data often should not leave the machine just to produce a chart. Keeping analysis local also keeps source understanding and execution close to the original evidence. Product telemetry, licensing and distribution can live elsewhere without absorbing business files, column names, query results or BA findings. A useful chart keeps its evidence attached I do not want LightBI to stop at “revenue fell 6%.” The useful path continues: where did it fall, which source scope was used, what caveats remain, and which rows are behind the selected chart point? That is why drill-through, Deep BA and export keep converging on the same rule: conclusions should not be detached from the evidence that produced them. The user should not need to learn the machinery People should not have to study semantic resolution or metric preflight before opening an Excel file. Those concepts exist so the product can be safer while the user experience becomes calmer. The goal is still ordinary: open the data, understand what it says, find what matters, and carry the result into a conversation with enough evidence to defend it.

Vietnamese title: Tôi không muốn LightBI bắt đầu bằng biểu đồ
Vietnamese summary: Một file Excel nhìn có vẻ đơn giản cho đến khi phải trả lời ba câu: mỗi dòng đại diện cho gì, cột nào thật sự là chỉ số kinh doanh, và phép tính nào an toàn.
Vietnamese text: Phần dễ nhất của BI thường là vẽ một cái chart. Ném vài cột vào một thư viện trực quan hóa, chọn bar hay line, thêm màu, thêm tooltip — vài phút là có thứ nhìn khá thuyết phục. Vấn đề là một biểu đồ đẹp không nói cho mình biết phép tính phía dưới có đúng hay không. Tôi bắt đầu LightBI với một suy nghĩ khá đơn giản: nếu người dùng đã có Excel, CSV hay dữ liệu từ ERP thì công cụ nên giúp họ nhìn ra vấn đề nhanh hơn. Càng làm sâu, tôi càng thấy câu hỏi đúng không phải là “vẽ chart nào?” mà là “mình đã hiểu dữ liệu này đủ để được phép vẽ chart chưa?” . Biểu đồ là phần dễ nhất Một file bán hàng có thể có cột tên Total , Amount , Revenue hoặc chỉ đơn giản là Value . Nhìn tên cột thôi chưa đủ. Nếu mỗi dòng là một sản phẩm trong đơn hàng, việc cộng doanh thu có thể hợp lý. Nếu mỗi dòng lặp lại tổng đơn hàng cho từng sản phẩm, cộng thẳng sẽ nhân doanh thu lên vài lần mà giao diện vẫn trông rất đẹp. Vì vậy LightBI phải biết thêm một chuyện tưởng nhỏ nhưng cực kỳ quan trọng: mỗi dòng đang đại diện cho cái gì . Trong code và tài liệu tôi gọi đó là grain. Nó không phải thuật ngữ để cho có vẻ “BI”; nó là ranh giới giữa một phép tổng hợp có nghĩa và một con số nghe rất hợp lý nhưng sai. Nếu chưa biết một dòng là gì, đừng vội cộng những thứ nằm trên dòng đó. Một cột trông đúng tên chưa chắc đã được phép tính LightBI tách hai việc mà nhiều hệ thống thường trộn làm một: nhận ra ý nghĩa và cho phép thực thi . Ví dụ, một cột có thể rất giống doanh thu. Semantic layer có đủ bằng chứng để nói: “khả năng cao đây là revenue”. Nhưng chuyện đó vẫn chưa chứng minh rằng nó an toàn để SUM, so sánh theo tháng hay ghép với một file khác. Trước khi chạy, còn phải biết grain, phạm vi nguồn, quan hệ giữa các file, dữ liệu thiếu ở đâu và phép tính đang đòi những bằng chứng gì. Tôi thích cách này vì nó buộc sản phẩm phải thành thật. LightBI có thể biết một thứ là gì nhưng vẫn nói “chưa đủ bằng chứng để làm việc này” . Với tôi, câu trả lời đó tốt hơn nhiều so với một dashboard tự tin nhưng sai. Hiểu trước, chạy sau Luồng hiện tại của LightBI vì vậy trông giống một quá trình điều tra hơn là một dashboard builder: Đọc cấu trúc vật lý của nguồn dữ liệu. Tìm các tín hiệu nghiệp vụ có bằng chứng. Xác định grain, keys và những điểm còn mơ hồ. Chỉ mở các góc nhìn mà bằng chứng hiện có hỗ trợ. Khi người dùng chọn phân tích, runtime mới thực thi trên đúng phạm vi nguồn. Chart, Deep BA hay export đều phải mang theo lineage và caveat của nó. Điểm tôi muốn giữ là: giao diện có thể ngày càng đơn giản, nhưng phía dưới không được đơn giản hóa bằng cách bỏ qua những câu hỏi khó. Local-first không chỉ là câu chuyện riêng tư LightBI chạy theo hướng local-first vì dữ liệu vận hành thường không phải thứ người dùng muốn ném lên một dịch vụ lạ chỉ để có một chart. Nhưng local-first còn cho tôi một lợi ích khác: nguồn dữ liệu vẫn ở gần nơi nó được hiểu và thực thi nhất . Portal có thể quản lý account, license hay distribution. Nhưng file người dùng import, tên cột, query result và BA finding không cần trở thành telemetry. Phân tích dữ liệu và việc quản lý sản phẩm là hai ranh giới khác nhau. Cách tách đó cũng khiến kiến trúc khó hơn một chút, nhưng bù lại nó tạo ra một quy tắc rất dễ nhớ: nếu một dịch vụ không cần dữ liệu kinh doanh để hoàn thành nhiệm vụ của nó, đừng gửi dữ liệu kinh doanh tới đó. Một chart tốt phải mang theo bằng chứng Tôi không muốn LightBI chỉ trả lời “doanh thu giảm 6%”. Tôi muốn người dùng có thể đi tiếp: giảm ở đâu, phép tính dùng nguồn nào, phạm vi nào, có caveat gì, click vào một nhóm trên chart thì những dòng nào đang nằm sau nó. Đó là lý do Deep BA, drill-through và export trong LightBI cứ bị kéo ngược về cùng một nguyên tắc: kết luận không được tách khỏi bằng chứng đã tạo ra nó . Nhìn từ ngoài, chuyện này có vẻ làm sản phẩm chậm lại. Thực tế nó làm tôi đỡ phải vá một kiểu lỗi khó chịu hơn rất nhiều: hệ thống chạy đúng code nhưng trả lời sai câu hỏi kinh doanh. Cuối cùng vẫn là một công cụ cho người bình thường Tôi không kỳ vọng người dùng phải học semantic resolution, grain hay metric preflight. Nếu họ buộc phải hiểu hết những thứ đó thì sản phẩm đã thất bại ở lớp giao diện. Mục tiêu vẫn rất đời thường: mở file lên, biết dữ liệu đang nói gì, thấy chỗ nào đáng xem và có đủ tự tin để mang kết quả đi trao đổi với người khác. Chỉ khác một điều: thay vì giấu độ không chắc chắn dưới một biểu đồ đẹp, LightBI cố giữ nó trong hệ thống cho tới khi có đủ bằng chứng để đi tiếp.

### A Stack That Can Explain Itself

URL: https://thaiduy.digital/writing/a-stack-that-can-explain-itself
Published: 2026-09-18T11:23:25.880Z
Updated: 2026-09-18T12:53:14.168Z
Tags: architecture, stack, systems

English title: A Stack That Can Explain Itself
English summary: A practical look at turning live infrastructure into a readable public system surface.
English text: A technical system becomes much easier to trust when it can show what is alive, what is connected, and what changed without asking the reader to understand the machinery first. The diagram became a living surface The first version of a stack page was only a topology drawing. It could show nodes and edges, but it still asked the visitor to think like an operator. The useful shift was to make the representation follow the way people already understand physical space. The Stack should reflect runtime truth, but the reader should experience a house, rooms and objects — not a database of infrastructure. That constraint changed both the interface and the architecture behind it. Runtime discovery stayed factual; presentation became a separate layer. House → Room → Object The public Stack now uses three levels of attention: House shows the whole system and the major technical rooms. Room shows one domain such as data, network, applications or observability. Object shows one live node and the relationships that matter around it. Why the metaphor matters A metaphor is useful only when it reduces explanation cost. Here it gives navigation a natural direction: enter a room, inspect an object, then step back. The same spatial language survives every level of zoom. Runtime truth belongs outside the web The web application should not need privileged access to the host just to render a public diagram. Discovery therefore happens on the host and publishes a sanitized snapshot. The site only reads that snapshot. Docker / LXD on host | host refresh worker | sanitized Redis snapshot | public Stack | House → Room → Object This separation also means a future containerized web runtime does not need docker.sock or Docker-in-Docker simply to answer a page request. Content is part of the system The same principle now applies to publishing. Projects maps directly to the public project surface, while Writing maps directly to published long-form articles. Internal registry details stay out of the normal editorial path. The editor should disappear A writing tool is successful when the author stops noticing it. Slash commands, media, Unsplash, headings and links should feel like parts of the document rather than controls around the document. What the reader sees A clear article title and a short reason to keep reading. Publication facts without invented engagement numbers. A large feature image that establishes visual context. A readable body with code, quotes, lists and images. A table of contents that follows the current section. A thin progress line that answers one quiet question: how far am I? The next constraint The interesting part is not adding more widgets. It is keeping the system legible as more real things become connected. Every new surface should earn its place by exposing useful truth without leaking internal complexity. This sample article exists to exercise the real Writing pipeline: CMS → database → sanitized rich content → public article renderer. If the presentation feels right while scrolling, the template can become the default for every future article.

Vietnamese title: Một Stack Có Thể Tự Giải Thích Chính Mình
Vietnamese summary: Một góc nhìn thực tế về cách biến hạ tầng đang sống thành một bề mặt hệ thống công khai có thể đọc.
Vietnamese text: Một hệ thống kỹ thuật trở nên dễ tin cậy hơn rất nhiều khi nó có thể cho thấy thứ gì đang sống, thứ gì đang kết nối và điều gì vừa thay đổi mà không bắt người đọc phải hiểu máy móc phía sau trước. Từ sơ đồ thành một bề mặt sống Phiên bản Stack đầu tiên chỉ là một bản vẽ topology. Nó cho thấy node và edge, nhưng vẫn bắt người xem suy nghĩ như một operator. Bước chuyển quan trọng là biểu diễn hệ thống theo cách con người vốn hiểu không gian vật lý. Stack phải phản ánh runtime truth, nhưng người đọc nên cảm nhận một ngôi nhà, các căn phòng và những đồ vật — không phải một cơ sở dữ liệu hạ tầng. Ràng buộc đó thay đổi cả giao diện lẫn kiến trúc phía sau. Discovery vẫn giữ tính sự thật; presentation trở thành một lớp riêng. House → Room → Object Public Stack hiện có ba cấp độ chú ý: House cho thấy toàn hệ thống và các phòng kỹ thuật chính. Room cho thấy một domain như data, network, applications hoặc observability. Object cho thấy một node đang sống và các quan hệ quan trọng quanh nó. Vì sao ẩn dụ này có ích Một ẩn dụ chỉ có giá trị khi nó giảm chi phí giải thích. Ở đây, hướng điều hướng trở nên tự nhiên: bước vào phòng, chạm vào một vật, rồi bước ngược ra. Cùng một ngôn ngữ không gian tồn tại xuyên suốt mọi cấp zoom. Runtime truth nên nằm ngoài web Ứng dụng web không nên cần đặc quyền truy cập host chỉ để vẽ một sơ đồ công khai. Discovery vì vậy chạy trên host rồi xuất một snapshot đã làm sạch. Website chỉ đọc snapshot đó. Docker / LXD trên host | host refresh worker | sanitized Redis snapshot | public Stack | House → Room → Object Cách tách này cũng giúp web runtime sau này có thể đóng container mà không cần docker.sock hay Docker-in-Docker chỉ để trả lời một page request. Content cũng là một phần của hệ thống Nguyên tắc tương tự giờ áp dụng cho publishing. Projects map trực tiếp với public project surface, còn Writing map trực tiếp với các bài viết dài đã publish. Chi tiết registry nội bộ không chen vào luồng biên tập thông thường. Trình soạn thảo nên biến mất Một công cụ viết tốt là khi người viết ngừng chú ý tới công cụ. Slash command, media, Unsplash, heading và link nên có cảm giác là một phần của tài liệu chứ không phải một bảng điều khiển quanh tài liệu. Người đọc sẽ thấy gì Một tiêu đề rõ ràng và một lý do ngắn để tiếp tục đọc. Thông tin xuất bản thật, không có các con số tương tác giả. Một feature image lớn tạo ngữ cảnh thị giác. Phần thân dễ đọc với code, quote, list và image. Mục lục đi theo section hiện tại. Một đường progress mảnh trả lời câu hỏi rất nhỏ: mình đã đọc tới đâu? Ràng buộc tiếp theo Phần thú vị không nằm ở việc thêm nhiều widget. Nó nằm ở việc giữ cho hệ thống còn đọc được khi ngày càng nhiều thứ thật được kết nối. Mỗi surface mới chỉ nên tồn tại nếu nó cho thấy một sự thật hữu ích mà không làm lộ độ phức tạp nội bộ. Bài mẫu này tồn tại để chạy xuyên suốt pipeline Writing thật: CMS → database → rich content đã sanitize → public article renderer. Nếu cảm giác kéo đọc đã đúng, template này có thể trở thành mặc định cho các bài sau.
