From 03b872f36496e618a9efbf618ed353d222f6997f Mon Sep 17 00:00:00 2001 From: Kit <344842+roodboi@users.noreply.github.com> Date: Fri, 13 Nov 2026 10:57:34 +0000 Subject: [PATCH 1/3] docs: draft next.17 upgrade actions pending env merge --- docs/env.md | 13 ++++- docs/guides/upgrade-to-v5.md | 45 ++++++++++++----- docs/guides/v5-release-notes.md | 59 ++++++++++++++++++++-- docs/versions/v5/guides/upgrade-from-v4.md | 39 +++++++++++--- 4 files changed, 131 insertions(+), 25 deletions(-) diff --git a/docs/env.md b/docs/env.md index 9d1cd209a..7dd03a11f 100644 --- a/docs/env.md +++ b/docs/env.md @@ -1155,7 +1155,18 @@ Older repos may still have: - `.hack/.env.` - configured secret backends via `hack env backend` -Hack still detects and reads that legacy format, but the preferred migration path is: +**Before migration, preserve a private readable copy of the original project +key and env files outside the working tree.** On next.16 or an earlier +prerelease, do not run `doctor --migrate-env-config` without a copy of +`.hack.secret.key`: explicit cleanup can remove it when a legacy store's +`keyPath` names the same file (HACK-2172). The merged live-input protection fix, +intended for next.17, refuses cleanup of current project/shared keys, config and +YAML inputs. It does not recover keys already removed. Keep the old encrypted +files until their original key is recovered; creating a replacement key is not +recovery. + +Hack still detects and reads that legacy format. After those backup checks, +the explicit migration path is: ```bash hack doctor --migrate-env-config diff --git a/docs/guides/upgrade-to-v5.md b/docs/guides/upgrade-to-v5.md index 39ee1930b..0e4168952 100644 --- a/docs/guides/upgrade-to-v5.md +++ b/docs/guides/upgrade-to-v5.md @@ -66,29 +66,50 @@ executable to v5. Review env migration before the Compose trial. ## Secrets after upgrading -This section will link the Doctor env hygiene check (HACK-2165) and the -protect-in-place command (HACK-2166) after their implementations merge. They are -pending at this audit; no command form is promised here. - -Until then, check by hand: +The next.17 env changes hide all values in ordinary `env list` output and add +`env protect` to encrypt selected plaintext YAML entries in place. Check that +the installed release contains those changes before using the new command. +For scripts, use `env list --json` and `has_value` for metadata, or an explicit +`env get KEY` with the same scope/overlay when a value is needed. `env get` +prints plaintext; keep it out of logs and reports. `--show-values` (also spelled +`--show-secrets`) requires terminal stdin/stdout and interaction enabled, so it +is not a bulk script interface. + +Run `hack env protect` for a names-only inventory, then select the keys to +protect. This preserves their values, scopes and layers; it does not remove +legacy compatibility copies. Keep `--secret --value-stdin` on later secret +updates. See [the env command guidance](../env.md#common-commands). + +Keep these manual checks too: - Check ownership and permissions of `.hack/hack.env.local.yaml` and `.hack/hack.env..local.yaml`. New local layers are created mode 0600, but existing layers keep their modes. Keep local layers owner-only and do not assume an upgrade tightened old files. - Check Git's tracked-file list for `.hack/.env.` and - `hack.env*.local.yaml`. The managed ignore block does not cover legacy - overlay dotenv names, and ignoring an already tracked file does not untrack - it. Review and remove any tracked sensitive files from the index without + `hack.env*.local.yaml`. next.16's managed ignore block omitted legacy overlay + dotenv names; newer ignore rules still cannot untrack an existing file. + Review and remove any tracked sensitive files from the index without deleting the local copy; treat earlier commits as a possible disclosure. -- Values migrated from v4 plaintext dotenv files remain plain until re-added - with `--secret`. `hack env list` can print those values. Inspect names and - provenance instead; re-add a sensitive value through a hidden prompt or - `--value-stdin`, never as a command argument. +- Values migrated from v4 plaintext dotenv files remain plain until explicitly + protected or re-added with `--secret`. next.16's `env list`, including JSON, + prints plain values; hiding them in a newer listing is not encryption. - Keep the project key and all backup copies private. Review logs, MCP results, multiplexer temporary files and retained background output as possible plaintext sinks; encryption at rest does not protect those outputs. +**On next.16 or an earlier prerelease, keep a private readable copy of +`.hack.secret.key` before `doctor --migrate-env-config`.** HACK-2172 lets +explicit cleanup delete that key when a legacy store's `keyPath` names it. +The live-input protection fix is merged for next.17: current project/shared +keys, config and YAML inputs are not cleanup targets, and cleanup refuses a +request that names one. It cannot recover a key already removed by an older +build. Back up original keys and env state before migration on any version. + +The broader Doctor secrets-hygiene report and repairs (HACK-2165, #764) are a +separate change; check the chosen release's availability. next.16 already +reports `env-key-weak-permissions` and suggests `chmod 600` for an old loose key. + See [Env and secrets](../env.md#legacy-repos-and-migration) and the [threat model](../security/env-secrets-threat-model.md). These are manual checks, not evidence that the real-machine upgrade or rollback has passed. diff --git a/docs/guides/v5-release-notes.md b/docs/guides/v5-release-notes.md index 52f4d0556..5843e4eb0 100644 --- a/docs/guides/v5-release-notes.md +++ b/docs/guides/v5-release-notes.md @@ -13,10 +13,53 @@ beta. `hack dev`, added in 4.3.0, is part of the core. This page is the readable summary. The generated [CHANGELOG](../../CHANGELOG.md) lists every change by commit. +## next.17: what changed and what to do + +These are source changes intended for `5.0.0-next.17`, not a claim that the +release is published. Check the installed candidate's version and release notes +before using a new flag or changing a script. An installed next.16 bundle keeps +its original behavior. + +| Change | What to do | +| --- | --- | +| **Native plain `logs SERVICE --follow` output changes.** It now prints application-text lines, matching a finite snapshot, instead of adding a `SERVICE \| ` prefix. Both service streams go to stdout; Hack notices go to stderr. | Stop parsing the old plain prefix. Use `--json` and the log event's `entry.service`, `entry.stream` and `entry.message` when a script needs those fields. Use `--timestamps` to request Engine timestamps. | +| **Env listings hide values by default, including migrated plaintext.** Ordinary `env` / `env list` text and JSON output are metadata. JSON omits `value` and reports `has_value`. | Use `has_value` for availability checks. For a value a script actually needs, call `hack env get KEY` with the same `--env` and `--service`; that command prints plaintext. Bulk `--show-values` requires interactive stdin and stdout; `--show-secrets` remains an alias. | +| **Migration cleanup preserves live keys (HACK-2172).** A legacy store's `keyPath` can no longer make the current project/shared key a cleanup target. Current config and YAML inputs are protected too. | Keep key and env backups before migration. On next.16 or an earlier prerelease, do not run `doctor --migrate-env-config` without a private readable copy of `.hack.secret.key`. The fix does not recover a key already removed. | + +### Env scripts and migrated plaintext + +Replace noninteractive bulk reveal with explicit single-key reads; do not log or +paste their output. `--json` is a format choice, not permission to reveal values. +The terminal reveal gate reduces accidental transcript exposure; it is not +access control against a local process with the same file and key access. + +Use `hack env protect` for a names-only inventory of plaintext YAML entries, +then choose keys to encrypt in their original scopes and layers, for example +`hack env protect API_TOKEN --service api`. Omitted `--env` covers all overlays. +Keep the existing key and recover missing key material before trying to protect +values. Encrypting a YAML entry does not erase legacy dotenv or store copies. + +Secret writes now use `--secret --value-stdin` or the hidden terminal prompt; +positional values with `--secret` are refused. Continue using `--secret` when +updating an encrypted entry. Review legacy lifecycle hooks that depended on a +service's values: they now receive only global contract values. Put only the +values a hook needs into global scope. For text parsers, prefer JSON metadata +or explicit single-key reads over the old tab column positions. YAML projects' +legacy daemon set/unset routes refuse with HTTP 409 +`yaml_env_mutation_unsupported`; use the canonical CLI env commands. + +See [the env command and script migration guidance](../env.md#common-commands) +and [legacy migration and cleanup](../env.md#legacy-repos-and-migration). +The live-key fix is merged in [#769](https://github.com/hack-dance/hack/pull/769). +The env contract above is awaiting [#767](https://github.com/hack-dance/hack/pull/767) +before this draft is opened for review. Cleanup receipts in +[#768](https://github.com/hack-dance/hack/pull/768) are a separate pending change; +they are not part of the merged key-preservation guarantee yet. + ## Highlights -- **Same projects, same commands.** A v4 project runs on v5 without a config - rewrite. +- **Same project folder and default backend.** Compose remains the default; + inspect legacy env migration before accepting project-file changes. - **Safer env.** Secrets can be entered without appearing in command arguments, and the env migration never rewrites a tracked file without your consent. - **`hack dev`.** One command runs a repository's own side-by-side development @@ -37,8 +80,8 @@ This page is the readable summary. The generated 4. Start the project with `hack up` and check the application itself: sign-in, data-backed pages, and anything that must survive a restart. -Projects need no changes to keep running on Compose. Three behavior changes can -affect an existing project: +Existing Compose projects keep the same project model. Review env migration and +command behavior before upgrading; these changes can affect an existing project: - **Managed env values that contain `$`.** v4 let Compose interpolate `$VAR` inside a managed value. v5 delivers the value exactly as stored. A value that relied on @@ -66,7 +109,13 @@ move to the layered YAML format with: hack doctor --migrate-env-config ``` -The migration is built to be safe to run on a real project: +Back up the project, env files and original project key before migration. On +next.16 or earlier prereleases, explicit Doctor cleanup can remove the project +key when a legacy store's `keyPath` names it (HACK-2172). Use a build containing +the fix or preserve a readable key copy outside the working tree first. A new +key cannot decrypt values encrypted with a missing original key. + +The migration has the following consent and delivery checks: - Tracked layers receive encrypted values, never legacy plaintext. Plain values go to gitignored local layers. diff --git a/docs/versions/v5/guides/upgrade-from-v4.md b/docs/versions/v5/guides/upgrade-from-v4.md index a43cbc944..0f599f078 100644 --- a/docs/versions/v5/guides/upgrade-from-v4.md +++ b/docs/versions/v5/guides/upgrade-from-v4.md @@ -35,15 +35,16 @@ flowchart TD Keep v4 when stability is required; otherwise back up, try one project on Compose, check the application, and only then consider an eligible native trial. -**next.16 migration warning (HACK-2172): do not run +**next.16 and earlier migration warning (HACK-2172): do not run `hack doctor --migrate-env-config` without a private, readable copy of `.hack.secret.key`.** If a legacy encrypted store's `keyPath` names that file, explicit Doctor cleanup can remove the key that the migrated values still need. Implicit migration also writes files, so back up before it too; the key-removal defect described here is in the explicit Doctor cleanup. See [Config and env migration](#config-and-env-migration) before any env-consuming -command. Keep this warning until a published fix replaces it with the verified -cleanup contract. +command. The live-key preservation fix is merged for a later prerelease; +next.16 and earlier bundles still need this warning. A new build cannot recover +a key already removed by an older cleanup. ## 1. Who should upgrade now @@ -248,7 +249,7 @@ Migration entry points: [up prompt](https://github.com/hack-dance/hack/blob/26a1 The project still uses `.hack/`, but this does **not** mean legacy env files are left untouched. -**Stop before migration on next.16 unless the project key is backed up.** +**Stop before migration on next.16 or earlier prereleases unless the project key is backed up.** HACK-2172 affects a legacy encrypted store configured with a `keyPath` pointing at `.hack.secret.key`: migration cleanup can delete that same file after using it for the new encrypted YAML values. The values then cannot be decrypted. @@ -259,8 +260,14 @@ dotenv files, not the store's `keyPath`, but it still writes project state: keep the backup before env-consuming commands that can migrate automatically too. The section 2 template already saves the key privately as `$BACKUP/project-.hack.secret.key`, outside the working tree. A published fix -for explicit Doctor cleanup is still required; a planned fix is not protection -for next.16. +for explicit Doctor cleanup is merged in +[#769](https://github.com/hack-dance/hack/pull/769), intended for next.17. +In a build containing that fix, project/shared env keys and current config/YAML +inputs are not cleanup targets, even when an old backend configuration names +one; cleanup refuses instead. Eligible obsolete contract/dotenv files, stores +and separate backend keys still need the documented delivery and consent +checks before removal. This does not repair an installed next.16 bundle +or recover a key removed earlier. Keep the backup until recovery is verified. After those prerequisites, the explicit migration command is: @@ -422,6 +429,24 @@ The Linux daemon additions are specified in the [merged service contract](https://github.com/hack-dance/hack/blob/5e017fddd30bae212883053c62c1105e56835ebc/docs/architecture.md#keeping-hackd-running). The complete 4.2.1 automation/exit/JSON transcript is **to be confirmed in the dogfood run**. +### Native followed-log format in next.17 + +The merged [#747](https://github.com/hack-dance/hack/pull/747) changes native +plain `logs SERVICE --follow` output for the next prerelease. Application-text +lines no longer get the old `SERVICE | ` prefix; the shape matches a finite +snapshot. Both service stdout and stderr reach the reader's stdout, while Hack +notices use stderr. This applies to native followed logs. + +Update a script that parsed the plain prefix to use `--json` and the log event's +`entry.service`, `entry.stream` and `entry.message`. Add `--timestamps` only when +Engine timestamps are wanted; in JSON they populate `entry.timestamp`. JSON +follow remains a stream of session events, including a named `end` on failure; +check both that event and the command exit status. Do not expect a second global +error envelope after the session. Log output can contain application secrets in +either format; do not paste raw output into reports. + +Source: [merged native log output contract](https://github.com/hack-dance/hack/blob/e7a70393e1bae3d3e453ac82bf20fad6273277b3/docs/reference/native-authored-commands.md#followed-service-logs). + ## 6. Try native, then return to Compose Only after the Compose pilot passes, use a disposable project and read @@ -583,7 +608,7 @@ next.16 bundle. | HTTP on port 80 works but routed HTTPS on 443 times out | On one Mac, another program listened on 443 on all addresses, including loopback; affected project hostnames resolved to `127.0.0.1`. Check listener ownership and hostname resolution. Hostnames resolving to the proxy container's address were not affected in that trial. A VPN's “serve” feature is one possible conflicting listener. Doctor does not yet detect this case. | | Candidate Doctor suggests `hack daemon start` | That command names the stable CLI. Keep the stable daemon and its launchd service stopped during the shared-home candidate run; the candidate hint is being corrected. | | `env list --json` reveals plain values | This is next.16 behavior. Review the breaking listing changes in [#767](https://github.com/hack-dance/hack/pull/767) before updating scripts for the next prerelease. | -| Explicit Doctor migration cleanup can remove `.hack.secret.key` | Keep a private readable key backup before any migration, including `doctor --migrate-env-config`. HACK-2172 remains a next.16 warning until the fix ships. | +| next.16 or earlier explicit Doctor migration cleanup can remove `.hack.secret.key` | Keep a private readable key backup before any migration, including `doctor --migrate-env-config`. The merged [#769](https://github.com/hack-dance/hack/pull/769) live-input protection is intended for next.17; an older bundle retains the bug, and upgrading does not recover an already removed key. | | An old project key has group or other access | next.16 Doctor reports `env-key-weak-permissions` with a `chmod 600` remedy. Open PR [#764](https://github.com/hack-dance/hack/pull/764) adds the broader secrets-hygiene report and fixes intended for the next prerelease. | Sources for startup failures: [next.16 lifecycle and startup handling](https://github.com/hack-dance/hack/blob/b21c3b189841c1a3cbb8af2b76414fa347dc7057/src/commands/project.ts). From 65295c474b00fdcc9169e8b03dc3e83c7f02111e Mon Sep 17 00:00:00 2001 From: Kit <344842+roodboi@users.noreply.github.com> Date: Fri, 13 Nov 2026 17:25:21 +0000 Subject: [PATCH 2/3] docs: clarify inferred readiness dependency limits --- docs/versions/v5/guides/upgrade-from-v4.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/versions/v5/guides/upgrade-from-v4.md b/docs/versions/v5/guides/upgrade-from-v4.md index 8c517a785..e82904ec0 100644 --- a/docs/versions/v5/guides/upgrade-from-v4.md +++ b/docs/versions/v5/guides/upgrade-from-v4.md @@ -530,6 +530,8 @@ command-only or disabled checks on routed services still need review. A complete HTTP response from 200 through 499 can establish inferred endpoint readiness, including an application's 404; 5xx, incomplete responses and timeouts cannot. This does not establish application correctness. +Inferred readiness also does not satisfy `depends_on: condition: service_healthy`; +that dependency still requires an explicit enabled healthcheck. The usual 300-second deadline belongs to the entire graph. Dependencies consume it too; a 240-second probe grace does not reset or extend it. For slow startup, From f1d0d72fede5db6ce46f56039ba22a47911aa308 Mon Sep 17 00:00:00 2001 From: Kit <344842+roodboi@users.noreply.github.com> Date: Fri, 13 Nov 2026 17:30:06 +0000 Subject: [PATCH 3/3] docs: align next.17 summaries with merged release contracts --- docs/env.md | 2 +- docs/guides/upgrade-to-v5.md | 4 ++-- docs/guides/v5-release-notes.md | 12 ++++++------ docs/versions/v5/guides/upgrade-from-v4.md | 5 +++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/env.md b/docs/env.md index bf55eb905..52712b389 100644 --- a/docs/env.md +++ b/docs/env.md @@ -1294,7 +1294,7 @@ prerelease, do not run `doctor --migrate-env-config` without a copy of `.hack.secret.key`: explicit cleanup can remove it when a legacy store's `keyPath` names the same file (HACK-2172). The merged live-input protection fix, intended for next.17, refuses cleanup of current project/shared keys, config and -YAML inputs. It does not recover keys already removed. Keep the old encrypted +YAML inputs, including filesystem aliases. It does not recover keys already removed. Keep the old encrypted files until their original key is recovered; creating a replacement key is not recovery. diff --git a/docs/guides/upgrade-to-v5.md b/docs/guides/upgrade-to-v5.md index 0e4168952..6913afa03 100644 --- a/docs/guides/upgrade-to-v5.md +++ b/docs/guides/upgrade-to-v5.md @@ -102,8 +102,8 @@ Keep these manual checks too: `.hack.secret.key` before `doctor --migrate-env-config`.** HACK-2172 lets explicit cleanup delete that key when a legacy store's `keyPath` names it. The live-input protection fix is merged for next.17: current project/shared -keys, config and YAML inputs are not cleanup targets, and cleanup refuses a -request that names one. It cannot recover a key already removed by an older +keys, config and YAML inputs are not cleanup targets, including filesystem +aliases, and cleanup refuses a request that names one. It cannot recover a key already removed by an older build. Back up original keys and env state before migration on any version. The broader Doctor secrets-hygiene report and repairs (HACK-2165, #764) are a diff --git a/docs/guides/v5-release-notes.md b/docs/guides/v5-release-notes.md index 98c3d5eda..4be82fc3a 100644 --- a/docs/guides/v5-release-notes.md +++ b/docs/guides/v5-release-notes.md @@ -24,10 +24,10 @@ its original behavior. | --- | --- | | **Native plain `logs SERVICE --follow` output changes.** It now prints application-text lines, matching a finite snapshot, instead of adding a `SERVICE \| ` prefix. Both service streams go to stdout; Hack notices go to stderr. | Stop parsing the old plain prefix. Use `--json` and the log event's `entry.service`, `entry.stream` and `entry.message` when a script needs those fields. Use `--timestamps` to request Engine timestamps. | | **Env listings hide values by default, including migrated plaintext.** Ordinary `env` / `env list` text and JSON output are metadata. JSON omits `value` and reports `has_value`. | Use `has_value` for availability checks. For a value a script actually needs, call `hack env get KEY` with the same `--env` and `--service`; that command prints plaintext. Bulk `--show-values` requires interactive stdin and stdout; `--show-secrets` remains an alias. | -| **Migration cleanup preserves live keys (HACK-2172).** A legacy store's `keyPath` can no longer make the current project/shared key a cleanup target. Current config and YAML inputs are protected too. | Keep key and env backups before migration. On next.16 or an earlier prerelease, do not run `doctor --migrate-env-config` without a private readable copy of `.hack.secret.key`. The fix does not recover a key already removed. | +| **Migration cleanup preserves live keys (HACK-2172).** A legacy store's `keyPath` can no longer make the current project/shared key a cleanup target. Current config and YAML inputs are protected too, including filesystem aliases. | Keep key and env backups before migration. On next.16 or an earlier prerelease, do not run `doctor --migrate-env-config` without a private readable copy of `.hack.secret.key`. The fix does not recover a key already removed. | | **Doctor fails when an env layer cannot be used by the runtime.** Unreadable, invalid or undecryptable layers no longer get an apparent all-clear. | Run `hack doctor` after upgrading. Fix the reported layer or recover the original key before starting; keep the encrypted file rather than generating a replacement key over it. | | **Doctor checks the Compose proxy's loopback ports.** A reachable container address no longer hides a broken published loopback path. | Read the `proxy ports` warning, check competing listeners and DNS/bind settings, then retry. HTTP success on port 80 is not HTTPS success on 443; the check applies no automatic repair. | -| **Native route readiness can be inferred.** A complete standard Caddy route with no authored healthcheck gets a reviewed HTTP probe and 240 seconds of initial grace. | Review the route port and startup logs. Keep explicit healthchecks; they are not replaced. The grace does not extend the whole graph's deadline or prove the application works. | +| **Native route readiness can be inferred.** A complete standard Caddy route with no authored healthcheck gets a reviewed HTTP probe and 240 seconds of initial grace. A complete HTTP 200–499 response establishes endpoint readiness, not application correctness. | Review the route port and startup logs. Explicit healthchecks are not replaced, and inferred readiness does not satisfy `depends_on: condition: service_healthy`. The grace does not extend the whole graph's deadline. | | **Native start waits for bridge sockets after a stopped pool resumes.** An immediate start no longer fails merely because provider readiness preceded the bridge listener. | Use normal native `up`; startup still requires a successful bridge connection within its deadline. Do not replace readiness checks with a fixed sleep. | ### Env scripts and migrated plaintext @@ -45,11 +45,11 @@ values. Encrypting a YAML entry does not erase legacy dotenv or store copies. Secret writes now use `--secret --value-stdin` or the hidden terminal prompt; positional values with `--secret` are refused. Continue using `--secret` when -updating an encrypted entry. Review legacy lifecycle hooks that depended on a -service's values: they now receive only global contract values. Put only the -values a hook needs into global scope. For text parsers, prefer JSON metadata +updating an encrypted entry. Review legacy lifecycle hooks and processes that +depended on a service's values: they now receive only global contract values. +Put only the values they need into global scope. For text parsers, prefer JSON metadata or explicit single-key reads over the old tab column positions. YAML projects' -legacy daemon set/unset routes refuse with HTTP 409 +daemon `GET /v1/env` returns names-only metadata. Their legacy set/unset routes refuse with HTTP 409 `yaml_env_mutation_unsupported`; use the canonical CLI env commands. See [the env command and script migration guidance](../env.md#common-commands) diff --git a/docs/versions/v5/guides/upgrade-from-v4.md b/docs/versions/v5/guides/upgrade-from-v4.md index e82904ec0..563bdcda9 100644 --- a/docs/versions/v5/guides/upgrade-from-v4.md +++ b/docs/versions/v5/guides/upgrade-from-v4.md @@ -306,7 +306,7 @@ The section 2 template already saves the key privately as for explicit Doctor cleanup is merged in [#769](https://github.com/hack-dance/hack/pull/769), intended for next.17. In a build containing that fix, project/shared env keys and current config/YAML -inputs are not cleanup targets, even when an old backend configuration names +inputs, including filesystem aliases, are not cleanup targets, even when an old backend configuration names one; cleanup refuses instead. Eligible obsolete contract/dotenv files, stores and separate backend keys still need the documented delivery and consent checks before removal. This does not repair an installed next.16 bundle @@ -545,6 +545,7 @@ Use normal `up`; a successful bridge connection is still required within the startup deadline. Do not add a fixed sleep as a substitute for that check. Source: [reviewed route probe and whole-graph budget](https://github.com/hack-dance/hack/blob/31339c7b64a0fde1ce7615a14ce8bfd21189cf89/docs/guides/native-candidate.md#native-http-readiness-probe). +The bridge wait is implemented in [the merged bridge startup code](https://github.com/hack-dance/hack/blob/ceb3e233221bdc4e57de3c80787aca60b0483e4a/packages/runtime-core/src/provider/bridge.rs). ## 6. Try native, then return to Compose @@ -703,7 +704,7 @@ next.16 bundle. | Symptom | What to check or do | | --- | --- | | `up` stops with `E_LIFECYCLE_FAILED` and a pre-up hook's message | In one trial, the hook needed its project's cloud credentials refreshed. Check that hook's own dependency and credentials privately, then retry. A failing `up.before` hook blocks startup; do not suppress it to continue. | -| `up -d` or `restart` exits 1 with `E_STARTUP_INCOMPLETE` although services are up | next.16 can misclassify a one-shot service that finishes in under a second. Check the reported service states and actual exit codes first. In the observed case, rerunning `up -d` succeeded. Open PR [#758](https://github.com/hack-dance/hack/pull/758) addresses short one-shot observation and is intended for the next prerelease; do not assume every incomplete start is this bug. | +| `up -d` or `restart` exits 1 with `E_STARTUP_INCOMPLETE` although services are up | next.16 can misclassify a one-shot service that finishes in under a second. Check the reported service states and actual exit codes first. In the observed case, rerunning `up -d` succeeded. Merged [#758](https://github.com/hack-dance/hack/pull/758), intended for next.17, addresses short one-shot observation; it does not change next.16, and not every incomplete start is this bug. | | HTTP on port 80 works but routed HTTPS on 443 times out | On one Mac, another program listened on 443 on all addresses, including loopback; affected project hostnames resolved to `127.0.0.1`. Check listener ownership and hostname resolution. Hostnames resolving to the proxy container's address were not affected in that trial. next.16 Doctor did not detect this case. Merged [#773](https://github.com/hack-dance/hack/pull/773) adds a `proxy ports` warning for failed published loopback paths; inspect competing listeners, VPN serve/runtime HTTPS settings and DNS/bind configuration. There is no automatic repair. | | next.16 candidate Doctor suggests `hack daemon start` | That command names the stable CLI. Keep the stable daemon and its launchd service stopped during the shared-home candidate run. Merged [#776](https://github.com/hack-dance/hack/pull/776) treats the daemon as optional for newer candidate Compose trials. | | `env list --json` reveals plain values | This is next.16 behavior. Review the breaking listing changes in [#767](https://github.com/hack-dance/hack/pull/767) before updating scripts for the next prerelease. |