Skip to content
View ntdatt812's full-sized avatar
🏢
Minh Lo Company
🏢
Minh Lo Company
  • LIGHT ROAD LIMITED COMPANY
  • Thanh Hoa
  • 10:08 (UTC +07:00)
  • Facebook ntdat812
  • Instagram nt.datt812

Block or report ntdatt812

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
ntdatt812/README.md

Nguyen Thanh Dat — plumbing under AI developer tooling

Landed Advisory Open Focus Location

I work on the plumbing under AI developer tooling — the API routers, session stores, and configuration managers that sit between a coding agent and the models it talks to. Almost all of it is root-cause work in codebases I did not write.

Where the project has a test suite, every patch below ships with a regression test that I verify fails on main before I open the pull request. Two of them — the drawdb pull requests — do not, because that repository has no test runner at all; those carry a written reproduction instead.

Contribution record

Public data for ntdatt812, counted 2026-08-20, covering the preceding 12 months. "Landed" means the change is in the upstream default branch of a repository I do not own — as a merged pull request, or as a commit the maintainer cherry-picked from one. Pull requests in my own repositories are not counted — the figures are what gh search prs --author ntdatt812 returns once ntdatt812/* is excluded.

Count What it counts
Pull requests merged 17 Merged by maintainers of repos I don't own
Additional commits landed 6 In decolua/9router master; the PRs were closed and the work cherry-picked
Security advisories 1 Published, credited as reporter
Pull requests open 31 Awaiting maintainer review
Repositories 14 Third-party repos I've contributed to

I am not a maintainer of any of these projects, and I don't claim to be.

Security

GHSA-w8pw-h853-frw2jdx/mise, 32.7k★. Moderate, CVSS 4.0 5.9. Affects <= 2026.8.7, patched in 2026.8.9. Reported privately, published by the maintainer, credited as reporter.

gitlab::get_headers and forgejo::get_headers attached the caller's token to any URL they were handed. The GitHub equivalent does not — it self-gates on is_github_api_url, and github::resolve_token additionally refuses the release-asset hosts. All three are called side by side, on the same value, so the GitHub path was protected and the other two were not. A GitLab release asset link may name any host, so mise sent Authorization: Bearer <GITLAB_TOKEN> to hosts it does not control.

What made this worth reporting rather than guessing at: the exposure is real but not universal. direct_asset_url is usually a gitlab.com permalink, so I sampled the live API across five projects to find where it isn't — inkscape/inkscape publishes a link whose direct_asset_url is inkscape.org. The report says plainly which parts I had measured, which rested on code reading, and that I had not run a network proof-of-concept and would not without the maintainer's agreement.

No CVE has been assigned, and the advisory is not yet in the global GitHub Advisory Database. Both are for the maintainer and GitHub to decide.

Landed

github/spec-kit — spec-driven development toolkit, 130k★. One pull request merged.

PR What it does
#4182 A workflow condition: written without a {{ }} block is never evaluated. evaluate_expression only substitutes {{ … }}, so the string comes back untouched and any non-empty text is truthy — condition: inputs.count > 100 always takes the then branch, and a while always runs to max_iterations. Rejects it at validation. The scan walks every block rather than stopping at the first, so a later unterminated one is caught too, and it separates a block that is never evaluated from one the interpolator truncates and does evaluate, because the two need opposite advice.

diegosouzapw/OmniRoute — AI gateway, 51.3k★. One pull request merged.

PR What it does
#10715 POST /api/tools/agent-bridge/cert/regenerate called generateCert() with no arguments, and that function short-circuits whenever both files already exist. On any machine that had started the bridge once, the endpoint was a no-op — while still answering { ok: true } with the two paths, so the UI reported success and /cert/download kept serving the identical file. generateCert now takes an opt-in { force }, and the regenerate route is its only caller. The other three callers only need a certificate to exist, so they keep the short-circuit and are untouched (closes #10467).

decolua/9router — LLM API router, 25.7k★. Six commits in master.

Commit What it does
9225921 Implements the hardening for GHSA-5mj8-gf6m-fhw8 (high): the router decided a request was local by trusting a client-supplied X-9r-Real-Ip header, so any remote caller could send 127.0.0.1 and reach the owner's LLM API with no key. Now the address must be proven to come from the socket.
70ba002 Preserves prompt_cache_key when translating Chat into Responses — without it every routed request silently lost its cache hit.
59d858b Reads Gemini's usageMetadata out of the antigravity response envelope, so token accounting stopped reporting zero.
27f3710 Ships sql.js in the Docker image so the pure-JS database fallback can actually start.
8af5e75 Adds Fish Audio as a text-to-speech provider.
b04c03c Adds the Alibaba Token Plan provider (token-plan.ap-southeast-1).

lidge-jun/opencodex — coding agent, 11k★. Ten pull requests merged.

PR What it does
#1788 Makes the responses path fail closed when a routed provider invokes a tool that was never declared, instead of passing it through.
#1780 Normalizes tool-call ids so conversation history replays across providers.
#2042 noStructuredOutputModels is documented, in seven locales, as an exact opt-out, and the Responses ingress enforces that. The native Chat passthrough matched the pre-colon prefix instead, so a <listed>:<tag> sibling the operator never opted out silently lost response_format and returned prose where JSON was expected.
#2059 Ten rows of the Lab behavior report tested list membership with a plain includes, while every runtime gate they describe matches through modelInList, which also accepts a bare entry for a tagged id. The report disagreed with production — and it is hashed into the behavior fingerprint that keys Lab evidence.
#2085 resolveInputCeiling read modelContextWindows and modelMaxInputTokens with a bare lookup, while the catalog resolves those same two maps through modelRecordValue, which also accepts a family entry for a tagged id. Admission gave gpt-oss:120b the provider-wide window instead of the gpt-oss family's — the documented behaviour.
#2086 The same mismatch on the CLI side: ocx models built four fields with bare lookups where the proxy resolves them through modelInList / modelRecordValue, so the table operators read did not describe the runtime they were operating.
#2129 Two Windows assertions pinned the eager-relay marker to a constant that only held before the annotations backfill became an unconditional block rewrite. Ties them to isWin32EagerRewrite instead, and proves the rewrite chain through the handler's own output rather than through the factory — the earlier check would have stayed green if production stopped registering it.
#2167 A 401/403 on real traffic quarantines the native account for reauth, but the next background /wham/usage refresh retracted that quarantine on a 200. A usage endpoint answering 200 does not prove the account can serve Responses traffic, which still answers 403 for a workspace the token can no longer select — so the account returned to rotation, failed identically, was re-marked, and needsReauth never settled. That is the symptom #327 was filed about, reintroduced through its own recovery path.
#1806 Keeps an absolute POSIX sqlite home literal in POSIX service files.
#1805 Gives the Windows test sandbox a real profile shape.

williamcachamwri/zalo-tg — Zalo↔Telegram bridge, 276★. Five pull requests merged: #42 group history backfill and offline auto-reply, #43 Zalo reactions as native Telegram reactions, #44 muted threads mirrored as silent, #45 typing and seen indicators, #46 message recall by reacting 🙈.

Open for review

Project Pull request
github/spec-kit 130k★ #4230 — follow-up to the above. The validator suggested a paste-ready correction for conditions that wrapping cannot repair, and each one silently inverted the condition: " " became "{{ }}", inputs.name == 'abc kept its open quote, `inputs.tags
garrytan/gstack 128k★ #2636 — the GITHUB_ prefix admitted operator credentials into hermetic child environments.
farion1231/cc-switch 128k★ #6477 — Codex Desktop's [desktop] config table was wiped on every provider switch. Also #6474, #6476, #6479.
thedotmack/claude-mem 91k★ #3619 — the provider recorded every assistant reply into the conversation history twice, and nothing dedupes it before it becomes the request's messages array, so the assistant half of every later request was double-billed. Also #3620, #3593.
drawdb-io/drawdb 39k★ #1115 — makes a real pg_dump file importable (closes #852). Also #1114, emitting the comma before inline foreign keys on SQLite export.
tinyhumansai/openhuman 36k★ #5586rpcUrl credentials were written to the log unredacted. Also #5588, scrubbing credentials that carry no upper-case character, and #5583, a lint rule for the config boundary the frontend documents but never enforced.
nicolargo/glances 33k★ #3670 — container network stats came from a single interface, so a container with several under-reported its traffic; aggregates over all of them (closes #3669).
decolua/9router 25.7k★ 13 open, including #3369 recovering a tool result that arrived without an id, and #3368 stopping a hard-coded heap cap from overriding the operator.
zenoamaro/react-quill 7k★ #1050 — replace findDOMNode with a ref so the editor works on React 19.
commandlineparser/commandline 4.8k★ #953 — retarget the test project to net8.0 so the suite runs on current SDKs.
nestjsx/nestjs-typeorm-paginate 875★ #927 — reject a limit of 0 instead of dividing totalPages by zero.

How I work

Most of these were found by reading code, not by reproducing a filed issue. The expensive part is never the patch — it's reading enough of an unfamiliar codebase to know which of five plausible causes is the real one. That's why the diffs tend to be three lines rather than thirty.

I apply the same standard to my own work, and reviewers do find things. On claude-mem #3620 a reviewer found two real defects in my diagnostic code — a capped summary reply reported as a truncated observation, and missing upstream usage rendered as zero output tokens. On openhuman #5583 a review caught that my lint selector was wrong in both directions: it missed import.meta['env'] entirely, because computed access stores the key somewhere else on the node, and it flagged new.target.env, which is a different meta-property. I reproduced each case before touching anything, then pinned the boundary with a test that reads the selector out of the shipped config rather than restating it. Fixes and tests the same day, in both cases.

Two recent ones are worth stating because I had them wrong first. On opencodex #2129 a maintainer and an automated reviewer independently made the same point: my test asserted only that a rewrite factory returns a function, which would have stayed green in exactly the case it existed to catch. On #2167 an automated review found that my fix keyed off a flag carrying two meanings, so a retry could launder a background refresh into an operator one — a real hole, and my first regression test for it asserted the wrong thing and failed. Both are corrected in the pull requests, with the reasoning left visible rather than quietly rewritten. I now mutation-check each test against the specific defect it claims to prevent, and put that table in the pull request.

I've also offered to take on verification work rather than only sending patches: claude-mem #3606 — checking each defect a tracker claims against current HEAD and reporting which are already fixed and which are still live, for the maintainer to accept or discard.

Day job

Fullstack — React/Next.js, NestJS, ASP.NET Core, MongoDB/Prisma/SQL. Based in Thanh Hoa, Vietnam. Open-source work is evenings and weekends.

Popular repositories Loading

  1. react-vite-ntdat react-vite-ntdat Public

    JavaScript

  2. react-ultimate-backend react-ultimate-backend Public

  3. react-ultimate-frontend react-ultimate-frontend Public

    JavaScript

  4. react-portfolio-ntdat react-portfolio-ntdat Public

    TypeScript

  5. cv-portfolio-ntdat cv-portfolio-ntdat Public

    TypeScript

  6. fontend-book-app-ntdat fontend-book-app-ntdat Public

    JavaScript