aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* fix(audit): exclude retired projects from the sync target listCraig Jennings6 days2-0/+21
| | | | The audit's project discovery uses find -maxdepth 3, which reaches ~/projects/.retired/<name>/.ai — one level deeper than a live project — so shelved projects were getting template syncs they should never receive. Skip any project under a .retired/ ancestor explicitly, so the exclusion holds regardless of the find depth.
* feat(triage): add a per-sweep timestamp to auto mode outputCraig Jennings6 days3-4/+18
| | | | | | Auto-mode sweeps now end with the date, time, and timezone on their own final line, so an away reader gauges each summary's freshness at a glance without computing it. The stamp prints on every sweep, including a quiet "no changes" one — there the stamp is the proof the loop ran. Same-day addendum to the work-project auto-mode proposal.
* feat(triage): add auto mode for unattended monitoringCraig Jennings6 days4-0/+201
| | | | | | | | | | Add an auto mode to the triage-intake engine: a self-running variant for when Craig is away but wants tight awareness. It runs the standard sweep on a short interval (default 20 min) as an in-session loop, accumulates findings instead of mutating state, and gates the mutations behind "close the triage" (flush the batch, keep looping) and "stop the triage" (flush, then stop). A sweep advances nothing — no sentinel write, no todos, no mail actions, no commit. The scan window grows from the last close to the next, so nothing between sweeps is dropped, and the sentinel still means "everything before this timestamp has been scanned" — it just advances once per close. Each sweep reports deltas plus a running "responses awaiting your acknowledgment" list, the primitive an away user needs that a delta-only sweep loses. The unacked list is durable in .ai/triage-intake-unacked.org so it survives a crash, a clear, or a restart — the away-from-desk case the mode exists for. Delivery is an in-session loop so MCP auth is inherited; a detached cron schedule stays out of scope and belongs to the morning-ops orchestrator, which can reuse this accumulate behavior as its triage limb. Source proposal from the work project, design decisions ratified 2026-06-15.
* feat(inbox): define monitor-inbox as a 15-min loop with clean-tree gatesCraig Jennings6 days6-50/+116
| | | | | | | | | | Redefine "monitor the inbox" as the explicit behavior Craig wants: run one process-inbox pass now, then loop process-inbox every 15 minutes. The 15-minute loop was previously an opt-in background recipe; it's now the defined meaning of the phrase. Gate the workflow at both ends on a clean worktree and a green full-suite run. Starting on a dirty tree lets the per-item auto-commit sweep up unrelated changes; starting on a red suite hides whether the monitor broke anything. On a dirty tree, offer to commit in discrete batches; on a red suite, offer to investigate — never start until both are satisfied, and leave the tree clean and green when the loop stops. Add the no-approvals execute criteria: an accepted item self-applies only when agreed (passed the value gate and Skeptical Review), quick (under ~15 min including verification), and solo (no decision needed from Craig). All three commit and push at the end of the item; miss any and it files or, for shared-asset and convention changes, parks. Broaden the Skeptical Review to run on every arriving task and file, not only shared-asset proposals — a core right/complete/simpler pass on everything, with the cross-project battery added for changes that sync to consuming projects.
* chore(todo): file spec storage + lifecycle-status proposal as a taskCraig Jennings6 days2-0/+64
| | | | | | File the .emacs.d spec-storage/lifecycle proposal as a [#C] :spec: task with the recommendation captured in the body, so the design thinking survives until the task is worked in priority order. Move the proposal out of the inbox into docs/design/ as the linked source. The recommendation leans org-TODO keyword + Status field over a filename suffix for lifecycle status (renames break cross-doc links across a synced doc set), and org-id links either way. Flagged that the keyword lean diverges from the filename-suffix idea, so the mechanism stays an open decision.
* chore(ai): archive session record, note helper-instance resume planCraig Jennings6 days2-8/+70
|
* chore(todo): checkpoint helper-instance — detection+contract done, wiring nextCraig Jennings6 days1-0/+18
|
* feat(ai): add helper-mode workflow contractCraig Jennings6 days6-0/+208
| | | | | | | | helper-mode.org is the canonical home of the helper-instance rules: a second Claude alongside a live primary in the same project. It defines the four read/write tiers (always-safe reads and own-context writes, safe-by-discipline scoped single-heading edits, primary-only file-wide passes and all git mutation, escalation), the four data-integrity windows, the light startup, and the helper wrap-up (archive own context file, skip commit, with the git ban lifting only for an orphaned helper that ends up alone). protocols.org gets a one-paragraph pointer, and INDEX.org gets a triggerless catalog entry like startup.org, so the no-trigger workflow clears the integrity check without a special case. The contract is the canonical home. The routing that sends a session here (ai --helper, startup's roster branch, the wrap-up helper branch) ships behind the feature's drill gate and isn't live yet. Until then a session adopts it by an explicit "you are a helper" instruction.
* feat(ai): add agent-roster detection script with testsCraig Jennings6 days5-1/+451
| | | | | | | | agent-roster is the single detection primitive for concurrent same-project Claude sessions: pgrep -x claude, resolve each pid's cwd from /proc, keep those at or inside the project root, and drop the scanner's own ancestry. It exits 0 when alone, 1 when other agents are present (printed pid + cwd), and 2 when the roster can't run. Both the helper launcher and the in-session startup check will call this rather than re-scanning. pgrep and /proc are the system boundary, so I made them injectable (ROSTER_PGREP, ROSTER_PROC, ROSTER_SELF_PID) and the bats exercise the real include/exclude logic against fixtures, no agents spawned. The unavailable paths (no /proc, or pgrep absent) report on stderr and exit 2 rather than a false "alone". This is the first slice of the helper-instance task. Startup and ai --helper wiring follow.
* docs(ai): require an epoch on the tail of helper-agent idsCraig Jennings6 days6-2/+26
| | | | | | A helper agent's session-context file is .ai/session-context.d/<id>.org. A bare, reused id like "codex" makes the next run resolve to the previous run's leftover anchor, which it then mistakes for a crash to recover or clobbers. That bit on 2026-06-13: a codex run left codex.org for the next session to clean up. The fix is a convention, not a resolver change. The spawner appends an epoch on the tail (host.project.runtime.<epoch>) so each run gets a fresh anchor. The epoch can't be minted inside session-context-path, since that resolver runs many times per session and must return the same path each call. I documented it in protocols.org, the wrap-up recommended-shape note, and the resolver header.
* chore(ai): archive 2026-06-13 session records, update inbox markerCraig Jennings7 days3-1/+88
|
* feat(ai): disable C-z suspend in launched Claude panesCraig Jennings7 days1-3/+10
| | | | An accidental C-z suspended Claude to the shell mid-session. C-z isn't a Claude Code keybinding. It's the tty's SIGTSTP char, delivered below the app, so the only place to clear it is the tty. The launcher now runs stty susp undef in each pane right before claude starts, so it's scoped to ai-launched panes. C-z keeps working as job control in every other terminal, shell, and program.
* chore: stamp 2026-06-13 inbox-process markerCraig Jennings8 days1-1/+1
|
* feat(hooks): title sessions host-project with a hyphen, no spaceCraig Jennings8 days3-10/+11
| | | | The SessionStart hook joined host and project with a space ("ratio rulesets"), which reads as two words in the claude.ai/code and mobile session lists. I changed the join to "$host-$project" ("ratio-rulesets") so the title is one token, and updated the three session-title-hook.bats expectations test-first.
* chore(todo): file session-title-format task routed from roam inboxCraig Jennings8 days1-0/+7
|
* feat(workflows): add inbox-zero for routing the roam inbox by projectCraig Jennings8 days8-0/+222
| | | | | | | | The global roam inbox (~/org/roam/inbox.org) is one shared capture file every project can see, and nothing routed its items to the project that owns them. inbox-zero claims the items prefixed for the current project, files them into that project's todo.org per the process-inbox discipline, and removes them from the shared inbox. Foreign-prefixed and unowned items stay. Every scan reports the total item count plus how many appear related to this project. This v1 is single-destination: it routes by explicit <project>: prefix only. The domain-aware mode that would guess every item's owner and empty the whole inbox in one run is deferred until the multi-project need is concrete. Wired into both session ends so each project touches the inbox twice a session: startup surfaces a read-only count and offer, wrap-up Step 3 sweeps the claimed set before the cleanup scripts so imported tasks ride the wrap commit. INDEX carries the trigger phrases.
* fix(elisp): byte-compile cross-project .el edits against their own modulesCraig Jennings8 days1-0/+5
| | | | | | The validate-el hook only put the current project's roots on the load path, so editing an .el file from another project failed Phase 1 byte-compile on free-variable warnings: the file's own sibling modules weren't reachable. I added the edited file's directory and its parent to the load path. For in-project edits both are redundant (already covered by PROJECT_ROOT and its modules dir). They only do work when the file sits outside the current project root. I left Phase 2's test runner alone. It discovers tests by stem under PROJECT_ROOT/tests, so a cross-project file's tests aren't found regardless of load path.
* chore: capture spec-decisions convention, skeptical-review gate, and wrapup ↵Craig Jennings8 days1-0/+196
| | | | routing spec
* docs(design): resolve wrap-up routing spec decisions (Reading B)Craig Jennings8 days2-22/+26
| | | | | | | | All six decisions resolved. The router's input is filed keepers that belong to another project, not raw inbox files (Reading B). That keeps it a separate sub-step from the inbox gate (D1) and distinct from the defer-and-stage router (D5). Transcript routing is deferred to vNext (D4). I reworked the design to match: the input definition, a candidate-set note bounding the router to session-filed keepers rather than the standing backlog, and Phase 3. The cookie reads [6/6] and the Status moved to ready for review. The A-vs-B input ambiguity was the root under D1 and D5. Reading B keeps the inbox gate, the router, and defer-and-stage each simple instead of entangling all three.
* docs(design): draft wrap-up routing specCraig Jennings8 days2-11/+180
| | | | | | | | A spec for the optional wrap-up step that routes inbox items (and, vNext, transcripts) to the project they belong to. Three decisions settled from grounding (reuse todo-cleanup's Open Work matcher as the destination anchor, move atomically through one helper, keep cross-project writes visible with a provenance note); three left open for Craig (separate router step vs merged into the inbox sanity check, transcript scope and trigger, reconciling with the defer-and-stage router). Five implementation phases, acceptance criteria, readiness dimensions. Status stays draft while decisions are open. The todo task moves to DOING and links the spec. From the archsetup handoff 2026-06-13.
* docs(design): capture wrap-up inbox/transcript routing proposalCraig Jennings8 days2-0/+72
| | | | | | A wrap-up router that surfaces outstanding inbox items, recommends a destination project for each, and batch-moves task items into that project's todo.org, with a parallel transcript-filing step. I captured it as a design source and filed a spec-bound feature task rather than building it now: the work clears the spec bar, with design uncertainty (merge or stay separate from the inbox sanity check, recommendation-engine confidence, an unresolved transcript source-location dependency) and overlap with this session's defer-and-stage router to reconcile. From the archsetup handoff 2026-06-13.
* docs(rules): manual-verification code steps go in org src blocksCraig Jennings8 days1-4/+14
| | | | | | | | A checklist step that is code the user runs (verification setup, bug repro, walkthrough wiring) now goes in an org src block instead of a list bullet, so the user executes it in place with C-c C-c and reads the result in the buffer rather than copy-pasting. Manual actions, prose context, and Expected lines stay as bullets between the blocks. I scoped the Steps bullet in the same edit: it had said "one action per item" with the command as a bullet, which the new rule would contradict. It now names manual actions as the bullet case and points code steps at the src block. From the smoke handoff 2026-06-12, worked out on its manual-verification walkthroughs.
* feat(workflows): skeptical review gate for inbox change proposalsCraig Jennings8 days6-44/+162
| | | | | | | | The value gate asks whether to take an inbox item, never whether the proposed change is right. process-inbox gains a Skeptical Review for proposals that change shared assets: a written question battery (fit for all consumers, conflicts elsewhere, effect on common activities, enhancement, simplification, plus at least three change-specific questions), ending in a summary and recommendation Craig approves before the change lands. In a no-approvals session, behavior-changing proposals park instead of self-applying: prepared diff in working/, a [#B] VERIFY carrying the decision package, a reply to the sender. Wording-only fixes proceed, logged. monitor-inbox's act-vs-file rule and protocols.org's act-now line gain the matching exception so all three statements of the rule agree. protocols.org's tables picked up the org-table-standard reflow in the same pass. The motivating case is today's spec-decisions handoff. I applied it as-is, and the after-the-fact review surfaced a lost state and a vacuous gate pass the battery would have caught up front.
* docs(rules): clarify proactive inbox-send vs the stop-and-ask ruleCraig Jennings9 days1-0/+5
| | | | A literal reading of cross-project.md could see its new propagation section (send synced-file edits to rulesets without being told) as conflicting with the file's stop-and-ask rule. One sentence reconciles them: ask-first governs work inside another project's scope, and an inbox drop is the sanctioned alternative to that, so it needs no confirmation.
* feat(workflows): SUPERSEDED/CANCELLED decision states + old-model gateCraig Jennings9 days4-8/+20
| | | | | | A superseded decision now flips to SUPERSEDED (linking its replacement) and a moot one to CANCELLED. Both are done-class via a #+TODO: header the spec template auto-adds, so the [/] cookie counts them resolved and neither blocks implementation-ready. The TODO/DONE pair alone had lost the old State: field's superseded value. spec-review's gate and Ready rubric now read "no decision is still TODO", and a spec still on the retired State: field model fails the gate item until converted. The gate as first written would have vacuously passed old specs, which have no decision tasks at all.
* docs(rules): codify propagating synced-file edits back to rulesetsCraig Jennings9 days2-1/+31
| | | | | | A downstream edit to a rulesets-owned synced file (workflows, scripts, rules, protocols.org) is a stopgap the next template sync reverts. cross-project.md now documents the three-step propagation (edit locally, inbox-send the file to rulesets, include an intro note with the why and any companions to reconcile) so agents propagate a synced-file edit without being told. From the .emacs.d handoff 2026-06-12.
* feat(workflows): spec decisions become org TODO/DONE tasksCraig Jennings9 days6-30/+62
| | | | | | Each spec decision is now an org TODO task that flips to DONE when the decision-maker agrees, with a [/] cookie on the Decisions heading and a Discussion child for disputes. This replaces the inline State: proposed | accepted | superseded field. spec-response folds settled decisions by flipping them to DONE. spec-review's readiness gate and Ready rubric require the cookie to read complete. A spec can't move past draft to implementation-ready while any decision is still TODO. From the .emacs.d handoff 2026-06-12.
* chore: file the cancelled archive-done task to ResolvedCraig Jennings9 days2-9/+83
|
* chore: drop the Signal triage-intake pluginCraig Jennings9 days4-236/+4
| | | | Remove the triage-intake Signal source plugin and de-list Signal from the engine's plugin enumeration. I'm rebuilding the Signal client (signel + signal-cli) from scratch, so the plugin would scan against an unstable client. The signal MCP server and its README setup stay. Re-add the plugin when the client is stable.
* chore: delete the page-signal pager wrapperCraig Jennings9 days8-311/+3
| | | | Remove the page-signal CLI wrapper, its workflow, and the references in INDEX.org, broadcast.org, and mcp/README.org. The signal MCP server stays. It's the two-way path and a separate capability. The pager number had deregistered and the send-only wrapper isn't worth re-registering.
* fix(todo-cleanup): keep --archive-done silent on a real-mode no-opCraig Jennings9 days4-28/+160
| | | | The wrap runs --archive-done twice (wrap-it-up, then open-tasks.org Phase A). The first pass archives and reports. The second finds nothing and used to print "0 subtree(s) moved", which reads as alarming next to the first pass's diff. Now a real-mode run that moves nothing and skips nothing says nothing. Check mode still previews "0 would move", and a missing-section skip still reports, since those are conditions the caller needs.
* chore: cancel the archive-done count bug as cannot-reproduceCraig Jennings9 days1-8/+5
| | | | | | The reported "0 subtree(s) moved while moving" is a second-run artifact, not a defect. open-tasks.org runs --archive-done after wrap-it-up already archived, so the second pass correctly reports 0 next to the first pass's diff. The counter increments inline with every move. The exact pre-archive state reports the right count. Also drops the page-signal pager VERIFY.
* chore: conform the task list to the Priority Scheme headerCraig Jennings9 days2-9/+10
| | | | Rename the "Priority and Tag Scheme" section to "Rulesets Priority Scheme" so the repo follows the convention it just documented. Refresh the review dates on the open tasks and drop a processed inbox note.
* docs(todo): require a per-project Priority Scheme headerCraig Jennings9 days1-0/+28
| | | | | | Every project's task list now opens with a "[Projectname] Priority Scheme" section declaring both the [#A]-[#D] semantics and the tag vocabulary. The concept already lived in the tooling (task-audit enforces a declared tag set, process-inbox checks for the scheme before filing), but nothing required the section or fixed its name, so a list could leave [#A] and its tags undefined. The set is declared, not fixed. A project adapts the priorities and tags to its own work. The floor is that both are spelled out.
* docs(task-audit): add tag-vocabulary enforcement and verify-then-closeCraig Jennings9 days2-0/+28
| | | | Two Phase C behaviors, both surfaced auditing an Emacs-config todo.org. Enforce a project's declared closed tag set (strip tags outside it) where the legend marks the set exhaustive, leaving open-vocabulary projects untouched. For a task whose code shipped but awaits a manual or visual check, file that check under the project's manual-testing parent (dedup first) and close the implementation task, rather than letting "done but unverified" linger half-open.
* chore: archive session record, file done work, and log a cleanup bugCraig Jennings9 days3-109/+235
| | | | The archive pass moved four closed subtrees to Resolved while reporting zero moves; the relocation was correct and the reporting defect is filed as a [#D] bug.
* chore: resolve the new-projects-as-areas question in the task listCraig Jennings9 days1-2/+4
|
* docs(spec): close the helper-spec review cycle on the second passCraig Jennings9 days3-111/+106
| | | | The re-review confirmed every disposition with no new high or medium findings: Phase 1.5 stands at Ready with caveats, phases 2-5 stay parked behind the decisions fence. The response is correspondingly small — the accepted editorial rename of the Emacs subsection (its "open issue / blocks readiness" heading outlived the body, which is now an integration contract) and the second-pass note in the dispositions section. The updated review file and its history and task-tracking edits ride along.
* chore: set opus as the machine-default modelCraig Jennings9 days1-5/+5
|
* chore: record memory-sweep results and file overnight handoffsCraig Jennings9 days7-1/+42
|
* fix(scripts): lint-org pre-registers runtime org link typesCraig Jennings9 days4-0/+74
| | | | mu4e registers its link type in a live Emacs, so batch org-lint parsed [[mu4e:msgid:...]] links as fuzzy heading refs and flagged "Unknown fuzzy location" on links that work interactively. lint-org now registers each type in lo-runtime-link-types as a no-op before linting. org-link-set-parameters merges rather than replaces, so a genuinely loaded mu4e keeps its real parameters.
* docs(spec): fold the Codex review into the agent-runtime specCraig Jennings9 days3-33/+308
| | | | | | The review's top finding was that one Not-ready label hid an implementable slice. Status now splits by arc: Phase 1.5 helper instances are READY WITH CAVEATS (the three-ring gate and the manual drills are binding, and the ai-term.el work is a coordinated .emacs.d handoff with an exact artifact), while phases 2-5 stay NOT READY behind a decisions-required section and a Phase 5 reverification prerequisite that demotes the model table to a recommendation. The remaining findings hardened the slice: per-ring rollback actions including the half-propagated-sync case, the review's test inventory adopted as normative, a message contract for stale helper files, and explicit roster-unavailable behavior on unsupported platforms. All recommendations accepted except the document split, modified to a dual rubric in one document. The review file and dispositions table ride along.
* docs(spec): record the three confirmed helper-design decisionsCraig Jennings9 days1-22/+33
|
* docs(spec): unify the helper section after the day's five revisionsCraig Jennings9 days1-60/+117
| | | | | | The detection and identity subsections were authored under one design and patched under two others. They're now three pieces: the roster as the single detection primitive, two spawn paths (deterministic launcher, startup safety net) sharing the same three steps, and identity plus the role contract, with helper-mode.org named the single home of the helper rules. Verified ai-term.el's launch mechanics in code: the startup instruction is embedded in the tmux new-session command string, so env injection is a prefix on that string, and the -A flag means one session per project, so the helper path needs its own session and buffer names. Added ai-term recommendations to ride the same handoff (roster-derived badges, agent-exit visibility, one source for opener strings) and reconciled the v0 session-context symlink question with the Phase 1.5 answer.
* docs(spec): correct the Emacs launch surface to ghostel + ai-term.elCraig Jennings9 days2-24/+41
| | | | | | The first draft of the Emacs open issue assumed eat/vterm and invented an ai --no-tmux mode for a tmux-less path that doesn't exist. Verified against the actual config: the terminal is ghostel (native emulator over libghostty-vt), and ai-term.el is already the Emacs AI launch surface, creating project-named aiv- tmux sessions with liveness badges and crash recovery. Emacs-born agents are therefore tmux-parented like shell launches, so detection is uniform across surfaces. The remaining design is integration, not a new surface: ai-term.el's session-create learns the roster, export, and opener steps, the picker gains a [helper] badge, and the launchers share only the agent-roster script since ai-term owns its own session naming and window placement.
* docs(spec): hold helper instances as not-ready behind Emacs surface and test ↵Craig Jennings9 days2-1/+76
| | | | | | | | gating Two gaps block implementation. Sessions are also born from Emacs terminal buffers, where roster detection works (the scan matches process cwd, and eat/vterm shells are children of emacs) but the deterministic spawn path doesn't exist; the open issue weighs an elisp command against shelling out to ai with a no-tmux mode, leaning to the latter so the logic lives once. Second, template sync makes "live everywhere" the default failure mode for startup.org changes, so the test strategy gains three-ring gating: bats with sleeper processes and a byte-identical no-op guarantee, a disposable sandbox project for the corruption, orphaned-helper, and raw-launch drills, then a dormant-by-construction pilot through project-scripts before the template-wide release. The Status section carries the readiness checklist and the implementation task is blocked on it.
* docs(spec): deterministic helper spawn and session-end ordering rulesCraig Jennings9 days2-14/+52
| | | | | | The launcher becomes the spawn mechanism: a shell script runs the roster check, assigns the id, and launches with the helper instructions in order, where a model-followed startup instruction can skip a step. The in-session roster check stays as the safety net for raw launches and still splits a live anchor into crashed versus concurrent. Session-end ordering was unhandled: a helper outliving the primary stranded a dirty worktree, since the helper may not commit and the agent allowed to is gone. The git ban on helpers is concurrency-scoped, so it lifts when the helper finds itself alone at wrap-up and the last agent out closes the door with the full wrap-up. The mirror case pauses too: a primary wrapping with live helpers stops at the commit and asks whether to sweep the helper's in-flight work, wait, or leave closing to the helper.
* docs(spec): detection-first helper routing, no operator action neededCraig Jennings9 days2-15/+69
| | | | | | A second agent now discovers concurrency itself instead of being told: a stateless process scan (running agent processes, /proc cwd matched within the project root, own ancestry excluded) runs as the first action of every session, before any pull. Alone with no anchor is a fresh session, alone with an anchor is today's crash recovery, and not-alone skips startup and routes to helper-mode.org, the role-contract workflow. The scan also splits the previously ambiguous live-anchor signal into crashed versus concurrent primary. Verified the signal live with four concurrent agents on this machine. The ai --helper launcher flag drops from mechanism to convenience. Known v1 limits recorded: sessions not running as local processes are invisible to the scan, and the match is process-cwd based.
* docs(spec): data-integrity rules for helper instancesCraig Jennings9 days2-2/+61
| | | | | | Four loss windows the scoped-edit discipline doesn't cover: a primary file-wide hygiene pass silently clobbering a helper's concurrent edit (gate on live session-context.d/ files before any such pass), a new primary misreading helper dirt as leftover mess (surface live helper files at startup), crash recovery for shared-file edits (helpers journal each edit before applying it), and MEMORY.md's anchor-less read-modify-write index (memory writes stay primary-only). Backstop: every file-wide pass snapshots to /tmp before modifying. lint-org and wrap-org-table already conform; todo-cleanup — the pass that moves whole subtrees — does not, and Phase 1.5 brings it up to the invariant.
* docs(spec): add helper-instance slice to the agent-runtime specCraig Jennings10 days2-0/+115
| | | | The v0 draft covered identity and message targeting for concurrent agents but not spawn mechanics or write-safety for the shared files the session-context split doesn't isolate. I added a section for the motivating case (a second Claude in one project doing lookups and safe task updates): ai --helper spawn with automatic AI_AGENT_ID, a tiered read/write contract where helpers make scoped single-heading org edits and file-wide passes plus all git mutation stay primary-only, light helper startup, and helper wrap-up. Phase 1.5 sequences the slice independently of the runtime-neutral phases 2-6.