{
  "title": "Vigilia — Stopped",
  "description": "Every time an autonomous AI agent was stopped, and by what. Only stops written by something other than the agent count. Counts only; no command, path or conversation is published.",
  "generated": "2026-09-23T08:51:35.728Z",
  "what_counts": "A record of a control firing, written by something that is not the agent: the harness classifier, a permission rule the operator wrote, the pre-action sentinel, a CI gate. The agent’s own account of being careful does not count.",
  "pre_action": {
    "harness_classifier": {
      "stopper": "Anthropic’s auto-mode classifier in Claude Code",
      "stops": 16,
      "decision_episodes": 16,
      "by_action": {
        "run inline Python": 3,
        "other (Bash)": 2,
        "post to a third-party GitHub repository": 4,
        "other (mcp__claude-in-chrome__browser_batch)": 5,
        "write its own agent inventory": 1,
        "write the portfolio charter": 1
      },
      "by_category": {
        "Blocked by classifier": 11,
        "Stage 2 classifier error - blocking based on stage 1 assessment (usually transient — retrying often succeeds)": 2,
        "Self-Modification": 1,
        "Instruction Poisoning": 1,
        "External System Writes": 1
      },
      "graded": false,
      "why_not_graded": "Judging whether each stop was right would mean reading the conversation it acted on. This instrument does not read conversations, so it reports what was stopped and leaves the grading to anyone with the records."
    },
    "permission_rules": {
      "stopper": "Deny rules the operator wrote into the project settings",
      "stops": 37,
      "decision_episodes": 31,
      "by_action": {
        "run inline Python": 31,
        "write its own standing orders": 3,
        "write its own agent inventory": 3
      }
    },
    "sentinel": {
      "stopper": "Vigilia’s own pre-action hook, deterministic, ledger sealed into Rekor",
      "decisions": {
        "allow": 2522,
        "ask": 36,
        "deny": 9
      },
      "flags_labelled": {
        "false-positive": 29,
        "unclear": 1,
        "true-positive": 9
      },
      "decision_episodes": 30,
      "episode_note": "A row is an artifact, not a decision. Same actor, same rule, inside five minutes counts once. Published beside the row count, never instead of it — practices rule 11, credited to Claudius Maximus.",
      "self_concordance_percent": 23.7,
      "self_concordance_note": "Share of flags the hook’s own author judged real. NOT precision: there is no independent labeller, and a third party labelling the same flags could get a materially different number that nothing here would let a reader adjudicate. An independent label set is invited. The dominant false-alarm class, as its author reads it: a dangerous-looking string that was data — a test fixture, a heredoc, code that names .env — not a command.",
      "unattended": {
        "flags": 2,
        "true_positive": 2,
        "evidence_class": "SINGLE-SOURCE. Nobody watching means nobody but the sentinel’s own ledger. The Rekor seal proves the entry was not altered after it was written; it does not prove it was true when written — integrity, never accuracy. These are the rows the finding leans on most and the ones with the weakest evidence class, and the seal makes that gap less visible, not more. An independent witness would be the scheduler’s own run log for each routine; not yet checked.",
        "what": [
          {
            "ts": "2026-09-21T01:18:58.160Z",
            "actor": "journalism-thread-check",
            "decision": "deny",
            "reason": "discards uncommitted or committed work",
            "label": "true-positive"
          },
          {
            "ts": "2026-09-21T13:50:15.763Z",
            "actor": "warnings-daily",
            "decision": "deny",
            "reason": "discards uncommitted or committed work",
            "label": "true-positive"
          }
        ]
      }
    },
    "human": {
      "provable_stops": null,
      "rendered": "— (out of scope by construction)",
      "why": "Not zero: unmeasured. The operator steers the agent in conversation, BEFORE a tool call is emitted, so his interventions are not missing from the numerator — they are absorbed into the denominator. The 1,700-odd decisions the sentinel saw are already the post-steering set; the calls he prevented appear in neither column. So the better the operator, the harder he is to see: \"no oversight\" and \"oversight so far upstream that nothing needed blocking\" give the same reading here. A rate per action cannot see a control that removes actions. This instrument does not read conversation, by design, and prints a dash rather than a number it cannot have."
    }
  },
  "after_the_fact": {
    "ci_gates": {
      "citations.yml": {
        "runs": 49,
        "failures": 7,
        "last_failure_at": "2026-09-08T13:17:29Z"
      },
      "i18n-parity.yml": {
        "runs": 85,
        "failures": 18,
        "last_failure_at": "2026-09-10T19:42:33Z"
      },
      "agent-scope.yml": {
        "runs": 211,
        "failures": 3,
        "last_failure_at": "2026-09-20T16:25:09Z"
      }
    },
    "note": "A CI gate runs after the push has landed. It is a tripwire, not a lock; it cannot stop anything and is counted apart."
  },
  "rates": {
    "harness_tool_calls_seen": 6887,
    "harness_stops_per_100_calls_at_least": 0.77,
    "note": "tool_calls_seen counts tool_use blocks across every session record for this project. A resumed session can repeat earlier calls in its record, so this is an upper bound on calls made, and a stop rate computed from it is a lower bound."
  },
  "harness_extracted_at": "2026-09-22T06:06:54.378Z",
  "harness_note": "The harness half is refreshed only when a live session on the operator’s Mac runs scripts/stops-extract-harness.mjs; no runner can reach those records. The date above is the last refresh."
}
