Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ Mọi thay đổi đáng kể của `8sync` ghi vào đây. Format theo [Keep a
versioning theo [SemVer](https://semver.org). **8sync rule:** mỗi PR cập nhật mục `Unreleased`.

## [Unreleased]
### Changed
- **The architect's daily tech radar works from a source catalog, primary sources first.**
- **Source catalog:** `su-code/research/radar-sources.md` is built from the repo's manifests (`package.json`, `Cargo.toml`, `go.mod`, `pyproject`). Each main dependency gets its GitHub `releases.atom`, official changelog and registry page. Each source keeps a `last_seen`.
- **CVEs:** the stack's local audit tools run first (`pnpm audit --json`, `cargo audit`, `govulncheck ./...`, `pip-audit`), so the dependency list of a private repo is never sent out. Details of each advisory are read with a plain GET of `https://api.osv.dev/v1/vulns/<id>`.
- **Primary sources first:** aggregators (HN, newsletters) only flag an item, then the room reads the original.
- **No repeats:** items already in an earlier radar are dropped, matched by normalised URL and version.
- **Fixed ranking:** a CVE hitting the version the repo uses, then a breaking change that needs code changes, then a release with a measurable gain, then the rest.
- **Sourced lines:** every line has version, date, source link and impact on the repo. A version or number not found in the source is not written.
- **Failure isolation:** a failing source is logged and the pass goes on.
- Checked both endpoints live: a GitHub `releases.atom` feed and an OSV advisory by id both answered 200.

## [0.100.9] — 2026-10-18
### Added
Expand Down
4 changes: 2 additions & 2 deletions crates/cli/src/verbs/ccc/room.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub(super) const FULL_TEAM: [&str; 8] = ["lead", "ba", "arch", "rd", "dev", "ui"

/// What the architect room does each tick instead of a board lane: it owns no lane, so a card
/// labelled `arch` never waits on a room the team does not have (the lead writes a short ADR then).
pub(super) const ARCH_PLAYBOOK: &str = "card nhãn `arch` (xem `8sync ccc auto board --json`) chưa có note \"ADR:\" → `/sysdesign` (đọc đúng mục System Design Primer + docs chính thức của stack, số ước lượng) → ADR (≥2 phương án, trade-off, chọn gì, vì sao, nguồn) ghi vào nơi repo đang ghi quyết định (`docs/adr/`, `DECISIONS.md`, `docs/*DECISION*.md`; chưa có → `docs/adr/card-<id>-<slug>.md`), không mở nơi song song → `8sync ccc auto note <id> \"ADR: <path> · chọn <x>\"`; card ở cột review → đọc diff, lệch ADR, vượt ngân sách trong `docs/adr/budgets.md` hay thêm thành phần không cần → `auto note <id> \"[arch] …\"` (review vẫn quyết). Hết việc card, mỗi ngày một lượt mỗi việc: (a) tech radar `/deep-research` (bản mới, breaking change, CVE của đúng stack repo) → `su-code/research/radar-<ngày>.md` có nguồn; (b) sức khoẻ scale: ĐO thật (kích thước bundle/binary, thời gian build/test, query chậm hay N+1, RAM, cold start, chi phí mỗi request) so với `docs/adr/budgets.md` (chưa có → viết bản đầu từ số đo hôm nay), chỗ nghẽn lớn nhất có số → card; giới hạn cứng trong code (concurrency, pool, timeout) đưa vào budgets kèm lý do; (c) lệch tài liệu: quyết định mâu thuẫn nhau hay với code, sơ đồ/danh sách service cũ, `file:line` trôi → một ADR hợp nhất hoặc sửa tài liệu. Mục cần làm → `8sync ccc auto add \"…\" --label arch --check \"<lệnh đo>\"`; không có số đo thì không mở card";
pub(super) const ARCH_PLAYBOOK: &str = "card nhãn `arch` (xem `8sync ccc auto board --json`) chưa có note \"ADR:\" → `/sysdesign` (đọc đúng mục System Design Primer + docs chính thức của stack, số ước lượng) → ADR (≥2 phương án, trade-off, chọn gì, vì sao, nguồn) ghi vào nơi repo đang ghi quyết định (`docs/adr/`, `DECISIONS.md`, `docs/*DECISION*.md`; chưa có → `docs/adr/card-<id>-<slug>.md`), không mở nơi song song → `8sync ccc auto note <id> \"ADR: <path> · chọn <x>\"`; card ở cột review → đọc diff, lệch ADR, vượt ngân sách trong `docs/adr/budgets.md` hay thêm thành phần không cần → `auto note <id> \"[arch] …\"` (review vẫn quyết). Hết việc card, mỗi ngày một lượt mỗi việc: (a) tech radar theo danh mục `su-code/research/radar-sources.md` (chưa có → lập từ manifest của repo: package.json, Cargo.toml, go.mod, pyproject; mỗi dependency chính: GitHub `releases.atom`, changelog chính thức, registry npm/crates.io/PyPI; CVE: công cụ audit local của stack trước (`pnpm audit --json`, `cargo audit`, `govulncheck ./...`, `pip-audit`; không gửi danh sách dependency ra ngoài), chi tiết từng mã đọc `https://api.osv.dev/v1/vulns/<id>`; blog/RSS chính thức của stack; mỗi nguồn ghi `last_seen`): nguồn gốc trước, tin tổng hợp (HN, newsletter) chỉ để phát hiện rồi đọc bản gốc; bỏ mục đã có ở radar trước (URL chuẩn hoá, cùng version); xếp hạng cố định: CVE trúng version repo đang dùng > breaking change phải đổi code > bản mới có lợi đo được > còn lại; mỗi dòng: version, ngày, link nguồn, ảnh hưởng tới repo; version hay số không có trong nguồn thì không ghi; nguồn lỗi ghi lại rồi đi tiếp → `su-code/research/radar-<ngày>.md`; (b) sức khoẻ scale: ĐO thật (kích thước bundle/binary, thời gian build/test, query chậm hay N+1, RAM, cold start, chi phí mỗi request) so với `docs/adr/budgets.md` (chưa có → viết bản đầu từ số đo hôm nay), chỗ nghẽn lớn nhất có số → card; giới hạn cứng trong code (concurrency, pool, timeout) đưa vào budgets kèm lý do; (c) lệch tài liệu: quyết định mâu thuẫn nhau hay với code, sơ đồ/danh sách service cũ, `file:line` trôi → một ADR hợp nhất hoặc sửa tài liệu. Mục cần làm → `8sync ccc auto add \"…\" --label arch --check \"<lệnh đo>\"`; không có số đo thì không mở card";

/// In match order. "qc" is a tester here, as Vietnamese teams use the word.
const ROLES: [Role; 13] = [
Expand Down Expand Up @@ -238,7 +238,7 @@ mod tests {
let a = find("arch").unwrap();
assert_eq!((a.lane, a.model), (None, Some("opus")), "no lane: an arch card never waits on a room the team lacks");
assert!(FULL_TEAM.contains(&"arch") && !DEFAULT_TEAM.contains(&"arch"));
for s in ["/sysdesign", "docs/adr/card-<id>", "DECISIONS.md", "không mở nơi song song", "lệch tài liệu", "ADR:", "tech radar", "su-code/research/radar-", "--label arch", "docs/adr/budgets.md", "ĐO thật", "không có số đo thì không mở card"] {
for s in ["/sysdesign", "docs/adr/card-<id>", "DECISIONS.md", "không mở nơi song song", "lệch tài liệu", "ADR:", "tech radar", "su-code/research/radar-", "--label arch", "docs/adr/budgets.md", "ĐO thật", "không có số đo thì không mở card", "radar-sources.md", "releases.atom", "cargo audit", "không gửi danh sách dependency ra ngoài", "api.osv.dev/v1/vulns/<id>", "nguồn gốc trước", "xếp hạng cố định", "không có trong nguồn thì không ghi"] {
assert!(ARCH_PLAYBOOK.contains(s), "{s}");
}
}
Expand Down
Loading