Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Code rules: max depth 2, braces always, no scattered console, no sync fs at runtime, no hand-written validation regex, constants out of logic (org-wide, ratcheted)

Open
#422 2 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
eslint, javascript, typescript

Research direction

Start by reading the @krizaka/config preset and rule registry at docs/standards/rules.json, then inspect the existing ratchet files and rule tests. The change spans shared configuration and every active TypeScript/JavaScript repository, so map the current rules and counts before estimating implementation. Done means the preset is released, rules are registered, active repos are green or ratcheted, and the Yororis lexicon files and lint step are removed from krizaka-com.

Written by the indexing model from the issue text.

Description

Why

Founder review, 2026-10-29, on krizaka-com scripts/lexicon.mjs check(): « for dans for dans for, avec des readFileSync, on bloque le process ; ce code n'est pas très sexy ». Two separate problems:

  1. Nesting. Three loops deep plus a condition, building an array by push. It is hard to read and hard to test. The rules we have (Sonar S3776 at cognitive complexity 15, S2004) did not catch it: it scores under 15.
  2. Synchronous I/O. readFileSync and existsSync in a loop. In a one-shot CLI script it blocks nothing: there is no concurrent work, and sync is even faster there. In code that serves requests, though (Next routes and server components, API handlers, workers, anything under app/, src/ or a package's src/), it stalls the event loop for every user. The rule targets that case.

The rule (org-wide: every TypeScript/JavaScript repo, through @krizaka/config, conformance-checked)

  • ESLint max-depth: 2 for loops and conditions inside one function, plus max-nested-callbacks: 3. Above that, extract a named function, or write a pipeline (flatMap / filter / map) that returns the result instead of pushing into an outer array.
  • ast-grep no-sync-fs-in-runtime. It refuses fs.*Sync(...) (readFileSync, writeFileSync, existsSync, readdirSync, statSync…) in runtime code: app/**, src/**, packages/*/src/**, apps/*/src/**, workers. Use fs/promises with Promise.all for independent reads. It is allowed in scripts/**, tools/**, *.config.* and tests, where sync is correct.
  • Ratchet. Both rules start at today's counts (lint-ratchet.json / sg-ratchet.json) and only go down. They go into the @krizaka/config preset and the rule registry (docs/standards/rules.json), with rule tests (valid and invalid cases).

Founder additions (2026-10-29, same review)

  • Braces always. if, for, while and else always take {}, even for one line. It reads better and avoids the classic mistake when a line is added later. ESLint curly: ["error", "all"], auto-fixed by --fix.
  • No scattered console.*. Logs go through the shared logger of @krizaka/* (levels, structure, redaction), never console.log / console.error directly. ESLint no-console in runtime code. CLI scripts print through one small output helper per script, not console calls scattered through the code.
  • No hand-written patterns for common facts. Example from the review: if (!/^\d{4}-\d{2}-\d{2}$/.test(date ?? "")). Dates, emails, URLs, slugs, phone numbers, postal codes and amounts are validated by the shared @krizaka/ts helpers (date through date-fns behind our facade; e.g. isIsoDate). A missing helper is added to the lib first (rule « Krizaka libs first »). ast-grep no-hand-written-validation-regex refuses a regex literal tested against those shapes, with rule tests.
  • Text and constants out of the logic. Word lists, labels, thresholds and limits live in data: messages for words, a settings/constants module for numbers, the DB when the admin edits them. They never sit inline in a function. One common structure in every repo: each domain's defaults are declared once in a shared module (@krizaka/* or the repo's config/), and the host app can override them through a typed override (settings in the DB when the admin configures them). It is not one global grab-bag file: each domain owns its constants, in the same shape everywhere. This builds on the existing no-unjustified-numeric-export rule.

Also

scripts/lexicon.mjs is the Yororis lexicon check. Yororis left the organisation (#413), so the script, scripts/lexicon-reviewed.json, the lexicon step of npm run lint and the AGENTS.md paragraph are dead code to remove in krizaka-com, not to rewrite.

Done when

  • The preset is released, the rules are in the registry, and every active TS/JS repo is green or ratcheted at its count (« a rule reaches every repo »).
  • krizaka-com: the Yororis lexicon is removed.
Dominant language
No language data
Stars
0
Forks
0
Avg merge
2h 49m
Merged PRs (30d)
212

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from krizaka/.github

All issues in krizaka/.github

Similar issues

More Build System issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.