Skip to content
Merged
3 changes: 3 additions & 0 deletions .github/labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@
- name: "epic:frontend-contrib"
color: "1d76db"
description: "Frontend contribution layer epic (plugins that ship UI)"
- name: "epic:openapi-mcp"
color: "5319e7"
description: "OpenAPI→MCP service introspection epic (RFC #1123, tracking #1117)"

# ── wave: release-train bucket (maps to milestone) ───────────────────────────
- name: "wave:v1"
Expand Down
54 changes: 54 additions & 0 deletions .llm/runs/plan-openapi-mcp-plugin--seed/FILING-LOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Filing log — plan-openapi-mcp-plugin--seed

Board filed 2026-08-03 under owner authorization (relayed). Precedent matched: #890 (epic #922)
and #891 (epic #892). **GitHub wins on conflict from this point.**

## Fork ratification (owner, 2026-08-03)

| Fork | Ruling |
| --- | --- |
| F1 | **NOT ratified by fiat — proof-arbitrated.** S-7 unlocked it: (a) post-allocation callback stands only if #1127's committed `proofs/P1-verdict.md` demonstrates the seam; a FAIL is a legitimate verdict that activates (b) the `aspire-cli` adapter. #1127's verdict decides. |
| F2 | **(a) ratified** — introspection v1; execution v2 behind opt-in. #1139 filed but out of scope until the owner flips F2. |
| F3 | **(a) ratified** — all first-party contracts enriched in one slice (#1137). |
| F4 | **(a) ratified** — receipts accepted (not required), and only after the S-15 fix (#1136 blocked by #1134). |
| F5 | Already applied to PR #1123; matches precedent. |

## Label created

`epic:openapi-mcp` (color 5319e7) — added to `.github/labels.yml` first, then created live.
Verified against the live taxonomy: none of the 15 existing `epic:*` labels fit.

## Mapping (all issues milestone **0.0.5**, label set per netscript-pr taxonomy, exactly one `status:` = `status:plan`, every child carries `Part of #1126`)

| OMB | Issue | Title | Labels beyond epic/status/milestone |
| --- | --- | --- | --- |
| — (epic) | #1126 | Epic: OpenAPI→MCP service introspection | type:umbrella area:tooling area:service priority:p1 — **no closing keyword anywhere in its body** |
| OMB-1 | #1127 | [S1] P1 proof: post-allocation endpoint-manifest seam (arbitrates F1) | type:test area:tooling area:aspire p0 |
| OMB-2 | #1128 | [S2] P2 proof: spec fidelity + size dry-run | type:test area:tooling area:service p0 |
| OMB-3 | #1129 | [S3] P3 proof: auth-guarded spec fixture | type:test area:tooling area:service p0 |
| OMB-4 | #1130 | [S4] Projection domain module | type:feat area:tooling p1 |
| OMB-5 | #1131 | [S5] Endpoint directory + source adapters | type:feat area:tooling p1 · **blocked by #1127 verdict** |
| OMB-6 | #1132 | [S6] Three read tools | type:feat area:tooling p1 |
| OMB-7 | #1133 | [S7] Manifest emission from the P1-proven seam | type:feat area:cli area:aspire p1 · **blocked by #1127 verdict** |
| OMB-8 | #1134 | [S8] Truncation metadata + receipt-after-validation fixes | type:fix area:tooling p1 |
| OMB-9 | #1135 | [S9] Activation surfaces + migration fixture | type:feat area:cli area:tooling p1 |
| OMB-10 | #1136 | [S10] Evidence-gate acceptance (F4a) | type:feat area:tooling p1 · **blocked by #1134, rationale in body (S-15)** |
| OMB-11 | #1137 | [S11] Contract summary/tags enrichment | type:feat area:service p1 |
| OMB-12 | #1138 | [S12] Docs reference + cross-links | type:docs area:docs p2 |
| OMB-13 | #1139 | [S13] EndpointPolicy + invoke (gated on F2) | type:feat area:tooling p2 · **fail-closed fixture set is the gate** |
| OMB-14 | #1140 | [S14] Wave observation (→ #1090) | type:chore area:tooling p2 · **cannot be closed by a PR; wave-four baseline carried in body** |

## Owner-mandated constraints carried into issue text (verified present)

- #1127: FAIL is legitimate → F1(b); gates #1131/#1133 (both bodies carry the block).
- #1139: F2 gate + the absent/malformed/empty/partial deny fixtures as `gate:` acceptance —
the predicate-bug class 0.0.4 shipped twice, named in the body.
- #1140: observational, PR-unclosable, routed to #1090, wave-four baseline (0 docs-MCP calls /
3 of 3 blind curl / ~25 min silent hang) in the body.
- #1136: dependency on #1134 explained in prose (pre-validation receipts would import the S-15
defect into #1078's machinery), not only in the table.

## Milestone note

The 0.0.6+ renumber (same day) did not touch 0.0.4/0.0.5; every issue here targets milestone
0.0.5 (GitHub milestone number 23) and no body references a milestone above 0.0.5.
443 changes: 443 additions & 0 deletions .llm/runs/plan-openapi-mcp-plugin--seed/adversarial-sol.md

Large diffs are not rendered by default.

47 changes: 47 additions & 0 deletions .llm/runs/plan-openapi-mcp-plugin--seed/adversarial-triage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Adversarial triage — dispositions for `adversarial-sol.md` (stage 2, Codex GPT-5.6 Sol · xhigh)

**Verdict: 25/25 accepted** (2 accepted-with-scope). No finding rejected. Integration lands as
rev 2 of `plan.md`, `design/canonical/00–06`, `design/examples/*`, and `rfc.md`. "Where" names
the primary integration point; several findings touch multiple docs.

| # | Sev | Disposition | Integration (rev 2) | Where |
| --- | --- | --- | --- | --- |
| S-1 | blocker | accept | Exact policy carrier defined: `.netscript/agent-mcp.json`, schema-validated at composition; absent → disabled default; unreadable/malformed/partial → disabled **plus surfaced warning**; end-to-end fixture set (valid-enable reaches choke point; absent/malformed/`{}`/partial all deny) becomes a Wave-3 gate | 04 §3 |
| S-2 | blocker | accept | Canonical-identity law: resolve to one unique spec operation first (exact dotted id, else exact `METHOD path`); **ambiguity refuses**; every policy predicate + `confirm` evaluates only the canonical dotted id; deny-wins test crosses aliases | 04 §3, 03 §2 |
| S-3 | major | accept | `confirm` demoted: named deliberate-action friction, **not credited as a security control**; safety rests on policy alone; no-auto-retry note added to the injection posture | 04 §3, §5 |
| S-4 | blocker | accept | Loopback guarantee narrowed and made honest: manifest/appsettings URLs must carry literal loopback hosts; DNS names resolved via `Deno.resolveDns` then pinned (fetch by resolved IP) or refused; overrides labeled operator-trusted and **plan.md's "no network beyond localhost" scoped accordingly**; socket-binding depth stays a named debt with the narrowed claim | 02 §security, plan.md |
| S-5 | blocker | accept | Validation named as real work: an OpenAPI-3.1-subset validator covering what oRPC emits (refs, unions, string constraints, type arrays); tool input becomes location-aware (`params: {path, query, headers}`), `body` accepts any JSON type; proof set includes required headers, same-name cross-location params, unions, non-object bodies; the existing `domain/schema.ts` evaluator is explicitly **not** the validator | 04 §2 |
| S-6 | major | accept | Spec prose declared untrusted at the model boundary; server-side tests assert injected instructions in descriptions never alter tool behavior; residual model-side risk documented rather than claimed away | 04 §5 |
| S-7 | blocker | accept | Option (a) **un-locked**: helper body demonstrably runs before allocation (reviewer's template + Aspire lifecycle evidence adopted); [P1] reframed — must positively demonstrate a run-mode post-allocation callback resolving host-perspective URLs, else F1(b) activates; D3 wording updated | 02 §producer, plan.md D3 |
| S-8 | blocker | accept | Manifest identity binding: adds `projectRoot` + a per-run `runId` (not PID-only); freshness = identity match, not PID+clock; before report/invoke, the fetched service is cross-checked against the binding (service-info name match); wrong-root/copied-worktree cases become refusals | 02 §staleness |
| S-9 | blocker | accept | Directory contract rewritten: every consulted source yields `used | absent | failed(reason)`; outcomes survive into `list_api_services` output (`sources` block); failed read is never rendered as healthy absence | 02 §port, 01 |
| S-10 | major | accept | Deterministic precedence (override > run-manifest > appsettings) with per-service conflict surfacing; source union gains `aspire-cli`; CLI-fallback failure states representable — "contract does not change" claim withdrawn in favor of "contract already contains the fallback's states" | 02 §port |
| S-11 | major | accept | Read-path fetches get bounded timeout + abort + per-service isolation + concurrency bound; one hanging spec ⇒ row-level failure, never a hung directory | 02 §fetch |
| S-12 | major | accept | One status mapping: connection-refused ⇒ `not_running`; connected-but-error/timeout/parse ⇒ `spec_unavailable`; example table corrected to match | 02, examples |
| S-13 | blocker | accept | Truncation arithmetic fixed: flows self-cap below the central truncator's bounds and compute `truncated` **after** all caps; implementation requirement recorded against `truncation.ts` (metadata recomputed after central caps; whole-result byte bound); "~1 line per operation" replaced by measured [P2] budget | 01 |
| S-14 | major | accept | "HEAD-style" dropped: `operations` count derives from a parsed bounded GET or is absent — never defaulted | 01 |
| S-15 | blocker | accept | Receipt commit moves **after** output validation; thrown/validation failures record a failed attempt (no stale green); named as a `withReceipt`/runner integration change, prerequisite to any F4 use | 01 §registry, 05 |
| S-16 | major | accept | F4(b) re-costed: requires per-evidence-class receipts keyed (resource, evidenceKind, operation) — new machinery, not configuration; fork text updated so the owner decides with true costs | 05 §2F, plan.md F4 |
| S-17 | blocker | accept | Wave-0 proofs emit committed artifacts (`proofs/P<n>-verdict.md` with measured result + verdict); first dependent slice carries a hard prerequisite failing on missing/stale/negative artifact | plan.md |
| S-18 | major | accept | Activation surface A corrected: `.mcp.json` pins exact release versions — existing projects reach the tools via documented `agent init` re-run + host restart, with a fixture starting from prior-release host files; "zero new install" claim scoped to new scaffolds | 05 §2A |
| S-19 | major | accept | Errors view derived from each operation's **actual** declared responses; common-envelope compaction only when detected present (no-database in-memory template is the reachable counterexample) | 03 §3 |
| S-20 | major | accept | Archetype reclassified: the `packages/mcp` change is ARCHETYPE-2 (integration behind ports/adapters), full matrix column applies — no hand-picked gate subset; plan + doctrine-fit updated | plan.md, 06 §2–3 |
| S-21 | major | accept-with-scope | The "no provider variance" residue claim withdrawn; the endpoint-source axis is named per doctrine 07 (typed identifier, factory at composition); verdict **re-argued on the axis and unchanged** — all variants are first-party adapters of one core port with no external provider, so core retains them; the plugin question would genuinely reopen on a first external endpoint provider | 06 §1 |
| S-22 | minor | accept | Rung 3 replaced with deterministic humanized-operationId (prior-art shape); the "reads as a sentence" schema-description rung removed | 03 §4 |
| S-23 | major | accept | Example re-labeled explicitly hypothetical throughout; the 202/poll causal chain presented as *one plausible mechanism*, not the recovered incident; the "25 minutes → three calls" claim reduced to what the evidence supports | examples/silent-hang-replay |
| S-24 | major | accept | `curlExample` differentiates `executable` vs `credential-required`; no-auth never inferred from absent OpenAPI security metadata (global auth middleware is invisible to the generator — reviewer's citation adopted) | 01, 04 §4 |
| S-25 | minor | accept | Opt-out gets its typed seam: `introspection.excludeServices` in the same validated `.netscript/agent-mcp.json` carrier; excluded services render as `excluded` rows, spec never fetched (tested) | 01, 02 |

## Cross-cutting notes

- **The reviewer's A/B/C required surfaces all produced blockers** (A → S-1/S-2/S-3; B →
S-9/S-13/S-14/S-15/S-16/S-17; C → S-7/S-8/S-10), vindicating the orchestrator learnings the
brief carried. The defended-checks table (A2 method-from-spec, meta-tool-vs-cache, thinness of
the projection, #1090 routing) is retained as-is — those defenses stand.
- **No finding overturns the two headline decisions** — extend-core-no-plugin (S-21 narrows the
argument, not the verdict) and the meta-tool triad (explicitly defended) — but S-7 converts
D3 from "chosen mechanism" to "P1-arbitrated mechanism," which is a real status change carried
into the RFC.
- Findings S-13/S-15/S-16 require changes to **existing** `packages/mcp` machinery
(`truncation.ts`, `withReceipt`, evidence store), not just new code; these are added to the
wave plan as named slices so they cannot be silently absorbed.
Loading
Loading