Skip to content

Reconcile proposed zsh-lint architecture ADR 0011 with the shipped analyzer #455

Description

@ss-o

Objective

Reconcile ADR 0011 with the semantic analyzer shipped on z-shell/zsh-lint main, then record an explicit maintainer decision to revise it in place or supersede it.

Audit pin — 2026-07-18

Shipped architectural boundary

The durable design is a conditional two-pass semantic core inside a three-phase diagnostic pipeline:

  1. Scope indexing runs only when a rule implements ScopeAwareRule and returns NeedsScope() == true.
  2. The analyzer walks nodes and evaluates registered rules.
  3. Suppression directives are collected/applied, meta/* diagnostics are preserved or added, and diagnostics are sorted once.

Additional verified facts:

  • No production rule currently requests scope; the opt-in exists in the engine and tests.
  • Rule requires ID() diag.RuleID, Name() string, and Analyze(ctx *Context, node syntax.Node).
  • Context.Report accepts positions, rule ID, severity, and message; there is no AnalyzerContext.Report(diagnostic) API.
  • The scope index is intentionally approximate rather than flow-sensitive local/global resolution.
  • Stable IDs, deterministic ordering, versioned JSON, suppression behavior, parser-gap handling, and rule evidence have their own product contracts and should be linked rather than copied into the ADR.

Claims requiring reconciliation

  • “is transitioning” is stale: the standalone Go analyzer is shipped.
  • Unconditional two-pass wording is incorrect.
  • “use before declaration with high accuracy” describes no shipped rule and is unsupported.
  • “walking twice is negligible” is unmeasured; syntax-only and scope-aware runs do not have the same walk count.
  • Adding a rule requires more than interface registration: stable ID, registry entry, tests, documentation, and rule-policy evidence are part of the shipping contract.
  • The single-pass alternative remains useful rationale but must not imply an existing undefined-function rule.

Draft implementation and review — 2026-07-18

  • Draft PR #456 contains the ADR-only reconciliation at 71286af3.
  • Focused Trunk markdownlint and git diff --check pass.
  • All referenced zsh-lint source and contract paths were resolved against the audited commit.
  • Independent review approved both specification compliance and document quality with no remaining findings.
  • Live CodeQL Advanced run 29637275127 succeeded on exact head 71286af3.
  • The ADR remains PROPOSED; no analyzer behavior changed.

Maintainer decision requested

Recommended outcome: revise ADR 0011 in place because the separation of optional indexing from rule evaluation remains recognizable.

Please decide:

  1. Retain optional scope indexing as an intended extension point even though no production rule consumes it yet.
  2. Keep the current ADR title or rename the decision around the conditional pipeline.
  3. Accept it with a named decider/date, keep it proposed with explicit objections, amend it, supersede it, or reject it.

Checklist

  • Compare ADR 0011 with the promoted analyzer, scope, suppression, diagnostics, and contract documentation.
  • Identify the exact phase, interface, scope-model, performance, and precision drift.
  • Prepare the ADR-only patch while retaining PROPOSED.
  • Link stable contracts instead of copying transient schemas or rule inventory.
  • Verify Markdown/style checks and source references.
  • Complete independent specification and quality review.
  • Record the maintainer decision and synchronize it with Linear.

Boundaries

This is architecture documentation and decision review. It must not change zsh-lint behavior merely to make the implementation resemble the old proposal. Avoid transient PR numbers, commit SHAs, current rule counts, and workflow inventories in the durable ADR.

Triage

Suggested item type: Documentation / architecture
Suggested priority: Medium
Suggested effort: Low
Suggested status: In review

Linear mirror: ZSH-23

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions