Description
Nothing stops a disallowed URL host from reaching the repository. Third-party domains get introduced in Rust source, TypeScript, configuration, and docs, and the only thing standing between a typo'd or lookalike host and main is a human noticing it in review.
Trusted Server runs at the edge on behalf of publishers, so an unreviewed outbound host is a supply-chain concern rather than a style issue. Lookalike authorities make it worse — each of these reads as a familiar name in a diff, while a browser resolves it somewhere else entirely:
| Written in source |
Where a browser actually connects |
//github.com%2eevil%2ecom/x |
github.com.evil.com |
https://github.com.com/x (soft hyphen, invisible in a diff) |
github.com.com |
https://%65vil.com/x |
evil.com |
We want a linter that flags non-allowlisted hosts, plus a pre-commit hook so the check runs before the code is ever pushed.
Proposed solution
ts dev lint domains — a pure-Rust linter over source, config, and docs:
- Four modes:
--staged, --changed-vs <ref>, full-repo audit, and explicit paths.
- All git access through gitoxide, never shelling out to
git.
- Captured authorities canonicalised through the
url crate (percent-decoding, IDNA, case, port) before the allowlist check, so a lookalike cannot pass by matching an allowlisted prefix.
- Allowlists:
EXACT_HOSTS, SUBDOMAIN_HOSTS, REFERENCE_HOSTS, plus RFC 2606 reserved TLDs. Per-line suppression via // allow-domain: <host>.
- Exit codes:
0 clean, 1 violations, 2 environment error. JSON output for CI.
ts dev install-hooks — a one-time installer that writes a managed pre-commit hook running ts dev lint domains --staged into git's own .git/hooks directory (the main repository's, from a linked worktree). It never edits git configuration or the working tree, refuses when core.hooksPath is set in any scope, refuses to clobber an unmanaged hook, and under --force backs the old hook up untouched.
Done when
Affected area
crates/trusted-server-cli (the ts dev command group), developer tooling, CI.
Design
The spec and plan land with the implementation in #733:
- Spec:
docs/superpowers/specs/2026-05-18-check-domains-design.md
- Plan:
docs/superpowers/plans/2026-05-18-ts-dev-lint-domains.md
Description
Nothing stops a disallowed URL host from reaching the repository. Third-party domains get introduced in Rust source, TypeScript, configuration, and docs, and the only thing standing between a typo'd or lookalike host and
mainis a human noticing it in review.Trusted Server runs at the edge on behalf of publishers, so an unreviewed outbound host is a supply-chain concern rather than a style issue. Lookalike authorities make it worse — each of these reads as a familiar name in a diff, while a browser resolves it somewhere else entirely:
//github.com%2eevil%2ecom/xgithub.com.evil.comhttps://github.com.com/x(soft hyphen, invisible in a diff)github.com.comhttps://%65vil.com/xevil.comWe want a linter that flags non-allowlisted hosts, plus a pre-commit hook so the check runs before the code is ever pushed.
Proposed solution
ts dev lint domains— a pure-Rust linter over source, config, and docs:--staged,--changed-vs <ref>, full-repo audit, and explicit paths.git.urlcrate (percent-decoding, IDNA, case, port) before the allowlist check, so a lookalike cannot pass by matching an allowlisted prefix.EXACT_HOSTS,SUBDOMAIN_HOSTS,REFERENCE_HOSTS, plus RFC 2606 reserved TLDs. Per-line suppression via// allow-domain: <host>.0clean,1violations,2environment error. JSON output for CI.ts dev install-hooks— a one-time installer that writes a managedpre-commithook runningts dev lint domains --stagedinto git's own.git/hooksdirectory (the main repository's, from a linked worktree). It never edits git configuration or the working tree, refuses whencore.hooksPathis set in any scope, refuses to clobber an unmanaged hook, and under--forcebacks the old hook up untouched.Done when
ts dev lint domainsflags non-allowlisted hosts in all four modes.ts dev install-hooksinstalls a hook git actually runs, and refuses rather than silently doing nothing when hook configuration is overridden.git commit -aandgit commit -- <path>, which git runs against a temporary index.Affected area
crates/trusted-server-cli(thets devcommand group), developer tooling, CI.Design
The spec and plan land with the implementation in #733:
docs/superpowers/specs/2026-05-18-check-domains-design.mddocs/superpowers/plans/2026-05-18-ts-dev-lint-domains.md