Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
4807bc8
docs(plan): open M2 with the first breadth batch
Blind-Striker Aug 13, 2026
b5be633
docs(agents): hand over the M2 execution state
Blind-Striker Aug 13, 2026
dd2c0ea
feat(generator): bind optional nullable query parameters into options…
Blind-Striker Aug 13, 2026
2b56b75
feat(generator): bind JSON request bodies into generated request models
Blind-Striker Aug 13, 2026
2762329
feat(generator): bind cursor-list envelopes and model the envelope kind
Blind-Striker Aug 13, 2026
2336603
feat(generator): collapse curated schema aliases before binding
Blind-Striker Aug 13, 2026
affd8db
feat(generator): merge wire groups sharing a curated client name
Blind-Striker Aug 13, 2026
8a4caf5
feat(sdk): grow the pipeline body path for JSON requests
Blind-Striker Aug 13, 2026
75c8e94
feat(generator): seal the List/Create verb rules and the naming walls
Blind-Striker Aug 13, 2026
165eb05
feat(sdk): add the list-pagination and parent-filter spine types
Blind-Striker Aug 13, 2026
e9821ad
feat(generator): emit options records, request bodies, and cursor-lis…
Blind-Striker Aug 14, 2026
70c5a15
feat(sdk): generate the first breadth batch surface
Blind-Striker Aug 14, 2026
9c9ce61
test(sdk): pin the breadth-batch contract matrix
Blind-Striker Aug 14, 2026
375e55f
fix(generator): reproduce the raw document through concrete Unknown* …
Blind-Striker Aug 14, 2026
be6f63a
fix(generator): land the fail-closed walls batch (#21)
Blind-Striker Aug 14, 2026
b438117
docs: close out the M2 first breadth batch
Blind-Striker Aug 14, 2026
2be2d0f
fix(sdk): refuse a blank explicit password (#20)
Blind-Striker Aug 14, 2026
39c46a9
docs: seal the alignment batch and hand it to the next session
Blind-Striker Aug 14, 2026
234a299
docs(agents): widen the handoff to the full M2 continuation arc
Blind-Striker Aug 14, 2026
c26653a
feat(sdk): unify operation inputs under the *Request family (Q83)
Blind-Striker Aug 14, 2026
251b483
refactor(sdk): migrate to the feature-slice layout (Q84)
Blind-Striker Aug 14, 2026
1680d7b
feat(extensions): bring up AddOpenCode registration (Q85)
Blind-Striker Aug 14, 2026
e008f1d
build(submodule): move the opencode pin to the v2 spec commit
Blind-Striker Aug 14, 2026
7ab8ae1
chore(repo): stop ignoring the tracked submodule path
Blind-Striker Aug 14, 2026
451434e
docs(research): capture the v2 location, auth, and census re-research
Blind-Striker Aug 14, 2026
a0c83a9
feat(sdk): reshape construction, options, and DI onto .NET conventions
Blind-Striker Aug 14, 2026
5daeffb
docs: record the Q90 reshape seal and refresh the operational state
Blind-Striker Aug 14, 2026
72bfbb9
docs(agents): hand off the M2 close-out — Q91 research, fix batch, me…
Blind-Striker Aug 14, 2026
a782d34
docs(research): seal Q91 — the caller-owned HttpClient constructor st…
Blind-Striker Aug 15, 2026
b099aaa
fix(sdk): refuse a default Authorization header on anonymous injected…
Blind-Striker Aug 15, 2026
7ccb717
fix(sdk): reject explicit JSON null on optional properties whose sche…
Blind-Striker Aug 15, 2026
f74be1f
refactor(sdk): order Pipeline members by access and usage
Blind-Striker Aug 15, 2026
5d65711
fix(sdk): refuse null cursor-list pages and page elements
Blind-Striker Aug 15, 2026
1b22c49
fix(sdk): reject numeric wire values on generated string enums
Blind-Striker Aug 15, 2026
ae73e8a
fix(tools): make format part of schema-alias deep identity
Blind-Striker Aug 15, 2026
64a94dc
fix(tools): refuse model names colliding with hand-written spine types
Blind-Striker Aug 15, 2026
9dd4a37
fix(tools): collision-check envelope DTO names against model names
Blind-Striker Aug 15, 2026
1c8b190
fix(tools): canonicalize property-override keys through the alias map
Blind-Striker Aug 15, 2026
e7015df
fix(tools): name selected component request bodies from their operations
Blind-Striker Aug 15, 2026
691efc8
fix(sdk): carrier converters handle null and enforce fixed outer markers
Blind-Striker Aug 15, 2026
52c9696
fix(sdk): land the small confirmed review fold-ins
Blind-Striker Aug 15, 2026
1bbb867
docs: record the fix-batch landing in the operational state
Blind-Striker Aug 15, 2026
7ac5bf3
refactor: sweep comments down to the status quo
Blind-Striker Aug 15, 2026
03c0aa1
fix(sdk): route timeouts onto the transport spine and refuse conflict…
Blind-Striker Aug 15, 2026
b628c0f
fix(tools): harden guard emission from the second review
Blind-Striker Aug 15, 2026
4a17439
docs: anchor the second-review queue with triggers in the operational…
Blind-Striker Aug 15, 2026
f2a409f
docs(agents): hand off the M3 pickup — plan-first opening, triggered …
Blind-Striker Aug 15, 2026
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
38 changes: 28 additions & 10 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -682,8 +682,8 @@ dotnet_diagnostic.RCS1141.severity = suggestion
# SECTION 12: SONARANALYZER (Sxxxx)
# =============================================================================
# Policy: only arbitrated rules are listed; everything else rides SonarWay
# defaults, which TreatWarningsAsErrors escalates to error (chosen fail-closed
# posture, 2026-08-08). When a Sonar rule misfires, arbitrate it here with a
# defaults, which TreatWarningsAsErrors escalates to error. When a Sonar rule
# misfires, arbitrate it here with a
# comment naming the winner.
dotnet_diagnostic.S125.severity = suggestion
dotnet_diagnostic.S2094.severity = suggestion
Expand All @@ -700,7 +700,7 @@ dotnet_diagnostic.S6602.severity = none
# SECTION 13: COMPILER DIAGNOSTICS (CSxxxx)
# =============================================================================
# Every public member on the shipped surface is documented: generated docs come from the
# spec, hand-written docs by hand (ADR-0004). Tests are exempted in Section 15.
# spec, hand-written docs by hand. Tests are exempted in Section 15.
dotnet_diagnostic.CS1591.severity = error

# =============================================================================
Expand Down Expand Up @@ -735,8 +735,8 @@ dotnet_diagnostic.VSTHRD111.severity = none
# =============================================================================
# Placed after every global C# diagnostic section so the file-scoped glob never
# narrows a later section. MA0048 (file name = type name) cannot apply to the
# file-based tool entry: the SDK synthesizes the Program type, and the sealed
# entry contract pins the file name (it is the tool name:
# file-based tool entry: the SDK synthesizes the Program type, and the entry
# contract pins the file name (it is the tool name:
# ./tools/opencode-tool.cs). Winner: the entry contract; the rule stays error
# for every other file, generated output included (emission keeps file = type).
[tools/opencode-tool.cs]
Expand Down Expand Up @@ -785,16 +785,34 @@ dotnet_diagnostic.S2325.severity = none
[tools/OpenCode.Sdk.Tools/Generator/Ingestion/Models/LiteralKind.cs]
dotnet_diagnostic.CA1720.severity = none

# Generated response adapters gain shared, non-virtual mapping helpers on this
# base at emission build-out, and default interface members cannot carry shared
# behavior on the locked net472/netstandard2.0 targets (CS8701). Winner: the
# The abstract adapter base carries shared, non-virtual mapping behavior for the
# generated response adapters, and default interface members cannot carry shared
# behavior on the net472/netstandard2.0 targets (CS8701). Winner: the
# abstract adapter base; S1694 remains enabled for every other file.
[src/OpenCode.Sdk/Internal/ResponseAdapter.cs]
dotnet_diagnostic.S1694.severity = none

# The generated route surface deliberately nests one static container per operation group
# (maintainer-approved shape, 2026-08-13); flattening would erase the grouping the public
# The generated route surface deliberately nests one static container per operation
# group; flattening would erase the grouping the public
# API promises. Winner: the generated route shape; CA1034 remains enabled for every other
# file.
[src/OpenCode.Sdk/OpenCodeRoutes.cs]
dotnet_diagnostic.CA1034.severity = none

# The shipped SDK slices by client family with flat public namespaces:
# client-family folders are placement, a namespace is API surface, and the
# test project mirrors the layout with equally flat test namespaces. Winner: the
# flat-namespace contract; IDE0130 remains error for every other folder, tools included.
# A new family folder extends these globs deliberately - curation changes are API reviews.
[src/OpenCode.Sdk/{Sessions,Health,Pagination}/**.cs]
dotnet_diagnostic.IDE0130.severity = none

[tests/OpenCode.Sdk.Tests/{Sessions,Health,Pagination}/**.cs]
dotnet_diagnostic.IDE0130.severity = none

# DI extension methods live in the Microsoft.Extensions.DependencyInjection namespace so
# consumers get AddOpenCode without an extra using - the ecosystem convention every
# companion DI package follows. Winner: the ecosystem
# namespace contract; IDE0130 remains error for every other Extensions file.
[src/OpenCode.Sdk.Extensions/OpenCodeServiceCollectionExtensions.cs]
dotnet_diagnostic.IDE0130.severity = none
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,6 @@ internal-docs/
!.claude/skills/
!.claude/skills/**

external/
tmp/

.fake
Expand Down
1 change: 1 addition & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
path = external/opencode
url = https://github.com/anomalyco/opencode
shallow = true
branch = v2
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<DefaultTargetFramework>net10.0</DefaultTargetFramework>
<AllTargetFrameworks>netstandard2.0;net472;net8.0;net9.0;$(DefaultTargetFramework)</AllTargetFrameworks>
<!-- Pinned; docs warn against 'latest' (machine-dependent). C# 14 on net472 is
<!-- Pinned: 'latest' resolves differently per machine and SDK. C# 14 on net472 is
unsupported-but-standard practice via polyfills (Polly/Serilog do the same). -->
<LangVersion>14.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
5 changes: 5 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
<PackageVersion Include="Aspire.Hosting" Version="13.4.6" />
<PackageVersion Include="Aspire.Hosting.AppHost" Version="13.4.6" />
<!-- microsoft packages -->
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.10" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.10" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.10" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.10" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="10.0.10" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.10" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.10" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.301" />
<PackageVersion Include="System.Text.Json" Version="10.0.11" />
Expand Down
3 changes: 3 additions & 0 deletions OpenCode.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
<Project Path="src/OpenCode.Sdk/OpenCode.Sdk.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/OpenCode.Sdk.Extensions.Tests/OpenCode.Sdk.Extensions.Tests.csproj" />
<Project Path="tests/OpenCode.Sdk.Performance.Tests/OpenCode.Sdk.Performance.Tests.csproj" />
<Project Path="tests/OpenCode.Sdk.Sandbox/OpenCode.Sdk.Sandbox.csproj" />
<Project Path="tests/OpenCode.Sdk.Tests/OpenCode.Sdk.Tests.csproj" />
<Project Path="tests/OpenCode.Sdk.Tools.Tests/OpenCode.Sdk.Tools.Tests.csproj" />
</Folder>
<Folder Name="/tools/">
<File Path="tools\curation.json" />
<File Path="tools\generation-profile.txt" />
<Project Path="tools/OpenCode.Sdk.Tools/OpenCode.Sdk.Tools.csproj" />
<File Path="tools/opencode-tool.cs" />
</Folder>
Expand Down
59 changes: 48 additions & 11 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Roadmap

Date: 2026-08-13
Date: 2026-08-15

Operational state: what is done, what is next, what is open. This file shrinks as work lands.
Evergreen rules and locked decisions live in `../AGENTS.md`; decision records in `adr/`.
Expand All @@ -27,7 +27,38 @@ the blocker set (typed-spine leaks, silent route rewriting) lands on the PR bran
issues #19–#25 pinned to the milestone that resolves it — nothing on that list outlives the
M series.

The next work is M2 — the first breadth batch, planned when it starts.
**M2's first breadth batch is complete** (plan:
`superpowers/plans/2026-08-14-m2-first-breadth-batch.md`; decisions: research log Sessions
19–20). `session.list`, `session.get`, `session.create`, and `message.list` are callable
through their final generated surface — uniform `*Request` operation inputs (Q83) with the
query records riding the `ListRequest` seam, `SessionCreateRequest` bodies through the
pipeline's JSON path, cursor-list envelopes with the shared `ListCursor`, query-composing
routes, the `Session.Info` model closure, and the first 5xx arm. Riders #19 (carrier converters), #21 (fail-closed walls + P2 single-pass
envelopes: `GetMessageAsync` 67.4→56.2 μs, `ListMessagesAsync` baseline 58.1 μs/28.24 KB),
and #22 (List/Create verb rules + C17–C20) landed with it; upstream's `InvalidRequestError1`
duplicate collapses through the new `schemaAliases` curation. Demonstrated live 2026-08-14
against `opencode2 serve` v0.0.0-next-17403 (create → list → get → messages, wire cursor
round-tripped). The #20 decision landed (blank explicit passwords refuse; the environment
fallback was later removed by Q90 — `null` sends anonymous requests) and #25 closed keep. The alignment batch is complete — the uniform
`*Request` rename (Q83), the feature-slice layout migration (Q84), and the Extensions
bring-up (Q85) — and the follow-on construction/options/DI reshape (research log Q90)
landed on the same PR: options-only construction with the read-only
`IOpenCodeClientOptions` view and configurable `Username`, no SDK environment reads,
`IHttpClientFactory`-based `AddOpenCode` returning the `IHttpClientBuilder`, pooled
connection lifetime on the owned transport, and the sandbox as the Generic Host DI
showcase. The PR #26 external review ran through adversarial verification (36 findings:
30 confirmed / 4 plausible / 2 refuted), and the verified fix batch landed 2026-08-15
red-test-first — all ten merge blockers plus the small confirmed fold-ins, with Q91 sealed
(research log Session 23, doc 16: the caller-owned HttpClient constructor stays public
behind a fail-closed anonymous-mode guard). A second full-diff review (15 verified
findings) closed the same day: six runtime/emitter fixes landed on the branch (timeouts
route onto the transport spine, conflicting BaseAddress refuses, handle guards match the
route guards, carrier payload guards, count-guard identity, the Pagination shadow wall)
for 932 green tests, and every surviving finding lives milestone-anchored with an explicit
trigger — #31 (M2, DI lifetime shape, decision-first), #32 (M3, EscapeDataString TFM
policy), #33 (M3, carrier hand-construction semantics, rides #23), #34 (M2, contract-test
consolidation), plus the #27 and #23 enrichments. Merge is awaiting the maintainer's word;
further breadth batches follow merge.

## Milestones

Expand All @@ -45,26 +76,32 @@ is revisited at each milestone boundary.
`superpowers/specs/2026-08-11-production-walking-skeleton-design.md`.
2. **M2 — Breadth batches.** The generation profile grows in vertical operation batches;
each batch lands its curation rows, reachable models, operation methods, and contract
tests together. Opens with the review hardening batch (#19 `Unknown*` serialization,
#20 password-semantics decision, #25 IVT decision); the generator fail-closed walls
batch (#21, includes the P2 envelope fold) and the naming/curation wall batch (#22)
land at this boundary.
3. **M3 — Streams.** SSE engine over the v2 stream surface (`v2.event.subscribe`,
tests together. The first batch (list/get/create/message-list) is complete with every
review rider resolved (#19–#22, #20, #25), and so is the alignment batch (uniform
`*Request`, feature-slice layout, Extensions bring-up — research log Q83–Q85). The
Extensions package grows in parallel with the remaining batches.
3. **M3 — Streams.** Planning opens with the **location + merged-Request input design
session** (sealed 2026-08-14, research log Session 22): the dual-channel location
mechanism, deepObject marshalling, the one-`*Request`-carrying-body-and-query shape,
and the `session.list` flat-field exception — census and mechanisms in research doc 15
§5a/§6. Then the SSE engine over the v2 stream surface (`v2.event.subscribe`,
`v2.session.log` with `after`/`follow`, cursor-paged `v2.message.list`); the v1
durable-stream design does not carry over and is re-derived here. Demo: watching a
real session's event stream. The net472 `ServicePointManager` item lands here. The
union single-pass deserialization and streaming adapter-boundary redesign (#23) land
on the M3 runway, gated on the performance baselines (#18).
on the M3 runway, gated on the performance baselines (#18), together with the
second-review perf mechanisms and #29; #32 (EscapeDataString TFM policy) rides the
net472 cluster and #33 (carrier hand-construction semantics) rides #23.
4. **M4 — Launcher.** `OpenCodeServer.StartAsync` with three-OS acceptance (ADR-0001)
over `opencode2 serve`; demo: the SDK starts the server itself and calls health. The
net472 stdout/tree-kill items land here. (`serve --stdio`'s stdin leash and the
background service's discovery file are candidate mechanisms — decided in the M4 plan;
platform detail: research doc 15.)
5. **M5 — Full surface.** Complete generation profile over the protocol surface,
exclusion fingerprints (ADR-0008), packaging unblocked.
6. **M6 — Operational closure.** `refresh-spec`, Extensions DI breadth,
retry/telemetry/hooks, quarantine lane, nightly canary (the performance suite joins
it); durable decisions distill into ADRs and the `superpowers/` documents retire. Any
6. **M6 — Operational closure.** `refresh-spec`, retry/telemetry/hooks, quarantine
lane, nightly canary (the performance suite joins it); durable decisions distill
into ADRs and the `superpowers/` documents retire. Any
hygiene-sweep leftovers (#24) are resolved here — nothing from the review queue
survives the M series.

Expand Down
75 changes: 0 additions & 75 deletions docs/agents/handover-prompts/HANDOFF-2026-08-13-3.md

This file was deleted.

Loading