Skip to content

docs(deploy): two-phase deploy, revert, by-reference deploys, and OIDC trusted publishing - #599

Draft
dawsontoth wants to merge 9 commits into
claude/cli-token-auth-docsfrom
claude/two-phase-deploy-docs
Draft

docs(deploy): two-phase deploy, revert, by-reference deploys, and OIDC trusted publishing#599
dawsontoth wants to merge 9 commits into
claude/cli-token-auth-docsfrom
claude/two-phase-deploy-docs

Conversation

@dawsontoth

@dawsontoth dawsontoth commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Draft. Documentation companion to the v5.3.0 deploy work. Stacked on #630, which carries the v5.2.0 CLI-token content that used to live here. Everything remaining describes unreleased surface — see the dependency table.

Depends-on: HarperFast/harper#1849, HarperFast/harper#1851, HarperFast/harper#2173
Depends-on: HarperFast/harper-pro#594

What this documents

Six files, not the two the previous description listed. The cluster-wide deploy lifecycle, rollback, deploy-by-reference, sealed deploy credentials, server-side SSH keygen, and OIDC trusted publishing.

Surface Upstream State
Two-phase deploy, revert_component, staging retention harper#1849 open
deploy by_ref=true / ref= / credential= harper#1850 merged, untagged
deploy setup=true harper#1851 open
add_ssh_key generate: true harper-pro#594 open
OIDC trusted publishing harper#2173 open (draft)

Two things changed since the last review pass

This is v5.3.0 surface, not v5.2.0. The placeholder is resolved, and it resolved differently than assumed. harper main is at 5.2.2 (tagged 2026-08-13) and by_ref merged 2026-08-14 — after that tag, and in no release. harper#2173 adds upgrade/directives/5-3-0.ts, confirming which release is next. Every badge here is now v5.3.0.

The one piece that genuinely shipped in v5.2.0 has left. login --for-ci and the token env vars (harper#1876, in v5.2.0 since 2026-07-31) are now #630, against main, mergeable today. That answers @Ethan-Arrowood's first sequencing question — the shipped half no longer waits on four unmerged PRs — and it puts the token rules inside main's canonical numbered Authentication Precedence section rather than in a competing paragraph beside it.

Review feedback

@kriszyp's eight findings (CHANGES_REQUESTED), each re-checked against upstream as it stands now rather than as it stood when filed. Four had been fixed at the source in the meantime.

# Finding Resolution
1 "All-or-nothing at go-live" is wrong Docs fixed. Reframed as an all-nodes staging barrier.
2 Deploy modes presented as independent knobs Fixed upstream, now documented as a matrix.
3 Explicit ref not resolved to a SHA Fixed upstream (5c85714b8, 26cce986d, 21043f994).
4 Rollback scope and restart claims too broad Docs fixed. Scoped to the two-phase path; restart documented as optional.
5 Absolute SSH-key encryption guarantee Docs fixed. Qualified — the plaintext fallback is deliberate upstream.
6 auth_* vs. ordinary username= precedence Fixed upstream; main's canonical list covers it, #630 extends it.
7 Plain "Available since" instead of badges; release notes Docs fixed. Badges + new 5.3.md.
8 Missing badges, summary-table row, release notes Docs fixed. Plus the revert_component row.

Worth expanding on three:

  • Finding 1 was a self-contradiction, not just imprecision: the page claimed all-or-nothing in its opening paragraph and then correctly described a version split twenty lines later. The staging barrier is what the two phases buy — it eliminates the common failure, a node that can't fetch or install — but activation is still per node. The activation-failure discussion is now its own #### Activation failures section rather than sitting mid-parameter-list, and the opening paragraph points at it.
  • Finding 2 became documentable because core added the validation @kriszyp asked for. activate: false and deployment_id are rejected when combined with two_phase: false, replicated: false, or an unreplicated system database, so a request that says stage-only can no longer activate. There is now a valid-combinations table, including that revert_on_failure is refused rather than ignored.
  • Finding 5 stands as a docs problem because core chose to keep the fallback: sealSSHKey still stores and replicates the private key in plaintext with a WARN when no secret custody is registered, deliberately, since SSH keys predate custody. So encryption at rest is a property of the deployment's configuration, not of the operation — stated as a warning, while noting custody is present by default so the risk doesn't read as likely.

@Ethan-Arrowood's structural hold is addressed:

  1. Sequencing — split, as above. The remaining content is uniformly unshipped v5.3.0, and the machine-readable marker at the top of this description arms it for #629's companion check.
  2. The conflict with main — resolved by hand, and it was the hazard he predicted. The ops table needed a three-way merge: main's seven backup rows (create_backup, list_backups, verify_backup, delete_backup, purge_backups, restore_backup, get_backup), this branch's four deploy rows, and this branch's recategorization. Taking either side wholesale would have silently dropped one set. I compared both sides row by row first and confirmed no description text differed, so the width churn is only Prettier re-padding. authentication.md no longer states precedence twice, since docs(cli): token credentials in the canonical auth precedence (v5.2.0) #630 owns that file's content.
  3. Duplicate precedence, stale body, missing config keys, (draft) in the title — the first is gone with the split, this description is rewritten, the title marker is dropped in favour of GitHub's own draft state.
  4. The system-replication precondition (his second question) — now documented. A plain deploy on a cluster with system excluded from replication silently takes the one-shot path, which also means no rollback target; the staged parameters are rejected rather than downgraded.

@cb1kenobi's five findings were fixed in the previous pass and remain so.

Still open

  • deployment_stagingRetention_maxCount and deployment_payloadRetention_* are documented inline, not in reference/configuration/options.md. @Ethan-Arrowood is right that operators look there, and right that the original justification ("matching how payloadRetention_maxSize is surfaced") was false — it isn't surfaced anywhere. Left as-is deliberately: three config keys for an unreleased feature seem better added when the options page can be updated in one pass against the shipping release. Happy to add them here instead.
  • harper-pro#594 is in a private repo, so the companion marker above will need COMPANION_CHECK_TOKEN configured before Add companion-check workflow: docs PRs auto-merge once their companion code PR lands #629's check can resolve it; without the token it fails closed rather than passing.

Verification

npm run build and npm run format:check clean. The build reports two broken anchors; both are pre-existing on main (confirmed by building main with these changes stashed) and neither is in a file this PR touches. Every claim re-verified against the current upstream branches — including three places where harper#2173's own description has drifted from its code: it is now issuer-agnostic with GitHub as a profile, replay keys on a token hash rather than issuer|jti, and the auth-audit-log gap it lists as not-done is implemented.

Description drafted by Claude Code (Opus 5).

…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.

Builds on the two-phase deploy docs (#599) to cover the rest of the
deploy-by-reference workflow.

reference/components/applications.md
- "Deploying by Reference" — `harper deploy by_ref=true`, `ref=`, `credential=`.
  Explains why a reference pins to a resolved SHA rather than the tag or branch
  name typed: peers resolve the package independently, so a tag that moves
  mid-deploy could otherwise leave nodes running different code. Notes that the
  cluster clones the pushed remote, and that by-reference means the cluster
  builds from source — so an app whose build can't run on the node should stay
  on payload deploys.
- "Provisioning a Deploy Credential" — `harper deploy setup=true`, the
  client-side sealing flow, and that reverting to the previous version needs no
  credential at all.

reference/cli/authentication.md
- Documents HARPER_CLI_REFRESH_TOKEN / HARPER_CLI_OPERATION_TOKEN and adds
  "Token credentials for CI/CD", so the CI guidance is no longer "put an admin
  password in your pipeline". Covers precedence, in-memory-only refresh, and
  token lifetimes (1d / 30d defaults).
- Warns that a user holds only ONE valid refresh token at a time: issuing a new
  one invalidates the last, so a routine local `harper login` silently breaks a
  pipeline using the same account. Hence the recommendation to give CI its own
  user. (Verified against security/tokenAuthentication.ts, which stores a single
  hashed refresh_token per user record.)

reference/cli/commands.md
- `harper login --for-ci`, including the stdout/stderr split that makes
  `| gh secret set --env-file -` work without displaying the token.

reference/security/secrets.md
- Points the existing private-source deploy credentials section at the CLI flow
  that automates it.

Documents HarperFast/harper#1850, #1851, and #1876. Verified every anchor link
in the changed files resolves (16 checked).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@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.

Comment thread reference/operations-api/operations.md Outdated
Comment thread reference/operations-api/operations.md Outdated
Comment thread reference/operations-api/operations.md Outdated
Comment thread reference/operations-api/operations.md Outdated
Comment thread reference/operations-api/operations.md Outdated
Comment thread reference/cli/operations-api-commands.md
…vert caveat

Addresses cb1kenobi's review on #599.

- "Terminal" wrongly included `staged`. The implementation's TERMINAL_STATUSES is
  {success, failed, rolled_back} and that set gates get_deployment_payload and
  payload-pruning eligibility, so listing `staged` as terminal contradicted the
  get_deployment_payload section. Split into Terminal / Resting / In flight, and
  noted why a resting payload is deliberately still held.
- get_deployment's `status` row listed 7 of 13 values; now lists all, pointing at
  the grouped explanation.
- The `restart: "rolling"` example's response showed the no-restart message.
  Corrected to the rolling shape (restartJobId + ", restarting Harper") and noted
  what the no-restart response looks like instead.
- revert_component: added a caution that reverting swaps live directories and does
  NOT rewrite the stored `package:` reference, so a node provisioned after a revert
  installs the reverted-away version. Verified in code: revertComponent never calls
  writeComponentRootConfig, and installApplications() installs from root config.
- deployment_id activate: documents that the staged package identifier and
  credential references are recovered and persisted at activation (fixed in
  harper#1849), so `package` need not be repeated on the activate call.
@github-actions
github-actions Bot temporarily deployed to pr-599 July 30, 2026 13:30 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.

@kriszyp kriszyp left a comment

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.

This is looking good, but some comments worth addressing.

🤖 Reviewed with GPT 5.6


Deploys a component. The `package` option accepts any valid NPM reference including GitHub repos (`HarperDB/app#semver:v1.0.0`), tarballs, or NPM packages. The `payload` option accepts a base64-encoded tar string from `package_component`. Supports `"replicated": true` and `"restart": true` or `"restart": "rolling"`.

Across a cluster, `deploy_component` runs in two phases so a deploy is all-or-nothing at go-live:

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.

deploy_component is not actually all-or-nothing at go-live. The stage barrier prevents fetch/install failures from touching live directories, but activation still occurs per node; if one swap fails, other nodes can already be live, and revert_on_failure is off by default. Please describe this as an all-nodes staging barrier (or reduced-risk activation), and explicitly say that an activation failure can split versions unless automatic rollback is enabled.


- `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.

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.

Please define and enforce the deployment modes before presenting these as independent knobs. The companion core validation currently permits deployment_id with activate: false or with a fresh package/payload; dispatch prioritizes deployment_id, so the request activates despite activate: false and ignores fresh build input. Likewise, two_phase: false plus activate: false—or any staged request when system is excluded from replication—takes the legacy one-shot path and goes live. Please reject conflicting/unsupported combinations in core, then document the valid matrix; a request that says stage-only should never activate.

harper deploy ref=9f8c2a1 restart=true replicated=true
```

**A reference is pinned to a SHA, not to the name you typed.** Tags and branches are resolved locally and the full commit SHA is what ships. This matters on a cluster: peers resolve the package independently, so a tag that moves mid-deploy — or a branch that advances — could otherwise leave nodes running different code.

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.

The companion CLI does not currently provide this guarantee for an explicit ref: resolveGitCommittish returns the supplied string unchanged, so ref=v1.2.0 produces a package ending in #v1.2.0 rather than a full SHA. Each peer can therefore resolve a mutable tag or branch independently, recreating the mixed-version risk this paragraph says is eliminated. Please resolve explicit refs locally to a commit (for example, git rev-parse <ref>^{commit}) before building the package, or require a full SHA and qualify the docs accordingly.

Comment thread reference/operations-api/operations.md Outdated

### `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.

This is narrower than documented. The retained .deploy-previous directory is created by two-phase activation; the legacy one-shot path used by two_phase: false (and by the no-system-replication fallback) does not retain it, so a later revert_component fails even after repeated deploys. Restart is also optional in the implementation. Please scope rollback to versions activated through the two-phase path and say it restarts only with restart: true/"rolling", or change core so these guarantees hold on every path.

Adds an SSH key (must be ed25519) for authenticating deployments from private repositories.
Adds an SSH key (must be ed25519) for authenticating deployments from private repositories. Supply the private key with `key`, or omit it and pass `generate: true` to have Harper mint the keypair itself.

The stored private key is encrypted at rest and only ever crosses the cluster as ciphertext; `list_ssh_keys` and the logs never return key material.

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.

This absolute security guarantee does not match the Pro implementation. sealSSHKey deliberately falls back to storing and replicating the private key in plaintext when no secret custody is registered; it logs a warning but does not fail. Please either make add_ssh_key (including generate: true) reject that configuration, or qualify this text to say encryption/ciphertext requires configured custody and explain the fallback, so operators do not assume a guarantee they may not have.

HARPER_CLI_REFRESH_TOKEN: ${{ secrets.HARPER_CLI_REFRESH_TOKEN }}
```

**Precedence**: an explicitly supplied username (arguments or `HARPER_CLI_USERNAME`/`HARPER_CLI_PASSWORD`) wins; otherwise env-var tokens are used; otherwise the token saved by `harper login`. Env-var tokens deliberately outrank the saved credentials file so a runner that has both behaves predictably. A token refreshed from an env var is held in memory for that invocation only — nothing is written to `~/.harperdb/credentials.json`.

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.

Please name the argument form precisely here. In the companion CLI, only auth_username=/auth_password=, target-URL userinfo, or a complete username/password environment pair beat env/saved bearer tokens. Ordinary username=/password= arguments are a legacy fallback after those tokens, so a reader following Method 3 can explicitly name one account while the saved account still executes the operation. Document the dedicated auth_* override and clarify where the ordinary payload fields sit in precedence.


### Deploying by Reference

Available since: v5.2.0

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.

Current reference docs use <VersionBadge version="v5.2.0" /> directly below headings for newly added minor-version surface. Please replace the plain Available since lines under both new sections with badges, and add these user-facing workflows—by-reference deploys, sealed deploy credentials, and CI token authentication/--for-ci—to release-notes/v5-lincoln/5.2.md so users can discover them from the release.

To roll back durably for a `package` deploy, deploy the older version explicitly (`deploy_component` with the previous `package` reference) instead of, or after, reverting. `revert_component` is the fast live-instance swap; an explicit deploy is what changes what a future node will install.
:::

### Deployment Operations

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.

Please finish the v5.2 discoverability/versioning work for this new surface: add a changed <VersionBadge> under deploy_component, added badges under revert_component and the generate subsection, add revert_component to the Components operation summary table, and cover these user-facing features in release-notes/v5-lincoln/5.2.md. The CLI table records v5.2 availability, but the API reference currently reads as though these behaviors exist throughout v5.

@Ethan-Arrowood Ethan-Arrowood left a comment

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.

Holding rather than stacking another CHANGES_REQUESTED on top of @kriszyp's — his eight findings already cover the prose, all are still open, and I reproduced 1, 2, 4 and 5 in local harper/harper-pro checkouts with no disagreement. My additions are structural, and they're the actual reason for the hold.

1. Merging this publishes four unmerged upstream features. There is no "next" tree for reference docs — docusaurus.config.ts sets the reference plugin to lastVersion: 'current', includeCurrentVersion: false, versions: { current: { label: 'v5', path: 'v5' } }. reference/ is the published /reference/v5 site, so merging is publishing. Upstream state as of this pass:

Documented surface Implementation State
two-phase, revert_component, staging retention harper#1849 open
deploy by_ref=true / ref= / credential= harper#1850 open
deploy setup=true harper#1851 open
add_ssh_key generate: true harper-pro#594 open
login --for-ci, HARPER_CLI_REFRESH_TOKEN harper main shipped (5.2.0)

One of five has landed. @cb1kenobi raised harper-pro#594 and the answer was that sequencing is handled outside the PR — that doesn't scale to four dependencies, and the merge gate in the body still names only #1849.

2. The conflict with main can silently drop content. git merge-tree origin/main 94152378 conflicts in reference/cli/authentication.md and reference/cli/operations-api-commands.md. (operations.md and applications.md auto-merge cleanly — I checked the merged blob and main's new host badge survives.) Two hazards:

  • The ops table is rewritten wholesale here (column re-padding plus the Users/Roles and SSH recategorisation). main has since added seven rows this branch has never seen: create_backup, list_backups, verify_backup, restore_backup, delete_backup, purge_backups, get_backup. Resolving by taking "ours" drops all seven — this needs a hand merge and re-pad, not picking a side. (The recategorisation itself is right; I confirmed #users--roles and #components both exist and the old #certificate-management targets for user ops were wrong.)
  • Authentication precedence is about to be stated twice. main landed a canonical numbered "Authentication Precedence" section in authentication.md after this branch forked. This PR adds a second, prose precedence statement in the same file, so post-merge the file gives the order twice, differently — and HARPER_CLI_REFRESH_TOKEN never gets slotted into the canonical list at all. Folding the token rules into the numbered section instead of adding a competing paragraph also resolves @kriszyp's auth_* vs. ordinary username= point in one place. Same file re-adds the (or CLI_TARGET_*) bullet style that main rewrote away.

3. Smaller, all new:

  • The PR body is stale. It describes two files; #616 merged into this branch on 07-29, so the diff is six. Someone reading the description alone won't know they're approving CI-credential and private-source-deploy docs.
  • deployment_stagingRetention_maxCount and deployment_payloadRetention_* are documented only inline in operations.md. grep -rn "payloadRetention\|stagingRetention" reference/ on main returns nothing, so the body's "matching how deployment_payloadRetention_maxSize is currently surfaced" doesn't hold — it isn't surfaced anywhere. Three operator-facing config keys with no entry in reference/configuration/options.md, which is where operators look.
  • Title still says "(draft)" but isDraft: false. Same on #616. If the marker is load-bearing use GitHub's draft state; otherwise drop it.

Two questions before I'd move off the hold:

  1. Sequencing. Merge only once all four upstream PRs ship in the same release, or split so the --for-ci/token half (already on harper main at 5.2.0) can land now?
  2. The system-replication precondition. Independent of whether core tightens the flag matrix per @kriszyp, does the prose get this caveat now? if (req.two_phase === false || isReplicatedExecution || !isSystemDatabaseReplicated()) takes the one-shot path, so a cluster with system excluded from replication silently gets one-shot deploys and no revert target while reading docs that promise both as unconditional cluster behavior.

Verified correct and not worth re-litigating: the status buckets against TERMINAL_STATUSES, deployment_timeout default 120000 vs. DEFAULT_AWAIT_ROW_TIMEOUT_MS, retention defaults (5 / 10 MiB / 1), the rolling-restart response carrying restartJobId and the , restarting Harper suffix, and every new internal anchor. @cb1kenobi's five findings are genuinely fixed — two at the source rather than papered over with a caveat, which was the right call.

sent with Claude Opus 5

…host

harper-pro#594 moved generation in-process (node:crypto), so the PATH
requirement and its error path no longer exist. The response shape and the
harper:<name> comment convention documented above are unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions
github-actions Bot temporarily deployed to pr-599 August 12, 2026 15:45 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 draft August 12, 2026 16:29
…evel

Brings the revert documentation in line with HarperFast/harper#1849 after review.
The behavior changed in three ways that each invalidated something documented here.

- `revert_on_failure` is gone — it is now rejected outright, so the bullet is
  removed. Replaced with what actually happens on a partial activation (the
  deployment stays `activating`; recover by rolling forward or by an explicit
  revert) and why there is no automatic rollback: past the activation barrier, a
  peer reporting failure does not prove it did not activate, so auto-reverting the
  failed nodes can split the cluster three ways instead of converging it.

- `revert_component` now takes a **required** `to_deployment_id` and is idempotent
  rather than a bidirectional toggle. Documented as such, with the reason the
  target is mandatory (a retry after a lost response must not flip the rejected
  release back in), a parameter table, the response fields including
  `from_deployment_id`/`rollback_of`, and the one-activation reach of retention.

- The `:::caution` saying a revert is not a config-level rollback is **no longer
  true** and is replaced by the opposite: the revert rewrites the stored `package:`
  reference and the boot-time application lock as part of the same operation, so a
  newly joined peer or a rebuilt components directory installs the version the
  cluster is actually running. Reverting away from a `package` deploy to a
  payload-deployed version removes the reference entirely.

CLI: `harper revert` now requires `to_deployment_id`, and the example and command
table say so. The wider CLI table diff is Prettier realigning column widths after
the description text changed.

Version badges still carry the placeholder release, per this PR's existing note.
@dawsontoth

Copy link
Copy Markdown
Contributor Author

Updated in d000da2 to match the current shape of HarperFast/harper#1849 after review. Three things documented here had become wrong:

  • revert_on_failure is removed — it is rejected outright now, so the bullet is gone. Replaced with what actually happens on a partial activation (the deployment stays activating; recover by rolling forward or with an explicit revert) and the reason there is no automatic rollback: past the activation barrier, a peer reporting failure does not prove it did not activate, so auto-reverting the failed nodes can split the cluster three ways rather than converging it.
  • revert_component takes a required to_deployment_id and is idempotent instead of a bidirectional toggle — a retry after a lost response now changes nothing rather than flipping the rejected release back in. Documented with a parameter table, the response fields (reverted, from_deployment_id, and rollback_of on the audit row), and the fact that retention reaches back exactly one activation.
  • The :::caution about revert not being a config-level rollback is no longer true, and is replaced by the opposite. The revert now rewrites the stored package: reference and the boot-time application lock in the same operation, so a newly joined peer or a rebuilt components directory installs the version the cluster is actually running. That was the durability gap @kriszyp flagged on the implementation PR.

harper revert requires the target too, so the CLI example and command table say so. The larger CLI table diff is Prettier realigning column widths after the description text changed.

Still holding merge until harper#1849 lands, and version badges still carry the placeholder release.

@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 changed the base branch from main to claude/cli-token-auth-docs August 17, 2026 20:16
@dawsontoth dawsontoth changed the title docs(deploy): two-phase deploy_component, revert_component, stage/activate CLI (draft) docs(deploy): two-phase deploy, revert, by-reference deploys, and OIDC trusted publishing Aug 17, 2026
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.

4 participants