code-standards 7.0.4__tar.gz → 7.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {code_standards-7.0.4 → code_standards-7.1.0}/PKG-INFO +2 -2
- {code_standards-7.0.4 → code_standards-7.1.0}/pyproject.toml +2 -2
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/_meta.py +3 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/api.py +26 -6
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/cli/main.py +78 -9
- code_standards-7.1.0/src/sarj_standards/configs/basedpyright.python315-watch.json +7 -0
- code_standards-7.1.0/src/sarj_standards/configs/basedpyright.strict.json +22 -0
- code_standards-7.1.0/src/sarj_standards/configs/cli-reference.v1.json +1 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/doctor.config.json +1 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/eslint.application.mjs +16 -12
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/eslint.peers.json +1 -1
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/eslint.strict.mjs +16 -12
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/pyright.strict.json +5 -18
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/ruff.application.toml +3 -0
- code_standards-7.1.0/src/sarj_standards/configs/ruff.python315-watch.toml +5 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/ruff.strict.toml +3 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/rule-inventory.v1.json +1 -1
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/rule-ledger.json +17 -3
- code_standards-7.1.0/src/sarj_standards/configs/rule-warning-levels.v1.json +1 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/configs.py +10 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/doctor.py +39 -3
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/scaffold.py +30 -11
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/service.py +16 -1
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/transaction.py +2 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/upgrade.py +16 -1
- code_standards-7.1.0/src/sarj_standards/libs/diagnostics/baseline.py +357 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/external.py +89 -37
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/textlint.py +10 -140
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/rollout.py +166 -12
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/docs.py +2 -2
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/repository.py +2 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_maintenance.py +21 -3
- code_standards-7.1.0/src/sarj_standards/schemas/rule-catalog.v1.json +1 -0
- code_standards-7.0.4/src/sarj_standards/configs/cli-reference.v1.json +0 -1
- code_standards-7.0.4/src/sarj_standards/configs/rule-warning-levels.v1.json +0 -1
- code_standards-7.0.4/src/sarj_standards/libs/diagnostics/baseline.py +0 -131
- code_standards-7.0.4/src/sarj_standards/schemas/rule-catalog.v1.json +0 -1
- {code_standards-7.0.4 → code_standards-7.1.0}/.gitignore +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/LICENSE +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/README.md +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/__main__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/cli/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/markdownlint.strict.yaml +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/taplo.strict.toml +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/yamllint.strict.yaml +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/exclusions.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/hooks.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/launcher.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/lifecycle.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/manifest.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/packagemanager.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/retired_suppressions.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/uvtool.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/catalogs/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/catalogs/slack_automations.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/corpus/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/corpus/manifest.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/corpus/snapshot.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/diagnostics/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/diagnostics/analysis.schema.json +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/diagnostics/models.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/diagnostics/serialize.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/diagnostics/source.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/filesystem.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/analysis.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/library_policy.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/policy.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/runner.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/_values.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/artifacts.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/causality.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/changes.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/process.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/publish.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/registry.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/release_age.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/tags.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/typescript.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/cli_reference_artifact.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/comment_corpus.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/config_generation.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/hooks.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/ledger.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_authoring.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_catalog_artifact.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_changes.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_inventory_artifact.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_lifecycle.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/rules/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/rules/catalog.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/rules/contracts.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/rules/corpus_runner.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/rules/evaluation.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/setup/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/setup/repository.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/py.typed +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/schemas/__init__.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/schemas/_paths.py +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/schemas/rule-catalog.v1.schema.json +0 -0
- {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/schemas/slack-automations.v1.schema.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: code-standards
|
|
3
|
-
Version: 7.0
|
|
3
|
+
Version: 7.1.0
|
|
4
4
|
Summary: One deterministic quality gate for Sarj Python, TypeScript, SQL, IaC, and repository policy.
|
|
5
5
|
Project-URL: Homepage, https://code-standards.sarj.ai/
|
|
6
6
|
Project-URL: Documentation, https://code-standards.sarj.ai/cli/
|
|
@@ -26,7 +26,7 @@ Requires-Dist: pydantic==2.13.4
|
|
|
26
26
|
Requires-Dist: pyyaml==6.0.3
|
|
27
27
|
Requires-Dist: ruff==0.16.3
|
|
28
28
|
Requires-Dist: sarj-iac-lint==0.14.3
|
|
29
|
-
Requires-Dist: sarj-python-lint==0.
|
|
29
|
+
Requires-Dist: sarj-python-lint==0.78.0
|
|
30
30
|
Requires-Dist: sarj-sql-lint==0.16.1
|
|
31
31
|
Description-Content-Type: text/markdown
|
|
32
32
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "code-standards"
|
|
3
|
-
version = "7.0
|
|
3
|
+
version = "7.1.0"
|
|
4
4
|
description = "One deterministic quality gate for Sarj Python, TypeScript, SQL, IaC, and repository policy."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.14"
|
|
@@ -25,7 +25,7 @@ dependencies = [
|
|
|
25
25
|
"PyYAML==6.0.3",
|
|
26
26
|
"ruff==0.16.3",
|
|
27
27
|
"sarj-iac-lint==0.14.3",
|
|
28
|
-
"sarj-python-lint==0.
|
|
28
|
+
"sarj-python-lint==0.78.0",
|
|
29
29
|
"sarj-sql-lint==0.16.1",
|
|
30
30
|
]
|
|
31
31
|
|
|
@@ -14,6 +14,9 @@ CONFIGS_DIR: Path = Path(__file__).resolve().parent / "configs"
|
|
|
14
14
|
RUFF_STRICT: Path = CONFIGS_DIR / "ruff.strict.toml"
|
|
15
15
|
RUFF_APPLICATION: Path = CONFIGS_DIR / "ruff.application.toml"
|
|
16
16
|
PYRIGHT_STRICT: Path = CONFIGS_DIR / "pyright.strict.json"
|
|
17
|
+
BASEDPYRIGHT_STRICT: Path = CONFIGS_DIR / "basedpyright.strict.json"
|
|
18
|
+
RUFF_PYTHON315_WATCH: Path = CONFIGS_DIR / "ruff.python315-watch.toml"
|
|
19
|
+
BASEDPYRIGHT_PYTHON315_WATCH: Path = CONFIGS_DIR / "basedpyright.python315-watch.json"
|
|
17
20
|
ESLINT_STRICT: Path = CONFIGS_DIR / "eslint.strict.mjs"
|
|
18
21
|
ESLINT_APPLICATION: Path = CONFIGS_DIR / "eslint.application.mjs"
|
|
19
22
|
MARKDOWNLINT_STRICT: Path = CONFIGS_DIR / "markdownlint.strict.yaml"
|
|
@@ -240,6 +240,7 @@ class Standards:
|
|
|
240
240
|
mode: AnalysisMode | str = AnalysisMode.POLICY,
|
|
241
241
|
rules: Sequence[str | RuleSelector] | None = None,
|
|
242
242
|
staged: bool = False,
|
|
243
|
+
react_doctor_triggered: bool = False,
|
|
243
244
|
) -> AnalysisReport:
|
|
244
245
|
try:
|
|
245
246
|
normalized_trust = TrustMode(trust)
|
|
@@ -264,12 +265,18 @@ class Standards:
|
|
|
264
265
|
try:
|
|
265
266
|
baseline_counts: dict[str, int]
|
|
266
267
|
baseline_counts = (
|
|
267
|
-
diagnostic_baseline.load(
|
|
268
|
+
diagnostic_baseline.load(
|
|
269
|
+
self.root / adopted.diagnostic_baseline,
|
|
270
|
+
require_v2=True,
|
|
271
|
+
expected_bundle_version=__version__,
|
|
272
|
+
expected_catalog_digest=diagnostic_baseline.bundled_catalog_digest(),
|
|
273
|
+
)
|
|
268
274
|
if normalized_mode is AnalysisMode.POLICY
|
|
269
275
|
and adopted is not None
|
|
270
276
|
and adopted.diagnostic_baseline is not None
|
|
271
277
|
else {}
|
|
272
278
|
)
|
|
279
|
+
changed_scope = diagnostic_baseline.changed_line_scope(self.root, staged=staged)
|
|
273
280
|
except (OSError, TypeError, ValueError) as exc:
|
|
274
281
|
return _failed_analysis(self.root, "baseline-failure", str(exc))
|
|
275
282
|
try:
|
|
@@ -335,7 +342,9 @@ class Standards:
|
|
|
335
342
|
)
|
|
336
343
|
if normalized_mode in {AnalysisMode.POLICY, AnalysisMode.OBSERVE}:
|
|
337
344
|
native = _with_warning_severity(native, _warning_rule_keys())
|
|
338
|
-
return _with_coverage(
|
|
345
|
+
return _with_coverage(
|
|
346
|
+
_without_baselined_diagnostics(native, baseline_counts, changed_scope=changed_scope), coverage
|
|
347
|
+
)
|
|
339
348
|
if selected_groups.typescript and adopted is not None and "eslint" not in adopted.configs:
|
|
340
349
|
coverage.append(
|
|
341
350
|
CoverageNotice(
|
|
@@ -355,7 +364,8 @@ class Standards:
|
|
|
355
364
|
policy=selection_policy,
|
|
356
365
|
capabilities=(frozenset({"eslint"}) if rule_selection is not None else frozenset(adopted.configs)),
|
|
357
366
|
grouped=selected_groups,
|
|
358
|
-
include_react_doctor=
|
|
367
|
+
include_react_doctor=rule_selection is None,
|
|
368
|
+
force_react_doctor=react_doctor_triggered,
|
|
359
369
|
react_doctor_staged=staged,
|
|
360
370
|
)
|
|
361
371
|
if adopted is not None
|
|
@@ -364,7 +374,8 @@ class Standards:
|
|
|
364
374
|
root=self.root,
|
|
365
375
|
trust=normalized_trust,
|
|
366
376
|
grouped=selected_groups,
|
|
367
|
-
include_react_doctor=
|
|
377
|
+
include_react_doctor=rule_selection is None,
|
|
378
|
+
force_react_doctor=react_doctor_triggered,
|
|
368
379
|
react_doctor_staged=staged,
|
|
369
380
|
)
|
|
370
381
|
)
|
|
@@ -386,7 +397,9 @@ class Standards:
|
|
|
386
397
|
combined = report_from_tools(self.root, (*native.tools, *external_reports))
|
|
387
398
|
if normalized_mode in {AnalysisMode.POLICY, AnalysisMode.OBSERVE}:
|
|
388
399
|
combined = _with_warning_severity(combined, _warning_rule_keys())
|
|
389
|
-
return _with_coverage(
|
|
400
|
+
return _with_coverage(
|
|
401
|
+
_without_baselined_diagnostics(combined, baseline_counts, changed_scope=changed_scope), coverage
|
|
402
|
+
)
|
|
390
403
|
|
|
391
404
|
def run(
|
|
392
405
|
self,
|
|
@@ -578,7 +591,12 @@ def _failed_analysis(root: Path, kind: str, message: str) -> AnalysisReport:
|
|
|
578
591
|
return AnalysisReport(root, Completion.FAILED, Conclusion.INCONCLUSIVE, (tool,))
|
|
579
592
|
|
|
580
593
|
|
|
581
|
-
def _without_baselined_diagnostics(
|
|
594
|
+
def _without_baselined_diagnostics(
|
|
595
|
+
report: AnalysisReport,
|
|
596
|
+
counts: dict[str, int],
|
|
597
|
+
*,
|
|
598
|
+
changed_scope: diagnostic_baseline.ChangedLineScope | None = None,
|
|
599
|
+
) -> AnalysisReport:
|
|
582
600
|
if not counts:
|
|
583
601
|
return report
|
|
584
602
|
remaining = counts.copy()
|
|
@@ -586,6 +604,8 @@ def _without_baselined_diagnostics(report: AnalysisReport, counts: dict[str, int
|
|
|
586
604
|
def active(diagnostic: Diagnostic) -> bool:
|
|
587
605
|
if not diagnostic_baseline.is_baselineable(diagnostic) or diagnostic.code == "SARJ206":
|
|
588
606
|
return True
|
|
607
|
+
if diagnostic_baseline.touches_changed_lines(diagnostic, changed_scope):
|
|
608
|
+
return True
|
|
589
609
|
fingerprint = diagnostic.fingerprint
|
|
590
610
|
budget = 0 if fingerprint is None else remaining.get(fingerprint, 0)
|
|
591
611
|
if budget < 1 or fingerprint is None:
|
|
@@ -50,6 +50,19 @@ _INVALID_DOCTOR_IDS = frozenset(
|
|
|
50
50
|
"doctor.package-json.invalid",
|
|
51
51
|
}
|
|
52
52
|
)
|
|
53
|
+
_REACT_DOCTOR_METADATA = frozenset(
|
|
54
|
+
{
|
|
55
|
+
"doctor.config.json",
|
|
56
|
+
"eslint.config.js",
|
|
57
|
+
"eslint.config.mjs",
|
|
58
|
+
"package-lock.json",
|
|
59
|
+
"package.json",
|
|
60
|
+
"pnpm-lock.yaml",
|
|
61
|
+
"tsconfig.json",
|
|
62
|
+
"yarn.lock",
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
_REACT_DOCTOR_TYPESCRIPT_SUFFIXES = frozenset({".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mts", ".cts"})
|
|
53
66
|
|
|
54
67
|
|
|
55
68
|
class _EvaluationScope(StrEnum):
|
|
@@ -125,6 +138,8 @@ class _Args(argparse.Namespace):
|
|
|
125
138
|
selector: RuleSelector | None = None
|
|
126
139
|
evaluation_scope: _EvaluationScope = _EvaluationScope.CORPUS
|
|
127
140
|
baseline: Path | None = None
|
|
141
|
+
baseline_rules: list[str]
|
|
142
|
+
react_doctor_triggered: bool = False
|
|
128
143
|
package: list[str]
|
|
129
144
|
exclude_subtree: list[str]
|
|
130
145
|
allow_increase: bool = False
|
|
@@ -141,6 +156,7 @@ class _Args(argparse.Namespace):
|
|
|
141
156
|
self.repo_only = []
|
|
142
157
|
self.roots = []
|
|
143
158
|
self.release_exclude = []
|
|
159
|
+
self.baseline_rules = []
|
|
144
160
|
self.release_exclude_file = []
|
|
145
161
|
self.release_targets = []
|
|
146
162
|
self.wheels = []
|
|
@@ -770,7 +786,7 @@ def cmd_library_policy(args: _Args, *, selected_paths: Iterable[str] | None = No
|
|
|
770
786
|
return 1 if findings else 0
|
|
771
787
|
|
|
772
788
|
|
|
773
|
-
def cmd_check(args: _Args) -> int:
|
|
789
|
+
def cmd_check(args: _Args) -> int: # ruff: ignore[too-many-locals] -- staged and PR scopes retain Doctor triggers.
|
|
774
790
|
from sarj_standards.libs.linting import external, runner # ruff: ignore[import-outside-top-level]
|
|
775
791
|
|
|
776
792
|
root = _resolve_dest(args.dest)
|
|
@@ -779,9 +795,11 @@ def cmd_check(args: _Args) -> int:
|
|
|
779
795
|
return catalog_status
|
|
780
796
|
repository_wide = not args.files
|
|
781
797
|
pull_request_scoped = False
|
|
798
|
+
react_doctor_triggered = False
|
|
782
799
|
if args.staged:
|
|
783
800
|
try:
|
|
784
801
|
staged_names = _staged_file_names(root)
|
|
802
|
+
react_doctor_triggered = _react_doctor_triggered_by(staged_names)
|
|
785
803
|
staged = _safe_staged_paths(root, staged_names)
|
|
786
804
|
except (OSError, subprocess.SubprocessError) as exc:
|
|
787
805
|
if args.output_format != "text":
|
|
@@ -819,7 +837,11 @@ def cmd_check(args: _Args) -> int:
|
|
|
819
837
|
pull_request_scoped = True
|
|
820
838
|
elif (root / ".git").exists() and (base := external.change_scope_base()):
|
|
821
839
|
try:
|
|
822
|
-
|
|
840
|
+
changed_names = _changed_file_names(root, base)
|
|
841
|
+
react_doctor_triggered = _react_doctor_triggered_by(changed_names)
|
|
842
|
+
args.files = [
|
|
843
|
+
path for path in _safe_staged_paths(root, changed_names) if runner.accepts_hook_path(Path(path))
|
|
844
|
+
]
|
|
823
845
|
pull_request_scoped = True
|
|
824
846
|
except (OSError, subprocess.SubprocessError) as exc:
|
|
825
847
|
if args.output_format != "text":
|
|
@@ -838,7 +860,7 @@ def cmd_check(args: _Args) -> int:
|
|
|
838
860
|
if health_status:
|
|
839
861
|
return health_status
|
|
840
862
|
args.files = [path for path in args.files if runner.accepts_hook_path(Path(path))]
|
|
841
|
-
if not args.files:
|
|
863
|
+
if not args.files and not react_doctor_triggered:
|
|
842
864
|
return 0
|
|
843
865
|
if args.output_format != "text":
|
|
844
866
|
if _validate_analysis_output(args, root):
|
|
@@ -862,18 +884,33 @@ def cmd_check(args: _Args) -> int:
|
|
|
862
884
|
external=True,
|
|
863
885
|
trust=TrustMode.TRUSTED if args.trust_repository_code else TrustMode.SAFE,
|
|
864
886
|
mode=AnalysisMode.POLICY,
|
|
887
|
+
react_doctor_triggered=react_doctor_triggered,
|
|
865
888
|
)
|
|
866
889
|
return _emit_analysis_report(args, root, report)
|
|
890
|
+
args.react_doctor_triggered = react_doctor_triggered
|
|
867
891
|
return cmd_analyze(args)
|
|
868
892
|
if pull_request_scoped:
|
|
869
893
|
adoption_report = _machine_adoption_gate(root)
|
|
870
894
|
if adoption_report is not None:
|
|
871
895
|
return _emit_analysis_report(args, root, adoption_report)
|
|
872
896
|
if not args.files:
|
|
897
|
+
if react_doctor_triggered:
|
|
898
|
+
return _run_canonical_check(
|
|
899
|
+
root,
|
|
900
|
+
(),
|
|
901
|
+
trusted=args.trust_repository_code,
|
|
902
|
+
react_doctor_triggered=True,
|
|
903
|
+
)
|
|
873
904
|
return _run_canonical_check(root, (), trusted=args.trust_repository_code)
|
|
874
905
|
if not args.files:
|
|
875
906
|
return cmd_verify(args)
|
|
876
|
-
|
|
907
|
+
check_options: dict[str, bool] = {
|
|
908
|
+
"trusted": args.trust_repository_code,
|
|
909
|
+
"staged": args.staged,
|
|
910
|
+
}
|
|
911
|
+
if react_doctor_triggered:
|
|
912
|
+
check_options["react_doctor_triggered"] = True
|
|
913
|
+
return _run_canonical_check(root, list(args.files), **check_options)
|
|
877
914
|
|
|
878
915
|
|
|
879
916
|
def cmd_validate_slack_automations(args: _Args) -> int:
|
|
@@ -945,6 +982,7 @@ def _run_canonical_check(
|
|
|
945
982
|
raw: bool = False,
|
|
946
983
|
trusted: bool = False,
|
|
947
984
|
staged: bool = False,
|
|
985
|
+
react_doctor_triggered: bool = False,
|
|
948
986
|
) -> int:
|
|
949
987
|
from sarj_standards.api import AnalysisMode, Standards, TrustMode # ruff: ignore[import-outside-top-level]
|
|
950
988
|
from sarj_standards.libs.diagnostics import to_text # ruff: ignore[import-outside-top-level]
|
|
@@ -955,6 +993,7 @@ def _run_canonical_check(
|
|
|
955
993
|
trust=TrustMode.TRUSTED if trusted else TrustMode.SAFE,
|
|
956
994
|
mode=AnalysisMode.RAW if raw else AnalysisMode.POLICY,
|
|
957
995
|
staged=staged,
|
|
996
|
+
react_doctor_triggered=react_doctor_triggered,
|
|
958
997
|
)
|
|
959
998
|
rendered = to_text(report)
|
|
960
999
|
if rendered:
|
|
@@ -977,6 +1016,7 @@ def cmd_analyze(args: _Args) -> int:
|
|
|
977
1016
|
trust=args.trust,
|
|
978
1017
|
mode=AnalysisMode(args.analysis_mode),
|
|
979
1018
|
staged=args.staged,
|
|
1019
|
+
react_doctor_triggered=args.react_doctor_triggered,
|
|
980
1020
|
)
|
|
981
1021
|
return _emit_analysis_report(args, root, report)
|
|
982
1022
|
|
|
@@ -1362,7 +1402,7 @@ def _staged_file_names(root: Path) -> list[str]:
|
|
|
1362
1402
|
msg = "git is required for --staged"
|
|
1363
1403
|
raise OSError(msg)
|
|
1364
1404
|
completed = subprocess.run( # ruff: ignore[subprocess-without-shell-equals-true] -- fixed argv, no shell.
|
|
1365
|
-
[git, "diff", "--cached", "--name-only", "--diff-filter=
|
|
1405
|
+
[git, "diff", "--cached", "--name-only", "--diff-filter=ACDMR", "-z"],
|
|
1366
1406
|
cwd=root,
|
|
1367
1407
|
check=True,
|
|
1368
1408
|
capture_output=True,
|
|
@@ -1373,19 +1413,29 @@ def _staged_file_names(root: Path) -> list[str]:
|
|
|
1373
1413
|
|
|
1374
1414
|
|
|
1375
1415
|
def _changed_file_paths(root: Path, base: str) -> list[str]:
|
|
1416
|
+
return _safe_staged_paths(root, _changed_file_names(root, base))
|
|
1417
|
+
|
|
1418
|
+
|
|
1419
|
+
def _changed_file_names(root: Path, base: str) -> list[str]:
|
|
1376
1420
|
git = shutil.which("git")
|
|
1377
1421
|
if git is None:
|
|
1378
1422
|
msg = "git is required for pull-request change scoping"
|
|
1379
1423
|
raise OSError(msg)
|
|
1380
1424
|
completed = subprocess.run( # ruff: ignore[subprocess-without-shell-equals-true] -- fixed argv, no shell.
|
|
1381
|
-
[git, "diff", "--name-only", "--diff-filter=
|
|
1425
|
+
[git, "diff", "--name-only", "--diff-filter=ACDMR", "-z", f"{base}...HEAD", "--"],
|
|
1382
1426
|
cwd=root,
|
|
1383
1427
|
check=True,
|
|
1384
1428
|
capture_output=True,
|
|
1385
1429
|
env=_git_environment(),
|
|
1386
1430
|
)
|
|
1387
|
-
|
|
1388
|
-
|
|
1431
|
+
return [part.decode("utf-8", errors="surrogateescape") for part in completed.stdout.split(b"\0") if part]
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
def _react_doctor_triggered_by(paths: Iterable[str]) -> bool:
|
|
1435
|
+
return any(
|
|
1436
|
+
Path(value).name in _REACT_DOCTOR_METADATA or Path(value).suffix.lower() in _REACT_DOCTOR_TYPESCRIPT_SUFFIXES
|
|
1437
|
+
for value in paths
|
|
1438
|
+
)
|
|
1389
1439
|
|
|
1390
1440
|
|
|
1391
1441
|
def _safe_staged_paths(root: Path, paths: Iterable[str]) -> list[str]:
|
|
@@ -1650,7 +1700,18 @@ def cmd_baseline(args: _Args) -> int:
|
|
|
1650
1700
|
print(f"error: {issue.kind}: {issue.message}", file=sys.stderr)
|
|
1651
1701
|
return 2
|
|
1652
1702
|
eligible = tuple(item for item in report.diagnostics if baseline.is_baselineable(item))
|
|
1653
|
-
|
|
1703
|
+
provenance = {
|
|
1704
|
+
"bundle_version": __version__,
|
|
1705
|
+
"consumer_base_sha": baseline.repository_base_sha(root),
|
|
1706
|
+
"catalog_digest": baseline.bundled_catalog_digest(),
|
|
1707
|
+
}
|
|
1708
|
+
if args.baseline_cmd == "update" and args.baseline_rules:
|
|
1709
|
+
if not output.is_file():
|
|
1710
|
+
print(f"error: scoped diagnostic baseline update requires an existing baseline: {output}", file=sys.stderr)
|
|
1711
|
+
return 2
|
|
1712
|
+
rendered = baseline.merge_scoped(output, eligible, selectors=args.baseline_rules, **provenance)
|
|
1713
|
+
else:
|
|
1714
|
+
rendered = baseline.render(eligible, **provenance)
|
|
1654
1715
|
try:
|
|
1655
1716
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
1656
1717
|
output.write_text(rendered, encoding="utf-8")
|
|
@@ -1916,6 +1977,14 @@ def build_parser() -> argparse.ArgumentParser: # ruff: ignore[too-many-locals]
|
|
|
1916
1977
|
action="store_true",
|
|
1917
1978
|
help="run repository-local analyzers that execute project code",
|
|
1918
1979
|
)
|
|
1980
|
+
if name == "update":
|
|
1981
|
+
command.add_argument(
|
|
1982
|
+
"--rule",
|
|
1983
|
+
action="append",
|
|
1984
|
+
dest="baseline_rules",
|
|
1985
|
+
default=[],
|
|
1986
|
+
help="replace debt only for this newly promoted rule (repeatable; source:RULE is also accepted)",
|
|
1987
|
+
)
|
|
1919
1988
|
command.add_argument("files", nargs="*", help="paths to analyze (default: the whole repository)")
|
|
1920
1989
|
|
|
1921
1990
|
ratchet = sub.add_parser("ratchet", help="keep the Python suppression budget from growing")
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Additive active BasedPyright policy. Upstream-Pyright consumers can extend
|
|
3
|
+
// pyright.strict.json directly without receiving unrecognized settings.
|
|
4
|
+
"extends": "./pyright.strict.json",
|
|
5
|
+
"enableBasedFeatures": false,
|
|
6
|
+
"strictGenericNarrowing": true,
|
|
7
|
+
|
|
8
|
+
"reportInvalidCast": "error",
|
|
9
|
+
"reportUnsafeMultipleInheritance": "error",
|
|
10
|
+
"reportImplicitRelativeImport": "error",
|
|
11
|
+
"reportExplicitAny": "error",
|
|
12
|
+
"reportIgnoreCommentWithoutRule": "error",
|
|
13
|
+
"reportPrivateLocalImportUsage": "error",
|
|
14
|
+
"reportAny": "error",
|
|
15
|
+
"reportUnannotatedClassAttribute": "error",
|
|
16
|
+
|
|
17
|
+
"reportImplicitAbstractClass": "error",
|
|
18
|
+
"reportEmptyAbstractUsage": "error",
|
|
19
|
+
"reportIncompatibleUnannotatedOverride": "error",
|
|
20
|
+
"reportInvalidAbstractMethod": "error",
|
|
21
|
+
"reportSelfClsDefault": "error"
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"commands":[{"commands":[],"name":"doctor","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["text","json"],"kind":"option","metavar":"OUTPUT_FORMAT","names":["--format"],"repeatable":false,"required":false,"summary":"output format (default: text)"},{"choices":[],"kind":"option","metavar":null,"names":["--repair"],"repeatable":false,"required":false,"summary":"transactionally repair safe drift with the executing bundle, then re-diagnose"},{"choices":[],"kind":"option","metavar":null,"names":["--no-install"],"repeatable":false,"required":false,"summary":"with --repair, update configuration without installing dependencies or hooks"}],"path":["doctor"],"summary":"diagnose adoption health and optionally repair safe drift","usage":"code-standards doctor [-h] [--format OUTPUT_FORMAT] [--repair] [--no-install]"},{"commands":[],"name":"setup","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["pre-commit","lefthook","none"],"kind":"option","metavar":"HOOKS","names":["--hooks"],"repeatable":false,"required":false,"summary":"hook manager (default: detect Lefthook, otherwise pre-commit)"},{"choices":[],"kind":"option","metavar":"PYTHON_DEST","names":["--python-dest"],"repeatable":false,"required":false,"summary":"the directory that owns pyproject.toml (default: detected)"},{"choices":[],"kind":"option","metavar":"TYPESCRIPT_DEST","names":["--typescript-dest"],"repeatable":false,"required":false,"summary":"the directory that owns the npm lockfile (default: detected)"},{"choices":[],"kind":"option","metavar":null,"names":["--dry-run"],"repeatable":false,"required":false,"summary":"print the complete plan without writing"},{"choices":[],"kind":"option","metavar":null,"names":["--force"],"repeatable":false,"required":false,"summary":"replace conflicting generated lint configuration after review"},{"choices":["standard","application"],"kind":"option","metavar":"PROFILE","names":["--profile"],"repeatable":false,"required":false,"summary":"policy profile to adopt (default: existing value, otherwise standard)"},{"choices":[],"kind":"option","metavar":null,"names":["--no-install"],"repeatable":false,"required":false,"summary":"write wiring without installing dependencies or hooks"},{"choices":["eslint","markdownlint","pyright","ruff","taplo","yamllint"],"kind":"option","metavar":"ONLY","names":["--config"],"repeatable":true,"required":false,"summary":"select one config explicitly (repeatable)"}],"path":["setup"],"summary":"adopt or converge the repository in one idempotent operation","usage":"code-standards setup [-h] [--hooks HOOKS] [--python-dest PYTHON_DEST] [--typescript-dest TYPESCRIPT_DEST] [--dry-run] [--force] [--profile PROFILE] [--no-install] [--config ONLY ...]"},{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--trust-repository-code"],"repeatable":false,"required":false,"summary":"allow executable repository ESLint configuration (generated hooks and CI set this explicitly)"},{"choices":[],"kind":"option","metavar":null,"names":["--staged"],"repeatable":false,"required":false,"summary":"run custom rules on hook-supplied paths, or discover staged files when none are supplied"},{"choices":["text","json","sarif","github"],"kind":"option","metavar":"OUTPUT_FORMAT","names":["--format"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":"write JSON or SARIF atomically to PATH"},{"choices":["0","1","2","3","4","5","6","7","8","9","10"],"kind":"option","metavar":"MAX_ANNOTATIONS_PER_LEVEL","names":["--max-annotations-per-level"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":"selected paths; when omitted, check the complete repository"}],"path":["check"],"summary":"run the complete quality gate or check selected paths","usage":"code-standards check [-h] [--trust-repository-code] [--staged] [--format OUTPUT_FORMAT] [--output OUTPUT] [--max-annotations-per-level MAX_ANNOTATIONS_PER_LEVEL] [files ...]"},{"commands":[],"name":"validate-slack-automations","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"PATH","names":["slack_catalog"],"repeatable":false,"required":true,"summary":""}],"path":["validate-slack-automations"],"summary":"validate a versioned Slack automation catalog","usage":"code-standards validate-slack-automations [-h] PATH"},{"commands":[],"name":"observe","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"SELECTED_RULES","names":["--rule"],"repeatable":true,"required":true,"summary":"canonical ENGINE:ID selector (repeatable)"},{"choices":["text","json","sarif","github"],"kind":"option","metavar":"OUTPUT_FORMAT","names":["--format"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":null,"names":["--trust-repository-code"],"repeatable":false,"required":false,"summary":"allow repository ESLint configuration to execute"},{"choices":[],"kind":"option","metavar":"MAX_ANNOTATIONS_PER_LEVEL","names":["--max-annotations-per-level"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":"selected paths; defaults to adopted verification paths"}],"path":["observe"],"summary":"report warning-stage findings with exit 0; invalid input or execution still exits 2","usage":"code-standards observe [-h] --rule SELECTED_RULES ... [--format OUTPUT_FORMAT] [--output OUTPUT] [--trust-repository-code] [--max-annotations-per-level MAX_ANNOTATIONS_PER_LEVEL] [files ...]"},{"commands":[],"name":"fix","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--staged"],"repeatable":false,"required":false,"summary":"fix only files staged in Git"},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":"selected paths; when omitted, fix the complete repository"}],"path":["fix"],"summary":"apply safe formatting and lint fixes","usage":"code-standards fix [-h] [--staged] [files ...]"},{"commands":[],"name":"update","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--check"],"repeatable":false,"required":false,"summary":"preview without writing; exit 1 when changes exist"},{"choices":[],"kind":"option","metavar":null,"names":["--offline"],"repeatable":false,"required":false,"summary":"reconverge the executing bundle and skip every network-dependent install; does not resolve latest"},{"choices":[],"kind":"option","metavar":"VERSION","names":["--to"],"repeatable":false,"required":false,"summary":"resolve and apply exactly this immutable coherent bundle version"},{"choices":[],"kind":"option","metavar":null,"names":["--no-install"],"repeatable":false,"required":false,"summary":"do not install dependencies or hooks"}],"path":["update"],"summary":"upgrade to the latest published coherent Standards bundle","usage":"code-standards update [-h] [--check] [--offline] [--to VERSION] [--no-install]"},{"commands":[{"commands":[],"name":"init","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":"baseline JSON (default: diagnostic-baseline.json)"},{"choices":[],"kind":"option","metavar":null,"names":["--trust-repository-code"],"repeatable":false,"required":false,"summary":"run repository-local analyzers that execute project code"},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":"paths to analyze (default: the whole repository)"}],"path":["baseline","init"],"summary":"record the first diagnostic baseline","usage":"code-standards baseline init [-h] [--output OUTPUT] [--trust-repository-code] [files ...]"},{"commands":[],"name":"update","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":"baseline JSON (default: diagnostic-baseline.json)"},{"choices":[],"kind":"option","metavar":null,"names":["--trust-repository-code"],"repeatable":false,"required":false,"summary":"run repository-local analyzers that execute project code"},{"choices":[],"kind":"option","metavar":"BASELINE_RULES","names":["--rule"],"repeatable":true,"required":false,"summary":"replace debt only for this newly promoted rule (repeatable; source:RULE is also accepted)"},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":"paths to analyze (default: the whole repository)"}],"path":["baseline","update"],"summary":"re-record the diagnostic baseline after reviewed cleanup","usage":"code-standards baseline update [-h] [--output OUTPUT] [--trust-repository-code] [--rule BASELINE_RULES ...] [files ...]"}],"name":"baseline","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["baseline"],"summary":"grandfather today's findings so only new ones fail","usage":"code-standards baseline [-h] {init,update}"},{"commands":[{"commands":[],"name":"init","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BASELINE","names":["--baseline"],"repeatable":false,"required":false,"summary":"budget JSON (default: suppression-baseline.json)"},{"choices":[],"kind":"option","metavar":"PACKAGE","names":["--package"],"repeatable":true,"required":false,"summary":"Python package root (repeatable)"},{"choices":[],"kind":"option","metavar":"EXCLUDE_SUBTREE","names":["--exclude-subtree"],"repeatable":true,"required":false,"summary":"generated or vendored subtree to persistently exclude (repeatable)"}],"path":["ratchet","init"],"summary":"create the first suppression budget","usage":"code-standards ratchet init [-h] [--baseline BASELINE] [--package PACKAGE ...] [--exclude-subtree EXCLUDE_SUBTREE ...]"},{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BASELINE","names":["--baseline"],"repeatable":false,"required":false,"summary":"budget JSON (default: suppression-baseline.json)"},{"choices":[],"kind":"option","metavar":"PACKAGE","names":["--package"],"repeatable":true,"required":false,"summary":"Python package root (repeatable)"},{"choices":[],"kind":"option","metavar":"EXCLUDE_SUBTREE","names":["--exclude-subtree"],"repeatable":true,"required":false,"summary":"generated or vendored subtree to persistently exclude (repeatable)"}],"path":["ratchet","check"],"summary":"fail when suppression debt grows","usage":"code-standards ratchet check [-h] [--baseline BASELINE] [--package PACKAGE ...] [--exclude-subtree EXCLUDE_SUBTREE ...]"},{"commands":[],"name":"status","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BASELINE","names":["--baseline"],"repeatable":false,"required":false,"summary":"budget JSON (default: suppression-baseline.json)"},{"choices":[],"kind":"option","metavar":"PACKAGE","names":["--package"],"repeatable":true,"required":false,"summary":"Python package root (repeatable)"},{"choices":[],"kind":"option","metavar":"EXCLUDE_SUBTREE","names":["--exclude-subtree"],"repeatable":true,"required":false,"summary":"generated or vendored subtree to persistently exclude (repeatable)"}],"path":["ratchet","status"],"summary":"show current suppression debt and available reductions","usage":"code-standards ratchet status [-h] [--baseline BASELINE] [--package PACKAGE ...] [--exclude-subtree EXCLUDE_SUBTREE ...]"},{"commands":[],"name":"update","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BASELINE","names":["--baseline"],"repeatable":false,"required":false,"summary":"budget JSON (default: suppression-baseline.json)"},{"choices":[],"kind":"option","metavar":"PACKAGE","names":["--package"],"repeatable":true,"required":false,"summary":"Python package root (repeatable)"},{"choices":[],"kind":"option","metavar":"EXCLUDE_SUBTREE","names":["--exclude-subtree"],"repeatable":true,"required":false,"summary":"generated or vendored subtree to persistently exclude (repeatable)"},{"choices":[],"kind":"option","metavar":null,"names":["--allow-increase"],"repeatable":false,"required":false,"summary":"permit a reviewed increase in suppression debt"}],"path":["ratchet","update"],"summary":"lock in reviewed suppression-budget changes","usage":"code-standards ratchet update [-h] [--baseline BASELINE] [--package PACKAGE ...] [--exclude-subtree EXCLUDE_SUBTREE ...] [--allow-increase]"}],"name":"ratchet","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["ratchet"],"summary":"keep the Python suppression budget from growing","usage":"code-standards ratchet [-h] {init,check,status,update}"},{"commands":[{"commands":[],"name":"list","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["exclude","list"],"summary":"list the complete denylist","usage":"code-standards exclude list [-h]"},{"commands":[],"name":"add","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["path","rule"],"kind":"positional","metavar":"{path,rule}","names":["exclude_kind"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"positional","metavar":"value","names":["value"],"repeatable":false,"required":true,"summary":"repository-relative glob or canonical engine:rule selector"}],"path":["exclude","add"],"summary":"add one exact denylist entry","usage":"code-standards exclude add [-h] {path,rule} value"},{"commands":[],"name":"remove","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["path","rule"],"kind":"positional","metavar":"{path,rule}","names":["exclude_kind"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"positional","metavar":"value","names":["value"],"repeatable":false,"required":true,"summary":"repository-relative glob or canonical engine:rule selector"}],"path":["exclude","remove"],"summary":"remove one exact denylist entry","usage":"code-standards exclude remove [-h] {path,rule} value"}],"name":"exclude","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["exclude"],"summary":"inspect or change explicit path and rule exclusions","usage":"code-standards exclude [-h] {list,add,remove}"},{"commands":[{"commands":[],"name":"state","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["show","state"],"summary":"print detected adoption state as JSON","usage":"code-standards show state [-h]"},{"commands":[],"name":"configs","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["show","configs"],"summary":"list bundled configurations","usage":"code-standards show configs [-h]"},{"commands":[],"name":"config","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["eslint","markdownlint","pyright","ruff","taplo","yamllint"],"kind":"positional","metavar":"name","names":["name"],"repeatable":false,"required":true,"summary":""},{"choices":["standard","application"],"kind":"option","metavar":"PROFILE","names":["--profile"],"repeatable":false,"required":false,"summary":""}],"path":["show","config"],"summary":"print one bundled configuration path","usage":"code-standards show config [-h] name [--profile PROFILE]"},{"commands":[],"name":"peers","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["show","peers"],"summary":"show tested ESLint peer dependencies and install command","usage":"code-standards show peers [-h]"},{"commands":[],"name":"rules","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["show","rules"],"summary":"print the machine-readable custom-rule inventory","usage":"code-standards show rules [-h]"},{"commands":[],"name":"ci","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":"write a managed workflow inside the repository"}],"path":["show","ci"],"summary":"print a complete pinned GitHub Actions standards workflow","usage":"code-standards show ci [-h] [--output OUTPUT]"}],"name":"show","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["show"],"summary":"print read-only package and adoption information","usage":"code-standards show [-h] {state,configs,config,peers,rules,ci}"},{"commands":[{"commands":[],"name":"setup","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--check"],"repeatable":false,"required":false,"summary":"print the deterministic setup plan without executing it"}],"path":["maintain","setup"],"summary":"install every standards development environment and repository hook","usage":"code-standards maintain setup [-h] [--check]"},{"commands":[{"commands":[],"name":"check-tag","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"tag","names":["tag"],"repeatable":false,"required":true,"summary":""}],"path":["maintain","release","check-tag"],"summary":"require a release tag to match its package manifest","usage":"code-standards maintain release check-tag [-h] tag"},{"commands":[],"name":"verify-tags","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"RELEASE_COMMIT","names":["--commit"],"repeatable":false,"required":false,"summary":"also require existing tags to match this publishing commit or an unchanged package tree"}],"path":["maintain","release","verify-tags"],"summary":"verify all manifest release tags on origin","usage":"code-standards maintain release verify-tags [-h] [--commit RELEASE_COMMIT]"},{"commands":[],"name":"create-tags","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["typescript","bootstrap","python","sql","iac","standards","tsconfig","docs-ui"],"kind":"positional","metavar":"release_targets","names":["release_targets"],"repeatable":true,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"RELEASE_COMMIT","names":["--commit"],"repeatable":false,"required":true,"summary":"exact commit that was published"},{"choices":[],"kind":"option","metavar":"ATTEMPTS","names":["--attempts"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"DELAY_SECONDS","names":["--delay-seconds"],"repeatable":false,"required":false,"summary":""}],"path":["maintain","release","create-tags"],"summary":"create and push manifest release tags","usage":"code-standards maintain release create-tags [-h] release_targets ... --commit RELEASE_COMMIT [--attempts ATTEMPTS] [--delay-seconds DELAY_SECONDS]"},{"commands":[],"name":"changes","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BEFORE","names":["--before"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"AFTER","names":["--after"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"GITHUB_OUTPUT","names":["--github-output"],"repeatable":false,"required":true,"summary":""}],"path":["maintain","release","changes"],"summary":"emit package version changes between Git revisions","usage":"code-standards maintain release changes [-h] --before BEFORE --after AFTER --github-output GITHUB_OUTPUT"},{"commands":[],"name":"causality","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BEFORE","names":["--before"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"AFTER","names":["--after"],"repeatable":false,"required":true,"summary":""}],"path":["maintain","release","causality"],"summary":"require every publishable package change to bump its version","usage":"code-standards maintain release causality [-h] --before BEFORE --after AFTER"},{"commands":[],"name":"lock-age","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"lockfile","names":["lockfile"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"MINIMUM_AGE","names":["--minimum-days"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"RELEASE_EXCLUDE","names":["--exclude"],"repeatable":true,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"RELEASE_EXCLUDE_FILE","names":["--exclude-file"],"repeatable":true,"required":false,"summary":"line-oriented exact package@version exceptions (repeatable)"}],"path":["maintain","release","lock-age"],"summary":"enforce npm lockfile minimum release age","usage":"code-standards maintain release lock-age [-h] lockfile [--minimum-days MINIMUM_AGE] [--exclude RELEASE_EXCLUDE ...] [--exclude-file RELEASE_EXCLUDE_FILE ...]"},{"commands":[],"name":"typescript","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["check","pack","publish"],"kind":"positional","metavar":"release_mode","names":["release_mode"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":"artifact directory (required for pack)"}],"path":["maintain","release","typescript"],"summary":"check, pack, or publish the TypeScript package","usage":"code-standards maintain release typescript [-h] release_mode [--output OUTPUT]"},{"commands":[],"name":"verify-wheel","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"wheels","names":["wheels"],"repeatable":true,"required":true,"summary":""}],"path":["maintain","release","verify-wheel"],"summary":"require non-empty license text in built Python wheels","usage":"code-standards maintain release verify-wheel [-h] wheels ..."},{"commands":[],"name":"verify-publications","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"ATTEMPTS","names":["--attempts"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"DELAY_SECONDS","names":["--delay-seconds"],"repeatable":false,"required":false,"summary":""}],"path":["maintain","release","verify-publications"],"summary":"wait for every exact sibling publication required by Standards","usage":"code-standards maintain release verify-publications [-h] [--attempts ATTEMPTS] [--delay-seconds DELAY_SECONDS]"},{"commands":[],"name":"publish","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["typescript","bootstrap","python","sql","iac","standards","tsconfig","docs-ui"],"kind":"positional","metavar":"release_target","names":["release_target"],"repeatable":false,"required":true,"summary":""}],"path":["maintain","release","publish"],"summary":"build and publish one package through its native client","usage":"code-standards maintain release publish [-h] release_target"}],"name":"release","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","release"],"summary":"validate and build publishable release artifacts","usage":"code-standards maintain release [-h] {check-tag,verify-tags,create-tags,changes,causality,lock-age,typescript,verify-wheel,verify-publications,publish}"},{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["ci-history","file-conventions","private-refs","versions"],"kind":"option","metavar":"REPO_ONLY","names":["--only"],"repeatable":true,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"COMMITS","names":["--commits"],"repeatable":false,"required":false,"summary":"also inspect commit messages in this revision range"},{"choices":[],"kind":"option","metavar":"POLICY_DEST","names":["--policy-root"],"repeatable":false,"required":false,"summary":"trusted repository policy root (default: --root)"},{"choices":[],"kind":"option","metavar":"PRIVATE_REFS_FILE","names":["--private-refs-file"],"repeatable":false,"required":false,"summary":"private-reference TOML outside the scanned repository"},{"choices":[],"kind":"option","metavar":null,"names":["--quiet"],"repeatable":false,"required":false,"summary":"hide finding details"}],"path":["maintain","check"],"summary":"run repository policy gates","usage":"code-standards maintain check [-h] [--only REPO_ONLY ...] [--commits COMMITS] [--policy-root POLICY_DEST] [--private-refs-file PRIVATE_REFS_FILE] [--quiet]"},{"commands":[],"name":"sync-ledger","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--check"],"repeatable":false,"required":false,"summary":"report drift without writing"}],"path":["maintain","sync-ledger"],"summary":"synchronize the rule compatibility ledger","usage":"code-standards maintain sync-ledger [-h] [--check]"},{"commands":[{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","docs","check"],"summary":"","usage":"code-standards maintain docs check [-h]"},{"commands":[],"name":"sync","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","docs","sync"],"summary":"","usage":"code-standards maintain docs sync [-h]"}],"name":"docs","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","docs"],"summary":"check or synchronize source-derived documentation","usage":"code-standards maintain docs [-h] {check,sync}"},{"commands":[],"name":"comment-corpus","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"roots","names":["roots"],"repeatable":true,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"PRIVATE_JSONL","names":["--include-text"],"repeatable":false,"required":false,"summary":"write sensitive comment text to a new owner-readable file"}],"path":["maintain","comment-corpus"],"summary":"extract comments for calibration","usage":"code-standards maintain comment-corpus [-h] roots ... [--include-text PRIVATE_JSONL]"},{"commands":[{"commands":[],"name":"install","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","hooks","install"],"summary":"install Lefthook","usage":"code-standards maintain hooks install [-h]"}],"name":"hooks","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","hooks"],"summary":"manage the pinned repository hooks","usage":"code-standards maintain hooks [-h] {install}"},{"commands":[{"commands":[],"name":"manifest","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","rules","manifest"],"summary":"print the shipped rule inventory","usage":"code-standards maintain rules manifest [-h]"},{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","rules","check"],"summary":"verify the shipped rule inventory matches live registries","usage":"code-standards maintain rules check [-h]"},{"commands":[],"name":"sync","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","rules","sync"],"summary":"update the shipped rule inventory from live registries","usage":"code-standards maintain rules sync [-h]"},{"commands":[],"name":"new","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"selector","names":["selector"],"repeatable":false,"required":true,"summary":"canonical ENGINE:ID selector"},{"choices":["architecture","correctness","maintainability","performance","security","style","testing"],"kind":"option","metavar":"RULE_CATEGORY","names":["--category"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"RULE_SUMMARY","names":["--summary"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":null,"names":["--apply"],"repeatable":false,"required":false,"summary":"create the planned files"}],"path":["maintain","rules","new"],"summary":"plan or create author-owned rule and test skeletons","usage":"code-standards maintain rules new [-h] selector --category RULE_CATEGORY --summary RULE_SUMMARY [--apply]"},{"commands":[],"name":"stage-warning","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"selector","names":["selector"],"repeatable":false,"required":true,"summary":"canonical ENGINE:ID selector"},{"choices":[],"kind":"option","metavar":null,"names":["--check"],"repeatable":false,"required":false,"summary":"report required staging without writing"}],"path":["maintain","rules","stage-warning"],"summary":"prepare one registered rule for warning-first publication","usage":"code-standards maintain rules stage-warning [-h] selector [--check]"},{"commands":[],"name":"prepare","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"selector","names":["selector"],"repeatable":false,"required":true,"summary":"canonical ENGINE:ID selector"},{"choices":[],"kind":"option","metavar":null,"names":["--check"],"repeatable":false,"required":false,"summary":"report required preparation without writing"}],"path":["maintain","rules","prepare"],"summary":"validate and prepare one registered rule for warning-first publication","usage":"code-standards maintain rules prepare [-h] selector [--check]"},{"commands":[],"name":"verify","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"selector","names":["selector"],"repeatable":false,"required":true,"summary":"canonical ENGINE:ID selector"}],"path":["maintain","rules","verify"],"summary":"validate one registered rule's authored files and public examples","usage":"code-standards maintain rules verify [-h] selector"},{"commands":[],"name":"changes","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BEFORE","names":["--before"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"AFTER","names":["--after"],"repeatable":false,"required":true,"summary":""},{"choices":["json","text"],"kind":"option","metavar":"OUTPUT_FORMAT","names":["--format"],"repeatable":false,"required":false,"summary":""}],"path":["maintain","rules","changes"],"summary":"compare rule inventory and policy between two Git revisions","usage":"code-standards maintain rules changes [-h] --before BEFORE --after AFTER [--format OUTPUT_FORMAT]"},{"commands":[],"name":"evaluate","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"SELECTED_RULES","names":["--rule"],"repeatable":true,"required":true,"summary":"canonical ENGINE:ID selector (repeatable)"},{"choices":["corpus","effective"],"kind":"option","metavar":"EVALUATION_SCOPE","names":["--scope"],"repeatable":false,"required":false,"summary":"corpus ignores baselines/rule exclusions; effective applies adopted repository policy"},{"choices":["json","text"],"kind":"option","metavar":"OUTPUT_FORMAT","names":["--format"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":null,"names":["--trust-repository-code"],"repeatable":false,"required":false,"summary":"allow executable repository ESLint configuration"},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":""}],"path":["maintain","rules","evaluate"],"summary":"calibrate selected custom rules; findings exit 1 and invalid input or execution exits 2","usage":"code-standards maintain rules evaluate [-h] --rule SELECTED_RULES ... [--scope EVALUATION_SCOPE] [--format OUTPUT_FORMAT] [--output OUTPUT] [--trust-repository-code] [files ...]"}],"name":"rules","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","rules"],"summary":"inspect live custom rules","usage":"code-standards maintain rules [-h] {manifest,check,sync,new,stage-warning,prepare,verify,changes,evaluate}"},{"commands":[{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","catalog","check"],"summary":"verify the public catalog matches every live rule","usage":"code-standards maintain catalog check [-h]"},{"commands":[],"name":"sync","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","catalog","sync"],"summary":"update the public catalog from source-owned rule metadata","usage":"code-standards maintain catalog sync [-h]"}],"name":"catalog","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","catalog"],"summary":"maintain the source-derived public rule catalog","usage":"code-standards maintain catalog [-h] {check,sync}"},{"commands":[{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","cli-reference","check"],"summary":"verify the shipped reference matches the parser graph","usage":"code-standards maintain cli-reference check [-h]"},{"commands":[],"name":"sync","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","cli-reference","sync"],"summary":"update the shipped reference from the parser graph","usage":"code-standards maintain cli-reference sync [-h]"}],"name":"cli-reference","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","cli-reference"],"summary":"maintain the source-derived CLI reference","usage":"code-standards maintain cli-reference [-h] {check,sync}"}],"name":"maintain","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain"],"summary":"repository policy, hooks, rule ledgers, and releases","usage":"code-standards maintain [-h] {setup,release,check,sync-ledger,docs,comment-corpus,hooks,rules,catalog,cli-reference}"}],"epilog":"Start with `code-standards setup`, then use `code-standards check`.","globalOptions":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--version"],"repeatable":false,"required":false,"summary":"show program's version number and exit"},{"choices":[],"kind":"option","metavar":"DEST","names":["--root"],"repeatable":false,"required":false,"summary":"repository root shared by the selected command (default: current directory)"}],"launcher":{"install":"uv tool install --python 3.14 code-standards","runLatest":"uvx --no-config --isolated --python 3.14 --from code-standards code-standards"},"program":"code-standards","schemaVersion":1,"summary":"Adopt, check, fix, diagnose, and update sarj-ai standards (v7.1.0).","version":"7.1.0"}
|
{code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/eslint.application.mjs
RENAMED
|
@@ -282,7 +282,9 @@ const UNICORN_MODERNISATION_RULES = {
|
|
|
282
282
|
"unicorn/prefer-import-meta-properties": "error",
|
|
283
283
|
"unicorn/prefer-iterable-in-constructor": "error",
|
|
284
284
|
"unicorn/prefer-iterator-concat": "error",
|
|
285
|
+
"unicorn/prefer-iterator-helpers": "error",
|
|
285
286
|
"unicorn/prefer-iterator-to-array": "error",
|
|
287
|
+
"unicorn/prefer-iterator-to-array-at-end": "error",
|
|
286
288
|
"unicorn/prefer-map-from-entries": "error",
|
|
287
289
|
"unicorn/prefer-math-abs": "error",
|
|
288
290
|
"unicorn/prefer-math-constants": "error",
|
|
@@ -747,6 +749,8 @@ export function createConfig(options = {}) {
|
|
|
747
749
|
// schema changes. Requiring an identical shape keeps the diagnostic tied
|
|
748
750
|
// to structural evidence instead of name correlation.
|
|
749
751
|
"@sarj/prefer-zod-infer": "error",
|
|
752
|
+
"@sarj/interface-contract-members-private": "error",
|
|
753
|
+
"@sarj/prefer-ecmascript-private-members": "error",
|
|
750
754
|
|
|
751
755
|
// Maintained upstream rules own these concerns instead of local copies.
|
|
752
756
|
// `.nullable().optional()` is exactly `.nullish()`, so prefer-nullish
|
|
@@ -943,12 +947,12 @@ export function createConfig(options = {}) {
|
|
|
943
947
|
"@sarj/no-raw-env": "error",
|
|
944
948
|
"@sarj/no-sentinel-return-on-catch": "error",
|
|
945
949
|
"@sarj/no-log-only-catch": "error",
|
|
946
|
-
"@sarj/no-bare-return-from-test-catch": "
|
|
947
|
-
"@sarj/no-dangerously-allow-svg": "
|
|
948
|
-
"@sarj/no-duplicate-lifecycle-refresh-listeners": "
|
|
949
|
-
"@sarj/no-production-browser-source-maps": "
|
|
950
|
-
"@sarj/no-router-refresh-polling": "
|
|
951
|
-
"@sarj/no-server-env-in-client-component": "
|
|
950
|
+
"@sarj/no-bare-return-from-test-catch": "error",
|
|
951
|
+
"@sarj/no-dangerously-allow-svg": "error",
|
|
952
|
+
"@sarj/no-duplicate-lifecycle-refresh-listeners": "error",
|
|
953
|
+
"@sarj/no-production-browser-source-maps": "error",
|
|
954
|
+
"@sarj/no-router-refresh-polling": "error",
|
|
955
|
+
"@sarj/no-server-env-in-client-component": "error",
|
|
952
956
|
"@sarj/no-long-comment": "error",
|
|
953
957
|
"@sarj/no-vague-suppression-description": "error",
|
|
954
958
|
"@sarj/no-generic-single-export-module": "error",
|
|
@@ -984,11 +988,11 @@ export function createConfig(options = {}) {
|
|
|
984
988
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
985
989
|
"@sarj/prefer-await-in-async-return": "error",
|
|
986
990
|
"@sarj/no-sleep-in-test-body": "error",
|
|
987
|
-
"@sarj/iac-source-coupled-test": "
|
|
988
|
-
"@sarj/repeated-static-call-cases": "
|
|
989
|
-
"@sarj/require-use-form-default-values": "
|
|
990
|
-
"@sarj/require-use-server-in-actions-file": "
|
|
991
|
-
"@sarj/source-coupled-test": "
|
|
991
|
+
"@sarj/iac-source-coupled-test": "error",
|
|
992
|
+
"@sarj/repeated-static-call-cases": "error",
|
|
993
|
+
"@sarj/require-use-form-default-values": "error",
|
|
994
|
+
"@sarj/require-use-server-in-actions-file": "error",
|
|
995
|
+
"@sarj/source-coupled-test": "error",
|
|
992
996
|
"@sarj/no-positional-tuple-return": "error",
|
|
993
997
|
"@sarj/no-restated-comment": "error",
|
|
994
998
|
"@sarj/no-restated-jsdoc": "error",
|
|
@@ -1004,7 +1008,7 @@ export function createConfig(options = {}) {
|
|
|
1004
1008
|
"@sarj/prefer-whole-object-assertion": "error",
|
|
1005
1009
|
"@sarj/duplicate-test-body": "error",
|
|
1006
1010
|
"@sarj/test-loops-over-literal-cases": "error",
|
|
1007
|
-
"@sarj/test-phase-label-comment": "
|
|
1011
|
+
"@sarj/test-phase-label-comment": "error",
|
|
1008
1012
|
// Both architectural rules stay enabled in the shared baseline. The
|
|
1009
1013
|
// fetch rule ships conservative client/service defaults; consumers can
|
|
1010
1014
|
// replace its `allow` list. The storage rule is intentionally inert until
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"peers": {
|
|
19
19
|
"@eslint-community/eslint-plugin-eslint-comments": "4.7.2",
|
|
20
20
|
"@eslint/compat": "2.1.0",
|
|
21
|
-
"@sarj/eslint-plugin": "15.
|
|
21
|
+
"@sarj/eslint-plugin": "15.13.0",
|
|
22
22
|
"eslint": "10.8.1",
|
|
23
23
|
"eslint-plugin-better-tailwindcss": "4.7.0",
|
|
24
24
|
"eslint-plugin-perfectionist": "5.10.1",
|