Skip to content

Orgabot is in private alpha. Request access, or join our Discord.

← All documentation
Start here

Upgrade an existing installation

Update the Orgabot framework in place while preserving registered projects, organizations, connectors, credentials, missions, schedules, and audit history, then verify each surface deliberately.

This is the path for an operator who already has Orgabot state. Do not start over, re-register every repository, or reconnect every provider merely because the framework changed. The framework code lives in the clone; operator state lives in the active Orgabot home. Updating one does not erase or replace the other.

What the upgrade preserves

An in-place framework update keeps the identifiers and history already stored for:

  • registered projects, their aliases, repository roots, verification and review policies, logos, issue owners, and organization mappings;
  • organizations, roles, actors, capability packs, duties, approvals, budgets, responsibilities, councils, decisions, departments, portfolios, and programs;
  • connector records, role grants, capability-slot bindings, MCP inventories, context-source bindings, and GitHub App installation selections;
  • missions, lifecycle journals, pending delivery records, audit ledgers, operational-store state, analytics, and memory references;
  • scheduler configuration and the saved durability choice.

Credentials remain in the protected store that already holds them. A framework update does not copy secrets into the repository or silently move them to a new backend.

Older orka spellings remain readable. An installation using ~/.orka keeps using it until you explicitly run orgabot migrate-home; there is no rename deadline and no need to combine that move with a framework upgrade.

1. Record the current installation before changing it

Finish or deliberately stop active work first. A framework update should not replace code underneath a running dashboard, scheduler invocation, or worker.

Create a private evidence directory first. The text files in this directory are not inputs to a migration and Orgabot never reads them. They are your before snapshot: what existed, what was active, and what you should see again after the upgrade. They can contain project names, mission instructions, pull-request URLs, provider ids, and local operating details, so do not publish them.

cd /path/to/orgabot
upgrade_evidence=/private/backup/path/orgabot-upgrade
mkdir -p "$upgrade_evidence"
chmod 700 "$upgrade_evidence"

(cd framework && npm run orgabot -- status) \
  | tee "$upgrade_evidence/01-mission-status-before.txt"
(cd framework && npm run orgabot -- long-runs) \
  | tee "$upgrade_evidence/02-long-runs-before.txt"
(cd framework && npm run orgabot -- stack status) \
  | tee "$upgrade_evidence/03-stack-status-before.txt"

These commands answer different questions:

CommandWhat it actually doesWhat to do with the result
orgabot statusThis is the authoritative mission reconciliation checkpoint, not a passive process list. It reconciles recorded liveness, attempts recovery for interrupted missions, supervises in-flight objectives, inventories open Orgabot pull requests, updates durable recovery work, and then prints recovery/hold sections plus up to the 20 newest missions.This is the primary stop/go check. Save it before and after. Do not replace the framework while it reports a running worker. A queued mission has not started yet, but can start when capacity returns, so stop its owning stack or cancel it before updating. awaiting input, awaiting approval, and waiting for follow-up are persisted holds; record their ids and confirm no worker process remains. Completed, failed, and cancelled rows do not block the code update.
orgabot long-runsThis is a read-only exception list of workers that have crossed their configured long-run notice threshold. It shows mission id, worker, elapsed time, current activity, and whether the notice was acknowledged. It does not stop, acknowledge, or steer anything.A row means a live worker needs an explicit choice: wait, steer it with follow-up, end it with stop, or acknowledge the notice and deliberately let it continue. Do not upgrade while it continues. no long-running workers does not mean there are no running workers; a newer run may be below the threshold, so status remains the primary check. Save this output when it has rows; saving the empty result is useful evidence but not required for recovery.
orgabot stack statusThis is a read-only report of the local stack components the current installation would reuse or start, including dashboard and durability readiness.Save it so you know which components must be present after restart. It is not proof that no individual worker is running; use status for that.

The tee files are operator evidence, not backups. If you prefer not to retain an empty long-runs file, it is safe to delete that one after confirming the message. Keep status and stack status until the post-upgrade comparison is complete.

If orgabot up is running, stop it from the terminal that owns it only after the mission check above is safe. orgabot down explains ownership; it does not hunt for unrelated processes to kill. Run status once more after stopping the stack and confirm that no mission is running or able to leave queued state before changing the checked-out framework code.

Take two backups:

  1. Back up the active Orgabot home with your normal local backup mechanism, preserving owner-only permissions. The active home may still be ~/.orka.
  2. Take a validated operational-store backup to a private path outside the Orgabot home:
(cd framework && npm run orgabot -- opstore backup /private/backup/path/operational-before-upgrade.db)

The database backup does not replace the home backup: some authoritative records, logs, project configuration, and compatibility artifacts live outside the database, while Keychain or another protected secret backend may live outside the home entirely.

Save the configuration inventory you will compare afterward. Unlike status, these commands do not reconcile missions. Their output proves that identities, policies, placement, and custody survived; it is not consumed by the upgrade.

(cd framework && npm run orgabot -- project list) \
  | tee "$upgrade_evidence/04-projects-before.txt"
(cd framework && npm run orgabot -- organization list) \
  | tee "$upgrade_evidence/05-organizations-before.txt"
(cd framework && npm run orgabot -- topology --json) \
  | tee "$upgrade_evidence/06-topology-before.json"
(cd framework && npm run orgabot -- opstore matrix) \
  | tee "$upgrade_evidence/07-opstore-matrix-before.txt"
(cd framework && npm run orgabot -- scheduler status) \
  | tee "$upgrade_evidence/08-scheduler-before.txt"
(cd framework && npm run orgabot -- secrets status) \
  | tee "$upgrade_evidence/09-secret-custody-before.txt"

For each organization, also save organization show <org> and connector list <org> under distinct filenames. Those commands print configuration and status, never secret material, but their identifiers and scopes are still private operational information.

2. Update the framework and installed skills

First preserve or commit any changes in your clone. Never use a reset to discard work just to make an upgrade fit. Then update from the branch you intentionally operate, normally main:

git status --short
git fetch origin
git switch main
git pull --ff-only origin main
(cd framework && npm install)
bash orgabot-skills/install.sh

npm install belongs in framework/; there is no root package.json. The CLI runs the TypeScript sources directly, so a framework build is not required for normal operation. The skills installer is idempotent: it refreshes the skill links and the framework pointer without replacing registered projects or organization state.

Do not start the first-run journey to perform this upgrade. When existing state is readable, the dashboard projects that state instead of asking you to recreate it.

3. Let the framework inspect and migrate its own stores

Run the general diagnostic first:

(cd framework && npm run orgabot -- doctor)

doctor self-heals the framework pointer and reports exact corrective commands for the state it can observe. Treat those findings as the upgrade plan; do not blindly advance an operational-store authority phase.

Then open and verify the operational store:

(cd framework && npm run orgabot -- opstore status)
(cd framework && npm run orgabot -- opstore verify)
(cd framework && npm run orgabot -- opstore matrix)

opstore status creates the store when absent and applies additive schema migrations transactionally. opstore verify checks integrity and recovery readiness. opstore matrix is observational. Never run prune-compat merely because it appears in CLI help; it deletes leftover files and should be used only for the specific doctor finding, refusal, or procedure that names it.

One refusal names it directly. If the operational store holds no organization document but the legacy organizations.json still exists under the Orgabot home, every organization read refuses (missions hold, the dashboard reports the store as unreadable) rather than answering with an empty org chart, because an empty chart is what hands a role-owned mission to the generic worker. This means the organizations domain never reached the store on this install. Check the legacy file is a leftover you no longer need, then acknowledge with:

(cd framework && npm run orgabot -- opstore prune-compat organizations --dry-run)
(cd framework && npm run orgabot -- opstore prune-compat organizations --yes)

Check older mission records without changing them:

(cd framework && npm run orgabot -- lifecycle migrate --dry-run)
(cd framework && npm run orgabot -- lifecycle reconcile --dry-run)

If the dry run or doctor reports legacy-only missions, run lifecycle migrate without --dry-run, then interpret the report rather than rerunning until every legacy count reaches zero. Migration is idempotent and preserves mission ids, statuses, and pull-request references.

The migration has four materially different outcomes:

OutputMeaningUpgrade decision
alreadyThe mission already has lifecycle-journal authority.Good; nothing was needed.
migratedThis pass created a journal only after proving the projected record round-tripped without changing evidence.Good; save the count. A second pass normally reports these under already.
left as legacyThe historical record could not be represented without changing one of its own fields or inventing evidence it never recorded. The command stamps and preserves it as legacy_unconvertible; conflicts are intentionally nonfatal.Expected for the sealed pre-journal archive. Do not force or edit it. Do not repeatedly rerun migration trying to reach zero.
failedOrgabot could not assess or publish a record safely, for example because existing lifecycle state was unreadable.Not an archive result. Stop and investigate; the command exits nonzero when this count is nonzero.

skipped is also actionable: it means a mission was running and the backfill refused to race its live writer. Let or make that mission settle, then rerun the migration for it. vanished means the record disappeared between listing and re-read and also deserves investigation if another process did not deliberately retire it.

For the current reference installation, a completed pass reports 1,727 scanned, 1,460 already authoritative, zero newly migrated, zero failed, and 267 retained as legacy_unconvertible. All 267 are terminal historical records from the closed 2026-06-26 through 2026-07-26 pre-journal window: 261 completed and six cancelled. Their exact preservation refusals are 225 missing verifyPassed claims, 33 contradictory verifyPassed claims, six missing cancellation summaries, and three status contradictions. Those records remain visible in history with their legacy provenance; they are not queued jobs and have no worker to restart.

The successful terminal condition is therefore:

  • failed: 0 (the line is absent when zero);
  • skipped: 0, or every skipped live mission is understood and handled;
  • every convertible record appears under already or migrated;
  • the remaining conflicts match the bounded historical archive rather than a newly created mission.

As of this framework version, lifecycle reconcile --dry-run, doctor, and the System health mission-authority check count the sealed archive inside the broad legacy-only / with no authority total. They can therefore continue to print orgabot lifecycle migrate or needs attention after the only safe migration has completed. That diagnostic does not distinguish an actionable unstamped legacy record from the intentional read-only archive. Judge migration completion from the migration report above: no failures, no unexplained skips, and no new record outside the historical archive window.

Run lifecycle reconcile --dry-run again after migration. Only run its write form when the preview identifies a compatibility record that drifted from an existing readable journal. Reconciliation cannot and must not manufacture a journal for the archived 267.

Analytics backfill is optional and idempotent. Run it if you want dashboards to include history from before the analytics journal existed:

(cd framework && npm run orgabot -- analytics backfill)

4. Decide separately whether to rename the state home

If this installation still uses ~/.orka, leaving it there is supported. To move it, stop the dashboard and inspect the atomic migration first:

(cd framework && npm run orgabot -- migrate-home --dry-run)
(cd framework && npm run orgabot -- migrate-home --yes)

The command refuses conflicting home variables, an existing destination, a cross-filesystem move, or a process holding the operational store. It takes a store backup, performs one rename, and creates the required compatibility symlink; if the symlink cannot be created it renames the home back. Do not copy the directory by hand while SQLite WAL files may be active.

5. Verify every registered project in place

Start with the registry you already have:

(cd framework && npm run orgabot -- project list)

For every project, verify these surfaces:

(cd framework && npm run orgabot -- project current /path/to/repository --json)
(cd framework && npm run orgabot -- project verify-policy <project>)
(cd framework && npm run orgabot -- context issue-source show <project>)

Repository roots own shared relationships

The registered project whose path is the repository root is the owner of that repository's external relationships. That includes the GitHub issue source, connector mappings, and other repo-level records. A child project is a monorepo-discovered execution target (usually a --workdir beneath the root), not a second repository owner. This distinction keeps one repository from acquiring competing issue or connector identities during an upgrade.

If a relationship points at the wrong root registration, use project set-issue-owner only to choose among multiple registrations of the same repository root. It cannot select a child project:

(cd framework && npm run orgabot -- project set-issue-owner <root-project>)

Replace the placeholder with the root project id you want to own the repository's issues. The command takes one project id, not a child selector; it chooses among the competing root registrations. If no repository-root project is registered, restore or register the root first; do not assign ownership to a monorepo child as a substitute. Then re-check the child projects and their inherited execution scope.

Use corrective commands only when the inventory shows a real difference:

  • A repository moved: project set-root <project> <path> [--workdir <subdir>].
  • Verification changed: project set-verify <project> ... or project verify-policy <project> --preset <preset>.
  • A shared repository resolves to the wrong registered root: project set-issue-owner <root-project> (root registrations only; it cannot select a child project).
  • A repository has no operating reference: project init <project>. It writes an uncommitted file for review. The legacy operating-reference filename remains readable and is updated in place when explicitly regenerated; do not use --force without reviewing the repository's custom guidance first.

Do not remove and re-add a project to fix its path or display name. Project ids key mission, pending-delivery, context, memory, issue-owner, and organization records; set-root and rename preserve that identity.

6. Verify organizations, connectors, and credentials

Canonical MCP cutover

This upgrade preserves organizations, attachments, grants, project roots, and audit history while establishing one installation-wide MCP registry keyed by transport fingerprint. Claude/Codex configuration is import evidence only, not authority. Preview and retain both plans before applying anything:

(cd framework && npm run orgabot -- connector mcp-plan <org>) | tee "$upgrade_evidence/mcp-plan.txt"
(cd framework && npm run orgabot -- connector mcp-migrate --dry-run) | tee "$upgrade_evidence/mcp-migrate-plan.txt"

Both commands are read-only. Stop on conflicts, changed fingerprints, or a manual-configuration finding that you have not resolved. reconnect_required is expected when the old credential belonged to Claude or Codex; it becomes a stop condition before granting Orgabot agents access, not a reason to avoid the safe structural migration. Apply only the reviewed migration and retain its receipt, then verify:

(cd framework && npm run orgabot -- connector mcp-migrate --apply) | tee "$upgrade_evidence/mcp-migrate-apply.txt"
(cd framework && npm run orgabot -- connector list <org>) | tee "$upgrade_evidence/mcp-connectors.txt"
(cd framework && npm run orgabot -- connector mcp-status) | tee "$upgrade_evidence/mcp-status.txt"

Apply mutates canonical bindings only; it does not widen role grants or change root/child project ownership. Complete bearer or environment custody with connector mcp-authorize or connector mcp-authorize-env; complete OAuth from the organization's Connections card. The Capability Registry is read-only. Retain the custody receipt and verify with doctor. Keep intentional Claude and Codex entries by default so those MCPs remain usable directly from either harness in iTerm. Orgabot's canonical profile must work independently, but import does not consume or delete the harness entry. If you no longer want an MCP in a particular harness, temporarily move only that entry aside and run one granted read-only tool through orgabot tool run-as <org> <role> <tool>. Restore the entry and stop if that call fails. Delete it only as an explicit cleanup choice after the canonical fingerprint, inventory, custody, role grants, and source-independent call all match.

An apply receipt may say consolidate for Claude- and Codex-sourced records of the same server. That is the intended repair: Orgabot keeps one active organization attachment for the canonical profile, preferring the record that owns grants or OAuth state, and retires the duplicate without restoring any revoked grant. A disconnected connector disappears from Configured and is shown under its provider in Available to reconnect; a retired duplicate is not offered when the same canonical profile or public server is already active.

Do not enter credentials for a connector labeled source-linked. That label means discovery found a private launcher inside an authoring harness app bundle, not a portable MCP installation. It is available only where that harness exists until the provider supplies a stable URL or standalone command that Orgabot can own. Keep it as harness inventory or configure the provider's portable MCP definition; do not copy a private harness credential into Orgabot.

List the existing organization rather than creating a replacement:

(cd framework && npm run orgabot -- organization list)
(cd framework && npm run orgabot -- organization show <org>)
(cd framework && npm run orgabot -- organization ledger verify <org>)
(cd framework && npm run orgabot -- organization health <org> --json)

If ledger verification reports previous_hash_mismatch, stop and inspect it; do not edit the ledger file or database row. A valid historical race can be previewed without changing state:

(cd framework && npm run orgabot -- organization ledger repair-fork <org> --reason "confirmed concurrent historical append")

The preview names the fork entry, current head, and orphan head. Only if it classifies exactly one two-head concurrency fork should you rerun with --yes. That first persists a readable immutable approval and then appends the reconciliation, after which verification should pass. Hash corruption, duplicate entries, unknown parents, and more complex graphs are refused rather than reclassified as valid history.

For each organization, inspect and then check its existing connectors:

(cd framework && npm run orgabot -- connector list <org>)
(cd framework && npm run orgabot -- connector check <org> <connector-id>)
(cd framework && npm run orgabot -- connector mcp-status)
(cd framework && npm run orgabot -- context sources list)
(cd framework && npm run orgabot -- secrets status)

connector check performs the connector's bounded live provider check and may refresh health evidence; for canonical MCP attachments, a successful native check also persists the broker's tools/list inventory without consulting the Claude/Codex source. It does not widen a grant. Do not reconnect a healthy connector just to adopt the new framework. Pause, rotate, replace, or remove it only when its check or doctor finding identifies that lifecycle action.

If secrets status reports the legacy plaintext connector-secret file, bare secrets migrate moves its handles into the selected protected local store. A cross-backend move requires explicit --from, --to, and handle ids; a default change never moves credentials across a custody boundary.

For adopted MCP and skill sources, verify the derived inventories separately:

(cd framework && npm run orgabot -- connector discover <org>)
(cd framework && npm run orgabot -- skills sync --check)
(cd framework && npm run orgabot -- skills verify)

Discovery and skills sync --check propose what changed. They do not grant a role access or admit a new skill digest.

7. Verify scheduling, workflow policy, and deployment placement

(cd framework && npm run orgabot -- scheduler status)
(cd framework && npm run orgabot -- workflow list --json)
(cd framework && npm run orgabot -- topology)
(cd framework && npm run orgabot -- topology --matrix)
(cd framework && npm run orgabot -- topology --json)

If scheduler status finds a legacy com.orka launchd entry or # ORKA BEGIN cron block, run scheduler reinstall; it removes that stranded entry and rewrites the current one idempotently. Do not reinstall a healthy scheduler solely because the framework changed.

Topology is read-only. Existing local-only operation stays local-only unless you deliberately edit ~/.orgabot/deployment.json and acknowledge any custody boundary. A newly available cloud adapter does not move existing state by itself.

8. Restart and perform a small acceptance check

Start the stack again:

(cd framework && npm run orgabot -- up)

In a second terminal, capture the corresponding after state:

(cd framework && npm run orgabot -- status) \
  | tee "$upgrade_evidence/10-mission-status-after.txt"
(cd framework && npm run orgabot -- long-runs) \
  | tee "$upgrade_evidence/11-long-runs-after.txt"
(cd framework && npm run orgabot -- stack status) \
  | tee "$upgrade_evidence/12-stack-status-after.txt"
(cd framework && npm run orgabot -- project list) \
  | tee "$upgrade_evidence/13-projects-after.txt"
(cd framework && npm run orgabot -- organization list) \
  | tee "$upgrade_evidence/14-organizations-after.txt"
(cd framework && npm run orgabot -- topology --json) \
  | tee "$upgrade_evidence/15-topology-after.json"
(cd framework && npm run orgabot -- opstore matrix) \
  | tee "$upgrade_evidence/16-opstore-matrix-after.txt"
(cd framework && npm run orgabot -- scheduler status) \
  | tee "$upgrade_evidence/17-scheduler-after.txt"
(cd framework && npm run orgabot -- secrets status) \
  | tee "$upgrade_evidence/18-secret-custody-after.txt"

Compare identities and configured choices, not volatile timestamps or health observation times. Project ids and roots, organization ids, connector ids and scopes, operational-store authority phases, scheduler target, topology providers, and credential backend should remain the same unless this procedure explicitly changed one. Mission status may legitimately advance while you make the installation safe; the important check is that every nonterminal mission id still exists with an explainable state and no worker was silently abandoned.

Confirm in the dashboard that:

  • the same projects, organizations, roles, connectors, duties, approvals, and recent missions are present;
  • project verification and issue-source choices match the pre-upgrade inventory;
  • connector health is known, and no role gained a new grant;
  • System health has no unexplained failure;
  • topology and durability show the intended providers.

Use a low-risk registered project for the final proof. A mock or narrowly scoped read-only check is enough to prove routing and state visibility; do not invent a production write merely to test the upgrade.

Roll back safely

If the new framework cannot read the installation:

  1. Stop the new dashboard and workers.
  2. Preserve its diagnostics and do not reset the Orgabot home.
  3. Restore the framework commit and matching framework/package-lock.json you intentionally used before the upgrade, then run npm install in framework/.
  4. If opstore verify identifies store damage, use the validated opstore restore <backup-path> path. It stages and validates the backup before replacing the working store and keeps a bounded rollback window.
  5. Restore the full home snapshot only with all Orgabot processes stopped, and only when the store-level recovery is insufficient.

Never reconnect providers, delete projects, run reset, or prune compatibility records as a first recovery step. Those actions broaden the failure and can discard the identity or evidence needed to repair it.

Upgrade-complete checklist

The installation is up to date when:

  • opstore verify and every organization ledger verification pass, and doctor has no unexplained finding. The known sealed-archive lifecycle count may remain as explained above; zero legacy-only records is not an acceptance criterion;
  • the project, organization, connector, scheduler, and topology inventories match the intended pre-upgrade state;
  • every registered repository resolves at its current path and retains its verification and issue-source policy;
  • connector checks succeed or produce an understood, actionable hold;
  • no credential changed custody and no role gained authority implicitly;
  • the dashboard restarts on the new framework and shows the existing history.

For a genuinely separate clean-install test, use a separate clone and an isolated --home <dir> value. Never point that experiment at the home whose upgrade you are validating.