Deliver on a decision, not on a resolution
See a queued decision re-evaluated as a new revision when a meeting ends, a timing table that cannot raise urgency into evidence, and two receipts that never stand in for each other.
When should the AI speak? The chapter’s answer is a table, and the table’s first rule is what it is not allowed to touch: delivery takes no resolution and no relevance as input, so a more urgent item can never become a better source, and a timing change can never rewrite an earlier decision.
Run it
git clone https://github.com/ernanhughes/project-language.git
cd project-language
git checkout 329660f679a5a87831f91fe1430c20ac9360dda8
npm ci
npm run example:radarOne invented afternoon. The model is a scripted stand-in; the human side of the receipt is a call to a UI function, not a screen.
Expected outcome
The same decision, re-evaluated after the meeting ends, becomes a new revision rather than an edit:
...
attn:contradiction r1 PENDING/BRIEF/QUEUE -> r2 PENDING/BRIEF/NOW -> r3 DELIVERED/BRIEF/NOW
attn:lossy r1 PENDING/SUMMARY/QUEUE -> r2 PENDING/SUMMARY/NOW -> r3 DELIVERED/SUMMARY/NOW
attn:mechanism r1 PENDING/BRIEF/AVAILABLE -> r2 PENDING/BRIEF/AVAILABLE
The BRIEF stayed a BRIEF while QUEUE became NOW. The mechanism paper stayed AVAILABLE: a calendar change does not promote an unresolved relation.Two receipts, and neither establishes the other:
...
can the model receipt show that the contradiction was presented to a person? false
can the human receipt show it? true (an interface call, not a screen)
did the person notice it, use it, or benefit? unknown. Nothing here observes any of them.And the timing table is reported as reasons, not as a score:
...
[urgency · computed_rule · after-break] it can wait for the next break and still arrive before the deadline
[interruption_cost · observed_context · calendar_state] the person is in a meeting
[timing · computed_rule · medium-urgency-high-cost] held for the next break; it still arrives before the deadlineDelivery takes no resolution
The timing table’s inputs are a deadline, a context and two declared flags. There is no resolution in it, so urgency cannot raise evidence.
/**
* The delivery table. Input has no resolution, no relevance, no confidence: urgency does not raise
* evidence, and timing cannot rewrite earlier decisions.
*/
export function schedule(i: TimingInput): Timing {
assertContext(i.context);
const u = urgencyOf(i); const c = costOf(i);
const reasons = [...u.reasons, ...c.reasons];
const brk = ctxVal(i.context, "next_break_at") ?? null;
const digest = ctxVal(i.context, "digest_at") ?? null;
let mode: DeliveryMode; let after: string | null = null;
if (i.non_interruptive) { mode = "AVAILABLE"; reasons.push(R("timing", "declared_policy", "non-interruptive", "declared non-interruptive: kept within reach, not competing for attention")); }
else if (c.cost === "LOW") {
if (u.urgency === "LOW") { mode = digest ? "DIGEST" : "QUEUE"; after = digest; reasons.push(R("timing", "computed_rule", "low-urgency-low-cost", digest ? "waits for the scheduled digest" : "queued for the next natural break")); }
else { mode = "NOW"; reasons.push(R("timing", "computed_rule", "cost-low", "surfacing now costs little and waiting would not help")); }
} else if (u.urgency === "HIGH") {
if (i.delay_exceeds_interruption) { mode = "NOW"; reasons.push(R("timing", "declared_context", "delay-exceeds-interruption", "declared: the cost of delay is larger than the cost of interrupting")); }
else { mode = "QUEUE"; after = brk; reasons.push(R("timing", "computed_rule", "high-urgency-high-cost", "interrupting costs more than the delay: held for the nearest break")); }
} else if (u.urgency === "MEDIUM") { mode = "QUEUE"; after = brk; reasons.push(R("timing", "computed_rule", "medium-urgency-high-cost", "held for the next break; it still arrives before the deadline")); }
else { mode = digest ? "DIGEST" : "AVAILABLE"; after = digest; reasons.push(R("timing", "computed_rule", "low-urgency-high-cost", digest ? "gathered into the digest" : "kept available, not surfaced")); }
return { urgency: u.urgency, cost: c.cost, mode, deliver_after: after, reasons };
}And the context it reads is declared or observed, never inferred. An unknown value is refused rather than read as permission to interrupt:
export const CONTEXT_KEYS = ["calendar_state", "focus_mode", "next_break_at", "digest_at", "do_not_disturb"] as const;
export type ContextKey = (typeof CONTEXT_KEYS)[number];
/** Allowed values. Anything else is refused: an unknown value is not read as permission to interrupt. */
export const CONTEXT_VALUES: Readonly<Partial<Record<ContextKey, readonly string[]>>> = {
calendar_state: ["in_meeting", "free", "unknown"],
focus_mode: ["normal", "blockers_only"],
do_not_disturb: ["on", "off"],
};
export interface ContextFact { key: ContextKey; value: string; origin: "declared_context" | "observed_context"; ref: string; at: string }
/** An inferred state, an unknown key, or a fact with no ref is refused. Mood, stress and boredom have no key. */
export function assertContext(facts: readonly ContextFact[]): void {
for (const f of facts) {
if (!(CONTEXT_KEYS as readonly string[]).includes(f.key)) throw new AttentionError("CONTEXT_KEY_NOT_ALLOWED", `${String(f.key)} is not a declared or observable context key`);
if ((f.origin as string) !== "declared_context" && (f.origin as string) !== "observed_context") throw new AttentionError("CONTEXT_ORIGIN", `${f.key}: origin ${String(f.origin)} is not declared or observed`);
if (!f.ref.trim()) throw new AttentionError("CONTEXT_NO_REF", `${f.key} has no ref`);
parseTime(f.at, `${f.key}.at`);
const allowed = CONTEXT_VALUES[f.key];
if (allowed && !allowed.includes(f.value)) throw new AttentionError("CONTEXT_VALUE_NOT_ALLOWED", `${f.key}=${JSON.stringify(f.value)} is not one of ${allowed.join(", ")}`);
if (!allowed) parseTime(f.value, `${f.key}.value`);
}
}Mechanism and limitations
Documented: the delivery table, the context keys and their allowed values,
and the revision lifecycle are in core/radar/src/attention/delivery.ts.
Observed: the run above. A queued decision became a new revision when the
meeting ended, keeping its BRIEF; the unresolved mechanism paper stayed
AVAILABLE across a calendar change; the human receipt could show presentation
and the model receipt could not; and noticed, used and helpful stayed
unknown throughout.
Not shown. The urgency and interruption-cost table is a declared policy, not a measured one, and whether it is the right policy for a person is not established. Nothing here observes a screen, a person, or attention: the human receipt records an interface call. An unresolved relation is never pushed in this implementation, which is a tested boundary of the scripted example rather than a general theory of urgency. There is no optional override for unconfirmed deployment alerts, and none is claimed.
Understand this example
Copy this prompt into your AI tool. No code runs here.
Apply this example
Copy this prompt into your AI tool. No code runs here.