Skip to content

Initialization

SASE initialization commands create or refresh durable files that agents and sidecar tools rely on. Bare sase init checks the current project and home setup first, then either reports that everything is current or shows the initializers that need attention:

sase init -c       # report drift without writing
sase init          # prompt before each needed initializer
sase init --yes    # run every needed initializer in order
sase init -M --yes # mark this repository as SASE-managed, then initialize it
sase init --all --check # check every enabled main project without writing
sase init --all         # visit every enabled main project; prompt when interactive
sase init --all --yes   # skip generic prompts for every enabled main project
sase init -p sase -p notes --check --json  # structured plan for named projects
sase init -p sase --yes                    # initialize named projects as one process

The coordinator first builds all six read-only plans in registry order—config, machine, memory, repositories, service, then skills—before it writes anything. It then applies the changed initializers in that same order. Config initialization establishes the explicit per-user/per-machine owner identity; machine initialization offers optional remote-machine enrollment after that identity exists; memory initialization owns agent-document initialization (managed AGENTS.md and its provider instruction copies); repository initialization owns configured sidecars and the workspace ignore rule. When the service_host beta flag is enabled, service initialization offers the machine-level native user unit once per init batch; declining records a machine marker so later bare onboarding stays quiet, while an explicit sase service init still checks it. In non-interactive shells, bare sase init reports drift and exits non-zero instead of prompting; use sase init --yes when you want to apply everything that does not require a resource-specific confirmation. Owner identity creation and migration still require a TTY. Apply runs can write project files, deploy home files through chezmoi when configured, and use each initializer's normal commit/push behavior. Project-wide ownership requires is_sase_managed: true in the current repository's own sase/sase.yml; defaults and merged user configuration cannot grant it. Without that local marker, memory init leaves project memory and the root AGENTS.md untouched while still copying every existing project-tree AGENTS.md to the provider instruction files beside it, and explicit repository initialization exits successfully without detecting a provider, materializing sidecars, or generating files.

One resource-specific exception is intentionally non-bypassable: --yes can run the repository initializer, but it cannot approve creation of a missing provider sidecar. Each creation always requires an interactive y/yes response to a prompt naming the host, repository, and configured visibility; unattended initialization can connect existing sidecars but cannot create them.

sase init --all uses the registered project inventory, so it can be run inside a project or from an unrelated directory. It visits enabled main projects only: disabled projects, sibling bookkeeping records, and the system-managed home project are excluded. Each project runs from its recorded primary workspace. Missing workspaces, invalid project records, planning errors, and initializer failures are reported under that project's heading without preventing later projects from being attempted; the final summary and exit status reflect the whole batch. --all --check is fully read-only and exits non-zero if any project has drift or cannot be checked. Without a TTY, --all remains read-only unless --yes is supplied. Machine enrollment is offered at most once per --all or repeated -p/--project invocation; accepting, declining, EOF, or a machine-init failure consumes that batch's machine opportunity while later projects continue with their other initializers.

-p, --project NAME selects one or more of those same enabled projects by project name, display name, or alias. Repeat the option to name a subset (sase init -p alpha -p beta --yes). Named projects still run as one process with one batched chezmoi deploy. The selector cannot be combined with --all, --enable-project-memory, or an explicit init subcommand. An unknown or non-enabled name fails immediately and lists the valid names.

--check -j/--json writes exactly one JSON document to stdout instead of the Rich report. The payload carries schema_version (currently 1) and a top-level status of current, drift, or blocked so callers can distinguish drift from blockers without using the exit code — both still exit 1. Each project entry includes name, display name, an InitRunStatus-style per-project status, unavailable_reason when inventory held the project back, and per-planner rows with label, summary, change and runnable flags, a requires_tty marker, warnings, blockers, and actions (including new_content so a consumer can render full diffs). --json requires --check.

The Admin Center Projects tab can drive the same flow: i initializes the marked or highlighted projects and I initializes every enabled project.

Use -M, --enable-project-memory to create or update the current project's sase/sase.yml with is_sase_managed: true before normal initialization. The compatibility spelling remains, but the marker now authorizes SASE management of the repository as a whole and thereby enables managed project memory and explicit repository initialization. The option preserves other local configuration and is available on both bare sase init and sase memory init (as well as the sase init memory compatibility alias). Because it writes configuration, it cannot be combined with --check, --all, or -p/--project; repositories must be marked one at a time.

Explicit subcommands are still available when you need narrower control:

sase config init
sase config init --check
sase init config # compatibility alias
sase machine init
sase machine init --check
sase init machine # compatibility alias
sase memory agent-docs list
sase memory init --no-commit
sase memory init --enable-project-memory --no-commit
sase memory init --check
sase memory list
sase memory log
sase memory log --path generated_skills.md
sase memory log --id <read-id>
sase repo init
sase repo init --check
sase repo init --diff --no-commit
sase init repo # alias for sase repo init
sase service init --check
sase service init --diff
sase service init --yes
sase init service # compatibility alias for sase service init
sase skill list
sase skill init --dry-run
sase skill log
sase skill log --runtime codex

# Agent-side audited operations, normally run from a SASE-launched agent:
sase memory read generated_skills.md --reason "Need generated skill context"
sase skill use sase_plan --reason "Need to prepare an implementation plan"

Start with sase init -c or sase memory init --check when you only want a drift report. After that, sase memory init --no-commit is the usual first apply run for memory because it writes the generated files but skips the project git commit/pull/push path. It is not a dry run: it can still write project files, write home memory, and follow home-level use_chezmoi deployment. sase init memory remains a compatibility alias for sase memory init, and sase init config remains a compatibility alias for sase config init, sase init repo is an alias for sase repo init, and sase init skills remains an alias for sase skill init. sase init machine remains a compatibility alias for sase machine init, and sase init service remains a compatibility alias for sase service init.

Commands

Command Purpose
sase init Check config, machine, memory, repositories, service, and skills; prompt once per needed initializer.
sase init -a, --all Check or initialize every registered enabled main project, continuing after project errors.
sase init -c, --check Report initialization drift without writing and exit non-zero when changes are needed.
sase init -j, --json With --check, emit one schema-versioned JSON plan; status distinguishes drift from blockers.
sase init -M, --enable-project-memory Mark the current repository as SASE-managed before running initialization.
sase init -p, --project NAME Check or initialize named enabled projects (repeatable; name, display name, or alias).
sase init -y, --yes Run every needed initializer in config, machine, memory, repository, service, skills order without generic prompts.
sase config init Interactively create, select, or migrate the explicit owner identity.
sase config init --check Report owner identity initialization, migration, or conflicts without writing.
sase init config Compatibility alias for sase config init.
sase machine init Discover, enroll, and activate remote machines; check mode is offline and never discovers.
sase machine init --check Report whether remote-machine enrollment can be offered without discovery or writes.
sase init machine Compatibility alias for sase machine init.
sase memory Alias for sase memory list.
sase memory list Inspect loaded, referenced, available, and missing memory files for the current root.
sase memory agent-docs Alias for sase memory agent-docs list.
sase memory agent-docs list Inspect project, home, and chezmoi AGENTS.md files and nearby provider instruction files.
sase memory read <path> Agent-side read of one reference memory file with an attributable audit event.
sase memory log Summarize audited reference memory reads.
sase memory log --path <path> Show a path-level summary and matching individual read events.
sase memory log --id <read-id> Show one full audited read event by id or unambiguous id prefix.
sase memory init Refresh home and SASE-managed project memory plus provider copies for existing AGENTS.md.
sase memory init --check Report memory initialization drift without writing files.
sase memory init -M Mark the repository as SASE-managed, then initialize project memory.
sase memory init -C Write memory files but skip the project git commit/pull/push path.
sase init memory Compatibility alias for sase memory init.
sase repo init Initialize configured sidecars, managed declarations, and /sase/repos/ ignore rule.
sase repo init --check Report sidecar, project-config, generated-guide, and ignore-rule drift without writing.
sase repo init --no-commit Apply project config and ignore changes without committing or pushing them.
sase init repo Alias for sase repo init.
sase service init Plan or install the native per-user service-host unit when the service_host flag is enabled.
sase service init --check Report native-unit, captured-environment, and legacy-unit drift without writing.
sase service init --diff Show planned native-unit changes, with captured environment values redacted.
sase service init --yes Apply the native-unit plan without the ordinary confirmation prompt.
sase init service Compatibility alias for sase service init.
sase skill Alias for sase skill list.
sase skill list Inspect generated skill sources, provider targets, and deployed-file drift without writing.
sase skill init Generate skill files; existing files require confirmation or --force.
sase skill init --dry-run Preview generated skill target paths without writing files.
sase skill init --check Report generated skill-file drift without writing files.
sase skill init --diff Show full generated skill-file diffs without writing files.
sase skill init --force Overwrite deployed skill files without confirmation and bypass the provenance manifest guard.
sase skill init --allow-dirty Deploy from uncommitted or unmerged xprompt sources; can revert other agents' deployments.
sase skill init -p <provider> Deploy only one provider's generated skill files.
sase skill log Summarize or inspect audited generated skill-use events.
sase skill use <name> Agent-side audit event recording that a generated skill was used.
sase init skills Compatibility alias for sase skill init.

Advanced deploy controls such as --no-commit, --no-push, and --no-apply live on explicit subcommands rather than the bare coordinator. Scoped --check flags also live on explicit subcommands when you want to validate only memory, repository/sidecar wiring, native service installation, or generated skill files.

Service host

Service initialization is available when the default-off service_host beta flag is enabled, either persistently with sase flag enable service_host or for one command with sase -f service_host service init. It installs a per-user systemd unit on Linux or a per-user LaunchAgent on macOS, plus a mode-0600 environment snapshot containing only the allowlisted variables needed by the host. The preview is the default:

sase -f service_host service init
sase -f service_host service init --check
sase -f service_host service init --diff
sase -f service_host service init --yes

--check and --diff never write. Apply retires recognized legacy service units and reloads the platform manager. Linux reports when user lingering is disabled because the unit then stops with the login session. A non-default SASE_HOME changes the native unit identity and therefore requires --force; the command prints the resulting home-scoped identity before applying it. Use sase service uninstall with the same preview, check, diff, force, and confirmation model to remove the managed unit.

Bare sase init offers this machine-scoped initializer at most once per batch. A decline is remembered for future broad onboarding runs on that machine, but it does not disable the service feature or suppress an explicit sase service init.

Remote machines

sase machine init is the canonical remote-machine initializer. sase init machine and the bare sase init machine spec delegate to the same planner and apply service. The operational target-preparation flow is covered in the Remote Dispatch Runbook.

--check, --json, and other previews inspect only local merged configuration: they never run discovery or talk to a gateway. --diff only renders ordinary initializer diffs; it is not a guarantee that no interactive apply-time discovery will occur when you accept the machine initializer. A zero-machine or all-enrolled registry is not drift, so sase init --check does not stay red just because enrollment is available. On an interactive TTY before the local review has completed, bare sase init may offer one explicit enrollment review.

The first successful explicit sase machine init review on a controller records a local acknowledgment in ~/.sase/fleet/machine_init_review.json (under SASE_HOME when set). The record is machine-local and is not synced through project config or chezmoi. A completed review includes candidates you consciously skip and successful empty reviews. After that local acknowledgment exists, bare sase init, sase init --all, and sase init --project do not perform automatic remote-machine discovery, prompt for newly appearing machines, or print provider health failures. They report the machine initializer as current from local state only. Existing installations need one catch-up review because old state cannot prove the first review happened, and an unreadable record also asks for a catch-up review with a local-state warning. Run sase machine init directly, or the sase init machine compatibility alias, any time you want to reconsider skipped candidates or force a fresh review. Use sase machine discover for an explicit discovery scan and sase machine status to check configured machines.

Explicit apply always rescans. Already-enrolled identities are listed and skipped; selecting one existing machine does not hide another candidate. A changed installation identity is never silently repinned — run sase machine repair ALIAS with a new bootstrap instead. Enrollment bundles come from -B/--bootstrap-file, piped stdin, or a hidden prompt; they are never accepted through an echoing input() prompt.

After the machine record and credential are written, init deploys a chezmoi-managed overlay through the scoped chezmoi apply --force path, reloads merged configuration, and runs a bounded authenticated hello. Only then does it print an enrolled success. Quarantine and failed activation exit non-zero. If apply or hello fails after the target may have consumed the one-time bootstrap, the command explains whether to retry the apply or issue a new bundle and run sase machine repair.

Agent Documents

sase memory agent-docs list is the read-only inventory for agent instruction documents: root AGENTS.md plus provider instruction files such as CLAUDE.md, GEMINI.md, QWEN.md, and OPENCODE.md (each a full copy of AGENTS.md).

sase memory agent-docs list

With no subcommand, sase memory agent-docs defaults to sase memory agent-docs list. The inventory shows project, subdirectory, home, and chezmoi-source AGENTS.md files, their H1 titles, whether they look managed, core/reference memory reference counts, and nearby provider instruction file status. It never writes files; sase memory init is the command that creates or refreshes these documents.

Memory Initialization

sase memory init always initializes the home-level memory surface. It initializes project-local memory only for a SASE-managed repository, and independently owns provider instruction copies:

sase memory init -M is the convenience path for a repository that should be SASE-managed: it creates or updates sase/sase.yml with the repository-wide marker before loading configuration and running the normal initializer. Despite the compatibility option name --enable-project-memory, this does not change ProjectSpec lifecycle state and is independent of sase project enable.

  • Project memory under ./sase/memory/, including sase/memory/README.md, the project-only generated core sase/memory/task_types.md catalog note, the committed sase/task_types.json snapshot, and flat note files with type/parent frontmatter, only when the project's own sase/sase.yml contains is_sase_managed: true. plugins.required is verified before any snapshot or note comparison, so a missing required plugin is reported as an install error rather than as memory drift. When a committed type's spec digest changes, --check names the type and its package.
  • Home memory under ~/sase/memory/, or under ~/.local/share/chezmoi/home/sase/memory/ when use_chezmoi: true.
  • A managed project AGENTS.md only with that same explicit opt-in. memory.h1_title customizes its H1; otherwise SASE derives the stable <project> - Agent Instructions title.
  • Provider instruction files CLAUDE.md, GEMINI.md, QWEN.md, and OPENCODE.md; each is a byte-for-byte copy of that root's final AGENTS.md. Chezmoi home source roots stay on static .md files unless a machine overlay under dot_config/sase/ declares memory.h1_title. In that case initialization writes AGENTS.md.tmpl and preferred *.md.tmpl shims whose H1 switches on .chezmoi.hostname, and each title-declaring overlay must have a .chezmoiignore hostname guard (the stanza sase config init writes). Legacy @AGENTS.md / @/path/to/home/AGENTS.md import shims and leftover static or *.md.tmpl sources are still recognized and migrated.

Managed projects can override the packaged Jinja templates for AGENTS.md, minimal agent instructions, sase/memory/sase.md, and sase/memory/README.md with root-relative paths in sase/sase.yml. The generated project-only reference notes sase/memory/sase_artifacts.md, sase/memory/sase_beads.md, and sase/memory/sase_sizes.md are fixed packaged assets with no override keys, generated only for SASE-managed project repositories and never for home or chezmoi-home roots. Home roots use convention-based template files in the SASE user-config directory (or its chezmoi source counterpart). Template variables and validation rules are listed in the generated templates configuration.

sase/memory/glossary.md is not a generated note — it is a user-owned memory-web descriptor, exactly like any other sase/memory/<web>.md file, with the project's terms authored as sibling strand files under sase/memory/glossary/. Memory initialization always inlines its descriptor body into the ## Memory Webs section of AGENTS.md and the provider instruction files, plus the descriptor's inline **GLOSSARY TERMS:** roster naming every strand keyword and alias, semicolon-separated. Strand bodies never inline into AGENTS.md; agents fetch a definition on demand with sase memory read glossary:<keyword> -r "<why>", passing every keyword needed in one command. See Memory Webs for the full read, browse, and edit workflow.

For a SASE-managed project, sase memory init inlines each core note into ## Core Memory and numbers every heading in the generated document, renders each memory web as its own numbered H3 subsection of ## Memory Webs (omitted entirely when the root has no webs), and renders reference memory as one ordered-list entry per top-level reference note, adds missing canonical frontmatter, and validates reachability. The instruction paragraph pointing agents at /sase_memory_read is direct body content of the ## Reference Memory heading, immediately followed by those per-note list entries; both the paragraph and the entries are omitted when a root has no top-level reference notes. Missing, false, merged-global, or memory.h1_title-only configuration does not authorize any project memory or root AGENTS.md creation, refresh, or validation. The retired memory.enabled key is not an alias. Existing projects must replace it once with:

is_sase_managed: true

Home and chezmoi-home initialization is unchanged: those roots remain managed and take an optional title from user config (~/.config/sase/sase.yml, overlays, or source-side dot_config/sase/). Chezmoi machine-overlay titles additionally emit AGENTS.md.tmpl as described under provider instruction files above.

Provider copying is the exception to project ownership. In both managed and unmanaged projects, every readable AGENTS.md found with the normal project-tree pruning rules is copied byte-for-byte to CLAUDE.md, GEMINI.md, QWEN.md, and OPENCODE.md beside it. A directory with no AGENTS.md is untouched, including any standalone provider files already there.

When use_chezmoi: true, the home files are written to the chezmoi source tree. The command can then commit those home changes and run chezmoi apply --force; --no-commit does not disable that home deployment path.

The generated sase/memory/sase.md summarizes workspace naming, linked repositories, and the /sase_final terminal-action contract for end-of-turn declarations. The generated reference sase/memory/sase_artifacts.md note owns artifact-reference and indexed-file workflow guidance. The generated reference sase/memory/sase_beads.md note provides shared bead workflow guidance and has sase/memory/sase_sizes.md as a child size-scale note. Top-level project-only reference notes are listed in the ## Reference Memory section of managed agent instructions, generated for SASE-managed project repositories only and never for home or chezmoi-home roots. The core sase/memory/task_types.md catalog note is likewise project-only. A root that no longer manages those notes (for example, a home root that previously generated them) deletes generated copies on the next sase memory init pass; copies a human has since edited are left alone and keep behaving as ordinary notes. Project memory reads linked-repo descriptions from the project-local sase/sase.yml; home memory reads them from the global config ~/.config/sase/sase.yml, or from the chezmoi-managed config path when use_chezmoi: true. Generated memory requires agents to use /sase_repo before reading or modifying any repository outside their own workspace checkout. This rule applies to configured linked repos and sidecars, other SASE projects, and unlinked GitHub repos even when no linked repositories are configured; the skill carries the command grammar and workspace-selection details.

Every configured linked_repos entry (or its deprecated sibling_repos alias) must have a non-empty description. Initialization fails instead of generating ambiguous memory when a description is missing.

By default, project memory initialization runs commit_hooks.before, stages generated project files, commits them with the standard memory-init commit message, pulls with rebase, and pushes. This path does not run commit_hooks.after. Use sase memory init --check for a read-only drift check, or sase memory init --no-commit when you want to review generated project files before committing. --no-commit only skips the project deploy path; home memory deployment still follows use_chezmoi when it is enabled.

Memory drift is judged against the running build's generator templates, so the build that answers matters. When the invoked project carries its own .venv/bin/sase but the command is running under a different interpreter — the usual case being a bare sase on PATH that resolves to a separate uv tool install — both --check and apply modes print a non-fatal warning naming the foreign interpreter and the pinned invocation to use instead (<project>/.venv/bin/sase memory init --check, or just check in a repo that provides it). Phantom drift that disappears under the pinned build is exactly this situation.

For managed roots, memory validation is reachability-based: Markdown files under sase/memory/ must be reachable from AGENTS.md directly or through transitive @sase/memory/... or sase/memory/... references. Unreferenced memory files make the command fail so important agent context is not silently ignored. Unmanaged project memory is not validated.

Memory Context List

sase memory list, or bare sase memory, renders a read-only dashboard for the current directory. It reports:

  • loaded files reached by transitive @... references from AGENTS.md in the project or home context.
  • referenced files mentioned by plain sase/memory/... text from loaded context or by audited sase memory read instructions. These are visible in the dashboard, but their contents are not loaded unless another @... edge reaches them.
  • available files present under project or home sase/memory/ that the current launch context does not reach.
  • missing referenced memory paths that do not exist.

The dashboard includes approximate local token estimates for loaded memory context.

For day-to-day read/write operations, including audited reads, see Memory.

Memory Read Audit Log

sase memory read <memory-relative-path> -r <reason> is the audited path for agent-initiated reference memory reads. The argument is relative to the selected project or home sase/memory/ root; the command allows type: reference Markdown notes and rejects type: core notes because core memory is expected to arrive through instruction loading. The command strips one leading YAML frontmatter block from stdout and appends ## Children when nested reference notes exist, but the audit log records only metadata such as path, agent name, timestamp, cwd, byte count, and reason.

This audited path is distinct from #memory/<stem> xprompt inclusion: an explicitly authored #memory/<stem> reference in a prompt expands the same note body at launch time, for both type: core and type: reference notes, without writing an audit event. See Memory Field.

Every read must include a non-empty reason via -r or --reason. The command also requires agent attribution from SASE_AGENT_NAME, SASE_AGENT, or SASE_ARTIFACTS_DIR/agent_meta.json; unattributed reads fail instead of writing a log row. Human shell users normally inspect files directly.

sase memory log reads the project-scoped audit log from SASE state under ~/.sase/projects/<project>/, not from the repo. Use --path or --agent to drill down to matching read events, --id <read-id> to inspect one event, and --json for deterministic machine-readable output.

# read requires SASE agent identity
sase memory read generated_skills.md --reason "Need generated skill context"
sase memory log
sase memory log --path generated_skills.md
sase memory log --id <read-id>

Repository Initialization

sase repo init initializes every enabled repos.sidecar entry for the current managed project. It also adds the explicit project-local plans, beads, and research declarations when absent:

repos:
  sidecar:
    builtin:
      plans:
        auto_clone: true
      beads:
        auto_sync: true
    custom:
      research:
        description: Durable SASE research reports and generated media.

Reserved roles are written under repos.sidecar.builtin and document sidecars under repos.sidecar.custom. If repos.sidecar still uses the removed list form, the write stops with an error asking you to migrate it to the two-bucket mapping first; sase doctor names the target bucket for each existing entry.

An existing entry for any of those roles is preserved verbatim, including disabled: true; disabling research is the project-local opt-out. The unpinned research entry derives <owner>/<project>--research from the primary GitHub repository, and the beads entry likewise derives <owner>/<project>--beads. The write uses SASE's comment-preserving configuration editor. The same initializer adds /sase/repos/ to the tracked root .gitignore; those two project-file changes use the normal commit/pull/push path unless --no-commit is supplied.

For each enabled sidecar, provider discovery runs before materialization. A missing remote gets its own default-no prompt naming the visibility, provider, full repository name, and host. Only y or yes authorizes creation; --yes, blank answers, EOF, interruption, and non-interactive stdin cannot authorize it. The configured repo: pin and visibility: are passed to the provider, and initialization fails closed if the provider cannot honor the requested visibility.

When non-interactive bare sase init --yes discovers a missing sidecar remote, it writes the project wiring, reports the missing repository, and leaves creation for a later interactive sase repo init. This keeps automated onboarding and post-commit hooks non-blocking without allowing --yes to authorize remote creation.

Managed projects also resolve an implicit public <project>--agents sidecar unless project configuration disables it, sets default_linked_repos: false, or supplies an explicit replacement. Its missing remote receives a separate, agent-specific, default-no creation prompt; --yes never authorizes publishing agent history. Declining that prompt continues initialization without the agents sidecar, while another missing sidecar can still make initialization incomplete. Before accepting, review the transported prompt, chat, commit, and relationship data and set a project-local visibility: private override when appropriate. Publication requires the selected overlay's complete id.username / id.machine_name identity; run sase config init first to migrate a legacy top-level machine_name. The initialized README explains the full project-scoped hood privacy implications, owner-sharded v2 browsing layout, active/optional transcript behavior, and synchronization/recovery commands. Existing v1 payload remains read-only during migration. See Agent Hood Synchronization.

Reserved sidecars and the default research presentation preset receive illustrated README guides and directory-map assets. Rerunning sase repo init upgrades a missing or stale agents infographic while preserving the manifest-derived root index of a populated agents sidecar. Custom sidecar roles receive a deterministic generic README using their configured description. Initialized guide files are committed and pushed in their respective sidecar repositories. When plans are available, the split SDD store record records every initialized role; research is not required.

The beads sidecar holds the project's durable bead state at its repository root. When it is created for a project whose bead state still lives in the plans clone, sase repo init adopts that state as part of the same run: it copies the store into the beads clone, commits it as Import bead state from <plans-repo>@<sha> and pushes, writes the schema-3 store record that makes bead commands resolve to the new repository, and only then removes beads/ from the plans clone. sase repo init --check lists that data move as a distinct planned action. Adoption is idempotent, so rerunning initialization after a partial failure retries cleanly; see SDD Storage for the full transaction and its failure semantics.

sase repo init                    # initialize sidecars and project wiring
sase repo init --check            # preview without network probes or writes
sase repo init --diff             # show file diffs, then apply
sase repo init --no-commit        # write project config/ignore changes without committing
sase init repo                    # alias for sase repo init

Both apply and --check first read the current repository's own sase/sase.yml (with root sase.yml as a legacy-only fallback). A missing or false is_sase_managed marker makes the command an informative, successful no-op before provider work; malformed YAML and non-boolean marker values fail safely. sase init repo delegates to the same repository initializer; sase init workspace is no longer a public subcommand because its ignore-rule work is part of repository initialization.

Built-in bare-git projects keep their provider-owned in-tree SDD layout. For those projects, sase repo init refreshes the existing generated SDD guides while still maintaining the managed sidecar declarations and repository ignore rule. Keep conceptual SDD documentation in docs/sdd.md and storage-mode details in docs/sdd_storage.md.

Skill Initialization

Generated skills start as Markdown sources in a canonical skills/ directory that set a truthy skill frontmatter field — see Skill Field. sase skill list is the read-only inventory: it shows loaded skill sources, the providers they target, and whether generated SKILL.md files are current, stale, or missing. It also reports misplaced sources in a "Misplaced Sources" panel. Bare sase skill shows the same dashboard.

sase skill init renders those sources into provider-specific SKILL.md files, and exits non-zero without writing anything while any placement violation remains. Sources include the bundled src/sase/xprompts/skills/ templates plus project, home, and plugin skill directories. By default, generated skill files include a first-step sase skill use <name> --reason ... directive so agent skill usage is attributable in the same project audit surface as memory reads; sase skill log summarizes and inspects those recorded skill-use rows. A source can set log_skill_use: false to omit that directive. The usual workflow is to inspect first, preview writes, commit the source change, and only then deploy:

sase skill list
sase skill init --dry-run
sase skill init --diff
# commit the skill source change and land it on the canonical branch first
sase skill init --force

Without use_chezmoi, generated skill files are written directly under the provider's home-directory skill targets. When use_chezmoi: true, skill initialization writes through the chezmoi-managed home tree and can commit, push, and apply those dotfile changes. The --no-commit, --no-push, and --no-apply flags only affect that chezmoi deployment sequence. sase init skills still works as a compatibility alias for sase skill init.

Commit Before Deploying

The chezmoi destination is a single global tree shared by every workspace, so a deploy from a workspace whose sources are not canonical publishes content that exists in no landed sase revision and can revert another agent's deployment. Two guards enforce that, and they apply only to writing chezmoi deploys — --check, --diff, --dry-run, and non-chezmoi targets are unaffected:

  • Source integrity. The deploy is refused when src/sase/xprompts/ has uncommitted changes, or when the invoking workspace's HEAD is not an ancestor of the canonical branch. The error names the offending files or the unmerged commits.
  • Provenance manifest. Each deploy records the source commit and an xprompt-set hash in .sase-skills-manifest.json under the chezmoi source root. A deploy whose source commit differs from the recorded one is refused rather than allowed to move the destination backwards. A missing or unparsable manifest bootstraps cleanly.

So the corrected workflow is: iterate with --diff / --dry-run, commit the template change to the sase repo, land it on the canonical branch, and deploy from that clean merged tree.

Because of those guards, --check does not fail on chezmoi deploy drift it has no way to resolve. When chezmoi deployment is enabled and generated skill files differ from their deployed chezmoi copies, sase init skills --check counts those files, reports them as a warning telling you to rerun sase init skills after landing, and drops them from its action list — so the check itself passes. If a dirty or unlanded tree would also make the real deploy refuse, that source-integrity reason is reported as a second warning. This keeps an unrelated read-only check from either failing for drift only a land can clear or triggering a mutating deploy as a side effect. Writing plans (interactive onboarding and direct deploys) are unaffected, as is the deploy-side integrity refusal. sase validate surfaces these warnings in its own Warnings: block; see sase validate.

--allow-dirty overrides the source-integrity guard and --force overrides the manifest guard. Both are deliberate escape hatches that can revert other agents' deployments; reach for them only when you know the destination is stale. --force still records the new manifest entry.

See XPrompt Skill Field for the skill-source contract and bundled skill list.