1
0
Fork 0
Workflow-first coordinated VCS!
  • Go 86.2%
  • HTML 7.9%
  • CSS 5.3%
  • JavaScript 0.6%
Find a file
Sky Johnson 68ded512a1 docs explain nested workspace workflow
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-14 16:50:07 -05:00
.github docs explain nested workspace workflow 2026-06-14 16:50:07 -05:00
cmd harbor report nested workspace status 2026-06-14 16:26:57 -05:00
docs docs explain nested workspace workflow 2026-06-14 16:50:07 -05:00
internal harbor benchmark nested workspace paths 2026-06-14 16:48:14 -05:00
templates hub trim save button labels 2026-06-14 14:59:05 -05:00
.DS_Store Update harbor skill 2026-05-30 15:11:04 -05:00
.gitignore hub: add root example config 2026-06-10 19:23:12 -05:00
go.mod build: add go module 2026-05-08 13:11:41 -05:00
harbor-hub.service add harbor hub service 2026-06-11 11:32:21 -05:00
hub.config.lob hub rename templates directory 2026-06-13 19:34:35 -05:00
README.md docs explain nested workspace workflow 2026-06-14 16:50:07 -05:00
setup.md hub rename templates directory 2026-06-13 19:34:35 -05:00
SKILL.md docs explain nested workspace workflow 2026-06-14 16:50:07 -05:00

Harbor

Harbor is a workspace-first version control prototype.

Git is excellent at tracking file history, but large multi-component workspaces often need a higher-level view of the whole project. Harbor treats the workspace itself as the main unit of state. A snapshot captures the files, component graph, contracts, and enough operation history to inspect, undo, sync, and repair the workspace later.

Harbor is ready for careful dogfooding on real projects with backups. It is not production-ready yet.

What works today

Harbor currently supports:

  • local repositories with .harbor.d metadata,
  • snapshots, logs, status, diffs, rollback, and undo,
  • local branch refs,
  • component manifests and dependency graphs,
  • nested component workspaces for colocated multi-repo projects,
  • compatibility contract metadata,
  • filesystem and HTTP/HTTPS remotes with publish, fetch, sync, and clone,
  • clone-time materialization filters for sparse workspaces,
  • local ignore/include/exclude rules,
  • object inspection,
  • operation history,
  • doctor and conservative repair flows.

The portable HTTP remote contract for Harbor-compatible hubs lives in docs/harbor-hub.md.

Build it

You need Go 1.26.2 or newer.

go build -o bin/harbor ./cmd/harbor
go build -o bin/harbor-hub ./cmd/harbor-hub

Or run directly while developing:

go run ./cmd/harbor --help
go run ./cmd/harbor-hub --config hub.config.lob --check-config

Start a workspace

On the first interactive Harbor command, Harbor asks for your name and email if global identity config is missing. It saves them in harbor/config.lob under your OS user config directory and reuses that identity for snapshot authors. Non-interactive commands do not block for prompts; they keep using environment defaults.

From an existing project directory:

harbor init
harbor status
harbor snapshot "initial import"

harbor init creates .harbor.d and a root .harbor manifest. harbor snapshot records the current workspace as immutable objects and moves the current branch ref to that new workspace snapshot.

If you already have a tree on disk and want Harbor to accept it as the current state without writing a message, use:

harbor adopt

Harbor snapshots use portable defaults without extra config: regular file bytes are stored exactly as written, text files must use LF line endings, unsafe cross-platform path names are rejected, case-insensitive path collisions are rejected, symlinks are not snapshotted by default, and file permissions are normalized to ordinary file or executable file.

Daily local workflow

harbor status
harbor diff
harbor snapshot "change terrain loader"
harbor log
harbor oplog

status and diff compare the worktree to Harbor HEAD. log shows first-parent snapshot history. oplog shows operations such as snapshot, fetch, sync, rollback, undo, clone, repair, branch changes, and component updates.

If you make a mistake:

harbor rollback HEAD_OR_WORKSPACE_ID
harbor undo

rollback moves to a specific workspace snapshot. undo walks operation history and restores the previous effective workspace state for HEAD-changing operations.

Branches

harbor branch feature-a
harbor branch list
harbor branch switch feature-a
harbor branch delete feature-a

Branches are workspace refs. Switching branches requires a clean worktree and restores that branch's workspace snapshot and manifest graph.

Remotes

Filesystem remotes can publish and fetch:

harbor remote add origin /srv/harbor/my-project
harbor publish origin
harbor fetch origin
harbor sync origin

publish copies missing typed objects and updates the remote workspace ref. Incremental publish uses the current remote branch head as a boundary, so unchanged history and unchanged blobs are skipped when the remote can be read. Remote-backed nested component pins must already exist at their component source before the parent publishes; publish never silently publishes child workspace work for you. fetch copies objects and records a local remote ref without changing your worktree. sync fetches and materializes the remote workspace into a clean local worktree.

HTTP and HTTPS remotes use the same object/ref contract against Harbor-compatible hubs. Core Harbor does not depend on a server, and hub implementations should follow docs/harbor-hub.md; Harbor also provides an optional bundled hub server as a conforming implementation.

Harbor's object compatibility contract starts at the canonical payload: object IDs are always sha256(object-type || 0x00 || canonical-payload), never hashes of compressed or stored bytes.

Run a local hub

The bundled hub server lives in cmd/harbor-hub. It hosts the portable .harbor.d remote contract at /<owner>/<repo>/.harbor.d/..., serves external templates/assets loaded at startup, writes file-backed metadata under its configured data root, supports browser setup/login/registration/repository creation, real user/group owner profiles, configurable registration/RBAC gates, and username/PAT Basic auth for CLI clone/publish access. HTTPS is preferred for deployed hubs; plain HTTP is useful for local development.

The root example config uses templates/ as template root and templates/assets/ as replaceable asset root:

go run ./cmd/harbor-hub --config hub.config.lob --check-config
go run ./cmd/harbor-hub --config hub.config.lob

--check-config validates the Lobster config and prints resolved paths. Real serving loads templates/assets and creates storage directories. Flat mockup pages in templates/*.html are offline design files; live hub routes use stored users, groups, repositories, and hosted Harbor objects.

Clone

harbor clone /srv/harbor/my-project my-project

Clone initializes the target, restores origin, records the remote ref, materializes files, hydrates declared nested component workspaces from recorded pins, and writes a clone operation.

You can choose what materializes at clone time:

harbor clone --full SOURCE target
harbor clone --component engine SOURCE target
harbor clone --include src/ SOURCE target
harbor clone --exclude assets/raw/ SOURCE target

Those flags write local materialization rules, so the workspace stays clean even when some tracked files are intentionally absent.

Components

Harbor workspaces can describe components in the root .harbor manifest:

harbor component add \
  --name engine \
  --path engine \
  --source /srv/harbor/engine \
  --role library

harbor component add \
  --name game \
  --path game \
  --source /srv/harbor/game \
  --depends engine=compatible

harbor component list
harbor graph

harbor status reports pending manifest-only graph edits as manifest changed. Run harbor snapshot to record component graph changes even when tracked files are unchanged.

You can update one component from its source:

harbor update engine

Nested component workspaces keep a game-engine style tree together while still letting each component snapshot, publish, and sync independently:

game/
  .harbor
  engine/
    .harbor
    .harbor.d/
  renderer/
    .harbor
    .harbor.d/

Declare a nested workspace component with the one extra marker:

harbor component add --name engine --path engine --source HUB_OR_PATH --workspace

That writes workspace = true in .harbor. If engine/.harbor.d already exists, component add and component link infer the marker. Parent snapshots do not capture the child's raw .harbor.d; they record the child's current workspace ID as a nested pin and overlay the child HEAD tree into the parent snapshot. Work child-first: cd engine && harbor snapshot ... && harbor publish, then cd .. && harbor snapshot ... && harbor publish. Parent clone/sync/rollback/branch switch recreate or update nested child workspaces from those pins.

Local-only nested links are useful while developing together:

harbor component link --name engine --path engine --local engine --workspace

They cannot be published from the parent until relinked to a remote source or absorbed. harbor component check reports nested state such as changed, dirty, unpublished, unreachable, or local-only. harbor doctor reports unmanaged nested Harbor workspaces and missing nested pin objects. Parent clean/materialization never deletes or rewrites child .harbor.d; dirty children must be snapshotted or cleaned inside the child first.

Contracts

Contracts are lightweight compatibility metadata attached to components:

harbor contract add \
  --component engine \
  --name api \
  --compatibility v1

harbor contract add \
  --component game \
  --name game-api \
  --compatibility v1 \
  --requires engine=v1

harbor contract list
harbor contract validate

Current validation checks ownership, duplicate names, required components, compatible dependency edges, and required compatibility labels. Deep ABI/schema/effect validation is still future work.

Local materialization and ignore rules

The root .harbor manifest can keep local-only noise out of status/snapshot and can control sparse materialization:

[ignore]
	patterns = ["build/", ".tmp/"]

[include]
	patterns = ["engine/src/"]

[exclude]
	patterns = ["assets/raw/"]

Ignore patterns affect local-only files. Include/exclude patterns affect which tracked remote paths should exist in the worktree. Harbor writes list rules as Lobster arrays; legacy newline multiline strings remain readable for existing workspaces.

Inspect and repair

harbor inspect HEAD
harbor inspect <object-id-or-prefix>
harbor doctor
harbor doctor --migrate-object-ids
harbor doctor --migrate-object-ids --repair
harbor doctor --repair

inspect prints deterministic summaries for Harbor objects. doctor checks layout, refs, configs, object hashes, object links, and operation history. Repair is conservative: it fixes cases Harbor can prove safe and refuses cases that would require guessing.

Additional docs

  • VCS design: docs/harbor.md
  • Hub setup and deployment: setup.md
  • HTTP remote contract and bundled hub notes: docs/harbor-hub.md
  • Lobster config format: docs/lobster.md

Suggested dogfood rules

Use Harbor on real projects, but keep it boring:

  1. Keep a Git repo or backup beside the Harbor workspace.
  2. Start with filesystem remotes before relying on hosted remotes.
  3. Run harbor status before destructive-looking commands.
  4. Prefer harbor snapshot "message" after each logical change, or let Harbor summarize the diff when the message is obvious.
  5. Run harbor doctor after sync, clone, and repair experiments.

Project status

Harbor is still a prototype. Its object model, CLI, and recovery story are in place enough to test the local VCS workflow end-to-end. The next big step is real-world feedback: try it on a real workspace, write down what feels awkward, and keep an eye on correctness, performance, and recovery behavior.