Skip to content

Define aha 0.2 Archive/Workspace lifecycle and compatibility boundaries - #16

Merged
adewale merged 8 commits into
mainfrom
plan/explicit-sync-state-machine-0.2
Jul 13, 2026
Merged

Define aha 0.2 Archive/Workspace lifecycle and compatibility boundaries#16
adewale merged 8 commits into
mainfrom
plan/explicit-sync-state-machine-0.2

Conversation

@adewale

@adewale adewale commented Jul 11, 2026

Copy link
Copy Markdown
Owner

What

Define aha's complete 0.2 lifecycle and compatibility boundaries around one explicit authority flow:

Agent histories --archive upload--> Archive --archive download--> Workspace

This replaces the pre-launch command model, makes Archive/Workspace transitions construction-safe, bounds repeated download work, preserves repair identity outside SQLite, and versions config, Archive, HTTP, and MCP boundaries.

Why

The previous surface mixed transport (depot), implementation (corpus), and combined-operation (refresh) concepts. A caller could not reliably infer:

  • where durable truth lived;
  • which resource a command would mutate;
  • whether a Workspace represented the latest Archive vector;
  • whether failed preflight had already created local state;
  • how an older reader or writer should handle newer state.

Because aha has no released users, retaining aliases would create permanent ambiguity without providing real compatibility. The lifecycle and rejection policy are specified in docs/command-state-machine-v0.2-plan.md; storage and behaviour compatibility policy is in docs/compatibility-policy.md.

How

Make authority and transitions explicit

  • Replace the public surface with archive, workspace, status, search, show, analyse failures, dashboard, and mcp check|serve commands.
  • Remove pre-launch commands, flags, and config keys rather than aliasing them.
  • Add exhaustive closed Archive/Workspace state tables and state-derived next actions.
  • Persist each Workspace's Archive binding and exact materialised machine vector.
  • Detect v1 Archives as unsupported input and never modify or migrate them in place.

Construct capabilities before effects

  • Require opaque initialised-Archive read/write capabilities and frozen upload/download plans; zero values authorise nothing.
  • Derive upload authorisation from the Archive transition model before capture or publication.
  • Validate address, credentials, Archive metadata, destination ownership, binding, and adapter support before opening a writable Workspace.
  • Keep upload independent of the Workspace and prohibit implicit Archive or bucket creation.
  • Advance the materialised vector only after the complete planned download succeeds.

Bound repeated work and preserve recovery

For M machines, C changed machines, and F(C) files in their current manifests:

  • current download is O(M) and performs no manifest/blob fetch, lifecycle lock, or SQLite write;
  • behind download is O(M + F(C));
  • unchanged-machine manifests are skipped;
  • blob checks use indexed point queries;
  • changed manifests are reused between planning and execution;
  • Archive status avoids blob HEADs; deep content auditing remains explicit under archive verify.

Workspace repair builds and verifies a sibling, atomically exchanges it, and retains the previous Workspace. A checksummed aha.workspace.identity.v1 witness outside SQLite preserves the Archive binding even when the database is unreadable.

Define compatibility boundaries

  • Config declares aha.config.v1, preserves JSONC comments, supports reverse-domain opaque extensions, and rejects unsupported schemas before mutation.
  • Archive markers declare format major/minor plus required and optional features. Unknown required features block read, verify, and write capabilities; unknown optional features remain ignorable.
  • Newer Workspace identity and SQLite schemas produce upgrade_required rather than being opened for mutation.
  • Unsupported snapshot adapters remain durable in the Archive but cannot make a Workspace falsely current.
  • HTTP uses /api/v2 and advertises aha.http.v2.
  • MCP advertises aha.mcp.v2 through aha_capabilities; the generated TypeScript client uses the same 0.2 vocabulary.
  • Compatibility dates are reserved for real semantic gates rather than persisted byte formats. An inert date is deliberately not added.

Keep interfaces and evidence aligned

  • Add aha.status.v2 and linker-injected version --json build identity.
  • Adopt British English for first-party interfaces, with explicit protocol/schema exceptions.
  • Update active documentation, generated command metadata, smoke scripts, dashboard routes, TypeScript surfaces, and MCP conformance together.

Alternatives considered

  • A combined sync command: rejected because upload and download have independent partial outcomes and mutation targets.
  • Compatibility aliases: rejected because this is pre-launch and aliases would preserve the model ambiguity this change removes.
  • Automatic Archive initialisation or bucket creation: rejected because upload must not acquire undeclared authority.
  • A compatibility date today: rejected because no intentional behaviour fork exists yet; dates need a change registry, support window, upgrade command, and rollback policy.
  • Another local cache to remove full-manifest scans: rejected because the remaining linear metadata cost requires a versioned delta-manifest/checkpoint design.

Testing

  • Added exhaustive transition and zero-capability tests.
  • Added regression coverage for no-op downloads, changed-machine planning, manifest reuse, WAL visibility, v1 preservation, unsupported schemas/features/adapters, identity-witness recovery, mismatch, unsafe destinations, and repair.
  • Confirmed focused tests failed during their red phase—for example, the HTTP contract test observed legacy /api/status returning 200, the config rewrite test lost nested extension comments, and unsupported Archive capabilities were initially accepted.
  • make verify-full passes: unit/integration tests, go vet, race suite, bounded fuzzing, pinned TypeScript 5.9.3 typechecking/runtime tests, Linux/Darwin/Windows builds, and MCP SDK/code-mode conformance.
  • The pinned executable N/N−1 journey builds b550e6b, publishes populated v2 history, then verifies, downloads, and searches it with current code; it also proves legacy writers cannot move v3 pointers.
  • Independent security, compatibility, capability, and performance re-reviews report no remaining blockers.
  • Both GitHub Actions checks pass for 748af25.
  • git diff --check passes.

The optional Python FastMCP conformance leg was skipped because the Python mcp package is unavailable; the TypeScript and Go reference-server legs pass. The credentialed live R2 smoke suite was not run without its pinned external capability.

Risk

This is intentionally a large, atomic pre-launch change: splitting command vocabulary, state authority, generated clients, and documentation would leave intermediate commits with contradictory public contracts.

Primary risks and mitigations:

  • Breaking CLI/HTTP/MCP names: intentional before release; removed vocabulary is covered by rejection/static tests.
  • Mixed-version writers: current readers accept exact legacy v2 state, current writers publish only v3 state under aha-v3/, and the pinned N/N−1 executable journey proves both forward reading and reverse-direction write refusal.
  • Workspace repair identity: the external witness is checksummed, fsynced, and cross-checked against SQLite when readable.
  • Remote behaviour: fake-R2, fault-injection, CAS, and cross-platform suites pass; the pinned live smoke remains the outstanding external check.
  • Residual complexity: each changed machine still publishes a logically full manifest, so metadata work remains linear in current changed-machine files.

There is no visual UI change requiring screenshots; dashboard edits update versioned endpoint paths, and the HTML change updates architecture copy/metrics.

Review guide

  1. internal/model/lifecycle.go and internal/model/lifecycle_test.go — closed transition contract.
  2. internal/depot/depot_v2.go and internal/depot/push_v2.go — capability construction, publication, and compatibility enforcement.
  3. internal/cli/command_archive.go — side-effect-free download planning and no-op path.
  4. internal/corpus/workspace_*.go — binding, vector, indexed lookup, identity witness, and repair state.
  5. internal/server/server.go, internal/mcp/tools.go, and generated TypeScript — versioned wire contracts.
  6. docs/command-state-machine-v0.2-plan.md and docs/compatibility-policy.md — product and compatibility decisions.

@adewale adewale changed the title Define the 0.2 command and state-machine model Define the 0.2 Archive and Workspace state model Jul 12, 2026
@adewale adewale changed the title Define the 0.2 Archive and Workspace state model Define the 0.2 Archive and Workspace model Jul 12, 2026
@adewale adewale changed the title Define the 0.2 Archive and Workspace model Implement the 0.2 Archive and Workspace lifecycle Jul 12, 2026
@adewale adewale changed the title Implement the 0.2 Archive and Workspace lifecycle Make aha 0.2 lifecycle explicit with Archive and Workspace Jul 12, 2026
@adewale adewale changed the title Make aha 0.2 lifecycle explicit with Archive and Workspace Define aha 0.2 Archive/Workspace lifecycle and compatibility boundaries Jul 12, 2026
@adewale
adewale merged commit 99588a2 into main Jul 13, 2026
2 checks passed
@adewale
adewale deleted the plan/explicit-sync-state-machine-0.2 branch July 13, 2026 00:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant