vigiles API reference
    Preparing search index...

    Type Alias NotLoadedReason

    NotLoadedReason:
        | { by: string; kind: "replaced" }
        | { kind: "on-demand"; when: "path-scoped" | "subdirectory" }
        | {
            by: string;
            byScope: InstructionScope;
            key: string;
            kind: "excluded-by-settings";
        }
        | { by: string; byScope: InstructionScope; kind: "superseded" }

    Why a file the domain enumerated is NOT in the loaded chain.

    A tagged union so an unloaded entry WITHOUT a reason is unrepresentable. That is what issue #262's shadows field was reaching for and could not be: "shadowing" is not a semantic the core can own, because what differs between harnesses is the COMBINATION RULE, not the fact of hiding — Claude Code APPENDS CLAUDE.local.md after CLAUDE.md (both are in context), Codex takes AGENTS.override.md INSTEAD OF AGENTS.md. The ordered loaded list already expresses the first; {kind:"replaced"} expresses the second.

    Type Declaration

    • { by: string; kind: "replaced" }

      Another file took this directory's one slot — Codex reads at most one.

    • { kind: "on-demand"; when: "path-scoped" | "subdirectory" }

      Loaded only when the agent reads a matching file — never at launch.

    • {
          by: string;
          byScope: InstructionScope;
          key: string;
          kind: "excluded-by-settings";
      }

      A setting removed it — Claude Code's claudeMdExcludes.

      🔴 byScope FOR THE SAME REASON IT EXISTS ON superseded BELOW, and it was missing here while being right there. The patterns from .claude/settings.json and from its gitignored .local sibling were flattened into one list, so an exclusion nobody else has removed the file from committedTotal too. Measured 2026-09-22 on a repo with a 500-char .claude/rules/policy.md:

      no excludes committed=800 effective=800 excluded in settings.json committed=300 effective=300 excluded in settings.LOCAL.json committed=300 effective=300 <- wrong

      The third row is a gitignored file lowering the PUBLISHED score, which is the one thing the two-number contract exists to prevent, and it put the CLI permanently out of agreement with the browser engine that reads a GitHub tree and can never see that file.

      • Readonlyby: string

        The settings file whose pattern matched.

      • ReadonlybyScope: InstructionScope
      • Readonlykey: string
      • Readonlykind: "excluded-by-settings"
    • { by: string; byScope: InstructionScope; kind: "superseded" }

      A file of a DIFFERENT instruction family is present, and its presence turns this whole family off — Claude Code reading AGENTS.md only when no CLAUDE.md counts.

      🔴 NOT THE SAME THING AS replaced, AND CONFLATING THEM WOULD LOSE THE ONE FACT THAT MATTERS. replaced is Codex taking at most ONE file per directory out of a same-named family, so the loser is a near-copy of the winner in the same place. superseded is a cross-family switch: the superseding file may sit in a different directory (.claude/CLAUDE.md), carries entirely different content, and — the part replaced has no room for — MAY NOT BE COMMITTED.

      🔴 WHICH IS WHY byScope IS A FIELD AND NOT A LOOKUP AT THE PRINT SITE. When the superseding file is "local", a gitignored file has changed the MEMBERSHIP of the load, not just its size: a teammate on the same commit loads this file and this working copy does not. weighInstructions reads exactly this field to keep committedTotal right in that case — see WeighedFile.supersededLocallyBy. A consumer that only knew by would have to re-derive the scope from the path, which is the "second list" defect this redesign removes.

      • Readonlyby: string

        The file whose presence did it.

      • ReadonlybyScope: InstructionScope

        Whether that file is committed, or one machine's.

      • Readonlykind: "superseded"