diff --git a/examples/06-whisper-prompt.md b/examples/06-whisper-prompt.md index 5292ff0..45f59d8 100644 --- a/examples/06-whisper-prompt.md +++ b/examples/06-whisper-prompt.md @@ -65,9 +65,11 @@ options. } ``` -The Coordinator routes this with the **`whisper` channel**: typically -an interrupt-style notification in the human's client, distinct from -normal review queues. The deadline starts ticking. +The Coordinator records the whisper, and its 60-second deadline runs +from this ask. Getting the question in front of Alice, for example as a +notification in her client, is up to the deployment: a Coordinator has +no delivery layer of its own (see +[SPECIFICATION.md §15.1](../SPECIFICATION.md#151-mandatory-protections)). --- @@ -102,8 +104,8 @@ whisper and the answer are recorded in the chain. ## 6.4 What if no one answers? -Whispers are deadline-bound. If Alice had been away from her desk, at -T+60s the Coordinator would emit: +Whispers are deadline-bound. If no answer is recorded within 60 +seconds, the first lapse check after the deadline records: ```json { @@ -125,9 +127,12 @@ T+60s the Coordinator would emit: } ``` -The agent proceeds with the default. The lapse is recorded as a -first-class evidence entry, so the auditor can see exactly when a -human declined to be reachable for a given decision. +The agent proceeds with the default. The lapse is an entry on the +chain, so an auditor can see that no answer came in time and which +default was applied. It does not say why: a person +who saw the question and let it lapse and a person who was never +notified leave the same record, because delivery is left to the +deployment (see [`profiles/whisper.md`](../profiles/whisper.md) §4). --- @@ -157,9 +162,9 @@ task's `complete`. responsiveness. - **Whisper analytics.** "What fraction of cancellations involve a whisper?" is a single audit query. -- **Visible accountability for non-response.** A lapsed whisper is - recorded with the timestamp and the default applied; nothing - silently disappears. +- **Visible lapses.** A lapsed whisper is recorded with its time and + the default applied, so an unanswered question stays on the record. + The record shows only that no answer arrived in time. Move on to [`07-handoff-shift-change.md`](./07-handoff-shift-change.md) for transferring an in-progress task between humans. diff --git a/packages/chap-analytics/chap_analytics/briefs.py b/packages/chap-analytics/chap_analytics/briefs.py index 5c6666d..35d22c8 100644 --- a/packages/chap-analytics/chap_analytics/briefs.py +++ b/packages/chap-analytics/chap_analytics/briefs.py @@ -301,7 +301,7 @@ def whispers(f: Frames) -> Brief: if not r["sufficient"]: decision = "Too few resolved questions to judge; the lapse rate will settle as more are asked." elif r["lapse_rate"] > 0.25: - decision = "More than a quarter lapse: the default answer is deciding those questions. Put the answer in the task input, or route whispers to whoever is at the desk." + decision = "More than a quarter lapse: the default answer is deciding those questions. Put the answer in the task input, check that the questions reach the people asked, or address them to someone who can answer in time." else: decision = "Questions are being answered in time." return Brief("whispers", "Whether agents get answers", head, text, decision, bool(r["sufficient"]), w) diff --git a/packages/chap-analytics/chap_analytics/charts.py b/packages/chap-analytics/chap_analytics/charts.py index fef47b5..1386b36 100644 --- a/packages/chap-analytics/chap_analytics/charts.py +++ b/packages/chap-analytics/chap_analytics/charts.py @@ -629,7 +629,8 @@ def whispers(w: pd.DataFrame, by: str = "asker") -> Chart: """Lapse rate per asker with intervals. Takes :func:`stats.whispers` output.""" name = "whispers" q = "How often do agents have to ask, and does anyone answer in time?" - d = "A high lapse rate is a question the task input should have answered, or a reviewer who is never at the desk." + d = ("A high lapse rate points at questions the task input should have answered, or at questions that " + "reach no one in time. The chain records only that no answer arrived before the deadline.") if w.empty: return _empty(name, "Whispers that lapsed", q, d, "No whispers in this chain.") key = by if by in w.columns else None diff --git a/packages/chap-analytics/docs/example_report.html b/packages/chap-analytics/docs/example_report.html index 786b24d..c73dcd5 100644 --- a/packages/chap-analytics/docs/example_report.html +++ b/packages/chap-analytics/docs/example_report.html @@ -701,7 +701,7 @@