| 1 | --- |
| 2 | name: end-session |
| 3 | description: End-of-session checklist β confirm all work is committed/pushed/PR'd and that the per-session status.elevenmessenger.com ledgers (SSH access, carbon tally, prompt registry) are written before wrapping up. |
| 4 | --- |
| 5 | |
| 6 | # π€ end-session β leave nothing owed |
| 7 | |
| 8 | Run this before wrapping up a working session. Two gates: **(A)** the work is |
| 9 | finished and pushed, **(B)** the public status ledgers this session touched are |
| 10 | written. **Check and report first; complete the mechanical parts only with the |
| 11 | user's OK** β never auto-merge, auto-deploy, or auto-publish (those stay the |
| 12 | user's call). Never echo secrets or capability/invite links (transcripts are |
| 13 | public β [[transcripts-are-public]]). |
| 14 | |
| 15 | Work through both gates, then end with the owed/clear summary at the bottom. |
| 16 | |
| 17 | ## A. Work finished & pushed |
| 18 | |
| 19 | 1. **Tasks.** If a task list is in use, `TaskList` β any `in_progress` / `pending` |
| 20 | left? Finish them, or state which are intentionally deferred and why. |
| 21 | 2. **Working trees.** `git status` in the main checkout, and `git worktree list` |
| 22 | then `git -C <wt> status` for every open worktree. Uncommitted changes β |
| 23 | commit (area-prefixed: `web:`/`server:`/`docs:`β¦) or explain why they're left. |
| 24 | 3. **Unpushed commits.** `git log --branches --not --remotes --oneline`. β οΈ In a |
| 25 | **shared checkout this lists every session's local branches, not just yours** β |
| 26 | scope to the branches THIS session created. Anything of yours that's genuinely |
| 27 | local-only β push it (feature branches, never `main`). Note a squash-merged |
| 28 | branch leaves a **stale local ref** that shows here as "unpushed" even though |
| 29 | the work is on `main` β that's not owed work, just delete the ref |
| 30 | (`git branch -D <branch>`). |
| 31 | 4. **Open PRs.** `gh pr list --author @me --state open`. β οΈ This returns **all of |
| 32 | your account's open PRs across every session** (the team commits under one |
| 33 | author here), so **scope to the PRs THIS session opened** β the rest are other |
| 34 | sessions' and not yours to touch. For each of yours: it's ready (offer to |
| 35 | `gh pr merge <n> --squash --delete-branch`) or say what it's waiting on. After a |
| 36 | squash-merge, delete the remote branch + `git worktree remove` the merged |
| 37 | worktree (gh may fail the local step when `main` is a sibling worktree β that's |
| 38 | cosmetic; the server-side merge still lands). |
| 39 | 5. **Leftover worktrees** from already-merged branches β `git worktree remove`. |
| 40 | 6. **Shared `main` checkout** is shared with other sessions β don't force-pull or |
| 41 | mutate it; just report if it's behind after a merge. |
| 42 | |
| 43 | ## B. Status ledgers (status.elevenmessenger.com) |
| 44 | |
| 45 | Authoritative procedures: **`docs/status.md`**. Three ledgers are **per-session** |
| 46 | (below). The rest β books / economics / contributors / security / milestones β |
| 47 | are periodic, not session-gated; mention one only if this session changed its |
| 48 | inputs. |
| 49 | |
| 50 | ### B1. SSH access ledger β REQUIRED if this session touched a fleet box |
| 51 | Did this session `ssh`/`scp` to the router box (`elevenbox`, `89.167.122.227`, |
| 52 | or any `*.11ch.at` / fleet box) β e.g. a canary deploy, a teardown, a box |
| 53 | inspection? If yes there **must** be a why-entry, or the public page renders the |
| 54 | session as **"no summary recorded"** (that state IS the enforcement). |
| 55 | |
| 56 | - **Check:** is there a `web/status/ssh/<today>-*.json` covering this session's |
| 57 | window? (`ls web/status/ssh/`.) |
| 58 | - **If missing, write** `web/status/ssh/YYYY-MM-DD-<slug>.json`: |
| 59 | ```json |
| 60 | { "date": "YYYY-MM-DD", "operator": "Full Name", "window": "HH:MMβHH:MM UTC (approx)", "why": "terse what-not-how summary", "refs": ["https://github.com/elevenmessenger/messenger/pull/NNN"] } |
| 61 | ``` |
| 62 | - `operator` **must** match a handle in `web/status/ssh-operators.json`, or the |
| 63 | join misses. |
| 64 | - `why` is *what, not how* β never a command, credential, token, host token, or |
| 65 | email. A security-sensitive session publishes as `"why": "(withheld: security)"` |
| 66 | rather than vanishing. Redaction bar: `web/status/ssh/README.md`. |
| 67 | - `date` + `window` are UTC and approximate; one entry may cover several |
| 68 | sessions in the same working window. |
| 69 | - The entry rides a normal commit/PR. It only reaches the page once scp'd to the |
| 70 | box (`web/status/ssh/*.json` β `/opt/lchat/status-pages/ssh/`), which happens on |
| 71 | a status publish β so if this session is *already* publishing to the box, copy |
| 72 | it too; otherwise the committed entry is enough and the next publish carries it. |
| 73 | |
| 74 | ### B2. Carbon tally |
| 75 | - Run `node tools/carbon-tally.mjs check`. **Silent β nothing owed.** If it says |
| 76 | accrue (this machine's newest entry is >3 days old β its transcripts prune after |
| 77 | ~a week, so a missed week is lost): |
| 78 | 1. `node tools/carbon-tally.mjs --write` (per-source cutoffs; safe to re-run), |
| 79 | 2. commit `web/status/carbon.json` as a **tiny standalone PR merged promptly** |
| 80 | (two branches accruing the same window is the one race the cutoffs can't |
| 81 | see; the contract test catches it on main), |
| 82 | 3. copy `web/status/carbon.json` to the box's `/opt/lchat/status-pages/`. |
| 83 | - `docs/status.md Β§ Keeping the carbon tally accruing`. The check nags; the |
| 84 | accrual is a judgment call you run. |
| 85 | |
| 86 | ### B3. Prompt registry |
| 87 | **Nothing auto-publishes the registry.** The only automation is the SessionStart |
| 88 | hook running `check`, which merely *nags* β building, **summarising**, and |
| 89 | uploading are all manual, so the ledger drifts whenever they're skipped. |
| 90 | - Run `node tools/prompt-registry.mjs check`. **Silent / "no corpus at β¦"** means |
| 91 | the *staleness* nag is quiet β but β οΈ **`check` only tests corpus AGE (>3 days), |
| 92 | not whether recent sessions are SUMMARISED.** A corpus published <3 days ago |
| 93 | without the haiku step passes silently. The visible tell is rows on |
| 94 | `prompts.html` that fall back to **"FIRST PROMPT / LATEST"** instead of a |
| 95 | one-line summary β those sessions still owe the **haiku summarise** step even |
| 96 | though `check` is quiet. So don't trust `check` alone here: glance at |
| 97 | `prompts.html` (or the built `index.json`) for un-summarised rows. |
| 98 | - To accrue (nagged, OR un-summarised rows exist), per `docs/status.md Β§ The |
| 99 | prompt registry`: build (`--out <dir>`) β **summarise every new session with |
| 100 | haiku subagents over the REDACTED build output only** (never raw transcripts; |
| 101 | β€90-char one-liners ending in the session's most relevant GitHub URL) β re-build |
| 102 | (fail-closed re-scan) β upload the corpus β commit the hash-ledger entry. It's |
| 103 | heavy, creds-bound (bucket PutObject), and judgment-bound (the security sweep) β |
| 104 | publishing is opt-in, so do it deliberately, never half-run it, and never |
| 105 | auto-publish it from this skill. |
| 106 | |
| 107 | ## What this skill does NOT do |
| 108 | - Merge / deploy / publish without the user's OK β fleet publishes, box scps, and |
| 109 | PR merges are surfaced as offers, never taken silently. |
| 110 | - Touch the secrets vault, echo any secret, or print an invite/capability link. |
| 111 | - Force-update or dirty the shared `main` checkout. |
| 112 | |
| 113 | ## Report |
| 114 | End with a tight table β each item **β
clear** / **β οΈ owed** (with the single |
| 115 | action that closes it) / **β n/a this session**: |
| 116 | |
| 117 | ``` |
| 118 | A1 tasks Β· A2 working trees Β· A3 unpushed Β· A4 open PRs Β· A5 worktrees Β· A6 main |
| 119 | B1 ssh ledger Β· B2 carbon Β· B3 prompt registry |
| 120 | ``` |
| 121 | |