← NightshiftCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Nightshift
Snapshot Sep 30, 2026 · 23:14 UTC · version 0.25.3
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"description": "File a finished shift into its own archive folder, laid out like the live site, so the live files keep only open work.",
"included_files": [],
"name": "archive",
"skill_md_contents": "---\nname: archive\ndescription: File a finished shift into its own archive folder, laid out like the live site, so the live files keep only open work.\nlicense: MIT\n---\n\nArchive the finished paperwork for the host-opened project. This files records — it never does\nshift work, never ticks a box, never touches the contract.\n\nThe four state files and what each holds are in\n`$NIGHTSHIFT_PLUGIN_ROOT/skills/nightshift/references/shift/state-map.md`. Archive each by its own lifecycle; never reclassify one as another.\n\nResolve the installed plugin root to an absolute `$NIGHTSHIFT_PLUGIN_ROOT` — `${CLAUDE_PLUGIN_ROOT}`\non Claude Code, `$PLUGIN_ROOT` on Codex when set, otherwise the absolute path this skill was\nattached from (`skills/archive/SKILL.md`). Run every command below through\n`\"$NIGHTSHIFT_PLUGIN_ROOT/runtime/ns\"` — native Windows: `& \"$NIGHTSHIFT_PLUGIN_ROOT\\runtime\\windows\\ns.ps1\"`\nin the PowerShell tool, same verbs — which resolves the host and the workspace; `ns help` lists the\nverbs, and `ns bind` prints the six resolved facts (`TASK_ROOT`, `NIGHTSHIFT_WORKSPACE`, `NS`,\n`NIGHTSHIFT_PLUGIN_ROOT`, `HOST`, `SOURCE`); `$NS` below is that `NS`. Never a bare relative path: the working\ndirectory persists between calls. Each `$NS/...` path below is where the current layout keeps that file;\n`ns path <key>` prints where this workspace keeps it, and `ns path --list` names every key.\n\nRead `$NS/state-version` first. Legacy (missing), `1` and the current `2` may be archived.\nA newer or malformed marker fails closed — file nothing, rewrite nothing, and never migrate.\n`state-version` itself stays live; it is not an archive record.\n\nIn artifact mode the work target is a persistent folder, not a Git repository. File the same\nNightshift records; do not require a work-target commit that cannot exist. Copy live receipts with\n`\"$NIGHTSHIFT_PLUGIN_ROOT/runtime/ns\" archive-receipts`, and pass `--retire <receipt-name>` once\nper ticked item (native Windows: `-Retire` with those names as one comma-separated list).\nMissing or empty receipts create no dated receipts folder.\nA receipts path that is not a usable directory is a refuse, not an empty skip.\n\nIf `$NS/run/.pending-filing` exists, a shift asked for filing at clock-out. It carries `date=` and\n`shiftId=` lines naming that shift — use them — and an `asked=1` line once the gate has held the\nsession to ask for it. Delete the marker once filing is done, and only then. Nothing else about it\nis special: file the same way you would on any explicit Archive.\n\n`$NS/run/.ended` names the shift that finished and where it files, in `shiftId=`, `archiveRoot=`,\n`archiveLayout=`, `shiftName=` and `archiveFolder=` lines. Clock-out claimed that folder for the\nshift, and every later Archive of it returns there, whatever day it runs.\n\n**Only what is closed is filed.** Each record lives in one place: filed once it is closed, live\nwhile it is open. Filing is a copy: nothing leaves live storage until its filed copy reads back.\nA ticked item's receipt leaving live storage is a separate step, and the\nagent running Archive takes it from `$NS/punch-list.md` — not later, not the owner, and not by\nguessing.\n`--retire` with one record name, repeated once per ticked item on POSIX; on native Windows,\n`-Retire` takes those names as a single comma-separated list. Receipts of open items are never\nnamed: they stay live and are not filed. The morning receipt is named only when that shift\nhas ended and no open item still needs it. Once the shift has ended, the helper also retires every\nticked item's receipt it filed, even if a name was missed. It will not retire an open item's\nreceipt.\n\nBefore naming anything, read `$NS/punch-list.md` and the records themselves. A shift can end with\nitems still open — `STOP` and the deadline both do that — so `.ended` is not a reason to leave a\nticked receipt live, and it is not a reason to pull an open one. Keep a record live when an open\nitem, an unanswered parking decision or work carried into the next shift still needs it, and when\nyou cannot tell who owns it. Rejected work is filed with its rejection, never erased. A name the\nhelper did not file is refused and told back to you.\n\n## Where it goes\n\nEach shift has one folder under the archive root (`archive.root` in the resolved policy), named by\n`archive.layout`:\n\n- `date` (the default): `<YYYY-MM-DD>/`, and a later shift that day `<YYYY-MM-DD>-shift-2/`,\n `-shift-3/` and so on.\n- `shift`: `shift-<id>/`.\n- `name`: the name on the punch list's title line, as in `# Punch List — Archive follow-ups`, so\n `archive-follow-ups/`.\n- `date-name`: both, `<YYYY-MM-DD>-archive-follow-ups/`.\n\nA shift with no name files by date under `name` and `date-name`, and a second shift under the same\nname takes `-shift-2`. The folder records its shift in `.shift-id`; another shift never writes into\nit, and filing the same shift again returns to it. `archive-receipts` prints the folder; receipts\nland in its `receipts/`, which is `archive/<YYYY-MM-DD>/receipts/` by default. A shift that never\nreached clock-out has no claimed folder yet and files by today's date: `date +%Y-%m-%d` on POSIX,\nor `Get-Date -Format yyyy-MM-dd` on native Windows.\n\n**The folder is laid out like the live site.** Every record sits at the path it has under `$NS/`:\n\n```text\narchive/<folder>/\n├── .shift-id\n├── punch-list.md the contract and the ticked items\n├── receipts/ the receipts of ticked items, the morning page, and an index of this folder\n├── inbox/\n│ ├── parking-lot.md the answered decisions\n│ └── snag-log.md the findings with a disposition\n└── run/\n ├── shift-policy.json filed by clock-out\n ├── shift-log.md\n ├── usage/ the shift's usage readings\n └── evidence/findings.jsonl filed by clock-out, when the shift used it\n```\n\nLinks between those records keep working as written. A link to a record that stayed live — the\ndrafting table, a receipt of an open item still being worked — is repointed back to it in the filed\npage, which is the only copy. Do not hand-edit it.\n\n## What moves, what stays\n\n- **Punch list → filed by the runtime.** Once the shift has ended, `archive-receipts` files the\n contract and the ticked items, then takes the ticked items out of `$NS/punch-list.md`.\n Open items, the contract and the gates stay live; an item ticked later joins the same filed list\n on the next Archive. Do not move items by hand. When the owner is present\n and no open box is left, ask whether to keep the contract for the next shift or change it. In\n unattended filing (a `.pending-filing` from clock-out) do not ask: append one reminder under\n `## Notes` (create the heading below `## Items` if it is missing):\n leftover Shift contract and Gates still bind the next Hunt or Start cut; review them before\n composing a new campaign; Archive does not reset them. Skip the note when open work remains, when the same sentence is already\n present, or if adding it would require an open checkbox. Never write `- [ ]` here and never edit\n above `## Items`.\n- **Receipts — the ticked ones filed and retired.** For each ticked item, pass `--retire <receipt-name>`;\n receipts of open items stay live and are not filed.\n `archive-receipts` rebuilds `receipts/README.md` on both sides of the move so each index lists\n only the receipts in its own folder.\n- **Shift log, usage, policy → filed by the runtime.** Once the shift has ended, the helper moves\n `$NS/run/shift-log.md` into the folder and starts a fresh one under the same heading, moves the\n shift's usage readings, and moves a policy of that shift that is still live. A `usage-<id>/`\n folder the Start preflight set aside goes to the folder of the shift it belongs to. Do not move\n any of these by hand.\n- **Snag log — the handled entries filed, only the open entries stay.** `archive-receipts` files\n each `- ` bullet entry of `$NS/inbox/snag-log.md` that carries a disposition (`fixed`, `ignored`,\n `answered`, `rejected-because`, `accepted-tradeoff`), takes those entries out of the live file,\n and appends one `Filed:` pointer to the filed copy (label: the folder's name, or the shift id in the `shift`\n layout; target: relative path to the filed file). A file with no entry files nothing. Do not\n hand-copy entries. Entries still awaiting the owner stay live: an open question is not history\n yet. Text written as a paragraph instead of a bullet is never filed; Doctor names it by file and\n line.\n- **Parking lot — the answered entries filed, only the unanswered stay.** Same helper, same pointer rule on\n `$NS/inbox/parking-lot.md`. The owner answers an entry by appending ` · answered: <decision>`; an\n answered entry is filed, never deleted. Parking-lot questions unanswered stay. Read live entries\n first; when checking whether a finding or decision was already handled, follow the pointer and\n search the linked file by topic or identifier. Historical decisions are evidence, not fresh\n authorization. A broken pointer is reported in the snag log; never guess or delete history.\n- **Work orders — only what's spent.** Pending orders are open boxes; they stay.\n A `## Work order` heading with no remaining box is leftover shell from a cut — delete it,\n do not file it. File only an order whose box was ticked in place, into the folder's\n `staging/work-orders.md`.\n- **Product research → the archive after its shift.** When no shift is active, append the completed\n entries from `$NS/product/product-research.md` to the folder's `product/product-research.md`,\n preserving their dates, sources, evidence, and conclusions; then restore the live file from the\n shipped template. During an active shift, leave all research live. Research is evidence, so never\n summarize it away or strip its source URLs while filing it.\n- **Opportunity map — only terminal outcomes.** Move `shipped` and `rejected` entries from\n `$NS/product/opportunity-map.md` into the folder's `product/opportunity-map.md`, preserving their\n evidence links and reasons. Keep `candidate`, `building`, and `parked` entries live: they can still\n affect a future cycle or need the owner. Restore the shipped headings if moving the last terminal\n entry leaves an empty section. Never renumber or silently change a status during archive.\n\n## Timing\n\nBest between shifts. During an active shift with open boxes, say so and ask before moving\nanything — the ticked lines are the night's scoreboard, and the owner may want the morning\nreview to see them in place. If the receipts repo exists (`$NS/.git`) **and**\n`receiptsAutoCommit` is true in `$NS/rules.json` (or `NIGHTSHIFT_RECEIPTS_AUTO_COMMIT=true`),\ncommit after archiving so the move itself has history. Default is false — leave the tree dirty\nfor the owner. When committing, use the same headless identity the clock-out gate uses, and\nturn signing off so a global `commit.gpgsign=true` cannot stall:\n\n```bash\ngit -C \"$NS\" add -A\ngit -C \"$NS\" -c user.name=nightshift -c user.email=nightshift@localhost \\\n -c commit.gpgsign=false commit -q -m \"archive\"\n```\n\nOn native Windows the same `git -C` flags work in PowerShell. Nothing to commit is success.\nNever add a remote, never push.\n\n## Retention\n\nAfter filing, preview generated history that the owner has opted in to prune. Run:\n\n```bash\n\"$NIGHTSHIFT_PLUGIN_ROOT/runtime/ns\" retain-history\n```\n\nPrint that preview verbatim — every eligible path, its age, and the governing rule\n(`retention.runtimeLogDays` or `retention.archiveDays`). Both default to `0` (keep forever);\na preview that lists nothing is success, not a prompt to invent a number.\n\nDeletion is a second, explicit step. If the preview lists paths and the owner confirms in this\ninteractive session, run the same command with `--apply` (POSIX) or `-Apply` (native Windows). If the shift is armed, the owner\ndoes not confirm, or either rule is `0`, stop after the preview. `--apply`/`-Apply` deletes only the\nallowlisted runtime log (`scheduled.log`) and shift folders — dated `archive/YYYY-MM-DD/` and\n`archive/YYYY-MM-DD-shift-N/`, and any folder a shift claimed in its `.shift-id` — that are old\nenough, resolved under `$NS/`, not symlinks, and free of still-open work. A claimed folder's punch\nlist is a copy whose open items stayed live, so it never holds work back.\n\nNever call `ns retain-history` from start, hooks, status, Doctor, or recovery. Never call `ns archive-receipts` from start, hooks, status, Doctor, or recovery. Never delete\nthe live punch list, drafting table, parking lot, rules, current shift files, or owner-authored\nfiles.\n\n## Index\n\nAfter filing, add the shift to the private history index: `history-index.md` at the top of the\narchive root (`archive/history-index.md` by default), one file and one shape on every host. When it\ndoes not exist but an `index.md` there opens with `# Archived shifts`, that file is the index under\nan older name: rename it to `history-index.md` and say so. Any other `index.md` is left alone. With\nneither, create the file with its heading:\n\n~~~markdown\n# Archived shifts\n\nOne entry per archived shift, from the history-context template. Fields not on record read unavailable.\n~~~\n\nEach shift is one entry in this shape. Its block is the history-context template in\n`$NIGHTSHIFT_PLUGIN_ROOT/skills/nightshift/references/receipts/cycle-specialist-evidence.md`:\n\n~~~markdown\n## <shift id, or unavailable> — <one-line objective> (<plugin version>)\n\n```text\n# history-context / preset\nobjective: <text>\ncontracts: <ids>\nverification: <profile>\nsources: <allowed locators>\nlimits: <hours, elevation>\n```\nhost: <host> · work target: <target, mode> · branch <branch> from <commit>\noutcome: <ticked of total; pull request, merge, release>\nevidence: <locators under the archive root>\ncommits: <count and tip, or the artifacts>\nduration: <start> → <end>\nending: <how the shift ended>\nrecord gaps: <what is missing or corrupt, or none>\n~~~\n\nFiling a shift again updates its entry instead of adding a second. Corrupt or missing fields are\nrecorded — never invented. Compare prior shifts from that index to reuse evidence locators and\nplans only; never replay side effects. Render audience-specific handoffs from one evidence truth.\n\n## Summarize\n\nPrint the shift's folder and one line per file moved or trimmed — and what stayed live and why.\nIf a retention preview ran, include whether anything was eligible and whether the owner\nconfirmed a delete.\n"
}SHA-256 of public snapshot: 2fd42994036558973a8577c24a81ee85cb510cb7c785cc75a76c8660ca4137e8