---
title: "ECC 2.0 Selective Install Discovery"
description: "This document turns the March 11 mega-plan selective-install requirement into a concrete ECC 2.0 discovery design."
type: skill
canonical_url: https://claudary.paisolsolutions.com/skills/selective-install-architecture
source: "Claudary"
difficulty: intermediate
author: "Claude Code Knowledge Pack"
date: 2026-07-10T11:43:27.593Z
license: CC-BY-4.0
attribution: "ECC 2.0 Selective Install Discovery — Claudary (https://claudary.paisolsolutions.com/skills/selective-install-architecture)"
---

# ECC 2.0 Selective Install Discovery
This document turns the March 11 mega-plan selective-install requirement into a concrete ECC 2.0 discovery design.

## Overview

# ECC 2.0 Selective Install Discovery

## Purpose

This document turns the March 11 mega-plan selective-install requirement into a
concrete ECC 2.0 discovery design.

The goal is not just "fewer files copied during install." The actual target is
an install system that can answer, deterministically:

- what was requested
- what was resolved
- what was copied or generated
- what target-specific transforms were applied
- what ECC owns and may safely remove or repair later

That is the missing contract between ECC 1.x installation and an ECC 2.0
control plane.

## Current Implemented Foundation

The first selective-install substrate already exists in-repo:

- `manifests/install-modules.json`
- `manifests/install-profiles.json`
- `schemas/install-modules.schema.json`
- `schemas/install-profiles.schema.json`
- `schemas/install-state.schema.json`
- `scripts/ci/validate-install-manifests.js`
- `scripts/lib/install-manifests.js`
- `scripts/lib/install/request.js`
- `scripts/lib/install/runtime.js`
- `scripts/lib/install/apply.js`
- `scripts/lib/install-targets/`
- `scripts/lib/install-state.js`
- `scripts/lib/install-executor.js`
- `scripts/lib/install-lifecycle.js`
- `scripts/ecc.js`
- `scripts/install-apply.js`
- `scripts/install-plan.js`
- `scripts/list-installed.js`
- `scripts/doctor.js`

Current capabilities:

- machine-readable module and profile catalogs
- CI validation that manifest entries point at real repo paths
- dependency expansion and target filtering
- adapter-aware operation planning
- canonical request normalization for legacy and manifest install modes
- explicit runtime dispatch from normalized requests into plan creation
- legacy and manifest installs both write durable install-state
- read-only inspection of install plans before any mutation
- unified `ecc` CLI routing install, planning, and lifecycle commands
- lifecycle inspection and mutation via `list-installed`, `doctor`, `repair`,
  and `uninstall`

Current limitation:

- target-specific merge/remove semantics are still scaffold-level for some modules
- legacy `ecc-install` compatibility still points at `install.sh`
- publish surface is still broad in `package.json`

## Current Code Review

The current installer stack is already much healthier than the original
language-first shell installer, but it still concentrates too much
responsibility in a few files.

### Current Runtime Path

The runtime flow today is:

1. `install.sh`
   thin shell wrapper that resolves the real package root
2. `scripts/install-apply.js`
   user-facing installer CLI for legacy and manifest modes
3. `scripts/lib/install/request.js`
   CLI parsing plus canonical request normalization
4. `scripts/lib/install/runtime.js`
   runtime dispatch from normalized requests into install plans
5. `scripts/lib/install-executor.js`
   argument translation, legacy compatibility, operation materialization,
   filesystem mutation, and install-state write
6. `scripts/lib/install-manifests.js`
   module/profile catalog loading plus dependency expansion
7. `scripts/lib/install-targets/`
   target root and destination-path scaffolding
8. `scripts/lib/install-state.js`
   schema-backed install-state read/write
9. `scripts/lib/install-lifecycle.js`
   doctor/repair/uninstall behavior derived from stored operations

That is enough to prove the selective-install substrate, but not enough to make
the installer architecture feel settled.

### Current Strengths

- install intent is now explicit through `--profile` and `--modules`
- request parsing and request normalization are now split from the CLI shell
- target root resolution is already adapterized
- lifecycle commands now use durable install-state instead of guessing
- the repo already has a unified Node entrypoint through `ecc` and
  `install-apply.js`

### Current Coupling Still Present

1. `install-executor.js` is smaller than before, but still carrying too many
   planning and materialization layers at once.
   The request boundary is now extracted, but legacy request translation,
   manifest-plan expansion, and operation materialization still live together.
2. target adapters are still too thin.
   Today they mostly resolve roots and scaffold destination paths. The real
   install semantics still live in executor branches and path heuristics.
3. the planner/executor boundary is not clean enough yet.
   `install-manifests.js` resolves modules, but the final install operation set
   is still partly constructed in executor-specific logic.
4. lifecycle behavior depends on low-level recorded operations more than on
   stable module semantics.
   That works for plain file copy, but becomes brittle for merge/generate/remove
   behaviors.
5. compatibility mode is mixed directly into the main installer runtime.
   Legacy language installs should behave like a request adapter, not as a
   parallel installer architecture.

## Proposed Modular Architecture Changes

The next architectural step is to separate the installer into explicit layers,
with each layer returning stable data instead of immediately mutating files.

### Target State

The desired install pipeline is:

1. CLI surface
2. request normalization
3. module resolution
4. target planning
5. operation planning
6. execution
7. install-state persistence
8. lifecycle services built on the same operation contract

The main idea is simple:

- manifests describe content
- adapters describe target-specific landing semantics
- planners describe what should happen
- executors apply those plans
- lifecycle commands reuse the same plan/state model instead of reinventing it

### Proposed Runtime Layers

#### 1. CLI Surface

Responsibility:

- parse user intent only
- route to install, plan, doctor, repair, uninstall
- render human or JSON output

Should not own:

- legacy language translation
- target-specific install rules
- operation construction

Suggested files:

```text
scripts/ecc.js
scripts/install-apply.js
scripts/install-plan.js
scripts/doctor.js
scripts/repair.js
scripts/uninstall.js
```

These stay as entrypoints, but become thin wrappers around library modules.

#### 2. Request Normalizer

Responsibility:

- translate raw CLI flags into a canonical install request
- convert legacy language installs into a compatibility request shape
- reject mixed or ambiguous inputs early

Suggested canonical request:

```json
{
  "mode": "manifest",
  "target": "cursor",
  "profile": "developer",
  "modules": [],
  "legacyLanguages": [],
  "dryRun": false
}
```

or, in compatibility mode:

```json
{
  "mode": "legacy-compat",
  "target": "claude",
  "profile": null,
  "modules": [],
  "legacyLanguages": ["typescript", "python"],
  "dryRun": false
}
```

This lets the rest of the pipeline ignore whether the request came from old or
new CLI syntax.

#### 3. Module Resolver

Responsibility:

- load manifest catalogs
- expand dependencies
- reject conflicts
- filter unsupported modules per target
- return a canonical resolution object

This layer should stay pure and read-only.

It should not know:

- destination filesystem paths
- merge semantics
- copy strategies

Current nearest file:

- `scripts/lib/install-manifests.js`

Suggested split:

```text
scripts/lib/install/catalog.js
scripts/lib/install/resolve-request.js
scripts/lib/install/resolve-modules.js
```

#### 4. Target Planner

Responsibility:

- select the install target adapter
- resolve target root
- resolve install-state path
- expand module-to-target mapping rules
- emit target-aware operation intents

This is where target-specific meaning should live.

Examples:

- Claude may preserve native hierarchy under `~/.claude`
- Cursor may sync bundled `.cursor` root children differently from rules
- generated configs may require merge or replace semantics depending on target

Current nearest files:

- `scripts/lib/install-targets/helpers.js`
- `scripts/lib/install-targets/registry.js`

Suggested evolution:

```text
scripts/lib/install/targets/registry.js
scripts/lib/install/targets/claude-home.js
scripts/lib/install/targets/cursor-project.js
scripts/lib/install/targets/antigravity-project.js
```

Each adapter should eventually expose more than `resolveRoot`.
It should own path and strategy mapping for its target family.

#### 5. Operation Planner

Responsibility:

- turn module resolution plus adapter rules into a typed operation graph
- emit first-class operations such as:
  - `copy-file`
  - `copy-tree`
  - `merge-json`
  - `render-template`
  - `remove`
- attach ownership and validation metadata

This is the missing architectural seam in the current installer.

Today, operations are partly scaffold-level and partly executor-specific.
ECC 2.0 should make operation planning a standalone phase so that:

- `plan` becomes a true preview of execution
- `doctor` can validate intended behavior, not just current files
- `repair` can rebuild exact missing work safely
- `uninstall` can reverse only managed operations

#### 6. Execution Engine

Responsibility:

- apply a typed operation graph
- enforce overwrite and ownership rules
- stage writes safely
- collect final applied-operation results

This layer should not decide *what* to do.
It should only decide *how* to apply a provided operation kind safely.

Current nearest file:

- `scripts/lib/install-executor.js`

Recommended refactor:

```text
scripts/lib/install/executor/apply-plan.js
scripts/lib/install/executor/apply-copy.js
scripts/lib/install/executor/apply-merge-json.js
scripts/lib/install/executor/apply-remove.js
```

That turns executor logic from one large branching runtime into a set of small
operation handlers.

#### 7. Install-State Store

Responsibility:

- validate and persist install-state
- record canonical request, resolution, and applied operations
- support lifecycle commands without forcing them to reverse-engineer installs

Current nearest file:

- `scripts/lib/install-state.js`

This layer is already close to the right shape. The main remaining change is to
store richer operation metadata once merge/generate semantics are real.

#### 8. Lifecycle Services

Responsibility:

- `list-installed`: inspect state only
- `doctor`: compare desired/install-state view against current filesystem
- `repair`: regenerate a plan from state and reapply safe operations
- `uninstall`: remove only ECC-owned outputs

Current nearest file:

- `scripts/lib/install-lifecycle.js`

This layer should eventually operate on operation kinds and ownership policies,
not just on raw `copy-file` records.

## Proposed File Layout

The clean modular end state should look roughly like this:

```text
scripts/lib/install/
  catalog.js
  request.js
  resolve-modules.js
  plan-operations.js
  state-store.js
  targets/
    registry.js
    claude-home.js
    cursor-project.js
    antigravity-project.js
    codex-home.js
    opencode-home.js
  executor/
    apply-plan.js
    apply-copy.js
    apply-merge-json.js
    apply-render-template.js
    apply-remove.js
  lifecycle/
    discover.js
    doctor.js
    repair.js
    uninstall.js
```

This is not a packaging split.
It is a code-ownership split inside the current repo so each layer has one job.

## Migration Map From Current Files

The lowest-risk migration path is evolutionary, not a rewrite.

### Keep

- `install.sh` as the public compatibility shim
- `scripts/ecc.js` as the unified CLI
- `scripts/lib/install-state.js` as the starting point for the state store
- current target adapter IDs and state locations

### Extract

- request parsing and compatibility translation out of
  `scripts/lib/install-executor.js`
- target-aware operation planning out of executor branches and into target
  adapters plus planner modules
- lifecycle-specific analysis out of the shared lifecycle monolith into smaller
  services

### Replace Gradually

- broad path-copy heuristics with typed operations
- scaffold-only adapter planning with adapter-owned semantics
- legacy language install branches with legacy request translation into the same
  planner/executor pipeline

## Immediate Architecture Changes To Make Next

If the goal is ECC 2.0 and not just “working enough,” the next modularization
steps should be:

1. split `install-executor.js` into request normalization, operation planning,
   and execution modules
2. move target-specific strategy decisions into adapter-owned planning methods
3. make `repair` and `uninstall` operate on typed operation handlers rather than
   only plain `copy-file` records
4. teach manifests about install strategy and ownership so the planner no
   longer depends on path heuristics
5. narrow the npm publish surface only after the internal module boundaries are
   stable

## Why The Current Model Is Not Enough

Today ECC still behaves like a broad payload copier:

- `install.sh` is language-first and target-branch-heavy
- targets are partly implicit in directory layout
- uninstall, repair, and doctor now exist but are still early lifecycle commands
- the repo cannot prove what a prior install actually wrote
- publish surface is still broad in `package.json`

That creates the problems already called out in the mega plan:

- users pull more content than their harness or workflow needs
- support and upgrades are harder because installs are not recorded
- target behavior drifts because install logic is duplicated in shell branches
- future targets like Codex or OpenCode require more special-case logic instead
  of reusing a stable install contract

## ECC 2.0 Design Thesis

Selective install should be modeled as:

1. resolve requested intent into a canonical module graph
2. translate that graph through a target adapter
3. execute a deterministic install operation set
4. write install-state as the durable source of truth

That means ECC 2.0 needs two contracts, not one:

- a content contract
  what modules exist and how they depend on each other
- a target contract
  how those modules land inside Claude, Cursor, Antigravity, Codex, or OpenCode

The current repo only had the first half in early form.
The current repo now has the first full vertical slice, but not the full
target-specific semantics.

## Design Constraints

1. Keep `everything-claude-code` as the canonical source repo.
2. Preserve existing `install.sh` flows during migration.
3. Support home-scoped and project-scoped targets from the same planner.
4. Make uninstall/repair/doctor possible without guessing.
5. Avoid per-target copy logic leaking back into module definitions.
6. Keep future Codex and OpenCode support additive, not a rewrite.

## Canonical Artifacts

### 1. Module Catalog

The module catalog is the canonical content graph.

Current fields already implemented:

- `id`
- `kind`
- `description`
- `paths`
- `targets`
- `dependencies`
- `defaultInstall`
- `cost`
- `stability`

Fields still needed for ECC 2.0:

- `installStrategy`
  for example `copy`, `flatten-rules`, `generate`, `merge-config`
- `ownership`
  whether ECC fully owns the target path or only generated files under it
- `pathMode`
  fo

---

Source: [Claudary](https://claudary.paisolsolutions.com/skills/selective-install-architecture) · https://claudary.paisolsolutions.com
