---
{
  "n": 20,
  "title": "Code Commandments",
  "abstract": "The static code checker judges the codebase, its hooks run inside the journal, and every rule and language is a switch in its settings",
  "refs": [],
  "seen": [
    "user",
    "plugin",
    "agent",
    "system"
  ],
  "data": {
    "enabled": true,
    "settings": {
      "ports": {},
      "chosen": {
        "folders_judged": "src",
        "folders_skipped": ".venv\n__pycache__\nsrc/web/dist\nsrc/web/dist-demo\n.claude/worktrees",
        "language_php": "false",
        "language_vue": "true",
        "language_ts": "false",
        "language_py": "true",
        "language_cs": "false"
      }
    },
    "token": "511138bbbe3a99b10c0672a6eb9fa006",
    "source": "https://github.com/jessegall/code-commandments",
    "revision": "",
    "commit": "d97ee3e06ce68cfd52cb819f022d5e77df388da1",
    "version": "1.64.15",
    "linked": false,
    "manifest": {
      "name": "code-commandments",
      "version": "1.64.15",
      "title": "Code Commandments",
      "description": "The static code checker judges the codebase, its hooks run inside the journal, and every rule and language is a switch in its settings",
      "journal": "2.267.16",
      "requires": {
        "curl": {
          "check": "curl --version",
          "hint": "curl fetches the checker's release binary into the plugin's own folder"
        },
        "sha256sum": {
          "check": "command -v sha256sum || command -v shasum",
          "hint": "sha256sum or shasum checks the fetched binary against its release's SHA256SUMS"
        }
      },
      "env": {
        "CLAUDE_PROJECT_DIR": "{project}",
        "COMMANDMENTS_RELEASE": "v5.18.15"
      },
      "setup": [
        {
          "name": "Fetch the checker's release binary, checked against its SHA256SUMS",
          "run": "sh .journal-plugin/fetch"
        },
        {
          "name": "Write the chosen switches into config.json",
          "run": "bin/commandments-release journal-config --keep-folders"
        },
        {
          "name": "Check for sins, on demand",
          "run": "journal check create \"Check for sins\" --set command=\".journal/plugins/code-commandments/bin/commandments-release judge\" --set every=0 --set failure=\"Code Commandments found {summary}\""
        }
      ],
      "services": {
        "hooks": {
          "run": "bin/commandments-release journal-serve",
          "restart": "always",
          "when": ""
        },
        "roslyn": {
          "run": "bin/commandments-release roslyn-serve",
          "when": "\"$JOURNAL_PLUGIN_DIR/bin/commandments-release\" has-csharp",
          "restart": "always"
        },
        "mypy": {
          "run": "bin/commandments-release mypy-serve",
          "when": "\"$JOURNAL_PLUGIN_DIR/bin/commandments-release\" has-python",
          "restart": "always"
        }
      },
      "on": {
        "hook.PostToolUse": {
          "run": "bin/commandments-release journal-hook"
        },
        "hook.Stop": {
          "run": "bin/commandments-release journal-hook"
        },
        "hook.SessionStart": {
          "run": "bin/commandments-release journal-hook"
        },
        "hook.SubagentStart": {
          "run": "bin/commandments-release journal-hook"
        },
        "plugin.updated": {
          "run": "bin/commandments-release journal-config"
        }
      },
      "refuse": "bin/commandments-release journal-hook",
      "reads": true,
      "refuse_seconds": 20,
      "refuse_socket": "hooks",
      "dashboards": [
        {
          "name": "sins",
          "title": "Sins"
        }
      ],
      "settings": {
        "folders_judged": {
          "title": "Folders to check",
          "help": "One folder per line, from the project root. Empty, the config keeps the folders it names.",
          "type": "list",
          "default": "",
          "group": "Folders",
          "when": []
        },
        "folders_skipped": {
          "title": "Folders to leave out",
          "help": "One folder per line, never read or reported, such as generated code. This list is what the config leaves out.",
          "type": "list",
          "default": "",
          "group": "Folders",
          "when": []
        },
        "judge_parallel": {
          "title": "Rules judged at once",
          "help": "How many detectors the check runs side by side. More finish sooner but use more cores and memory.",
          "type": "number",
          "default": "2",
          "group": "Performance",
          "when": []
        },
        "language_php": {
          "title": "PHP",
          "help": "Enables PHP sin detection",
          "type": "flag",
          "default": "true",
          "group": "Languages",
          "when": []
        },
        "language_vue": {
          "title": "Vue",
          "help": "Enables Vue sin detection",
          "type": "flag",
          "default": "true",
          "group": "Languages",
          "when": []
        },
        "language_ts": {
          "title": "TypeScript",
          "help": "Enables TypeScript sin detection",
          "type": "flag",
          "default": "true",
          "group": "Languages",
          "when": []
        },
        "language_py": {
          "title": "Python",
          "help": "Enables Python sin detection",
          "type": "flag",
          "default": "true",
          "group": "Languages",
          "when": []
        },
        "language_cs": {
          "title": "C#",
          "help": "Enables C# sin detection",
          "type": "flag",
          "default": "true",
          "group": "Languages",
          "when": []
        },
        "sin_blank-string-default": {
          "title": "BlankStringDefault",
          "help": "`string $x = ''` standing in for absence \u2014 then asked `$x === ''`",
          "type": "flag",
          "default": "true",
          "group": "backend/absence",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_blank-string-on-the-wire": {
          "title": "BlankStringOnTheWire",
          "help": "A `string` field sent over the wire whose TypeScript reader has to check `=== ''` to mean \"missing\" \u2014 only that reader knows the blank stands for absence.",
          "type": "flag",
          "default": "true",
          "group": "backend/absence",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_cancelled-coalesce": {
          "title": "CancelledCoalesce",
          "help": "`??` cancelled by the comparison it sits in \u2014 `($x ?? '') !== ''`",
          "type": "flag",
          "default": "true",
          "group": "backend/absence",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_conditional-array-spread": {
          "title": "ConditionalArraySpread",
          "help": "An array built by spreading a conditional element \u2014 `...($x ? ['k' => $x] : [])` or `array_merge($base, $cond ? [...] : [])` \u2014 a ternary-and-empty-array trick that really just means \"include this when the value is present.\"",
          "type": "flag",
          "default": "true",
          "group": "backend/absence",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_de-nulled-finder": {
          "title": "DeNulledFinder",
          "help": "A finder that returns `null` for both \"missing\" and \"broken\" instead of throwing \u2014 the kind of `?T` finder whose callers all end up de-nulling it.",
          "type": "flag",
          "default": "true",
          "group": "backend/absence",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_erased-null-object": {
          "title": "ErasedNullObject",
          "help": "A blank-rendering Null Object written into a `string` slot \u2014 coerced back to `''`",
          "type": "flag",
          "default": "true",
          "group": "backend/absence",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_nullable-callback": {
          "title": "NullableCallback",
          "help": "Nullable callback normalised in the body instead of a Null Object default",
          "type": "flag",
          "default": "true",
          "group": "backend/absence",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_option-as-nullable": {
          "title": "OptionAsNullable",
          "help": "`Option<T>` used as if it were nullable \u2014 `?Option`, `Option | null`, `unwrapOr(null)`",
          "type": "flag",
          "default": "true",
          "group": "backend/absence",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_flag-argument": {
          "title": "FlagArgument",
          "help": "a method whose whole body branches on a `bool` parameter \u2014 or on whether a nullable one was given \u2014 two methods sharing one name",
          "type": "flag",
          "default": "true",
          "group": "backend/behaviour-per-method",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_member-after-method": {
          "title": "MemberAfterMethod",
          "help": "A trait use, constant, property, property hook, or enum case declared below a method \u2014 so the reader only meets that state after seeing the behaviour that uses it.",
          "type": "flag",
          "default": "true",
          "group": "backend/class-layout",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_member-out-of-order": {
          "title": "MemberOutOfOrder",
          "help": "A declaration in the head of a class that arrives after something belonging below it \u2014 a constant under a property, a public field under a private one, a hook above the fields it reads",
          "type": "flag",
          "default": "true",
          "group": "backend/class-layout",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_concurrent-subclass": {
          "title": "ConcurrentSubclass",
          "help": "Class `extends Concurrent` instead of composing `Concurrent<self>`",
          "type": "flag",
          "default": "true",
          "group": "backend/concurrent-state",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_namespace-cycle": {
          "title": "NamespaceCycle",
          "help": "two namespaces that reference each other \u2014 neither can be read, tested or moved alone",
          "type": "flag",
          "default": "true",
          "group": "backend/dependency-direction",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_namespace-dependency": {
          "title": "NamespaceDependency",
          "help": "a declared layer references a layer it may not use (the arrow points back up)",
          "type": "flag",
          "default": "true",
          "group": "backend/dependency-direction",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_archaeology-comment": {
          "title": "ArchaeologyComment",
          "help": "History/archaeology comments (\"formerly / used to be / refactored / no longer an X / was extracted\")",
          "type": "flag",
          "default": "true",
          "group": "backend/documentation",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_bloated-docblock": {
          "title": "BloatedDocblock",
          "help": "Multi-paragraph class docblock (class too big)",
          "type": "flag",
          "default": "true",
          "group": "backend/documentation",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_ceremony-docblock": {
          "title": "CeremonyDocblock",
          "help": "Docblock that only restates the typed signature (`@param Type $x`, no description)",
          "type": "flag",
          "default": "true",
          "group": "backend/documentation",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_dangling-doc-reference": {
          "title": "DanglingDocReference",
          "help": "A docblock `{@see}`/`{@link}` cross-references a FIRST-PARTY class that does not exist in the codebase \u2014 documentation pointing at a name that was renamed or removed, never at what the code actually is",
          "type": "flag",
          "default": "true",
          "group": "backend/documentation",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_inline-docblock": {
          "title": "InlineDocblock",
          "help": "A docblock whose delimiter shares a line with its text \u2014 a one-liner, or a block that opens or closes next to content",
          "type": "flag",
          "default": "true",
          "group": "backend/documentation",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_negative-space-comment": {
          "title": "NegativeSpaceComment",
          "help": "A comment defending the code against a strawman (\"not random\", \"no magic\", \"not a coincidence\", \"not dead code\")",
          "type": "flag",
          "default": "true",
          "group": "backend/documentation",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_restated-comment": {
          "title": "RestatedComment",
          "help": "An inline comment that only spells the statement below it back in prose (\"// save the order\" over `$this->orders->save($order)`)",
          "type": "flag",
          "default": "true",
          "group": "backend/documentation",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_stacked-docblock": {
          "title": "StackedDocblock",
          "help": "Two or more docblocks stacked on one declaration \u2014 PHP reads only the last, so the ones above it are documentation nobody sees",
          "type": "flag",
          "default": "true",
          "group": "backend/documentation",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_const-class-enum": {
          "title": "ConstClassEnum",
          "help": "A class of 2+ scalar `const`s and nothing else \u2014 a closed set hand-rolled as constants instead of a native enum",
          "type": "flag",
          "default": "true",
          "group": "backend/enums-with-behaviour",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_enum-case-or-chain": {
          "title": "EnumCaseOrChain",
          "help": "`$x === Enum::A || $x === Enum::B` \u2014 a hand-rolled case-group test",
          "type": "flag",
          "default": "true",
          "group": "backend/enums-with-behaviour",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_enum-value-match": {
          "title": "EnumValueMatch",
          "help": "A `match`/`switch` over an enum's `->value` at the call site \u2014 logic that belongs on the enum but lives elsewhere instead.",
          "type": "flag",
          "default": "true",
          "group": "backend/enums-with-behaviour",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_in-array-mirrors-enum": {
          "title": "InArrayMirrorsEnum",
          "help": "`in_array($x, [literals])` whose literals mirror an existing enum's cases",
          "type": "flag",
          "default": "true",
          "group": "backend/enums-with-behaviour",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_match-default-returns-null": {
          "title": "MatchDefaultReturnsNull",
          "help": "`match` `default` that returns `null`/`false`/`[]` (or has no body) instead of throwing",
          "type": "flag",
          "default": "true",
          "group": "backend/enums-with-behaviour",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_string-match-mirrors-enum": {
          "title": "StringMatchMirrorsEnum",
          "help": "`match`/`switch` over string/int literals that mirror an existing backed enum's case values",
          "type": "flag",
          "default": "true",
          "group": "backend/enums-with-behaviour",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_unnamed-vocabulary-literal": {
          "title": "UnnamedVocabularyLiteral",
          "help": "A raw string in an argument the codebase elsewhere fills from a named vocabulary \u2014 `expect('{')` beside `expect(Token::COLON)`, where `Token::BRACE_OPEN` already names it",
          "type": "flag",
          "default": "true",
          "group": "backend/enums-with-behaviour",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_generic-exception": {
          "title": "GenericException",
          "help": "`throw new <bare SPL>` (RuntimeException/LogicException/\u2026) instead of a named type",
          "type": "flag",
          "default": "true",
          "group": "backend/exceptions",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_message-at-throw": {
          "title": "MessageAtThrow",
          "help": "Message string built at the throw site (no domain values / named factory)",
          "type": "flag",
          "default": "true",
          "group": "backend/exceptions",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_swallow-catch": {
          "title": "SwallowCatch",
          "help": "`catch` whose only effect is `return null/false/[]`; empty catch (silent swallow)",
          "type": "flag",
          "default": "true",
          "group": "backend/exceptions",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_wrapping-without-cause": {
          "title": "WrappingWithoutCause",
          "help": "Wrapping a caught exception without passing it as `previous`/cause",
          "type": "flag",
          "default": "true",
          "group": "backend/exceptions",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_constructor-side-effect": {
          "title": "ConstructorSideEffect",
          "help": "A constructor that performs a side effect on a collaborator and throws away the result, so simply creating the object changes something outside it.",
          "type": "flag",
          "default": "true",
          "group": "backend/fix-at-the-source",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_divergent-twin": {
          "title": "DivergentTwin",
          "help": "Two functions do the same job, but one of them skips a step the other takes \u2014 usually a fix made in one copy and forgotten in the other.",
          "type": "flag",
          "default": "true",
          "group": "backend/fix-at-the-source",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_duplicate-function": {
          "title": "DuplicateFunction",
          "help": "Copy-pasted code \u2014 two+ functions with an identical AST (formatting/comments aside)",
          "type": "flag",
          "default": "true",
          "group": "backend/fix-at-the-source",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_manufactured-fake-fill": {
          "title": "ManufacturedFakeFill",
          "help": "`?? <empty literal>` filling a required slot (manufactured fake)",
          "type": "flag",
          "default": "true",
          "group": "backend/fix-at-the-source",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_mutable-static-state": {
          "title": "MutableStaticState",
          "help": "A write to a static property \u2014 really a global variable with a namespace attached \u2014 where whichever write happens last wins, so the order code runs in changes the result.",
          "type": "flag",
          "default": "true",
          "group": "backend/fix-at-the-source",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_near-duplicate-function": {
          "title": "NearDuplicateFunction",
          "help": "Redundant methods \u2014 two+ functions with the same SHAPE differing only in names/literals (type-2 clone)",
          "type": "flag",
          "default": "true",
          "group": "backend/fix-at-the-source",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_coalesced-loop-subject": {
          "title": "CoalescedLoopSubject",
          "help": "`foreach ($x[$k] ?? [] as \u2026)` \u2014 the absence check buried in the loop header instead of stated as a guard",
          "type": "flag",
          "default": "true",
          "group": "backend/guard-clauses-and-flow",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_deep-nesting": {
          "title": "DeepNesting",
          "help": "`if` nested 3-deep (a pyramid \u2014 hoist guards / extract)",
          "type": "flag",
          "default": "true",
          "group": "backend/guard-clauses-and-flow",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_if-else-ladder": {
          "title": "IfElseLadder",
          "help": "if/elseif ladder of 4+ branches (should be match/dispatch)",
          "type": "flag",
          "default": "true",
          "group": "backend/guard-clauses-and-flow",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_inline-throw": {
          "title": "InlineThrow",
          "help": "`?? throw` fed into a call or dereferenced on the same line (inline throw mid-expression)",
          "type": "flag",
          "default": "true",
          "group": "backend/guard-clauses-and-flow",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_loop-inverted-guard": {
          "title": "LoopInvertedGuard",
          "help": "Loop body (multi-statement) wrapped in an `if` instead of `continue` guard",
          "type": "flag",
          "default": "true",
          "group": "backend/guard-clauses-and-flow",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_nested-ternary": {
          "title": "NestedTernary",
          "help": "Nested/chained ternary `$a ? $b : ($c ? $d : $e)` (hidden control flow)",
          "type": "flag",
          "default": "true",
          "group": "backend/guard-clauses-and-flow",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_non-counting-for": {
          "title": "NonCountingFor",
          "help": "A `for` loop that looks like it's counting, but its step actually assigns the next item instead of incrementing a counter.",
          "type": "flag",
          "default": "true",
          "group": "backend/guard-clauses-and-flow",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_redundant-else": {
          "title": "RedundantElse",
          "help": "`else` after an `if` branch that already returns/throws (redundant)",
          "type": "flag",
          "default": "true",
          "group": "backend/guard-clauses-and-flow",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_short-circuit-statement": {
          "title": "ShortCircuitStatement",
          "help": "a bare `$a && $b->do();` statement \u2014 a short-circuit whose result nothing reads, so the operator is an `if` in disguise",
          "type": "flag",
          "default": "true",
          "group": "backend/guard-clauses-and-flow",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_ternary-statement": {
          "title": "TernaryStatement",
          "help": "a bare `$cond ? doThis() : doThat();` statement \u2014 a ternary whose value nothing reads, so it is choosing an ACTION, not a value",
          "type": "flag",
          "default": "true",
          "group": "backend/guard-clauses-and-flow",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_config-read": {
          "title": "ConfigRead",
          "help": "`config('\u2026')` read inside a class",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_container-reach": {
          "title": "ContainerReach",
          "help": "`app()`/`resolve()` reach inside a container-resolved class",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_dead-config-key": {
          "title": "DeadConfigKey",
          "help": "A config key nothing reads \u2014 dead surface left behind by a deleted feature, which new code may wrongly adopt",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_dead-event-wiring": {
          "title": "DeadEventWiring",
          "help": "An `Event::listen` on an event class no live code path can fire \u2014 a listener chain that dead-ends but reads as live wiring",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_duplicated-config-default": {
          "title": "DuplicatedConfigDefault",
          "help": "A config key whose default is stated TWICE \u2014 once in the config file, again as the reader's inline fallback \u2014 two sources of truth that drift silently",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_facade-call": {
          "title": "FacadeCall",
          "help": "Laravel facade call (`Cache::`, `Log::`, `Mail::` \u2026)",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_mass-update-at-call-site": {
          "title": "MassUpdateAtCallSite",
          "help": "Bare `$model->update([...])` mass-array update at a call site",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_model-mutation-at-call-site": {
          "title": "ModelMutationAtCallSite",
          "help": "Set-property-then-`save()` at a call site (should be an intention method)",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_orphaned-binding": {
          "title": "OrphanedBinding",
          "help": "A container binding whose abstract nothing ever resolves \u2014 dead wiring that reads as load-bearing and survives every refactor",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_raw-request-input": {
          "title": "RawRequestInput",
          "help": "Raw `->input()/->get()/->query()/->post()` on a Request",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_request-accessor-recast": {
          "title": "RequestAccessorRecast",
          "help": "Re-coercing a typed request accessor at a call site \u2014 `$request->string('id')->toString()` or `(string) $request->string('id')` instead of a named getter on a request class",
          "type": "flag",
          "default": "true",
          "group": "backend/laravel-idioms",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_bare-state-predicate": {
          "title": "BareStatePredicate",
          "help": "A `bool` about the object's own state named as a bare verb \u2014 `binds()`, `spins()` \u2014 where a question belongs",
          "type": "flag",
          "default": "true",
          "group": "backend/method-mood",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_narrated-command": {
          "title": "NarratedCommand",
          "help": "A command named in the third person \u2014 `hides()`, `entersTestMode()` \u2014 where a call is an order, not a description of one",
          "type": "flag",
          "default": "true",
          "group": "backend/method-mood",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_constructor-orchestration": {
          "title": "ConstructorOrchestration",
          "help": "A page object fills a public slot imperatively in the constructor (`$this->x = $this->projector->\u2026()`) where a `#[Computed]` property hook would describe it in place",
          "type": "flag",
          "default": "true",
          "group": "backend/page-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_injected-service-not-hidden": {
          "title": "InjectedServiceNotHidden",
          "help": "A page object injects a service (`#[FromContainer]`, \u2026) into a public property without `#[Hidden]` \u2014 it leaks into the generated TypeScript type",
          "type": "flag",
          "default": "true",
          "group": "backend/page-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_manual-output-transform": {
          "title": "ManualOutputTransform",
          "help": "A `Data` computed slot hand-flattens a value object into a wire array, instead of a `#[WithTransformer]` that owns the serialized shape",
          "type": "flag",
          "default": "true",
          "group": "backend/page-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_page-object-missing-typescript": {
          "title": "PageObjectMissingTypeScript",
          "help": "A page object travels back in a response but carries no `#[TypeScript]` \u2014 the `.vue` page reads it as untyped `any`, so the whole page-prop contract goes unchecked",
          "type": "flag",
          "default": "true",
          "group": "backend/page-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_service-location-in-page-object": {
          "title": "ServiceLocationInPageObject",
          "help": "A page object reaches into the container with `app()`/`resolve()` instead of injecting the collaborator via `#[FromContainer]`",
          "type": "flag",
          "default": "true",
          "group": "backend/page-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_transformer-without-ts-type": {
          "title": "TransformerWithoutTsType",
          "help": "A `#[WithTransformer]` changes a property's wire shape but has no paired `#[TypeScriptType]`/`#[LiteralTypeScriptType]`, so the generated TypeScript keeps the wrong (PHP) type",
          "type": "flag",
          "default": "true",
          "group": "backend/page-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_computed-boolean-argument": {
          "title": "ComputedBooleanArgument",
          "help": "A parameter that's just true/false, computed by every caller from the same object it could be given instead.",
          "type": "flag",
          "default": "true",
          "group": "backend/pass-the-object",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_converted-argument": {
          "title": "ConvertedArgument",
          "help": "A parameter typed as the already-converted form instead of the raw value, so every call site repeats the same conversion before calling it (e.g. `Raises::of(ClassAlias::of($interaction), \u2026)`).",
          "type": "flag",
          "default": "true",
          "group": "backend/pass-the-object",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_derived-argument": {
          "title": "DerivedArgument",
          "help": "Passing the same object twice \u2014 once whole and once broken into a piece (`persist($request, $request->shopId())`), or broken into several pieces at once (`new AgentTurn($r->output(), $r->failed(), $r->errorOutput())`) \u2014 when the callee could derive each piece itself from the one object.",
          "type": "flag",
          "default": "true",
          "group": "backend/pass-the-object",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_param-resolved-from-param": {
          "title": "ParamResolvedFromParam",
          "help": "Unpacking the target out of a container parameter \u2014 a method takes `(Workflow $workflow, string $nodeId)` and resolves `$workflow->graph->nodeById($nodeId)` itself, when it could just receive the node directly.",
          "type": "flag",
          "default": "true",
          "group": "backend/pass-the-object",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_repeated-guard": {
          "title": "RepeatedGuard",
          "help": "The SAME compound guard condition recurs in \u22652 places \u2014 the same check spelled differently (inline reaches vs locals) or reordered still counts, so a copied condition has no name",
          "type": "flag",
          "default": "true",
          "group": "backend/repeated-call-helper",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_repeated-named-call": {
          "title": "RepeatedNamedCall",
          "help": "The same `with`-style (variadic) method is called with the same named argument at 2+ sites, instead of a named helper on the type",
          "type": "flag",
          "default": "true",
          "group": "backend/repeated-call-helper",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_repeated-type-guard": {
          "title": "RepeatedTypeGuard",
          "help": "The SAME multi-`instanceof` type-narrowing guard (`$x instanceof A && $x->y instanceof B`) is written verbatim in \u22652 places \u2014 a check with no name, copied instead of named",
          "type": "flag",
          "default": "true",
          "group": "backend/repeated-call-helper",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_nullable-registry-lookup": {
          "title": "NullableRegistryLookup",
          "help": "A keyed-store `get()` that returns `null` on a miss (should resolve-or-throw)",
          "type": "flag",
          "default": "true",
          "group": "backend/role-vocabulary",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_boundary-duplicated-operation": {
          "title": "BoundaryDuplicatedOperation",
          "help": "The same domain operation hand-rolled at two DIFFERENT entry boundaries (a console command and an MCP tool, a controller and a command) \u2014 one operation with two implementations that drift",
          "type": "flag",
          "default": "true",
          "group": "backend/route-actions",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_dangling-route-name": {
          "title": "DanglingRouteName",
          "help": "A `route('x')` lookup naming a route no registration mints \u2014 a stringly cross-reference that only fails at runtime, as a 500",
          "type": "flag",
          "default": "true",
          "group": "backend/route-actions",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_duplicate-route": {
          "title": "DuplicateRoute",
          "help": "Two route registrations of the same verb bind different URLs to the SAME `[Controller, method]` \u2014 two names for one handler (invokable single-action controllers, commonly aliased to several canonical URLs, are exempt)",
          "type": "flag",
          "default": "true",
          "group": "backend/route-actions",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_duplicate-route-action": {
          "title": "DuplicateRouteAction",
          "help": "Two route actions in different controllers thinly delegate to the SAME operation (`return $this->exporter->export(...)`) \u2014 the same entry point twice",
          "type": "flag",
          "default": "true",
          "group": "backend/route-actions",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_route-delegates-to-controller": {
          "title": "RouteDelegatesToController",
          "help": "A route action forwards to ANOTHER controller's action (`return $this->otherController->action(...)`) \u2014 a redundant entry point onto an operation that already has one",
          "type": "flag",
          "default": "true",
          "group": "backend/route-actions",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_all-nullable-data": {
          "title": "AllNullableData",
          "help": "All-nullable \"god\" DTO \u2014 every field `?T`/defaulted (type doesn't tell the truth)",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_all-optional-data": {
          "title": "AllOptionalData",
          "help": "Every field of a `Data` object is `T|Optional` \u2014 the type promises nothing is ever present; the absence belongs on the CONTAINER field where it's used",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_data-collection-type": {
          "title": "DataCollectionType",
          "help": "A `Data` property is TYPED as `DataCollection` \u2014 it should be `array` (or `Collection`) with `#[DataCollectionOf(X)]`; the `DataCollection` type emits malformed TypeScript and skips element-typed hydration",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_data-method-hint-collision": {
          "title": "DataMethodHintCollision",
          "help": "`@method` tag that re-declares a real method (names the concrete factory, not the magic `from`/`collect`)",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_hook-missing-computed": {
          "title": "HookMissingComputed",
          "help": "A get-only property HOOK on a `Data` class lacks `#[Computed]` \u2014 Spatie reads the virtual property as a hydration INPUT, expects it in `::from()`, and crashes or silently drops it",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_manual-hydration-loop": {
          "title": "ManualHydrationLoop",
          "help": "Collections hydrated with `::from()` per item instead of `#[DataCollectionOf]` + `::collect()`",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_manual-input-cast": {
          "title": "ManualInputCast",
          "help": "A `Data` value-object property is hand-built at every construction site, instead of a `#[WithCast]` / `Castable` that owns the hydration once",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_nested-type-missing-typescript": {
          "title": "NestedTypeMissingTypeScript",
          "help": "A `#[TypeScript]` Data has a property typed as a nested `Data` class that itself lacks `#[TypeScript]` \u2014 the transformer emits it as `undefined`, a silent hole in the generated type (a nested enum is fine; the enum collector auto-generates it)",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_new-data-object": {
          "title": "NewDataObject",
          "help": "`new <Data subclass>` instead of `::from()` / a `fromX()` factory",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_non-final-data": {
          "title": "NonFinalData",
          "help": "Data class not `final` / props not `readonly` promoted",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_null-to-optional-map": {
          "title": "NullToOptionalMap",
          "help": "A producer hand-maps null\u2192`new Optional` \u2014 `$x === null ? new Optional : Foo::from($x)` or `expr() ?? new Optional` \u2014 instead of one named factory (Spatie's `optional()` maps null\u2192null, the opposite of what a `T|Optional` slot needs)",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_nullable-wire-object": {
          "title": "NullableWireObject",
          "help": "A nested object on a `#[TypeScript]` Data is typed `T | null` \u2014 it ships `null` on the wire where `T | Optional` would OMIT it (what the frontend's `x?.` reads for \"absent\")",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_prefer-optional-create": {
          "title": "PreferOptionalCreate",
          "help": "A raw `new Optional` is constructed in a runtime expression where Spatie's built-in `Optional::create()` factory reads clearer",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_data-to-array-roundtrip": {
          "title": "DataToArrayRoundtrip",
          "help": "A `X::from(...)->toArray()` sits in a `::from` slot typed `X` that re-hydrates it \u2014 build \u2192 array \u2192 build",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data-hydration",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_derived-collection-cast": {
          "title": "DerivedCollectionCast",
          "help": "A `#[DataCollectionOf]` is filled by mapping a factory over inputs at the call site, where a `#[WithCast]` should own the derivation",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data-hydration",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_hand-key-remap": {
          "title": "HandKeyRemap",
          "help": "A `::from([...])` mechanically renames `$src['snake_key']` \u2192 `camelKey` by hand, instead of a class-level `#[MapInputName]`",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data-hydration",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_redundant-enum-unwrap": {
          "title": "RedundantEnumUnwrap",
          "help": "An enum is unwrapped to `->value` at a hydration site (`'status' => $order->status->value`) where the property is typed as that enum \u2014 Spatie re-casts the scalar straight back to the enum",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data-hydration",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_redundant-native-cast": {
          "title": "RedundantNativeCast",
          "help": "An enum / date is constructed at a hydration site (`Enum::from($x)`, `new DateTime($x)`) where the property auto-casts the raw scalar",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data-hydration",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_redundant-nested-from": {
          "title": "RedundantNestedFrom",
          "help": "A nested `X::from([...])` fills a slot the parent `::from` already auto-hydrates from the array",
          "type": "flag",
          "default": "true",
          "group": "backend/spatie-data-hydration",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_feature-envy": {
          "title": "FeatureEnvy",
          "help": "Exiled behaviour / feature envy \u2014 a method operating on ONE other owned object's internals that belongs ON that object",
          "type": "flag",
          "default": "true",
          "group": "backend/tell-dont-ask",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_keyed-lookup-envy": {
          "title": "KeyedLookupEnvy",
          "help": "Indirect feature envy \u2014 a method that uses an owned object's IDENTITY as a key to look up a fact about it through a collaborator",
          "type": "flag",
          "default": "true",
          "group": "backend/tell-dont-ask",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_type-switch": {
          "title": "TypeSwitch",
          "help": "two or more `instanceof` tests on the same subject deciding different branches \u2014 asking a value what it IS instead of telling it what to do",
          "type": "flag",
          "default": "true",
          "group": "backend/tell-dont-ask",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_assembled-template": {
          "title": "AssembledTemplate",
          "help": "A multi-line template assembled as an array of line fragments and joined with a newline \u2014 the output is unreadable in the source that emits it",
          "type": "flag",
          "default": "true",
          "group": "backend/templates",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_masked-invariant": {
          "title": "MaskedInvariant",
          "help": "Masked invariant \u2014 an own field read as `?->\u2026 ?? <fake literal>`, even though the very operation sets that field first, so the fallback only ever answers an impossible \"not set yet\".",
          "type": "flag",
          "default": "true",
          "group": "backend/type-honesty",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_phantom-nullable": {
          "title": "PhantomNullable",
          "help": "Phantom nullable \u2014 a field typed `?T` (promoted param or declared property, any class) whose value, traced through the whole program, is always read as present and NEVER guarded, so the null never happens",
          "type": "flag",
          "default": "true",
          "group": "backend/type-honesty",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_placeholder-filled-data": {
          "title": "PlaceholderFilledData",
          "help": "A required non-nullable `string` slot handed `''` \u2014 the type promises a value that is always there and the caller has none",
          "type": "flag",
          "default": "true",
          "group": "backend/type-honesty",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_redundant-arrow-return-type": {
          "title": "RedundantArrowReturnType",
          "help": "An arrow function whose return type only repeats what its one expression provably yields \u2014 `fn (): string => $this->name` on a `string` property",
          "type": "flag",
          "default": "true",
          "group": "backend/type-honesty",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_scratch-state-restore": {
          "title": "ScratchStateRestore",
          "help": "Scratch state on `$this` \u2014 a method that saves one of its own fields to a local and restores it (`$prev = $this->scope; \u2026 $this->scope = $prev`), the field really a per-call input",
          "type": "flag",
          "default": "true",
          "group": "backend/type-honesty",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_useless-property-hook": {
          "title": "UselessPropertyHook",
          "help": "A `get` hook that reads nothing from `$this` \u2014 a stored property wearing computed syntax",
          "type": "flag",
          "default": "true",
          "group": "backend/type-honesty",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_array-bag": {
          "title": "ArrayBag",
          "help": "String-indexing (`$arr['key']`) a structured array param instead of giving it a name \u2014 the type was never defined.",
          "type": "flag",
          "default": "true",
          "group": "backend/value-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_array-return-bag": {
          "title": "ArrayReturnBag",
          "help": "Returning a multi-field string-keyed array literal (a bag that should be a value object)",
          "type": "flag",
          "default": "true",
          "group": "backend/value-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_coupled-fields": {
          "title": "CoupledFields",
          "help": "A class's own fields always change and get checked together \u2014 one concept split across several fields \u2014 and should be folded into a single value object.",
          "type": "flag",
          "default": "true",
          "group": "backend/value-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_data-clump": {
          "title": "DataClump",
          "help": "The same 3+ scalar params threaded through 2+ classes (a recurring data clump \u2192 one object)",
          "type": "flag",
          "default": "true",
          "group": "backend/value-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_flat-field-cluster": {
          "title": "FlatFieldCluster",
          "help": "A `#[TypeScript]` `Data` class spreads a value object it already models flat across sibling scalar fields sharing a camelCase prefix (`wireType` + `wireLabel`) instead of nesting the existing `Wire{type, label}`.",
          "type": "flag",
          "default": "true",
          "group": "backend/value-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_hand-rolled-wither": {
          "title": "HandRolledWither",
          "help": "A wither method rebuilds the whole object by re-listing every constructor field, so adding a new field means updating every wither in the class.",
          "type": "flag",
          "default": "true",
          "group": "backend/value-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_mutable-value-object": {
          "title": "MutableValueObject",
          "help": "A value type that mutates its own field after construction, so two things holding what should be the same value can end up different \u2014 one changes without the other knowing.",
          "type": "flag",
          "default": "true",
          "group": "backend/value-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_positional-tuple-return": {
          "title": "PositionalTupleReturn",
          "help": "Returning a positional TUPLE \u2014 `return [$node, $key, $inputs, $outputs]` \u2014 bundling independent values as a keyless list the caller destructures by position",
          "type": "flag",
          "default": "true",
          "group": "backend/value-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_raw-decoded-array-return": {
          "title": "RawDecodedArrayReturn",
          "help": "Returning a raw decoded boundary array (`json_decode(...)`) untyped",
          "type": "flag",
          "default": "true",
          "group": "backend/value-objects",
          "when": [
            {
              "language_php": true
            }
          ],
          "detail": true
        },
        "sin_csharp-blank-string-default": {
          "title": "BlankStringDefault",
          "help": "a `string` parameter or property defaulted to `\"\"` and then checked with `== \"\"` or `string.IsNullOrEmpty` \u2014 the blank is being used to mean \"missing\"",
          "type": "flag",
          "default": "true",
          "group": "csharp/absence",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-cancelled-coalesce": {
          "title": "CancelledCoalesce",
          "help": "a `??` fallback compared against the same value it falls back to \u2014 `(name ?? \"\") != \"\"` \u2014 so \"missing\" and \"empty\" end up in one branch without saying so",
          "type": "flag",
          "default": "true",
          "group": "csharp/absence",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-de-nulled-finder": {
          "title": "DeNulledFinder",
          "help": "a finder returning a nullable object whose every caller asserts it is there \u2014 `Find(id)!`, `Find(id) ?? throw \u2026` \u2014 a miss the finder should have refused itself",
          "type": "flag",
          "default": "true",
          "group": "csharp/absence",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-invented-default": {
          "title": "InventedDefault",
          "help": "`F(x ?? \"\")` \u2014 an empty string, `0` or `false` invented to fill an argument, or answered by a lookup helper on a miss, a stand-in the callee cannot tell from real data",
          "type": "flag",
          "default": "true",
          "group": "csharp/absence",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-null-forgiven": {
          "title": "NullForgiven",
          "help": "The null-forgiving `!` on a value declared nullable \u2014 the compiler told the caller it may be null, and `!` silences it instead of deciding",
          "type": "flag",
          "default": "true",
          "group": "csharp/absence",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-flag-argument": {
          "title": "FlagArgument",
          "help": "a method whose whole body branches on a `bool` parameter \u2014 `if (compact) \u2026 else \u2026` \u2014 two methods sharing one name",
          "type": "flag",
          "default": "true",
          "group": "csharp/behaviour-per-method",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-member-after-method": {
          "title": "MemberAfterMethod",
          "help": "a field, constant or stored property declared below a constructor or a method \u2014 the type's state hidden among its behaviour",
          "type": "flag",
          "default": "true",
          "group": "csharp/class-layout",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-member-out-of-order": {
          "title": "MemberOutOfOrder",
          "help": "a `const` or `static readonly` value declared below a field or a stored property \u2014 the top of the type read in no particular order",
          "type": "flag",
          "default": "true",
          "group": "csharp/class-layout",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-namespace-cycle": {
          "title": "NamespaceCycle",
          "help": "two of the project's namespaces that each use the other \u2014 a cycle that makes them one namespace split under two names",
          "type": "flag",
          "default": "true",
          "group": "csharp/dependency-direction",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-namespace-dependency": {
          "title": "NamespaceDependency",
          "help": "a reference out of a declared layer into a namespace that layer did not declare it may use",
          "type": "flag",
          "default": "true",
          "group": "csharp/dependency-direction",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-archaeology-comment": {
          "title": "ArchaeologyComment",
          "help": "a comment that tells the code's past \u2014 `// formerly lived in CheckoutService`, `// refactored to use the cache` \u2014 describing a version nobody is reading",
          "type": "flag",
          "default": "true",
          "group": "csharp/documentation",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-bloated-docblock": {
          "title": "BloatedDocblock",
          "help": "a type whose doc comment runs to two or more paragraphs \u2014 usually a sign the type does too much",
          "type": "flag",
          "default": "true",
          "group": "csharp/documentation",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-ceremony-docblock": {
          "title": "CeremonyDocblock",
          "help": "a doc comment whose every tag is empty or only repeats the signature \u2014 `<param name=\"order\">The order.</param>`, an empty `<returns>`",
          "type": "flag",
          "default": "true",
          "group": "csharp/documentation",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-dangling-doc-reference": {
          "title": "DanglingDocReference",
          "help": "a `<see cref>` that resolves to nothing from where it is written \u2014 a name the project no longer declares, or one spelled so it does not reach it",
          "type": "flag",
          "default": "true",
          "group": "csharp/documentation",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-negative-space-comment": {
          "title": "NegativeSpaceComment",
          "help": "a comment defending the code against a reading nobody made \u2014 `// not magic, just a day`, `// deliberately not sorted` \u2014 saying what it is not instead of what it is",
          "type": "flag",
          "default": "true",
          "group": "csharp/documentation",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-restated-comment": {
          "title": "RestatedComment",
          "help": "a comment above a statement whose every word the statement already spells \u2014 `// set the total to the order total` over `var total = order.Total;`",
          "type": "flag",
          "default": "true",
          "group": "csharp/documentation",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_duplicate-csharp-method": {
          "title": "DuplicateMethod",
          "help": "Copy-pasted code \u2014 two+ C# methods, accessors or local functions with an identical body, formatting, comments and attributes aside",
          "type": "flag",
          "default": "true",
          "group": "csharp/duplication",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_near-duplicate-csharp-method": {
          "title": "NearDuplicateMethod",
          "help": "A near-copy \u2014 two+ C# methods, accessors or local functions with one control-flow skeleton that differ only in their local names or the literals they use (a key, a route, a message)",
          "type": "flag",
          "default": "true",
          "group": "csharp/duplication",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-const-class-enum": {
          "title": "ConstClassEnum",
          "help": "a class that holds nothing but `const` strings or numbers \u2014 a closed set of values written as constants instead of an `enum`",
          "type": "flag",
          "default": "true",
          "group": "csharp/enums",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-enum-case-or-chain": {
          "title": "EnumCaseOrChain",
          "help": "`s == Status.Paid || s == Status.Refunded` (or `s is Status.Paid or Status.Refunded`) \u2014 a group of enum cases tested by hand at the call site",
          "type": "flag",
          "default": "true",
          "group": "csharp/enums",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-in-array-mirrors-enum": {
          "title": "InArrayMirrorsEnum",
          "help": "`new[] { \"paid\", \"refunded\" }.Contains(status)` or `status is \"paid\" or \"refunded\"` \u2014 a list of strings that repeats the members of an enum the code already has",
          "type": "flag",
          "default": "true",
          "group": "csharp/enums",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-match-default-returns-null": {
          "title": "MatchDefaultReturnsNull",
          "help": "a `switch` that names every member of an enum, then answers `null`, `default` or `false` in its `_` arm \u2014 the one value that arm can see is a bug, and it is answered as if it were fine",
          "type": "flag",
          "default": "true",
          "group": "csharp/enums",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-string-mirrors-enum": {
          "title": "StringMirrorsEnum",
          "help": "A `switch` or an `if` ladder dispatching on strings that are the names of an enum the codebase already declares \u2014 the enum, written out again as text",
          "type": "flag",
          "default": "true",
          "group": "csharp/enums",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-unnamed-vocabulary-literal": {
          "title": "UnnamedVocabularyLiteral",
          "help": "a raw string handed to a parameter the codebase elsewhere fills from a named constant \u2014 `Expect(\"{\")` beside `Expect(Token.Colon)`, where `Token.BraceOpen` already names it",
          "type": "flag",
          "default": "true",
          "group": "csharp/enums",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-generic-throw": {
          "title": "GenericThrow",
          "help": "`throw new Exception/InvalidOperationException(\"\u2026\")` \u2014 a failure that names nothing, described in prose at the throw site",
          "type": "flag",
          "default": "true",
          "group": "csharp/exceptions",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-swallowed-exception": {
          "title": "SwallowedException",
          "help": "A bare `catch` or `catch (Exception)` whose body is empty, continues, or returns nothing \u2014 every failure, expected or not, made to vanish",
          "type": "flag",
          "default": "true",
          "group": "csharp/exceptions",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-wrapping-without-cause": {
          "title": "WrappingWithoutCause",
          "help": "a `catch` that throws a new exception without passing the caught one as its inner exception, so the original stack trace is lost",
          "type": "flag",
          "default": "true",
          "group": "csharp/exceptions",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-constructor-side-effect": {
          "title": "ConstructorSideEffect",
          "help": "a constructor that calls a method on something it was handed and ignores the result \u2014 just creating the object changes something outside it",
          "type": "flag",
          "default": "true",
          "group": "csharp/fix-at-the-source",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-mutable-static-state": {
          "title": "MutableStaticState",
          "help": "a `static` field that methods write to \u2014 state no instance owns, changed by whichever code ran last",
          "type": "flag",
          "default": "true",
          "group": "csharp/fix-at-the-source",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-coalesced-loop-subject": {
          "title": "CoalescedLoopSubject",
          "help": "a `foreach` over `items ?? []` (or `Enumerable.Empty<T>()`, or a new empty list) \u2014 the check for a missing collection is hidden in the loop header",
          "type": "flag",
          "default": "true",
          "group": "csharp/flow",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-inline-throw": {
          "title": "InlineThrow",
          "help": "a `?? throw` inside a call's argument or in front of a member call \u2014 the check that stops the method is hidden in the middle of the work",
          "type": "flag",
          "default": "true",
          "group": "csharp/flow",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-loop-wrapped-in-if": {
          "title": "LoopWrappedInIf",
          "help": "A `for`, `foreach` or `while` whose whole body is one `if` (no `else`) around real work \u2014 the iteration pushed a level deep behind a condition",
          "type": "flag",
          "default": "true",
          "group": "csharp/flow",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-nested-ternary": {
          "title": "NestedTernary",
          "help": "a `?:` with another `?:` as one of its branches \u2014 several decisions packed into one expression",
          "type": "flag",
          "default": "true",
          "group": "csharp/flow",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-non-counting-for": {
          "title": "NonCountingFor",
          "help": "a `for` loop whose step assigns the next item instead of moving a counter \u2014 a walk written as a count",
          "type": "flag",
          "default": "true",
          "group": "csharp/flow",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-subject-ladder": {
          "title": "SubjectLadder",
          "help": "An `if`/`else if` chain of four or more rungs that each compare the same subject with a constant \u2014 a dispatch written as a ladder.",
          "type": "flag",
          "default": "true",
          "group": "csharp/flow",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_deep-csharp-nesting": {
          "title": "DeepNesting",
          "help": "An `if`, loop or `switch` opening a fourth level of choices inside one C# method \u2014 an arrow of conditions and loops",
          "type": "flag",
          "default": "true",
          "group": "csharp/flow",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_redundant-csharp-else": {
          "title": "RedundantElse",
          "help": "An `else` after an `if` branch that already left \u2014 it ends in `return`, `throw`, `continue` or `break` \u2014 indenting the rest of the method for nothing",
          "type": "flag",
          "default": "true",
          "group": "csharp/flow",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-bare-state-predicate": {
          "title": "BareStatePredicate",
          "help": "a `bool` about the object's own state named as a claim \u2014 `Binds()`, `Spins` \u2014 where a question belongs",
          "type": "flag",
          "default": "true",
          "group": "csharp/method-mood",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-converted-argument": {
          "title": "ConvertedArgument",
          "help": "a scalar parameter its callers keep filling with the same conversion \u2014 `ReceiptFor(order.Id.ToString())` call after call \u2014 because it asks for the converted form instead of the value",
          "type": "flag",
          "default": "true",
          "group": "csharp/pass-the-object",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-derived-argument": {
          "title": "DerivedArgument",
          "help": "a call that hands over an object and a projection of it \u2014 `Persist(request, request.ChannelId)` \u2014 or an object in three pieces, where the method could read them itself",
          "type": "flag",
          "default": "true",
          "group": "csharp/pass-the-object",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-param-resolved-from-param": {
          "title": "ParamResolvedFromParam",
          "help": "a method that takes a container and a key and first resolves one against the other \u2014 `Rename(Workflow workflow, string nodeId)` doing `workflow.Graph.Node(nodeId)` \u2014 when it only wanted what the key names",
          "type": "flag",
          "default": "true",
          "group": "csharp/pass-the-object",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-repeated-guard": {
          "title": "RepeatedGuard",
          "help": "the same compound condition \u2014 `order.Paid && !order.Cancelled` \u2014 written at two or more sites, a question with no name",
          "type": "flag",
          "default": "true",
          "group": "csharp/repeated-call-helper",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-repeated-named-call": {
          "title": "RepeatedNamedCall",
          "help": "the same `with` copy \u2014 `order with { Status = OrderStatus.Shipped }` \u2014 written at two or more sites, an operation the record never named",
          "type": "flag",
          "default": "true",
          "group": "csharp/repeated-call-helper",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-repeated-type-guard": {
          "title": "RepeatedTypeGuard",
          "help": "the same chain of type checks \u2014 `node is Invocation call && call.Target is MemberAccess` \u2014 written at two or more sites, a shape with no name",
          "type": "flag",
          "default": "true",
          "group": "csharp/repeated-call-helper",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-feature-envy": {
          "title": "FeatureEnvy",
          "help": "a method that loops another object's collection or writes its members, reaching into it more than into its own state \u2014 behaviour exiled from the object it works on",
          "type": "flag",
          "default": "true",
          "group": "csharp/tell-dont-ask",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-type-switch": {
          "title": "TypeSwitch",
          "help": "`shape switch { Circle c => \u2026, Square s => \u2026 }` \u2014 asking which of your own types a value is, to decide what to do with it",
          "type": "flag",
          "default": "true",
          "group": "csharp/tell-dont-ask",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-assembled-template": {
          "title": "AssembledTemplate",
          "help": "`string.Join(\"\\n\", new[] { \"public class X\", \"{\", \"}\" })` or `sb.AppendLine(\"\u2026\")` line after line \u2014 a multi-line text built from line fragments, so its shape cannot be seen in the source",
          "type": "flag",
          "default": "true",
          "group": "csharp/templates",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-placeholder-filled-data": {
          "title": "PlaceholderFilledData",
          "help": "`new Card(title, \"\")` \u2014 a record's required `string` filled with a blank so the record can be built, hiding a missing value no type check can see",
          "type": "flag",
          "default": "true",
          "group": "csharp/type-honesty",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-array-return-bag": {
          "title": "ArrayReturnBag",
          "help": "a method that returns `new Dictionary<string, object> { [\"sku\"] = \u2026, [\"qty\"] = \u2026 }` \u2014 a record with fixed fields, handed back as a dictionary",
          "type": "flag",
          "default": "true",
          "group": "csharp/value-objects",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-coupled-fields": {
          "title": "CoupledFields",
          "help": "a type whose own fields always travel together \u2014 assembled into one value again and again, null-checked together, or one copying what a sibling field already holds \u2014 one concept held as several fields",
          "type": "flag",
          "default": "true",
          "group": "csharp/value-objects",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-data-clump": {
          "title": "DataClump",
          "help": "The same three or more string, number, date or id parameters threaded through methods of two or more types \u2014 values that always travel together but have no type of their own.",
          "type": "flag",
          "default": "true",
          "group": "csharp/value-objects",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-dictionary-bag": {
          "title": "DictionaryBag",
          "help": "A string-keyed dictionary or JSON object read by keys written in the source \u2014 `row[\"sku\"]`, `json.GetProperty(\"name\")` \u2014 a record nobody declared",
          "type": "flag",
          "default": "true",
          "group": "csharp/value-objects",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-mutable-value-object": {
          "title": "MutableValueObject",
          "help": "a record that can change after it is built \u2014 a `set` accessor, or a method that writes its own state \u2014 so two holders of the same value can end up seeing different things",
          "type": "flag",
          "default": "true",
          "group": "csharp/value-objects",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_csharp-positional-tuple-return": {
          "title": "PositionalTupleReturn",
          "help": "a method that returns `(decimal, decimal, string)` \u2014 unnamed values the caller reads by position, where two of the same type can be swapped and nothing notices",
          "type": "flag",
          "default": "true",
          "group": "csharp/value-objects",
          "when": [
            {
              "language_cs": true
            }
          ],
          "detail": true
        },
        "sin_mirrored-server-type": {
          "title": "MirroredServerType",
          "help": "A hand-written TypeScript type mirrors a backend `Data` class one-to-one \u2014 two sources of truth for one contract that drift the moment the server shape changes",
          "type": "flag",
          "default": "true",
          "group": "frontend/mirrored-server-type",
          "when": [
            {
              "language_vue": true
            },
            {
              "language_ts": true
            }
          ],
          "detail": true
        },
        "sin_compound-inline-component": {
          "title": "CompoundInlineComponent",
          "help": "A compound primitive (`Dialog`/`Card`/`Sheet`/`Tabs`\u2026) assembled inline with a substantial body \u2014 extract it into its own named component.",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-components",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_deep-data-reach": {
          "title": "DeepDataReach",
          "help": "A group of elements in a sizeable template that all reach deep into the same nested object (\u22652 distinct fields) \u2014 extract the shared mid-object into a component that takes it as a prop.",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-components",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_deep-nested": {
          "title": "DeepNested",
          "help": "Template markup nested far too deep \u2014 extract a subtree as its own component",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-components",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_duplicate-element": {
          "title": "DuplicateElement",
          "help": "Identical markup (3+ elements) repeated 2+ times \u2014 within a template or across components \u2014 extract one component",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-components",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_inline-case-views": {
          "title": "InlineCaseViews",
          "help": "A dispatch whose cases each render a whole view inline \u2014 one component doing a job per case",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-components",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_near-duplicate-element": {
          "title": "NearDuplicateElement",
          "help": "Markup with one skeleton repeated 2+ times \u2014 the same tags, attributes and nesting binding different data \u2014 within a template, across components, or as two components' whole templates",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-components",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_oversized-component": {
          "title": "OversizedComponent",
          "help": "A component whose template renders more elements than the project's declared budget \u2014 one component doing several jobs",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-components",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_prop-drilling": {
          "title": "PropDrilling",
          "help": "A prop forwarded through a chain of 2+ components, none of which read it \u2014 passed down through components that only pass it further.",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-components",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_prop-mutation": {
          "title": "PropMutation",
          "help": "A prop is written to \u2014 `v-model` bound to it, or `@event=\"prop = \u2026\"` \u2014 but props are read-only (a build error or a silent no-op).",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-components",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_control-flow-on-element": {
          "title": "ControlFlowOnElement",
          "help": "`v-if`/`v-for`/`v-else`/`v-else-if` on an HTML/component tag instead of a `<template>`",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-control-flow",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_index-as-key": {
          "title": "IndexAsKey",
          "help": "`:key` bound to the `v-for` index \u2014 a positional key corrupts state when the list reorders or an item is inserted",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-control-flow",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_loop-with-condition": {
          "title": "LoopWithCondition",
          "help": "`v-for` and `v-if`/`v-else-if` on the same element \u2014 the condition is re-evaluated every iteration.",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-control-flow",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_switch-case": {
          "title": "SwitchCase",
          "help": "A `v-if`/`v-else-if` chain re-testing the same subject (should be `<SwitchCase :value>`)",
          "type": "flag",
          "default": "true",
          "group": "frontend/vue-control-flow",
          "when": [
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_python-blank-string-default": {
          "title": "BlankStringDefault",
          "help": "`x: str = \"\"` standing in for absence \u2014 then asked `x == \"\"`, `not x` or `if x:` in its own scope",
          "type": "flag",
          "default": "true",
          "group": "python/absence",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-cancelled-fallback": {
          "title": "CancelledFallback",
          "help": "`(x or \"\") != \"\"` \u2014 a value defaulted to a blank only to be compared against that same blank, so a missing value and an empty one are treated the same without saying so.",
          "type": "flag",
          "default": "true",
          "group": "python/absence",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-conditional-spread": {
          "title": "ConditionalSpread",
          "help": "`**({\"k\": v} if v else {})` / `*([x] if x else [])` \u2014 an entry is spread in only when present, using a conditional that turns absence into an empty collection.",
          "type": "flag",
          "default": "true",
          "group": "python/absence",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-invented-default": {
          "title": "InventedDefault",
          "help": "`f(x or \"\")` \u2014 an empty string, `0` or `False` invented to fill an argument when the value is missing, a stand-in the callee cannot tell from real data",
          "type": "flag",
          "default": "true",
          "group": "python/absence",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-nullable-callback": {
          "title": "NullableCallback",
          "help": "`cb: Callable | None = None` asked `if cb is not None:` / `if cb:` / `cb or \u2026` in the body \u2014 a no-op treated as if it might be missing.",
          "type": "flag",
          "default": "true",
          "group": "python/absence",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-flag-argument": {
          "title": "FlagArgument",
          "help": "a function whose whole body branches on a `bool` parameter \u2014 or on whether an optional one was given \u2014 two functions sharing one name",
          "type": "flag",
          "default": "true",
          "group": "python/behaviour-per-method",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-member-after-method": {
          "title": "MemberAfterMethod",
          "help": "a constant, class attribute or field declared below a method \u2014 the class's state hidden among its behaviour",
          "type": "flag",
          "default": "true",
          "group": "python/class-layout",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-member-out-of-order": {
          "title": "MemberOutOfOrder",
          "help": "a constant declared below a field in the head of a class \u2014 the inventory read in an ad-hoc order",
          "type": "flag",
          "default": "true",
          "group": "python/class-layout",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-namespace-cycle": {
          "title": "NamespaceCycle",
          "help": "two of the project's packages import each other \u2014 a cycle that makes them one package split under two names.",
          "type": "flag",
          "default": "true",
          "group": "python/dependency-direction",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-namespace-dependency": {
          "title": "NamespaceDependency",
          "help": "an import out of a declared layer into a package that layer did not declare it may use",
          "type": "flag",
          "default": "true",
          "group": "python/dependency-direction",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-archaeology-comment": {
          "title": "ArchaeologyComment",
          "help": "a comment or docstring narrating the code's history \u2014 where it lived, what it replaced, what it no longer is",
          "type": "flag",
          "default": "true",
          "group": "python/documentation",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-bloated-docblock": {
          "title": "BloatedDocblock",
          "help": "a class docstring of two or more paragraphs of prose \u2014 an essay that says the class does too much",
          "type": "flag",
          "default": "true",
          "group": "python/documentation",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-ceremony-docblock": {
          "title": "CeremonyDocblock",
          "help": "a docstring with no summary whose every entry restates the annotated signature \u2014 `order (Order):`, `:rtype: int`",
          "type": "flag",
          "default": "true",
          "group": "python/documentation",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-dangling-doc-reference": {
          "title": "DanglingDocReference",
          "help": "a Sphinx cross-reference in a docstring (`:class:`shop.cart.Basket``) to a first-party name the codebase no longer declares",
          "type": "flag",
          "default": "true",
          "group": "python/documentation",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-negative-space-comment": {
          "title": "NegativeSpaceComment",
          "help": "a comment or docstring defending the code against a misunderstanding nobody actually had \u2014 what it is not, rather than what it is.",
          "type": "flag",
          "default": "true",
          "group": "python/documentation",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-restated-comment": {
          "title": "RestatedComment",
          "help": "a `#` comment that only narrates the statement below it \u2014 every word of it already spelled by the code",
          "type": "flag",
          "default": "true",
          "group": "python/documentation",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_duplicate-python-function": {
          "title": "DuplicateFunction",
          "help": "Copy-pasted code \u2014 two+ Python functions or methods with an identical body, formatting, comments and docstrings aside",
          "type": "flag",
          "default": "true",
          "group": "python/duplication",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_near-duplicate-python-function": {
          "title": "NearDuplicateFunction",
          "help": "A near-copy \u2014 two+ Python functions or methods with one control-flow skeleton that differ only in their local names or the literals they use (a path, a key, a message)",
          "type": "flag",
          "default": "true",
          "group": "python/duplication",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-constant-class-enum": {
          "title": "ConstantClassEnum",
          "help": "a class that is nothing but `PENDING = \"pending\"` constants \u2014 a closed set of values written out by hand instead of an `Enum`",
          "type": "flag",
          "default": "true",
          "group": "python/enums",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-enum-case-or-chain": {
          "title": "EnumCaseOrChain",
          "help": "`s == Status.PENDING or s == Status.LATE` \u2014 a group of an enum's members re-derived at the call site instead of named on the enum",
          "type": "flag",
          "default": "true",
          "group": "python/enums",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-enum-value-match": {
          "title": "EnumValueMatch",
          "help": "`match status.value: case \"paid\": \u2026` at a call site \u2014 the enum's raw values matched again where the enum could answer",
          "type": "flag",
          "default": "true",
          "group": "python/enums",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-in-literals-mirrors-enum": {
          "title": "InLiteralsMirrorsEnum",
          "help": "`x in (\"pending\", \"late\")` whose literals are an existing enum's values \u2014 a group of its members spelled as raw strings at the call site",
          "type": "flag",
          "default": "true",
          "group": "python/enums",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-match-wildcard-returns-none": {
          "title": "MatchWildcardReturnsNone",
          "help": "a `match` over an enum's members whose `case _:` returns `None` \u2014 a member nobody handled answers nothing instead of failing",
          "type": "flag",
          "default": "true",
          "group": "python/enums",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-string-match-mirrors-enum": {
          "title": "StringMatchMirrorsEnum",
          "help": "`match raw: case \"pending\": \u2026` whose cases are an existing enum's values \u2014 dispatching on loose strings the enum already seals",
          "type": "flag",
          "default": "true",
          "group": "python/enums",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-unnamed-vocabulary-literal": {
          "title": "UnnamedVocabularyLiteral",
          "help": "a raw string handed to a parameter the codebase elsewhere fills from a named constant \u2014 `expect(\"{\")` beside `expect(Token.COLON)`, where `Token.BRACE_OPEN` already names it",
          "type": "flag",
          "default": "true",
          "group": "python/enums",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-message-string-raise": {
          "title": "MessageStringRaise",
          "help": "`raise Exception/RuntimeError(\"\u2026\")` \u2014 a failure that names nothing, described in prose at the raise site",
          "type": "flag",
          "default": "true",
          "group": "python/exceptions",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-raise-without-cause": {
          "title": "RaiseWithoutCause",
          "help": "`raise Other(...)` inside an `except` block with no `from` \u2014 the failure being handled left as an implicit context, never named as the cause",
          "type": "flag",
          "default": "true",
          "group": "python/exceptions",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-swallowed-exception": {
          "title": "SwallowedException",
          "help": "A bare `except:` or `except Exception` whose body only passes, continues or returns nothing \u2014 every failure, expected or not, made to vanish",
          "type": "flag",
          "default": "true",
          "group": "python/exceptions",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-constructor-side-effect": {
          "title": "ConstructorSideEffect",
          "help": "an `__init__` that tells a collaborator to act and throws the answer away \u2014 merely building the object has an effect outside it.",
          "type": "flag",
          "default": "true",
          "group": "python/fix-at-the-source",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-divergent-twin": {
          "title": "DivergentTwin",
          "help": "two functions do the same job, but one of them skips a step the other takes \u2014 usually a fix made in one copy and forgotten in the other.",
          "type": "flag",
          "default": "true",
          "group": "python/fix-at-the-source",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-mutable-static-state": {
          "title": "MutableStaticState",
          "help": "a `global` written from a function, or a class attribute set from a method \u2014 state no instance owns, changed by whoever ran last",
          "type": "flag",
          "default": "true",
          "group": "python/fix-at-the-source",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_deep-python-nesting": {
          "title": "DeepNesting",
          "help": "An `if`, loop or `match` opening a fourth level of choices inside one Python function \u2014 an arrow of conditions and loops",
          "type": "flag",
          "default": "true",
          "group": "python/flow",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-coalesced-loop-subject": {
          "title": "CoalescedLoopSubject",
          "help": "`for x in d.get(k, [])` / `for x in y or []` over a parameter \u2014 whether the caller handed anything over, decided in the loop header instead of stated as a guard",
          "type": "flag",
          "default": "true",
          "group": "python/flow",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-conditional-statement": {
          "title": "ConditionalStatement",
          "help": "a bare `a() if x else b()` statement \u2014 a conditional expression whose value nothing reads, so it chooses an action, not a value.",
          "type": "flag",
          "default": "true",
          "group": "python/flow",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-loop-wrapped-in-if": {
          "title": "LoopWrappedInIf",
          "help": "A `for` or `while` whose whole body is one `if` (no `else`) around real work \u2014 the iteration pushed a level deep behind a condition",
          "type": "flag",
          "default": "true",
          "group": "python/flow",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-nested-conditional": {
          "title": "NestedConditional",
          "help": "`a if x else b if y else c` \u2014 a conditional expression inside another's branch, a branching decision folded into one line",
          "type": "flag",
          "default": "true",
          "group": "python/flow",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-short-circuit-statement": {
          "title": "ShortCircuitStatement",
          "help": "a bare `a and b()` or `a or b()` statement \u2014 an `and`/`or` whose value nothing reads, so the operator is really acting as an `if`.",
          "type": "flag",
          "default": "true",
          "group": "python/flow",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-subject-ladder": {
          "title": "SubjectLadder",
          "help": "An `if`/`elif` chain of four or more rungs that each test the same subject for equality with a constant \u2014 a dispatch written as a ladder.",
          "type": "flag",
          "default": "true",
          "group": "python/flow",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_redundant-python-else": {
          "title": "RedundantElse",
          "help": "An `else:` after an `if` branch that already left \u2014 it ends in `return`, `raise`, `continue` or `break` \u2014 indenting the rest of the function for nothing",
          "type": "flag",
          "default": "true",
          "group": "python/flow",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-bare-state-predicate": {
          "title": "BareStatePredicate",
          "help": "a `bool` about the object's own state named as a bare verb \u2014 `binds()`, `spins` \u2014 where a question belongs",
          "type": "flag",
          "default": "true",
          "group": "python/method-mood",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-narrated-command": {
          "title": "NarratedCommand",
          "help": "a command named in the third person \u2014 `hides()`, `locks_for_night()` \u2014 where a call is an order, not a description of one",
          "type": "flag",
          "default": "true",
          "group": "python/method-mood",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-computed-boolean-argument": {
          "title": "ComputedBooleanArgument",
          "help": "a method taking only bools that every caller computes from the same object \u2014 the decision re-derived at each call site",
          "type": "flag",
          "default": "true",
          "group": "python/pass-the-object",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-converted-argument": {
          "title": "ConvertedArgument",
          "help": "a scalar parameter its callers keep filling with the same conversion \u2014 `receipt_for(str(order.id))` call after call \u2014 because it asks for the converted form instead of the value",
          "type": "flag",
          "default": "true",
          "group": "python/pass-the-object",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-derived-argument": {
          "title": "DerivedArgument",
          "help": "a call that hands over an object and a projection of it \u2014 `persist(request, request.channel_id)` \u2014 or an object in three pieces, where the function could read them itself",
          "type": "flag",
          "default": "true",
          "group": "python/pass-the-object",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-param-resolved-from-param": {
          "title": "ParamResolvedFromParam",
          "help": "a function that takes a container and a key and first resolves one against the other \u2014 `def rename(workflow, node_id)` doing `workflow.graph.node(node_id)` \u2014 when it only wanted what the key names",
          "type": "flag",
          "default": "true",
          "group": "python/pass-the-object",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-repeated-guard": {
          "title": "RepeatedGuard",
          "help": "the same compound `and` condition recurs in 2+ places \u2014 it still counts even when reordered, or read through a local variable \u2014 and nobody has named it.",
          "type": "flag",
          "default": "true",
          "group": "python/repeated-call-helper",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-repeated-named-call": {
          "title": "RepeatedNamedCall",
          "help": "the same `**changes` call is built the same way with the same keyword at 2+ sites \u2014 an operation that has no name on the type it belongs to.",
          "type": "flag",
          "default": "true",
          "group": "python/repeated-call-helper",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-repeated-type-guard": {
          "title": "RepeatedTypeGuard",
          "help": "the same multi-`isinstance` narrowing (`isinstance(x, A) and isinstance(x.y, B)`) is written in 2+ places \u2014 a check on a shape that nobody has named.",
          "type": "flag",
          "default": "true",
          "group": "python/repeated-call-helper",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-nullable-registry-lookup": {
          "title": "NullableRegistryLookup",
          "help": "a keyed store handing back `None` for a key it lacks \u2014 `return self._handlers.get(kind)` \u2014 so every caller decides what a miss means",
          "type": "flag",
          "default": "true",
          "group": "python/role-vocabulary",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-feature-envy": {
          "title": "FeatureEnvy",
          "help": "a method that loops another object's collection or writes its fields, reaching into it more than into its own state \u2014 behaviour exiled from the object it works on",
          "type": "flag",
          "default": "true",
          "group": "python/tell-dont-ask",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-keyed-lookup-envy": {
          "title": "KeyedLookupEnvy",
          "help": "a method that uses an object's key to fetch a fact about it through a collaborator \u2014 `self.registry.get(node.key).reserved` \u2014 treating the object as a key into its own data",
          "type": "flag",
          "default": "true",
          "group": "python/tell-dont-ask",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-type-switch": {
          "title": "TypeSwitch",
          "help": "an `isinstance` ladder over classes the codebase owns \u2014 the value is asked what it is so the caller can decide what to do.",
          "type": "flag",
          "default": "true",
          "group": "python/tell-dont-ask",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-assembled-template": {
          "title": "AssembledTemplate",
          "help": "a multi-line string built as a list of line fragments and `\"\\n\".join(...)`-ed, instead of a triple-quoted f-string that shows its output",
          "type": "flag",
          "default": "true",
          "group": "python/templates",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-constant-property": {
          "title": "ConstantProperty",
          "help": "an `@property` whose body never reads `self` \u2014 `return \"box\"` \u2014 a stored value made to look like a computed one.",
          "type": "flag",
          "default": "true",
          "group": "python/type-honesty",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-masked-invariant": {
          "title": "MaskedInvariant",
          "help": "a literal answering for the object's own scratch state \u2014 `self.period.includes(day) if self.period else False` \u2014 where the field is only unset because an operation sets it part-way",
          "type": "flag",
          "default": "true",
          "group": "python/type-honesty",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-phantom-nullable": {
          "title": "PhantomNullable",
          "help": "a field annotated `X | None` that every read assumes is there and none guards \u2014 a `None` the design never has",
          "type": "flag",
          "default": "true",
          "group": "python/type-honesty",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-placeholder-filled-data": {
          "title": "PlaceholderFilledData",
          "help": "`Card(title=\u2026, body=\"\")` \u2014 a dataclass field required as `str` handed the blank to satisfy the signature, a value the type cannot catch",
          "type": "flag",
          "default": "true",
          "group": "python/type-honesty",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-scratch-state-restore": {
          "title": "ScratchStateRestore",
          "help": "`previous = self.scope \u2026 self.scope = previous` \u2014 an attribute used as per-call scratch, saved and restored around the call",
          "type": "flag",
          "default": "true",
          "group": "python/type-honesty",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-coupled-fields": {
          "title": "CoupledFields",
          "help": "a class whose own fields always travel together \u2014 assembled into one value again and again, guarded together, or one copying a sibling field's value \u2014 one concept held as several fields.",
          "type": "flag",
          "default": "true",
          "group": "python/value-objects",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-data-clump": {
          "title": "DataClump",
          "help": "The same three or more scalar parameters (`street: str, city: str, postcode: str`) threaded through functions in two or more classes or modules \u2014 one concept with no type of its own.",
          "type": "flag",
          "default": "true",
          "group": "python/value-objects",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-dict-bag": {
          "title": "DictBag",
          "help": "A parameter typed as a dict read by string keys \u2014 `row[\"sku\"]`, `row.get(\"quantity\")` \u2014 a record nobody declared",
          "type": "flag",
          "default": "true",
          "group": "python/value-objects",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-dict-return-bag": {
          "title": "DictReturnBag",
          "help": "`return {\"total\": \u2026, \"tax\": \u2026}` \u2014 a record of several fields handed back as a dict its callers read by string key",
          "type": "flag",
          "default": "true",
          "group": "python/value-objects",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-hand-rolled-replace": {
          "title": "HandRolledReplace",
          "help": "`return Order(self.number, self.lines, self.note, \"paid\")` in a dataclass \u2014 every field re-listed to change one",
          "type": "flag",
          "default": "true",
          "group": "python/value-objects",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-mutable-value-object": {
          "title": "MutableValueObject",
          "help": "a dataclass whose own methods write the fields it was built from after construction \u2014 a value that changes under everyone holding it",
          "type": "flag",
          "default": "true",
          "group": "python/value-objects",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-positional-tuple-return": {
          "title": "PositionalTupleReturn",
          "help": "`return net, vat, currency` \u2014 a bundle of different things the caller must unpack by position, where a reordering breaks silently",
          "type": "flag",
          "default": "true",
          "group": "python/value-objects",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_python-raw-decoded-return": {
          "title": "RawDecodedReturn",
          "help": "`return json.loads(\u2026)` \u2014 decoded text from outside handed on as bare dicts and lists, its shape known to no type",
          "type": "flag",
          "default": "true",
          "group": "python/value-objects",
          "when": [
            {
              "language_py": true
            }
          ],
          "detail": true
        },
        "sin_defended-certain-field": {
          "title": "DefendedCertainField",
          "help": "An `?.` on a field the class declares as always present \u2014 a defence against a case the type says cannot happen, so the code doubts something the design already rules out.",
          "type": "flag",
          "default": "true",
          "group": "typescript/absence",
          "when": [
            {
              "language_ts": true
            }
          ],
          "detail": true
        },
        "sin_falsely-optional-field": {
          "title": "FalselyOptionalField",
          "help": "A field declared optional (`x?: T`, `T | null`) that is initialised where it is declared \u2014 it is never absent, and every `?.` and `??` downstream defends a case that cannot happen",
          "type": "flag",
          "default": "true",
          "group": "typescript/absence",
          "when": [
            {
              "language_ts": true
            }
          ],
          "detail": true
        },
        "sin_duplicate-typescript-function": {
          "title": "DuplicateFunction",
          "help": "Copy-pasted code \u2014 two+ TypeScript functions (a `function`, a method, a `const` arrow; in a `.ts` module or a component's script) with an identical body, formatting and comments aside",
          "type": "flag",
          "default": "true",
          "group": "typescript/duplication",
          "when": [
            {
              "language_ts": true
            },
            {
              "language_vue": true
            }
          ],
          "detail": true
        },
        "sin_near-duplicate-typescript-function": {
          "title": "NearDuplicateFunction",
          "help": "A near-copy \u2014 two+ TypeScript functions with one control-flow skeleton that differ only in their local names or the literals they use (an endpoint, a key, a label)",
          "type": "flag",
          "default": "true",
          "group": "typescript/duplication",
          "when": [
            {
              "language_ts": true
            },
            {
              "language_vue": true
            }
          ],
          "detail": true
        }
      },
      "skills": "journal-skills/.agents/skills",
      "command": "bin/commandments-release",
      "installed": "bin/commandments-release journal-scan",
      "events": {
        "sin-found": {
          "title": "Sin found",
          "tone": "warn",
          "card": {
            "label": "Sin found",
            "icon": "warn",
            "collapsed": true
          }
        },
        "sin-resolved": {
          "title": "Sin repented",
          "tone": "good",
          "card": {
            "label": "Sin repented",
            "icon": "check",
            "collapsed": true
          }
        }
      },
      "fits": {
        "languages": [
          "PHP",
          "Python",
          "TypeScript",
          "Vue",
          "C#"
        ]
      },
      "hooks": {
        "PostToolUse": "async",
        "Stop": "async",
        "SessionStart": "async",
        "SubagentStart": "async"
      },
      "chat": [],
      "pages": [],
      "load": {}
    },
    "environment": "main",
    "files": {},
    "member": "owner",
    "update": {}
  },
  "created": 1791145003.475161,
  "updated": 1791711531.64448,
  "deleted": 0.0,
  "completed": 0.0,
  "outcome": "",
  "type": "plugin"
}
---

