Skip to main content
Use the planner to review core and company changes together before modifying a project, or integrate it into your own CLI or automation.

Plan through Python

Create a new project with planner.plan_init("support-bot", options={"acme": {"team": "support"}}). Options are grouped by pack name. This method also accepts framework="adk" or "langgraph" and minimal=True for the built-in scaffold. If omitted, the built-in framework defaults to ADK. To initialize from your team’s preferred template, pass template instead of scaffold options:
Templates accept a project name, slug, or HTTPS wheel URL; use template_sha256 to pin a wheel. Template framework and mode take precedence, so do not combine a template with framework or minimal=True. Pack hooks run against the rendered files. Inspect ProjectPlan before applying. It exposes proposed changes and blockers, plus readable and JSON-safe summaries; see plan results. The JSON summary is for display, not an executable plan format. Keep the original ProjectPlan object when applying a reviewed plan programmatically. apply_project_plan rejects blockers and stale inputs; it returns the backup directory or None when nothing changed.

Planning order

1

Snapshot project source

Read the project’s regular source files. Exclude runtime and cache directories such as .harnest, .venv, and .git; reject source symlinks.
2

Prepare Harnest changes

Generate the built-in scaffold, render the selected template, or apply core migrations in a disposable copy. The live project remains unchanged.
3

Run company hooks

Run packs in their supplied order and migrations in schema order. Each hook reads the current staged state and returns operations. Validate each pack’s resulting company configuration.
4

Review the combined result

Report final changed paths, owners, and blockers. A failure can leave partial proposals in the preview, but prevents applying the entire plan.
Only explicitly installed pack objects execute. Project lock files cannot import packages. Callbacks are trusted Python, not a sandbox: keep them deterministic and free of external side effects, including during previews.

Track versions and ownership

Commit both lock files: Ownership hashes allow managed updates to distinguish unchanged generated content from user edits. Option values are not recorded in the pack lock. Do not advance version numbers manually to skip migrations; doing so tells future upgrades that those changes already happened.

Resolve blockers

Apply and recover

Apply rechecks the source, locks against other pack applies, and backs up changed files under .harnest/project-backups/. Handled write failures restore those originals.
Backups can contain the original configuration contents. Treat them with the same access controls as the project source.
A process crash or disk failure can require manual recovery:
  1. Ensure the original apply process is no longer running.
  2. Inspect the backup’s plan.json and source/ files. Restore affected originals and reconcile files that the interrupted plan created or deleted.
  3. If .harnest/project-apply.lock remains, remove it only after recovering the interrupted operation.
  4. Generate a fresh plan and review it before applying again.
The apply lock coordinates project-pack operations; it does not stop unrelated editors from writing. Keep the project free of concurrent edits while applying. YAML operations preserve values but not comments or formatting. File/directory conversions require manual migration. Company model validation does not replace the usual Harnest compile and test checks for the complete agent.