---
name: "convention-hold-windows"
type: convention
description: The first-class convention for Aled's calendar hold windows — the reserved recurring blocks Aide books his committed work into. Names the live lanes and their scope (work.Focus and work.Overflow for cycle-goal work, deep and interruptible; work.MrP for editorial; work.Apps and work.MBN for the venture lanes; work.Operators for the weekly per-operator session; work.Unblock for post-stand-up unblockers; the fixed daily rituals; hold.Calls on request only), bookability as an exclusion not an enumeration (every work.* block is bookable, personal.* never, anything else busy is worked around), the capacity read that subtracts a Busy overlap from an occurrence as an absence zeroes a day, and the window lifecycle — declared, filled, consumed. Read before booking or reading hold time, before adding a window, or when reasoning about Aide's calendar scope. Aide is the single calendar writer; referenced by agent-aide and skill-time-block.
license: CC BY-NC-SA 4.0
---

# Hold windows

A **hold window** is a reserved, recurring block on Aled's calendar that Aide is allowed to book his committed work into. The windows are the standing structure of his week: the Owner declares them once as recurring events, Aide fills each week's occurrences with the specific blocks the cycle needs, and nothing outside a window is ever touched. This convention makes the windows first-class — named, lane-scoped, and referenced by the Aide skills — rather than a single `work.Hold` assumption baked inside `agent-aide` (APP-598, APP-578).

This is the tool-agnostic model of the windows. `agent-aide` and `skill-time-block` reference it; `convention-linear` holds any Linear binding; the Google Calendar mechanics live in the skills.

## The named windows and their lane scope

Each live window is a lane. Allocation into a live window is therefore a **routing decision** — which window does this item belong in — not one queue against one window. **Most of this table is now retired:** the Owner ruling of 2026-10-05 retires the windows that carried cycle-goal work and keeps only the rituals and the named holds, so the day shape is a convention rather than a set of calendar events. Read *The hold windows are retired* below before reading the rows — a row marked **retired** records a deliberate decision, not a gap to be fixed.

| Window | Lane — what may be booked into it | Owner event |
|---|---|---|
| `work.Focus` | **Retired as a window** (Owner ruling, 2026-10-05 — APP-2042, APP-1883). What it held is now a convention: the biggest, most complex, most important work is attempted in the morning, with no hold and no event behind it | **retired** — no event, by decision. Absent from the calendar on the 2026-10-05 read across the 2026-10-05 and 2026-10-12 weeks (**reported**). Formerly Mon–Thu 10:00–12:00 |
| `work.Overflow` | **Retired as a window** (Owner ruling, 2026-10-05 — APP-2042, APP-1883). What it held is now a convention: the afternoon is for prioritised work but overflow in character — reviews, unblocking, small Owner tasks, and the previous day's unfinished work if it is still important | **retired** — no event, by decision. Absent on the 2026-09-30, 2026-10-05 and 2026-10-12 reads (**reported**). Formerly Tue–Thu 14:30–16:30 |
| `work.MrP` | Editorial: Mr Pritchard writing and content work. **Thursday mornings** (Owner ruling, 2026-10-05 — APP-2042, APP-1883) | live — **reported** Thu 10:00–12:00, titled `work.MrP + Promotion` on the 2026-10-05 and 2026-10-12 weeks. Formerly Mon 14:30–16:30; the Monday occurrence is gone, and the Thursday event is the intended occupant of that slot rather than drift — which answers APP-1883's second ask directly |
| `work.Apps` | **Retired as a window** (Owner ruling, 2026-10-05 — APP-2042, APP-1883). Apps portfolio work takes its place in the day-shape convention like any other prioritised work, with no lane of its own | **retired** — no event, by decision. Absent on the 2026-10-05 and 2026-10-12 reads (**reported**). Formerly Fri 14:30–16:00 |
| `work.MBN` | **Retired as a window** (Owner ruling, 2026-10-05 — APP-2042, APP-1883). BARA / MBN venture work takes its place in the day-shape convention like any other prioritised work, with no lane of its own | **retired** — no event, by decision. Absent on the 2026-10-05 and 2026-10-12 reads (**reported**). Formerly Fri 10:00–12:00 |
| `work.Planning` | Cycle and week planning | live — **observed** Fri 16:00–17:00 |
| `work.Unblock` | **Retired as a window, kept as a gap** (Owner ruling, 2026-10-05 — APP-2042, APP-1883). Stand-up follow-ups and queue unblockers are still real, but held as **a gap outside focus time with no calendar event behind it** — held by the Owner's intent rather than by a placeholder. It was already Owner-filled and never Aide-filled (Owner correction, Aled 2026-09-23 — APP-1706), so nothing Aide was permitted to do changes; what changes is that there is no occurrence to read for capacity. **Two decisions per session, at estimate 1 (15 minutes) each** still sizes the gap — see *The `work.Unblock` cap counts decisions, not tickets* below. Whether the gap has any representation at all is an open Owner question (APP-2042) | **retired** — no event, by decision. Absent on the 2026-10-05 and 2026-10-12 reads (**reported**). Formerly Mon–Fri 09:30–10:00 (Owner-created 2026-08-17) |
| `work.Operators` | Operator sessions: the weekly per-operator strategic session (the operator layer books here via Aide), 30 minutes. **Held, but cycling through a rotation** rather than one operator per weekday (Owner ruling, 2026-10-05 — APP-2042). The rotation is `skill-operating-loop`'s rota to express; this table does not restate it, and a weekday with no occurrence is the rotation working rather than a missing window | live — **observed** Mon–Fri 13:30–14:00 as a series (Owner-created 2026-08-10, **reported**; **not to be deleted**), occurring **Mon, Thu and Fri only** on the 2026-10-05 and 2026-10-12 weeks (**reported**) |
| `work.Standup` | Fixed daily ritual, opening the day. Bookable inside spare capacity, **never displaced** | live — **observed** Mon–Fri 09:00–09:30 |
| `work.Close` | **Retired as a window** (Owner ruling, 2026-10-05 — APP-2042, APP-1883). The day's close is no longer a held event. `work.Planning` Fri 16:00–17:00 is the one surviving end-of-week ritual, and `work.Standup` is the one surviving daily one | **retired** — no event, by decision. Absent on the 2026-10-05 and 2026-10-12 reads (**reported**). Formerly Mon–Thu 16:30–17:00. Basis: the ruling's blanket clause plus the absence, not a clause naming this lane — see *The hold windows are retired* below |
| `hold.Calls` | Reserved call time. **On request only** — Aide places a call here when the Owner asks for one, and never sweeps into it on the routine capacity fill, because that time is what Calendly offers out | live — **observed** Mon–Fri, twice daily, 12:00–12:30 and 14:00–14:30 |

Every figure above marked **observed** was read from the Owner's calendar on 2026-09-09 over the week of 2026-09-21; every one marked **reported** comes from the note that requested the change and has not been independently confirmed. Two lanes are **declared but not bookable** and are listed here so the assertion below resolves them rather than reporting them as unmatched every run: **`personal.Fitness`** (observed Mon–Fri 12:30–12:45) and **`personal.Lunch`** (observed Mon–Fri 12:45–13:30). Both are marked Free on the calendar and are nonetheless off limits — transparency is not the test, the prefix is.

**`work.Focus` and `work.Overflow` share one admission test and differ only on depth** (Owner ruling, 2026-09-08, APP-1162). Both admit work aligned to the cycle goal; Focus is deep and uninterrupted, Overflow is interruptible. Overflow is not leftovers and not extra focus capacity — it is the rest of the goal work in a mode that tolerates switching. Unblock spillover and review work qualify for Overflow because they are non-focus tickets on the cycle goal, not because they are blockers; a simple task that is not on the goal has no claim on the window at all. `work.Hold–Overflow` as "an extension of `work.Hold`" is retired as a framing, not merely renamed.

The set grows as new lanes appear; a new window is a new row here plus the Owner creating its recurring event. Adding a window costs a row and an event, not a change to Aide's guardrail.

**The hold windows are retired — the day shape is a convention, not calendar events** (Owner ruling, 2026-10-05 — APP-2042, APP-1883, APP-1761). Six declared lanes stop being windows: `work.Focus`, `work.Overflow`, `work.Unblock`, `work.Close`, `work.MBN` and `work.Apps`. What survives on the calendar is the rituals and the named holds — `work.Standup`, `work.Operators` on its rotation, `work.MrP` on Thursday mornings, `work.Planning`, `hold.Calls` — plus `fractional.Muse` blocked out Tue and Wed, which is a declared non-`work.` lane and therefore unavailable under *A declared lane that is neither `work.*` nor `personal.*` is unavailable* below rather than a window to book into.

In the Owner's own words, transcribed from the session of 2026-10-05:

> "we said that weren't going to have the windows, and allow us more flexibility to shift things around. that means that stand up stays, but unblock becomes a gap we hold outside of focus time but no calendar event to hold it. same with focus, no hold anymore just a convention that we try and complete the biggest most complex most important work in the morning. the afternoon session are then for prioritised work but more about overflow of things that need reviewing, unblocking, small tasks for me, any things that didn't get done from the day before (if they are still important). we said that we would block muse out for Tuesday and Wednesday. Mr P is for thursday mornings and operator sessions are held but cycle through a rotation."

**The day shape, as a convention.** Mornings are for the biggest, most complex, most important work. Afternoons are for prioritised work but overflow in character — reviews, unblocking, small Owner tasks, and the previous day's unfinished work if it is still important. The post-stand-up unblock is a gap held outside focus time with no event behind it.

**The reason is flexibility, and it is the point rather than a side effect.** Fixed windows made the week rigid; removing them lets things shift. A row marked **retired** is therefore **not** the "row with no live event" mismatch the assertion rule exists for, and must never be reported as one — the rows carry `retired` precisely so the assertion resolves them instead of raising an Owner action every run. This ruling was given twice and captured neither time (APP-2042), and the cost of the second miss was the Owner repeating a decision he had already made to a run that had re-escalated it.

**Figure basis.** The ruling reaches canon as Aide's transcription of a session, on APP-2042's body and APP-1883's comment of 2026-10-05 — **reported**, not observed. The absences, the `work.MrP + Promotion` occupant and the Mon/Thu/Fri Operators pattern come from the 2026-10-05 weekly `task-aide-loop` run across the 2026-10-05 and 2026-10-12 weeks — also **reported**. The 2026-09-09 observed figures still stand for the lanes that remain live. `work.MBN`, `work.Apps` and `work.Close` are not named individually in the ruling; their retirement rests on "we said that weren't going to have the windows" plus their absence on both weeks read.

**Left standing deliberately.** *The `work.Unblock` cap counts decisions, not tickets* below is unchanged: it governs the unit admitted to the unblock gap, not the existence of a placeholder event, so retiring the event does not retire the cap. **What Aide does now — render the convention as a proposed morning and afternoon queue, or stop writing the calendar beyond the stand-up and the operator rotation — is an open Owner question and is not settled here** (APP-2042). This convention records the shape of the week; it does not decide Aide's remit against it.

**`ops.Hold` is retired** (Owner ruling, 2026-09-02, APP-852 / APP-922). It was declared 13:30–14:30 over the top of `work.Operators` and the editorial window and never had reachable capacity; `work.Operators` is what the Owner created and uses, and the 30-minute session default in `skill-operating-loop` step 8 falls out of its length. An operator session is booked into `work.Operators` and nowhere else. The naming exception this paragraph used to record is gone: under the old scheme `work.Operators` was the odd one out for not carrying the `work.Hold` prefix, and every lane now sits under `work.` on equal terms.

**The `work.Unblock` cap counts decisions, not tickets (Owner ruling, 2026-09-14, APP-1439).** The unit admitted to the window is the **decision**. Tickets that resolve in the same sitting — same surface, same context, one decision — bundle under it and consume one slot between them. Counting tickets penalises correct hygiene: splitting a decision into a fix and the sibling question it raised is right, and under a ticket count it doubles the item's apparent cost and displaces work already scheduled for the window. The bundle is named by whoever routes the item into the window — the stand-up — and recorded as one line in the booking comment naming every ticket the slot covers, which is the record a dispatched occurrence already owes under *A dispatched session's occurrence is accounted, not just consumed*. A bundle whose tickets turn out to need separate sittings is two items, and the second returns to the queue rather than overrunning the window. (Worked case: APP-1413 and APP-1438 were one decision about the same GitHub account, read as a full window, and appeared to displace the Luna credentials — APP-1034 / APP-58 — APP-1439.)

**A window is not usable until both exist.** A live event with no row here, or a "to create" row against an event that is already live, is a reportable gap — surfaced once by the first run that sees it, not re-derived per run. The Owner declares a window in the tool the moment he needs it, which is right; the lifecycle assumed the row followed and nothing detected when it did not (`work.Operators` and `work.Unblock` both ran for weeks invisible to Aide in both directions — APP-922).

**Windows carry a working-day cadence.** A window does not fall on every calendar day. Since the 2026-10-05 retirement the live set runs `work.Standup` Mon–Fri, `hold.Calls` Mon–Fri twice daily, `work.Operators` on its rotation (Mon, Thu and Fri on the two weeks read, **reported**), `work.MrP` Thu and `work.Planning` Fri. The retired lanes carry no cadence at all, so the Mon–Thu, Tue–Thu and Fri shapes this paragraph used to record are history and must not be used to resolve a day. "The next window occurrence" is still the next day that actually **carries a live window**, not the literal next calendar day, and a weekend carries none. Aide's daily loop used this to define "tomorrow" (`skill-time-block`, `task-aide-loop`; APP-872) — but under the convention a day no longer has to carry a window for work to be done on it, so how that loop resolves "tomorrow" without windows is `skill-time-block`'s to restate and is not settled here.

## Read by prefix, write by exact name

The read and write sides are deliberately asymmetric, so capacity can widen without loosening the safety guardrail:

- **Bookability is an exclusion, not an enumeration** (Owner decision, Aled 2026-09-08, APP-1162). **Every `work.*` block is bookable** — including the fixed rituals `work.Standup` and `work.Close`. **`personal.*` is off limits**: no reads for capacity, no writes. **`hold.Calls` is bookable on request only** and is never touched by the routine capacity fill. **Anything else marked Busy is worked around** — meetings the Owner books himself, and invitations he accepts — read as occupied, never ignored and never overwritten. This replaces the old naming-marker mechanism rather than renaming it: under the previous scheme `work.Hold` *was* the bookability marker, so the answer was derivable from the event name; the new lane names carry no marker and need none. The rule is rename-proof — a future `work.Whatever` is bookable the day it appears, with no canon edit — which is the whole point. The rename of 2026-09-08 collapsed Aide's readable capacity: of the 30 hours of `work.*` on the calendar as read on 2026-09-09, the retired prefix list matched 5, so roughly 25 hours of declared capacity went invisible in a single afternoon, and the write set lost delivery and editorial entirely.
- **One `work.*` lane is read but never filled: `work.Unblock`.** The exclusion above is deliberately short, and this is its second member. `work.Unblock` is the container for stand-up items that need more time than the stand-up has, and the Owner decides its content **live, at the end of the stand-up he runs** — so an item Aide selects the evening before was not carried out of a stand-up that had not happened. Aide **reads** the occurrence: it is `work.*`, so its span counts in the capacity total and in the overcommitment signal, and dropping it from the read would understate the Owner's committed time. Aide does not **place** into it on the routine fill, exactly as with `hold.Calls`, and its role there is to record what he places, not to pre-select it. A daily or weekly pass that finds a Free `work.Unblock` occurrence reports its capacity and books nothing. (Worked case: the 2026-09-23 EOD `task-aide-loop` run followed the standing-lane instructions literally and booked A1-429 and MRP-12 into Thursday 24 September's `work.Unblock` from the committed-cycle sized worklist; the Owner corrected it in session and the booking was reverted to the bare placeholder — APP-1706.)
- **Read capacity by prefix match on `work.*`.** Any Free `work.*` event counts as available hold time, so a lane the Owner adds by hand is seen rather than silently stranded and the overcommitment signal is not inflated by a blind spot (APP-759). `hold.*` and `personal.*` are excluded from the capacity read. **Transparency is not the test.** As read on 2026-09-09, `personal.Fitness` and `personal.Lunch` are both marked Free, so a filter on Free alone would book work into the Owner's lunch; the prefix is what excludes them, and the Free filter only removes the meetings.

- **A declared lane that is neither `work.*` nor `personal.*` is unavailable, whatever its transparency.** The exclusion above answers bookability and leaves availability open for a fourth case: a standing lane the Owner names with some other prefix and marks **Free**, as he marks every standing lane on this calendar. *Anything else Busy is worked around* does not reach it, because it is not Busy; *`personal.*` is off limits* does not name it; and being outside `work.*` makes it invisible to the capacity read rather than protective. So **a recurring lane whose prefix is neither `work.` nor `personal.` is read as occupied, and its span is subtracted from any overlapping `work.*` occurrence exactly as a Busy overlap is** (APP-1164) — never booked into, never counted as capacity, and reported once against the window table like any other unmatched lane rather than every run. This is the exclusion-not-enumeration principle (Owner decision, Aled 2026-09-08, APP-1162) applied to the availability side rather than the bookability side, and it fails safe: an unrecognised prefix costs capacity that was never Aide's to book. (Worked case: `fractional.Muse`, created 2026-09-28 08:31Z, Tue and Wed 09:00–17:00, `transparency: transparent` — plainly committed fractional client time, matching none of the three cases and therefore reading as fully free. It was harmless only because no `work.*` occurrence existed on a Tuesday or Wednesday that week; with one present, bounded auto-hold (APP-828) would have booked delivery work across a client day unattended — APP-1811.)
- **Read capacity with a prefix filter and a bounded range, never an open multi-week window.** A capacity read is a `list_events` call, and an unbounded one overflows: a 14-day open range returned ~81,600 characters, persisted to a host temp path the sandbox cannot reach while the call reported success (`skill-dispatch-run`, *Any connector read can silently return nothing usable*). Read hold capacity with a `fullText` filter on the `work.` prefix and a range no wider than the booking horizon actually needed — one week at a time, paged — so the read returns the hold events and nothing else. A read that came back empty after a wide range is an overflow to recover with the Read tool, not an empty calendar. (Worked case: A1-362, Aide's sizing of the Meirion cutover chain, 2026-08-18 — APP-1016.)
- **Write into `work.*` events only, and never into `personal.*`.** Aide writes blocks inside `work.*` events; it writes into `hold.Calls` only on an explicit Owner request; it writes into `personal.*` never. The fixed rituals `work.Standup` and `work.Close` may be **filled** in spare capacity and are never **displaced** — the drain's ruling on the one detail the Owner's decision left open, taken this way because the standing guardrail below already says Aide never moves, deletes or reschedules an event, and filling inside one does not touch it.
- **The window table is a capacity-accounting record, not the bookability test.** A window missing from the table is still bookable if it is a `work.*` event; the row exists so capacity can be reported per lane. **Assert the declared set against the live calendar at the top of each run and report a mismatch** — a lane on the calendar with no row, or a row with no live event — **once, as an Owner action, never weekly as a capacity signal**. A rename is silent by construction, and this is the second time a calendar change left Aide blind (APP-922 was the first, APP-1162 the second); the assertion is what makes the class self-detecting rather than dependent on someone noticing. The assertion resolves the two `personal.*` lanes recorded above, so an off-limits lane is not reported as an unmatched one every run.

If no Free window event can be found for a lane **the table above marks live**, stop and tell Aled the window is missing — never fall back to booking elsewhere on the calendar. This does not apply to a lane marked **retired**: there is no event to find, by decision of 2026-10-05, and a run that reports a retired lane as a missing window is reporting a decision as a defect and will do so forever.

## The window lifecycle — declared, filled, consumed

A window is a placeholder with a lifecycle, not a permanent fixture:

1. **Declared** — the Owner creates the recurring window event. Aide cannot manage a window that does not exist.
2. **Filled** — Aide books the week's real blocks inside that occurrence. Within a bounded envelope — committed-cycle items that `skill-attention-sweep` has already sized, booked inside the exact-named windows — Aide may fill **unattended** (bounded auto-hold, APP-828); outside that envelope it proposes and waits for Aled's confirmation. The graduation changes *when* Aide writes, never *where*: the write scope stays exactly as below.
3. **Consumed** — once a given occurrence has been filled, the empty container has done its job. **Aide may delete that single filled occurrence** so the calendar reads as actual work rather than a reservation plus the work inside it.

The delete is a **narrow, named exemption** to Aide's "never moves, deletes, or responds to other events" guardrail — the boundary that makes an agent with calendar write access safe — and it is bounded precisely:

- **Single occurrence only, never the series.** These are recurring events; deleting the series removes every future window and breaks every later run. Only the one occurrence just filled may be removed.
- **Gated on a successful write.** The delete is the closing step after blocks are written and confirmed for that occurrence — never a standalone tidy pass.
- **Unfilled occurrences survive.** If Aide fills two of three occurrences (the worklist ran out, or the week is light), the unfilled ones stay. The rule is per-occurrence and gated on "this occurrence now contains booked work", not per-week.
- **The general rule is intact.** "Never moves/deletes/responds to other events" still holds for everything that is not a hold occurrence Aide has just filled. The exemption is named, not a softening.

Recoverability: once an occurrence is deleted the reservation is gone, but the booked blocks now hold the time, so the reservation has served its purpose.

**A partial fill is not a consume — and the placeholder's `work.*` name is load-bearing, so it is never renamed away.** The lifecycle has three states and one consuming action, a delete. A fourth shape exists in practice and canon did not sanction it: the occurrence is filled for *part* of its declared span and the bare placeholder is **retitled** to the work that went in it. That breaks the read, not the write. `work.*` is the prefix the capacity read matches on, so a retitled occurrence returns **no row at all** — a `fullText: "work."` read of the day finds nothing for that lane — and the remainder is then neither readable Free capacity nor an acknowledged zero. The run has no rule-following way to tell "thirty minutes of real spare capacity" from "this occurrence is fully spent", and the rule it does reach is *If no Free window event can be found for a lane, stop and tell Aled the window is missing*, which refuses real capacity and reports a window that is not in fact absent. So: **fill inside the occurrence, never over its name.** Write the booked block as its own event inside the bare `work.*` placeholder and leave the placeholder in place; consume — delete — only where the fill takes the **whole** declared span. Reconstructing the span from the window table is not the remedy: the table is a capacity-accounting record and not the bookability test, and making it load-bearing for a read contradicts that. Where an occurrence is found already renamed, treat the stamped block's span as booked (it is still found by its durable identifier, APP-898) and report the occurrence once as a lane whose placeholder has gone, in the same once-not-weekly form as an unmatched lane. (Worked case: Thursday 24 September 2026's `work.Focus`, declared 10:00–12:00, carried an `[aide-block:A1-DE:W39:A1-452,A1-433]` block over 10:00–11:30 and was titled "Agents homepage: A1-452 motion review → A1-433 cutover call"; the same day's `work.Overflow` was a full-span fill and showed none of this. The 2026-09-23 EOD run correctly refused the 11:30–12:00 remainder as unbookable — APP-1705.)

### A dispatched session's occurrence is accounted, not just consumed (APP-1328)

The lifecycle above ends at the calendar. That is enough for a routine cycle-goal block, where the ticket's own state moves and the stand-up reads the move. It is not enough for an **ad hoc dispatched session** — a `work.Unblock` or host session booked against a named runbook or ticket set — because the only thing that changes is the calendar, and a deleted occurrence and a session that never happened look identical from Linear. So a dispatched occurrence carries two extra obligations, both cheap.

* **The dispatch names its targets.** A booking made against a dispatch ticket records, in the booking comment, the **ticket identifiers the session is for** — not the runbook's title, the tickets. A session booked against "APP-824's host-lane runbook" is accounted for only if the comment says which of APP-929 / APP-932 / APP-915 the slot covers. This is what makes the closing read a lookup rather than an inference.
* **A spent slot needs a record on a target, and a reservation is not one.** Before the next stand-up treats the slot as spent, **one** of the named targets carries either a state change or a comment saying what happened — including the explicit "did not run". The delete at *Consumed* is evidence the occurrence was **filled**, never evidence the work was **done**: a filled-then-deleted occurrence with no record on any target is read as **unconfirmed**, not as spent.
* **Unconfirmed is reported once, then the slot is re-offered.** The stand-up that finds a dispatched occurrence with no record on any target reports it once — *"the [date] [window] session against [tickets] left no record; either it did not run or it made no progress"* — and treats the work as still needing a slot, rather than silently counting the time as spent and moving on. Report once per occurrence, never daily: this is the same once-not-weekly discipline as an unreachable or unavailable window above.

The failure this closes is a **read** failure, not a write one, and it does not widen Aide's write scope: the closing record is a comment on a target ticket, and where nobody writes one the correct behaviour is to report the absence, not to infer an outcome. (Worked cases: the 2026-09-04 host session pencilled against APP-982's runbook — recorded in the 09-09 entry as *"either that session did not happen or did not finish"* — and the 2026-09-10 `work.Unblock` slot booked 10:45–11:00 UTC against APP-824's runbook covering APP-929, where the booking comment on APP-1276 recorded the calendar action and no target ticket recorded anything. Two occurrences, one class — APP-1328.)

### A window that exists but offers no capacity — one rule, three faces (APP-922, APP-1029, APP-1164)

A busy week is handled by `skill-time-block`'s hand-booked-lane rule: read what is there, never overwrite, surface the capacity signal. Two other cases look like a busy week and are not, and both are **reported once as an Owner action, never weekly as a capacity signal**. **Unreachable by overlap:** a declared window wholly covered, on every occurrence and by construction, by standing events Aide may not touch is a **structural fault in the window's declaration** — it cannot do its job as declared, and reporting it "full" each week hides that (`ops.Hold` offered 0m of its declared 60m on every occurrence from 2026-08-13, covered by `work.Operators` and `mrp.Hold`; A1-342 could not be placed). **Unavailable by absence:** a hold occurrence overlapped by an all-day leave or out-of-office event is **zero capacity** — the Owner's availability is a first-class booking input and its home is the calendar, where Aide already reads; a prefix-matched Free window during an absence otherwise reads identically to one in a working week, and under bounded auto-hold that books Owner decision work into a holiday unattended (19–28 Aug 2026 leave existed only as a Linear comment; nothing was booked only because an unrelated freshness test failed — APP-1029). Report an absence once at its start, not daily as a full lane. **Busy inside the day:** a Busy event overlapping a window occurrence **subtracts its duration from that occurrence's capacity**, in the same way an all-day absence zeroes it — absence is the whole-day case of this rule, not a separate one. The capacity read is a prefix match filtered to Free events, so a real meeting carries no window prefix and never enters it: an occurrence sitting under a live call reads as fully available, and under bounded auto-hold that books delivery work straight across it. So read the occurrence's **remaining** capacity — its declared span less any Busy event overlapping it, and less anything already booked inside it — and place work only in what is left; where nothing usable is left, surface it as a capacity signal rather than forcing work in, exactly as a hand-booked full lane is handled (`skill-time-block`, APP-828). None of the three faces loosens the guardrail: this is a read rule, and Aide still never moves, shortens, deletes or responds to the overlapping events. (Worked case, observed on the calendar 2026-09-09: `Ann x Aled` recurs Tuesdays 14:00–15:00, Busy, and is the only Busy event inside the working day of the week read. It covers the 14:00 `hold.Calls` occurrence entirely and takes the first 30 minutes off `work.Overflow`, which reads as fully free for its full two hours, with nothing reserved on either side of the call — APP-1164.)

**Bounded auto-hold does not widen the write guardrail (APP-828).** Aide's graduation from propose-and-confirm to unattended booking within the committed-cycle, already-sized envelope changes only whether a human clicks approve first. Every other constraint holds unchanged: Aide writes blocks only inside `work.*` events, and never moves, deletes, reschedules, or responds to any other event or invite — including Aled's own hand-booked holds, which are read for capacity and never touched. The one narrow exemption remains consuming a single occurrence Aide has just filled, never the series. An item **outside** the envelope — not in the committed cycle, not yet sized, or needing a write anywhere but a hold window — still waits for Aled's confirmation. The envelope widens autonomy in *time*; it does not loosen the write guardrail in *space*.

## The Owner's placement is authoritative (APP-898)

The prefix-match capacity read above has a corollary the write guardrail does not reach. Reading capacity by prefix is what keeps hand-added extensions in view — and it is exactly why a block the Owner **drags** to Tuesday afternoon, or out of the window set entirely, leaves Aide's field of view: it no longer starts with a window prefix, so a naive next run would treat the item as unbooked and place it again. Under bounded auto-hold there is no confirmation step to catch that, so without a recognition rule the first unnoticed move produces one duplicate block per run, indefinitely. The rule that closes this is a matter of **reads**, and it does not loosen the never-move/never-delete guardrail one bit:

- **A block Aide wrote is recognised by its durable identifier, not its window.** `skill-time-block` stamps every block with a stable marker at write time (not the title alone — the Owner may retitle), and reads its own blocks back **wherever they now sit** — in a window, in a moved slot, or outside every window. Reading an event is not touching it.
- **The Owner's placement wins.** A stamped block found outside the window Aide first placed it in — or outside the window set entirely — is **still Aide's and still counts as booked**. Aide **records** the new placement, does **not** restore its original slot, and does **not** re-book the item. His manual move is authoritative: an explicit, in-the-moment correction of Aide's placement.
- **It is also a learning signal.** A moved block is the strongest evidence of the Owner's placement preference available — far better than inferring preference from what eventually closed — and it feeds `skill-time-management`'s adaptation layer (APP-599).
- **A meeting that lands on a block Aide already placed is surfaced once, never silently resolved.** *Busy inside the day* covers the order where the meeting exists first: its span comes off the occurrence before anything is placed (APP-1164). The reverse order — a Busy event created **after** a stamped block and overlapping it — is found on the read-back of Aide's own blocks, not by the capacity read, because the time is already booked. Aide **reports the collision to the Owner once**, in the next daily proposal, naming the block, the tickets it holds, the overlapping event and the minutes lost; it does **not** silently re-book, re-time, shorten or delete its block, and it never touches the meeting. Once per collision, not once per run: a later run that finds the same collision already reported does not report it again. Whether Aide may re-time its own already-placed block without asking is an Owner decision about the unattended envelope (APP-828) and is not settled here; until he makes it, the collision waits for him, and an in-session instruction resolves that instance only. (Worked case: a "Meeting with Aled", Tue 22 Sep 09:30–10:30, was created at 16:31Z on 21 Sep over the whole of `work.Unblock` and the first 30 minutes of a `work.Focus` block Aide had written at 10:10Z; the EOD run left both alone and flagged it, and the Owner then directed the rebooking in session — APP-1628, 2026-09-21.)

This is the same shape as every other exemption here: a precise, named read rule, gated on the block being one Aide itself wrote, that leaves "never moves/deletes/responds to other events" fully intact.

## Aide is the single calendar writer

Across every window, **Aide is the only writer**. The operator layer books its `work.Operators` sessions *through* Aide, not directly — five operators writing the calendar in parallel would produce exactly the overcommitment Aide exists to flag, with nothing holding a total view of Aled's time (APP-578). An operator surfaces its session need; Aide places it, holding the whole picture.

## Quick checklist — before touching a hold window

- [ ] Booking into the right window for the item's lane (editorial → `work.MrP`, operator session → `work.Operators`, week planning → `work.Planning`) — and, for everything else, treating the day shape as a convention rather than hunting for a retired window (`work.Focus`, `work.Overflow`, `work.Unblock`, `work.Close`, `work.MBN`, `work.Apps`)?
- [ ] Declared set asserted against the live calendar at the top of the run, and any mismatch — a lane with no row, or a row marked **live** with no live event — reported once as an Owner action, with a row marked **retired** resolved silently and never reported?
- [ ] Occurrence capacity read as **remaining** — its span less any Busy overlap and less anything already booked inside it — rather than as its declared span?
- [ ] Reading capacity by prefix match on `work.*`, writing only into a `work.*` event — with `personal.*` untouched in both directions and `hold.Calls` written only on an explicit Owner request?
- [ ] Read back your own stamped blocks first — recognising any the Owner has moved (in a window or not), counting them as booked, and never re-booking or restoring them (APP-898)?
- [ ] Any Busy event that now overlaps one of your own stamped blocks reported to the Owner once, with the block and the meeting both left as they are (APP-1628)?
- [ ] Window event actually exists for a lane marked **live** — and if not, stopping and telling Aled rather than booking elsewhere, while treating a lane marked **retired** as having no event by design?
- [ ] Any delete confined to a single occurrence Aide has just filled — never the series, never an unfilled one?
- [ ] Any unattended fill confined to committed-cycle, already-sized items inside the exact-named windows — with anything outside that envelope still proposed for confirmation?
- [ ] Aide the writer, even for an operator's `work.Operators` session?

## Tone

Calm, precise, sentence case, British spelling, no exclamation marks, outcome before adjective. (cos.tov.)
