Skip to content

Latest commit

 

History

History
1082 lines (821 loc) · 91.1 KB

CHANGELOG.md

File metadata and controls

1082 lines (821 loc) · 91.1 KB

Changelog

Installs pin to the version in plugins/nightshift/.claude-plugin/plugin.json, so every entry here is a version users receive. Dates are release dates; the tags carry the exact trees.

0.26.1 (2026-10-09)

Bug Fixes

  • preserve planning restrictions and item accounting (f8735b4)

0.26.0 (2026-10-09)

Features

  • add soft and hard item budgets (9990b89)
  • add the plan room fence to hardhat (7bee67b)
  • add the plan room skill (f2212d5)
  • check drafted items before promotion (427120d)
  • estimate a shift from past receipts (d5e8bc1)
  • keep the plan room's decisions across sessions (c237fa6)
  • leave the plan room only on an owner command (cd445c8)
  • review the finished shift in the plan room (4333587)

Bug Fixes

  • arm the native Windows watchman with the dispatcher's flag spelling (41c9acf)
  • keep an open item's time and tokens across Reset (a4ab424)
  • show receipt and log times in the local time zone (4a8e7dd)
  • total every session of an item in its receipt and the index (e807a95)

0.25.4 (2026-10-01)

Bug Fixes

  • leave host permission configuration to the owner (b091c6a)

0.25.3 (2026-09-29)

Bug Fixes

  • archive: file only closed records, once (8386f64)

0.25.2 (2026-09-26)

Bug Fixes

  • arm the watchman for the right workspace and confirm it armed (eb13766)
  • report Codex input without the cached tokens it already counts (16646e7)
  • resolve Codex Windows hook paths inside PowerShell (e354be1)
  • revive a Codex turn that ended on an API error and keep an interrupted shift's accounting (6ea1660)

0.25.1 (2026-09-25)

Bug Fixes

  • claim a shift only through Start's binding probe (440a840)

0.25.0 (2026-09-25)

Features

  • file each shift into its own archive folder laid out like the live site (5851088)

0.24.1 (2026-09-25)

Bug Fixes

  • give the archive history index one name (12f341a)
  • keep a filed shift log when Start rotates the journal (fc56693)
  • name receipts by number, title and id (d215f76)
  • never let one shift take over another shift's archive folder (74b2d15)

0.24.0 (2026-09-24)

Features

  • group the .nightshift folder by purpose (08892b8)

Bug Fixes

  • end an inbox entry where the morning receipt ends it (e8bedd0)
  • file and retire usage folders on both runtimes (83e06bc)
  • find a UUID shift's archived policy in the morning receipt (aa91bee)
  • keep .nightshift/ ignored when the Windows workspace is its own repository (72dd478)
  • keep the segment's model when a reading reports none (57ed58b)
  • keep the shipped PowerShell ASCII so Windows PowerShell 5.1 reads it as written (1ba7363)
  • read only the ended shift's archived policy in the morning receipt (46dab64)
  • refuse to arm a shift policy that has already run (e3941c5)
  • show how parking-lot and snag-log entries are closed (b97d1aa)
  • stage drafting-table work only on the owner's request (61c4872)
  • write park-needs entries as bullets Archive can file (07bde30)

0.23.0 (2026-09-24)

Features

  • archive each shift's punch list with its contract (8182c7b)
  • charge time and tokens to the item being worked (6b002a0)
  • control token usage, duration and progress updates separately (dd6c01f)
  • give every punch-list item a permanent id (db50487)
  • make the morning receipt the end-of-shift verdict (0834c3d)

Bug Fixes

  • charge each ticked item to itself when ticks land out of order (9137ba3)
  • check the approved list before clocking out a finished shift (a509f2d)
  • count a capital [X] as a tick when labelling usage (04ecdc6)
  • file each same-day shift into its own archive folder (dc8ab60)
  • group the receipt-path and pause-window conditions for shellcheck (81685ac)
  • match the em dash in item labels under Windows PowerShell (a28d935)
  • name the cited-report checker check-report (442474a)
  • read the work target's history from inside it in the morning receipt (6b47ca7)
  • record tonight's snapshot when Start arms an uncomposed shift (a85c596)
  • round usage numbers the same way on every runtime (fb6c5be)
  • run the Windows schedule preflight under PowerShell off Windows (4ceb2cb)
  • say where archived receipts land in the Archive skill (77d8530)
  • state the receipt and fetched-text rules plainly in skill references (739f785)
  • stop repeating a progress reminder once the receipt is refreshed (389bb09)
  • take the plain Start snapshot right before arming (bce9980)

0.22.4 (2026-09-23)

Bug Fixes

  • list archived receipts in item order (3001bf6)

0.22.3 (2026-09-16)

Bug Fixes

  • idle only from the host project env, not $PWD (546f073)
  • stand hooks down before any work when no shift is armed (3cf74a4)

0.22.2 (2026-09-15)

Bug Fixes

  • file wrapped review entries and show usage as tables (956aab2)

0.22.1 (2026-09-14)

Bug Fixes

  • bound hook stdin and retire ticked receipts on archive (01ed97a)
  • drop the leftover session on stop and link the work target at setup (9ef17c5)
  • keep usage across stop and show every dimension on receipts (a4c2a42)
  • recover start and watchman after stop, silence, and denied spawn (735d407)

0.22.0 (2026-09-09)

Features

  • archive: link live review records to their filed history (f0544dc)
  • evidence: define baseline and checkpoint evidence guidance (c94585d)
  • receipts: inject the receipt duty at item start, cadence, tick, resume, and clock-out (52bac79)
  • replace the shift report with per-item receipts and a runtime index (11eb48e)

Bug Fixes

  • archive: file receipts by their item's state and keep their links whole (4e47489)
  • archive: report a broken Filed pointer and file leftover reports (bb529e5)
  • doctor: count receipt files, not report sections, when judging artifact completion (475268f)
  • doctor: point the unusable-path act at receipts (d8890c7)
  • hardhat: allow a parking-lot entry to name the rules file it is about (62b1793)
  • hardhat: quote a backslash without tripping shellcheck (1039e7f)
  • hardhat: refuse a parking-lot write that reaches the rules file (b83c5b0)
  • labels: keep hyphenated item titles whole (394f990)
  • manifests: describe the plugin as coding shifts (b82f3b2)
  • preflight-needs: print one report layout on every host (cfeae3a)
  • receipts: freeze tonight's receipts block and keep titles on the index (30e3f9b)
  • receipts: inject pulse notices only for the owning session (2804790)
  • receipts: keep empty Windows label lists empty (e0f7585)
  • receipts: print missing item numbers from the Windows list (9dd2425)
  • receipts: render the morning receipt from an accepted policy and link the index (c37c646)
  • runtime: name the exact path in a purge confirmation refusal (67f122f)
  • runtime: refuse an unknown link-workspace flag with usage (acdbcbb)
  • runtime: render the continuity fence as readable JSON (361d474)
  • runtime: say watchman absent when nothing ran (78acb95)

0.21.0 (2026-09-07)

Features

  • archive: file every record through one configured destination (2cceaed)
  • archive: give the model its turn to file before the session ends (5704413)
  • archive: support configurable lossless shift filing (fed1947)
  • gate: hold the punch-list contract and items by digest while a shift is armed (1baa5c9)
  • gate: send the full clock-out message only when the shift state changed (aaf9254)
  • policy: define unified owner settings contract (6f6560b)
  • policy: fix the owner's preferences for the shift that is running (40bc092)
  • policy: migrate remembered choices into the owner rules file (11e660b)
  • policy: resolve the owner's preference blocks into the one view (753947b)
  • receipts: support owner-defined handoff presentation (7f0107f)
  • report: accumulate item results and rotate closed shift records (ec41e02)
  • report: evaluate the progress cadence and the shift clock in the runtime (5cb22bb)
  • report: measure per-item usage from the host's own records at the tick (61c459e)
  • runtime: add the ns dispatcher — one verb per helper, host and workspace resolved by the runtime (1352562)
  • runtime: print the next punch-list item and the gates on request (803bfb4)
  • setup: scaffold the state directory with a helper (f3bd83e)
  • start: print the explanation and repair for each preflight verdict (7573143)
  • status: print every status fact from the helper (5b1963f)
  • usage: account for a shift's cost on native Windows (f9ddc8d)

Bug Fixes

  • archive: contain the whole destination path, not just its last part (d31db65)
  • archive: keep a finished shift's identity through its filing (8fda33f)
  • archive: rebase every relative link when the report moves (75b4a09)
  • archive: retire only the records established as closed (bb1664d)
  • evidence: reject unavailable sources without finding rows (6258746)
  • gate: account for a stop only once the stopping session owns the shift (a7734eb)
  • hardhat: inspect here-documents that an interpreter runs (4ed4c5c)
  • hardhat: read a quoted heredoc body as data, not as a command (0599338)
  • hooks: bound the read of a hook's stdin (ca14662)
  • hooks: run the Claude pulse's block after the functions it calls (a9e7adc)
  • hooks: ship the Windows SessionStart hook the dispatch file calls (27cef67)
  • normalize: reject incomplete JUnit reports (3f9387b)
  • normalize: retain TypeScript error counts or report unavailable (6d4f46e)
  • ns: honour the bound workspace, and refuse a mismatch before writing (c5a1912)
  • profiles: write remembered choices where they are read from (5cc24ac)
  • receipts: preserve evidence in clock-out handoffs (65518e7)
  • recovery: preserve authorized host permissions (b336057)
  • recovery: refuse a revival that cannot be shown to inherit its scope (67ad1e6)
  • recovery: resolve the launch scope the same way on every host (6f95ccc)
  • recovery: revive with the permissions the shift was started under (16d2d56)
  • references: give the GitHub issue hunt one spelling per command (dea9a6f)
  • references: point the catalog recipe at the cited-research page (5f1428e)
  • references: restore the names that are not commands to every receipt kind (86b62dc)
  • runtime: let native Windows evidence-archive name the file it wrote (3ac5b0a)
  • runtime: make the morning-receipt renderer executable (de83900)
  • runtime: make the native Windows morning page match the POSIX one (bf3f97e)
  • runtime: preserve owner policy without optional parsers (93597b0)
  • schema: apply a numeric bound to numbers, and restore the one on hours (118efcb)
  • skills: honor resolved owner choices across the shift (8c4fd25)
  • skills: repair three fragments left by the command-spelling pass (543d001)
  • skills: route the model to every receipt kind (5c7a2cf)
  • skills: state each rule once, and point at it (16675af)
  • start: keep the fence inspection and the control decision on their verdicts (ad17252)
  • start: offer linking as well as relaunching on a binding mismatch (f7253bf)
  • usage: bill only an armed shift its owner is working, and keep CI green on every host (eb1784c)
  • usage: count a response once when its lines straddle two reads (0b71bce)
  • usage: mark an item when it is ticked, not when the session stops (540e8e1)
  • usage: retire a finished shift's accounting when the next one arms (ee6e31e)
  • usage: start each transcript where it stood when the shift armed (96e849f)
  • watchman: keep a claim that has changed hands (311f64c)

0.20.0 (2026-09-05)

Features

  • start: one native preflight prints a verdict per line (ok / warn / refuse) and arms without asking, so a scheduled run behaves like an interactive one; it needs neither jq nor python3
  • hunt, quality: the owner's sentence is the objective — no keyword router. A time budget plus an actionable goal composes and runs directly. Feature, product, or UI work given to Quality continues as Hunt; quality tools do not hijack that night
  • policy: hooks read Nightshift's own rules.json with a bundled reader (POSIX awk + bash, Windows ConvertFrom-Json). A malformed file fails closed and does not arm
  • rules: five elevation categories — sudo, containers, global-packages, daemons, external-services — are denied by default. Elevation gates creating system state (docker run, brew install, path-prefixed or sh -c sudo); docker ps and brew list stay ordinary work. Built-in patterns match the shipped template whether or not the file carries an elevation object and whether or not jq is on PATH
  • receipts: the model writes the morning receipt from a template under .nightshift/receipts/. Status and Doctor show one resolved policy block and the source of every effective setting
  • runtime: the plugin ships no Python. Skills read helper verdicts instead of runbooks. Auto-add is the model plus a bash/PowerShell seatbelt (baseline / diff / rollback); there is no install engine and no pinned recipe catalog
  • catalog: 30 stand-alone shifts that use the project's own tools or report unavailable. Tooling hints name common tools; they pin no version and run no install
  • hosts: Claude Code, Codex, and Cursor share the same contract. Cursor's question tool is denied during a shift, same as the other two hosts

Bug Fixes

  • hardhat: control-file denies compare canonical absolute paths, so .nightshift//, /./, /../, and \\ forms cannot write shift-policy.json or the other control files
  • hardhat: STOP means stop work now; the hook stays armed until clock-out writes .ended. Reset is the explicit escape
  • runtime: the worker fence reads the on-disk lease / session / pid. A model-authored "I am not a duplicate" cannot take over; a missing fence refuses to arm
  • evidence: finding ids stay inside .nightshift; temps that hold tool output use mode 700. An unreadable punch list fails closed — clock-out does not release as "0 open"
  • policy: verification defaults to none on POSIX and Windows unless the owner or a profile set one
  • support: the default bundle is an allowlisted subset (version, markers, policy summary, counts). Raw scheduled.log and unrestricted evidence are omitted. There is no secret scanner and no "redacted / sanitized" claim
  • hooks: a punch list that exists but cannot be counted keeps hardhat armed on both engines
  • windows: PowerShell 5.1 no longer uses unguarded ProcessStartInfo.ArgumentList
  • docs: drop "optional Python / honest skip", "hardhat is a sandbox", and planner/redaction claims that the runtime does not keep

0.19.0 (2026-09-01)

Features

  • codex: stand watchman down on SessionEnd and pulse the bound session (8dc70eb)

Bug Fixes

  • claude: pulse the bound session so a quiet live tab is not guessed dead (38ba175)
  • cursor: keep a quiet IDE shift alive until the owner closes it (3a91882)
  • windows: accept SessionEnd stdin and age Codex recovery fixtures (431a200)

0.18.1 (2026-08-29)

Bug Fixes

  • cursor: keep Claude marketplace hooks off Cursor leases (9991770)

0.18.0 (2026-08-29)

Features

  • cursor: register the plugin in the repo-root marketplace file (fe03d00)

Bug Fixes

  • cursor: reuse the shipped Codex logo on the Cursor listing (050747b)

0.17.0 (2026-08-29)

Features

  • cursor: ask before writing CLI file hooks (51389c6)
  • cursor: revive dead shifts in a CLI worker (3c1af44)

Bug Fixes

  • cursor: tell the origin tab how to attach or stop (d26a867)

0.16.0 (2026-08-28)

Features

  • cursor: first-class Cursor plugin (a718ce6)
  • expose remaining owner knobs in rules.json (cac9368)

Bug Fixes

  • cursor: pass hook argv through to cursor_read_input (237f84f)
  • cursor: pin Stop interrupt to the live aborted payload (c4f3344)

0.15.0 (2026-08-28)

Features

  • add a finite research-synthesis catalog shift (c739695)
  • add a finite SEO audit catalog shift (ab17a81)
  • add a finite sourced documentation-writing shift (b09850e)
  • add a reusable cited research-and-report contract (53dfcd6)
  • add an isolated-branch rule profile (885f943)
  • copy artifact receipts into the dated archive with a helper (c34b9c8)
  • discover rule profiles from the shipped directory (9bbebc4)
  • inspect the work target during automatic Hunt selection (c1a0d47)
  • leave an Archive note when a campaign is fully filed (5fa842f)
  • name product-evolution branches for morning review (d0dbb49)
  • name the latest artifact receipt in Doctor (26fa7da)
  • offer to restore a leftover punch-list contract in Setup (cf6fb5b)
  • persist repository and artifact work modes (bb99a0b)
  • propose plugin and shell gates from Setup (f901756)
  • surface leftover punch-list contracts after a finished shift (e3bd09f)
  • warn when artifact ticks have no receipts (4fee9e9)
  • write artifact completion receipts without a git commit (19455ba)

Bug Fixes

  • bound terminal clock-out and restore the interactive lease (f695e15)
  • claim a real session record over a planted shift-session symlink (20a0049)
  • close git -C and git -c holes in isolated-branch (845e853)
  • cut proposed imports through the promote helper on Schedule (d0a75a2)
  • cut proposed imports through the promote helper on Start (ebcd07e)
  • cut the whole work-order section, not just the box (b5fbc6a)
  • detect plugin gates under plugins/<name> (515d64c)
  • diagnose empty watchman recovery keys in Doctor (fbcd448)
  • disarm Stop immediately and add Reset and Purge helpers (dd1b96a)
  • do not count the drafting-table example as staged work (85da326)
  • do not follow dated archive symlinks when detecting known issues (b203984)
  • Doctor offers Setup when unset mode would be artifact (d1f7af7)
  • Doctor warns when unset mode would be artifact (a8e77ed)
  • export-support does not treat a symlink armed marker as armed (fd191d6)
  • export-support does not treat a symlink ended marker as clocked out (962f2b6)
  • export-support does not treat a symlink session-end as a clean exit (7935d4d)
  • export-support does not treat a symlink shift-session as recorded (ba922b6)
  • export-support reads plugin name without jq (b51c59d)
  • fail closed Windows protected-dir git-dir writes (61da12b)
  • fail schedule preflight on empty watchman recovery keys (baf03e2)
  • give Hunt and Quality the same four-file state map (48f5c10)
  • give Status native Windows deadline and reason helpers (4db762a)
  • Hunt refuses to compose on an unset notes folder (81a8ac3)
  • Hunt refuses to compose when the work target cannot be resolved (9cc706e)
  • Hunt refuses to compose when work-mode is malformed (410069b)
  • ignore nested files under artifact receipts (980c4f3)
  • import the Windows module before Hunt identity check (f47c5fb)
  • inspect artifact folders during automatic Hunt and Quality (77730b3)
  • inspect the work target in open-ended catalog shifts (60ed28b)
  • isolate open-ended catalog shifts without git-init (d3890f3)
  • keep Hunt's one-shift contract mode-aware (3fe25e9)
  • keep TrustedShiftControl array-safe under StrictMode (8e5c4d3)
  • let Quality detect nested plugin manifests (1295dda)
  • match the Windows session-end marker to POSIX (00eaf8e)
  • match Windows Doctor process start times (a82a272)
  • match Windows expected-email denials to POSIX (bb7884c)
  • match Windows forbidden-command denials to POSIX (2b438cb)
  • match Windows never-commit denials to POSIX (6dc0f40)
  • match Windows watchman pid to its start time (218d7e1)
  • match Windows watchman start before Start stand-down (ed44002)
  • name artifact receipts in revival and Start work (fe7a196)
  • name Hunt and Quality watchman launchers (c046d54)
  • name native flags in Windows helper errors (14460b1)
  • name parked work when schedule preflight finds an empty list (5605df6)
  • name portable dates for archive folders (daf6450)
  • name Setup in the Windows unreadable-rules clock-out (2be4ea3)
  • name Setup in Windows toolDeny hardhat repairs (6105c43)
  • name Setup when Windows schedule finds no state (7586cbf)
  • name Setup when Windows watchman cannot read rules (c962111)
  • name the env var when a Windows pattern is invalid (64ff559)
  • name the headless receipts commit in Archive (2615386)
  • name Windows Codex agent flag in Schedule permissions (4f1655b)
  • name Windows JSON key listing in Setup and Start (156e9a3)
  • name Windows lease helpers in Start preflight (26a66a6)
  • name Windows schedule list and remove in the skill (9353e95)
  • offer a replace action when receipts path is unusable (2d732d8)
  • pair Windows import-issues flags in the skill steps (486b6c1)
  • pick the latest artifact receipt by mtime (8be7d04)
  • rank Automatic Hunt by work-target evidence (aa09eca)
  • read Status process liveness from Doctor (d2f4f7f)
  • refuse a non-directory archive dest (213970d)
  • refuse a non-directory archive receipts source (8251266)
  • refuse a non-directory receipts path (f20426f)
  • refuse a symlink receipts directory (71f1875)
  • refuse Hunt compose when artifact receipts path is unusable (bc9bb04)
  • refuse symlink outputs in Windows check-report (12b9ce0)
  • refuse symlink outputs in Windows write-receipt (cbe941e)
  • refuse to arm Start when watchman recovery keys are empty (42a4f11)
  • refuse to arm when artifact receipts path is unusable (6673369)
  • refuse to schedule when artifact receipts path is unusable (e7df569)
  • refuse Windows profile apply while a shift is armed (0a3abec)
  • report the deadline file from Doctor (3429a13)
  • restore punch-list history without git-init of notes folders (f763f03)
  • run Hunt Codex identity check before watchman (2272694)
  • run the item gate before a commit or artifact receipt (5f6e99c)
  • satisfy Ubuntu ShellCheck and Windows PowerShell parsing (e754c6e)
  • Schedule refuses an unset notes folder (fa3f6ed)
  • Schedule refuses when the work target cannot be resolved (5ff4971)
  • send Quality cuts through the Hunt work-order file (f267324)
  • skip a symlink child git repo when proposing work mode (8035762)
  • skip a symlink shift-session in watchmen and session-end (f48af51)
  • skip Automatic Hunt entries the work target cannot support (0d9445c)
  • skip coverage hunt in artifact mode (6f1d459)
  • skip defect hunt in artifact mode (238344c)
  • skip documentation drift in artifact mode (a06a0ed)
  • skip empty dated folders when nothing copies (45cac1a)
  • skip Quality entries the work target cannot support (7b2d6eb)
  • skip symlink dated archive dirs at retention listing (b9adc46)
  • skip symlink files in Windows receipt count (6781bdd)
  • skip symlink punch-lists in Windows archive retention (b21d577)
  • skip the GitHub issue hunt in artifact mode (5d6c085)
  • skip TODO and FIXME debt in artifact mode (09cbaff)
  • skip tooling quality-debt catalog entries in artifact mode (46fb925)
  • Start refuses to arm an unset notes folder (2daff15)
  • stop Windows import-issues from eating issue URLs as -Repo (295689a)
  • treat a symlink deadline as not passed (6851eeb)
  • treat a symlink ended marker as not a clock-out (83cd676)
  • treat a symlink notified marker as not a prior whistle (3ab26c2)
  • treat a symlink session-end as not a clean exit (5bf1d79)
  • treat a symlink shift-session as not a recorded session (5ab3e26)
  • treat a symlink stall as not a stall count (a613f8b)
  • treat a symlink watchman pidfile as not a live owner (66edf0d)
  • treat a symlink work-mode file as malformed (5123fbb)
  • treat a symlink work-target file as unreadable (c43172e)
  • unblock bats pins and Windows CI parse/bind failures (aea6465)
  • warn on empty punch list in Windows schedule generate (3357fce)
  • warn when the artifact receipts path is unusable (8d3b469)
  • Windows setup refuses a notes folder before scaffolding (bd7511f)
  • Windows setup refuses default repository on a notes folder (519e0c3)
  • write Hunt and Start deadlines as UNIX epochs (f54643d)

0.14.5 (2026-08-26)

Bug Fixes

  • hooks: classify the session host from its transcript path (07f52e4)

0.14.4 (2026-08-23)

Bug Fixes

  • clarify persistent workspace guidance (629e3b3)

0.14.3 (2026-08-19)

Bug Fixes

  • stop treating the process-lease id as a secret (6eb196d)

0.14.2 (2026-08-19)

Bug Fixes

  • qualify Nightshift paths and pair native Windows helpers (7232b3d)

0.14.1 (2026-08-18)

Bug Fixes

  • hardhat: check Git paths for protectedDirs (f1f3d26)
  • hardhat: inspect the commit Git would write (a84c225)
  • hardhat: protect armed-shift control files (bc2e047)

0.14.0 (2026-08-18)

Features

  • compatibility: verify remote development environments (4051f7c)
  • recovery: fence concurrent shift processes (3efbac8)
  • windows: add native runtime support (7d80a66)

Bug Fixes

  • share shift ownership and close review gaps (e3643e9)
  • skills: align host roots and shift lifecycle (46287d1)

0.13.1 (2026-08-15)

Bug Fixes

  • preserve the directory subtitle in uploads (c230e7d)

0.13.0 (2026-08-15)

Features

  • shifts: add custom timed owner walkthroughs (4e484ed)

0.12.0 (2026-08-14)

Features

  • archive: add explicit history retention (1e4cc4f)
  • catalog: add GitHub issue hunts (c2257d7)
  • doctor: export redacted support bundles (f63deb8)
  • github: stage selected issues for shifts (c182ef2)
  • rules: add opt-in local profiles (d2ddbe7)
  • schedule: generate systemd user timers (7c6a010)
  • state: version Nightshift workspaces (45cfeb9)

Bug Fixes

  • ci: align Linux portability checks (9162265)
  • ci: harden Linux runtime portability (2c47003)
  • github: roll back partial queue promotion (f090099)
  • recovery: support minimal process environments (4391c1f)

0.11.0 (2026-08-14)

Features

  • catalog: add accessibility repair shift (aa1c0e4)
  • catalog: add API contract drift shift (8c12b05)
  • catalog: add dead-code cleanup shift (410bd66)
  • catalog: add flaky-test repair shift (f289d53)
  • catalog: add localization parity shift (323d21f)
  • catalog: add TODO debt shift (593ea7b)
  • shifts: add guided and automatic execution modes (52946d1)

0.10.0 (2026-08-14)

Features

  • catalog: add a CI warning cleanup shift (c26b6b0)
  • catalog: add a documentation drift shift (3ae803b)
  • community: add a catalog shift proposal form (ce24c61)
  • community: add a safe failed-shift report form (20681e1)
  • config: add a schema for Nightshift rules (0b22de5)
  • diagnostics: add a read-only Nightshift Doctor (28c22eb)
  • harden Nightshift diagnostics and cross-host reliability (#92) (08e3263)
  • recovery: expose reason-coded watchman outcomes (16bc18d)
  • schedule: add a no-install preflight check (e0f3b83)

Bug Fixes

  • codex: reject non-resumable session identities (1227a01)
  • runtime: close shift review gaps (e530363)

0.9.4 (2026-08-13)

Bug Fixes

  • codex: park native user questions during shifts (a058e36)
  • codex: park native user questions during shifts (#58) (a39626e)

0.9.3 (2026-08-12)

Bug Fixes

  • state: align remaining active-shift checks (7108184)
  • workspace: link tasks to authoritative shift state (a3a1992)
  • workspace: reject ambiguous link files (13235d6)

0.9.2 (2026-08-12)

Bug Fixes

  • harden Nightshift across Claude Code and Codex (#53) (2ebfce5)
  • hardhat: align active-shift detection across hosts (0374ac8)
  • schedule: safely encode generated cron and launchd paths (e713d3c)
  • session: always record the Claude host in shift identity (bdfb0aa)
  • setup: resolve a single repository inside parent workspaces (20424b1)
  • skills: clarify state-file roles across model workflows (6ef7014)
  • test: measure coverage from current plugin paths (0a3e6f7)

0.9.1 (2026-08-12)

Bug Fixes

  • redirect temporary ChatGPT workspaces (809c906)

0.9.0 (2026-08-12)

Features

  • add evidence-backed product evolution to the ready-made hunt catalog
  • preserve active opportunity progress across compaction and resumed sessions
  • integrate product research and opportunity tracking with setup, status, and archive
  • make Codex a first-class host alongside Claude Code (7f62a2d)

0.8.1 (2026-08-05)

Bug Fixes

  • Codex packaging and host wording catch up to the release (a1ab3a1)

0.8.0 (2026-08-05)

nightshift runs on OpenAI Codex. One package, a manifest per host, and the same night either way — the gate, the guards, the skills, the scheduler, and the watchman.

Features

  • the Codex clock-out gate and hardhat enforce the same shift — Claude's decisions behind Codex's own hook wiring, verified in a live session (2bac060)
  • the night watchman works Codex shifts — a killed session is revived into its own conversation and the list is finished with nobody attached, verified with a live SIGKILL mid-shift (fc3510f)
  • the shift record names its host, so each watchman minds only its own shifts (19d619f)
  • the skills speak both hosts — permissions, liveness and the watchman step fork per host, and the schedule generator takes --agent so one entry serves either runner (349bfed)
  • Codex install is advertised: the .agents marketplace entry and the README's codex plugin commands (e52c18a)

Unattended Codex runs that commit use the danger-full-access sandbox — workspace-write blocks git commit. nightshift's guards hold in every mode. A Codex session alive at an API error is stood by, not revived.

v0.7.4 — the plugin is a subdirectory

The plugin ships from plugin/. Tests, CI workflows and the README's screenshots no longer install with it: an install is 216 KB, down from 876 KB.

v0.7.3 — a shift is a file

Catalog entries live one per file in skills/nightshift/references/shifts/, and /nightshift:hunt lists that directory rather than reading a single page. Adding a shift is two new files — the entry and its test — with no edit to anything shared, so two people can contribute one the same week without meeting in a diff. The structural rules glob the directory, so a new entry is checked the moment it lands: its title declares its ending, and it carries a pasteable item, a Verify line and a stated ending condition.

Two entries join the catalog, both finite, both working from a list the project's own tooling produces:

  • Dependency upgrade sweep — direct dependencies brought current one at a time, patches before majors, each behind the item gate and its own commit. The release notes are the work: a version bump that compiles is not an upgrade. A major that sprawls past a bounded attempt is reverted clean and parked, because a half-migrated major leaves the tree worse than the old version did. Prereleases are refused, and the lockfile, the package manager and the runtime version are the owner's.
  • Vulnerability sweep — advisories cleared critical-first, so an interrupted night cleared what mattered. It never downgrades to satisfy an advisory and never adds a suppression: where the only offered fix is an older version, or the advisory sits in a transitive dependency, it parks the decision with the link and the severity.

v0.7.2 — a shift starts when you start it

/nightshift:start is what puts a session on shift. It writes .nightshift/.shift-armed, and until that marker exists the punch list is an ordinary to-do file — the clock-out gate holds nobody, hardhat's guards apply to no one, and a session that writes items while planning still stops freely. Every way in already runs start: interactively, from the scheduler's claude -p '/nightshift:start', and through a revival that re-claims the record it left behind.

  • The gate binds the session start hands it. The hooks read the shift record; they no longer create one, so the shift is never inherited by whichever session happens to trip a hook first. Ending a shift disarms the site, so the guards leave with the night that needed them.
  • Boxes count under the ## Items heading only. A checkbox anywhere above it is contract prose — an owner's note, an example — and holds nothing. The watchman counts the same range as the gate, so the two can't disagree about whether work remains.
  • The contract names the Items list without repeating its heading, leaving one ## Items in the file for anything that splits on it.
  • Every path that starts a shift arms it — /nightshift:hunt answering now and /nightshift:quality answering fix now both begin the shift where they stand, so both write the marker. A stop-work order disarms the site whether or not a list survived to summarise.
  • /nightshift:status says whether a shift is running, rather than leaving open boxes to imply it, and counts the same range the gate does.
  • Fifteen tests cover the arming boundary from both sides.

v0.7.1 — the site is where the owner put it

Every skill resolves .nightshift/ and .claude/ against $CLAUDE_PROJECT_DIR, so the site stays the site no matter where a shell has wandered. The working directory persists between commands and follows gates, builds, and stack detection into the code repo; on the recommended layout — the code repo a level below the project root — anything written relative to it lands in the repo instead of the site.

  • Permissions reach the project. /nightshift:setup writes $CLAUDE_PROJECT_DIR/.claude/settings.local.json, the file a headless revival inherits. A copy anywhere else grants the project nothing, and the night finds out at its first prompt.
  • Scaffolding, rules, gates, and the receipts repo are placed by path, not by proximity. The receipts repo is created with git -C, since git init follows the working directory too.
  • Six tests hold the rule across every skill, including ones not written yet.

v0.7.0 — one place composes work, one place starts it

/nightshift:start asks nothing. Everything it needs was decided when the work was composed, so the same command serves an interactive start, a headless revival, and a scheduled one. That single property is what makes an unattended night schedulable at all, and it is why the ready shifts moved: a command that prompts cannot run while its owner sleeps.

  • /nightshift:hunt composes the shift. It offers the whole catalog rather than three fixed presets, takes more than one entry per night, asks for hours only where the ending needs them, and takes one free-text answer for scope — "only packages/api/", "use the in-memory test harness" — added as its own bullet beneath the entry's contract, never in place of it. The assembled shift is shown exactly as it will be written before anything is armed, and answering now starts it there — no second command to type.
  • /nightshift:quality closes the same way. After the read-only scan it offers three answers: fix now, which writes the items and starts the shift; draft for later, which stages them on the drafting table and arms nothing; or ignore. The punch list is written on nothing but an explicit fix now — an open box arms the gate for the current session, so the box and the start belong together or neither happens.
  • /nightshift:start executes what it finds. With open items in the punch list it asks nothing and promotes nothing — parked orders and drafts stay where the owner left them, and the list is the shift exactly as written. Only when the punch list is empty does it speak: it shows what is parked and asks which to work. A cut is a move, never a copy, so an item never exists in two files. The deadline is read rather than requested, a spent one is swept as a leftover while one still in the future survives as tonight's plan, and an open-ended walkthrough with no clock is refused rather than started.
  • The shift catalog is the contribution surface. shift-catalog.md gains a finite entry, clear quality debt, beside the three open-ended hunts, and catalog-recipe.md states what a new entry must declare: its ending, how it discovers work, its definition of done, what it will never do, its verification, and the stacks it supports. Entries are markdown; they touch no hooks, so the catalog can grow without the product growing.
  • /nightshift:schedule — the scheduler nightshift will not become. It checks what an owner would otherwise discover at 4am — that work is actually queued in the punch list, that headless permissions will not stall the run, that nothing is registered twice — then prints the launchd plist or crontab line for the project and the single command that installs it. It registers nothing itself, because waiting for a clock stays the operating system's job: a process that sleeps for hours dies to a closed lid. Underneath it, adapters/schedule.sh is plain shell that spends no model tokens and needs no session. That is not an implementation detail — the moment an owner most wants to schedule a run is the moment their quota is gone, and a slash command is read by the model. The README documents the script directly for exactly that day. It refuses a second entry where one exists (two scheduled starts on one punch list is two agents on one shift), identifies a project by path rather than folder name so two checkouts named api never collide, and says plainly that a sleeping machine runs nothing.
  • foreman is removed. It existed because Claude Code was once the only agent with hooks; Cursor, Codex and Kimi now ship lifecycle hooks of their own, so a generic outer loop is the weakest possible way to serve any of them. nightshift extends Claude Code through Claude Code's own extension points, and the README and CONTRIBUTING now say so as a scope rule: no schedulers, no dashboards, no second install channel.

v0.6.1 — one copy

The rules file is the config, and it lives with everything else nightshift owns: .nightshift/rules.json, copied as-is from the shipped template by setup, read by the hooks directly on every tool call — an owner's edit applies from the very next action, nothing is synced into settings, nothing needs a restart, and deleting .nightshift/ removes all of nightshift, rules included. Env vars of the matching names remain session-start overrides — the test suite's lever and the one-off exception, never a copy to maintain.

  • The night never touches its own leash. During a shift, the working session is denied the rules file — file tools and shell commands alike, the same pattern-match honesty as every guard here. A rule that must change mid-shift changes by the owner's hand and reads from the next tool call.
  • Setup migrates and cleans. A pre-0.6.1 .claude/nightshift-rules.json is moved into .nightshift/ (the hooks read the old home as a fallback until then), and setup offers to strip the NIGHTSHIFT_* env keys an earlier version synced. The receipts-repo question is asked neutrally: its default is no, and it is never presented as recommended.
  • The watchman reads its own cadence (watchMinutes, watchRetrySeconds, notifyCommand, both revival orders) from the rules file at arm time; start no longer passes an interval.
  • No hidden defaults. Every shipped value — both revival orders, the clock-out reinjection, the park message, the cadences — lives visibly in the template setup copies; the hooks carry no fallback copies. A missing or unreadable rules file fails loudly and closed: the gate still blocks, questions stay parked, the watchman refuses to arm — each naming the repair.

v0.6.0 — the 500 night, start to finish

Start a shift, watch the very first call come back API Error: 500, and go to sleep anyway: the watchman now carries that night from the first error to the morning receipts, and the whole story — the 500, the revival, the finished work — is one conversation you open with one click.

  • The wedge is the transcript's last word, read structurally. Claude Code records an API failure as its own synthetic event, flagged isApiErrorMessage:true; the watchman requires that flag on the last conversation event before calling a live-but-quiet session wedged. An owner pasting an error report as a prompt, or an error the session already retried past, no longer reads as a wedge — if anything followed the error, somebody was there, and that session is not the watchman's to touch. The owner's Esc is read by the same rule: an interrupt is a pause only as the last conversation event — one the owner already resumed past is history, and a real death after that resume reads as death.
  • A 500 before first work is still the wedge. The shift records its identity at the first tool call — but an outage can land before any tool runs, leaving no record. A project whose newest conversation ends in the host's error event now revives via --continue, which resumes that very conversation, instead of standing by all night behind "a live claude session in the project".
  • Session-first, and only the session. The verdict reads the session's own signals in order — the owner's Esc above all, the shift's transcript, the recorded process, then the host's registry: claude agents --json listing the recorded id is the host saying alive (it even rescues a stale pid), and a clean roster without it is death evidence no folder churn can drown out. Project files never vote — a detached loop, a build, or a sync can neither mute the owner's Esc nor mask a dead session as alive.
  • Revival orders match what the session knows. A resumed conversation carries its own context, so its order is one line: cut off, continue — the contract already lives in the thread, and the gate enforces the ending. The fresh-session fallback starts empty and gets the full pointer at the punch list. Both texts are the owner's (revivalPrompt, freshRevivalPrompt).
  • The morning is one click away. A successful revival leaves a notice in parking-lot.md — the file the owner reads — with the thread's handles: claude --resume <id> for the terminal, the cursor:// and vscode:// deep links for the IDE panel. The first thing you open is the exact conversation: the error, the revival, and everything it finished. The one night event that needs the owner — a dead session no attempt could bring back — rings the morning whistle instead, once per outage.
  • Tighter cadence. The watch interval defaults to 10 minutes (NIGHTSHIFT_WATCH=N still sets it), and a dead API never stretches the rhythm: three tries per wake, every wake, until the API answers.
  • The night cannot click Allow. Setup now asks to enable bypassPermissions in the project's settings (recommended; written to .claude/settings.local.json so revivals inherit it), start warns once when no frictionless grant exists, and the README says the trade plainly. nightshift's guards are hooks and stay armed in every permission mode.
  • One rules file, every decision the owner's. Setup copies a ready template to .claude/nightshift-rules.json and syncs it into the env block — clean JSON to edit, the escaping machine-written. It carries the per-tool denial map (toolDeny: your message per tool, an empty message lifts a rule, absent keys keep the defaults), every guard pattern, the stall cap and warning cadence, the watch cadence, the morning whistle, the watchman's revival orders, and the gate's clock-out reinjection. The env stays the enforcement surface, fixed at session start — the file is the owner's editor, never the agent's lever — and start warns when the file drifts from the running session's rules. Re-running setup after an update offers what the new template added — missing keys, a changed contract — and never touches the owner's words.
  • The receipts repo is opt-in. A git repo living inside the project is not everyone's taste: setup now asks before git init-ing .nightshift/, and the default is no — the receipts remain as plain files, and the gate's snapshot commit is a no-op without the repo.
  • /nightshift:archive — the finished part becomes a dated record. Ticked items move into archive/<date>/shipped.md, the journal rotates whole, snags and parked questions move only once they carry the owner's answer. The live files stay lean; what shipped stays on disk as plain dated facts. Start auto-rotates a journal past ~500 KB into the same archive.
  • The shift binds one session. The gate holds, and the site rules govern, the recorded shift session alone — a second conversation in the same project chats, stops, and asks freely; the night is not its business unless the owner brings it. A watchman revival stays bound under whatever id the fallback chain gave it and re-claims the record, so the watchman follows the living thread. Start refuses to start a second agent beside a living one — it hands the owner the running thread's claude --resume and IDE deep link instead.
  • One writer per site. Two sessions stopping at once could tear the stall counter, double the morning whistle, or collide in the receipts repo. The gate's decision tail now runs under a per-site lock (mkdir-based — every platform has it; a dead holder's lock is broken on sight, a live one is waited on, bounded), and the whistle marker is claimed with an exclusive create. The wait can never hang a session: an unlockable site is decided unlocked.

v0.5.2 — strong evidence of death

The one truly harmful watchman failure is spawning a second agent beside a living one: a resumed id APPENDS to the same session, so two writers interleave into one conversation while sharing a working tree. v0.5.0 read liveness from project files alone — long reasoning, research, or a 25-minute test run writes none and looked dead. Revival now requires strong positive evidence of death, never "looks stuck".

  • Liveness is a ladder. The shift's transcript is the primary pulse — a live session streams every turn into it, project files or not. Project activity stays as the second rung. Then the process witness: the hooks record the claude ancestor's pid and start time alongside the session id, and the watchman checks that exact process — kill -0 plus the start time, a pair no pid reuse can counterfeit. Alive with a quiet, unerrored transcript is long silent work: stand by. Dead is dead even while other tabs live in the project: revive. No pid recorded degrades to the conservative reading — any claude process working in the project stands the watchman by.
  • The 500 wedge is recognized, not guessed. Claude Code writes API failures verbatim into the transcript ("API Error: 500 …", "529 Overloaded"). A live shift process whose quiet transcript ends in one is a session sitting at an errored prompt with nobody there to press retry — the night the watchman exists for. That combination revives; prose merely mentioning API errors does not match.
  • Every retry re-checks the whole ladder first. A site that comes back to life mid-wake — or an owner who acts — cancels the remaining attempts. Each failed attempt re-baselines the sentinel, so the watchman's own error events in the transcript never read as site life.
  • The revival chain is real and logged per rung: the recorded conversation first, claude --continue next, a fresh claude -p last — the morning log says exactly which recovery level carried the night.
  • The identity claim is atomic. .shift-session is taken with an exclusive create — two racing first sessions cannot interleave; one record lands whole.
  • A revival's own exit is not the owner's hand on the door. Spawned sessions carry a mark, and the SessionEnd hook stays inert for them — without it, the worker finishing (or dying on the API again) would write the clean-end marker under the recorded id and stand the watchman down mid-outage after the first revival.

v0.5.1 — the shift knows its own session

Live dogfooding with two tabs in one project exposed the guess in v0.5.0: the watchman read "the newest transcript" for the Esc tell and revived with --continue, and with a second session in the project both could point at the wrong conversation.

  • The shift records its own identity. Every hook receives the session id and transcript path; the first session to work under an active shift writes them to .nightshift/.shift-session, once. A second tab never overwrites the record.
  • The Esc tell reads the shift's own transcript — a helper tab's interrupt proves nothing and is ignored. No record yet falls back to the newest transcript in the project.
  • The revival is claude --resume <that id> -p — the shift's exact conversation, with everything it knew before the crash: hours of context, decisions, where it stood mid-item. No record yet means --continue, and the last retry of a wake still falls back to a fresh session.
  • The clean-exit marker is the shift's alone — SessionEnd writes it only when the ending session matches the record, so closing an unrelated tab in the same project no longer stands the watchman down.
  • start and the hunt cut clear the record with the other markers; setup gitignores it in the receipts repo.

v0.5.0 — the night watchman

A Stop hook can only act inside a living session. A session killed by an API outage, a crash, or a closed terminal fires no hooks — the punch list survived on disk, but nothing re-invoked the agent, and the night was lost. The watchman is the outside half.

The watchman

  • adapters/watchman.sh, armed in the background by /nightshift:start and the hunt cut. It wakes every 20 minutes (NIGHTSHIFT_WATCH=N minutes; 0 disarms) and, only when boxes are open and nothing in the project has changed since the last wake, sends the conversation back to work.
  • It stands down at every honest ending: a stop-work order, an ended shift, every box ticked, a spent deadline, or a clean session exit. A crash at the finish line still gets its clock-out — all-ticked-but-never-released and dead-past-deadline each spawn one closing run, so receipts and the morning whistle happen even when the session died first.
  • An API outage costs a handful of logged attempts, not one per tick: 2–3 spawn tries per wake spaced ~30s/2m, then the interval backs off, doubling per failed wake up to 8×.
  • One watchman per site (a pid file; a stale one is taken over). Esc still means stop: Claude Code records a user interrupt in the session transcript and a 500 or a crash never does — that is the tell. At a quiet wake the watchman reads the transcript tail: interrupt there, it stands by; none, it revives. Unreadable defaults to reviving — waking a paused session costs an apology, a lost night costs the night.
  • The revival is claude --continue -p by default — it chains onto the same conversation, so the morning transcript is one unbroken thread in the terminal and the IDE extension alike. On the default agent, the last retry of a wake falls back to a fresh claude -p: if the transcript itself is what broke, --continue would fail every wake forever, and the punch list on disk is enough for a fresh session to carry on. NIGHTSHIFT_WATCH_AGENT overrides the command entirely.

Hooks

  • A SessionEnd hook writes .nightshift/.session-end when a session ends cleanly during an active shift. Crashes and kills never reach the hook — which is the tell: marker means the owner's hand closed the session and the watchman stands down; no marker means it died and the watchman revives it. start and the hunt cut clear the marker, re-arming the night.

v0.4.2 — overrides the guards can't read are denied

Guards

  • A commit that relocates itself with --git-dir or --work-tree is denied whenever a commit guard is configured. The guards resolve git -C <dir> and cd <dir> &&, but those two flags point the commit past that resolution — the guard would inspect one repository while the commit lands in another. Unverifiable means denied, exactly like the ambiguous-repo case.
  • With an expected identity configured, a commit that overrides identity on the command line — -c user.email=, --author, or a GIT_AUTHOR_EMAIL/GIT_COMMITTER_EMAIL prefix — is denied. The guard reads the repository's configuration, and with an override present that read describes nothing.
  • The no-push recipe is now git .*push, so config injection (git -c k=v push) cannot slip between the words. Commit messages remain scrubbed first: a message mentioning a flag is not a use of it.

Docs

  • The fine print states what the gate re-injects: the full working standard, at every stop attempt, so it never decays out of context — alongside what it cannot prove.

v0.4.1 — a page of its own

  • homepage in both manifests points at https://orwamahmoud.com/nightshift/, which explains what the plugin does and what it deliberately does not. repository still points at the source, so the two fields no longer say the same thing.

v0.4.0 — guards look where the commit lands

Guards

  • Commit guards inspect the repository a command names — git -C <dir>, cd <dir> && — instead of the session's working directory, so a commit aimed at a sibling repo is checked where it lands. Where the target is genuinely ambiguous they deny rather than guess.
  • The never-commit sweep widens from the index to the working tree against HEAD whenever a command stages implicitly. git commit -a and pathspec commits stage as they run, so the index alone never described them.
  • Guards resolve correctly for projects under a dotted path. The child-skipping rule matched any hidden component anywhere in the path, which denied every commit in such a project.
  • A stop-work order keeps the site rules armed. The agent works on until its next stop attempt, and the gate now writes .nightshift/.ended when it truly releases — that alone stands the rules down.
  • An unparseable NIGHTSHIFT_FORBIDDEN_COMMANDS or NIGHTSHIFT_NEVER_COMMIT_PATTERNS is refused with a message instead of reading as "no match".
  • NIGHTSHIFT_PROTECTED_DIRS matches whole path components, so ai_docs no longer condemns ai_docs_public, and only a commit message is blanked before matching — a forbidden command inside quotes is still seen.

Shifts

  • /nightshift:start and /nightshift:hunt clear the same five stale markers before anything writes a new deadline. A spent deadline used to end the next shift at its first stop attempt with nothing done; a leftover stop-work order made a hunt a no-op.
  • /nightshift:quality puts accepted proposals on the drafting table. Writing them straight into the punch list armed the clock-out gate for every session in the project, including the one that ran the command.
  • A commit in the repo below the project dir counts as progress, in the clock-out gate and in foreman alike — the recommended layout puts it there.
  • Receipts commit with signing disabled, so a global commit.gpgsign cannot silently discard the night's record, and a failed receipts commit is logged rather than swallowed.
  • foreman.sh rejects an option with no value instead of spinning forever on a shift that cannot move.

Packaging and docs

  • Slash commands live in skills/, the layout the plugin docs recommend. Invocation names are unchanged.
  • Every guard is documented as shift-scoped, the stop-work order as landing at the next stop attempt, and the deadline as a whistle rather than an axe.
  • Releases are tagged from the manifest version by CI, and a pull request that changes shipped files without bumping it fails.

v0.3.0 — a stalled shift is held, never sent home

  • A stalled shift is held and red-flagged by default instead of being clocked out; NIGHTSHIFT_STALL_MAX=N restores auto-clock-out, in the gate and the foreman loop alike.
  • /nightshift:hunt stages the ready-made overnight jobs as work orders — the item and its hours park together, and the cut starts the clock.
  • Hook and foreman hardening from a review pass, each finding with a test.

v0.2.0 — nothing is blocked out of the box

  • Nothing is blocked out of the box. Every safety rule became the owner's opt-in, replacing the built-in denials.
  • /nightshift:quality added; the spot-check hook retired.
  • CI validates the plugin and marketplace manifests on every push.

v0.1.0 — the clock-out gate

  • First release: the clock-out gate (Stop hook), hardhat (PreToolUse guard), park-don't-ask, the morning whistle, the nightshift skill, the punch-list/parking-lot/snag-log templates, stack-aware gates, /nightshift:setup|start|status|stop, and adapters/foreman.sh for other agent CLIs.