DD-333 Phase F.4 (scanner) — S-DOM-002 domain_scope honesty lint #4

Merged
piersdd merged 1 commit from feat/dd-333-phase-f4-domain-scope into main 2026-05-22 13:15:15 +00:00
piersdd commented 2026-05-22 13:07:33 +00:00 (Migrated from github.com)

Summary

  • Adds catalog-scope lint rule S-DOM-002 that flags the "single + scope-arg" contradiction: a plugin tool declares granularity.domain_scope: single (or derived non-conforming-explicit via non_conformance_rationale.domain_scope_unspecified) while advertising a user-domain-shaped argument (name matches /^(scope|domain|domains|domainName|domain_name)$/i, type string/enum).
  • Tool authors opt out per tool via // scope-arg-disclaimer: <reason> in the description; findings are then downgraded to info-only (rendered as warning with [info-only] prefix in message body since LintSeverity only ships "warning" | "error").
  • Ships at warning severity per architect lock #7. Mirrors S-DOM-001 posture — promote to error only after DD-338 A.2.dom blade-side backfill.

Types extension

  • ToolGranularity.domain_scope?: "single" | "multi" | "non-conforming-explicit" — optional 5th dimension mirroring stallari-plugins catalog-entry.schema.json F.4 schema add.
  • NonConformanceRationale.domain_scope_unspecified?: string[] — sister to existing affected_tools / scope_filtering derivation.
  • CatalogTool.arguments?: CatalogToolArgument[] — optional per-tool argument inventory consumed by S-DOM-002. Existing catalog entries (which omit the field) pass through unchanged.

Tests

22 new cases — 127 baseline + 22 new = 149 tests green; tsc --noEmit clean.

  • s_dom_002_passes_honest_pack — multi+arg legitimate, single+no-arg legitimate, undeclared silent
  • s_dom_002_warns_on_single_plus_scope_arg — contradiction → 1 warning
  • s_dom_002_respects_disclaimer — disclaimer annotation downgrades to info-only
  • Argument-name heuristic exhaustion (case-insensitive cover)
  • Argument-type gating (only string/enum count)
  • Multi-declaration silence + omission silence at F.4
  • Non-conformance rationale derivation flow
  • Pack/plugin type gating
  • Registration + posture checks
  • scanCatalogEntries aggregator integration

Version

1.1.0 → 1.2.0 (scanner has its own cadence per spec).

Convention #23 reader-audit

This rule reads three contract slices — the new granularity.domain_scope enum, the optional arguments[] inventory, and the new non_conformance_rationale.domain_scope_unspecified slot. F.4 is additive; existing 11 packs / 30+ plugins are unaffected.

Out of scope

  • Schema add lives in stallari-plugins (sibling PR)
  • Pack-spec docs add lives in stallari-pack-spec (sibling PR)
  • S-DOM-002 check #1 (multi requires _meta.domain_attribution) defers to F.5
  • Promotion to required: + severity escalation to error defer to F.4.b post-DD-338 A.2.dom

Test plan

  • npm test green (149 tests)
  • npm run lint (tsc --noEmit) clean
  • Convention #17 — exactly one Co-Authored-By: Claude Opus 4.7, no Signed-off-by
  • Convention #23 — reader-audit notes embedded in rule docstring + types

Related: DD-333, DD-341, DD-338

## Summary - Adds catalog-scope lint rule `S-DOM-002` that flags the "single + scope-arg" contradiction: a plugin tool declares `granularity.domain_scope: single` (or derived `non-conforming-explicit` via `non_conformance_rationale.domain_scope_unspecified`) while advertising a user-domain-shaped argument (name matches `/^(scope|domain|domains|domainName|domain_name)$/i`, type `string`/`enum`). - Tool authors opt out per tool via `// scope-arg-disclaimer: <reason>` in the description; findings are then downgraded to info-only (rendered as warning with `[info-only]` prefix in message body since `LintSeverity` only ships `"warning" | "error"`). - Ships at `warning` severity per architect lock #7. Mirrors S-DOM-001 posture — promote to `error` only after DD-338 A.2.dom blade-side backfill. ## Types extension - `ToolGranularity.domain_scope?: "single" | "multi" | "non-conforming-explicit"` — optional 5th dimension mirroring stallari-plugins `catalog-entry.schema.json` F.4 schema add. - `NonConformanceRationale.domain_scope_unspecified?: string[]` — sister to existing `affected_tools` / `scope_filtering` derivation. - `CatalogTool.arguments?: CatalogToolArgument[]` — optional per-tool argument inventory consumed by S-DOM-002. Existing catalog entries (which omit the field) pass through unchanged. ## Tests 22 new cases — 127 baseline + 22 new = 149 tests green; `tsc --noEmit` clean. - `s_dom_002_passes_honest_pack` — multi+arg legitimate, single+no-arg legitimate, undeclared silent - `s_dom_002_warns_on_single_plus_scope_arg` — contradiction → 1 warning - `s_dom_002_respects_disclaimer` — disclaimer annotation downgrades to info-only - Argument-name heuristic exhaustion (case-insensitive cover) - Argument-type gating (only string/enum count) - Multi-declaration silence + omission silence at F.4 - Non-conformance rationale derivation flow - Pack/plugin type gating - Registration + posture checks - `scanCatalogEntries` aggregator integration ## Version `1.1.0 → 1.2.0` (scanner has its own cadence per spec). ## Convention #23 reader-audit This rule reads three contract slices — the new `granularity.domain_scope` enum, the optional `arguments[]` inventory, and the new `non_conformance_rationale.domain_scope_unspecified` slot. F.4 is additive; existing 11 packs / 30+ plugins are unaffected. ## Out of scope - Schema add lives in stallari-plugins (sibling PR) - Pack-spec docs add lives in stallari-pack-spec (sibling PR) - S-DOM-002 check #1 (`multi` requires `_meta.domain_attribution`) defers to F.5 - Promotion to `required:` + severity escalation to `error` defer to F.4.b post-DD-338 A.2.dom ## Test plan - [x] `npm test` green (149 tests) - [x] `npm run lint` (tsc --noEmit) clean - [x] Convention #17 — exactly one `Co-Authored-By: Claude Opus 4.7`, no `Signed-off-by` - [x] Convention #23 — reader-audit notes embedded in rule docstring + types Related: [[DD-333]], [[DD-341]], [[DD-338]]
Sign in to join this conversation.
No description provided.