From 1a4d408e566b93b0a2343c2d14e2a387a7a1a253 Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah <22363102+codeforester@users.noreply.github.com> Date: Wed, 21 Oct 2026 23:24:11 +0530 Subject: [PATCH 1/2] docs: publish the installation-route upgrade contract (#2597) --- .ai-context/COMMANDS.md | 5 + CHANGELOG.md | 4 + FAQ.md | 14 +++ README.md | 2 + docs/README.md | 3 + docs/bootstrap.md | 31 ++--- docs/command-reference.md | 2 +- docs/homebrew-upgrade-rehearsal.md | 5 + docs/shell-startup.md | 37 ++---- docs/upgrading.md | 178 +++++++++++++++++++++++++++++ skills.md | 6 +- 11 files changed, 234 insertions(+), 53 deletions(-) create mode 100644 docs/upgrading.md diff --git a/.ai-context/COMMANDS.md b/.ai-context/COMMANDS.md index 5dec535d..39ee0a81 100644 --- a/.ai-context/COMMANDS.md +++ b/.ai-context/COMMANDS.md @@ -32,6 +32,11 @@ the v1.x compatibility window; new automation should use `--debug-wrapper`. environment and optional project artifacts. Project `--dry-run` previews run through Base's interpreter and work before the project virtualenv exists, without creating or recreating that environment. +- `basectl update [project]` - update Base by default, or the named consumer + project. Current Homebrew updates always reconcile setup; ordinary Git + updates do so only when the revision changes. Stable Base source checkouts + can use `--release `. Consult `docs/upgrading.md` for version availability, + older-version fallback, explicit setup, trust, and recovery. - `basectl check [project]` - check Base readiness only by default; pass a project name or `--manifest` to also check manifest-declared project requirements. It does not install or repair prerequisites, modify project diff --git a/CHANGELOG.md b/CHANGELOG.md index ebeb31f9..b93e9494 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,9 +18,13 @@ numeric next development line is tracked in `DEVELOPMENT_VERSION`. - Stability compatibility: publish workspace-test JSON schema version 2 so automation can distinguish trust-blocked and not-run projects from tests that actually executed. +- Reconcile pinned Base runtime requirements after Homebrew upgrades even when + the formula version is unchanged, using the newly linked executable. ### Added +- Upgrade clean, detached Base source checkouts to a reviewed later stable tag + with `basectl update --release `, including a preview and setup recovery. - Stability compatibility: enroll the new `basectl gh review fetch` and `basectl gh review prune` command contracts, including the migration path from ordinary local `pr-*` branches to namespaced detached review refs. diff --git a/FAQ.md b/FAQ.md index 2f6f23e4..d511e7ad 100644 --- a/FAQ.md +++ b/FAQ.md @@ -259,6 +259,20 @@ route. ## Setup, Profile, And Diagnostics +### How Do I Upgrade An Existing Base Installation? + +Use the [Upgrade Contract](docs/upgrading.md). Homebrew and mutable default-branch +source installs use `basectl update`. A stable detached source checkout uses +`basectl update --release ` when that option is available; older versions +use the documented pinned-checkout procedure. Confirm the active executable +with `command -v basectl` and `type -a basectl` before choosing a route. + +Omitting the project updates Base itself. `basectl update example` updates the +consumer project instead. Direct Homebrew or Git operations need an explicit +setup step. `update-profile` refreshes shell integration and does not upgrade +Base. The upgrade guide distinguishes current-main features from v1.10.5 and +explains runtime verification and trust re-review. + ### What is the difference between basectl setup and basectl update-profile? `basectl setup` prepares Base and project prerequisites: Homebrew artifacts, diff --git a/README.md b/README.md index 412a6501..be06c24c 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,8 @@ inventory -> prepare -> verify -> trust -> onboard -> hand off For the canonical source-checkout install commands, see the [source checkout install recipe](docs/bootstrap.md#source-checkout-install-recipe). +For an existing installation, use the [Upgrade Contract](docs/upgrading.md) +to select the Homebrew, mutable-source, or stable-tag procedure. For the complete install-to-verified-project-PR journey, see the [adopter golden path](docs/adopter-golden-path.md). Then run the trust-conscious project proof: diff --git a/docs/README.md b/docs/README.md index 8368a894..6f8c5a52 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,6 +8,9 @@ the documentation map. For contribution workflow, branch naming, tests, and PR expectations, see [CONTRIBUTING.md](../CONTRIBUTING.md). +For an existing installation, see [Upgrading Base](upgrading.md), including +Homebrew, mutable source, stable tags, and recovery after setup failures. + For the public support front door, discussion categories, response target, and discussion-to-issue workflow, see [Community Support](community-support.md). diff --git a/docs/bootstrap.md b/docs/bootstrap.md index 058bcb8b..e6354c35 100644 --- a/docs/bootstrap.md +++ b/docs/bootstrap.md @@ -285,29 +285,10 @@ basectl update-profile exec "$SHELL" -l ``` -For upgrades, prefer `basectl update`, which runs the Homebrew upgrade and then -reconciles the managed Base environment. If Homebrew is run directly, follow -it with setup through the newly linked executable; `brew upgrade` alone does -not reconcile an existing managed environment: - -```bash -brew upgrade basefoundry/base/base -env \ - -u BASE_HOME -u BASE_BIN_DIR -u BASE_CLI_DIR -u BASE_BASH_DIR \ - -u BASE_BASH_COMMANDS_DIR -u BASE_LIB_DIR -u BASE_BASH_LIB_DIR \ - -u BASE_SHELL_DIR -u BASE_OS -u BASE_HOST -u BASE_SHELL \ - -u BASE_PLATFORM_TOOLS_HOME -u BASE_PLATFORM_TOOLS_BIN_DIR \ - -u BASE_PROJECT -u BASE_PROJECT_ROOT -u BASE_PROJECT_MANIFEST \ - -u BASE_PROJECT_VENV_DIR \ - "$(brew --prefix base)/libexec/bin/basectl" setup -``` - -Verify the result before running project tests: - -```bash -basectl check base --verify-project-runtime -basectl test base -``` +For existing installations, use the [Upgrade Contract](upgrading.md#homebrew). +It covers `basectl update`, direct Homebrew upgrade plus explicit setup, +version availability, trust review, and readiness verification. A package +upgrade alone does not reconcile an existing managed Base environment. ### Stable Source Install Recipe @@ -322,7 +303,9 @@ exec "$SHELL" -l ``` The stable checkout reports `basectl 1.10.5`. For future releases, replace the -release version and tag with the intended published release. +release version and tag with the intended published release. To upgrade an +existing stable checkout, follow [Stable Tagged Source Checkouts](upgrading.md#stable-tagged-source-checkouts), +including the fallback for versions without `update --release`. ### Source Checkout Install Recipe diff --git a/docs/command-reference.md b/docs/command-reference.md index e10b9729..438c2935 100644 --- a/docs/command-reference.md +++ b/docs/command-reference.md @@ -57,7 +57,7 @@ full compatibility contract. |---|---|---| | `basectl setup [project]` | Install or reconcile Base and optional project artifacts. Project-originated IDE app, extension, and user-setting mutations require separate approval. | `--project `, `--ci`, `--format `, `--profile `, `--dry-run`, `--manifest `, `--yes`, `--allow-project-ide-mutations`, `--recreate-venv`, `--upgrade-pip`, `--notify`, `--no-notify` | | `basectl update-profile` | Create, refresh, or remove Base-managed Bash and Zsh startup snippets, backing up existing dotfiles before changes. | `--defaults`, `--no-defaults`, `--remove`, `--dry-run` | -| `basectl update [project]` | Update a Base-managed project checkout through Git, or update Base through Homebrew when Base is Homebrew-managed, then run setup for the selected project. | `--project `, `--release `, `--dry-run` | +| `basectl update [project]` | Update Base or a selected project through its installation route. Ordinary Git updates run setup only when the revision changes; current Homebrew updates always reconcile setup. Stable Base source tags use `--release`. See [Upgrading Base](upgrading.md) for version availability and recovery. | `--project `, `--release `, `--dry-run` | | `basectl onboard [project]` | Guide first-run setup through check, setup, shell profile, doctor, project discovery, and read-only manifest trust status. Defaults to `base`. | `--project `, `--profile `, `--dry-run`, `--yes`, `--allow-project-ide-mutations`, `--no-profile` | | `basectl version` | Show the installed Base version. | `--all`, `--json` | diff --git a/docs/homebrew-upgrade-rehearsal.md b/docs/homebrew-upgrade-rehearsal.md index 3bb11590..5c735a53 100644 --- a/docs/homebrew-upgrade-rehearsal.md +++ b/docs/homebrew-upgrade-rehearsal.md @@ -8,6 +8,11 @@ separate from the tap update checklist: the tap checklist proves the formula can be published, while this rehearsal proves an existing user can upgrade without losing local Base state. +Use [Upgrading Base](upgrading.md) for the consumer command matrix, runtime +reconciliation, version availability, and recovery. This rehearsal exercises +the direct Homebrew route plus explicit setup; it does not replace the +`basectl update` route described there. + ## Preconditions - Run on a macOS machine or test account that can install Homebrew packages. diff --git a/docs/shell-startup.md b/docs/shell-startup.md index d6a26194..ec9cd86a 100644 --- a/docs/shell-startup.md +++ b/docs/shell-startup.md @@ -45,32 +45,17 @@ run `basectl update-profile --no-defaults` to disable them again. Plain `BASE_PROFILE_VERSION` records the schema version of this Base-managed file. It is reserved for future migrations and is not intended to be edited by users. -Update Base or a Base-managed project checkout with: - -```bash -basectl update -basectl update bankbuddy -``` - -Omitting the project is equivalent to `basectl update base`. This command is -intentionally conservative. In a source checkout, it only runs from the selected -project repository's default branch, requires tracked project files to be clean, -pulls the latest changes through Git, and runs `basectl setup ` only -when the pull changes the checked-out revision. Untracked files do not block the -update; Git still stops the pull if an incoming tracked file would overwrite -them. - -In a Homebrew-managed install, the Base update path remains Base-only: -`basectl update` runs the Base package upgrade, -`brew upgrade basefoundry/base/base`, and runs `basectl setup base` with -inherited Base environment variables cleared only when the installed Base version -changes. `basectl update --dry-run` prints the Git or Homebrew handoff it would -perform without changing files or packages. -For manual Homebrew upgrades outside `basectl update`, prefer -`brew upgrade --no-ask basefoundry/base/base` so Homebrew skips the preview -prompt path on already-current installs. If Homebrew refuses to load -`basefoundry/base/base-bash-libs` from an untrusted tap, run -`brew trust basefoundry/base` once and retry the upgrade. +For Base and consumer-project upgrades, follow the [Upgrade Contract](upgrading.md). +It distinguishes Homebrew, mutable default-branch source checkouts, and stable +source tags. Current Homebrew updates reconcile setup even when the formula +version is unchanged; ordinary Git updates run setup only when the revision +changes. Stable Base source upgrades use `update --release` when supported by +the installed version. + +`basectl update-profile` only refreshes managed shell integration. Run it when +the selected installation path or shell configuration changes, then open a +fresh shell and confirm the active `basectl`. It does not replace upgrading +Base or reconciling its runtime with setup. Base also reads `~/.baserc` when it exists. Unlike `profile.conf`, `~/.baserc` is user-managed and may be hand-edited. It is intended for simple, diff --git a/docs/upgrading.md b/docs/upgrading.md new file mode 100644 index 00000000..93dbdb2f --- /dev/null +++ b/docs/upgrading.md @@ -0,0 +1,178 @@ +# Upgrading Base + +This is the upgrade contract for Homebrew, mutable source checkouts, and stable +tagged source checkouts. It describes current main. The `update --release` +option and Homebrew reconciliation when the formula version is unchanged were +added after v1.10.5; they must not be assumed available in that release. Check +`basectl update --help` on the executable you are actually running. Older +versions can use the explicit setup and pinned-checkout paths below. + +## Choose The Installation You Intend To Upgrade + +```bash +command -v basectl +type -a basectl +basectl version +``` + +Homebrew and source copies can coexist. `basectl update` targets the Base +installation containing that executable, not every Base copy on the machine. +Use an explicit executable path when the shell selects the wrong installation. +Homebrew usually exposes `/opt/homebrew/bin/basectl` on Apple Silicon or +`/usr/local/bin/basectl` on Intel macOS; a source checkout exposes its own +`bin/basectl`. See [Homebrew and source coexistence](../FAQ.md#homebrew-and-source-coexistence). + +## Upgrade Matrix + +| Installation / operation | Command | Setup behavior | Verification | +| --- | --- | --- | --- | +| Homebrew-managed Base | `basectl update` | Runs `brew upgrade basefoundry/base/base`, then setup through the newly linked executable with inherited Base/project variables cleared. Current main reconciles even when the formula version is unchanged. | Confirm active executable and version, then `basectl check base --verify-project-runtime`. | +| Mutable Base source checkout on its default branch | `basectl update` | Updates the checkout through Git and runs `basectl setup base` only when the revision changes. | Version and explicit runtime check; source contributors also run the Base test contract after trust review. | +| Stable detached Base source checkout, with `--release` support | `basectl update --release ` | Moves to a later stable tag verified against `origin`, stays detached, then runs setup. Repeating the current tag reconciles setup without moving the checkout. | Confirm exact tag/commit and version, explicit runtime check, then appropriate tests after trust review. | +| Direct Homebrew operation | `brew upgrade basefoundry/base/base` followed by explicit setup | Package-manager upgrade alone does not reconcile the persistent Base environment. Use the sequence below. | Verify using the newly linked Homebrew executable. | +| Direct Git operation | Reviewed Git update followed by `basectl setup base` from that checkout | Git does not reconcile the environment. Run setup even if a subsequent `basectl update` says the revision is already current. | Confirm ref/version, runtime readiness, and applicable tests. | + +`basectl update` without a project means `basectl update base`, including when +you are inside a consumer repository. `basectl update example` updates that +consumer project's default-branch checkout and runs its setup only if the +revision changes. It does not upgrade the Base installation. `--release` is +only for the Base source checkout, not Homebrew or consumer projects. + +`basectl setup [project]` reconciles requirements at the already selected +revision; it does not select a newer release. `basectl update-profile` refreshes +shell integration; it is not an upgrade operation. Refresh the profile when +the installation path or managed shell configuration changes, then start a +fresh shell. An ordinary same-path upgrade does not require a profile rewrite. + +## Homebrew + +Preview, then apply through the Homebrew-managed executable: + +```bash +basectl update --dry-run +basectl update +``` + +The preview does not run the package upgrade or setup. Apply performs both, so +an unchanged formula version can still repair missing or stale pinned runtime +requirements. If Homebrew reports a tap-trust requirement, review and run +`brew trust basefoundry/base`, then retry. + +For a direct `brew upgrade`, or recovery after an older updater skipped setup, +use the newly linked executable rather than an old Cellar path: + +```bash +brew upgrade basefoundry/base/base +env \ + -u BASE_HOME -u BASE_BIN_DIR -u BASE_CLI_DIR -u BASE_BASH_DIR \ + -u BASE_BASH_COMMANDS_DIR -u BASE_LIB_DIR -u BASE_BASH_LIB_DIR \ + -u BASE_SHELL_DIR -u BASE_OS -u BASE_HOST -u BASE_SHELL \ + -u BASE_PLATFORM_TOOLS_HOME -u BASE_PLATFORM_TOOLS_BIN_DIR \ + -u BASE_PROJECT -u BASE_PROJECT_ROOT -u BASE_PROJECT_MANIFEST \ + -u BASE_PROJECT_VENV_DIR \ + "$(brew --prefix base)/libexec/bin/basectl" setup +``` + +Stop if the upgrade fails and resolve Homebrew's reported problem before +continuing. See the [Homebrew Upgrade Rehearsal](homebrew-upgrade-rehearsal.md) +for release-validation evidence and preserved-state checks. + +## Mutable Source Checkouts + +Ordinary `basectl update` requires the selected repository's default branch +and clean tracked files. It leaves unrelated untracked files to Git's normal +overwrite protection. It does not switch away from a feature branch or +resolve local changes on your behalf. + +```bash +~/work/base/bin/basectl update --dry-run +~/work/base/bin/basectl update +``` + +If Git changes the checkout but setup fails, the checkout remains updated. +Resolve the setup failure and rerun `basectl setup base`; another ordinary +update can skip setup because the revision is already current. Local +development validation uses [Contributor Setup](../CONTRIBUTING.md#contributor-setup) +and [Testing](testing.md), including the configured provider checkouts. + +## Stable Tagged Source Checkouts + +Use an explicitly reviewed published `vMAJOR.MINOR.PATCH` release tag in place +of ``: + +```bash +~/work/base/bin/basectl update --release --dry-run +~/work/base/bin/basectl update --release +``` + +This path requires a clean tracked checkout detached at an exact stable tag. +A different target must be a later stable version; it does not follow `main`, +accept prerelease tags, or provide an automatic downgrade. Apply verifies the +target tag's commit against `origin`, refuses a conflicting local tag, fetches +the target when necessary, and refuses untracked or ignored paths overlapping +files changed by the target release. Unrelated local files are preserved. + +The dry run queries the remote tag without fetching, changing refs, or running +setup. The real upgrade performs the additional local-path collision check. +A remote-tag match establishes the checkout target; it is not a replacement +for reviewing the published release and its immutable BOM evidence. + +After a ref change, setup failure leaves the checkout at the target release. +Correct the error and run `basectl setup base`, or repeat the same-tag command +to reconcile the current environment. The updater does not roll back the ref +or erase persistent user configuration and trust state. Changed manifest or +test-requirement digests can invalidate approval, so review trust again. + +### Older Versions Without `--release` + +An older stable install must not be moved to `main` merely to obtain the new +upgrade option. Use the [Stable Source Install Recipe](bootstrap.md#stable-source-install-recipe) +with the desired published release ref. A separate pinned checkout is also a +way to preserve the original checkout while selecting the new release: + +```bash +# Replace vX.Y.Z with the reviewed published target release. +TARGET_RELEASE=vX.Y.Z +git clone --branch "$TARGET_RELEASE" --single-branch \ + https://github.com/basefoundry/base.git "$HOME/work/base-$TARGET_RELEASE" +``` + +After cloning succeeds, confirm the tag and version in the new checkout, run +its `bin/basectl setup`, and verify readiness. Run that checkout's +`bin/basectl update-profile` only when choosing it as the shell's active Base, +then open a fresh shell and confirm `command -v basectl` again. The checkouts +share the user's managed Base environment; keeping an older checkout does not +create an isolated runtime or an automatic rollback guarantee. + +## Readiness, Trust, And Recovery + +After selecting the intended executable and reviewing its runtime inputs: + +```bash +basectl version +basectl check base --verify-project-runtime +basectl trust status base +``` + +Default `check` performs static inspection; package readiness can remain +unverified. `--verify-project-runtime` explicitly permits executing runtime and +tool probes. It does not repair state or grant manifest-command approval. +If trust status reports changed manifest or declared test requirements, review +the new content and use the exact digest-bearing approval command it prints +before running tests. See [Manifest Command Trust](manifest-command-trust.md). + +For source contributor validation, run `basectl test base` with the documented +developer prerequisites/provider checkouts. For consumer readiness, check the +consumer project and run its declared test contract after approving its own +manifest. Successful Base upgrade does not prove every consumer project is +ready, and upgrading Base does not implicitly update all consumer repositories. + +| Failure | Recovery | +| --- | --- | +| Dirty tracked checkout | Save or commit the work deliberately, then retry. Do not discard it to satisfy the updater. | +| Mutable checkout on a non-default branch | Finish the branch's workflow and select the intended default-branch checkout. | +| Detached checkout without a stable exact tag | Identify its provenance; use a reviewed stable checkout or an intentional mutable default-branch checkout. | +| Target tag missing, conflicting, or remote unavailable | Check the intended remote/release and resolve the discrepancy; do not force-replace a tag. | +| Stable-upgrade local-path collision | Preserve and move the conflicting untracked/ignored content, then retry. | +| Setup failed after Git/Homebrew changed the installation | Keep the reported revision, fix the underlying dependency/configuration problem, and rerun setup through the selected executable. | +| Mixed Homebrew/source shell state | Use an explicit executable, refresh the intended profile when necessary, and verify in a fresh shell. | diff --git a/skills.md b/skills.md index 90fb1f15..392349af 100644 --- a/skills.md +++ b/skills.md @@ -191,8 +191,10 @@ behavior. - User-facing install test coverage: `tests/install.bats` - Homebrew tap repository: `https://github.com/basefoundry/homebrew-base` - User-facing Homebrew install command: `brew install basefoundry/base/base` -- Keep Homebrew users on `brew upgrade basefoundry/base/base` rather than - `basectl update`. +- Follow the [Upgrade Contract](docs/upgrading.md) for Homebrew, mutable source, + and stable tagged source installations. Prefer `basectl update` for Homebrew; + a direct `brew upgrade` needs setup through the newly linked executable. + Check version availability before recommending `update --release`. - Validate with: ```bash From e1b226e6e9ead5b261cbdca4b8c22c7dc5cf241f Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah <22363102+codeforester@users.noreply.github.com> Date: Wed, 21 Oct 2026 23:30:37 +0530 Subject: [PATCH 2/2] docs: connect upgrade guidance to contract evidence --- docs/contracts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contracts.md b/docs/contracts.md index 9e321e68..1c0c92a0 100644 --- a/docs/contracts.md +++ b/docs/contracts.md @@ -29,7 +29,7 @@ before treating the fix as complete. | Read-only inspection JSON | [Inspection JSON](inspection-json.md), [Command Quick Reference](command-reference.md) | `cli/bash/commands/basectl/tests/inspection-json.bats`, `cli/python/base_release/tests/test_engine.py`, [`base-cli/tests/test_inspection.py`](https://github.com/basefoundry/base-cli/blob/main/tests/test_inspection.py), `tests/test_stability_tiers_docs.py` | A scoped command emits prose or invalid JSON, changes the v1 envelope, loses finding/error semantics, or diverges from text-mode exit policy | CLI | | Project metadata defaults | `.github/base-project.yml`, [GitHub Workflow](github-workflow.md), [Repository Baseline](repo-baseline.md) | `cli/python/base_github_projects/tests/`, `cli/bash/commands/basectl/tests/gh.bats`, `cli/bash/commands/basectl/tests/repo.bats` | Issue defaults, Project field options, or repo-visible Project configuration drift from the Base Project schema | Product | | Canonical positioning documentation | [Product Requirements](product-requirements.md), [Product Assessment](product-assessment.md), [Why Base](why-base.md), and the canonical introduction surfaces | `tests/test_contract_hardening.py` | A canonical newcomer, contributor, or agent surface reintroduces retired product positioning or drops the accepted local-operating-contract thesis and outcome loop | Product | -| Adopter golden path | [Base Adopter Golden Path](adopter-golden-path.md), [First-Mile Bootstrap](bootstrap.md), [Manifest Command Trust](manifest-command-trust.md), and [GitHub Workflow](github-workflow.md) | `tests/test_adopter_golden_path_docs.py` | The install-to-first-verified-project-PR journey becomes ambiguous, hides trust or platform boundaries, or loses actionable recovery guidance | Adoption | +| Adopter golden path | [Base Adopter Golden Path](adopter-golden-path.md), [First-Mile Bootstrap](bootstrap.md), [Upgrading Base](upgrading.md), [Manifest Command Trust](manifest-command-trust.md), and [GitHub Workflow](github-workflow.md) | `tests/test_adopter_golden_path_docs.py`, `cli/bash/commands/basectl/tests/update.bats` (upgrade behavior; prose completeness still needs review) | Installation, upgrade, or the first verified project PR becomes ambiguous, hides trust or platform boundaries, or loses actionable recovery guidance | Adoption | | Native Windows support boundary | [Native Windows Support Contract](windows-support.md), `README.md`, canonical product/context docs, and `.github/workflows/windows-contract.yml` | `tests/test_windows_support_docs.py` | A public surface or release note claims native Windows support before the launcher, command subset, and clean-install gates exist | Platform | ## Contract Check Runner