summaryrefslogtreecommitdiff
path: root/docs/LINTING.txt
diff options
context:
space:
mode:
authorDoan Luu Duc Tai <doan@luuduct.ai>2026-10-31 13:08:08 -0500
committerDoan Luu Duc Tai <doan@luuduct.ai>2026-10-31 13:08:08 -0500
commita80df869a92c330fbad9695057720b11a18af901 (patch)
tree5307272821cb3adc3f0348413a3b904290890044 /docs/LINTING.txt
parent9139398d465f5899cc31bc4cdd54daa7392ca550 (diff)
Forbid Rust lints and enforce strict typed TypeScript linting
Diffstat (limited to 'docs/LINTING.txt')
-rw-r--r--docs/LINTING.txt194
1 files changed, 194 insertions, 0 deletions
diff --git a/docs/LINTING.txt b/docs/LINTING.txt
new file mode 100644
index 0000000..6185b0d
--- /dev/null
+++ b/docs/LINTING.txt
@@ -0,0 +1,194 @@
+Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+STRICT LINT POLICY
+
+ Work is on linting/strict, based on the TypeScript migration. Main and
+ production are separate until this branch is explicitly merged and deployed.
+ Cargo.toml is the workspace policy; all four packages inherit it.
+
+ Forbid rejects source-level attempts to lower a lint. Deny rejects a
+ violation but permits a narrower source-level override. Neither prevents
+ someone from changing the build configuration itself. Compiler/tool versions
+ are pinned, and the checked build is the supported development path.
+
+RUST AND CLIPPY
+
+ Every previously denied individual Clippy rule and every enabled Clippy
+ group now uses forbid. There are no blanket Clippy allow entries. This
+ includes all, correctness, suspicious, cargo, style, complexity, perf,
+ pedantic, nursery, multiple_crate_versions, and redundant_pub_crate.
+ All Rustdoc lints in its supported all group are forbidden too.
+
+ Rust safety, documentation, visibility, casts, edition/future compatibility,
+ underscore bindings, and warnings use forbid. Unused-group members that do
+ not conflict with generated code are independently forbidden. Additional
+ restrictions cover panic/unimplemented/unreachable paths, panic inside Result
+ functions, unsafe allowance attributes, numeric/pointer casts, native-endian
+ data, string slicing, infinite loops, and test placement. Cargo.toml lists
+ the precise rules. Contradictory restriction groups are not enabled wholesale.
+
+ The supported workarounds were implemented instead of lowering these rules:
+
+ Clap derives became explicit checked Clap builders. All argument parsing
+ stays in Clap; application code does not implement a shell parser.
+ Both command schemas have regression tests for modes, required paths,
+ listener parsing, global --root, and maintenance conflicts. Help flags
+ and rejected-option exit codes were compared against the previous binaries.
+ The unused Clap derive feature and its lockfile dependency were removed.
+
+ Tokio's runtime attribute became an explicit checked runtime builder.
+ Runtime construction errors propagate through the existing error path.
+ The broad generated expect/style/complexity allowances are no longer needed.
+
+ Management and server implementations live inside private app namespaces.
+ Internal interfaces use pub(super), narrower than crate visibility. Only
+ the documented program entry point is re-exported at the binary root.
+ This satisfies both redundant_pub_crate and unreachable_pub without
+ exposing helper modules or allowing either lint.
+
+ Serde containers specify crate = "serde". This supported attribute avoids
+ the generated extern-crate branch and its unused_extern_crates and
+ clippy::useless_attribute allowances. File and wire representations retain
+ their existing field names, ordering, tagging, and unknown-field checks.
+
+ Result-returning tests report failed checks with anyhow::ensure instead
+ of panicking. This permits panic_in_result_fn without suppressions.
+
+THREE REMAINING RUST DENY SETTINGS
+
+ unused, nonstandard_style, and unused_qualifications remain deny. This is
+ a generated-code compatibility requirement, not permission to add source
+ allowances. clippy::allow_attributes and allow_attributes_without_reason
+ are forbidden for first-party source.
+
+ The pinned Serde derive implementation unconditionally emits allowances for
+ non_upper_case_globals, unused_attributes, unused_qualifications, and
+ clippy::absolute_paths in serde_derive/src/dummy.rs. Its generated field
+ identifier visitor also allows non_camel_case_types. These are generated
+ attributes even when the first-party type has correct names and no redundant
+ qualification. They cannot be removed by renaming fields or imports.
+
+ The supported crate-path workaround was applied and all macros were inspected.
+ Repeating Clippy with -F unused, -F nonstandard_style, or
+ -F unused_qualifications still rejects the pinned Serde expansion. There is
+ no supported derive setting to suppress that unconditional wrapper. Further
+ changes would require forking the generator or replacing the serialization
+ implementation, including security-sensitive identity/envelope/request formats.
+ Those are explicit upstream/format migrations, not configuration fixes.
+
+ Every other unused-group member and non_snake_case is independently forbidden.
+ warnings itself is forbidden; the explicit deny groups provide the narrowly
+ required effective levels for the generated attributes. No first-party
+ allow/expect attributes were added.
+
+DUPLICATE DEPENDENCIES
+
+ clippy.toml restricts allowed-duplicate-crates to generic-array, getrandom,
+ and syn: the names actually diagnosed in this workspace. The Clippy lint
+ and cargo group remain forbidden for every other dependency.
+
+ The incompatible lines come from the pinned crypto/parser/build graph:
+ generic-array 0.14.7 and 1.4.5
+ getrandom 0.2.17 and 0.4.3
+ syn 2.0.119 and 3.0.9
+
+ These are different semver compatibility lines, not duplicate patch releases.
+ Unifying them requires upstream API changes or older dependencies. No crypto
+ algorithm/backend changes or dependency downgrades were made for a lint.
+ cargo-deny continues to enforce its exact reviewed version exceptions in
+ deny.toml, including build/development dependencies. Clippy's name-only
+ configuration does not replace that stronger version-specific audit.
+
+TYPESCRIPT
+
+ The compiler checks strict mode and the additional indexed access, optional
+ property, unused, return, switch, override, and import checks. noCheck and
+ allowJs are explicitly false. Both declaration-library skip flags are false.
+ isolatedModules, erasableSyntaxOnly, and verbatimModuleSyntax remain enabled.
+ Browser/worker configurations use Bundler resolution with Preserve output;
+ they contain no runtime imports. Tests and tooling use NodeNext separately.
+
+ eslint.config.ts extends the typed strict and stylistic TypeScript presets.
+ All diagnostics are errors and any warning fails the check. Inline config
+ is disabled; suppression directives and unsafe assertions are prohibited.
+ Additional rules reject ambiguous boolean coercion, unhandled/misused promises,
+ explicit or leaked any, non-null assertions, unsafe calls/returns/arguments,
+ eval, unsafe casts, and unchecked discriminated-union switches. Functions
+ expose checked return types; callback contexts retain their declared contracts.
+
+ UI async tasks now have explicit rejection handlers at the DOM boundary.
+ Test HTTP handlers also catch rejected work rather than returning unobserved
+ promises to Node. WASI validates its start export before calling it, and the
+ shared host is installed as a frozen, non-writable global property. Dynamic
+ JSON and worker boundaries still validate unknown values at runtime.
+
+ TypeScript 7.0.2 remains the emitting compiler, installed under the explicit
+ typescript-native npm alias. typescript-eslint 8.72.1 supports TypeScript
+ >=4.8.4 <6.1.0 and requires the JavaScript compiler API, so TypeScript 6.0.3
+ supplies that supported lint API. Sources are checked by both compilers;
+ no unsupported-peer or ignore-peer-dependency install flags are used.
+ Every invocation names the intended compiler path to avoid npm bin collisions.
+
+ Isolated declaration emission is a library-distribution constraint, not an
+ additional application safety check. This project serves classic scripts
+ for the tested LibreJS path and does not publish a TypeScript library.
+ moduleDetection=force is used for tests/tools; changing browser scripts to
+ ESM solely for that setting would change their loading/LibreJS contract.
+ TypeScript 7 removed allowSyntheticDefaultImports=false, so that obsolete
+ switch is not used. Typed linting checks unsafe interop at use sites.
+
+DEVELOPMENT DEPENDENCY ADVISORY
+
+ ESLint and typescript-eslint currently request minimatch 10. The public
+ GHSA-g3hv-75wg-m249 advisory affects minimatch <11.0.1. The root npm override
+ pins the patched 11.0.3 release instead of ignoring the advisory or applying
+ npm audit fix --force. Its supported exports and Node engine were reviewed;
+ typed linting and rule-selection/negative-control checks exercise compatibility.
+ Remove the override when upstream ranges admit a patched version naturally.
+
+ npm audit --audit-level=info is part of npm run check and therefore the Cargo
+ check/release path. Development dependency findings fail the build too.
+ Installed tools preserve their original notices and machine SPDX identifiers.
+ Human documentation calls SPDX MIT the Expat License. No third-party
+ JavaScript dependency is delivered to visitors.
+
+CHECKS AND EXPORTS
+
+ npm run build
+ cargo stack check
+ cargo stack release
+
+ The first checks both TypeScript compilers, typed ESLint, and npm advisories,
+ then emits the browser/worker/test artifacts. Cargo also runs formatting,
+ strict Clippy, all workspace tests, strict Rustdoc, cargo-deny, and cargo-about.
+ Browser checks and GNU LibreJS controls are documented in TYPESCRIPT.txt.
+
+ clippy.toml, eslint.config.ts, every tsconfig, and both lockfiles are included
+ in corresponding sources, releases, and backups. Installed node_modules,
+ runtime state, and the private .env remain outside public exports. Nothing
+ introduces another deployment environment file or a production Node runtime.
+
+PRIMARY REFERENCES
+
+ https://doc.rust-lang.org/stable/rustc/lints/levels.html
+ https://doc.rust-lang.org/clippy/lints.html
+ https://doc.rust-lang.org/clippy/lint_configuration.html
+ https://serde.rs/container-attrs.html
+ https://github.com/serde-rs/serde/blob/v1.0.229/serde_derive/src/dummy.rs
+ https://www.typescriptlang.org/tsconfig/
+ https://typescript-eslint.io/users/configs/
+ https://typescript-eslint.io/users/dependency-versions/
+ https://github.com/advisories/GHSA-g3hv-75wg-m249