Skip to content
Merged
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
81 changes: 81 additions & 0 deletions .llm/runs/feat-openapi-mcp-manifest-cli--1133/context-pack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Context Pack: Aspire CLI adapter hardening

## Run Metadata

| Field | Value |
| --- | --- |
| Run ID | `feat-openapi-mcp-manifest-cli--1133` |
| Branch | `feat/openapi-mcp-manifest-cli` |
| Current phase | `implementation evaluation` |
| Archetype | `2 - Integration` |
| Scope overlays | `none` |

## Current State

The identity-bound F1(b) adapter and scaffold named gate are implemented. A real proxy collision
proved the identity guard and added allocated target-PORT selection. Package/static gates pass;
pre-reconcile branch CI passed the named live adapter gate and the canonical suite 71/71 with
cleanup. After S6 and #1211 landed, a fresh randomized-port scaffold passed the public
`list_api_services` capture against its exact AppHost while a foreign AppHost remained live.

## Completed

- Required skills/docs, issue, RFC §F1, P1 verdict, doctrine, gate matrix, and real Aspire output read.
- S6 checked: open with no PR, so directory fixture is current E2E fallback.
- Composed/not-local PLAN-EVAL ruling recorded.
- Adapter fixtures cover CLI absence, command failure, benign format drift, torn output, foreign
project resources, and AppHost restart races.
- Package check/tests, scoped lint/fmt, quality/architecture, docs, and publish dry-run gates pass.
- Canonical S7 negative case rejected a foreign service on the fixed proxy port.
- Box-43 positive case correlated `aspire describe` target `PORT=45253` to the tool's live
`users` base URL `http://127.0.0.1:45253`, source `aspire-cli`, with 3 operations.

## In Progress

- Composed implementation review/sign-off under milestone ruling D6.

## Next Steps

1. Obtain separate composed implementation review/sign-off.
2. Move to `status:ready-merge` only after the evaluator comment and complete DoD.

## Key Decisions

| Decision | Source | Notes |
| --- | --- | --- |
| F1(b) only | P1/RFC/owner | No template manifest emission. |
| Exact path + stable AppHost PID | real Aspire `ps` | CLI adapter's observable run binding. |
| Foreign resource rejects source | doctrine/S-8 | Never partially trust foreign describe output. |

## Files Changed

| Path | Status | Notes |
| --- | --- | --- |
| `.llm/runs/feat-openapi-mcp-manifest-cli--1133/*` | new | Harness bootstrap and locked design. |
| `packages/mcp/src/infrastructure/service-endpoints/aspire-cli-*.ts` | changed/new | identity-bound query, spawn boundary, output parser |
| `packages/mcp/src/ports/service-endpoint-directory-port.ts` | changed | finite `run_id_mismatch` failure code |
| `packages/mcp/tests/service-endpoint-*` | changed | negative and drift fixtures |
| `packages/mcp/README.md` + generated asset | changed | production behavior and permissions |
| `packages/cli/e2e/**` | changed/new | named live directory gate wired into scaffold.runtime |

## Gates

| Gate family | Current status | Evidence |
| --- | --- | --- |
| Static | pass | check + scoped lint/fmt |
| Fitness | pass | focused/package tests, quality scan, arch check, JSR dry run |
| Runtime | pass | pre-reconcile suite 71/71 plus D15 exact-path adapter capture on #1211-rebased head |
| Consumer | pass | public MCP `list_api_services` returned live `users` at the describe-correlated target port |

## Open Questions

- Which composed reviewer surface will supply the separate IMPL-EVAL verdict after the automatic OpenHands job was policy-skipped?

## Drift and Debt

- Drift: F1(b) rescope and composed PLAN-EVAL are recorded.
- Debt: none created.

## Commits

- See the draft PR's commit list + per-slice PR comments.
70 changes: 70 additions & 0 deletions .llm/runs/feat-openapi-mcp-manifest-cli--1133/drift.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Drift Log: Aspire CLI adapter hardening

## 2026-08-04 — F1(b) re-scope replaces manifest emission

- **What:** Issue #1133's original manifest-template deliverable is replaced by production hardening
of the `aspire-cli` endpoint source.
- **Source:** RFC #1123 §F1, P1 verdict, owner/orchestrator comment, staged brief.
- **Expected:** Post-allocation manifest template emission if P1 passed.
- **Actual:** P1 `FAIL` selects qualified F1(b); S5's CLI adapter is primary and this slice extends it.
- **Severity:** significant
- **Action:** rescope
- **Evidence:** `.llm/runs/test-openapi-mcp-wave0-proofs--wave0/proofs/P1-verdict.md`

## 2026-08-04 — formal PLAN-EVAL composed at milestone level

- **What:** No local formal PLAN-EVAL is launched.
- **Source:** Milestone-run evaluator protocol and orchestrator ruling D6 in the owner brief.
- **Expected:** Ordinary single-run harness would use a separate local PLAN-EVAL.
- **Actual:** `plan-eval.md` records `COMPOSED_NOT_LOCAL`; evaluation occurs via separate composed surfaces.
- **Severity:** minor
- **Action:** accept
- **Evidence:** `.llm/harness/workflow/milestone-run.md`

## 2026-08-04 — real Aspire proxy collision required target-port selection

- **What:** A live scaffold described fixed proxy URL `127.0.0.1:3001` while that port belonged to a
foreign `products` process; the resource's allocated executable `PORT` was the trustworthy live target.
- **Source:** Canonical `scaffold.runtime` named gate `behavior.mcp-endpoint-directory`.
- **Expected:** The first declared HTTP URL would resolve to the described service.
- **Actual:** Identity probe correctly returned `identity_mismatch`; adapter selection was hardened to
prefer the described executable target port without weakening project/run/service identity checks.
- **Severity:** significant
- **Action:** fix
- **Evidence:** focused multi-port fixture plus scaffold output recorded in `worklog.md`.

## 2026-08-04 — local full gate blocked by unrelated runtime health

- **What:** Serialized canonical attempts did not reach a green suite after S7 was registered.
- **Source:** `scaffold.runtime --cleanup --format pretty`.
- **Expected:** All baseline runtime resources healthy, then S7 assertion passes.
- **Actual:** Attempts stopped at existing users DB-health aggregation or workers-api readiness; cleanup
passed. The one S7 execution fired its negative identity case and drove the target-port fix.
- **Severity:** minor
- **Action:** defer to fresh branch CI verdict
- **Evidence:** `worklog.md`; GitHub scaffold-runtime was green on the prior adapter commit.

## 2026-08-04 — composed evaluator surface did not auto-start

- **What:** Draft-to-ready fired repository review workflows, but the OpenHands job was policy-skipped
and no separate review verdict was posted automatically.
- **Source:** Milestone-run evaluator protocol / orchestrator ruling D6 and PR #1206 checks.
- **Expected:** Ready transition plus label surface composes a separate review/evaluation.
- **Actual:** Automated implementation and runtime gates passed; separate reviewer sign-off remains
pending. Cloud OpenHands cannot be forced for this local run under its routing policy.
- **Severity:** minor
- **Action:** leave `status:impl-eval` and request an eligible composed/owner review; never self-certify.
- **Evidence:** PR #1206 timeline and OpenHands Agent check on head `dfcf2b23a`.

## 2026-08-04 — D15 waives serialization for adapter-level capture only

- **What:** The box-43 adapter capture ran alongside foreign AppHosts; the full `scaffold.runtime`
suite remains serialized.
- **Source:** Written orchestrator ruling D15.
- **Expected:** Earlier expensive-gate law blocked any local AppHost while another was live.
- **Actual:** #1211 randomizes listener defaults, while S7 exact-path project/run binding and
service identity checks discriminate the selected AppHost. Coexistence is the strongest identity
proof for this adapter-level capture.
- **Severity:** minor
- **Action:** accept for box 43 only; leave foreign resources untouched and stop only the exact S7 AppHost.
- **Evidence:** Fresh `s7-box43-live` describe/tool correlation recorded in `worklog.md` and PR #1206.
23 changes: 23 additions & 0 deletions .llm/runs/feat-openapi-mcp-manifest-cli--1133/leak-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Run resource leak report

Generated: 2026-08-04T11:21:49.172Z
Worktree: `/home/codex/repos/ns005-s7`
Aspire probe: ok
Docker probe: ok

## container: postgres-d76868c4 (bdd5011afacb1dee73ccc19e6e3c59661845edf1410c8853783c568754f80a29)

- Ownership: `foreign`
- Apparent owner: `/home/codex/repos/ns005-sagas`
- Age: 656794 ms
- Stale: false
- User command: `docker rm -f 'bdd5011afacb1dee73ccc19e6e3c59661845edf1410c8853783c568754f80a29'`

## container: postgres-89449635 (97b90646098858f6cfe163b470fb9d57ff7033d5661f6fe2390c9300ff1ebaec)

- Ownership: `foreign`
- Apparent owner: `/home/codex/repos/wave5-deepseek`
- Age: 4927778 ms
- Stale: false
- User command: `docker rm -f '97b90646098858f6cfe163b470fb9d57ff7033d5661f6fe2390c9300ff1ebaec'`

8 changes: 8 additions & 0 deletions .llm/runs/feat-openapi-mcp-manifest-cli--1133/plan-eval.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# PLAN-EVAL — feat-openapi-mcp-manifest-cli--1133

`COMPOSED_NOT_LOCAL`

Per `milestone-run.md` evaluator protocol and orchestrator ruling D6, this delegated milestone PR
does not spawn a local formal PLAN-EVAL. Evaluation is composed at draft-to-ready through the
separate CI/reviewer surfaces. The implementation supervisor does not self-certify the result.

133 changes: 133 additions & 0 deletions .llm/runs/feat-openapi-mcp-manifest-cli--1133/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Plan: production-harden the Aspire CLI endpoint source

## Run Metadata

| Field | Value |
| --- | --- |
| Run ID | `feat-openapi-mcp-manifest-cli--1133` |
| Branch | `feat/openapi-mcp-manifest-cli` |
| Phase | `plan` |
| Target | `packages/mcp` Aspire CLI endpoint adapter + scaffold runtime evidence |
| Archetype | `2 - Integration` |
| Scope overlays | `none` |

## Archetype

Archetype 2 governs: a small consumed port already has four source adapters; this slice hardens the
external Aspire CLI adapter and its failure boundary without adding runtime lifecycle ownership.

## Current Doctrine Verdict

Keep effects at the adapter edge, preserve the port-owned finite vocabulary, and keep application
composition dependent on the port rather than CLI details. No new debt is planned.

## Axioms in Play

| Axiom | Why it matters |
| --- | --- |
| A1 | Failure and identity vocabulary remains explicit in the published port contract. |
| A7 | Use `Deno.Command`, URL/path primitives, and injected seams; no process wrapper dependency. |
| A11 | Extend the named `EndpointSource` axis rather than fork discovery. |
| A13 | CLI spawn, parse, restart races, and foreign identity are explicit crash boundaries. |
| A14 | Fixtures and runtime evidence prove negative cases fire. |

## Goal

Make `aspire-cli` a trustworthy primary live endpoint source: tolerate benign output drift while
explicitly failing CLI absence, non-zero exit, torn output, foreign project resources, and AppHost
restart races. Prove live scaffold ports resolve through the directory (or S6 tool if landed).

## Scope

- Query `aspire ps` around `aspire describe` and bind the result to exact AppHost path/process run.
- Real-path bind AppHost and executable resource working directories to `projectRoot`.
- Parse documented field aliases and banner-prefixed balanced JSON without accepting torn payloads.
- Add deterministic adapter fixtures for drift and every failure/identity state.
- Update package docs and generated publish assets if the public behavior description changes.
- Queue one `scaffold.runtime` run behind the current baseline owner.

## Non-Scope

- No endpoint manifest template emission (F1(b)).
- No S6 read-tool implementation or registry wiring.
- No changes to source precedence, probing, OpenAPI projection, or service templates.
- No AppHost cleanup belonging to the baseline verification.

## Hidden Scope

- Preserve cancellation across all CLI invocations.
- Bound failure reasons so CLI output cannot become an unbounded MCP row.
- Regenerate package publish assets if README content changes.
- Re-check S6 and expensive-gate ownership immediately before runtime validation.

## Locked Decisions

| ID | Decision | Rationale |
| --- | --- | --- |
| D1 | Treat exact real `appHostPath` + stable `appHostPid` as the CLI adapter run binding. | These are the run identity facts exposed by `aspire ps`; the manifest UUID is not observable through CLI. |
| D2 | Read `ps`, then `describe`, then `ps`; mismatch is `run_id_mismatch`. | Prevents stale/torn describe output from reading as current after restart. |
| D3 | Require candidate executable `workDir` to resolve inside real `projectRoot`; foreign candidates fail the whole source. | Partial trust would let a foreign endpoint appear live. |
| D4 | Accept casing aliases and balanced banner/trailer JSON, but reject incomplete JSON and missing required structures. | Tolerates version/format drift without converting corruption into health. |
| D5 | Reuse existing explicit source failure rows; add only the finite codes needed for CLI identity ambiguity. | Keeps P3-style visible degraded data at the source boundary. |

## Open-Decision Sweep

| Decision | Status | Notes |
| --- | --- | --- |
| E2E call path | safe to defer until gate | Use `list_api_services` only if S6 merges; otherwise fixture `directory.list()`. |
| AppHost slot timing | safe to defer until gate | Serialized behind baseline; no local start while `aspire ps` is non-empty for that owner. |

## Risk Register

| Risk | Mitigation |
| --- | --- |
| `ps` format varies | Parse array or common envelope aliases; fixture both. |
| PID changes between calls | Pre/post identity equality gate. |
| Some non-executable URL resource lacks workDir | Only accept endpoint candidates with a trustworthy project-root binding; surface failure instead of guessing. |
| S6 lands during work | Rebase before runtime gate and switch evidence to the public tool path. |

## Anti-Patterns to Resolve or Avoid

| AP | Status | Plan |
| --- | --- | --- |
| AP-2 | risk | Keep parsing/domain value-add in adapter; do not wrap `Deno.Command` generically. |
| AP-9 | risk | Add focused parsing functions only where real CLI variants require them. |
| AP-19 | existing documented | Preserve README `--allow-run` declaration. |
| AP-25 | compliant | Process effect remains inside infrastructure adapter. |

## Fitness Gates

| Gate | Required | Expected evidence |
| --- | --- | --- |
| F-3 layering | yes | `deno task arch:check` |
| F-5 public surface/docs | yes | `deno doc --lint` full package exports |
| F-6 publishability | yes | package `deno publish --dry-run` |
| Archetype-2 full column | yes | scoped static, unit/integration, contract, fault, consumer, quality gates |

## Arch-Debt Implications

| Entry | Action | Notes |
| --- | --- | --- |
| `.llm/harness/debt/arch-debt.md` | none expected | Record only if the real CLI cannot supply the locked identity proof. |

## Validation Plan

| Order | Gate | Command or check | Expected result |
| --- | --- | --- | --- |
| 1 | focused tests | `deno test -A packages/mcp/tests/service-endpoint-sources_test.ts packages/mcp/tests/service-endpoint-directory_test.ts` | all pass |
| 2 | scoped static | run-deno check/lint/fmt wrappers over `packages/mcp` | pass |
| 3 | package tests | package test task | pass |
| 4 | doctrine quality | `deno task quality:scan` + `deno task arch:check` | pass |
| 5 | JSR | full export doc lint + package dry-run | pass, zero slow types |
| 6 | consumer runtime | serialized `scaffold.runtime`; S6 tool or directory fixture | live allocated port resolved through `aspire-cli` |

## Dependencies

- S5/#1131 is present on main.
- S6/#1132 is optional for the E2E presentation edge and currently open.
- Baseline verification currently owns the single AppHost slot.

## Drift Watch

- Any need for template emission, a new process, a second port, or non-CLI identity carrier is a rescope.

34 changes: 34 additions & 0 deletions .llm/runs/feat-openapi-mcp-manifest-cli--1133/research.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Research — feat-openapi-mcp-manifest-cli--1133

## Re-baseline

- Carried-in source: `/home/codex/ns005s7-brief.md`, issue #1133, RFC #1123 §F1, and P1 verdict.
- Re-derived against `main` @ `f7558aa1c` on 2026-08-04.
- S5 landed on main in #1194 and already supplies the Aspire CLI adapter, endpoint-source port,
precedence, probe isolation, and explicit source outcomes. This run extends that adapter.
- P1 is `FAIL`; qualified F1(b) is authoritative. No template manifest emission is in scope.
- S6/#1132 remains open with no PR, so the expensive evidence must fixture the directory call unless
S6 merges before the gate is run.

## Findings

| # | Finding | How to verify |
| --- | --- | --- |
| 1 | Current adapter invokes `aspire describe` directly and trusts any parseable `resources[]`. | `packages/mcp/src/infrastructure/service-endpoints/aspire-cli-endpoint-source.ts` |
| 2 | Aspire 13.4.6 `ps --format Json` identifies a run by exact `appHostPath` and `appHostPid`. | Read-only `aspire ps --format Json` captured 2026-08-04. |
| 3 | Real describe resources expose `properties.executable.workDir`; executable service candidates can be bound to `projectRoot`. | Read-only describe of the baseline verification AppHost. |
| 4 | The live AppHost slot is occupied by baseline verification; no runtime gate may start yet. | `aspire ps --format Json` showed three AppHosts under `ns005-baseline`. |
| 5 | Banner noise and field-name drift are plausible across CLI versions; torn/trailing output must never be silently accepted. | Existing 13.4.6 fixture plus F1(b) brief. |

## jsr-audit surface scan (package/plugin waves)

- Surface scanned: `packages/mcp/deno.json`, root `mod.ts`, and exported Aspire adapter types.
- The existing public types are documented. This slice should avoid adding a new export; any added
option stays on the already-exported options interface and receives JSDoc.
- Full `deno doc --lint` and package dry-run are required after implementation.

## Open questions

- S6 may merge before the serialized runtime gate. Re-check immediately before running it; otherwise
exercise `createServiceEndpointDirectory().list()` directly in the scaffold fixture.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"schemaVersion": 2,
"worktreeRoot": "/home/codex/repos/ns005-s7",
"appHosts": [],
"containers": [],
"ownedRoots": [
"/home/codex/repos/ns005-s7/.llm/tmp/cli-e2e/plugin-smoke-20260804-093556",
"/home/codex/repos/ns005-s7/.llm/tmp/cli-e2e"
]
}
25 changes: 25 additions & 0 deletions .llm/runs/feat-openapi-mcp-manifest-cli--1133/supervisor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Supervisor Identity — feat-openapi-mcp-manifest-cli--1133

| Field | Value |
| --- | --- |
| Model | Codex GPT-5 |
| Session | Codex API session (thread identifier not exposed) |
| Host | Linux / `/home/codex` |
| Checkout | `/home/codex/repos/ns005-s7` |
| Worktree | `/home/codex/repos/ns005-s7` |
| Branch | `feat/openapi-mcp-manifest-cli` |
| Baseline | `f7558aa1c4e06f076114d924c7324feddf554e45` (`origin/main`, 2026-08-04) |
| Run ID | `feat-openapi-mcp-manifest-cli--1133` |

## Routes in force

| Task lane | Provider / model / effort | Role in this run |
| --- | --- | --- |
| implementation supervisor | Codex GPT-5 | research, plan, implementation, gate evidence, PR handoff |
| composed evaluator | milestone-run CI/reviewer composition | separate implementation evaluation at draft-to-ready |

## Recorded lane/eval overrides

- Owner/orchestrator ruling D6 applies: no local formal PLAN-EVAL for this delegated milestone PR.
`plan-eval.md` records `COMPOSED_NOT_LOCAL`; plan and implementation proceed in this run.

Loading
Loading