Skip to content

docs(deploy): two-phase deploy_component, revert_component, stage/activate CLI (draft) - #599

Open
dawsontoth wants to merge 5 commits into
mainfrom
claude/two-phase-deploy-docs
Open

docs(deploy): two-phase deploy_component, revert_component, stage/activate CLI (draft)#599
dawsontoth wants to merge 5 commits into
mainfrom
claude/two-phase-deploy-docs

Conversation

@dawsontoth

Copy link
Copy Markdown
Contributor

Draft. Documentation companion to the two-phase deploy work in HarperFast/harper#1849 (also a draft). Tracks that PR — the API surface there is still settling (the ops fold landed; the team is finalizing before de-draft), so hold merge until #1849 lands and pin the version badges to the shipping release.

What this documents

The deploy_component operation now runs as a two-phase, cluster-wide deploy, and there are new operator-facing knobs plus a rollback operation. This PR updates the reference docs to match.

reference/operations-api/operations.md

  • deploy_component — documents the internal stage → cluster-wide barrier → activate flow (all-or-nothing at go-live), and the new properties:
    • activate: false — stage-and-stop; returns a staged deployment_id, nothing goes live.
    • deployment_id — activate a previously-staged deployment (no re-fetch/install).
    • revert_on_failure, two_phase, ignore_replication_errors, deployment_timeout.
    • Worked examples for a normal deploy and for stage-now / activate-later.
  • revert_component (new section) — fast cluster-wide rollback to the retained previous version; bidirectional; customer-driven-rollback use case.
  • Deployment lifecycle — updated phase names (stage/activate, legacy prepare/replicate), the new statuses (staging/staged/activating/rolled_back), and staged-build retention (deployment_stagingRetention_maxCount, default 5) with the "aged-out deployment_id" caveat.

reference/cli/operations-api-commands.md

  • Added harper stage, harper activate, and harper revert to the alias table and the aliases list, with examples in Component Operations.

Notes for review

  • Version badges use v5.2.0 as a placeholder — confirm against the actual shipping release before merge.
  • I did not touch the reference_versioned_docs/version-v4/ copies (this is a v5 feature).
  • No new config-reference page was added for deployment_stagingRetention_maxCount; it's described inline where deployments are documented, matching how deployment_payloadRetention_maxSize is currently surfaced. If you'd prefer a dedicated configuration entry, happy to add one.

🤖 Generated with Claude Code

…ivate CLI

Document the two-phase deploy behavior and the new surface from HarperFast/harper#1849:

- deploy_component: cluster-wide stage -> barrier -> activate; new properties
  activate:false (stage-and-stop, returns a staged deployment_id), deployment_id
  (activate a previously-staged deployment), revert_on_failure, two_phase, and
  the ignore_replication_errors / deployment_timeout knobs.
- revert_component: fast cluster-wide rollback to the retained previous version.
- Deployment lifecycle: stage/activate phase names, staged/staging/activating/
  rolled_back statuses, and staged-build retention (deployment_stagingRetention_maxCount).
- CLI: harper stage / activate / revert verbs (aliases + examples).

Companion to HarperFast/harper#1849 (still a draft).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the documentation for the CLI and Operations API to reflect the new two-phase deployment process (staging and activation) and the rollback mechanism (revert_component). It introduces new CLI commands, aliases, API parameters, and examples. The review feedback suggests improving consistency by pointing the new CLI operation category links to the main #components section, and enhancing readability in the API documentation by adding clear labels to the multi-step "Stage now, activate later" JSON examples.

Comment thread reference/cli/operations-api-commands.md Outdated
Comment thread reference/operations-api/operations.md
@github-actions
github-actions Bot temporarily deployed to pr-599 July 21, 2026 14:32 Inactive
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-599

This preview will update automatically when you push new commits.

…tage/activate example

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions
github-actions Bot temporarily deployed to pr-599 July 21, 2026 14:42 Inactive
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-599

This preview will update automatically when you push new commits.

@dawsontoth
dawsontoth marked this pull request as ready for review July 29, 2026 17:53
@dawsontoth
dawsontoth requested a review from a team as a code owner July 29, 2026 17:53
Conflict in reference/operations-api/operations.md was additive: main added the
`credentials` parameter plus its "Deploy credentials" section (#581) where this
branch adds the two-phase parameters. Kept both — the parameter list now carries
activate/deployment_id/revert_on_failure/ignore_replication_errors/
deployment_timeout/two_phase AND credentials, followed by main's credentials
section. main's get_deployment_payload / delete_deployment_payload docs (#600)
are untouched.
… values

Documents harper-pro#594 and syncs with harper#1849's latest behavior.

add_ssh_key `generate: true` (harper-pro#594):
- Harper mints the ed25519 keypair on the node and returns only `public_key`,
  so the private key is never carried in a request body, shell history, or CI
  log. Includes the response shape and the `harper:<name>` comment.
- `key` and `generate` are mutually exclusive; ssh-keygen must be on PATH.
- Notes that `public_key` is returned ONLY on the generating call — Harper does
  not retain it, and update_ssh_key requires a key you supply (it cannot mint
  one), so the recovery path is delete_ssh_key + add_ssh_key generate again.
- CLI example added alongside the deploy/stage/activate/revert examples.

Payload retention (harper#1849):
- Splits the old one-line aside into its own subsection with a table covering
  both bounds: payloadRetention_maxSize (10 MiB, bounds a single payload) and
  the new payloadRetention_maxCount (default 1, bounds how many are kept per
  project). Explains why the default is conservative, that rows are never
  deleted, and that a reclaimed payload reports payload_blob_present: false.

Also:
- revert_on_failure / ignore_replication_errors now note they apply to a
  `deployment_id` activate too, matching the peer-failure gate added to that
  path.
- list_deployments `status` listed only 5 of 13 real values; replaced with
  terminal vs in-flight groupings.
- New note on restartRequired: deploying a brand-new component without a
  restart marks one as required (per node), while redeploying a live component
  does not.
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-599

This preview will update automatically when you push new commits.

@github-actions
github-actions Bot temporarily deployed to pr-599 July 29, 2026 18:03 Inactive
…cument them

The SSH rows linked to #certificate-management, but the SSH operations are
documented under ## Components — so every one of those seven links landed the
reader in the wrong section. Repointed them to #components (the convention the
other 15 component rows already use).

Auditing the same block turned up the identical defect on the six user/role rows
(list_users, add_user, alter_user, drop_user, list_roles, drop_role), which are
documented under ## Users & Roles. Repointed those to #users--roles, matching the
existing link to that section elsewhere in the docs.

The five genuine certificate rows (create_csr, sign_certificate,
list_certificates, add_certificate, remove_certificate) were already correct and
are unchanged. Category labels updated to match their new targets.

Verified every operations.md anchor referenced from this table against the real
headings — all 11 resolve.
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-599

This preview will update automatically when you push new commits.

@dawsontoth

Copy link
Copy Markdown
Contributor Author

Opened #616 stacked on this branch: docs(deploy): by-reference deploys, sealed credentials, CI token auth.

It targets claude/two-phase-deploy-docs rather than main, so its diff shows only the new material (+139, no deletions, no overlap with this PR). Merge this one first and #616 retargets to main automatically.

Where the two meet: this PR documents the two-phase deploy and revert_component; #616 documents how you point a cluster at a specific commit in the first place (harper deploy by_ref=true), how it authenticates to a private source (harper deploy setup=true), and how CI authenticates to the cluster (harper login --for-ci + HARPER_CLI_REFRESH_TOKEN). It leans on your revert_component section for the point that a rollback to the previous version needs no credential at all.

- `urlPath` — override the HTTP URL path the component is mounted at (e.g. `"/api/v2"`)
- `install_allow_scripts` — set to `true` to allow npm pre/post install scripts (disabled by default)
- `activate` — set to `false` to **stage only** and stop before go-live. The build is prepared and verified on every node and the response returns a `deployment_id` in a `staged` state; nothing goes live. Activate it later by calling `deploy_component` again with that `deployment_id` (see below). Useful for pre-staging a release and flipping it live in a separate, fast step.
- `deployment_id` — activate a previously-staged deployment (from an `activate: false` call). No new payload is fetched or installed; the already-staged build is swapped live cluster-wide. `project` is still required.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium: deployment_id activate doesn't persist root config for a package deploy

In the reference implementation (harper#1849, deployComponentActivateExisting in components/operations.js), writeComponentRootConfig only runs if (req.package). The activation example just below (line 714) omits package — consistent with this bullet's own "no new payload is fetched or installed" framing — so a real activate-by-deployment_id call for a package deploy will not update harperdb-config.yaml's stored package: reference for the component. A node that restarts without ever having this version installed, or a new peer joining the cluster, re-installs from that stale root config — silently reverting to the pre-activation package. Worth a caveat here (or requiring package again on the activate call) so this isn't assumed to be as durable as a normal single-shot deploy.

Suggested fix: add a line such as "Note: for a package deploy, also pass package on this call to durably update harperdb-config.yaml — omitting it activates the build cluster-wide but leaves the stored package reference unchanged, so a future restart or new peer may reinstall the older version."


Generated by Barber AI


### `revert_component`

Swaps a component's live version back to its **retained previous version** across the cluster, then restarts. Every `deploy_component` activation retains the version it replaced (one previous version is kept per component), so `revert_component` is a fast rollback that does not re-fetch or re-install. The swap is bidirectional — reverting a revert rolls forward again.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium: revert_component won't reconverge a new peer to the reverted version

revertApplication only swaps directories on disk — writeComponentRootConfig is called from the deploy/activate paths only, never from revertComponent. Boot-time installApplications installs strictly from root config's package: reference, so a node that joins the cluster (or has its components directory rebuilt) after a revert installs the newer, reverted-away version, not the one every existing node just reverted to. That's a gap in the "across the cluster" framing here — revert is a live-instance swap, not a config-level rollback, and a not-yet-provisioned node won't pick it up.

Suggested fix: add a caveat that a node provisioned after a revert (new peer, rebuilt components dir) installs the current root-config package reference, not the reverted-to version — so revert doesn't durably change what a future node will run.


Generated by Barber AI


Deployment statuses fall into two groups:

- **Terminal** — `success`, `failed`, `rolled_back`, and `staged` (an `activate: false` stage-and-stop resting until it is activated or ages out of the staging-retention window).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium: "Terminal" bucket incorrectly includes staged

The implementation's own terminal-status set — TERMINAL_STATUSES in both components/deploymentRecorder.ts and components/deploymentOperations.ts — is {success, failed, rolled_back}; staged is explicitly excluded. That set gates get_deployment_payload ("... is not in a terminal state") and payload-retention pruning eligibility. Listing staged under "Terminal" here contradicts the unchanged get_deployment_payload section a few paragraphs down, which requires success, failed, or rolled_back — not staged.

Suggested fix: give staged its own "resting" bucket (the parenthetical already describes it that way) instead of grouping it with the true terminal statuses.


Generated by Barber AI

| `deployment_id` | Unique identifier (content hash) |
| `project` | Component project name |
| `package_identifier` | Package reference or `payload` for tar uploads |
| `status` | `pending`, `staging`, `staged`, `activating`, `success`, `failed`, or `rolled_back` |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Low: status field list is incomplete

The "Deployment statuses" section just above correctly lists all in-flight statuses (pending, extracting, installing, staging, loading, replicating, activating, reverting, restarting), but this field description only picked up staging/staged/activating and still omits extracting, installing, loading, replicating, reverting, and restarting. Someone building tooling against get_deployment's status field (e.g. during a revert) won't find the value documented here.

Suggested fix:

Suggested change
| `status` | `pending`, `staging`, `staged`, `activating`, `success`, `failed`, or `rolled_back` |
| `status` | `pending`, `extracting`, `installing`, `staging`, `staged`, `loading`, `replicating`, `activating`, `reverting`, `restarting`, `success`, `failed`, or `rolled_back` |


Generated by Barber AI

{
"deployment_id": "a3f8c2d1...",
"message": "Component deployed successfully"
"message": "Successfully deployed: my-app"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Low: example response doesn't match the request's restart: "rolling"

The request right above sets "restart": "rolling", but per deployComponentTwoPhase's rolling-restart branch the response includes a restartJobId and a message ending in , restarting Harper ("Successfully deployed: my-app, restarting Harper"). The plain "Successfully deployed: my-app" shown here is only returned when no restart was requested.

Suggested fix: either drop "restart": "rolling" from the request to match this response, or update the response to include restartJobId and the , restarting Harper suffix.


Generated by Barber AI

**Mint a deploy key for a private repository** (Harper generates the ed25519 keypair server-side and returns only the public half — register it with your git host):

```bash
harper add_ssh_key name=my-key generate=true host=my-key.github.com hostname=github.com

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Low: add_ssh_key generate documents an untracked cross-repo dependency

This example (and the mirrored section in operations.md) documents generate: true, implemented in HarperFast/harper-pro#594 — a separate, still-open draft PR. This PR's own "hold merge until #1849 lands" note only tracks HarperFast/harper#1849; it doesn't mention harper-pro#594. If #1849 merges (and this docs PR follows) before harper-pro#594 ships, these docs advertise an operation that isn't yet available.

Suggested fix: add harper-pro#594 to the merge-gating note in the PR description, or split this section into a follow-up PR tied to that dependency.


Generated by Barber AI

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.

2 participants