Mục lục bài viết24 mục
- 1.Phạm vi vận hành và định nghĩa thuật ngữ
- 2.Tiêu chí sàng lọc và loại trừ repo
- 3.Hệ phân loại (taxonomy) theo chức năng SEO
- 4.Các ngưỡng và quy tắc phân loại đa năng
- 5.Truy vấn tìm kiếm hiệu quả trên GitHub và GitLab
- 6.Quy trình thu thập bulk và lọc trùng
- 7.Quy trình kiểm tra phụ thuộc API tĩnh (scan code)
- 8.Quy trình kiểm tra phụ thuộc API runtime trong 30 phút
- 9.Mẫu script tự động hoá quét dấu hiệu API (outline, bash + ripgrep + jq + curl)
- 10.Bảng dữ liệu tổng hợp repo và trường bắt buộc
- 11.Quy trình kiểm thử nhanh 30 phút cho mỗi repo
- 12.Phương pháp rút ra điểm mạnh thực dụng từ README, issues và thử nhanh
- 13.Kịch bản người dùng để gắn điểm mạnh với công việc cụ thể
- 14.Tiêu chí xếp hạng ưu tiên khi đưa vào bài
- 15.Cấu trúc dàn bài xuất bản cho phần tổng hợp
- 16.Kịch bản kiểm thử chéo và cập nhật định kỳ
- 17.Cảnh báo tuân thủ pháp lý và ToS khi dùng scraping
- 18.Tiêu chí rút ra "điểm mạnh thực dụng" và template viết ngắn
- 19.Kịch bản ngoại lệ khi không đủ repo cho một loại
- 20.Checklist bàn giao cho nhóm viết và biên tập
- 21.Hướng dẫn an toàn vận hành khi thử chạy repo (sandbox)
- 22.Lộ trình thực thi để gom >=30 repo hợp lệ
- 23.Ghi chú giới hạn phạm vi và nhãn [KHÔNG CHẮC]
- 24.Kết luận
Mình cung cấp khung sàng lọc, bộ lệnh grep mẫu, quy trình kiểm chứng 30 phút và mẫu bảng evidence để bạn thu thập, phân loại và xác minh các repository công cụ SEO chạy cục bộ mà không cần khóa API; kèm chỉ dẫn rõ ràng để ghi nhãn, ưu tiên và bàn giao.
Phạm vi vận hành và định nghĩa thuật ngữ
Mục này định nghĩa ranh giới vận hành cho toàn bộ khảo sát: bạn cần biết chính xác khi nào một repository được xem là "không có kết nối API" để tránh đưa nhầm công cụ phụ thuộc dịch vụ trả phí. Mình trình bày ngắn, thực dụng và có quy tắc áp dụng khi rà soát.
Repo
- Định nghĩa vận hành: một repository là toàn bộ cây mã nguồn công khai trên Git hosting (ví dụ GitHub, GitLab), bao gồm mã, tài liệu (README, docs/), ví dụ (examples/, fixtures/) và file cấu hình (Dockerfile, CI). Khi mình nói "repo" nghĩa là clone được để kiểm tra build/run cục bộ.
- Chú ý: monorepo có nhiều subproject tính từng subfolder như một repo logic nếu mỗi subfolder có entrypoint riêng.
Tool SEO
- Định nghĩa vận hành: phần mềm hoặc tập hợp script/neural pipeline mà mục tiêu chính là hỗ trợ công việc SEO. Công dụng phổ biến: crawl/thu thập dữ liệu, audit on-page, phân tích log, phân tích từ khóa, thu thập SERP, phân tích liên kết nội bộ, sinh sitemap/schema, tối ưu ảnh, đo hiệu năng. Từ "tool" ở đây nhấn mạnh tới sản phẩm có thể chạy và trả output hữu dụng (report, CSV, graph) cho workflow SEO.
- Không tính: thư viện thuần để dev tích hợp mà không có entrypoint hoặc ví dụ chạy; bài tập học tập nếu không có hướng dẫn chạy.
"Không có kết nối API" – định nghĩa vận hành (cốt lõi)
- Nguyên tắc: một repo được gắn nhãn "không có kết nối API" nếu chức năng chính của tool có thể chạy và tạo ra output hữu dụng mà không yêu cầu khóa API, client SDK của dịch vụ bên thứ ba, hoặc credential dịch vụ đám mây để hoạt động.
- Cụ thể:
- Không yêu cầu người dùng cung cấp biến môi trường kiểu APIKEY, CLIENTID/SECRET, SERVICE_ACCOUNT JSON, hoặc đăng ký tài khoản bên ngoài để chạy chức năng core.
- Không khởi tạo hay gọi SDK thương hiệu (vd. googleapis, aws-sdk, serpapi client) trong luồng thực thi mặc định để tạo output chính.
- Việc tool có thêm chế độ "enhancement" dùng API khi người dùng chủ động cung cấp key là chấp nhận được, nhưng phải rõ ràng: core functionality vẫn hoạt động khi không có key.
- Ghi chú: việc tool truy vấn trang HTML công khai bằng HTTP/HEAD hoặc dùng headless browser để render JavaScript không bị coi là "kết nối API" theo định nghĩa này, miễn là không cần khóa/credential của dịch vụ bên thứ ba.
Ngoại lệ điển hình và cách xử lý
- Ngoại lệ A – "Mixed-mode" (core offline, enhancement online): repo có core chạy cục bộ nhưng có flag kích hoạt enrichment qua API (ví dụ: enrich keyword data via paid API). Xử lý: chấp nhận repo nếu core thực tế đã được chứng minh chạy offline; khi mô tả, ghi rõ "core không cần API – enrichment có thể dùng API".
- Ngoại lệ B – "Optional SDK only for CI/tests": repo import SDK chỉ trong test/devDependencies hoặc CI để chạy demo. Xử lý: kiểm tra entrypoint và ví dụ. Nếu production entrypoint không dùng SDK, vẫn coi là không API, kèm note "SDK chỉ dùng cho tests".
- Ngoại lệ C – "Internal API endpoints": repo gọi domain api.something nhưng đó là endpoint của cùng project hoặc self-hosted service mà người dùng có thể tự deploy. Xử lý: nếu có kịch bản deploy độc lập để chạy local end-to-end, chấp nhận; nếu runtime cần service cloud trả phí, loại khỏi "không API".
- Ngoại lệ D – "Requires login to target site": tool dùng headless browser và cần tài khoản mục tiêu để thu dữ liệu. Đây là không phải API-key của bên thứ ba nhưng vẫn yêu cầu credentials người dùng. Xử lý: gắn nhãn "yêu cầu login" và không gán nhãn "không API" nếu login bắt buộc cho core.
Lưu ý quan trọng về scraping vs API
- Phân biệt căn bản:
- Scraping HTML: truy vấn trang công khai, parse HTML/DOM, thường không cần API key. Đây vẫn có rủi ro ToS, robots.txt và anti-bot.
- API call: truy vấn endpoint được thiết kế cung cấp dữ liệu programmatic, thường yêu cầu key/quota. Gọi endpoint dạng /api/v1/… hoặc các domain api.* thường là API nhưng không tuyệt đối – cần kiểm chứng runtime.
- Quy trình kiểm chứng runtime (tóm lược): grep tìm biến env tên KEY/TOKEN, quét dependency SDK, grep URL có api/ hoặc domain bên thứ ba, rồi thực hiện curl thử endpoint không kèm header/auth để xem có trả dữ liệu công khai. Nếu endpoint trả 401/403 hoặc code chờ key/secret hoặc mã nguồn set Authorization header từ env, coi là API-dependent.
Kết luận vận hành ngắn
- Trong bài tổng hợp, mình chỉ đưa vào những repo mà mình đã kiểm chứng theo định nghĩa trên: core functionality chạy cục bộ không cần khóa/SDK bên thứ ba. Mọi repo mixed-mode hoặc có nghi ngờ đều được ghi chú rõ ràng với evidence và tag tương ứng để bạn và nhóm kỹ thuật dễ rà soát.
Tiêu chí sàng lọc và loại trừ repo
Mục tiêu phần này: cung cấp danh sách kiểm tra bắt buộc và các tiêu chí loại trừ rõ ràng để bạn lọc các repository SEO "không API" hiệu quả, đồng thời cho bộ grep/rg mẫu để tự động hoá bước rà soát ban đầu. Mọi repo vào danh sách cuối phải qua các bước kiểm tra tĩnh và runtime cơ bản theo checklist bên dưới.
Danh sách kiểm tra bắt buộc (must-pass)
- License hợp lệ
- Yêu cầu: license mã nguồn mở (MIT, Apache-2.0, BSD, GPL v3 tùy chính sách). Nếu không có license rõ ràng, loại.
- Kiểm tra nhanh: tìm file LICENSE hoặc trường license trong package.json/pyproject.toml.
- Cập nhật gần đây
- Yêu cầu: pushed within 24 months (mốc tính từ ngày rà). Nếu repo không được cập nhật trong >24 tháng, đánh dấu review thêm về tính tương thích/ổn định.
- Kiểm tra nhanh: xem last commit date trên GitHub hoặc dùng gh api.
- Mức duy trì tối thiểu
- Yêu cầu: ít nhất 1 commit trong 24 tháng và/hoặc activity trong issues/PRs cho thấy maintainer responsive. Nếu repo abandoned và không có branch bảo trì, loại hoặc gắn cảnh báo.
- Manifest dependencies
- Yêu cầu: có file manifest rõ ràng (requirements.txt, package.json, pyproject.toml, go.mod, Gemfile, composer.json). Nếu không có manifest, phải có Dockerfile hoặc hướng dẫn build reproducible.
- Presence of CI / Docker secrets indicators
- Yêu cầu: không để secrets/credentials hardcoded trong repo; nhưng nếu CI workflow tham chiếu tới secrets thì phải kiểm tra xem secrets đó dùng cho feature optional hay cho core. Nếu CI yêu cầu secret để build/run core, loại.
- Khả năng build/run cơ bản
- Yêu cầu: repo phải có hướng dẫn Quickstart rõ ràng, hoặc Dockerfile/docker-compose để chạy demo. Nếu không build được trong môi trường thử nghiệm (container) trong 30 phút, loại hoặc gắn trạng thái cần kiểm chứng thêm.
Quy trình rà soát tĩnh nhanh (5-15 phút)
- Clone repo hoặc dùng GitHub web tree.
- Chạy bộ lệnh tìm nhanh các file và patterns quan trọng. Mẫu dùng ripgrep (rg) hoặc grep -E.
Mẫu lệnh rà soát nhanh:
# tìm license, manifest, docker, ci workflows, env example
rg -n --hidden "(LICENSE|license|requirements.txt|pyproject.toml|package.json|go.mod|Gemfile|composer.json|Dockerfile|docker-compose.yml|.env.example|.github/workflows)" || true
# tìm biến môi trường và từ khóa API
rg -n --hidden "(API_KEY|API-KEY|APIKEY|ACCESS_TOKEN|CLIENT_SECRET|CLIENT_ID|GOOGLE_APPLICATION_CREDENTIALS|OPENAI_API_KEY|SERPAPI_KEY)" || true
# tìm SDK/clients phổ biến
rg -n --hidden "(googleapis|@google-cloud|aws-sdk|boto3|@azure|openai|serpapi|serpstack|semrush|ahrefs|mozapi)" || true
# tìm gọi HTTP trực tiếp có URL literal
rg -n --hidden "(https?://[A-Za-z0-9._:-]+)" || true
# tìm tham chiếu secrets trong GitHub Actions
rg -n --hidden "\${{\s*secrets\.[A-Z0-9_]+}}" .github || true
Tiêu chí loại trừ (hard exclusion) kèm ví dụ grep patterns
- Yêu cầu API key để chạy chức năng chính
- Loại ngay nếu README, .env.example, hoặc code explicit yêu cầu API_KEY để produce core output.
- Patterns:
(?i)\b(API_KEY|OPENAI_API_KEY|SERPAPI_KEY|GOOGLE_API_KEY|AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|CLIENT_SECRET)\b
- Sử dụng SDK/clients thương hiệu cho chức năng chính
- Nếu dependency list chứa libraries tên dịch vụ thương mại (serpapi, semrush, ahrefs, googleapis, @google-cloud, aws-sdk, openai) và import được dùng trong luồng main -> loại.
- Mẫu grep:
rg -n --hidden "(serpapi|semrush|ahrefs|googleapis|@google-cloud|aws-sdk|openai)" || true
- CI/Docker build bắt buộc cần secret ngoài
- Nếu .github/workflows hoặc Dockerfile bắt buộc đăng nhập vào dịch vụ bên ngoài để build/run core, loại.
- Pattern:
rg -n --hidden "\${{\s*secrets\.[A-Z0-9_]+}}" .github || true
rg -n --hidden "(aws ecr login|gcloud auth|az login|docker login)" .github Dockerfile || true
- Repo chỉ là wrapper cho SaaS
- Nếu code chỉ orchestration gọi API thương mại và không thực thi logic phân tích cục bộ, loại.
- Tìm các cuộc gọi HTTP trực tiếp đến domains của SaaS:
rg -n --hidden "https?://(api|www)\.(serpapi|semrush|ahrefs|moz|majestic|googleapis|openai|bing)\." || true
- License không cho phép tái sử dụng theo mục tiêu của bạn
- Nếu license restrictive (ví dụ không cho phép commercial use) và bạn cần công cụ dùng nội bộ/thuê ngoài, loại.
Các tiêu chí cảnh báo (soft flags) cần review thủ công
- Presence of headless browser deps (puppeteer, playwright, selenium)
- Không loại ngay, nhưng cần kiểm tra binary dependency và deploy complexity.
- High concurrency defaults, no rate-limit config
- Nếu code mặc định concurrency cao và không có throttle config, gắn cảnh báo operational.
- Pre-seeded credentials in example files
- Nếu .env.example chứa token-like strings (không phải ‘CHANGE_ME’), cần manual inspection.
Output checklist mẫu để gắn vào bảng repo (bắt buộc điền)
- license_status: OK / MISSING / INCOMPATIBLE
- last_pushed: YYYY-MM-DD
- active_maintainer: yes/no (commit in 24 months)
- manifest_present: yes/no (manifest path)
- apikeyindicators: count + matches (list)
- sdk_imports: list
- cisecretrefs: list
- canbuildquickstart: yes/no (notes)
- classification: NOAPI / REQUIRESAPI / MIXED / NEEDS_MANUAL
Lưu ý vận hành và tips
- Không dựa vào README một mình. Luôn quét manifest và CI.
- Nếu repo là "MIXED" (core offline, enhancement requires API) chấp nhận khi core thực sự chạy offline; ghi rõ tính năng nào cần API.
- Khi automation báo dấu hiệu API (>=1 indicator), chuyển vào hàng review thủ công; không loại tự động nếu chỉ có 1 dấu hiệu nhẹ như import devDependency.
Kết luận ngắn Dùng checklist bắt buộc trên để sàng lọc nhanh 70–80% trường hợp. Bộ lệnh rg/grep mẫu đưa ở trên là công cụ thực tế để chạy trên từng repo. Mọi repo có dấu hiệu API phải qua bước kiểm chứng runtime trước khi được gạt vào danh sách "không API".
Hệ phân loại (taxonomy) theo chức năng SEO
Mục tiêu: cung cấp khung phân loại rõ ràng để gán nhãn repository công cụ SEO không phụ thuộc API, đồng thời định nghĩa cách quyết định primary/secondary và quy tắc khi một repo đa năng.
11 loại chính (taxonomy)
- Crawler / site scraper – thu thập HTML, sitemap discovery, link queueing.
- Audit on-page – kiểm tra thẻ meta, heading, canonical, accessibility rules.
- Log analysis – parser access log, session stitching, traffic attribution.
- Keyword tooling – extractor, n-gram, TF-IDF, corpus analysis từ nội dung cục bộ.
- SERP scraper / SERP parser – thu SERP bằng HTML scraping hoặc headless rendering.
- Internal link analysis – build site graph, anchor analysis, pagerank nội bộ.
- Schema / JSON-LD – validator, generator, snippet templates cho schema.org.
- Sitemap generator / parser – tạo sitemap.xml, sitemap index, chunking.
- Image SEO tools – alt audit, responsive srcset generator, local compression.
- Performance tooling – Lighthouse-like local audits, resource timing aggregator.
- Utilities kỹ thuật – canonicalization, redirect checker, robots.txt validator, bulk fetchers.
Tiêu chí để quyết định Primary vs Secondary
- Primary = chức năng lõi của repo, thể hiện rõ ở một hoặc nhiều tiêu chí sau:
- Entrypoint rõ ràng: có CLI command, bin script, hoặc module entrypoint chuyên cho chức năng đó. (trọng số cao)
- Output mẫu: có sample output hoặc example report dành riêng cho chức năng. (trọng số cao)
- Code chuyên dụng: folder/module riêng chứa logic chính cho chức năng. (trọng số trung bình)
- Tests / CI: test suite hoặc CI job dành cho chức năng đó. (trọng số trung bình)
- Docs dedicated: section docs/README mô tả usage và options cho chức năng. (trọng số thấp)
- Secondary = chức năng hỗ trợ hoặc phụ; thường thỏa ít nhất hai điều:
- Có module/flag thực hiện tính năng nhưng không phải entrypoint chính.
- Có ví dụ nhỏ hoặc helper scripts nhưng thiếu test hoặc docs riêng.
- Code liên quan chiếm diện tích nhỏ so với repo.
Quy tắc gán nhãn vận hành (reproducible)
- Bằng chứng cần thiết: để gán primary cho type X, repo phải có 1) entrypoint hoặc CLI command để chạy X và 2) sample output hoặc test chứng minh X hoạt động. Nếu thiếu một trong hai, gán là secondary hoặc mixed.
- Nếu repo chỉ mô tả chức năng bằng văn bản mà không có entrypoint hay sample output, không gán nhãn functional.
- Luật ưu tiên: nếu nhiều loại thỏa điều kiện primary, chọn primary theo điểm tổng:
- Entrypoint riêng: +30
- Sample output: +20
- Code module >= 20% LOC: +15
- Tests/CI presence: +10
- Docs section: +5
Loại có điểm cao nhất là primary; các loại khác đạt ngưỡng >=45% điểm max được gán secondary.
Rules cho repo đa năng (multi-tool)
- Định nghĩa: đa năng khi có >=2 chức năng độc lập, mỗi chức năng thỏa cả 3 yêu cầu cơ bản: entrypoint riêng, code/module chuyên dụng, và output/example.
- Trường hợp common pattern: monorepo có subprojects – xử lý per-subfolder. Gán nhãn theo subproject nếu subfolder có entrypoint và docs.
- Nếu chức năng phụ chỉ là helper/formatter/output exporter thì không coi là chức năng độc lập.
- Khi repo có nhiều chức năng nhưng chỉ được bật qua flag của một CLI chung, vẫn cho multi-label nếu code được tách module, tests riêng, và docs hướng dẫn chạy từng tính năng độc lập.
- Metadata yêu cầu: mỗi nhãn secondary phải kèm evidence_links (path tới entrypoint hoặc example) trong bảng tổng hợp.
Ghi chú vận hành ngắn
- Mọi quyết định nhãn phải lưu evidence: đường dẫn file, dòng README, lệnh CLI dùng thử. Nếu evidence mơ hồ, gán tag NEEDSMANUALREVIEW và không đưa vào primary.
Các ngưỡng và quy tắc phân loại đa năng
Mục tiêu phần này là cung cấp một bộ quy tắc số hóa, có thể lặp lại, để quyết định khi nào một repo SEO được gán multi-label và cách chọn primary_type. Quy tắc dựa trên bằng chứng trong repo: entrypoint, code density, sample output, tests, docs. Mỗi tiêu chí có điểm, tổng điểm quyết định nhãn. Bạn dùng quy trình này để audit nhanh và để bảng tổng hợp có thể tự động xếp hạng.
- Nguyên tắc vận hành ngắn
- Phân loại dựa trên hành vi thực thi và bằng chứng, không dựa trên tiêu đề README hay tag marketing.
- Mỗi loại chức năng phải có bằng chứng tối thiểu để được gán: entrypoint hoặc module thực thi, và ít nhất một dạng output hoặc test minh họa.
- Multi-label chỉ dành cho repo có ít nhất hai chức năng độc lập theo định nghĩa dưới đây.
- Định nghĩa "chức năng độc lập" (operational)
Một chức năng X được coi là độc lập nếu cùng lúc thỏa cả ba:
- Entrypoint riêng: có CLI command/module/binary/subfolder chạy X mà không cần khởi chạy toàn bộ hệ thống.
- Code chuyên dụng: tồn tại module hoặc folder chứa logic rõ rệt cho X (không chỉ vài hàm helper).
- Output minh chứng: có sample output, example file, hoặc test fixture chỉ rõ kết quả X.
- Các tiêu chí đánh giá và điểm số (scoring)
Mỗi repo cho mỗi chức năng ứng viên sẽ được chấm điểm theo các tiêu chí sau. Điểm tổng từ 0 đến 100 cho mỗi chức năng.
- Entrypoint (0 – 30 điểm)
- 30 pts: có bin/cli script hoặc package entrypoint riêng cho chức năng; docs có ví dụ run đầy đủ.
- 20 pts: có CLI flag –mode hoặc subcommand rõ ràng để chạy chức năng, kèm snippet.
- 10 pts: chỉ có function exportable (module) nhưng không có CLI hướng dẫn.
- 0 pts: không có entrypoint nào.
- Code density / separation (0 – 20 điểm)
- 20 pts: module/folder riêng chiếm >= 30% LOC của repo (sau loại trừ templates/vendor).
- 15 pts: module riêng chiếm 20-29% LOC.
- 10 pts: module riêng chiếm 10-19% LOC hoặc >=3 file chuyên dụng.
- 0 pts: code rải rác, không có module rõ rệt.
- Sample output / fixtures (0 – 20 điểm)
- 20 pts: có sample output file (CSV/JSON/HTML/GraphML) khớp với chức năng và có schema.
- 12 pts: có example snippet trong README hiển thị output.
- 6 pts: có test fixture nhưng không có output sample.
- 0 pts: không có.
- Tests & CI (0 – 15 điểm)
- 15 pts: có unit/integration tests targeting chức năng + CI job chạy tests.
- 8 pts: có tests nhưng không CI.
- 0 pts: không có tests.
- Docs / Usage section (0 – 15 điểm)
- 15 pts: docs riêng hoặc dedicated section trong README giải thích toàn bộ workflow chức năng + options.
- 8 pts: có vài dòng usage hoặc flags.
- 0 pts: không có docs.
- Quy tắc quyết primary_type
- Tính điểm cho mỗi loại chức năng khả dĩ theo bảng trên. Loại có điểm cao nhất là primary_type.
- Tỷ lệ an toàn: để chọn primary cần >= 50 điểm. Nếu cao nhất < 50, gắn primary theo highest-score nhưng kèm tag NEEDS_VERIFICATION.
- Nếu top two types có điểm chênh < 10 và đều >= 40, đánh dấu primary là type thường gặp trong README bằng thứ tự xuất hiện, đồng thời gán multi-label.
- Quy tắc gán multi-label
- Gán multi-label (Secondary types) khi mỗi chức năng phụ đạt tối thiểu 45 điểm theo cùng thang điểm.
- Nếu một chức năng phụ đạt 30-44 điểm, có thể gán secondary có tag WEAK_EVIDENCE; yêu cầu reviewer chạy kiểm thử nhanh 30 phút để xác nhận trước khi xuất bản.
- Không gán secondary nếu điểm < 30.
- Xử lý repo monorepo và subproject
- Nếu repo là monorepo, áp quy tắc trên theo subfolder. Mỗi subfolder được coi như một "sub-repo" để tính điểm. Điểm tổng của toàn repo có thể là max(subproject scores) cho primary và các subprojects đủ điều kiện cho secondary.
- Cách đo code density thực thi (hướng dẫn nhanh)
- Loại trừ thư mục: node_modules, vendor, dist, build, .venv.
- Tính LOC bằng ripgrep + wc hoặc cloc; đo % LOC của folder chức năng / total LOC.
- Nếu repo nhỏ (< 1000 LOC), ưu tiên count files và function definitions: >=3 file chuyên dụng hoặc >=4 function/class tên liên quan đủ điều kiện thay cho threshold %.
- Kiểm chứng tối thiểu trước khi gán multi-label (30 phút rule)
Trước khi public multi-label, thực hiện:
- Chạy entrypoint chức năng phụ theo docs để sinh sample output (nếu có), hoặc chạy test tương ứng.
- Nếu không thể chạy do environment hoặc API key, ghi rõ trong notes và không gán secondary; hoặc gán nhưng kèm tag REQUIRESAPICHECK / REQUIRES_BUILD.
- Ghi artifact: command run + output snippet + đường dẫn file trong bảng.
- Template evidence lưu vào bảng tổng hợp
Mỗi nhãn phải kèm cột evidence (copy-paste format):
- entrypoint: path or command
- code_path: path/to/module
- sample_output: path/to/sample.json
- tests: path/to/tests or CI link
- docs_section: README#section-link
- score: numeric
Ví dụ evidence string ngắn:
- "entrypoint: bin/audit | code: src/audit/ | sample: examples/audit.json | tests: tests/test_audit.py | docs: README#audit | score: 72"
- Quy tắc ưu tiên khi có xung đột
- Nếu primary_type dựa trên điểm nhưng reviewer có thông tin vận hành (ví dụ chức năng phụ thực sự là core trong thực tế usage) thì reviewer có quyền override kèm ghi lý do ngắn trong notes và initial.
- Override cần 1 reviewer kỹ thuật + 1 biên tập xác nhận.
- Ghi nhãn trạng thái chứng thực
- Tags chuẩn kèm nhãn: VERIFIED, WEAKEVIDENCE, NEEDSVERIFICATION, REQUIRES_API, MULTI.
- Chỉ repo với primary score >=50 và tag VERIFIED mới được dùng làm "recommendation" trong phần top tools.
- Ví dụ minh họa ngắn
- Repo A: entrypoint crawl (bin/crawl) + sample out crawl.json + code src/crawl (35% LOC) + tests -> crawl score 85 -> primary: Crawl.
- Repo B: một CLI với flags –crawl –audit nhưng code audit chỉ 2 file, sample output chỉ cho crawl -> crawl score 70, audit score 38 -> primary Crawl; audit not gán secondary (score <45) -> tag audit WEAK_EVIDENCE.
- Checklist nhanh để áp quy tắc (copy-paste)
- [ ] Có entrypoint cho chức năng X? (yes/no)
- [ ] Có module/folder chuyên dụng? (yes/no)
- [ ] Có sample output? (yes/no)
- [ ] Có tests/CI? (yes/no)
- [ ] Có docs usage? (yes/no)
- [ ] Tính điểm theo bảng và ghi score
- [ ] Nếu secondary gán, chạy kiểm thử 30 phút nếu score 30-44
- [ ] Ghi evidence vào bảng
Kết luận ngắn Bộ quy tắc điểm này giúp bạn đưa việc gán nhãn thành quy trình có thể lặp, audit và tự động hóa một phần. Mọi quyết định vượt ngưỡng hoặc override đều phải ghi bằng chứng vào trường notes để giữ minh bạch khi biên tập bài.
Truy vấn tìm kiếm hiệu quả trên GitHub và GitLab
Mục tiêu phần này là cung cấp tập query mẫu và checklist tìm nhanh repo tool SEO "không cần API" trên GitHub và GitLab, kèm hướng lọc giảm nhiễu. Bạn dùng các query này để thu thập danh sách ban đầu, rồi áp quy trình kiểm mã/runtime để loại bỏ phụ thuộc API.
- Nguyên tắc khi tạo query
- Tìm trong README để ưu tiên repo là tool chứ không phải tutorial: dùng in:readme.
- Giới hạn thời gian cập nhật: dùng pushed:>=YYYY-MM-DD (24 tháng gần nhất).
- Loại bỏ fork/archived: archived:false.
- Ưu tiên repo có entrypoint: tìm package.json, setup.py, bin/, cmd/ hay Dockerfile.
- Tránh từ khóa gây nhiễu: tutorial, example, course, demo, slides.
- Các trường lọc thường dùng (GitHub Advanced Search)
- in:readme – tìm chuỗi trong README
- language:Python | language:JavaScript | language:Go – lọc ngôn ngữ
- pushed:>=2024-07-19 – cập nhật 24 tháng (thay ngày tương ứng)
- size:>50 – loại repo rất nhỏ (kB)
- stars:>3 – ưu tiên repo có cộng đồng tối thiểu
- topic:seo | topic:crawler | topic:cli – khi có topic
- filename:package.json | path:/bin | filename:Dockerfile – tìm dấu hiệu runnable
- archived:false – loại kho lưu trữ đã archive
- Query mẫu GitHub (copy-paste và sửa pushed: theo ngày bạn chạy)
Crawl / site crawler (Python)
in:readme ("site crawler" OR "site-crawler" OR "crawler") language:Python pushed:>=2024-07-19 archived:false size:>50 stars:>3 filename:requirements.txt
On-page audit CLI (Node)
in:readme ("on-page audit" OR "on page audit" OR "SEO audit") language:JavaScript pushed:>=2024-07-19 archived:false filename:package.json in:readme usage
SERP scraper (HTML scraping, no paid API)
in:readme (serp OR "SERP scraper" OR "search results scraper") (language:Python OR language:JavaScript) pushed:>=2024-07-19 archived:false -in:readme "Google API" -in:readme "API key"
Sitemap generator
in:readme ("sitemap generator" OR "generate sitemap") pushed:>=2024-07-19 archived:false language:Python OR language:Ruby size:>10
Keyword extractor (local)
in:readme ("keyword extractor" OR "keyword tool" OR "ngram") language:Python pushed:>=2024-07-19 archived:false size:>20
Ghi chú: thay stars:>3 nếu bạn muốn mở rộng phạm vi. Khi mở rộng, tăng kiểm chứng sau lọc.
- Tránh từ khóa gây nhiễu
- Tránh các truy vấn chỉ có "seo" hay "keyword" đơn lẻ. Thay bằng chuỗi cụ thể kết hợp CLI/usage.
- Loại trừ bằng -in:readme tutorial OR demo OR "course" để giảm tutorial repositories.
- Ví dụ: add
-in:readme tutorial -in:readme demovào query.
- Dùng GitLab Explore / API
- GitLab Explore web: search với từ khóa + sắp xếp theo Last activity; lọc Public projects; dùng ngôn ngữ để thu hẹp.
- Dùng GitLab API để thu bulk: ví dụ endpoint public gitlab.com:
- GET https://gitlab.com/api/v4/projects?search=TERM&withprogramminglanguage=python&lastactivityafter=2024-07-19
- Thực tế: GitLab search kém linh hoạt hơn GitHub; do đó thu thập chủ yếu từ GitHub, bổ sung GitLab cho loại hiếm.
- Cách lọc trùng và sắp hàng
- Lấy fullname (owner/repo) + repourl để dedupe.
- Sắp theo last push (mới nhất) hoặc theo apidependencyscore (sau khi scan), hoặc theo priority: application usefulness, verified non-API, last commit.
- Nếu số lượng lớn, ưu tiên review repo có stars>10 trước.
- Checklist truy vấn cho thu thập ban đầu (dùng cho automation/nhân sự)
- Chạy 12 biến thể query cho mỗi loại (kết hợp keywords, language, pushes).
- Lưu kết quả raw (CSV: fullname, url, description, stars, pushedat, language).
- Dedupe theo full_name.
- Lọc nhanh manifest: giữ repo có package.json / requirements.txt / setup.py / Dockerfile / bin/ / cmd/.
- Chấm điểm sơ bộ phụ thuộc API bằng grep: tìm "API_KEY|APIKEY|service account|google-credentials|serpapi" (thang 0-3).
- Lấy shortlist 3x số repo cần cho bước runtime check (ví dụ cần 30 repo – shortlist 90).
- Những query bổ sung giúp tìm công cụ cục bộ
- Tìm explicitly "no external API" trong README:
in:readme "no external API" OR in:readme "no API key" pushed:>=2024-07-19
- Tìm repo có Dockerfile + CLI:
filename:Dockerfile in:readme ("Usage" OR "Quickstart") pushed:>=2024-07-19
- Ghi chú vận hành
- Các query chỉ là bước thu thập ban đầu. Không bao giờ coi một query trả kết quả là xác nhận "không API". Luôn chạy quy trình kiểm tra phụ thuộc API tĩnh và runtime trước khi gán vào danh sách "không API".
- Giữ log truy vấn và xuất CSV để audit. Với mỗi repo lưu evidence paths: README line, manifest file, sample command.
- Mẫu workflow nhanh (áp dụng cho thu 150 candidates)
- Stage 1 – Query & collect raw (automate 12 queries per type) – export CSV.
- Stage 2 – Dedupe + manifest filter (package files, Dockerfile) – keep ~3x target.
- Stage 3 – Static scan grep for API indicators – mark probable API.
- Stage 4 – Manual/runtime quick test 30 phút cho shortlisted repos.
Dùng những query mẫu ở trên, bạn sẽ thu được candidate chất lượng cao để tiếp quy trình kiểm chứng chi tiết theo checklist đã mô tả. Hãy luôn lưu kết quả truy vấn và bằng chứng để biên tập có thể trích dẫn chính xác khi soạn phần tổng hợp.
Quy trình thu thập bulk và lọc trùng
Mục tiêu: tự động thu gom danh sách repo từ GitHub/GitLab, sàng lọc theo stars/size/pushed date, loại trùng bằng fullname và repourl, và lưu log truy vấn có thể audit được.
Tổng quan bước chính (tự động)
- Thu gom candidates bằng API hoặc gh CLI
- Ví dụ dùng GitHub REST qua gh CLI:
- gh api -X GET "search/repositories?q=site:github.com+topic:seo+language:Python+stars:>3+pushed:>=2024-07-19&perpage=100" > hitspage1.json
- Hoặc dùng curl:
- curl -s -H "Authorization: token $GHTOKEN" "https://api.github.com/search/repositories?q=seo+stars:>3+pushed:>=2024-07-19&perpage=100" > hits_page1.json
- Lặp qua pages để thu hết; cho GitLab dùng GitLab API tương tự.
- Chuẩn hoá metadata và lưu theo bản ghi
- Từ mỗi API response trích các trường bắt buộc: fullname (owner/repo), repourl (htmlurl), cloneurl, stars, size(kB), pushed_at, language, license, topics.
- Lưu mỗi repo như một dòng JSON (JSONL) để dễ xử lý: one JSON object per line.
- Dedupe ban đầu theo fullname và repourl
- Sau thu gom nhiều page/queries, gộp tất cả JSONL rồi dedupe:
- jq -c ‘.items[] | {fullname: .fullname, repourl: .htmlurl, cloneurl: .cloneurl, stars: .stargazerscount, size: .size, pushedat: .pushedat, language: .language}’ hits*.json > all.jsonl
- jq -s ‘uniqueby(.repourl)’ all.jsonl > dedupbyurl.jsonl
- jq -s ‘uniqueby(.fullname)’ dedupbyurl.jsonl > dedup_final.jsonl
- Luôn ưu tiên dedupe theo repourl trước, sau đó theo fullname để tránh forks hoặc chuyển tên repo.
- Lọc theo stars/size/pushed date
- Dùng jq hoặc csvkit để apply filter:
- jq ‘select(.stars >= 3 and .size >= 20 and (.pushedat >= "2024-07-19"))’ dedupfinal.jsonl > filtered.jsonl
- Ghi chú: ngưỡng stars/size có thể điều chỉnh theo yêu cầu dự án; giữ cấu hình ở file params.yml để reproducible.
- Báo cáo và export cho bước scan tiếp theo
- Xuất csv cho workflow review:
- jq -r ‘[.fullname, .repourl, .cloneurl, .stars, .size, .pushedat, .language] | @csv’ filtered.jsonl > shortlist.csv
Quy trình clone bulk (tự động có kiểm soát)
- Tạo script clone list từ shortlist.csv:
- xargs -P4 -I{} bash -c ‘git clone –depth 1 {}’ < <(cut -d, -f3 shortlist.csv | tr -d ‘"’)
- Với nhiều repo, dùng –depth 1 để giảm thời gian và dung lượng. Ghi nhãn commit hash HEAD vào metadata sau clone.
Cách lọ trùng nâng cao
- Loại forks: kiểm tra .fork = true trong API result; nếu bạn muốn chỉ chính repo chính, loại fork trừ khi fork có activity hơn upstream.
- Rename history: nếu same fullname nhưng khác repourl (unlikely), giữ bản mới nhất (pushed_at latest).
- Mirror hoặc duplicate content: dùng checksum của file README.md hoặc đo cosine similarity của README để phát hiện duplicate logic. Nếu README giống > 95% thì coi là duplicate.
Lưu log truy vấn cho audit (bắt buộc)
- Mỗi lần chạy ghi 1 dòng JSONL log với cấu trúc:
- timestamp, querystring, apiendpoint, page, totalcount, resultfile
- Ví dụ dòng log human+machine:
- 2026-07-19T10:02:00Z | search/repositories?q=seo+stars:>3… | api.github.com | page=1 | total=234 | hits_page1.json
- Lưu cả raw response file và parsed JSONL; đặt tên file có tiền tố timestamp để dễ truy vết.
Trường metadata bắt buộc vào bảng giao nhận (mẫu)
- fullname | repourl | cloneurl | stars | sizekb | pushedat | language | license | apidependencyscore | evidencepaths | retrieved_at
Ghi chú vận hành ngắn
- Chạy thu gom bằng cron hoặc CI job, version script trong repo nội bộ và commit logs. Nếu cần mở rộng, thêm GitLab search và Awesome lists crawl.
- Luôn dedupe theo repourl trước rồi fullname. Giữ logs chi tiết để audit; mọi quyết định loại trừ phải có evidence path.
Quy trình kiểm tra phụ thuộc API tĩnh (scan code)
Mục tiêu: trong bước sàng lọc nhanh, bạn cần phát hiện các dấu hiệu trong mã nguồn và cấu hình báo rằng repo có phụ thuộc API bên thứ ba hoặc yêu cầu khoá. Quy trình dưới đây là checklist thực thi bằng công cụ dòng lệnh, các regex thực dụng, và tiêu chí chấm điểm flags để đánh giá mức rủi ro. Mình viết theo hướng để bạn có thể chạy tự động trên hàng chục repo rồi trả về bảng kết quả để quyết tiếp.
- Tệp và vị trí phải quét
- File môi trường mẫu và config vận hành: .env, .env.example, .env.sample, docker-compose.yml, .env.production, .env.local, config/.yml|.yaml|*.json, settings.py, config.py.
- Docker / container / build: Dockerfile, docker-compose.yml, Dockerfile.*.
- CI / workflows: .github/workflows/*.yml, .gitlab-ci.yml, .circleci/config.yml, Jenkinsfile, .travis.yml.
- Scripts khởi động / entrypoints: bin/, scripts/, start.sh, entrypoint.sh, Procfile.
- Manifest phụ thuộc: package.json, requirements.txt, pyproject.toml, Pipfile, go.mod, Gemfile, composer.json.
- Thư mục examples, demos, notebooks: examples/, demo/, notebooks/*.ipynb.
- Tài liệu hướng dẫn: README.md, docs/*.
- Tệp credential mẫu: client_secret.json, credentials.json, service-account.json, .pem, .p12.
- Regex mẫu hữu dụng để phát hiện dấu hiệu
Mình đưa các regex để dùng với ripgrep (rg) hoặc grep -E. Chạy trong thư mục repo.
- Biến môi trường tên khóa:
- (?i)\b(?:API[-]?KEY|APIKEY|ACCESS[-]?TOKEN|ACCESS[-]?KEY|SECRET[-]?KEY|CLIENT[-]?SECRET|CLIENT[-]?ID|OPENAIAPIKEY|SERPAPI|SERPAPIKEY|GOOGLEAPIKEY|BINGAPI_KEY)\b
- Header/authorization:
- (?i)\bAuthorization\b|\bBearer\s+[A-Za-z0-9\-_\.]+|\bx-api-key\b|\bX-Api-Key\b
- Endpoint domain có vẻ là API:
- (?i)https?://(?:api|data|services|graph|search|graphql|maps)\.[A-Za-z0-9\.-]+
- (?i)https?://(?:[\w\.-]+\.)?(?:googleapis|openai|serpapi|serpstack|bing|azure|amazonaws|aws|algolia|ahrefs|semrush|moz|facebook|twitter|linkedin)\.[A-Za-z0-9\.-]+
- Path chỉ API/graphQL:
- (?i)/api/|/v[0-9]+/|/graphql\b|/oauth|/token\b|/auth\b
- SDK imports (manifest + code):
- Node package.json scan: (?i)"(openai|serpapi|googleapis|aws-sdk|@aws-sdk|@azure|algoliasearch|serpstack|semrush|ahrefs|moz)":
- Python requirements.txt / imports: (?i)\b(openai|serpapi|google-api-python-client|boto3|azure|algoliasearch|semrush|ahrefs|moz)\b
- Code import statements: (?m)^\s(?:import|from).(openai|serpapi|google|boto3|azure|algoliasearch|semrush|ahrefs)\b
- CI secrets usage:
- (?i)\$\{\{ secrets\.[A-Z0-9_]+ \}\}|\bsecrets\.[A-Z0-9]+\b|\$[A-Z0-9]+
- Lệnh cơ bản bằng ripgrep / grep để chạy nhanh
- Quét biến môi trường tên khóa:
rg -n --hidden "(?i)\b(?:API[_-]?KEY|ACCESS[_-]?TOKEN|CLIENT[_-]?SECRET|OPENAI_API_KEY|SERPAPI|GOOGLE_API_KEY)\b"
- Quét endpoint REST/graphQL:
rg -n --hidden "(?i)https?://(?:api|data|services|graph|search|graphql|maps)\.[A-Za-z0-9\.-]+|/api/|/graphql\b"
- Quét SDK trong manifests:
rg -n --hidden "(?i)openai|serpapi|googleapis|aws-sdk|@azure|algoliasearch|semrush|ahrefs|moz" package.json requirements.txt pyproject.toml go.mod Gemfile composer.json || true
- Quét CI secrets:
rg -n --hidden "\${{ *secrets\.[A-Z0-9_]+ *}}|secrets\.[A-Z0-9_]+|GITHUB_TOKEN|AWS_SECRET_ACCESS_KEY" .github .gitlab-ci.yml || true
- Cách tự động hoá chạy trên nhiều repo (outline script)
- Ý tưởng: với danh sách repo clone sẵn, script chạy các rg command trên và xuất JSON line per repo chứa các flag. Mình mô tả pseudocode bash:
#!/usr/bin/env bash
for repo in $(cat repos.txt); do
cd "$repo" || continue
res_env=$(rg -n --hidden "(?i)\b(?:API[_-]?KEY|ACCESS[_-]?TOKEN|CLIENT[_-]?SECRET|OPENAI_API_KEY|SERPAPI)" || true)
res_sdk=$(rg -n --hidden "(?i)openai|serpapi|googleapis|aws-sdk|semrush|ahrefs" package.json requirements.txt pyproject.toml go.mod || true)
res_endpoint=$(rg -n --hidden "(?i)https?://(?:api|data|services|graph|search)\." || true)
res_ci=$(rg -n --hidden "\${{ *secrets\.[A-Z0-9_]+ *}}|GITHUB_TOKEN|AWS_SECRET_ACCESS_KEY" .github .gitlab-ci.yml || true)
jq -n --arg repo "$repo" --arg env "$res_env" --arg sdk "$res_sdk" --arg endpoint "$res_endpoint" --arg ci "$res_ci" '{repo:$repo, env:($env|length>0), sdk:($sdk|length>0), endpoint:($endpoint|length>0), ci:($ci|length>0)}' >> scan_results.jsonl
done
- Tiêu chí chấm điểm flags (scoring) và quyết định
- Mỗi indicator gán điểm:
- Credential env var tên rõ ràng (APIKEY, *SECRET, *_TOKEN) : +3
- SDK import (manifest hoặc code import) : +4
- Literal external API endpoint với api/ hoặc domain thương hiệu : +3
- CI secret reference / Docker ENV referencing API key : +3
- Authorization header usage in code: +2
- Credential files present (service-account.json, client_secret.json): +5
- Tổng điểm interpret:
- 0 – 1 : likely no external API dependency for core feature
- 2 – 4 : possible hybrid – manual runtime check recommended
- >=5 : likely requires external API or credentials – exclude for "no-API" list or mark as requires-key
- Ghi kết luận per repo: apistatus = "NOAPI", "POSSIBLEAPI", "REQUIRESAPI" kèm score và evidence paths.
- Gợi ý kiểm tra thêm khi score ở ngưỡng trung gian
- Nếu score 2-4, mở file location match để xem context: biến env có trong .env.example nhưng code không dùng? SDK chỉ xuất hiện trong devDependencies? Nếu ambiguous, chạy quick runtime test sau bước tĩnh để xác minh.
- Lưu kết quả và metadata bắt buộc
- Mỗi repo output JSONL cần ít nhất:
- repourl, scandate, apiscore, apistatus, evidencepaths (mảng), topmatches (lấy 5 dòng có match)
- Ví dụ trường:
- { "repo":"owner/repo", "date":"2026-07-19", "score":6, "status":"REQUIRES_API", "evidence":["README.md:12","package.json:dependencies.serpapi"], "notes":"uses serpapi SDK" }
- Lưu ý vận hành và các cảnh báo
- Regex có thể đưa false positive. Luôn mở evidence file xem ngữ cảnh, đặc biệt với endpoint domain thuộc chính trang target (ví dụ api.example.com là API public của target site not a third-party).
- Kiểm tra cách code dùng env var: nếu var chỉ để kích hoạt optional feature, classify là "optional", không loại thẳng.
- Không vội loại repo chỉ vì một placeholder API_KEY trong .env.example; kết hợp score sẽ giảm false positive.
Kết luận ngắn
- Dùng bộ tệp cần quét + regex trên để thực hiện scan tĩnh nhanh. Áp scoring như đề xuất để phân loại tự động. Với các repo score cao, loại khỏi danh sách "không API"; với score trung bình, chuyển sang bước runtime 30 phút để xác minh cơ chế gọi endpoint và tính bắt buộc của API key. Nếu bạn muốn, mình có thể cung cấp script hoàn chỉnh (bash + jq) để chạy bulk và xuất bảng scan_results.jsonl theo schema trên.
Quy trình kiểm tra phụ thuộc API runtime trong 30 phút
Mục tiêu: trong 30 phút xác định nhanh liệu một repo SEO có phụ thuộc API bên thứ ba khi chạy chức năng chính hay không. Kết quả phải là một trong ba nhãn rõ ràng: REQUIRESAPI, OFFLINEOK, NEEDS_LOGIN. Dưới đây là quy trình timeboxed, công cụ lệnh có thể sao chép, và quy tắc quyết định dùng evidence thu được.
Thời gian tổng: 30 phút. Phân bổ gợi ý: Tĩnh scan 7 phút, curl endpoint tests 6 phút, chạy sample với mạng vô hiệu 10 phút, quan sát network bằng strace/mitmproxy 6 phút, kết luận 1 phút.
- Chuẩn bị nhanh 1 phút
- Clone repo; mở README để lấy lệnh Quickstart hoặc ví dụ chạy. Ghi lại command ví dụ để chạy sau. Chuẩn bị terminal với rg/ripgrep, curl, docker, strace (Linux), hoặc mitmproxy nếu cần.
- Tĩnh scan 7 phút
- Mục đích: tìm dấu hiệu mạnh báo cần API trước khi chạy runtime.
- Chạy các lệnh:
rg -n --hidden "(?i)\b(API[_-]?KEY|ACCESS[_-]?TOKEN|CLIENT[_-]?SECRET|OPENAI_API_KEY|SERPAPI|GOOGLE_API_KEY|AWS_ACCESS_KEY_ID)\b" || true
rg -n --hidden "(?i)https?://(?:api|auth|graph|search|v[0-9])\.[A-Za-z0-9\.-]+" || true
rg -n --hidden "(?i)openai|serpapi|googleapis|aws-sdk|boto3|azure|semrush|ahrefs|moz" package.json requirements.txt pyproject.toml go.mod || true
rg -n --hidden "ENV|ARG|secrets\." .github .gitlab-ci.yml Dockerfile docker-compose.yml || true
- Ghi chép nhanh: nếu thấy biến env kiểu API_KEY, SDK có tên thương hiệu, endpoint api.* hoặc .github/workflows tham chiếu secrets, đánh dấu high suspicion và note file/line.
- Curl endpoint tests 6 phút
- Mục đích: kiểm tra endpoint nghi ngờ có trả dữ liệu công khai hay yêu cầu auth.
- Từ kết quả tĩnh scan lấy danh sách endpoint nghi ngờ. Với mỗi endpoint:
- Thử curl đơn giản không header:
curl -i -sS 'https://example.com/api/search?q=test' | head -n 20
- Nếu trả 200 JSON không yêu cầu auth, note "public JSON".
- Nếu trả 401/403/302->login hoặc body có thông báo "API key required", note "protected".
- Nếu trả 429 hoặc trả HTML challenge, note "rate-limited / protected".
- Kiểm tra cookie/Referer requirement:
curl -i -sS -H "Referer: https://example.com" 'https://example.com/api/search?q=test'
- Ghi evidence: HTTP status, response snippet, headers Authorization/WWW-Authenticate/Retry-After.
- Chạy sample với mạng vô hiệu 10 phút
- Mục đích: xác minh command Quickstart có thể chạy core feature offline.
- Nếu repo có Dockerfile/Docker Compose, dùng chế độ network none:
# build nếu cần
docker build -t repo-test . || true
# chạy command ví dụ trong container với network disabled
docker run --rm --network none repo-test <example-command> > run.out 2>&1 || true
- Nếu không dùng Docker, tắt mạng tạm thời hoặc chặn egress DNS/HTTP (local dev): ví dụ disconnect network adapter hoặc dùng iptables để chặn.
- Chạy lệnh Quickstart (thay command bằng lệnh từ README). Quan sát:
- Kết quả A: tool hoàn thành và tạo output tương tự README mà không có lỗi network => OFFLINE_OK.
- Kết quả B: tool thất bại với error rõ "missing APIKEY" hoặc exception từ SDK init => REQUIRESAPI.
- Kết quả C: tool vẫn chạy nhưng output giảm chức năng (ví dụ thiếu enrichment) hoặc log chỉ ra "skipping external enrichment" => mark NEEDSLOGIN nếu yêu cầu session, hoặc OFFLINEOK với chú thích "reduced features".
- Lưu run.out và capture stderr để làm evidence.
- Quan sát network calls nếu vẫn mơ hồ 6 phút
- Nếu tĩnh scan không rõ hoặc chạy sample với network bật mà muốn biết thực tế outbound hosts, dùng một trong hai cách:
A. strace (Linux) – nhanh, không cần proxy
# chạy binary/command dưới strace để log syscalls mạng
strace -f -e trace=network -o /tmp/strace.log <example-command> 2>&1 || true
rg "connect|sendto" /tmp/strace.log || true
- Kiểm tra các connect tới hostname/IP. Nếu có connect tới api.thirdparty.com hoặc openai.com, đây là evidence mạnh REQUIRES_API.
B. mitmproxy – chi tiết nội dung HTTPS (khi có thể thiết lập)
- Chạy mitmdump để log requests:
mitmdump -w /tmp/mitmflows -q
# trong terminal khác, export http(s)_proxy
export HTTP_PROXY=http://127.0.0.1:8080
export HTTPS_PROXY=http://127.0.0.1:8080
# chạy example-command
<example-command>
# sau đó:
mitmdump -n -r /tmp/mitmflows --no-upstream-cert=false
- Lưu ý: mitmproxy cần cài cert trên môi trường test. Nếu quá phức tạp hoặc không được phép, ưu tiên dùng strace.
- Quy tắc quyết định nhanh – rule of thumb
- REQUIRES_API nếu:
- README/.env.example yêu cầu API_KEY AND code/runtime throws missing-key error; OR
- strace/mitmproxy shows outbound calls to known third-party API domains; OR
- repo imports third-party SDK and that SDK is used in code path that produces core output.
- OFFLINE_OK nếu:
- Running Quickstart with network disabled produces core output matching README; AND
- Static scan không show mandatory credential files or CI secrets; AND
- No outbound connect observed in strace when run with network enabled (or endpoint tests showed public JSON without auth).
- NEEDS_LOGIN if:
- Endpoint requires session cookies or 302->login redirect and repo uses headless browser/login flows; or
- Quickstart runs only when provided site credentials; classify as needs-login, not REQUIRES_API.
- Ghi chép evidence và báo cáo 1 phút
- Ghi 3 dòng kết luận: repourl, verdict (REQUIRESAPI / OFFLINEOK / NEEDSLOGIN), evidence pointers (file:line, curl output snippet, strace lines, run.out).
- Nếu verdict là POSSIBLE/ambiguous, đánh dấu cho deeper review và không đưa vào danh sách "no-API" công khai.
Lưu ý an toàn và đạo đức
- Chạy curl tests và probing với giới hạn thấp để tránh gây traffic lớn. Nếu target là site ngoài, dùng sample local HTML thay vì thử hàng loạt trên production. Tuân thủ robots.txt và chính sách nội bộ khi thực hiện probing.
Kết thúc: theo quy trình này bạn sẽ có evidence tái lập được trong 30 phút để gắn nhãn repo cho danh sách tổng hợp một cách an toàn và có thể giải trình.
Mẫu script tự động hoá quét dấu hiệu API (outline, bash + ripgrep + jq + curl)
Mục tiêu: quét nhanh một repo local, thu các dấu hiệu API (env var, SDK, endpoint, CI secrets), thử curl endpoint công khai an toàn, và xuất kết quả JSON để load vào bảng tổng hợp.
Lưu ý vận hành ngắn
- Chạy trên clone local của repo. Không tự động truy vấn nhiều host ngoài. Curl chỉ test nhẹ, rate-limited và không gửi credentials.
- Nếu bạn muốn chạy bulk, lặp gọi script cho mỗi repo clone.
- Các pattern dùng (ripgrep)
- Biến môi trường/placeholder: APIKEY, ACCESSTOKEN, CLIENTSECRET, GOOGLEAPPLICATIONCREDENTIALS, AWSSECRETACCESSKEY
- SDK names: googleapis, boto3, aws-sdk, openai, serpapi, serpstack, semrush, ahrefs, azure
- Endpoint API-like: domain với api., path chứa /api/, /v1/, /graphql, /token, /oauth
- Script outline (bash)
#!/usr/bin/env bash
set -euo pipefail
REPO_DIR="${1:-.}"
OUT_JSON="${2:-scan-result.json}"
TS=$(date --iso-8601=seconds)
cd "$REPO_DIR"
# 1. static scans with ripgrep
rg --hidden -n --no-ignore -S -e '(?i)\b(API[_-]?KEY|ACCESS[_-]?TOKEN|CLIENT[_-]?SECRET|GOOGLE_APPLICATION_CREDENTIALS|AWS_SECRET_ACCESS_KEY)\b' || true > /tmp/rg_env.txt
rg --hidden -n --no-ignore -S -e '(?i)(googleapis|boto3|aws-sdk|openai|serpapi|semrush|ahrefs|azure)' package.json requirements.txt pyproject.toml go.mod Gemfile || true > /tmp/rg_sdk.txt
rg --hidden -n --no-ignore -o -e 'https?://[A-Za-z0-9\.\-_/:%?&=]+' || true > /tmp/rg_urls.txt
rg --hidden -n --no-ignore -S -e '(?i)secrets\.|env:\s|ACTIONS_SECRET' .github .gitlab-ci.yml docker-compose.yml Dockerfile || true > /tmp/rg_ci.txt
# 2. extract candidate endpoints (unique, filter local)
grep -Eo 'https?://[A-Za-z0-9\.\-_/:%?&=]+' /tmp/rg_urls.txt | sort -u > /tmp/urls_all.txt
# filter out localhost and file urls
rg -v 'localhost|127\.0\.0\.1|file:|/static/|/assets/' /tmp/urls_all.txt > /tmp/urls_external.txt || true
# 3. light curl tests (non-destructive) - only GET, 5s timeout, stop after 10 urls
MAX=10
CNT=0
> /tmp/endpoint_tests.json
while read -r url && [ "$CNT" -lt "$MAX" ]; do
CNT=$((CNT+1))
# safe GET without cookies, no auth headers
out=$(mktemp)
http_status=$(curl -sS -I -L --max-time 5 "$url" 2>/dev/null | head -n 1 | awk '{print $2}' || echo "")
echo "{\"url\":\"$url\",\"http_status\":\"$http_status\"}" >> /tmp/endpoint_tests.json
done < /tmp/urls_external.txt
# 4. build result JSON fields
jq -n \
--arg repo_dir "$REPO_DIR" \
--arg timestamp "$TS" \
--slurpfile env /tmp/rg_env.txt \
--slurpfile sdk /tmp/rg_sdk.txt \
--slurpfile urls /tmp/urls_external.txt \
--slurpfile ci /tmp/rg_ci.txt \
--slurpfile tests /tmp/endpoint_tests.json \
'{
repo_path: $repo_dir,
timestamp: $timestamp,
env_matches: ($env | map(.)),
sdk_matches: ($sdk | map(.)),
external_urls: ($urls | map(.)),
ci_matches: ($ci | map(.)),
endpoint_tests_raw: ($tests | map(fromjson? // .)),
verdict: (if ($sdk|length) > 0 or ($env|length) > 0 or ($ci|length) > 0 then "POSSIBLE_API" elif ($urls|length) > 0 then "POSSIBLE_EXTERNAL_ENDPOINTS" else "NO_OBVIOUS_API" end)
}' > "$OUT_JSON"
echo "Wrote $OUT_JSON"
- Giải thích các bước chính
- Step 1: ripgrep scan tĩnh cho env vars, SDK names, URL literal, CI references. Lưu kết quả để tra cứu.
- Step 2: gom URL ngoài, loại bỏ localhost/file.
- Step 3: curl nhẹ tối đa N urls để xem status code – không gửi auth. Nếu 401/403/401+WWW-Authenticate xuất hiện thì đó là dấu hiệu mạnh cần API/cred.
- Step 4: tổng hợp JSON giúp nhập vào bảng.
- Các trường JSON để điền vào bảng tổng hợp (bắt buộc)
- repopath – đường dẫn repo local hoặc repourl khi thu từ Git remote
- timestamp – thời điểm quét
- env_matches – mảng dòng tìm thấy chứa tên biến môi trường (file:line)
- sdk_matches – mảng dòng tìm thấy tên SDK/dependency (file:line)
- external_urls – mảng URL literal phát hiện trong code/docs
- ci_matches – mảng dòng từ CI/CD/Dockerfile có tham chiếu secrets/env
- endpointtestsraw – mảng objects { url, http_status } từ curl thử nghiệm
- verdict – one of NOOBVIOUSAPI | POSSIBLEEXTERNALENDPOINTS | POSSIBLE_API
- notes – reviewer note ngắn (nên fill thủ công)
- reviewer – initials của người quét
- Hướng dùng nhanh
- Chạy script: ./scan-api-signs.sh /path/to/repo result.json
- Mở result.json bằng jq để review: jq ‘.’ result.json
- Quy tắc quyết định khi import: nếu verdict==POSSIBLEAPI hoặc endpointtests shows 401/403 -> mark NEEDSMANUALREVIEW và run runtime check 30 phút theo checklist.
- Ghi chú an toàn
- Curl chỉ GET, timeouts ngắn. Không cố gắng brute-force hay đăng nhập. Nếu script phát hiện domain thương mại (serpapi, openai, googleapis) treat as high-risk ngay và không thử thêm.
Bảng dữ liệu tổng hợp repo và trường bắt buộc
Mục tiêu của bảng là chuẩn hóa thông tin đầu vào để đội viết và reviewer có thể so sánh, lọc và kiểm chứng nhanh. Mình trình bày mẫu schema (CSV / Google Sheet) và giải thích từng trường, định dạng giá trị, quy tắc điền, và ví dụ mẫu để bạn dùng trực tiếp.
Mẫu header CSV / Google Sheet (1 dòng)
- repourl | primarytype | secondarytypes | evidenceentrypoints | apidependencyscore | lastcommit | license | runstatus | reviewer | notes
Giải thích và quy tắc điền từng trường
- repo_url
- Nội dung: URL đầy đủ tới repo (https://github.com/owner/name hoặc gitlab.com/…).
- Quy tắc: bắt buộc, duy nhất, không dùng redirect. Nếu repo là monorepo và bạn phân loại subproject, ghi thêm subpath trong notes.
- Ví dụ: https://github.com/example/seo-crawler
- primary_type
- Nội dung: loại chức năng chính theo taxonomy của bạn (ví dụ crawl, auditonpage, loganalysis, keywordtool, serpscraper, internallink, schema, sitemap, image_seo, performance, utilities).
- Quy tắc: một giá trị duy nhất, dùng từ khóa chuẩn trong taxonomy. Nếu không rõ, để "utilities" và note giải thích.
- Ví dụ: crawl
- secondary_types
- Nội dung: các loại phụ, nếu có, phân cách bằng dấu phẩy (no space) hoặc pipe nếu bạn thích (ví dụ auditonpage,internal_link).
- Quy tắc: dùng cùng vocabulary như primary_type. Nếu không có, để trống.
- Ví dụ: auditonpage,internal_link
- evidence_entrypoints
- Nội dung: chứng cứ cho entrypoint chạy được độc lập. Ghi dạng list; mỗi mục là "type|path|command" để máy đọc và con người hiểu.
- Format khuyến nghị: entrytype|fileorcommand|short_note
- entrytype ∈ {cli, module, docker, example}
- fileorcommand: đường dẫn file (bin/cli) hoặc command ví dụ
- short_note: 1-6 từ mô tả
- Ví dụ:
- cli|bin/seo-crawl|"usage: crawl –start"
- docker|Dockerfile| "docker-compose demo"
- module|src/audit/main.py|"importable audit.run()"
- Quy tắc: ít nhất một entry nếu repo cho là runnable. Nếu chỉ là library, nêu module importable.
- apidependencyscore
- Nội dung: chỉ số đánh giá phụ thuộc API theo quy 0-10.
- Định nghĩa:
- 0 = Không dấu hiệu API; core chạy offline.
- 1-3 = Có vài dấu hiệu mơ hồ (endpoint public, optional enrichment).
- 4-6 = Có SDK hoặc env var mẫu; có khả năng cần key cho một số tính năng.
- 7-9 = Rõ ràng phụ thuộc API cho chức năng chính.
- 10 = Bắt buộc API key/SDK; không thể chạy core without key.
- Quy tắc: reviewer ghi số nguyên. Luôn kèm notes giải thích ngắn (ví dụ "SDK openai in deps" hoặc "requests to api.serpapi.com observed").
- Ví dụ: 2
- last_commit
- Nội dung: timestamp ISO (YYYY-MM-DD) của commit gần nhất trên default branch.
- Quy tắc: bắt buộc; dùng git API hoặc gh cli để lấy. Nếu repo archived, thêm chú thích trong notes.
- Ví dụ: 2026-04-12
- license
- Nội dung: ký hiệu license chuẩn (SPDX) hoặc "unknown".
- Quy tắc: ưu tiên SPDX id (MIT, Apache-2.0, GPL-3.0-only). Nếu multiple, liệt kê cả và note.
- Ví dụ: MIT
- run_status
- Nội dung: trạng thái chạy kiểm thử nhanh nhất (one of predefined).
- Giá trị phép: runnable | requiressetup | needsapikeys | failsbuild | manualreviewneeded | unknown
- Giải thích ngắn:
- runnable: chạy local với sample input và không cần key.
- requires_setup: cần DB, binary, hoặc steps but no external API.
- needsapikeys: core yêu cầu key; không thể tiếp tục.
- fails_build: không build/run trong 30 phút.
- manualreviewneeded: ambiguous, cần reviewer deeper check.
- Ví dụ: requires_setup
- reviewer
- Nội dung: initials hoặc username người kiểm tra (ví dụ TD, minh).
- Quy tắc: bắt buộc cho mỗi dòng sau khi được triage; dùng định dạng consistent.
- Ví dụ: annt
- notes
- Nội dung: ghi chú ngắn, evidence summary hoặc cảnh báo pháp lý. Không dài quá 200 chữ.
- Quy tắc: phải nêu bằng chứng cụ thể ngắn gọn, ví dụ file path hoặc log snippet, và tag [KHÔNG CHẮC] nếu còn mơ hồ.
- Ví dụ: "uses puppeteer; Dockerfile lacks chrome binary; optional SERP enrich via serpapi (env SERPAPI_KEY) — [KHÔNG CHẮC]"
Một số hướng dẫn vận hành thực tế khi điền bảng
- Nếu evidence_entrypoints liệt kê nhiều mục, sắp theo độ ưu tiên: docker, cli, module, example.
- Luôn đặt apidependencyscore kèm một short note giải thích (cột notes). Không để score trống.
- lastcommit là chỉ số duy trì; nếu >24 tháng, mark runstatus manualreviewneeded.
- Khi runstatus == needsapikeys, trong notes nêu rõ biến môi trường hoặc domain API (vd. OPENAIAPI_KEY, api.serpapi.com).
- Đặt reviewer khác với người thu thập ban đầu để có kiểm chứng độc lập.
Ví dụ một hàng CSV hoàn chỉnh
- https://github.com/example/seo-crawler | crawl | auditonpage | cli|bin/seo-crawl|"usage: crawl –start";docker|Dockerfile|"compose demo" | 2 | 2026-04-12 | MIT | requiressetup | annt | "crawler core runs offline; optional SERP enrich needs SERPAPIKEY in .env.example"
Kết thúc: mẫu này vừa cho máy đọc dễ parse, vừa đủ thông tin cho biên tập và reviewer ra quyết định nhanh. Nếu bạn muốn, mình sẽ xuất kèm mẫu Google Sheet với validation rules (drop-down cho primarytype và runstatus, numeric validation cho apidependencyscore) để paste trực tiếp vào team.
Quy trình kiểm thử nhanh 30 phút cho mỗi repo
Mục tiêu: trong tối đa 30 phút xác định nhanh liệu một repo công cụ SEO có phù hợp với tiêu chí "không phụ thuộc API" và thu đủ bằng chứng để ghi vào bảng tổng hợp. Quy trình này timeboxed, lặp được, và cho ra kết luận tạm thời: KHÔNG-API | CẦN-API | YÊU CẦU-LOGIN | MANUAL_REVIEW. Mỗi bước có lệnh mẫu để bạn chạy và thu bằng chứng.
0: Chuẩn bị nhanh (trước khi bắt đầu)
- Mở terminal, đảm bảo có rg (ripgrep), curl, docker, jq, git. Nếu có mitmproxy/strace thì tốt để bắt kết nối.
- Tạo thư mục evidence/<repo-name>/ để lưu stdout, file log và snapshot.
- 0-5 phút – đọc README + manifest
Mục tiêu: tìm bằng chứng trực tiếp về cách chạy, nhu cầu API và ví dụ dùng. Các việc thực hiện:
- Mở README.md, tìm sections: Usage, Quickstart, Requirements, Environment.
- Mở manifest files: package.json, requirements.txt, pyproject.toml, go.mod, Dockerfile, docker-compose.yml, .env.example, .github/workflows/*.yml.
- Ghi nhanh vào notes: có lệnh CLI sample không? có .env.example chứa *_KEY? có Dockerfile kéo binary từ external?
Lệnh mẫu:
# clone once
git clone <repo_url> repo && cd repo
# save README head lines
sed -n '1,200p' README.md > ../evidence/README_snippet.txt
# list common manifests
ls -1 package.json requirements.txt pyproject.toml go.mod Dockerfile docker-compose.yml .env.example .github/workflows 2>/dev/null > ../evidence/manifests.txt
Kết quả mong đợi: nếu README có example command và không nhắc API key, gắn flag "READMEOK". Nếu .env.example có APIKEY hoặc CI workflow refs secrets, gắn flag "POTENTIAL_API".
- 5-10 phút – scan tĩnh mã nguồn bằng regex
Mục tiêu: tìm dấu hiệu SDK, biến môi trường API, endpoint cứng, hoặc thư viện cloud. Việc thực hiện:
- Chạy ripgrep với bộ pattern quan trọng; lưu kết quả vào file evidence.
Lệnh mẫu:
# patterns cơ bản
rg -n --hidden --no-ignore -S "(API[_-]?KEY|APIKEY|ACCESS_TOKEN|CLIENT_SECRET|OPENAI|SERPAPI|GOOGLE_API|AWS_ACCESS_KEY_ID|AZURE|serpapi|googleapis|aws-sdk|boto3|requests_oauthlib|openai|serper|semrush|ahrefs)" > ../evidence/rg_keys.txt || true
# tìm URL endpoint literal
rg -n --hidden --no-ignore -o "https?://[^\s'\"`]+" > ../evidence/rg_urls.txt || true
# tìm HTTP client calls
rg -n --hidden --no-ignore "(requests\.get|axios\(|fetch\(|http\.Get\(|curl )" > ../evidence/rg_http_calls.txt || true
Cách đọc nhanh:
- Nếu thấy SDK tên thương hiệu hoặc biến env *APIKEY -> tăng đánh dấu "CẦN-API".
- Nếu chỉ thấy requests to google.com/search hoặc other public pages -> khả năng là scraping HTML, không API key.
- 10-20 phút – chạy sample nhanh (network on, rồi off)
Mục tiêu: reproduce example, quan sát runtime behavior và xác định dependency network. Phần A – chạy sample với network on:
- Nếu README có command sample, chạy với verbose/–dry-run nếu có. Lưu stdout/stderr.
Lệnh mẫu:
# ví dụ chạy CLI nếu có
# thay bằng command thực tế từ README
./bin/seo-tool --example-flag > ../evidence/run_on_stdout.txt 2> ../evidence/run_on_stderr.txt || true
- Quan sát logs cho các host được gọi. Nếu không có logs, bật tracing network đơn giản:
# chạy trong background để log connections (Linux)
sudo ss -tnp | rg seo-tool > ../evidence/ss_before.txt
# hoặc dùng strace để log connect syscalls nếu binary/entrypoint đơn giản
strace -f -e trace=network -o ../evidence/strace.log ./bin/seo-tool --example-flag 2>&1 || true
Phần B – chạy sample với network disabled:
- Mục đích: xem tool có hoạt động core khi không có internet.
- Cách nhanh: dùng docker run –network none nếu có Dockerfile, hoặc tắt network tạm thời (cẩn thận).
# nếu có Dockerfile with ENTRYPOINT
docker build -t temp-repo . 2>/dev/null || true
docker run --rm --network none -v $(pwd):/work -w /work temp-repo ./bin/seo-tool --example-flag > ../evidence/run_off_stdout.txt 2> ../evidence/run_off_stderr.txt || true
Kết luận tạm thời:
- Nếu sample chạy và tạo output tương tự cả khi network off -> classify KHÔNG-API (core runs offline).
- Nếu chạy thất bại với error về missing API key or unable to reach api.domain -> classify CẦN-API.
- Nếu chạy chỉ cần login session cookie -> classify YÊU CẦU-LOGIN.
- Nếu ambiguous (runs but misses features) -> classify MANUAL_REVIEW with note what missing.
- 20-30 phút – capture evidence và phân loại
Mục tiêu: đóng gói bằng chứng, ghi metadata, quyết định final label tạm thời. Việc thực hiện:
- Thu thập files evidence/*, tóm tắt bằng 1 file verdict.txt gồm:
- repourl, primarytype, runstatus (runnable | requiressetup | needsapikeys | failsbuild | manualreviewneeded), apidependency_score (0-10), evidence pointers (paths), reviewer initials, timestamp.
- Ghi short note 1-2 câu cho biên tập: ví dụ "Core crawler runs offline on sample; optional SERP enrich via SERPAPI documented in .env.example – api_score 2 – notes: .env.example line 4".
Mẫu lệnh đóng gói evidence:
# create verdict
cat > ../evidence/verdict.txt <<EOF
repo: <repo_url>
run_status: $(grep -q "missing API" ../evidence/run_on_stderr.txt && echo "needs_api_keys" || echo "runnable")
api_dependency_score: 2
evidence_files: $(ls -1 ../evidence | tr '\n' ',' )
reviewer: <your_initials>
timestamp: $(date -Iseconds)
notes: <short note>
EOF
Quy tắc quyết định nhanh (rule-of-thumb)
- any SDK import or explicit API_KEY variable in README or .env.example -> classify CẦN-API unless README documents optional mode and you validated offline core works.
- literal calls to api.thirdparty.com or presence of secrets in CI -> classify CẦN-API.
- only requests to public HTML pages and no SDK/env var -> likely KHÔNG-API but add ToS risk note.
- if ambiguous, mark MANUALREVIEW and set apidependency_score >=3.
Ghi chú vận hành
- Luôn lưu stdout/stderr và strace/ss logs; chúng là bằng chứng bạn sẽ gắn vào bảng.
- Nếu bạn gặp repo mixed-mode (core offline, enchancement via API) hãy ghi rõ field runstatus and notes: "coreok – enrichmentrequiresKEY".
- Nếu thấy dấu hiệu bypass CAPTCHA hoặc external captcha-solver libs, flag đỏ và ghi cảnh báo pháp lý trong notes.
Kết thúc 30 phút: bạn có verdict, evidence files, và một dòng note để copy vào bảng tổng hợp. Làm theo quy trình này cho mỗi repo để đảm bảo nhất quán giữa các reviewer.
Phương pháp rút ra điểm mạnh thực dụng từ README, issues và thử nhanh
Mục tiêu: trong lần đọc nhanh README, issues và một thử nghiệm ngắn, bạn cần rút ra các điểm mạnh thực dụng có thể trích ra trực tiếp vào phần per-tool của bài. Phương pháp dưới đây cho bạn một khung có thể thực hiện lặp lại, gồm thang bằng chứng A/B/C, mẫu mapping evidence -> claim và mẫu cách ghi nguồn cùng mức độ tin cậy.
- Nguyên tắc vận hành ngắn
- Luôn ưu tiên bằng chứng thực thi hơn tuyên bố văn chương. Một câu trong README không bằng một lệnh có thể chạy được và output mẫu.
- Ghi mọi bằng chứng theo 3 yếu tố: nguồn file/line, snapshot output, và tag mức độ tin cậy (A/B/C).
- Mỗi claim về điểm mạnh phải kèm 1 mẫu evidence tối thiểu: A hoặc B. Nếu chỉ có C, ghi rõ là "không xác minh".
- Thang bằng chứng (tiêu chí nhanh)
- Cấp A (chắc chắn): có command/example trong README hoặc scripts kèm input mẫu, bạn chạy được trong 30 phút và thu được output giống ví dụ; hoặc có test/CI chạy thành công với fixture minh họa. Mức tin cậy cao.
- Cấp B (hỗ trợ): README có ví dụ lệnh hoặc output mẫu nhưng không chạy ngay (thiếu dependency) hoặc có issue/PR diễn tả use-case thực tế nhưng chưa có sample output tái lập. Mức tin cậy trung bình, cần note "cần xác minh".
- Cấp C (yếu): chỉ có mô tả tính năng bằng ngôn từ, roadmap hoặc feature request; không có ví dụ hay logs. Không đủ để rút thành điểm mạnh, chỉ dùng như gợi ý.
- Quy trình 15 phút để rút claim thực dụng
- Bước 0 (0-2 phút) đọc nhanh mục Usage/Quickstart và .env.example. Tìm lệnh mẫu và bất kỳ biến env như API_KEY.
- Bước 1 (2-6 phút) scan tĩnh: rg/grep tìm keywords liên quan chức năng (ví dụ internal link, sitemap, audit, serp). Lưu ra list file/line để trích dẫn.
- Bước 2 (6-12 phút) thử chạy example nhỏ: dùng sample input hoặc examples/fixtures. Chụp stdout và, nếu có output file, lưu snapshot.
- Bước 3 (12-15 phút) soạn evidence entry: nguồn (file:line hoặc issue#), bản copy output (hoặc path file), và gán mức A/B/C. Nếu không thể chạy, gán B hoặc C và nêu nguyên nhân.
- Mapping evidence -> claim, ví dụ cụ thể
- Claim: "Tối ưu internal links"
- Evidence cấp A: README có lệnh
./cli link-graph --site example.com --out graph.json+ bạn chạy lệnh, file graph.json chứa nodes/edges. Trích dẫn: README.md line X; evidence file: evidence/graph.json. Mức tin cậy: A. - Evidence cấp B: README mô tả tính năng và có screenshot graph nhưng không có sample output; hoặc issue user kèm hình ảnh export graph. Mức tin cậy: B.
- Evidence cấp C: chỉ có câu "provides internal link analysis" trong features list. Mức tin cậy: C.
- Mẫu sample output graph (JSON nhỏ):
{
"nodes": [
{"id": "https://example.com/", "title": "Home"},
{"id": "https://example.com/blog/post-1", "title": "Post 1"}
],
"edges": [
{"source": "https://example.com/", "target": "https://example.com/blog/post-1", "anchor": "Read more", "nofollow": false}
]
}
- Ghi claim vào bài: "Rút internal link graph với xuất JSON nodes/edges (evidence: README.md#Usage, run output evidence/graph.json) — mức tin cậy A."
- Claim: "Audit on-page cho meta-description và H1"
- Evidence A: sample CSV chứa rows: url, status, titleok, metadesclen, h1count. Bạn chạy example và CSV khớp format.
- Evidence B: tests/fixtures có asserts cho title/meta; no sample CSV but tests imply structure.
- Evidence C: chỉ có bullet "checks meta tags".
- Cách ghi nguồn và biểu diễn mức độ tin cậy trong bài
- Format trích dẫn trên một dòng ngắn cho mỗi claim:
- [ToolName] — claim short. Evidence: README.md#Usage (line X), example run: evidence/run_stdout.txt. Confidence: A.
- Nếu evidence là issue/PR, ghi thêm link issue và trích đoạn comment. Ví dụ:
- Evidence: issue#42 comment by @user "ran cli –audit on 200 URLs, output report.csv" (link), Confidence: B.
- Không dùng language tưởng tượng. Nếu claim dựa trên B hoặc C, thêm câu nhắc rõ: "chưa xác minh cục bộ" hoặc "dựa trên docs".
- Template ngắn để ghi vào bảng tổng hợp (một dòng)
- fields: repourl | shortclaim | evidence_refs | confidence
- Ví dụ:
- https://github.com/org/repo | "Export internal link graph (nodes/edges JSON)" | README.md#usage (L23), evidence/graph.json | A
- Quy ước viết câu mô tả điểm mạnh trong bài
- Cấu trúc 3 câu ngắn:
- Chức năng chính: "Tool X xuất internal link graph dạng JSON (nodes/edges)."
- Lợi ích thực dụng: "Dễ tích hợp vào pipeline graph analysis; dùng để phát hiện orphan pages và anchor distribution."
- Bằng chứng & cảnh báo: "Bằng chứng: README.md#Usage + thử chạy local (evidence/graph.json). Confidence: A. Lưu ý: không thay thế dữ liệu clickstream."
- Nếu confidence B hoặc C, bắt đầu câu thứ 3 bằng "Cần kiểm chứng: …"
- Khi evidence là screenshot hoặc sample image
- Kèm metadata về kích thước, đường dẫn file và mô tả ngắn. Ví dụ:
- Screenshot: docs/screens/linkgraph.png — shows force-directed graph with node sizes representing in-degree. Confidence: B (screenshot không cho JSON schema).
- Nếu claim dựa vào hình ảnh, cố gắng chạy thử để lấy native output; nếu không được, hạ confidence.
- Một số lưu ý phòng ngừa
- Nếu README có lệnh nhưng kèm biến env tên *_KEY, đừng gán A ngay. Chỉ gán A nếu bạn chạy được mà không cần key, hoặc xác định rõ key là optional.
- Nếu evidence từ issues: kiểm tra ngày và activity; một issue cũ chưa trả lời có confidence thấp.
- Luôn lưu artifacts runtime (stdout, file outputs, strace nếu dùng) vào thư mục evidence để làm bằng chứng cho biên tập viên kỹ thuật.
- Mẫu ngôn ngữ ghi chú trong phần caveats
- Viết rõ: "Confidence A/B/C" và "evidence: path hoặc URL". Ví dụ: "Confidence B — docs include sample CSV but sample requires dataset not included; manual run not performed."
Kết luận ngắn
- Áp dụng quy trình này cho mỗi tool: đọc README -> scan tĩnh -> thử chạy -> ghi evidence & confidence. Chỉ công bố điểm mạnh khi có evidence cấp A hoặc B kèm chú giới hạn. Dùng mẫu JSON/CSV/graph để minh họa output khi có A, và luôn ghi nguồn file:line hoặc issue link để người đọc kiểm chứng.
Kịch bản người dùng để gắn điểm mạnh với công việc cụ thể
Dưới đây là 8 kịch bản điển hình. Với mỗi kịch bản mình nêu: mục tiêu công việc, điểm mạnh thực dụng của loại công cụ tương ứng, và cách bạn/đội xác thực nhanh tính đúng nghĩa của điểm mạnh khi đánh giá repo.
- Audit hàng tuần (weekly on-page audit)
- Mục tiêu: phát hiện regressions on-page trên tập URL quan trọng mỗi tuần.
- Điểm mạnh thực dụng: chạy cục bộ nhanh, output machine-readable (CSV/JSON) cho diffs, tích hợp với CI để fail build khi số issue vượt ngưỡng.
- Kiểm chứng nhanh: README có lệnh CLI ví dụ để chạy theo danh sách URL; có flag –output csv; sample report; test run trên 10 URL tạo CSV chứa columns như url, issue_code, severity.
- Crawl cho migration (migration-focused crawler)
- Mục tiêu: crawl site hiện tại để thu thập URLs, status, canonical, hreflang, redirect chains trước migration.
- Điểm mạnh thực dụng: khả năng giới hạn depth, respect robots, cấu hình dedupe query params, xuất redirect chain và sitemap-ready URL list.
- Kiểm chứng nhanh: config mẫu chứa max_depth, dedupe rules; command sample crawl –max-pages N; output cung cấp redirect chain per URL hoặc sitemap.xml generator.
- Log analysis cho session stitching (server log -> session stitching)
- Mục tiêu: nối các request thành session, map tới landing pages và conversion funnel, xuất cho attribution.
- Điểm mạnh thực dụng: parser cho common log formats, configurable session window, join key để enrich với crawl data, output session-level CSV.
- Kiểm chứng nhanh: repo có sample log fixture + script parse producing sessions.csv with fields sessionid, startts, pages[], useragent; config param sessiontimeout (s).
- Keyword harvest cục bộ (local n-gram / keyword extractor)
- Mục tiêu: trích keyword từ content nội bộ để build topic clusters, không phụ thuộc công cụ API từ khóa trả phí.
- Điểm mạnh thực dụng: chạy trên corpus local (HTML/text), options language/stopwords, min_freq thresholds, xuất candidate list ranked (tf-idf).
- Kiểm chứng nhanh: có script extract –input path/to/html –min-freq 3 –out keywords.csv; keywords.csv gồm term, freq, ngram_length, score.
- SERP sampling (SERP scraper without paid API)
- Mục tiêu: lấy snapshot SERP cho tập query nhỏ để so sánh thay đổi ranking hoặc kiểm tra SERP features.
- Điểm mạnh thực dụng: scraping HTML SERP với proxy/headless optional, configurable geo/domain, sample-mode (n queries, 1 page), output normalized (position, url, snippet, feature flags).
- Kiểm chứng nhanh: README nêu cách chạy sample queries list; sample output shows positions and feature flags; kiểm tra tool có tùy chọn proxy và rate-limit.
- Internal link audit (site graph / orphan detection)
- Mục tiêu: xây dựng graph internal links, tìm orphan pages, compute in/out-degree để ưu tiên tối ưu nội bộ.
- Điểm mạnh thực dụng: sản sinh graph format (GraphML/GEXF/edges CSV), canonicalization rules, dedupe query params, support seed URLs or sitemap input.
- Kiểm chứng nhanh: command example generate-graph –site example.com –out graph.gexf; open graph.gexf hoặc edges.csv chứa source,target,anchor,no_follow.
- Schema generator / validator (JSON-LD)
- Mục tiêu: tạo hoặc validate schema.org JSON-LD cho content hàng loạt, dễ tích hợp vào CMS pipeline.
- Điểm mạnh thực dụng: templates per content type (Article/Product), validator offline, output injectable snippets and a report of missing required properties.
- Kiểm chứng nhanh: repo có templates/*.jsonld, command generate –type Article –input content.md –out schema.jsonld; validator cli check –file schema.jsonld returns OK or list of missing fields.
- Image audit (alt text, size, srcset)
- Mục tiêu: kiểm tra alt attr, detect missing alt, oversized images, and produce remediation suggestions.
- Điểm mạnh thực dụng: batch scan local image folder or crawled images, compute dimensions/filesize, detect missing/duplicate alt, suggest srcset breakpoints, support lossless compression local tools.
- Kiểm chứng nhanh: sample run image-audit –input path –out imagereport.csv; report columns: url, imgsrc, width, height, filesize, alt_text, suggestion.
Hướng dẫn ngắn để bạn gắn điểm mạnh trong bài
- Mỗi tool trong bài nên có một câu ngắn nêu "điểm mạnh thực dụng" theo cấu trúc: chức năng chính + lợi ích cho workflow + evidence reference. Ví dụ: "Tool X – crawl migration: thu thập redirect chains và xuất sitemap-ready list (evidence: README#Usage + examples/redirects.json). Confidence: A/B."
- Khi evidence chưa đủ (chỉ docs, không chạy được), ghi rõ confidence B hoặc C và yêu cầu kiểm thử 30 phút như checklist trong phân tích.
Mình đã gói đủ 8 kịch bản và cách diễn giải điểm mạnh thực dụng tương ứng để bạn dùng trực tiếp khi soạn phần công cụ theo loại.
Tiêu chí xếp hạng ưu tiên khi đưa vào bài
Mục tiêu: cung cấp khung chấm điểm minh bạch để sắp thứ tự repo đưa vào bài theo mức độ hữu dụng thực tế cho đội SEO, đồng thời tránh bias chỉ dựa vào stars. Mình đưa ra trọng số gợi ý, công thức điểm tổng và quy tắc tie-breaker cùng lưu ý vận hành.
- Các tiêu chí chính và trọng số (tổng chuẩn hóa = 100)
- Tính ứng dụng thực dụng (Usefulness) – 40 điểm
- Mức độ giúp giải việc SEO cụ thể – crawl, audit, log, v.v.
- Bằng chứng: ví dụ lệnh/cli, sample output, workflow tích hợp.
- Độ ổn định / duy trì (Stability & Maintenance) – 20 điểm
- Last commit trong 24 tháng, issue response, test/CI presence.
- Độ phổ biến và cộng đồng (Popularity) – 15 điểm
- Stars, forks, contributors. Dùng để ưu tiên review, không là quyết định duy nhất.
- Dễ dùng / trải nghiệm triển khai (Usability) – 15 điểm
- Dockerfile, setup scripts, sample config, docs rõ ràng.
- Rủi ro phụ thuộc API và pháp lý (Risk) – 10 điểm, tính theo chiều âm
- Nếu repo yêu cầu API khoá bên thứ ba cho chức năng core hoặc có code bypass anti-bot, trừ điểm. Nếu không có API dependency, được cộng thấp.
- Công thức điểm (ví dụ)
- Score = 0.4Usefulness_norm + 0.2Stabilitynorm + 0.15*Popularitynorm + 0.15Usability_norm – 0.1Risk_norm
- Mỗi thành phầnnorm chuẩn hóa 0-100 trước khi nhân trọng số. Risknorm = 0 nếu không có rủi ro, 100 nếu rủi ro cao.
- Chi tiết cách đánh từng tiêu chí (phiên bản ngắn)
- Usefulness: đánh 0-100 dựa trên evidence: có CLI + sample output (≥80), chỉ docs mô tả chức năng (40-60), không có ví dụ thực tế (≤30). Gắn thêm +10 nếu core feature chạy offline không cần API.
- Stability: 100 nếu last commit trong 6 tháng, tests + CI pass, maintainer active; 50 nếu cập nhật trong 12-24 tháng; 0 nếu >24 tháng hoặc archived.
- Popularity: hợp nhất stars (60%) và forks/contributors (40%). Nhưng clamp giá trị tối đa không vượt 30 điểm sau chuẩn hóa để tránh át các tiêu chí khác.
- Usability: 100 khi có Dockerfile + examples + config mẫu + one-line install; giảm khi thiếu bước reproducible.
- Risk: scan mã/CI tìm APIKEY, SDKs, endpoints api.*; nếu phát hiện API required cho core, Risknorm = 100. Nếu optional: 50. Nếu chỉ scraping public HTML và có politeness config, Risk_norm = 10.
- Cách tránh bias stars-only
- Giới hạn trọng số Popularity nhỏ hơn Usefulness và Stability.
- Khi sorting, nếu hai repo có score chênh < 3 điểm, ưu tiên repo có Usefulness cao hơn, không stars.
- Trong trang xuất bản, hiển thị 3 chỉ số hàng đầu cho mỗi repo: Usefulness, Stability, Risk để độc giả thấy logic sắp xếp.
- Prioritize manual spot-check cho repo ít sao nhưng score Usefulness cao.
- Tie-breaker và sàng lọc cuối
- Tie-breaker: 1) Usefulness, 2) Stability, 3) lower Risk, 4) higher Usability, 5) stars.
- Loại trừ tự động: license incompatible, archived > 24 tháng, hoặc core yêu cầu API key mà bài chủ yếu là "không API".
- Vận hành thực tế – hướng dẫn nhanh cho bạn
- Giai đoạn thu thập: tính điểm sơ bộ tự động bằng script; lọc top 50 theo Score.
- Giai đoạn kiểm thử: dành 30 phút/run cho mỗi repo top 50 theo checklist runtime; cập nhật các thành phần Usefulness, Risk, Usability thực tế.
- Trạng thái xuất bản: chỉ đưa repo có Score ≥ threshold do bạn đặt và Risk_norm ≤ 40; với repo borderline, gắn note "needs verification".
Kết luận ngắn: khung này giúp bạn ưu tiên công cụ dựa trên giá trị thực dụng hơn là tiếng vang cộng đồng. Khi áp dụng, giữ log evidence cho mỗi field để biên tập có thể giải trình lựa chọn.
Cấu trúc dàn bài xuất bản cho phần tổng hợp
Mục tiêu ngắn gọn: cung cấp khung xuất bản rõ ràng để phần tổng hợp repo SEO không API có thể được viết, kiểm chứng và xuất bản nhanh. Dàn bài phân thành 5 khối chính: mở bài phương pháp, taxonomy + tiêu chí chọn, phần tổng hợp theo loại (per-type highlights), cảnh báo pháp lý/ToS, phụ lục evidence table. Mỗi khối kèm chỉ dẫn nội dung bắt buộc, bằng chứng cần đính kèm và mẫu ngắn để nhóm viết/biên tập dễ thực hiện.
- Intro + Methodology (khoảng 1 đoạn tóm tắt + 1 đoạn quy trình)
- Nội dung: tóm tắt mục tiêu tổng hợp, định nghĩa vận hành "không có kết nối API" được dùng ở bài, phạm vi nền tảng (ưu tiên GitHub, mở rộng GitLab), mốc thời gian cập nhật (24 tháng).
- Phương pháp tuyển chọn: liệt kê bước thu thập (queries GitHub), sàng lọc tự động (scan deps, .env, CI), quy trình kiểm tra 30 phút (static scan, curl test, run sample with network toggled), và cách đánh dấu [KHÔNG CHẮC] cho repo cần kiểm chứng sâu.
- Bằng chứng bắt buộc: link script quét, log truy vấn, tiêu chí loại trừ tóm tắt. Viết rõ ai chịu trách nhiệm kỹ thuật để tái hiện.
- Taxonomy + Selection (khung phân loại và tiêu chí sàng lọc)
- Danh sách loại công cụ (mỗi loại 1 dòng định nghĩa ngắn): crawl/thu thập, audit on-page, log analysis, keyword extraction, SERP scraper (HTML-based), internal-link analysis, schema tools, sitemap generator, image SEO tools, performance tools, utilities kỹ thuật.
- Tiêu chí gán nhãn primary/secondary: entrypoint riêng, sample output, code density/module riêng, docs/tests. Ghi rõ điểm tối thiểu cần có để gán nhãn (ví dụ evidence_score ≥ 45).
- Tiêu chí sàng lọc đầu vào: license (OSI-compatible), last pushed <= 24 months, không archived, buildable/runable (smoke test). Mẫu note nếu loại: vì phụ thuộc API / license / dead.
- Trường lớp dữ liệu trong bảng sơ bộ để fill: repourl | primarytype | secondarytypes | apidependencyscore | lastcommit | license | run_status | reviewer.
- Per-type highlights (mỗi loại 1 đoạn, format tiêu chuẩn)
- Mục đích: cho reader thấy trong mỗi loại có những repo tiêu biểu, và rút ra 2-3 điểm mạnh thực dụng gắn với workflow SEO.
- Format bắt buộc cho mỗi loại:
- Lead-in 1 câu nêu vai trò loại.
- Top 3 tools (tên + repo_url) với 2 trường ngắn cho mỗi tool:
- Điểm mạnh thực dụng (1-2 câu): nói rõ lợi ích cho practitioner, ví dụ "rút internal link graph nhanh giúp ưu tiên migrate canonical".
- Hạn chế vận hành ngắn (1 câu): ví dụ "cần headless chrome để render JS".
- Kịch bản ứng dụng điển hình (1-2 bullets): ai dùng, khi nào, output cần có.
- Yêu cầu evidence: mỗi điểm mạnh phải kèm 1 bằng chứng trong repo (CLI example, sample output, issue report) và trích dẫn line/URL.
- Caveats pháp lý / Terms of Service (section ngắn nhưng sắc)
- Nội dung bắt buộc: tóm tắt rủi ro ToS khi scraping; nguyên tắc vận hành an toàn (respect robots.txt, contact UA, rate-limit, không bypass CAPTCHA); lưu ý về dữ liệu cá nhân và privacy.
- Hình thức: bullet checklist cho người dùng trước khi chạy tool (sandbox, proxy controlled, user-agent contact).
- Mẫu disclaimer text ngắn để copy-paste vào bài và hướng dẫn biên tập ghi rõ: "Không phải tư vấn pháp lý; kiểm tra ToS mục tiêu trước khi chạy".
- Appendix: Evidence table + phương pháp kiểm chứng
- Bảng dữ liệu chuẩn (máy đọc): mỗi dòng một repo; các trường bắt buộc:
- repourl | primarytype | secondarytypes | lastcommit | license | apidependencyscore | runstatus (passed/failed/partial) | evidenceentrypoints (path/command) | evidenceoutputpath | reviewer | notes
- Giải thích trường: apidependencyscore cách tính, run_status định nghĩa (passed = ran sample offline without API).
- Kèm checklist kiểm thử 30 phút (timebox): 0-5m README + manifest scan; 5-10m rg scan for API tokens/SDK; 10-25m run sample with network on/off; 25-30m capture logs, classify.
- Hướng dẫn lưu artifacts: stdout/stderr, lsof/strace snapshot, curl responses, và link lên storage nội bộ; tên file chuẩn hóa reposhortnameevidence_TIMESTAMP.zip.
Kết thúc và giao việc
- Ở cuối bài, đính kèm short handover checklist cho nhóm viết: top 8 repo per type đã được xác thực, mẫu đoạn mô tả điểm mạnh (3 câu), links evidence, và tag rủi ro. Biên tập viên chỉ lấy từ Appendix table và copy template per-type highlights để hoàn thiện nội dung xuất bản.
Kịch bản kiểm thử chéo và cập nhật định kỳ
Mục tiêu: giữ độ chính xác của danh sách repo và các nhãn "KHÔNG-API" theo chu kỳ, phát hiện thay đổi yêu cầu API hoặc rủi ro vận hành, và lưu lịch sử kiểm chứng rõ ràng để biên tập/tech review tra lại.
Tổng quan quy trình định kỳ
- Chu kỳ ngắn – 3 tháng: kiểm tra nhanh mọi repo trong danh sách 30 repo để phát hiện thay đổi rõ rệt (pushed:, CI workflow thay đổi, biến env mới xuất hiện, issues/PR gợi ý thay đổi). Thực hiện scan tự động + một lượt triage thủ công cho items flagged.
- Chu kỳ dài – 6 tháng: kiểm tra sâu từng repo mục tiêu – chạy lại kịch bản 30 phút runtime test, kiểm tra full CI/Docker/README, cập nhật tag apidependencyscore và evidence. Ghi changelog kiểm chứng phiên bản.
Nguyên tắc vận hành
- Automate first – triage second. Dùng script scan để tìm diff; chỉ gửi cho reviewer những repo có signal.
- Giữ bằng chứng cho mọi lần kiểm chứng – lưu artifacts (logs, curl responses, kết quả rg, stdout run) có timestamp.
- Phiên bản kiểm chứng là 1 chuỗi semantic-lite: verified-v{YYYYMMDD}-{checkerInitials}-{level}, level ∈ {quick, deep}. Ví dụ: verified-v20260719-MT-deep.
- Tự động re-scan hàng tháng (ci job)
- Trigger: cron job nội bộ (ví dụ GitHub Actions scheduler) chạy script trên danh sách repo.
- Script thực thi:
- git ls-remote/pushed: check pushed:>= lastverifieddate for each repo.
- rg scan trong tip commit cho patterns: API_KEY, secrets., imports của SDK tên thương hiệu, calls to api. domains, .env.example changes, .github/workflows changes.
- CI manifests check: diff .github/workflows, docker-compose, Dockerfile for new ENV or curl/secret usage.
- Output: JSON report per repo with fields: repourl, lastpushed, flags[], apidependencyscoredelta, artifactslinks.
- Threshold: nếu flags > 0 hoặc score tăng >1 -> enqueue triage.
- Quy trình triage nhanh (3-months cycle – ~per repo 10-30 phút)
- Người chịu trách nhiệm: reviewer kỹ thuật (dev reviewer).
- Bước:
- Mở report JSON, xem flags và diff highlight.
- Mở PR/commit thay đổi gần nhất, kiểm tra .env.example, Dockerfile, .github/workflows. Nếu thấy biến env chứa KEY/TOKEN hoặc new SDK import -> classify as "needs-deep-check".
- Thực hiện quick runtime check: curl suspected endpoints (no auth), run sample CLI minimal with –dry-run or –help. Nếu xuất hiện 401/403/Authorization header usage -> mark "requires-API".
- Ghi log kết quả, cập nhật apidependencyscore và run_status.
- Kết quả triage: accept (no API), warn (optional API/features), reject (requires API).
- Thời gian mục tiêu: 10-30 phút/repo flagged. Repos không flagged: update timestamp verified with quick note.
- Quy trình kiểm thử sâu (6-months cycle – ~per repo 30-60 phút)
- Người chịu trách nhiệm: dev reviewer + tech editor verification.
- Bước:
- Clone repo, chạy static scan đầy đủ (regex list), build container nếu Dockerfile, chạy unit tests nếu có.
- Thực thi 30-minute runtime test: run Quickstart command(s) with network on, capture network calls (strace/tcpdump) để xác định outbound domains; rerun with network disabled to check offline path.
- Nếu tool có "offline mode" test đó, record evidence that core feature works without API keys. Nếu không, capture exact missing-key error text.
- Nếu code gọi external API chỉ ở optional path, document which feature needs key and mark core capability still "no-API".
- Ghi chú: luôn chạy trong sandbox container; không gửi credential. Tất cả output, curl responses, strace logs nén và attach.
- Ghi phiên bản kiểm chứng và giữ changelog kiểm chứng
- Phiên bản kiểm chứng format: verified-vYYYYMMDD-INITIALS-level.
- Changelog kiểm chứng: một file kiểm chứng chung trong kho nội bộ (CSV/Markdown) có cột:
- repourl | lastverified | verifiedversion | verifier | level | result (accept/warn/reject) | scorebefore | scoreafter | artifactslink | notes
- Khi trạng thái thay đổi (ví dụ từ accept -> reject), tạo entry mới và gửi thông báo cho biên tập viên + team SEO.
- Cơ chế thông báo và hành động
- Nếu triage hoặc deep-check phát hiện "requires API" cho repo đã từng được liệt kê là "no-API", thực hiện:
- Ghi changelog entry và attach evidence.
- Thay đổi trạng thái trong dataset: mark as removedfromnoapilist = true; thêm note public nếu cần.
- Thông báo cho biên tập viên chịu phần đó để chỉnh nội dung bài trước khi xuất bản lại.
- Nếu phát hiện rủi ro ToS (captcha bypass, explicit disable robots), escalate to legal/compliance.
- Báo cáo tổng kết định kỳ
- Mỗi chu kỳ 3 tháng: tóm tắt số repo checked, số repo flipped status, top causes (CI changes, new SDK imports, new examples requiring keys).
- Mỗi 6 tháng: audit report to stakeholders with sample artifacts, list of accepted/rejected, recommended actions.
Checklist ký tay cho reviewer khi hoàn thành 1 repo (tickbox)
- [ ] Ran auto-scan and saved JSON report
- [ ] Reviewed README and CI/Docker changes
- [ ] Performed quick curl/run test with network on/off
- [ ] Captured artifacts and stored link
- [ ] Updated apidependencyscore and run_status
- [ ] Wrote changelog entry with verified_version
- [ ] Notified editor if status changed
Ghi chú vận hành ngắn
- Mọi thay đổi trạng thái phải có artifacts. Không được thay đổi nhãn dựa vào cảm quan.
- Lưu artifacts tối thiểu 12 tháng. Phiên bản kiểm chứng giúp audit và rollback nội dung nếu cần.
Cảnh báo tuân thủ pháp lý và ToS khi dùng scraping
Mục tiêu phần này là cung cấp cho bạn checklist vận hành để giảm rủi ro pháp lý và vi phạm điều khoản dịch vụ khi dùng công cụ scraping trong bộ tổng hợp. Nội dung nhắm vào quyết định vận hành: khi nào nên chạy, khi nào dừng, và cách ghi chú cảnh báo trong bài. Mình đưa ra checklist hành động, các tình huống cần xin phép, và mẫu wording disclaimer để chèn vào bài.
- Nguyên tắc cốt lõi
- Tôn trọng robots.txt không tự động đồng nghĩa hợp pháp, nhưng là minimum hành xử kỹ thuật. Nếu robots.txt chặn một path, coi đó như giới hạn kỹ thuật cần tuân thủ trừ khi có sự cho phép rõ ràng.
- Không cố gắng vượt cơ chế bảo vệ: bypass CAPTCHA, sử dụng dịch vụ giải CAPTCHA tự động, dùng kỹ thuật che giấu danh tính để né detection là hành vi rủi ro cao, dễ vi phạm ToS và có thể vi phạm luật trong một số vùng.
- Phân biệt scraping HTML hợp lệ và gọi API kín: nếu mã gọi endpoint api.* hay yêu cầu API key, xử lý như dịch vụ bên thứ ba – cần kiểm tra điều khoản và có thể xin phép.
- Checklist pháp lý vận hành (trước khi chạy trên bất kỳ target nào)
- Kiểm tra robots.txt:
- Fetch và parse robots.txt cho domain trước khi chạy.
- Tôn trọng Disallow, Crawl-delay khi có, và respect sitemap nếu nêu.
- Nếu bạn có lý do hợp lý để bỏ qua robots.txt (ví dụ hợp tác với chủ site), chỉ làm khi có bằng chứng bằng văn bản.
- Rate limits và concurrency:
- Thiết lập rate limit mặc định: concurrency per domain <= 5 và delay ngẫu nhiên trung bình 2-3s; điều chỉnh thấp hơn nếu robots.txt quy định crawl-delay lớn hơn.
- Dừng khi thấy 429/403 liên tiếp – pause và backoff exponential với jitter.
- Ghi log mọi response 429/403 và số lần lặp lại trước khi dừng.
- User-Agent và contact:
- Đặt User-Agent rõ ràng: tên công cụ + phiên bản + contact email hoặc URL liên hệ, ví dụ "my-seotool/0.1 (+mailto:ops@example.com)".
- Không giả mạo User-Agent trình duyệt để né detection; nếu bạn cần browser UA để xem nội dung, hãy dùng UA hợp lý và ghi chú rủi ro.
- Cookie/session và login:
- Nếu scraping yêu cầu login, chỉ dùng credentials hợp pháp do chủ site cung cấp. Không dùng account của người khác hay brute-force.
- Nếu tool cần session token, hướng dẫn người dùng chạy trên account của họ và không lưu trữ credential trong repo công khai.
- CAPTCHA và anti-bypass:
- Tuyệt đối không tích hợp hoặc khuyến nghị dịch vụ giải CAPTCHA tự động (2captcha, anticaptcha…) cho tính năng mặc định.
- Nếu repo chứa ví dụ hoặc plugin giải CAPTCHA, gắn nhãn rõ rủi ro và khuyến nghị xóa trước khi chạy.
- Proxy và IP rotation:
- Nếu dùng proxy, ưu tiên proxy trả phí có SLA; không dùng public proxy lists. Luôn kiểm tra terms-of-service của proxy provider.
- Không chia sẻ proxy/credentials trong repo; cấu hình proxy phải do người dùng cung cấp.
- Dữ liệu nhạy cảm và privacy:
- Nếu thu thập dữ liệu cá nhân, tuân thủ luật bảo vệ dữ liệu địa phương (ví dụ GDPR). Án tử nghiệp: anonymize PII trước lưu trữ nếu có thể.
- Ghi rõ mục đích, thời hạn lưu trữ và quyền truy cập dữ liệu trong tài liệu nội bộ.
- Ghi lại và báo cáo:
- Ghi log chi tiết cho mỗi lần chạy: domain, thời gian, requests, response codes, pause events.
- Nếu chủ site yêu cầu ngừng, ngừng ngay và xóa dữ liệu theo yêu cầu.
- Khi nào cần xin phép chính thức
- Khi scraping dữ liệu không công khai hoặc đòi hỏi đăng nhập tài khoản người dùng mà bạn không sở hữu.
- Khi bạn định thu thập khối lượng lớn dữ liệu có thể gây tải đáng kể cho host (hàng ngàn request/ngày cho cùng domain).
- Khi mục tiêu có rõ ràng trong ToS là cấm scraping hoặc khi robots.txt cấm phần bạn cần.
- Khi dữ liệu thu thập có thể nhạy cảm (thông tin cá nhân, dữ liệu tài chính, nội dung có bản quyền).
- Khi bạn sẽ sử dụng dữ liệu cho mục đích thương mại quy mô lớn hoặc chia sẻ công khai.
- Quy trình xin phép ngắn gọn
- Xác định contact người quản lý site (ở domain contact, abuse@, webmaster@).
- Soạn email ngắn gọn nêu:
- mục đích thu thập, phạm vi (ví dụ số trang/ngày, paths), thời gian thử nghiệm, User-Agent bạn sẽ dùng, và thông tin liên hệ để phối hợp.
- Đợi phản hồi bằng văn bản. Nếu có điều kiện (ví dụ rate limit), tuân thủ theo thỏa thuận.
- Mẫu wording disclaimer để chèn trong bài tổng hợp
Bạn có thể dùng đoạn sau để minh bạch cho độc giả:
"Mẫu disclaimer (thêm vào phần phương pháp) Mọi công cụ nêu trong bài được đánh giá theo tiêu chí ‘không yêu cầu khóa API để chạy chức năng chính’ tại thời điểm kiểm chứng. Trước khi chạy trên website thật, bạn nên:
- kiểm tra robots.txt của site mục tiêu và tuân thủ mọi chỉ dẫn;
- cấu hình rate limit và User-Agent có contact để giảm rủi ro bị block;
- không sử dụng kỹ thuật bypass CAPTCHA hay chia sẻ credentials;
- xin phép chủ sở hữu site khi thu thập khối lượng lớn hoặc dữ liệu không công khai.
Tác giả không chịu trách nhiệm cho hành vi vi phạm ToS hoặc pháp luật khi người đọc vận hành các công cụ này. Nếu bạn cần, hãy tham vấn bộ phận pháp chế hoặc liên hệ trực tiếp với chủ site."
- Gợi ý để ghi chú trong bảng repo
- Thêm cột "ToS-risk" với mức Low/Medium/High dựa trên:
- High: tool chuyên SERP scraping, có hướng dẫn proxy/CAPTCHA, hoặc mặc định concurrency cao.
- Medium: tool dùng headless browser, cần login cho một số tính năng.
- Low: tool làm việc trên file local hoặc chỉ audit local HTML.
- Kèm link evidence: .env.example, README line, CI workflow reference.
Kết luận ngắn
- Tuân thủ kỹ thuật (robots, rate limits, UA) và nguyên tắc không bypass là step tối thiểu để giảm rủi ro. Khi có nghi ngại pháp lý hoặc thương mại, xin phép bằng văn bản. Trong bài, luôn hiển thị disclaimer rõ ràng và gắn nhãn rủi ro cho từng repo để người đọc biết điểm cần kiểm chứng trước khi triển khai.
Tiêu chí rút ra "điểm mạnh thực dụng" và template viết ngắn
Mục tiêu phần này là cho bạn một khuôn mẫu rõ ràng để rút ra và viết ngắn gọn "điểm mạnh thực dụng" cho mỗi repo trong danh sách. Mình cung cấp: (A) nguyên tắc nhanh để quyết định một điểm mạnh là thực dụng, (B) template 3 câu bắt buộc dùng cho mọi repo, và (C) ví dụ thực tế sẵn sàng copy-paste cho các loại công cụ SEO phổ biến.
A. Nguyên tắc rút điểm mạnh thực dụng (quick rules)
- Chỉ rút khi có bằng chứng cấp A hoặc B: lệnh CLI + output mẫu, hoặc sample config + example output, hoặc issue/PR thực tế kèm log. Nếu chỉ có mô tả trừu tượng, ghi nhãn [CẦN KIỂM CHỨNG].
- Điểm mạnh phải gắn trực tiếp với một workflow SEO cụ thể: audit on-page, tạo sitemap, map internal links, enrich keyword list, phân tích log, v.v. Viết sao cho người đọc biết ngay được họ sẽ dùng tool vào bước nào trong quy trình.
- Luôn kèm rủi ro/limit thực dụng: ví dụ cần headless browser, cần proxy, tốc độ mặc định cao, gọi API bên thứ ba, hoặc vấn đề ToS. Nếu rủi ro chưa rõ, dùng tag [KHÔNG CHẮC] và mô tả bước kiểm chứng tiếp theo.
- Ngắn gọn và hành động: mỗi repo 3 câu, max 2 dòng mỗi câu. Câu 1: chức năng chính; Câu 2: ích lợi thực dụng cho workflow; Câu 3: rủi ro hoặc giới hạn vận hành.
B. Template chuẩn 3 câu (mẫu chung, fill-in)
- Câu 1 (chức năng chính): "[Tên repo] là một công cụ để [động từ chính + mục tiêu], ví dụ: [một-line mô tả kỹ thuật ngắn]."
- Câu 2 (lợi ích thực dụng): "Trong workflow SEO, nó giúp [việc cụ thể] bằng cách [cách output hỗ trợ công việc], do đó tiết kiệm/giảm thiểu [nỗi đau cụ thể]."
- Câu 3 (rủi ro/limit): "Lưu ý: [rủi ro/chế độ giới hạn], nên khi dùng bạn nên [biện pháp giảm rủi ro hoặc điều kiện dùng]."
Ví dụ generic để dán vào trực tiếp (thay TÊN/điền chỗ phù hợp)
- "seocrawl-tool là một crawler site nhỏ gọn để thu thập HTML và metadata từ danh sách seed URL. Trong workflow SEO, nó cho phép bạn nhanh chóng sinh bảng URL + tiêu đề + meta-description để chuẩn hóa audit trước migration. Lưu ý: mặc định không dùng proxy và concurrency cao, khuyên chạy với delay 1.5–3s và bật respect robots.txt."
C. Ví dụ cụ thể theo loại công cụ — copy-paste ready
- Crawl / site crawler
- "mini-crawler là một spider đơn luồng thu thập HTML và trích xuất title/meta/h1 từ sitemap hoặc seed list. Trong quy trình SEO, dùng nó để tạo dataset đầu vào cho audit on-page và kiểm tra broken link nhanh trong bước tiền-migration. Lưu ý: mặc định concurrency thấp nhưng không xử lý JS; nếu site cần render JS thì phải bật headless và chuẩn bị Chrome binary."
- Audit on-page
- "page-audit-cli chạy tập hợp kiểm tra on-page (title, meta description, H1, canonical, status code) cho danh sách URL. Nó giúp biên tập và SEO lead tạo report CSV trực tiếp để phân phối cho tác vụ chỉnh sửa nội dung. Lưu ý: rule mặc định cho tiếng Anh, với nội dung tiếng khác bạn cần cung cấp stopword/lang config."
- Log analysis
- "log-parser là tool parse Apache/Nginx access logs để ghép session và tính organic landing pages. Trong workflow, dùng nó để nối click path vào data crawl để ưu tiên sửa trang có traffic thật. Lưu ý: cần sample log định dạng ‘combined’ hoặc mapping pattern; khuyên thử trên small sample trước khi scale."
- Keyword extractor / n-gram
- "keyword-extract thu thập n-gram từ corpus HTML và cho điểm tf-idf, xuất CSV có volume estimate nếu bạn cung cấp file export. Dùng để nhanh làm seed keyword list cho cluster testing và content briefs. Lưu ý: mặc định dùng stopwords tiếng Anh; với nội dung tiếng Việt cần thay stopword list."
- SERP scraper (HTML, no API)
- "serp-scrape lấy SERP HTML cho truy vấn nhất định và parse title/snippet/position mà không cần API key. Hữu ích cho sampling SERP nhanh trước khi quyết chiến lược content/feature snippets. Lưu ý: rủi ro ToS và bot detection cao; khuyên chạy low-rate và dùng geo/proxy có kiểm soát."
- Internal link analyzer
- "link-mapper xây dựng graph internal link từ crawl output và xuất dạng graphml/CSV. Trong workflow, dùng nó để xác định orphan pages và tối ưu anchor text cho silos. Lưu ý: cần input crawl có cùng canonicalization rules; nếu site dùng nhiều query params, bật dedupe rules."
- Sitemap generator
- "sitemap-gen sinh sitemap.xml từ danh sách URL dựa trên rules changefreq/priority. Dùng để tạo sitemap hợp lệ cho submit GSC sau migration. Lưu ý: mặc định không gzip; với >50k URLs bạn phải bật chunking theo chuẩn sitemap."
- Image SEO tool
- "image-audit scan alt attributes và kích thước, xuất gallery các ảnh thiếu alt hoặc quá lớn. Giúp team front-end/SEO ưu tiên compress và thêm alt cho pages tác động cao. Lưu ý: nếu tool hỗ trợ compression bằng API, kiểm tra config vì tính năng nén có thể yêu cầu service ngoài."
- Performance tool (lightweight)
- "perf-check chạy đo thời gian tải đơn giản bằng headless fetch và báo render time + kích thước tài nguyên chính. Dùng nó cho checkpoint performance pre/post thay đổi front-end. Lưu ý: nếu bật lighthouse mode cần local Chrome binary; phiên bản headless có thể khác kết quả PageSpeed Insights."
- Utilities (canonical checker, redirect tracer)
- "redirect-checker theo dõi chuỗi redirect cho list URL và báo loop/chain dài. Hữu dụng trong audit migration để tìm redirect chain gây mất link equity. Lưu ý: mặc định followredirects=true và maxredirects=10; chỉnh nếu bạn muốn phát hiện chain dài hơn."
D. Ghi chú vận hành nhanh cho bạn khi viết phần repo
- Luôn kèm 1 nguồn chứng cứ ngay sau 3 câu: trích 1 dòng README hoặc link issue/command (vd: Usage: seocrawl –start urls.txt). Nếu không có, thêm tag [CẦN KIỂM CHỨNG].
- Nếu rủi ro là ToS/scraping, viết đủ để người đọc biết cách giảm rủi ro: delay, respect robots.txt, UA contact, proxy policy.
- Dùng ngôn ngữ thực dụng, tránh thuật ngữ mơ hồ như "powerful" hoặc "comprehensive" nếu không có bằng chứng.
Kết thúc. Bạn có thể dùng template và các ví dụ trên copy-paste trực tiếp vào bảng repo; giữ nguyên cấu trúc 3 câu + 1 evidence link cho mỗi mục.
Kịch bản ngoại lệ khi không đủ repo cho một loại
Mục tiêu: khi không gom đủ ngưỡng tối thiểu cho một loại công cụ, chính sách ngoại lệ phải bảo đảm tính minh bạch, tái kiểm chứng và an toàn cho độc giả. Dưới đây là quy trình chặt chẽ bạn áp dụng để chấp nhận ngoại lệ, các điều kiện bắt buộc phải thỏa, và mẫu note công khai để ghi vào bảng tổng hợp.
- Nguyên tắc vận hành
- Ngoại lệ chỉ được xét khi sau một chiến dịch tìm kiếm chuẩn hóa vẫn không tìm đủ repo hợp lệ cho loại đó. Không chấp nhận ngoại lệ vì thiếu công sức tìm kiếm.
- Mọi ngoại lệ phải kèm evidence stack có thể tái lập bởi người thứ ba trong 30 phút.
- Mọi ngoại lệ phải được review độc lập bởi ít nhất hai người, gồm một reviewer kỹ thuật và một reviewer nội dung/SEO.
- Khi xét ngoại lệ
Bạn được quyền đề xuất ngoại lệ khi một trong các tình huống sau có bằng chứng:
- Loại công cụ thực sự ít xuất hiện public do rào cản pháp lý, ToS, hoặc tính chuyên ngành.
- Các tính năng của loại đó thường xuất hiện như module trong repo đa năng thay vì repo chuyên biệt.
- Có repo duy nhất nhưng có chất lượng cao, hoạt động tốt, và có khả năng được dùng làm ví dụ đại diện.
- Điều kiện bắt buộc để chấp nhận ngoại lệ
Mỗi đề xuất ngoại lệ phải kèm đầy đủ ba nhóm chứng cứ dưới đây. Thiếu một trong ba, đề xuất bị từ chối.
A. Search log (bắt buộc)
- Ghi lại các truy vấn đã chạy (ít nhất 12 truy vấn biến thể trên GitHub + 4 trên GitLab hoặc 2 nguồn curated như Awesome lists).
- Lưu kết quả thô: top 50 kết quả cho mỗi truy vấn, với lý do loại trừ cho các repo bị loại.
- Đính kèm timestamp và tên người chạy truy vấn.
B. Evidence stack (bắt buộc)
- Ít nhất hai loại evidence độc lập từ repo(s) được nêu: README usage example, sample output, test/CI job chạy, bin/entrypoint, hoặc demo reproducible trong container.
- Nếu lựa chọn repo đa năng có module, phải có: entrypoint/module độc lập + sample output cho module đó + log chạy minh chứng.
- Nếu thiếu sample runtime, phải có evidence thị trường giải thích tính hiếm (ví dụ báo cáo ToS, bài viết ngành, hoặc danh sách thương mại thay thế).
- Tất cả evidence phải kèm đường dẫn file cụ thể trong repo hoặc snapshot stdout/stderr.
C. Reviewer sign-off (bắt buộc)
- Reviewer A (kỹ thuật) xác nhận evidence stack tái lập được trên môi trường test trong tối đa 30 phút hoặc nêu rõ lỗi reproducible.
- Reviewer B (nội dung/SEO) xác nhận công cụ thực sự phục vụ workflow SEO và ghi rõ phạm vi giới hạn.
- Cả hai reviewer phải ký tên (initials) và ghi timestamp trong metadata.
- Quy tắc công khai minh bạch
- Mọi ngoại lệ đưa vào bảng tổng hợp phải kèm một note ngắn công khai theo mẫu dưới đây. Note sẽ xuất hiện bên cạnh mục loại hiếm trong bài xuất bản.
Mẫu note công khai (copy-paste)
- exception_note | Loại: <tên loại>; Repos tìm được: <n>; Lý do ngoại lệ: <ngắn gọn>; Evidence: <link1>, <link2>; Reviewers: <A initials> (<role>), <B initials> (<role>); Rủi ro: <tóm tắt rủi ro>; Recommendation: <hành động khuyến nghị>
Ví dụ thực tế:
- exception_note | Loại: SERP scraper; Repos tìm được: 2; Lý do ngoại lệ: SERP scraping public ít do ToS và đa số giải pháp là thương mại; Evidence: https://github.com/owner/repoA#usage, https://github.com/owner/repoB#module; Reviewers: NT (tech), LM (editor); Rủi ro: bot detection, ToS; Recommendation: dùng để minh họa kỹ thuật, không khuyến nghị production.
- Hậu kiểm và cập nhật
- Ngoại lệ được gắn nhãn EXCEPTION và review lại sau 3 tháng. Nếu trong chu kỳ review phát hiện thêm repo phù hợp, cập nhật bảng và gỡ nhãn EXCEPTION.
- Mọi artifacts (search log, run logs, reviewer notes) lưu vào folder nội bộ kèm thời gian để cho phép audit về sau.
Kết luận ngắn
- Chấp nhận ngoại lệ là hành động có chủ ý, cần bằng chứng tái lập được, ít nhất hai reviewer độc lập, và note công khai. Nếu thiếu bất kỳ điều kiện bắt buộc nào, không đưa ngoại lệ vào bài.
Checklist bàn giao cho nhóm viết và biên tập
Mình đưa checklist hoàn chỉnh để bạn dùng trực tiếp khi nhận repo đã sàng lọc. Mỗi mục là yêu cầu bắt buộc trước khi biên tập viết phần mô tả điểm mạnh thực dụng.
- Tổng quan và bản đính kèm (bắt buộc)
- Bảng repo đã fill: file CSV/Google Sheet với các cột tối thiểu: repourl | primarytype | secondarytypes | lastcommit | license | apidependencyscore | reviewerinitials | runstatus | exception_note.
- Evidence files: thư mục evidence/ chứa screenshot README lines, snippets từ issues, sample output files, và link trực tiếp tới file trong repo.
- Scripts used: thư mục scripts/ chứa script scan (rg/curl) và script chạy thử đã dùng để kiểm tra từng repo; kèm README ngắn cách chạy script.
- Run logs: lưu run-logs/<repo>-<date>.log cho mọi thử nghiệm runtime (stdout/stderr) và network-capture nếu có.
- Meta file: metadata.yml liệt kê reviewer, ngày kiểm chứng, profile chạy (A/B/C), và verdict (KHÔNG-API | CẦN-API | YÊU CẦU-LOGIN | YÊU CẦU-KIỂM-TRA).
- Checklist kiểm chứng nội dung cho mỗi repo (từng hàng)
- README quickcheck – copy dòng lệnh Usage nếu có, và paste vào evidence/readme-snippets.txt.
- Dependencies scan – đính kèm output của rg trên manifests; highlight bất kỳ SDK tên thương hiệu nào.
- Env/CI scan – đính kèm kết quả grep cho patterns API_KEY, secrets, .github/workflows references.
- Endpoint scan – list các URL literal trích ra bởi script; gắn tag domain nếu là third-party (ví dụ serpapi.com).
- Runtime test – ghi rõ command đã chạy, profile dùng, thời gian, kết quả (pass/fail) và file log tương ứng.
- Network behavior – nếu repo claim không cần API, attach capture (strace/tcpdump) chứng minh không gọi third-party API; nếu có gọi, nêu host và classify.
- Yêu cầu cho evidence khi rút điểm mạnh (mỗi claim phải có)
- Claim tính năng core: phải có 1 trong {CLI command + sample output, test/CI job, example output file}. Ghi nguồn bằng đường dẫn file và dòng.
- Claim "không cần API": phải có runtime evidence no-outbound OR code scan không thấy env/API SDK AND README không yêu cầu key. Nếu có nghi ngờ, gắn tag [KHÔNG CHẮC].
- Claim “scale/performance”: cần có benchmark hoặc notes trong README hoặc issue. Nếu không, ghi cảnh báo "no benchmark".
- Files and artifacts naming convention
- Bảng: repos.csv
- Evidence: evidence/<owner>-<repo>/<type>-<timestamp>.(png|txt|json)
- Scripts: scripts/scan-repo.sh, scripts/run-profile-A.sh
- Logs: run-logs/<owner>-<repo>-profileA-YYYYMMDD.log
- Recommended profile to run (ghi rõ cho writer/tech reviewer)
- Profile A – Polite minimal: concurrency=2, delay=random(1.0,3.0)s, maxpages=20, respectrobots=true. Dùng để kiểm tra core parsing.
- Profile B – Functional quick: concurrency=4, delay=1s, maxpages=50, jsrender=false. Dùng để kiểm chứng feature detection.
- Profile C – JS-heavy: headless=true, concurrency=1, max_pages=10, requires local headless binary. Dùng chỉ khi repo dùng puppeteer/playwright.
- Ghi profile dùng bên cạnh run log.
- Tone notes cho phần viết
- Giữ tông practitioner: ngắn, cụ thể, hướng dẫn hành động. Dùng cấu trúc 3 câu cho mỗi tool: (1) công năng chính, (2) lợi ích thực dụng cho workflow SEO, (3) caveat / rủi ro vận hành.
- Nếu repo có [KHÔNG CHẮC], dùng câu cảnh báo rõ ràng: "Cảnh báo: cần kiểm chứng thêm" và chỉ dẫn cụ thể để kiểm chứng.
- Tránh so sánh giá trị với SaaS trả phí; nếu độc giả cần so sánh, chỉ nêu khả năng kỹ thuật, không nêu ROI.
- Tags và nhãn bắt buộc trong bảng (standardized)
- run_status: PASSED | FAILED | PARTIAL
- apiflag: NOAPI | REQUIRESAPI | HYBRID | NEEDSLOGIN
- evidence_level: A | B | C
- risktag: TOSRISK | HEAVY_DEPENDENCY | UNMAINTAINED
- review_state: DRAFT | VERIFIED | EXCEPTION
- Nơi cần kiểm chứng thêm [KHÔNG CHẮC] – bắt buộc tag và note
- Nếu có bất kỳ dấu hiệu động runtime (dynamic config, remote config fetch) mà script tĩnh không phát hiện, tag [KHÔNG CHẮC] và ghi bước kiểm chứng tiếp theo.
- Nếu sample output không reproduce trong 30 phút thử nghiệm, tag [KHÔNG CHẮC] và attach run log lỗi.
- Nếu repo có demo-mode hoặc fixtures dùng sẵn, ghi rõ "demo-mode detected" và note kiểm chứng: run with different input to confirm behavior.
- Giao nhận và ký nhận
- Trước khi giao cho biên tập, reviewer kỹ thuật ký vào metadata.yml với verdict và đính evidence zip.
- Biên tập viên đối chiếu bảng repos.csv, mở evidence folder, và trong CMS chèn một hàng meta gồm evidence links + tone note + tags.
- Lưu tất cả artifacts cuối cùng vào một commit riêng trong repo nội bộ: /handover/<date>-<initials>.zip
- Checklist cuối trước khi publish
- [ ] repos.csv complete và validated
- [ ] evidence folder có run logs cho mọi repo đánh dấu VERIFIED
- [ ] scripts runable và có README hướng dẫn
- [ ] recommended profile noted per repo
- [ ] tone notes + 3-sentence template cho mỗi repo
- [ ] tags set, mọi [KHÔNG CHẮC] đều có bước kiểm chứng rõ ràng
- [ ] metadata.yml có reviewer signatures
Mình đã chuẩn hóa tên file và mẫu để bạn copy-paste vào quy trình. Bạn dùng checklist này để kiểm nhận cuối cùng trước khi biên tập viết phần điểm mạnh cho từng công cụ.
Hướng dẫn an toàn vận hành khi thử chạy repo (sandbox)
Mục tiêu: cho bạn quy trình an toàn để thử chạy một repository không rõ nguồn gốc trong môi trường cách ly, ghi lại artifacts để làm bằng chứng, và có bước rollback an toàn nếu cần.
Chuẩn bị môi trường
- Chạy trong container để cô lập filesystem và process.
- Vô hiệu hóa network ở container khi muốn chắc chắn không có egress.
- Nếu cần quan sát traffic, dùng proxy trung gian (mitmproxy) hoặc capture syscall (strace).
- Luôn chuẩn bị snapshot hoặc layer để rollback container/image nhanh.
Bước 1 – Tạo container sandbox
- Dùng Docker để chạy container với mạng tắt. Ví dụ chạy image base có sẵn môi trường dev:
docker run --rm -it --name repo-sandbox --network none -v "$PWD":/work -w /work python:3.10 bash
- Giải thích ngắn:
- –network none ngăn container kết nối internet.
- mount dự án vào /work để chạy thử mã.
- Nếu cần persistent state cho artifacts, mount thư mục host artifacts.
Bước 2 – Chuẩn bị capture và logging
- Chuẩn bị ghi log lệnh và stdout/stderr vào file:
script -q -c "bash -lc 'your-start-command here'" run-output.log
- Nếu muốn giám sát syscalls network, dùng strace (cần cài trong image):
strace -f -e trace=network -o /work/strace.log bash -c "your-start-command here"
- Nếu muốn quan sát HTTP traffic có thể cho phép egress nhưng rút qua proxy kiểm soát:
- Khởi chạy mitmproxy trên host và chạy container nối mạng nội bộ chỉ tới proxy; cấu hình HTTPPROXY/HTTPSPROXY cho container. Ghi chú: mitmproxy hiển thị request/response để bạn kiểm chứng endpoint.
Bước 3 – Chạy thử theo profile an toàn
- Chạy ở chế độ "dry-run" hoặc với sample data khi repo hỗ trợ.
- Nếu repo cung cấp profile config, override tham số concurrency/rate/limit để giữ mức nhẹ.
- Chạy lệnh ví dụ và thu mọi artifacts: report.json, output/*.csv, logs, database file. Lưu vào thư mục artifacts/ trên host:
mkdir -p ../artifacts && cp run-output.log ../artifacts/
cp /work/path/to/report.json ../artifacts/ || true
cp /work/strace.log ../artifacts/ || true
Bước 4 – Kiểm tra network và phát hiện API/endpoint
- Nếu container ở chế độ none thì mọi outbound bị ngăn, điều này sẽ lộ ra nếu mã phụ thuộc API vì lỗi xuất hiện nhanh.
- Nếu cho phép proxy, xem mitmproxy để phát hiện domain, Authorization header, query param chứa key. Nếu thấy API key patterns, đánh dấu repo yêu cầu API.
- Dùng ripgrep trên mã trước khi chạy để tìm biến môi trường kiểu API_KEY, hoặc import SDK rõ ràng.
Bước 5 – Lưu artifacts và metadata
- Ghi metadata thử nghiệm: repo URL, commit SHA, thời gian, command dùng, profile config.
- Ví dụ cấu trúc lưu:
- artifacts/<repo>-<sha>/run-output.log
- artifacts/<repo>-<sha>/strace.log
- artifacts/<repo>-<sha>/mitmproxy.har
- artifacts/<repo>-<sha>/metadata.json
- metadata.json nên chứa: { "repo": "…", "sha": "…", "cmd": "…", "profile": "…", "result": "PASS/FAIL", "notes": "…" }
Bước 6 – Rollback và dọn dẹp
- Nếu dùng Docker ephemeral: docker run –rm tự tidy up. Nếu dùng docker create/run với volumes, xóa container:
docker rm -f repo-sandbox || true
- Xóa image tạm nếu cần:
docker image rm <temp-image> || true
- Nếu đã thay đổi host (ví dụ cài tool global), revert bằng snapshot hoặc restore từ backup. Luôn ưu tiên làm mọi thay đổi trong container để không cần rollback host.
Cảnh báo vận hành và best practice
- Luôn assume mã có thể âm thầm gọi network hoặc thực hiện I/O bất kỳ. Chạy first-pass với –network none.
- Không chạy với quyền root trên host. Trong container, hạn chế quyền bằng user không root khi có thể.
- Nếu phát hiện behavior đáng ngờ (call tới external API, upload data), dừng ngay, lưu artifacts, và chuyển mục đó vào queue “needs manual review”.
- Ghi chú pháp lý: tránh gửi dữ liệu người dùng ra ngoài khi thử, và tuân thủ robots.txt, ToS khi kích hoạt chế độ có network.
Kết luận ngắn
- Quy trình ngắn: clone vào host, chạy container –network none, chạy command với logging và strace, mở proxy chỉ khi cần quan sát, lưu artifacts và metadata, rồi xóa container. Nếu cần, mình có thể gửi script bash mẫu để tự động hóa các bước trên.
Lộ trình thực thi để gom >=30 repo hợp lệ
Mục tiêu ngắn: trong 4 tuần gom tối thiểu 30 repository công cụ SEO thỏa điều kiện "không cần API key để chạy chức năng chính", kèm bằng chứng kiểm chứng và bản nháp điểm mạnh thực dụng cho mỗi loại công cụ. Kết quả giao kèm: bảng dữ liệu hoàn chỉnh, 30 repo final có evidence, 8 loại công cụ có ít nhất 1 mẫu điểm mạnh đã soạn, và checklist bàn giao cho nhóm viết.
Tuần 1 – Query và thu thập 150 candidates (7 ngày)
- Mục tiêu tuần: thu thập 150 repo candidates từ GitHub (ưu tiên), mở rộng GitLab nếu cần.
- Hoạt động chính:
- Chuẩn bị queries chuẩn hóa (GitHub Advanced Search + topic lists + Awesome lists). Dùng template query đã thống nhất.
- Chạy các query, export kết quả thô (repo url, stars, last pushed, language, description).
- Loại trùng và lọc sơ bộ theo license và last pushed >= 24 tháng.
- Gán nhãn sơ bộ theo taxonomy (crawl, audit, log, keyword, serp, link, schema, sitemap, image, performance, utils).
- Phân công:
- 2 người searcher chạy queries và export (mỗi người 75 repo).
- 1 người build sheet tổng hợp ban đầu và script dedupe.
- Deliverables tuần:
- Sheet candidates.csv (150 rows) + log truy vấn (queries.txt) để audit.
- Script dedupe.sh hoặc gh CLI command list.
- KPI tuần:
- Số candidates >=150.
- Tỉ lệ candidates với license OSI-approved >= 85%.
- Log truy vấn đầy đủ và reproducible.
Tuần 2 – Triage tĩnh và static scan -> shortlist 60 (7 ngày)
- Mục tiêu tuần: từ 150 xuống 60 bằng kiểm tra tĩnh, loại bỏ repo phụ thuộc API rõ rệt hoặc dead/archived.
- Hoạt động chính:
- Chạy pipeline static scan tự động (script: rg + parsing package manifests + check .env.example + CI workflows). Output: apiflags, sdkflags, env_vars found.
- Manual review cho các trường hợp ambiguous. Mỗi repo có checklist tĩnh phải được tick: license OK, pushed >=24 months, no explicit API_KEY requirement, no SDK proprietary imports OR has offline mode doc.
- Gán score sàng lọc (0-10). Giữ 60 repo score cao nhất theo rule: priority = (no-api evidence, recent commit, runnable sample).
- Phân công:
- 3 reviewers tĩnh, mỗi người 20-25 repo; 1 kỹ sư viết script và aggregate results.
- Deliverables tuần:
- Shortlist60.csv với cột evidence static (files checked, matched patterns), api_flag boolean, notes.
- Các artifact scan per-repo (json).
- KPI tuần:
- Tỉ lệ false positive static scan < 10% (đo bằng sampling manual).
- Shortlist đạt 60 repo có evidence static pass >= 80% fields.
Tuần 3 – Runtime check 30 phút/repos -> final 30 (7 ngày)
- Mục tiêu tuần: với mỗi repo trong shortlist, chạy quy trình kiểm thử runtime tối đa 30 phút/repo để phân loại thành FINAL_OK hoặc REJECT.
- Quy trình 30 phút (tiêu chuẩn, timeboxed):
0-5m: đọc README Quickstart, xác định command mẫu và sample data. 5-10m: run static grep tiếp (APIKEY, sdk imports, endpoints). Nếu phát hiện dấu rõ ràng, mark REJECT. 10-25m: chạy sample command trong sandbox (docker –network none) hoặc với proxy/mitmproxy nếu muốn log egress. Ghi lại stdout/stderr, artifacts. 25-30m: phân tích logs: có outbound calls tới third-party API? có require env APIKEY? có produce usable output? Kết luận: PASS / HYBRID (core run without API but optional features use API) / FAIL.
- Phân công và throughput:
- Mỗi reviewer runtime đảm nhiệm 6 repo/ngày ~ 30 phút/repo -> 6 repos x 5 ngày = 30 repos tối đa per reviewer/week. Tổ team cần 2 reviewers runtime đồng thời để hoàn thành 60 trong 5 ngày. Thực tế bố trí 3 reviewer để buffer.
- Deliverables tuần:
- Final30.csv gồm 30 repo PASS, kèm artifacts folder per-repo: run-output.log, strace/mitm logs if any, metadata.json (cmd, sha, timestamp).
- Reject list với lý do rõ ràng (apirequired, buildfail, archived).
- KPI tuần:
- Tỉ lệ PASS trên shortlist >= 50% để đạt 30 final. Nếu thấp, phải mở rộng shortlist nhanh.
- Mỗi repo PASS có metadata đầy đủ và evidence file.
Tuần 4 – Soạn nháp điểm mạnh thực dụng + peer review, phân công công việc và KPIs (7 ngày)
- Mục tiêu tuần: cho 30 repo final, soạn nháp điểm mạnh thực dụng theo template 3 câu, peer review 2 lượt, chuẩn bị giao cho nhóm viết.
- Hoạt động chính:
- Viết nháp điểm mạnh cho mỗi repo theo template: chức năng chính | lợi ích thực dụng cho workflow SEO | rủi ro/limit. Mỗi nháp 40-60 từ.
- Peer review nội bộ: reviewer độc lập kiểm chứng bằng evidence artifacts; chấp nhận/requests changes.
- Tổ biên tập nhóm SEO chọn top 8 loại công cụ và viết phần tổng hợp điểm mạnh theo loại.
- Chuẩn bị checklist bàn giao cho nhóm viết: sheet final, artifacts, sample commands, recommended profile to run.
- Phân công:
- 3 copywriters mỗi người 10 repo nháp.
- 2 peer reviewers (kỹ thuật + SEO lead) duyệt.
- 1 PM tổng hợp và finalise deliverables.
- Deliverables tuần:
- Draft article section per-type with sample tools and points.
- Handover package: final csv, artifacts zip, run scripts, review logs.
- KPI tuần:
- 100% repo final có nháp điểm mạnh và evidence link.
- Peer review pass rate >= 90% (số nháp approved/total).
- Handover hoàn tất sớm nhất 2 ngày trước deadline.
Cơ chế quản lý rủi ro và điều chỉnh tiến độ
- Nếu tuần 3 không thu đủ 30 PASS, ngay lập tức lặp lại tuần 2 queries mở rộng + thêm 30 candidates và repeat triage ngắn trong 48 giờ.
- Mỗi ngày báo cáo stand-up: số repo processed, PASS, REJECT, blockers. PM quyết chỉ đạo mở rộng nguồn nếu tỉ lệ PASS low.
KPIs chung dự án (4 tuần)
- Candidates collected >=150.
- Shortlist after static triage = 60.
- Final PASS >=30.
- Draft điểm mạnh cho 30 repo + peer review complete.
- Evidence artifacts per-repo >= 3 files (readme snippet, run log, output file).
- Tỉ lệ false inclusion < 10% (sau spot-check).
Giao nhận cuối cùng
- Bảng final CSV với trường bắt buộc, artifacts zip, report ngắn nêu methodology, và checklist bàn giao cho nhóm viết. Mình khuyến khích bạn yêu cầu mỗi reviewer attach một "timestamped evidence pack" để audit sau này.
Ghi chú giới hạn phạm vi và nhãn [KHÔNG CHẮC]
Mình liệt kê rõ những giới hạn phân tích trong khung này, các trường hợp runtime-resolved endpoints khó phát hiện, và hành động follow-up bắt buộc khi gặp repo gắn nhãn [KHÔNG CHẮC]. Mục tiêu là giúp bạn đưa ra quyết định an toàn trước khi công bố hoặc đưa repo vào danh sách.
Giới hạn phương pháp luận
- Phân tích ưu tiên GitHub, mở rộng GitLab nếu cần, trong phạm vi các repo public cập nhật trong 24 tháng gần nhất. Repo private, npm/pypi packages không public và artifacts binary không được quét tự động nằm ngoài phạm vi.
- Định nghĩa "không API" là: chức năng chính chạy được mà không cần API key hoặc SDK bên thứ ba. Repo có tính năng tùy chọn dùng API vẫn chấp nhận nếu core chạy offline. Tuy nhiên điều này phụ thuộc vào logic runtime, nên đôi khi cần kiểm thử.
- Quét tĩnh (grep/rg) + checks trên CI/Dockerfile thường bắt phần lớn dấu hiệu. Nhưng không thể khẳng định tuyệt đối nếu mã xây dựng endpoint tại runtime hoặc tải config từ remote.
- Kiểm thử runtime 30 phút là trade-off giữa tốc độ và độ chính xác; một số dependency ẩn hoặc đường dẫn điều kiện hiếm có thể bị bỏ sót.
Trường hợp runtime-resolved endpoints khó phát hiện
- Endpoint được tạo từ biến môi trường mà tên biến không chuẩn, chẳng hạn CONFIGURL hoặc ENDPOINTBASE, và giá trị được cung cấp từ CI hoặc secrets manager. Static grep dễ bỏ sót.
- Endpoint được tải động từ remote config file/gist hoặc registry ở bước bootstrap. Mã không chứa URL tĩnh nên quét tĩnh không thấy.
- Code sử dụng service discovery, DNS CNAME hoặc subdomain do deploy tạo ra, ví dụ host được ghép theo tenant hoặc environment, không thể phân biệt bằng regex.
- Binary/vendored module hoặc submodule đóng gói endpoint trong mã nhị phân hoặc minified JS, gây khó đọc.
- Chức năng bị lazy-loaded và chỉ kích hoạt qua flag ít dùng hoặc trong cron job; Quickstart không phủ tới code path ấy nên runtime test ngắn bỏ sót.
- Proxying: repo gọi một host trung gian do tác giả quản lý, và host đó thực tế chuyển tiếp tới API bên thứ ba. Qua grep thấy host nội bộ, nhưng runtime vẫn cần service bên ngoài.
Hành động follow-up bắt buộc khi gặp nhãn [KHÔNG CHẮC]
- Ghi lại evidence pack ngay: file README excerpt, kết quả grep, file CI/Docker liên quan, timestamp, commit SHA. Lưu vào folder evidence/ để audit.
- Bắt buộc chạy thử mở rộng: 1) thực thi Quickstart trong container với –network none; 2) nếu pass, chạy lại với network enabled và giám sát outbound bằng strace hoặc mitmproxy để ghi tất cả host gọi ra. Ghi log network.
- Nếu phát hiện outbound tới domain lạ hoặc api.* hoặc header Authorization dùng env var, treat as "requires API" và loại khỏi danh sách "không API".
- Nếu không thể reproduce do thiếu binary hoặc môi trường, mở ticket "NEEDSDEEPREVIEW" và gán cho dev reviewer để làm full audit (tối đa 4 giờ).
- Luôn thêm nhãn công khai trong bảng tổng hợp: "[KHÔNG CHẮC] – evidencepacklink – recommended_action" để người đọc biết cần thẩm định thêm.
- Với các trường hợp chứa proxying hoặc runtime config tải từ remote, yêu cầu maintainer trả lời issue: xác nhận tính năng có thể chạy offline và cung cấp script demo offline; nếu maintainer không trả lời trong 7 ngày, loại bỏ khỏi bài hoặc đánh dấu rõ rủi ro ToS.
Ghi chú vận hành cuối
- Mỗi repo gắn [KHÔNG CHẮC] phải qua 2 người kiểm chứng độc lập trước khi đổi nhãn thành "KHÔNG-API" hoặc "CẦN-API". Mọi quyết định thay đổi nhãn phải kèm evidence_pack và log runtime. Nếu bạn cần, mình có script mẫu tự động hóa phần grep + curl + strace để thu evidence.
Kết luận
Sau khi áp dụng khung này, bạn sẽ có một danh mục repo SEO chạy cục bộ đã được sàng lọc, phân loại và chứng thực đủ bằng chứng để đưa vào quy trình biên tập hoặc triển khai. Lưu ý thực tế quan trọng nhất: luôn chạy thử trong môi trường cô lập với mạng vô hiệu hóa trước khi cho phép bất kỳ repo nào truy cập ngoài, vì nhiều phụ thuộc chỉ lộ khi runtime.