Browse Ship docs
Ship docs
Ship docsThe .ship folder

The .ship folder

Where your repo meets Ship

When shipctl init runs in a repository, it creates a folder called .ship/. That folder is the local home of everything Ship needs to operate on the repo without phoning home for every small fact. Think of it as the repo's checked-in copy of the workspace's vocabulary — the knowledge starters your team wants every agent to read, the policy files that pin behaviour, the cached bundle of artifacts the routines use, and a small holding area for outgoing feedback drafts.

Most of it is human-readable. Most of it is meant to be reviewed in pull requests like any other source. The folder is committed to git on purpose.

What you find inside

A typical .ship/ directory holds:

  • config.yml — the configuration. Records the preset, the bundle version pin, the workspace API base, stack hints, and the routine wiring that maps each lane to its specialist.
  • knowledge/ — markdown files that mirror into the workspace's knowledge base. A change here, committed and pushed, surfaces as a draft in the review queue, not as a live article. The reference repo's .ship/knowledge/ typically holds files like code-style.md and ui-runbook.md — starter articles your team customises from day one.
  • cache/ — local cache of the artifact bundle. Filled by shipctl sync. Commit it for deterministic builds or .gitignore it if your CI fetches fresh on every run.
  • state/ — small files written during a routine run to remember progress between steps. Safe to commit but not required.
  • feedback-drafts/ — local markdown drafts written with shipctl feedback draft. When submitted, they move to feedback-drafts/sent/.
  • tracker-fsm.md (when present) — a checked-in description of the ticket workflow the routines should obey. The states, the transitions, the labels.

You may see additional files depending on the preset — a policies/ directory, agent-specific overrides. Everything inside .ship/ is a first-class part of the repo.

Why commit it

Committing .ship/ is the difference between "the team has a process" and "the team can prove it had a process on the day of the incident." Six months from now, when somebody asks why a routine behaved the way it did, the answer lives in git log .ship/. The config that was in force on the day. The knowledge starters the agent read. The bundle version the routines were pinned to. All of it diff-able, reviewable, owned by the same humans who own the rest of the codebase.

Prompts and policies are not vibes. They are policy written in a language models actually read. They belong in the repository for the same reason database migrations live in git — behaviour you cannot diff is behaviour you cannot audit.

The single sanctioned write path

Here is the one rule that matters more than any other in this folder.

The server's source of truth — the knowledge base, the audit log, the workspace state — is mutated through one path: the harvester. The harvester is the workspace-side process that watches your repo, reads the changes you committed under .ship/, and proposes them as drafts into the review queue. From there, a human reviews and publishes, the way every other piece of knowledge gets published.

There is no second path. The CLI does not push articles into the live knowledge base. An agent running in CI does not bypass review and write straight to the bucket. A script you might write that calls the workspace API directly is not a sanctioned path — even if the API would accept the call, the convention is that the harvester is the one place where "this is what the repo says" meets "this is what agents read."

A single write path is the only way to keep three things true at once: the knowledge base does not silently diverge from the repo, the review queue is always where new facts surface, and the audit log can credibly answer "who promoted this article." If anything that could call the API could publish, drift would arrive within a quarter.

So: commit changes to .ship/knowledge/ like any code change. Open a pull request, review it, merge it. The harvester takes it from there. Not through a script. Not through a side door.

What does not belong in .ship/

A short list of things to keep out:

  • Secrets, credentials, tokens. Same as anywhere else in the repo. If the file would be a problem in a leak, it does not belong in git.
  • Customer data, real ticket bodies, anything you would redact in a screenshot. Knowledge is policy and conventions, not transcripts.
  • Generated files larger than a few hundred kilobytes. The cache is the exception, and even the cache should be committed deliberately, not by accident.

.ship/ is a small, opinionated folder. Treat it the way you would treat a migrations/ directory or a .github/ directory — owned, reviewed, committed, and meaningful.

The .ship folder — Ship docs — Harbor Gang