Skip to content

Add: per-sub-rule threshold tuning in build-time override file (ADR-0017)#233

Merged
twschiller merged 2 commits into
mainfrom
sub-rule-thresholds
Jun 9, 2026
Merged

Add: per-sub-rule threshold tuning in build-time override file (ADR-0017)#233
twschiller merged 2 commits into
mainfrom
sub-rule-thresholds

Conversation

@twschiller

Copy link
Copy Markdown
Contributor

Summary

  • Widens the ADR-0016 leaf-type invariant from boolean-only to boolean | finite number. Each encoded-payload-redact sub-rule may now be a boolean (existing on/off behaviour from Add: ESLint-style per-rule build-time options (encoded-payload sub-rules) #232) or an object carrying enabled plus named tuning thresholds (minLength, minWords, validRatio, minCommonWords, etc.).
  • A bare boolean at a sub-rule is shorthand for { "enabled": <boolean> }; omitted threshold fields keep their committed defaults.
  • The MIN_* constants that used to live in extension/src/rules/encoded-payload-redact.ts relocate into RULE_OPTION_DEFAULTS in extension/src/rules/rule-metadata.ts alongside the sub-rule on/off shape, so a reader of one file sees both the binary and numeric configuration for each sub-rule. The rule reads its merged thresholds via getRuleOptions(...) at module init and rebuilds the threshold-derived regex candidates (BASE64_CANDIDATE, HEX_CANDIDATE, TEXT_CIPHER_CANDIDATE, LEET_CANDIDATE, MORSE_CANDIDATE) from those values.
  • Validation: leaf type must match the declared default (boolean → boolean, number → finite number). No range checks — operators tuning thresholds are reading the rule source by definition (the sophisticated-user policy recorded in ADR-0017).

Follow-up to #232.

Example

{
  "encoded-payload-redact": {
    "subRules": {
      "leetspeak": false,
      "nato": { "enabled": true, "minWords": 14 },
      "morse": { "enabled": true, "validRatio": 0.95, "minCommonWords": 5 }
    }
  }
}

Implementation

  • extension/src/rules/rule-metadata.tsRULE_OPTION_DEFAULTS carries { enabled, ...thresholds } per sub-rule. WidenLeaves<T> widens both boolean and number literal leaves.
  • extension/scripts/load-default-overrides.ts — validator walks the option tree; accepts booleans at boolean positions, finite numbers at number positions, and the bare-boolean shorthand at object positions whose enabled default is boolean. Reports mistyped option values for: <path> for type mismatches.
  • extension/src/lib/rule-options.tsmergeOptionTree handles all three leaf types and the shorthand. Malformed-bundle defence still falls back to defaults.
  • extension/src/rules/encoded-payload-redact.ts — file-scope MIN_* constants removed; threshold references now read SUB_RULES.<sub-rule>.<knob>. Shared helpers (qualifies, tryCipherDecode, alreadyEnglish) take the threshold as an argument so each caller passes its own.
  • Docs: docs/src/content/docs/install.md, skills/agent-browser-shield-install/SKILL.md, and extension/data/defaults-overrides.example.json demonstrate the threshold form. Spec 0011 FR-2a / FR-4 / NFR-S-2 reworded.

Test plan

  • bun run test — 1954 tests pass (8 new: 1 catalog parity check widening the leaf-type invariant, 7 loader cases for the numeric/object/shorthand shapes, 3 threshold-tuning rule tests).
  • bun run check — biome + eslint clean.
  • pre-commit run — markdown preflight clean (mdformat + markdownlint).
  • End-to-end build smoke — bun run build --defaults /tmp/threshold-overrides.json logs Applying 1 build-time default override(s) with mixed boolean/object sub-rules.
  • Validation failure modes — non-number at a number leaf, unknown sub-rule field, non-boolean shorthand at a boolean-only sub-rule each fail with a clear path-qualified message.

🤖 Generated with Claude Code

…DR-0017)

Widens the ADR-0016 leaf-type invariant from boolean-only to
`boolean | finite number`. Each `encoded-payload-redact` sub-rule may now be
a boolean (existing on/off behaviour) or an object carrying `enabled` plus
named tuning thresholds (`minLength`, `minWords`, `validRatio`,
`minCommonWords`, etc.). Bare boolean at a sub-rule is shorthand for
`{ enabled: <boolean> }`; omitted threshold fields keep their committed
defaults.

The `MIN_*` constants that used to live in `encoded-payload-redact.ts`
relocate to `RULE_OPTION_DEFAULTS` in `rule-metadata.ts` alongside the
sub-rule on/off shape, so a reader of one file sees both the binary and
numeric configuration for each sub-rule. The rule reads its merged
thresholds via `getRuleOptions(...)` at module init and rebuilds the
threshold-derived regex candidates from those values.

Validation: leaf type must match the declared default (boolean → boolean,
number → finite number). No range checks — operators tuning thresholds are
reading the rule source by definition (the sophisticated-user policy
recorded in this ADR).

Stacks on PR #232; both PRs together expose the full per-sub-rule
configuration surface.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agent-browser-shield-demo-site Ready Ready Preview, Comment Jun 9, 2026 3:52pm

Request Review

The ADR was drafted before the PR was opened, with `PR #TBD` placeholders.
Resolve to the actual PR number now that the implementation PR is live.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@twschiller twschiller merged commit b6b5045 into main Jun 9, 2026
2 checks passed
@twschiller twschiller deleted the sub-rule-thresholds branch June 9, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant