> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pandaprobe.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Notices, mailbox & journal

> The diagnostic workspace: what a notice contains and where everything lives

## Anatomy of a notice

A `DiagnosticNotice` is everything the agent needs to diagnose one detected degradation:

```json theme={null}
{
  "id": "n-20260703T053511-f2019e57",
  "created_at": "2026-07-03T05:35:11.698999+00:00",
  "session_id": "s-demo-1",
  "turn_index": 1,
  "severity": "breach",
  "metrics": [
    {
      "name": "agent_reliability",
      "value": 0.30,
      "threshold": 0.5,
      "reason": "identical repeated tool call detected",
      "conditions": ["breach"]
    }
  ],
  "flagged_traces": ["trace-1"],
  "signal_breakdown": {
    "trace-1": { "loop_detection": 0.1, "tool_correctness": 0.2 }
  },
  "dump_path": "/harness/traces/n-20260703T053511-f2019e57.json",
  "summary": "agent_reliability=0.30 [breach, threshold 0.50]; flagged traces: trace-1",
  "signatures": ["breach:agent_reliability"],
  "status": "pending",
  "resolution": null
}
```

| Field              | Purpose                                                                                                      |
| ------------------ | ------------------------------------------------------------------------------------------------------------ |
| `metrics`          | Every alerting metric with its value, threshold, platform `reason`, and which conditions fired.              |
| `flagged_traces`   | The trace ids the platform identified as problematic — the starting point for `harness_trace_inspect`.       |
| `signal_breakdown` | Per-trace signal scores (`loop_detection`, `tool_correctness`, …) already extracted from the score metadata. |
| `dump_path`        | An immutable, verbose evaluation dump under `traces/` for the full picture.                                  |
| `signatures`       | The compact condition labels — used for de-dup, rule tags, and eval-case matching.                           |
| `resolution`       | Filled on acknowledgment: when, and which rule resolved it.                                                  |

Notice ids are timestamp-sortable and validated as safe path components (the agent supplies them to tools, and they become filenames).

## The mailbox

```text theme={null}
mailbox/
├── pending/<notice-id>.json     # awaiting the agent
├── processed/<notice-id>.json   # acknowledged, with resolution attached
└── status.json                  # {pending_count, max_severity, latest_id}
```

* The hook **posts** to `pending/`; the agent **acknowledges** via `harness_mailbox_ack`, which moves the notice to `processed/` with a `Resolution` (`acked_at`, optional `rule_id`, optional note).
* `status.json` is the cheap summary the system-context banner reads — composing the prompt never scans the directory.
* The banner carries only a count and a severity enum. **No eval-derived free text enters the preamble**; rich content stays behind explicit tool calls, where it is sanitized and framed as untrusted data.

```python theme={null}
harness.mailbox.pending()          # list[DiagnosticNotice], oldest first
harness.mailbox.read(notice_id)    # pending or processed
harness.mailbox.acknowledge(notice_id, rule_id="r-...", note="mitigated")
```

## Trace dumps

Two artifacts under `traces/`:

* `latest_eval.json` — always rewritten with the most recent evaluation, alerting or not. A cheap "what did the harness last see" probe.
* `<notice-id>.json` — one immutable dump per notice: every score with thresholds, conditions, per-trace signals, and (with `enrich_flagged_traces=true`) the worst flagged trace's TOOL spans fetched at notice time.

## The journal

`journal.jsonl` is the append-only, cross-run event log — the agent's long-term memory of its own health. The agent mines it through `harness_journal` (recent events, filterable by type) and `harness_reflect` (an assembled reflection context: recent notices, the live rule set, validation outcomes, and per-rule effectiveness counts).

```python theme={null}
harness.journal.recent(20, types=("notice", "rule_promote"))
```

The full event-type list is in [How it works](/harness/get-started/how-it-works#journal-event-types). Because the journal spans process restarts, a fresh harness over the same workspace inherits everything: rules re-enter the context, and past notices inform new baselines.

<Note>
  Everything in the workspace is plain JSON on disk. When in doubt, `cat` it — the file layout *is* the API surface for operators.
</Note>
