Skip to content

feat(env): surface .env compatibility and explicit backend/trust-model UX - #27

Closed
roodboi wants to merge 4 commits into
mainfrom
codex/linear-mention-hack-462-preserve-.env-compatibility-whil
Closed

feat(env): surface .env compatibility and explicit backend/trust-model UX#27
roodboi wants to merge 4 commits into
mainfrom
codex/linear-mention-hack-462-preserve-.env-compatibility-whil

Conversation

@roodboi

@roodboi roodboi commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Motivation

  • Preserve existing .env-style local workflows while making backend and trust-model implications explicit in hack env output.
  • Users must be able to tell which values are plaintext vs encrypted, where values are stored, and whether portable env state is configured.

Description

  • Clarify hack env list human and JSON output by exposing committed contract metadata, .hack/.env plaintext compatibility status, ambient process.env fallback, local secret backend descriptor, compatibility materialization rules, and portable-state message (changes in src/commands/env.ts).
  • Expand hack env backend status to include storage_mode, trust_model, portability, and explicit .env compatibility guidance in both JSON and human-readable panels (changes in src/commands/env.ts).
  • Add helper renderers and a small refactor for persisting backend selection to reduce complexity and centralize messaging (src/commands/env.ts).
  • Document the compatibility plan and recommended UX language in docs/env.md and docs/cli.md, and add a focused design note at docs/plans/2026-03-23-env-compatibility-and-trust-model-ux-design.md.
  • Add regression tests covering the new JSON status surfaces and compatibility reporting in tests/env-backend-command.test.ts.
  • Created a follow-up ticket T-JC89E7C801 to mirror these compatibility and trust-model messages in the macOS UI.

Testing

  • Ran bun test tests/env-backend-command.test.ts which executed 6 tests (6 pass / 0 fail) covering backend status, backend selection/provisioning, secret storage, and the new JSON compatibility fields, and all tests passed.
  • Ran formatting and lint checks with bunx ultracite check (issues were fixed where safe), and checks passed after fixes.
  • Created a ticket with hack tickets create to track desktop UI follow-up (T-JC89E7C801).

Codex Task

@linear

linear Bot commented Mar 23, 2026

Copy link
Copy Markdown

@changeset-bot

changeset-bot Bot commented Mar 23, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d1cc5e7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ca25dfcb2e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/commands/env.ts
},
compatibility_mode: {
plaintext_target: input.storage.localPlaintext.path,
secret_backend: input.storage.localSecrets.backend,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Surface shim storage in compatibility_mode.secret_backend

When controlPlane.secrets.backend is "cloud", this new field is serialized as "cloud" even though resolveSecretStore() still routes those values through createCloudShimAdapter() and persists them in the local encrypted-file shim. Any caller that relies on the new compatibility_mode block to explain where secrets materialize or whether they are portable will therefore misclassify cloud-shim projects as remotely backed instead of machine-local, which defeats the trust-model UX this change is trying to add.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4bc30cf515

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/commands/env.ts
Comment on lines +578 to +580
const backendStatus = describeBackendTrustStatus({
backend: secretsConfig.backend,
provider: secretsConfig.cloud.provider ?? null,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Flag cloud backends with no provider as invalid

If controlPlane.secrets.backend is already "cloud" but cloud.provider is unset — a state older hack env backend use cloud invocations could leave behind, or a manual config edit can create — env backend status now builds a normal-looking status block and exits 0. That is misleading because createCloudSecretStore() in src/lib/secret-store.ts throws on this exact configuration, so hack env list and secret writes still fail immediately. The new trust-model UX should surface this as invalid instead of reporting a provider-targeted shim.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ce503ca7db

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/commands/env.ts
Comment on lines +578 to +580
const backendStatus = describeBackendTrustStatus({
backend: secretsConfig.backend,
provider: secretsConfig.cloud.provider ?? null,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject cloud status when provider is unset

If controlPlane.secrets.backend is cloud but controlPlane.secrets.cloud.provider is missing (possible from older configs or manual edits), env backend status still emits a normal status block and exits successfully. That state is not actually usable: secret-store resolution throws (createCloudSecretStore() in src/lib/secret-store.ts requires a provider), so hack env list and secret writes fail immediately. This makes the new status output unsafe for readiness checks because it reports a healthy cloud backend that cannot be used.

Useful? React with 👍 / 👎.

@roodboi roodboi closed this Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant