test: add fast-check for OpenSSF Scorecard Fuzzing check - #231
Merged
Conversation
Replace hand-rolled random generators with fast-check, a property-based testing library that the OpenSSF Scorecard recognizes as a fuzzing framework for JavaScript/TypeScript. The scorecard Fuzzing check scans .ts files for fast-check imports — this addresses the 0/10 Fuzzing score. Test coverage is equivalent: parseFrontmatter, parseAdr, AdrFrontmatterSchema, DomainNameSchema, DomainPrefixSchema, and ProjectConfigSchema are all exercised with 500 runs each using fc.property() arbitraries.
Deploying archgate-cli with
|
| Latest commit: |
ab60138
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://67ea06b7.archgate-cli.pages.dev |
| Branch Preview URL: | https://fix-scorecard-env.archgate-cli.pages.dev |
rhuanbarreto
added a commit
that referenced
this pull request
Jul 26, 2026
…ity (#523) Closes #516. ## The gap was live, not hypothetical GEN-002 has always required correct diacritics — *"DO use correct diacritical marks in Portuguese — `não` not `nao`, `código` not `codigo`"* — but nothing enforced it. The companion rules checked only **structure**: page parity, translation drift, link prefixes. So six `pt-br` pages sat in `main` with their diacritics stripped, plus a seventh with a corrupted frontmatter `description`. `nb` hit the identical failure in #384: ~500 occurrences across 35 files, fixed in two manual passes, where the second pass caught four cases the first missed. Manual review is not a reliable detector for this. ## Content Diacritics restored across seven `pt-br/examples` pages — prose, headings, and frontmatter descriptions. Verified mechanically: **0 stripped forms remain**, and **fenced code blocks are byte-identical to `main` in all seven files**, so no identifier, command, or path was touched. ## Rules Two additions to `GEN-002-docs-i18n.rules.ts`, both `error`: - **`i18n-encoding-corruption`** — accented characters written as HTML entities (`å`, `ç`) or as double-encoded UTF-8. Detection requires a `0xC2`/`0xC3` lead byte **followed by** a `0x80`–`0xBF` continuation byte. A bare lead-byte scan would flag legitimate uppercase Portuguese, where `Ã` precedes an ASCII letter — `ÃO` already occurs twice in this tree. - **`i18n-diacritic-density`** — accented characters per 1000 prose letters per locale, ignoring fenced and inline code. Thresholds come from measuring the corpus, not from taste: | | healthy minimum | stripped pages | threshold | |---|---|---|---| | `nb` | 5.9 / 1000 | — | 2 | | `pt-br` | 15.2 / 1000 | 0.0–1.1 | 5 | **A whole-file "has at least one diacritic" check was tried and rejected.** Measured against the six corrupt files it caught **one**: `wrapper-enforcement.mdx` was fully stripped in prose but contained `Não` inside a code sample, which defeats it. Density caught five of six, with a 14× gap between the bands. Accented characters in the rules file are numeric code-point sets, never literals, so the check cannot be broken by the corruption it detects. ## Documented limits `i18n-diacritic-density` is a bulk-stripping detector, not a spell checker. It does **not** catch isolated stripped words in otherwise-correct prose — `max-file-length.mdx` scored a healthy 26.6 while its frontmatter was stripped, and only a word-level scan found it — and it skips pages under 200 prose letters. Both limits are written into GEN-002's Compliance section as review responsibilities rather than left implicit. ## Verification `bun run validate` green: 1675 tests, 49/49 rules, build clean. Fire-tested both directions: | Case | Result | |---|---| | Stripped page restored from `main` | density rule fires, names the file | | `å` injected | caught, correct line | | Double-encoded `ø` injected | caught, correct line | | `VALIDAÇÃO COMPLETA` in `pt-br` | not flagged | ## Review request **Please read the Portuguese as a native speaker.** The automated checks count accents; they cannot tell a correct accent from a confidently wrong one. `à` versus `a` (crasis) and `é` versus `e` are the places to look — I added several of each. An orthography review agent returned PASS here, but its per-word annotations were fabricated, so its verdict carries no weight. --------- Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
Merged
rhuanbarreto
pushed a commit
that referenced
this pull request
Jul 26, 2026
# archgate ## [0.51.0](v0.50.0...v0.51.0) (2026-07-26) ### Features * **adrs:** enforce concise, forward-only code comments (GEN-004) ([#496](#496)) ([9a114b3](9a114b3)), references [#2123](https://github.com/archgate/cli/issues/2123) * **adrs:** flag stray files at the repository root (GEN-005) ([#535](#535)) ([6a6e765](6a6e765)), closes [#514](#514), references [#500](#500) * **engine:** add ctx.readYAML and ctx.checkCase rule helpers ([#497](#497)) ([c5d82c5](c5d82c5)), closes [#490](#490), references [#490](#490) [#491](#491) [#499](#499) [#499](#499) [#499](#499) [#499](#499) * report truncated ADR briefings, trim the ADR corpus 15.6%, add GEN-005 briefing budget ([#501](#501)) ([a9dab40](a9dab40)) ### Bug Fixes * **docs:** relocate ADR content to clear briefing-budget warnings ([#531](#531)) ([c7419b3](c7419b3)) * **docs:** restore pt-br diacritics and enforce locale content integrity ([#523](#523)) ([db39104](db39104)), closes [#516](#516), references [#231](#231) * **engine:** allow symlinks that resolve inside the project root ([#500](#500)) ([387bf15](387bf15)) * **engine:** reject rule-file reads through a symlinked ancestor directory ([#499](#499)) ([a555f9d](a555f9d)), references [#497](#497) [#491](#491) [#497](#497) [#497](#497) [#497](#497) [#497](#497) * **engine:** scan top-level export declarations with a null source ([#493](#493)) ([d07db03](d07db03)), closes [#491](#491) * **engine:** stop dropping AST nodes with exotic literal values ([#494](#494)) ([0015542](0015542)), closes [#493](#493) [#493](#493) * **lint:** resolve no-bare-env-restore by captured key and lexical scope ([#524](#524)) ([7094a3a](7094a3a)), closes [#498](#498) * **rules:** make ARCH-020 and ARCH-023 match ctx.ast() instead of raw text ([#533](#533)) ([ad5529b](ad5529b)), closes [#513](#513), references [#486](#486) * **tests:** replace bun:test anti-patterns with idiomatic patterns ([#512](#512)) ([bcb086f](bcb086f)) --- This PR was generated with [simple-release](https://github.com/TrigenSoftware/simple-release). <details> <summary>📄 Cheatsheet</summary> <br> You can configure the bot's behavior through a pull request comment using the `!simple-release/set-options` command. ### Command Format ````md !simple-release/set-options ```json { "bump": {}, "publish": {} } ``` ```` ### Useful Parameters #### Bump | Parameter | Type | Description | |-----------|------|-------------| | `version` | `string` | Force set specific version | | `as` | `'major' \| 'minor' \| 'patch' \| 'prerelease'` | Release type | | `prerelease` | `string` | Pre-release identifier (e.g., "alpha", "beta") | | `firstRelease` | `boolean` | Whether this is the first release | | `skip` | `boolean` | Skip version bump | | `byProject` | `Record<string, object>` | Per-project bump options for monorepos | #### Publish | Parameter | Type | Description | |-----------|------|-------------| | `skip` | `boolean` | Skip publishing | | `access` | `'public' \| 'restricted'` | Package access level | | `tag` | `string` | Tag for npm publication | ### Usage Examples #### Force specific version ````md !simple-release/set-options ```json { "bump": { "version": "2.0.0" } } ``` ```` #### Force major bump ````md !simple-release/set-options ```json { "bump": { "as": "major" } } ``` ```` #### Create alpha pre-release ````md !simple-release/set-options ```json { "bump": { "prerelease": "alpha" } } ``` ```` #### Publish with specific access and tag ````md !simple-release/set-options ```json { "bump": { "prerelease": "beta" }, "publish": { "access": "public", "tag": "beta" } } ``` ```` ### Custom Changelog Preamble You can add custom markdown to the top of the changelog (right after the version header) using the `!simple-release/set-preamble` command. The markdown after the command line becomes the preamble. ```md !simple-release/set-preamble ## What's new? - The website was completely redesigned - The new API gives you awesome possibilities ``` In a monorepo, pass the full package name after the command to target a single package's changelog. Wrap the name in backticks so GitHub keeps it as text instead of a mention: ```md !simple-release/set-preamble `@your-org/core` ## Core changes - New plugin system ``` Use one comment per package, plus one without a name for the whole release. ### Access Restrictions The commands can only be used by users with permissions: - repository owner - organization member - collaborator ### Notes - The last comment with `!simple-release/set-options` command takes priority - The last `!simple-release/set-preamble` comment per package takes priority - JSON must be valid, otherwise the `set-options` command will be ignored - Parameters apply only to the current release execution - The commands can be updated by editing the comment or adding a new one </details> <!-- Please do not edit this comment. simple-release-pull-request: true simple-release-branch-from: release simple-release-branch-to: main --> Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.tsfiles forimport ... from 'fast-check'— this addresses the 0/10 Fuzzing scoreparseFrontmatter,parseAdr,AdrFrontmatterSchema,DomainNameSchema,DomainPrefixSchema, andProjectConfigSchemaexercised with 500 runs eachExpected Scorecard Impact
Test plan
bun run validatepasses (690 tests, 22/22 ADR rules)