Skip to content

refactor(config): readonly-domain-types (stack 8/12, re-split #307) - #381

Closed
YosefHayim wants to merge 1 commit into
refactor/types/readonly-stack-07-credentialsfrom
refactor/types/readonly-stack-08-config
Closed

refactor(config): readonly-domain-types (stack 8/12, re-split #307)#381
YosefHayim wants to merge 1 commit into
refactor/types/readonly-stack-07-credentialsfrom
refactor/types/readonly-stack-08-config

Conversation

@YosefHayim

@YosefHayim YosefHayim commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Stack 8/12 of re-split HOLD #307

Domain: config
Base: refactor/types/readonly-stack-07-credentials
Full green tip: refactor/foundation/readonly-types-full

Land stack in order. Intermediate PRs may not typecheck alone.


Summary by cubic

Refactored the config domain to use readonly types for env patterns, args, and tool lists to prevent accidental mutation. Also typed the built app descriptor as MutableDeep<AppDescriptor> where internal mutation is needed.

  • Refactors
    • env.ts: Marked exclude patterns and related params as readonly string[]; updated ResolveEnvInput.envExclude.
    • toolchain.ts: Updated ToolchainIo.run to args: readonly string[]; detectMissing and installBrewTools now take readonly Tool[].
    • config.ts: Imported MutableDeep and constructed the descriptor as MutableDeep<AppDescriptor>.

Written for commit 014e7d0. Summary will update on new commits.

Review in cubic

@codeant-ai

codeant-ai Bot commented Aug 7, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR 014e7d0 Aug 07, 2026 · 11:07 11:09

@changeset-bot

changeset-bot Bot commented Aug 7, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 014e7d0

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

@codeant-ai

codeant-ai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 35ae8a81-212c-4659-9448-0a17890efaff

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:XS This PR changes 0-9 lines, ignoring generated files label Aug 7, 2026
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Refactor config domain consumers for readonly types

✨ Enhancement 🕐 10-20 Minutes

Grey Divider

AI Description

• Adapt config parsing/building to construct mutable intermediates for readonly domain types.
• Tighten public APIs to accept readonly arrays where inputs are not mutated.
• Align toolchain I/O interfaces with readonly arguments to satisfy updated type contracts.
Diagram

graph TD
  A["config.ts"] --> T["Readonly domain types"]
  A --> M["MutableDeep utility"]
  E["env.ts"] --> T
  K["toolchain.ts"] --> T
  T --> U["Downstream config/tooling consumers"]
Loading
High-Level Assessment

The chosen approach (readonly inputs + mutable intermediate construction via MutableDeep) is the most direct way to keep runtime behavior unchanged while making consumers compatible with readonly domain types. Alternatives like rewriting construction to be purely functional (no post-assignment) would add churn without improving correctness.

Files changed (3) +9 / -8

Refactor (3) +9 / -8
config.tsUse MutableDeep when constructing AppDescriptor +2/-1

Use MutableDeep when constructing AppDescriptor

• Switches the local descriptor builder to 'MutableDeep<AppDescriptor>' so optional fields can be assigned during parsing even when the exported domain type is readonly. Runtime behavior is unchanged; this is a typing/compatibility adjustment for the readonly-types stack.

src/core/config/config.ts

env.tsAccept readonly env-exclusion patterns throughout env resolution +4/-4

Accept readonly env-exclusion patterns throughout env resolution

• Updates 'isEnvExcluded', 'missingKeys', and 'ResolveEnvInput.envExclude' to use 'readonly string[]' and adjusts internal variables accordingly. This better reflects non-mutating usage and aligns with readonly domain typing.

src/core/config/env.ts

toolchain.tsMake toolchain IO args and tool lists readonly +3/-3

Make toolchain IO args and tool lists readonly

• Changes 'ToolchainIo.run' to accept 'readonly string[]', and updates helper functions to accept 'readonly Tool[]' where inputs are only read. This is a type-safety refactor with no execution flow changes.

src/core/config/toolchain.ts

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread src/core/config/env.ts
Comment on lines 47 to 49
for (const pattern of patterns) {
if (pattern.endsWith('*')) {
if (name.startsWith(pattern.slice(0, -1))) return true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: A configured pattern of "*" is accepted by the schema, but this treats it as a prefix wildcard with an empty prefix, so every environment variable matches and is removed from every layer. This can silently produce an empty build environment and exempt every documented key from missing-key validation. Reject "*" or handle it explicitly according to the intended configuration semantics. [incorrect condition logic]

Severity Level: Major ⚠️
- ❌ Build environment can be emptied by one accepted configuration entry.
- ⚠️ Missing-key validation is bypassed for every documented variable.
- ❌ Builds requiring environment values can fail later downstream.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/core/config/env.ts
**Line:** 47:49
**Comment:**
	*Incorrect Condition Logic: A configured pattern of `"*"` is accepted by the schema, but this treats it as a prefix wildcard with an empty prefix, so every environment variable matches and is removed from every layer. This can silently produce an empty build environment and exempt every documented key from missing-key validation. Reject `"*"` or handle it explicitly according to the intended configuration semantics.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines 198 to 201
export type ToolchainIo = {
exists(command: string): Effect.Effect<boolean, unknown>;
run(command: string, args: string[]): Effect.Effect<void, unknown>;
run(command: string, args: readonly string[]): Effect.Effect<void, unknown>;
confirm(message: string): Effect.Effect<boolean, unknown>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The newly exposed run operation propagates non-zero command failures from executeCommand directly to callers. In particular, ensureCcacheInstalled documents that failed installation/configuration must never throw and should return a skipped result, but its brew install and configuration calls now fail the whole effect instead; the same failure propagation can abort ensureToolchain instead of returning its documented boolean outcome. Map command failures to the appropriate best-effort result or log and continue where the contract requires it. [api mismatch]

Severity Level: Major ⚠️
- ❌ Accepted ccache install failures can abort iOS builds.
-`launch doctor --fix` can fail instead of reporting readiness.
- ⚠️ Optional caching becomes a hard build dependency after acceptance.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/core/config/toolchain.ts
**Line:** 198:201
**Comment:**
	*Api Mismatch: The newly exposed `run` operation propagates non-zero command failures from `executeCommand` directly to callers. In particular, `ensureCcacheInstalled` documents that failed installation/configuration must never throw and should return a skipped result, but its `brew install` and configuration calls now fail the whole effect instead; the same failure propagation can abort `ensureToolchain` instead of returning its documented boolean outcome. Map command failures to the appropriate best-effort result or log and continue where the contract requires it.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 3 files

Re-trigger cubic

@YosefHayim

Copy link
Copy Markdown
Owner Author

Superseded by land of tip stack #386 (same 12 domain commits).

@YosefHayim YosefHayim closed this Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS This PR changes 0-9 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant