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):
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line when done."}

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 platformsNon-sub-agent platforms
Claude / Cursor / OpenCode / Codex / Kiro / Gemini / Qoder / CodeBuddy / Copilot / DroidKilo / Antigravity / Windsurf
Dispatch trellis-implement sub-agent per Phase 2.1Load trellis-before-dev skill (main-session flow)

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.
def _has_curated_jsonl_entry(jsonl_path: Path) -> bool:
    """A freshly seeded jsonl only contains `{"_example": ...}` — that is NOT ready."""
    for line in jsonl_path.read_text(encoding="utf-8").splitlines():
        line = line.strip()
        if not line:
            continue
        try:
            row = json.loads(line)
        except json.JSONDecodeError:
            continue
        if isinstance(row, dict) and row.get("file"):
            return True
    return False
ImplementationConsumed by
shared-hooks/session-start.pyClaude, Cursor, Kiro, CodeBuddy, Droid, Gemini, Qoder
codex/hooks/session-start.pyCodex
copilot/hooks/session-start.pyCopilot
opencode/plugins/session-start.jsOpenCode (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 scriptPre-flight order
release / release:minor / release:majorcheck-manifest-continuity.jspnpm test → bump → commit → tag → push
release:beta / release:rc / release:promotecheck-manifest-continuity.jscheck-docs-changelog.jspnpm test → bump → …
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.
FixLocation
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 phasepackages/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 Windowspackages/cli/src/commands/update.ts:689
collectAllFiles skips symlinks and Windows NTFS junctions (isSymbolicLink() returns true for junctions too), preventing infinite scans on cyclic pathspackages/cli/src/commands/update.ts:787
Print full stack trace when DEBUG=1 or TRELLIS_DEBUG=1 is setpackages/cli/src/cli/index.ts:130
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.
$ node scripts/create-manifest.js --stdin <<< '{"version": "0.5.0-beta.11", ...}'
✗ Version 0.5.0-beta.11 is already published on npm.
  Its manifest is part of the update contract and must NOT be rewritten.
  If you need to release additional migrations, use the NEXT version number.

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.
// Before — blanket empty return:
vi.mock("node:child_process", () => ({
  execSync: vi.fn().mockReturnValue(""),
}));

// After — conditional return for python version probe:
vi.mock("node:child_process", () => ({
  execSync: vi.fn().mockImplementation((cmd: string) => {
    const py = process.platform === "win32" ? "python" : "python3";
    return cmd === `${py} --version` ? "Python 3.11.12" : "";
  }),
}));
Resolves 36 pre-existing failures. Full suite: 664/664 green.

Upgrade

Existing projects:
trellis update
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:
python3 ./.trellis/scripts/get_context.py --mode packages       # see what specs exist
python3 ./.trellis/scripts/task.py add-context <task-dir> implement \
  ".trellis/spec/<pkg>/<layer>/index.md" "why it applies"
After first real entry, the session-start breadcrumb flips from PLANNING (Phase 1.3) to READY. Fresh install:
npm i -g @mindfoldhq/[email protected]