Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
My confidence level of correctness now: 68%

# Correctness (100%)

- The A/B ownership and foreign-state behavior is backed by 6,464 passing tests, byte-for-byte collision smoke, and an independent checker with no remaining confirmed security blocker.
- The core #829 behavior is supported, but the strict delivery claim is not correct yet: `framework` mutation scored 86.7% against its declared 93% floor, while 13 final-tree scopes remain unchecked. The user authorized a partial draft, not a green gate or merge.
- Copilot 1.0.83 fails closed on native source proof. That preserves existing state but does not deliver fresh native activation on that installed version.

# Deal breakers

- Do not mark the issue closed or the draft PR merge-ready under strict SDLC. At least 515 additional framework mutants must be detected to meet the existing floor; targeted witnesses or a simpler proof flow need a new validated candidate.
- Partial Copilot 1.0.83 functionality must remain explicit in the draft. Native fresh activation is not verified, so end-to-end satisfaction remains uncertain.

# Suggestions (enhancements only)

- Inventory changed-line mutants before the expensive whole-scope campaign, then test each negative and positive ownership branch; retain the whole-scope gate for the final tree.
- Keep a single source/test SHA and Node/HOME fixture contract through full gates and mutation. Reuse a green report only when those inputs are identical.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# #829 Check follow-up contract

Source: [issue #829](https://github.com/ai-driven-dev/framework/issues/829), `review.md`, and the second read-only preflight (blocked, 2026-09-15). The user will handle legacy state manually.

1. Project sync never refreshes a host marketplace without proving the exact host catalogue is AIDD-owned and contains no foreign plugin refs. No unnamed/global host refresh. A project-labelled catalogue is not proven by a plugin claim alone; without canonical catalogue provenance, skip refresh, preserve host state, and name the limitation. Fresh install must still activate AIDD's plugin without taking over a preexisting catalogue.
2. A conflicting reserved `aidd-framework` host catalogue is never force-removed or rebuilt without canonical AIDD ownership and absence of foreign refs, even when the host calls its registration dead or unknown. Otherwise refuse and leave host state intact.
3. Project `marketplace remove` and `uninstall plugin` remove only A's project-local hooks/scripts and any tool-specific local MCP projection created by that flow before deleting A's manifest projection or detaching A's machine claim where one exists. Cursor's MCP file is user-global, not project-local, and stays for B. Failure retains the truthful local projection and any existing machine claim for a safe retry; B and all machine-owned files/refs remain intact. Do not invent an OpenCode machine claim.
4. A prior AIDD hostName/ref claim is not proof of the current host catalogue source. Native sync, targeted update/remove, and project/user clean compare the effective source read from the host with exact AIDD provenance before any host mutation. Even an owned catalogue may contain a foreign installed ref: catalogue removal also requires the full host ref list and refuses a noncanonical ref. Fresh absence is read from the host; an unreadable/unsupported source fails closed. The installed Copilot 1.0.83 lacks documented structured listing, so it must not activate partially or fabricate ownership.
5. A name/path is not proof of current local file contents. Use installed digests for Cursor user-scope files, OpenCode MCP entries, and Cursor project hook entries/scripts before update/unmerge/delete; a changed or legacy-unproven contribution remains in place and retains truthful claims for manual reconciliation.

Proof: test-first A/B and foreign fake-HOME host assertions, targeted mutation of each destructive guard, then all required CLI gates and a fresh independent Check. No automated legacy migration, no floor reductions, no force bypass.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
status: in-progress
---

# Instruction: guard native activation

## Architecture projection

> Tree of the final files. ✅ create · ✏️ modify · ❌ delete

```txt
cli/
src/contexts/framework/application/flows/marketplace-sync-settings-use-case.ts ✏️ provenance before upgrade/reclaim
src/contexts/tools/domain/ports/native-plugin-activator.ts ✏️ exact catalogue refresh contract if supported
src/contexts/tools/infrastructure/native-plugin-cli-adapter.ts ✏️ exact host CLI dispatch if supported
tests/contexts/framework/application/flows/ ✏️ foreign collision and A/B activation
tests/contexts/tools/infrastructure/ ✏️ exact CLI process arguments
scripts/smoke-collision.sh ✏️ catalogue and cache witnesses
```

## User Journey

```mermaid
flowchart TD
Fixture["Foreign catalogue and plugin in fake HOME"] --> Sync["A syncs its plugin"]
Sync --> Choice{"AIDD proves catalogue ownership?"}
Choice -- "No" --> Refuse["Name collision; foreign state unchanged"]
Choice -- "Yes" --> Exact["Refresh exact AIDD catalogue only"]
```

## Test Scope

```mermaid
---
title: Native activation test scope
---
journey
section Setup
Seed foreign catalogue and cache => witness hashes recorded: 5: cli
section Happy path
Sync AIDD owned exact catalogue => only that catalogue refreshes: 5: cli
section Edge case - foreign collision
Foreign same name or ref => sync refuses and hashes stay equal: 1: cli
section Edge case - stale registration
Unproven dead host registration => no force remove or rebuild: 1: cli
section Teardown
Clean fake HOME => real HOME unchanged: 5: cli
```

## Tasks to do

### `1)` Prove ownership before host mutation

> No unscoped refresh or forced takeover can run on foreign state.

1. Write failing fake-host collision tests and targeted mutation checks.
2. Limit refresh to exact proven host catalogues; refuse when the host cannot target safely.
3. Guard reserved-name reclaim with canonical ownership and no foreign refs; update older migration expectations.

## Test acceptance criteria

| Task | Acceptance criteria |
| --- | --- |
| 1 | A sync preserves foreign catalogue registration, plugin ref, and cache bytes; only a proven AIDD catalogue changes, with exact host arguments. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
status: in-progress
---

# Instruction: finish project-local removal

## Architecture projection

> Tree of the final files. ✅ create · ✏️ modify · ❌ delete

```txt
cli/
src/contexts/framework/application/flows/marketplace-remove-use-case.ts ✏️ local cleanup before orphan detach
src/contexts/framework/application/uninstall/uninstall-plugin-use-case.ts ✏️ local cleanup before uninstall detach
src/contexts/framework/application/ownership/project-plugin-cleanup.ts ✏️ reuse or narrow shared cleanup
tests/contexts/framework/application/flows/ ✏️ Cursor hook and MCP orphan removal
tests/contexts/framework/application/ ✏️ uninstall failure and B survival
```

## User Journey

```mermaid
flowchart TD
Shared["A and B share a machine plugin"] --> Remove["A removes a marketplace or uninstalls"]
Remove --> Local["Remove A's local hooks and any local MCP projection"]
Local --> Choice{"Local cleanup succeeded?"}
Choice -- "No" --> Retain["Keep truthful local projection and any existing claim"]
Choice -- "Yes" --> Detach["Detach A; B and machine plugin remain"]
```

## Test Scope

```mermaid
---
title: Project removal test scope
---
journey
section Setup
Install shared Cursor plugin in A and B => local hook and global MCP witnesses ready: 5: cli
section Happy path
Remove from A => A integration gone and B still works: 5: cli
section Edge case - local failure
Hook or MCP delete fails => A projection and any claim stay for retry: 1: cli
section Edge case - tool-specific MCP
Remove OpenCode flat plugin => only A's local MCP entry unmerged: 1: cli
section Teardown
Remove B then user clean => machine plugin removed only after both detach: 5: cli
```

## Tasks to do

### `1)` Complete local cleanup before detachment

> Do not leave A's local projections behind without a plugin record; do not remove Cursor's global MCP.

1. Write failing `marketplace remove` and `uninstall plugin` integration tests.
2. Reuse project-local cleanup for hooks/MCP before manifest removal and claim detach.
3. Prove failure retains A's claim and B's global plugin remains intact.

## Test acceptance criteria

| Task | Acceptance criteria |
| --- | --- |
| 1 | Both commands remove A's project hooks/scripts and any local MCP projection created by that flow before detach; failure retains A's projection and any existing machine claim; Cursor's global MCP, B, and machine-owned state remain unchanged. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
status: in-progress
---

# Instruction: prove current host source

## Outcome

For Codex/Copilot, read the effective host catalogue source before add, refresh, update, project removal, or project/user clean. An AIDD machine claim alone cannot authorize a mutation when the source has been repointed. Before unregistering even an owned catalogue, prove its full host ref list contains no foreign ref. Fresh absence permits registration; an unreadable or foreign source refuses with a named manual remedy. Record exact source only after a proven fresh add. No legacy claim inference.

Apply this gate to project plugin removal even when an old manifest lacks a native registration, if that removal would reach the host. Project clean may still detach a shared user-scope claim and clean local state without catalogue proof, because it must not mutate that shared catalogue. An unproven plugin ref is left enabled rather than uninstalled. [Copilot repository `enabledPlugins` is declarative auto-install](https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-config-dir-reference), so even writing settings is an activation side effect: defer that projection until the catalogue and plugin ref are proven and activated.

Before `clean --scope user`, map every canonical machine claim to exactly one registered host catalogue with current source/ref proof. An orphan or ambiguous claim cannot be uninstalled through a different proven catalogue. A machine-global ref without a canonical claim is likewise not exclusive to this project, even if its host source is AIDD-owned.

User clean preflights availability of every native activator it will need before uninstalling the first tool. A known missing second binary must not leave the first tool already changed while machine claims still record the old state.

Codex 0.151.0 exposes `marketplace list --json` with `name`, `root`, and `marketplaceSource`. The installed Copilot 1.0.83 refuses `--json` despite current official docs; its repository overlay can replace the user source. Do not parse human text as an ownership proof. Feature-probe structured output and fail closed on unsupported versions until an exact source witness can be measured.

## Verification

- A/B fresh registration works; a foreign same-name source and cache stay byte-identical through sync/update/remove/clean.
- Copilot activation refusal leaves foreign repository settings, including `extraKnownMarketplaces` and `enabledPlugins`, byte-identical.
- Native CLI readers and source parsing use installed binary/official contracts, fail closed on unknown shapes.
- User clean refuses an orphan `x@B` claim when only catalogue A is proven; project clean never uninstalls an unclaimed machine-global ref used manually by B.
- Multi-tool user clean with the second binary unavailable refuses before the first host catalogue or ref changes.
- Full tests, architecture, build, smoke, targeted destructive mutants, then all declared mutation scopes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
status: in-progress
---

# Instruction: preserve edited local integration

## Outcome

OpenCode MCP and Cursor project hooks/scripts are user-owned after installation. Compare each current contribution with its recorded install digest before unmerge or deletion. Edited or legacy-unproven entries refuse local detach and preserve claims for manual reconciliation. Reinstall must treat edited MCP as a user collision. Do not delete an entire script directory by plugin name.

Content digest is not path confinement: reject a hooks config, script/parent directory, or MCP output whose resolved path leaves canonical projectRoot, even if the external bytes match the install digest. Preflight before native/shared claims move, then revalidate immediately before write/delete.

## Verification

- A/B remove and clean preserve B and edited project integration; unedited A contributions are removed precisely.
- A failed read/write or digest mismatch leaves A projection/claim truthful and retry-safe.
- Project clean preflights edited hooks before dropping a shared-source reference or undoing any native registration; removal rechecks immediately before write.
- Symlinked hooks config, script parent, and MCP output outside the project remain byte-identical; claims and B remain untouched.
- Targeted RED→GREEN tests and destructive mutation witnesses; full gates run on integrated tree.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
status: in-progress
---

# Instruction: guard user-scope files

## Outcome

Before plugin update, remove, marketplace remove, or global user clean touches a Cursor user-scope file, compare current bytes with the installed digest already in the manifest. A changed, unreadable, or legacy-unproven file blocks that file's mutation and keeps ownership records truthful for manual reconciliation. Containment checks remain mandatory but are not content proof.

On update, a new path absent from the previous owned-file list must also be absent on disk. An existing user-created path is not an AIDD file merely because a later plugin version wants to write it.

For a plugin with both native refs and user files, prepare every file update and validate all old digests/new-path collisions before any native update. Applying a validated plan can still fail through unexpected I/O; retain truthful claims and name manual reconciliation rather than assert cross-host atomicity.

Recheck all planned old paths just before the file write. If a tracked path or parent becomes a symlink outside the user plugin root between planning and application, refuse rather than writing through it; a reduced safe-file map is not permission to continue.

## Verification

- Edited `plugin.json`/script octets survive all four operations; an unedited A contribution is still removable without harming B.
- A user-created `new.md` that collides with a new plugin-version file survives update byte-identically.
- A mixed native+file update collision causes no host call, no file change, and no claim change.
- A symlink substituted after planning cannot overwrite external bytes, even if the native host update has already succeeded.
- A partial failure does not detach a project or machine claim while its local state remains unproven.
- Targeted tests and destructive mutant witnesses, then the integrated full gates.
44 changes: 44 additions & 0 deletions aidd_docs/tasks/2026_09/2026_09_15_fix-829-shared-scope/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
objective: "Project A can install or remove a plugin without changing foreign machine state or stranding A's local integration while B remains dependent."
status: in-progress
---

# Plan: #829 Check repairs

## Overview

| Field | Value |
| --- | --- |
| **Goal** | Prove native catalogue ownership before host mutation; complete local cleanup before claim detach. |
| **Source** | [#829](https://github.com/ai-driven-dev/framework/issues/829), [`frame.md`](./frame.md), [`review.md`](./review.md) |

## Phases

| # | Phase | File |
| --- | --- | --- |
| 1 | Guard native activation | [`phase-1.md`](./phase-1.md) |
| 2 | Finish project-local removal | [`phase-2.md`](./phase-2.md) |
| 3 | Prove current host source | [`phase-3.md`](./phase-3.md) |
| 4 | Preserve edited local integration | [`phase-4.md`](./phase-4.md) |
| 5 | Guard user-scope files | [`phase-5.md`](./phase-5.md) |

## Resources

| Source | Verified |
| --- | --- |
| `codex plugin marketplace upgrade --help` | No name updates all configured Git marketplaces. |
| `copilot plugin marketplace update --help` | No name updates all registered marketplaces. |
| [`docs/ARCHITECTURE.md`](../../../../docs/ARCHITECTURE.md) | Host CLI calls stay behind the native activator port; application owns provenance. |

## Decisions

| Decision | Why |
| --- | --- |
| Refuse an unproven host catalogue; no `force` takeover | #829 requires preexisting user state untouched, including same-name collisions. |
| No unproven native legacy migration | Local registry scope normalization can continue; ambiguous host state is for manual reconciliation. |
| Skip automatic refresh of unproven project-labelled catalogues | A plugin claim does not prove machine catalogue ownership; preserve foreign state before optimizing refresh. |
| Local cleanup before machine claim detach | A failure must leave a truthful claim so retry cannot harm B. |
| A past machine claim is not current host source proof | Same-name catalogues can be repointed after AIDD registration; refuse host mutations without a current source witness. |
| Current source proof is not full ref ownership | An AIDD-owned catalogue can contain foreign host refs; read and partition host refs before unregistering it. |
| Compare local integration to install digests | Hooks and MCP in user-owned project files may be edited; never remove by name alone. |
| Compare user-scope files to install digests | Path containment is not ownership of current contents; edited files must not be updated or deleted by explicit user-scope operations. |
Loading
Loading