Skip to main content
Phase 1.3 is now agent-curated. 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 old task.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.

Session-start READY gate across four implementations

Before this release, all four session-start implementations treated implement.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.

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. Historical gaps frozen in 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. Regression coverage added in 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.
Resolves 36 pre-existing failures. Full suite: 664/664 green.

Upgrade

Existing projects:
Picks up the updated scripts + hooks. Existing 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:
After first real entry, the session-start breadcrumb flips from PLANNING (Phase 1.3) to READY. Fresh install: