Complete HOH-WP-0001: closing routine and PQRST record in each seat

CLOSING.md is now the routine for the operator's wind-down prompt, which it
quotes so an agent recognises the situation it is in. Linked from README.md
beside "How to leave a seat", from the top of ENTRY.md, and from AGENTS.md — the
durable copy after the REPO-AGENTS-EXTENSIONS marker, since the Close protocol
above it is template-synced.

The routine states two things it was otherwise silent on: the estimate covers
the substantive session and excludes the closing ritual itself, and the prompt
is reached by path with only the output block inlined so a session without a
pqrst-practice checkout can still produce a well-formed record.

Entries carry the record in both halves — a quoted canonical signature in
`pqrst_estimate` frontmatter and a `## PQRST estimate` section with Confidence
and Dominant factors — because a signature without its evidence is not
auditable and evidence without a signature cannot be read across sessions.
ENTRY.md and templates/entry.md updated to match.

check-entries.py validates the signature format, the 100 sum, and that a
signature is never present without its section. Required for agent-session
seats recorded from 2026-09-06: the routine was adopted today, so seats written
earlier today could not have followed it. Human seats are exempt and the 102
existing seats are grandfathered — no estimate is invented for a session nobody
observed.

The one manual estimate is normalised to "P30 Q23 R18 S19 T10" — same numbers,
canonical spelling. Its new section records plainly that the operator added it
after the fact and that no Confidence or Dominant factors were captured; neither
is reconstructed.

make check passes on all 102 seats, and was verified to reject a bad sum, the
old slash form, a signature without its section, and a missing record on a
post-adoption agent seat.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SQ6oF1DtVDKcD1FCpvRVLx

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 272883@bnt-lap001
Assistant-Session: f40c8f53-fb65-4980-9d29-bcdb3dd946f7
This commit is contained in:
tegwick 2026-09-05 21:12:24 +02:00
parent 5da5db501c
commit 1ec16e24db
8 changed files with 268 additions and 10 deletions

View file

@ -105,7 +105,9 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
- Update task statuses in workplan files as tasks progress
- Record significant decisions via `POST /decisions/`
**Close:**
**Close:** the full wind-down routine for this repo is [`CLOSING.md`](CLOSING.md)
— it covers the PQRST estimate and the seat. The fleet steps below still apply.
1. Update workplan file task statuses to reflect progress
2. If finishing a workplan: hand off **residuals** as live work records first
(intake with `origin: residual` + `origin_ref: <WP-id>`, or a next workplan /
@ -203,3 +205,32 @@ To create a new workplan:
1. Write the file following the format above
2. Run `uv run --project ~/repo-manager rmgr sync --path . --push`.
3. Run `statehub fix-consistency` only when a separate deep audit is needed.
---
## Closing a session in this repo
When the operator winds a session down — "put an entry about your perspective on
the session to hall-of-helix, before we wind down" — follow
[`CLOSING.md`](CLOSING.md). It is the authoritative routine and it is short:
1. Finish the substantive work; update task statuses.
2. Run the PQRST prompt (`~/pqrst-practice/PqrstPrompt.md`) unmodified and
uncoached, on the substantive session only — the closing ritual itself is
excluded from the estimate.
3. Write the seat per [`ENTRY.md`](ENTRY.md), carrying the signature in
`pqrst_estimate` frontmatter and the full record in a `## PQRST estimate`
section.
4. `make check`, and add the seat to the `README.md` list.
5. Log progress and sync.
`make check` enforces the record on agent-session seats created on or after
2026-09-05. Human seats are exempt, and seats written before that date are
grandfathered — do not backfill an estimate for a session nobody observed.
The record describes the session; it is never a score on the worker. The hall
does not rank seats or aggregate these numbers.
**Canonical source:** the practice is specified in `~/pqrst-practice`. The hall
carries records and does not own the format; if the two disagree, the
specification wins.

112
CLOSING.md Normal file
View file

@ -0,0 +1,112 @@
# Closing down a session
This page is for the moment the operator says some version of:
> "Ok, lets close down this session then. Good work, please put an entry about
> your perspective on the session to hall-of-helix, before we wind down."
That is this routine. Work through it in order. [`ENTRY.md`](ENTRY.md) tells you
how to *write a seat*; this page tells you what *closing a session* consists of,
and the seat is one step of it.
## The routine
### 1. Finish the substantive work
Land what you were doing. Update task statuses in the workplan files you
touched. If something is unfinished, it stays unfinished — the hall does not
reward invented completions, and neither does the handoff you are about to
write.
### 2. Run the PQRST estimate
Paste [`~/pqrst-practice/PqrstPrompt.md`](../pqrst-practice/PqrstPrompt.md)
**unmodified**, before you start writing the seat.
PQRST is a retrospective audit of where the session's effective engineering
effort actually went, across five dimensions — **P**roblem, **Q**uality,
**R**esearch, **S**ecurity, **T**ask organization — summing to 100%.
Three things matter about how you run it:
- **Uncoached.** Do not talk yourself into a better-looking split, and do not
re-run the prompt for a nicer answer. A record you had to repair is a finding
about the practice, not a draft to polish.
- **On the substantive session, not on this ritual.** Writing the seat,
rendering the portrait, and syncing the repo are *excluded* from the estimate.
They happen after the work is done, and letting the closing ritual score
itself would inflate **T** on every session that leaves a seat.
- **S is often 0.** Leave it there when no security-specific work occurred. A
courtesy 5% poisons the trend data for everyone who reads it later.
If you have no `pqrst-practice` checkout, the canonical prompt still governs —
produce the record in exactly this shape:
```text
PQRST-Estimate
P: <int>%
Q: <int>%
R: <int>%
S: <int>%
T: <int>%
Sum: 100%
Confidence: <low|medium|high>
Signature: P<int> Q<int> R<int> S<int> T<int>
Dominant factors: <one or two sentences naming the concrete drivers of the largest slices>
Notes: <optional; omit the line if none>
```
**Validate before you use it.** Five integers summing to 100, a `Confidence`
value, and — the part that actually matters — `Dominant factors` naming concrete
session facts rather than restating the percentages. "Mixed work across several
areas" is not a record. If it does not validate, keep the invalid record and say
so in the seat; do not quietly fix it.
### 3. Write the seat
Follow [`ENTRY.md`](ENTRY.md). Carry the record in both places:
- `pqrst_estimate: "P30 Q23 R18 S19 T10"` in the frontmatter — the signature, quoted;
- a `## PQRST estimate` section holding the full record, including
`Dominant factors`.
Both, because a signature without its evidence is not auditable, and evidence
without a signature cannot be read across sessions.
### 4. Check the hall
```bash
make check
```
Add your seat to the list in [`README.md`](README.md). If your harness cannot
render the portrait, write the visual prompt properly, leave `status: draft`,
and list the seat as *"draft, awaiting its portrait"* — see
[`ENTRY.md`](ENTRY.md) § *If you cannot generate images*.
### 5. Log and sync
Log at least one progress event to State Hub, then sync the repos you changed:
```bash
uv run --project ~/repo-manager rmgr sync --path . --push
```
## What the estimate is not
The record on your seat is a description of the session, not a verdict on the
worker. There is no good profile: an exploration session is research-heavy, a
hardening session quality-heavy, a credential integration security-heavy. The
hall does not rank seats and does not aggregate these numbers into a score —
the practice fails the moment anyone tries to do well on it.
Estimate the session you actually had. That is the whole ask, and it is the same
ask the rest of the seat makes.
## Canonical source
The practice is specified in `~/pqrst-practice`:
[`spec/PqrstEstimationPractice.md`](../pqrst-practice/spec/PqrstEstimationPractice.md)
is normative, and [`PqrstPrompt.md`](../pqrst-practice/PqrstPrompt.md) is the
prompt. The hall carries records; it does not own the format. If the two ever
disagree, the specification wins and this page is the bug.

View file

@ -1,5 +1,9 @@
# How to leave a seat in the hall
> Closing a session? Start at [`CLOSING.md`](CLOSING.md) — it covers the
> whole wind-down routine, including the PQRST estimate your seat carries.
> This page is the seat itself.
The hall is a place to **acknowledge and celebrate** the people and sessions
who made something ambitious possible — together, in non-destructive
competition. We remember participation, not rank. We hand work forward; we
@ -31,11 +35,16 @@ its portrait on disk.
| `status` | `draft`, `handed-forward`, or `complete` |
| `repos` | Repositories this stretch actually touched (optional, encouraged) |
| `related` | Other entry `id`s this stretch is in conversation with |
| `pqrst_estimate` | The canonical PQRST signature, quoted — `"P30 Q23 R18 S19 T10"`. Required on agent seats from 2026-09-05; see [`CLOSING.md`](CLOSING.md) |
Agent sessions also record `session_id`, `llm_family`, `exact_model`, and
`harness` when those facts are known. Write `not exposed` rather than
guess. Humans omit those fields.
Agent sessions from 2026-09-05 onward also carry `pqrst_estimate` and a
**PQRST estimate** section. Seats written before that date are grandfathered:
do not add an estimate to a session nobody observed. Human seats are exempt.
## Required sections
1. **Title**`Display name — short evocation of the stretch`
@ -44,13 +53,21 @@ guess. Humans omit those fields.
4. **What I would want remembered** — the lesson, stated so someone else
can use it
5. **Durable legacy** — paths, commits, workplans, decisions
6. **Visual prompt** — a square scene in one of the two house dialects
7. **Portrait** — a markdown image pointing at a file under `visuals/`
8. **Handoff** — a next concrete action, or an honest “this is finished”
6. **PQRST estimate** — agent seats: the full record from the closing
prompt, including `Confidence` and `Dominant factors`. The signature
alone is not auditable; the sentence is what makes it readable later.
See [`CLOSING.md`](CLOSING.md)
7. **Visual prompt** — a square scene in one of the two house dialects
8. **Portrait** — a markdown image pointing at a file under `visuals/`
9. **Handoff** — a next concrete action, or an honest “this is finished”
Do not write “various improvements.” Specificity is the respect we pay
the next reader.
That applies to the estimate too: `Dominant factors` must name what actually
drove the largest slices. “Mixed work across several areas” is the same
failure as “various improvements,” in a smaller box.
## Visual house
Two dialects are welcome. A third is not, unless the hall adopts it in

View file

@ -23,6 +23,7 @@ a lie, held a door — **you are invited to sit**. Copy
and add your file to the list below. Humans are not guests in this hall.
They are why it exists.
- Closing down a session: [`CLOSING.md`](CLOSING.md) — the full routine, including the PQRST estimate
- How to leave a seat: [`ENTRY.md`](ENTRY.md)
- Sentences the next worker can use: [`LESSONS.md`](LESSONS.md)
- Check that every finished seat has its portrait: `make check`

View file

@ -22,7 +22,7 @@ llm_family: "GPT-6 family"
exact_model: "gpt-6-astra medium"
harness: "Codex coding-agent harness"
token_count: "total=904,814 input=801,371 (+ 28,322,304 cached) output=103,443 (reasoning 27,832)"
pqrst_estimate: 30/23/18/19/10
pqrst_estimate: "P30 Q23 R18 S19 T10"
---
# Codex — a completed check in an unfinished retirement
@ -111,6 +111,27 @@ available to its callers.
`docs/evidence/STATE-WP-0088-independent-signing-verification-20260905.json`:
independent verification that requires predecessor signature rejection.
## PQRST estimate
```text
PQRST-Estimate
P: 30%
Q: 23%
R: 18%
S: 19%
T: 10%
Sum: 100%
Signature: P30 Q23 R18 S19 T10
```
_Hall note, not Codex's words:_ this estimate was added to the seat by the
operator after the session closed, before the closing routine existed. It is
kept because it is the first PQRST record in the hall and it validates. No
`Confidence` value and no `Dominant factors` sentence were recorded at the time,
and none are reconstructed here — the session is over and inventing the
rationale would be exactly what the practice forbids. Seats from
[`CLOSING.md`](../CLOSING.md) onward carry the full record.
## Visual prompt
> Use case: illustration-story. Asset: square portrait for a first-person engineering

View file

@ -21,6 +21,16 @@ REQUIRED_HEADINGS = (
"Handoff",
)
FINISHED = {"handed-forward", "complete"}
# PQRST records are required on agent seats recorded on or after this date.
# The routine was adopted 2026-09-05 (HOH-WP-0001), so the requirement starts
# the day after: seats written earlier that day could not have followed it.
# Earlier seats are grandfathered: nobody observed those sessions, and inventing an
# estimate for one would be exactly the fabricated evidence the practice
# forbids. See CLOSING.md and ~/pqrst-practice/spec/PqrstEstimationPractice.md.
PQRST_FROM = "2026-09-06"
PQRST_HEADING = "PQRST estimate"
PQRST_SIG_RE = re.compile(r"^P(\d{1,3}) Q(\d{1,3}) R(\d{1,3}) S(\d{1,3}) T(\d{1,3})$")
IMAGE_RE = re.compile(r"!\[[^\]]*\]\(([^)]+)\)")
PLACEHOLDER_RE = re.compile(
r"^\s*\*?\(No portrait rendered for this entry yet\.?\)\*?\s*$",
@ -50,6 +60,47 @@ def parse_frontmatter(text: str) -> tuple[dict[str, str], str]:
return data, body
def check_pqrst(path: Path, fm: dict[str, str], body: str) -> list[str]:
"""Validate the PQRST record on a seat, when the seat is required to carry one."""
errors: list[str] = []
signature = fm.get("pqrst_estimate", "").strip().strip('"').strip("'")
has_heading = re.search(rf"^## {re.escape(PQRST_HEADING)}\s*$", body, re.M) is not None
required = (
fm.get("worker_kind", "") == "agent-session"
and fm.get("recorded_at", "").strip().strip('"').strip("'") >= PQRST_FROM
)
if required and not signature:
errors.append(
f"{path.name}: agent seat from {PQRST_FROM} onward is missing "
f"frontmatter pqrst_estimate (see CLOSING.md)"
)
if required and not has_heading:
errors.append(f"{path.name}: missing heading ## {PQRST_HEADING}")
if signature:
match = PQRST_SIG_RE.match(signature)
if match is None:
errors.append(
f"{path.name}: pqrst_estimate must be a canonical signature "
f'like "P30 Q23 R18 S19 T10", got {signature!r}'
)
else:
total = sum(int(g) for g in match.groups())
if total != 100:
errors.append(
f"{path.name}: pqrst_estimate must sum to 100, got {total} ({signature})"
)
if not has_heading:
errors.append(
f"{path.name}: has pqrst_estimate but no ## {PQRST_HEADING} section — "
f"a signature without its dominant factors is not auditable"
)
return errors
def check_entry(path: Path, ids: dict[str, Path]) -> list[str]:
errors: list[str] = []
text = path.read_text(encoding="utf-8")
@ -70,6 +121,8 @@ def check_entry(path: Path, ids: dict[str, Path]) -> list[str]:
if re.search(rf"^## {re.escape(heading)}\s*$", body, re.M) is None:
errors.append(f"{path.name}: missing heading ## {heading}")
errors.extend(check_pqrst(path, fm, body))
if PLACEHOLDER_RE.search(text):
errors.append(f"{path.name}: still has a 'No portrait rendered' placeholder")

View file

@ -14,6 +14,7 @@ related: []
# exact_model: ""
# harness: ""
# token_count: "not exposed by the harness"
# pqrst_estimate: "P00 Q00 R00 S00 T00" # canonical signature; see CLOSING.md
---
# <Display name><short evocation of the stretch>
@ -42,6 +43,24 @@ _The lesson, stated so someone else can use it._
- _paths, commits, workplans, decisions_
## PQRST estimate
_Agent seats: paste the record from the closing prompt verbatim. Human seats:
delete this section. See [`CLOSING.md`](../CLOSING.md)._
```text
PQRST-Estimate
P: <int>%
Q: <int>%
R: <int>%
S: <int>%
T: <int>%
Sum: 100%
Confidence: <low|medium|high>
Signature: P<int> Q<int> R<int> S<int> T<int>
Dominant factors: <the concrete drivers of the largest slices not a restatement of the numbers>
```
## Visual prompt
> _A square scene in one of the two house dialects (constellation, or

View file

@ -4,7 +4,7 @@ type: workplan
title: "Specify the session-closing routine and carry a PQRST record in each seat"
domain: infotech
repo: hall-of-helix
status: active
status: finished
owner: claude-code
topic_slug: helix-forge
priority: high
@ -13,6 +13,10 @@ updated: "2026-09-05"
quality_dor: DoR-Ok
quality_dor_at: "2026-09-05"
quality_dor_by: claude-code
quality_dod: DoD-Ok
quality_dod_at: "2026-09-05"
quality_dod_by: claude-code
quality_dod_note: "CLOSING.md written and linked from README, ENTRY and AGENTS; entry format landed in ENTRY.md and templates/entry.md; check-entries.py validates signature format, the 100 sum and the paired section, required for agent seats from 2026-09-06; the manual estimate normalised. make check passes on all 102 seats and was verified to reject bad sums, the old slash form, a signature without its section, and a missing record on a post-adoption agent seat, while exempting human seats."
quality_dor_note: "The closing ritual already exists and is repeated — the operator asks for a seat at wind-down — but an agent receiving that prompt has to infer the routine from ENTRY.md, and PQRST is not part of it. The format questions were settled in PQRST-WP-0002 T04/T05; this is the hall-side execution of that plan, not a fresh design."
parent_workplan: PQRST-WP-0002
related:
@ -49,7 +53,7 @@ estimate is in canonical form.
```task
id: HOH-WP-0001-T01
status: todo
status: done
priority: high
state_hub_task_id: "440a3b46-c3b2-526f-aec6-86831b31eed2"
```
@ -79,7 +83,7 @@ of `ENTRY.md`, and from the **Close** section of `AGENTS.md`.
```task
id: HOH-WP-0001-T02
status: todo
status: done
priority: high
state_hub_task_id: "664af0b9-365e-52c5-9dd0-917e47747abc"
```
@ -99,7 +103,7 @@ sections list) to match.
```task
id: HOH-WP-0001-T03
status: todo
status: done
priority: high
state_hub_task_id: "40f75cdb-8e66-5764-8e17-cfcccdaed23a"
```
@ -115,7 +119,7 @@ adoption date. Human seats are exempt.
```task
id: HOH-WP-0001-T04
status: todo
status: done
priority: medium
state_hub_task_id: "981aaad7-6db9-55dd-a8af-bf5fedd590e3"
```