Skip to content

Add: ESLint-style per-rule build-time options (encoded-payload sub-rules)#232

Merged
twschiller merged 2 commits into
mainfrom
worktree-rippling-sprouting-fog
Jun 9, 2026
Merged

Add: ESLint-style per-rule build-time options (encoded-payload sub-rules)#232
twschiller merged 2 commits into
mainfrom
worktree-rippling-sprouting-fog

Conversation

@twschiller

Copy link
Copy Markdown
Contributor

Summary

  • Extends the --defaults / EXTENSION_DEFAULTS_FILE build-time override file to accept an ESLint-style object value { enabled?: boolean, ...subRuleOptions } for any rule that declares a sub-rule shape in RULE_OPTION_DEFAULTS. Plain booleans still work; the Options-page export shape stays flat-boolean and is untouched. Build-time only this iteration — no chrome.storage or Options-page UI changes.
  • First (and only) consumer: encoded-payload-redact. Its seven detectors (base64, hex, percent, substitutionCipher, leetspeak, nato, morse) are now individually togglable. Operators can disable the higher-false-positive text ciphers (leetspeak / NATO / Morse) without losing coverage of the byte encodings.
  • Validation is strict: object values for rules without declared options, unknown sub-rule keys, and non-boolean leaves all fail the build with path-qualified messages (e.g. encoded-payload-redact.subRules.bogus).

Example

{
  "encoded-payload-redact": {
    "enabled": true,
    "subRules": { "leetspeak": false, "nato": false, "morse": false }
  }
}

Implementation

  • extension/src/rules/rule-metadata.ts — adds RULE_OPTION_DEFAULTS + RuleOptions type alongside the existing flat RULE_DEFAULTS. Pure data, service-worker-safe.
  • extension/src/lib/rule-options.ts (new) — parses EXTENSION_RULE_OPTIONS once at content-script init, merges over defaults, exposes typed getRuleOptions(id). Malformed JSON silently degrades (mirrors lib/storage.ts, spec 0011 NFR-S-2).
  • extension/scripts/load-default-overrides.ts — recursively walks per-rule option trees, accumulates path-qualified validation issues.
  • extension/build.ts — passes RULE_OPTION_DEFAULTS to the loader and injects EXTENSION_RULE_OPTIONS via define:.
  • extension/src/rules/encoded-payload-redact.ts — reads SUB_RULES at module init and gates each collectMatches step.
  • Docs: specs/0011-build-time-customization.md (new FR-2a, updated FR-4 / NFR-S-2 / Current implementation), docs/src/content/docs/install.md, skills/agent-browser-shield-install/SKILL.md, extension/data/defaults-overrides.example.json.

Test plan

  • bun run test — 1946 tests pass (12 new sub-rule / loader cases, 2 new catalog invariants).
  • bun run check — biome + eslint clean.
  • pre-commit run — markdown preflight clean (mdformat + markdownlint).
  • End-to-end build smoke — bun run build --defaults /tmp/sub-rule-overrides.json logs Applying 2 build-time default override(s).
  • Validation failure modes — four malformed inputs (object value for pii-redact, unknown sub-rule key, non-boolean leaf, unknown top-level group under a rule object) each fail with a clear path-qualified message.

🤖 Generated with Claude Code

…les)

Extends the `--defaults` / `EXTENSION_DEFAULTS_FILE` override file to accept
an object value `{ enabled?: boolean, ...subRuleOptions }` for any rule that
declares a sub-rule shape in `RULE_OPTION_DEFAULTS`. Plain booleans still
work; the Options-page export shape stays flat. Build-time only this
iteration — no chrome.storage or Options-page UI changes.

First (and only) consumer: `encoded-payload-redact`, whose seven detectors
(base64, hex, percent, substitutionCipher, leetspeak, nato, morse) are now
individually togglable. Operators can turn off the higher-false-positive text
ciphers (leetspeak / NATO / Morse) without losing coverage of the byte
encodings.

Validation is strict: object values for rules without declared options,
unknown sub-rule keys, and non-boolean leaves all fail the build with
path-qualified messages (e.g. `encoded-payload-redact.subRules.bogus`).

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:24pm

Request Review

Records the decision behind the override-file shape introduced earlier in
this PR: a rule's value may be a boolean (existing behaviour) or an
ESLint-style object `{ enabled?, ...subRuleOptions }`, gated on the rule
declaring a shape in `RULE_OPTION_DEFAULTS`. Considered alternatives — a
top-level `ruleOptions` sibling key and dot-notation flat keys — captured
with pros / cons.

Updates `decisions/README.md` index and adds ADR-0016 to spec 0011's Related
section.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@twschiller twschiller merged commit d6dca16 into main Jun 9, 2026
7 checks passed
@twschiller twschiller deleted the worktree-rippling-sprouting-fog branch June 9, 2026 15:35
twschiller added a commit that referenced this pull request Jun 9, 2026
…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>
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