> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trytrellis.app/llms.txt
> Use this file to discover all available pages before exploring further.

# v0.5.0-beta.18

> 2026-04-29

Beta.18 redesigns Phase 3 of the workflow: a new `Phase 3.4 Commit changes` step lets the AI batch commits of this session's edits, and `/trellis:finish-work` refocuses on archive + journal, refusing to run on a dirty working tree. Also fixes parent-task progress regression on child archive, hash-tracks `AGENTS.md` during `trellis update`, and supports OpenCode PowerShell context injection on Windows.

## Enhancements

### Phase 3.4 Commit changes

`workflow.md` Phase 3 gains a required `3.4 Commit changes` step that drives the commit cadence for the AI rather than leaving it to the user.

| Step | What the AI does                                                                                             |
| ---- | ------------------------------------------------------------------------------------------------------------ |
| 1    | Runs `git status --porcelain` to snapshot every dirty path                                                   |
| 2    | Runs `git log --oneline -5` to learn the repo's commit-message style (prefix, language, length)              |
| 3    | Classifies dirty files into `AI-edited this session` and `Unrecognized` groups                               |
| 4    | Drafts a multi-commit plan, one batch per coherent change unit                                               |
| 5    | Presents the plan once for one-shot user confirmation                                                        |
| 6    | On confirmation: runs `git add` + `git commit` per batch, no `--amend`, no `git push`                        |
| 7    | On rejection ("不行" / "我自己来" / "manual" / any pushback): exits to manual mode, no second plan, no flag needed |

The Wrap-up reminder previously at `3.4` renumbers to `3.5`. The `[workflow-state:completed]` breadcrumb (and the four hook fallbacks in `inject-workflow-state.py` / `inject-workflow-state.js`) now point users at `/trellis:finish-work` instead of the legacy `task.py finish` + `task.py archive` sequence.

### `/trellis:finish-work` refocuses on survey + archive + journal

The skill drops its old "Remind user to commit" step and gains a survey step that surfaces completed-but-unarchived tasks for one-shot cleanup. The new flow is:

| Step | Action                                                                                                                                                                                  |
| ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1    | `get_context.py --mode record` prints active tasks, git status, and recent commits. If other completed tasks beyond the current one surface, prompt once: "archive these N too? \[y/N]" |
| 2    | `git status --porcelain`, excluding paths under `.trellis/workspace/` and `.trellis/tasks/` (managed by the script auto-commits). Bails out if anything else is dirty.                  |
| 3    | `task.py archive <task>` for the active task (always) and any extra confirmed in Step 1. Each produces a `chore(task): archive ...` commit                                              |
| 4    | `add_session.py --commit <hashes>` writes the session journal (produces `chore: record journal` commit). Hashes come from Step 1's `Recent commits` list                                |

Final git log order is `<work commits from 3.4>` → `chore(task): archive ...` (one or more) → `chore: record journal`, never interleaved.

The common skill template uses `{{CMD_REF:finish-work}}` so each platform's `cmdRefPrefix` resolves correctly: `/trellis:finish-work` for Claude Code and OpenCode, `$finish-work` for Codex, `/trellis-finish-work` for Cursor.

## Bug Fixes

### Parent-task progress no longer regresses on child archive

`task.py list` previously dropped completed children from the parent's `[x/y done]` count whenever a child task was archived.

| Scenario                             | Before beta.18 | beta.18      |
| ------------------------------------ | -------------- | ------------ |
| 6 children, 1 completed and archived | `[0/5 done]`   | `[1/6 done]` |
| 6 children, 2 completed and archived | `[0/4 done]`   | `[2/6 done]` |

`cmd_archive` no longer removes the archived child name from the parent's `children` list, and `children_progress` treats children missing from active statuses as completed (`cmd_archive` always sets `status=completed` before moving the directory). The invariant is documented in `.trellis/spec/cli/backend/script-conventions.md` → "Parent-child invariant".

### `AGENTS.md` hash-tracked during `trellis update`

Pre-0.5.0-beta.18 projects wrote `AGENTS.md` without recording its template hash, which surfaced as a false "modified by you" conflict on update. Beta.18 introduces:

| Mechanism                                           | Behavior                                                                                                                        |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `<!-- TRELLIS:START -->` block                      | Marks the Trellis-managed region inside `AGENTS.md`; `update` only replaces this block, never user content outside it           |
| `LEGACY_UNTRACKED_AGENTS_MD_BLOCK_HASHES` allowlist | Pristine pre-beta.18 block hashes (e.g. `c1f511b1...`) are accepted silently so old untouched projects update without prompting |
| Hash tracking                                       | `template-hash.ts` records the new template's hash going forward, so subsequent updates use normal classification               |

User customizations outside the Trellis block are preserved.

### OpenCode PowerShell context injection on Windows

`inject-subagent-context.js` now picks the correct shell syntax based on `host.platform`:

| Platform | Injected prefix                                |
| -------- | ---------------------------------------------- |
| `win32`  | `$env:TRELLIS_CONTEXT_ID = '<key>'; <command>` |
| Other    | `export TRELLIS_CONTEXT_ID='<key>'; <command>` |

The explicit-assignment dedup detector matches both POSIX (`TRELLIS_CONTEXT_ID=...`, `export TRELLIS_CONTEXT_ID=...`) and PowerShell (`$env:TRELLIS_CONTEXT_ID = ...`) forms, so manually-prefixed commands are not double-wrapped.

## Internal

### Vitest test isolation: strip host-shell session env vars

A new `packages/cli/test/setup.ts` is registered via `setupFiles` in `vitest.config.ts`. It deletes `process.env.TRELLIS_CONTEXT_ID` and `process.env.OPENCODE_RUN_ID` at vitest process start so the OpenCode resolver tests no longer pick up a Claude/OpenCode host-session env var that would hijack the platform-input-derived `contextKey`. The pattern is documented in `.trellis/spec/cli/unit-test/conventions.md` → "Test Isolation".

### Spec updates

| Spec file                                         | Addition                                                                                                       |
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `.trellis/spec/cli/backend/script-conventions.md` | Parent-child `children` list invariant — historical list, not pruned on archive, `children_progress` semantics |
| `.trellis/spec/cli/unit-test/conventions.md`      | Test Isolation pattern — strip host-shell session env vars in vitest setup                                     |

## Upgrade

Existing projects:

```bash theme={null}
trellis update
```

No `--migrate` flag is required for this beta.
