task.py init-context is removed; task.py create seeds implement.jsonl / check.jsonl with a self-describing _example line on sub-agent-capable platforms, and the AI fills real spec + research entries per workflow.md Phase 1.3. Session-start READY gate across four implementations now requires at least one curated entry. Skill Routing tables split per-platform. Release pipeline hardened. Not breaking; trellis update handles existing tasks transparently.
Feature Changes
workflow.md Phase 1.3 is now filled in by the agent, not by a script with pre-generated defaults
The oldtask.py init-context pre-filled implement.jsonl / check.jsonl from dev_type + package config, assuming the template path spec/<package>/{backend,frontend}/index.md. Monorepos that split by language (e.g. package = backend + package = frontend) produced entries pointing at files that don’t exist — which then led the agent to pre-fill the jsonl itself, and the many tool-call rounds that followed scattered the model’s attention and drifted it off the Trellis workflow.
Seed row format (one line per jsonl, no file field so every consumer skips it):
Skill Routing tables split per-platform
workflow.md Skill Routing and DO-NOT-skip tables now have two dispatch modes: IDEs/CLIs that support sub-agents invoke trellis-implement to do the actual coding, while platforms without sub-agents load trellis-before-dev in the main agent and code there directly.
| Sub-agent platforms | Non-sub-agent platforms |
|---|---|
| Claude / Cursor / OpenCode / Codex / Kiro / Gemini / Qoder / CodeBuddy / Copilot / Droid | Kilo / Antigravity / Windsurf |
Dispatch trellis-implement sub-agent per Phase 2.1 | Load trellis-before-dev skill (main-session flow) |
Session-start READY gate across four implementations
Before this release, all four session-start implementations treatedimplement.jsonl file existence as “ready for Phase 2”. After task.py create seeded jsonl, the breadcrumb jumped straight to Status: READY and the AI skipped Phase 1.3 curation.
Now each implementation scans the jsonl for at least one row with a file key. Seed-only jsonl surfaces as Status: PLANNING (Phase 1.3) with a Next-Action pointing at the curation step.
| Implementation | Consumed by |
|---|---|
shared-hooks/session-start.py | Claude, Cursor, Kiro, CodeBuddy, Droid, Gemini, Qoder |
codex/hooks/session-start.py | Codex |
copilot/hooks/session-start.py | Copilot |
opencode/plugins/session-start.js | OpenCode (JS plugin runtime) |
Hook + prelude tolerance for seed-only jsonl
shared-hooks/inject-subagent-context.py:read_jsonl_entries filters rows without file silently (no error) but emits a single stderr warning when the result is empty.
configurators/shared.ts:buildPullBasedPrelude teaches Class-2 sub-agents (Codex / Copilot / Gemini / Qoder) to skip rows without file and fall back to prd.md + self-discovered specs when the jsonl has only the seed row.
Internal Improvements
Pre-release manifest continuity guard
packages/cli/scripts/check-manifest-continuity.js queries npm view @mindfoldhq/trellis versions --json and diffs against local src/migrations/manifests/*.json. Any version on npm without a corresponding local manifest fails the check non-zero.
Background: trellis update applies migrations where v > installed && v <= current. A version on npm without its local manifest silently skips its migration bucket for users upgrading from adjacent versions — see the beta.10 incident in .trellis/spec/cli/backend/migrations.md.
| Release script | Pre-flight order |
|---|---|
release / release:minor / release:major | check-manifest-continuity.js → pnpm test → bump → commit → tag → push |
release:beta / release:rc / release:promote | check-manifest-continuity.js → check-docs-changelog.js → pnpm test → bump → … |
KNOWN_GAPS (pre-manifest-system versions 0.1.0–0.1.8, 0.2.1–0.2.11; early public prerelease 0.3.10-beta.0). The comment block documents the list must not be extended — any new gap means root-cause fix, not whitelist append.
Emergency bypass: SKIP_MANIFEST_CONTINUITY=1 pnpm release:beta. Prints a loud banner when set.
trellis update backup-phase stack-overflow fix
createFullBackup() descended into old .trellis/.backup-* directories during .trellis/ scan, and those old backups in turn contained nested .opencode/node_modules (tens of thousands of files). The original collectAllFiles() used recursion + files.push(...largeArray), which tripped V8’s Maximum call stack size exceeded on large file counts. trellis update crashed at the backup phase after the user confirmed.
| Fix | Location |
|---|---|
collectAllFiles rewritten as iterative stack traversal (no recursion, no large-array spread) | packages/cli/src/commands/update.ts:770 |
Skip node_modules, .backup-*, and other excluded dirs at the scan phase, not only at the copy phase | packages/cli/src/commands/update.ts:683 |
Normalize backslashes to forward slashes before matching BACKUP_EXCLUDE_PATTERNS (aligns with isManagedPath’s existing regex). .claude\worktrees\... now matches on Windows | packages/cli/src/commands/update.ts:689 |
collectAllFiles skips symlinks and Windows NTFS junctions (isSymbolicLink() returns true for junctions too), preventing infinite scans on cyclic paths | packages/cli/src/commands/update.ts:787 |
Print full stack trace when DEBUG=1 or TRELLIS_DEBUG=1 is set | packages/cli/src/cli/index.ts:130 |
test/commands/update-internals.test.ts and test/commands/update.integration.test.ts.
Temporary workaround for users on a pre-fix published CLI: rm -rf .trellis/.backup-* drops the old backups; subsequent trellis update runs won’t hit the overflow source.
create-manifest.js guards against rewriting published manifests
The script now refuses to (re)write a manifest for a version already on npm — even with force: true. Interactive mode adds the npm-published check before the existing local-file overwrite prompt.
vi.mock("node:child_process") now returns a valid Python version string
update.integration.test.ts and init-joiner.integration.test.ts stubbed execSync to return empty string for all commands. init() invokes requireSupportedPython() which calls execSync("python3 --version") and treats empty output as “Python not found”, throwing before any test assertion ran.
Upgrade
Existing projects:implement.jsonl / check.jsonl files keep working — seed rows without file are ignored by every consumer. If your prior init-context-generated jsonl points at paths that don’t exist on your monorepo spec layout (typical for package = backend | frontend projects), re-curate per workflow.md Phase 1.3:
PLANNING (Phase 1.3) to READY.
Fresh install: