Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
23cad1c
docs(referents): the referent catalog design, measured on two real in…
hugocool Sep 8, 2026
d439598
docs(referents): the implementation plan, nine tasks against the desi…
hugocool Sep 8, 2026
d51f245
feat(referents): the descriptor a judge sees, with the plan's own blo…
hugocool Sep 9, 2026
380973b
feat(referents): one provider seam, gathered concurrently, ids minted…
hugocool Sep 9, 2026
7e14688
feat(referents): one call over the minted candidates, returning a ref…
hugocool Sep 9, 2026
97e0fc4
test(referents): the gist is read by a judge and never compared by code
hugocool Sep 9, 2026
de152e4
test(referents): extend gist guard with slack import and builtin func…
hugocool Sep 9, 2026
f4cba3b
test(referents): narrow builtin guard to flag only direct gist refere…
hugocool Sep 9, 2026
3d9c91d
feat(referents): timeboxing sessions as the first provider
hugocool Sep 9, 2026
9f69d65
fix(referents): tag naive UTC updated_at with UTC, not as_of.tzinfo
hugocool Sep 9, 2026
ae63740
feat(timeboxing): standing_rows answers which sessions stand, with ea…
hugocool Sep 9, 2026
c2d86b3
fix(timeboxing): parse rendered plan rows with csv, not a naive comma…
hugocool Sep 9, 2026
909838b
feat(slack): a follow-up reaches the session it is about, instead of …
hugocool Sep 9, 2026
84661e1
fix(slack): the rung asks rather than creates, and never outranks a l…
hugocool Sep 9, 2026
1929966
fix(slack): one reading of "would this turn mint a session", and the …
hugocool Sep 9, 2026
3a4342a
fix(slack): a store outage stops sessions being minted, not every con…
hugocool Sep 9, 2026
20d9a54
fix(slack): a partial catalog is refused by the store, not by the mes…
hugocool Sep 9, 2026
77024eb
test(referents): resolution quality on the pin, two frozen incidents,…
hugocool Sep 9, 2026
f5de0ee
docs(referents): the interface-strain log the marshal's provider inhe…
hugocool Sep 9, 2026
2af9145
fix(referents): the chosen day survives the turn, and a model outage …
hugocool Sep 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/setup/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,41 @@ what that means; this section is only the operational side.
material store no longer holds. The refusal names the block and the
handle; clear the link on that block with an explicit null, or restore the
ticket under the same handle, before the day can be committed again.

## A session-store outage refuses every timeboxing turn {#session-store-outage}

**Expected, and it will not look expected.** When the timeboxing session store
cannot be read, the referent rung (`src/fateforger/slack_bot/handlers.py`)
cannot draw the catalog of days that already stand, and every door that would
hand a turn to `timeboxing_agent` refuses with:

> :warning: I couldn't check what you already have planned, so I won't start a
> second session over the top of it. Say that again and I'll retry, or open one
> from the day's own thread if there is one.

That includes **continuing a session that really does stand**. The guard asks
the store whether a row exists at the key the turn would use
(`_a_partial_catalog_forbids_this_turn`), and the store is the thing that is
down, so "there is nothing there" and "I could not tell" have to answer the
same way. Fail-closed is deliberate: the alternative is a second five-stage
session opened over a day that was already committed, which is the 2026-09-05
incident this rung exists to close.

What it looks like on call, and what to do:

- **Symptom.** Every planning message — new day, DM, a reply in a live session
thread — comes back with the line above. Nothing else in the bot is affected:
the receptionist still answers, and a message not headed for a session runs
normally. A bot answering some things and refusing all planning is the
signature; a total outage is not.
- **Confirm it is the store.** `record_error(component="surface_intent")` fires
with `error_type="referent_catalog_partial"` on every refusal, and
`component="referent_catalog"`, `error_type="provider_failure"` on the read
that failed. The exception itself is logged by `build_catalog`.
- **Fix.** The store is the sessions database behind
`SqlAlchemyTimeboxingSessionRepository`; restore it or its connection. The
refusal clears by itself on the next message once reads succeed — there is no
cache to bust and no flag to reset.
- **Do not** work around it by restarting the bot or clearing focus. Neither
touches the store, and `/ff-clear` drops a focus binding without dropping the
redirect beside it, which is a separate hazard the same guard covers.
369 changes: 369 additions & 0 deletions docs/superpowers/notes/2026-09-referent-interface-strain.md

Large diffs are not rendered by default.

Loading