Provider conformance suite + provider-author checklist: executable seam obligations, live-spike merge gate #80
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab#80
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
The AgentProvider seam contract lives in interface comments (
internal/provider/provider.go), ADRs (0008, 0016, 0017, 0026, 0030), and claude-code's example. Nothing executable stops a new adapter (#2 Codex, Gemini) from silently missing an obligation — the clear/epoch rotation rule, the argv prompt-trailing shape, the SeedMeta pattern dialect. Decided in provider-seam grill (2026-07-09): 'passes the conformance suite + checklist' becomes the definition of done for any adapter, in two enforced tiers.Design
Tier 1 — hermetic conformance suite (
internal/provider/providertest, e.g.providertest.Conformance(t, provider)), run in CI for every registered adapter:SeedMetarules: ScrubPatterns/SeededPathPatterns compile in the BRE∩RE2 common dialect (#75's contract);ContextFileNamefollows the lab-owned.local-suffix rule (#79);ExcludeEntriescover every seeded path; declared slices are defensively cloned (mutation test).SpawnArgvshape: initial prompt rides as the trailing positional; empty prompt appends nothing; declared spawn options are applied by the provider (fake options round-trip).AuthFlow.Kindis a recognized constant.tmuxx.IsLoginSession(#77).SeedWorkspace(Incogni: true)produces a worktree whose seeded files carry no tracked-file writes, and the provider's ScrubPatterns strip its OWN attribution samples through the #75 sanitizer mechanism (each adapter ships marker samples as test vectors).Tier 2 — required live spikes (ADR-0008 bar; run on a host with the real CLI, tagged like
live_recipes_test.go), required per adapter and evidenced by a committedcompat.md:AGENTS.local.mdvia project config).Checklist (
docs/agents/provider-authoring.md): the ordered author path — implement seam, declare SeedMeta, register config map entries (#78), pass Tier 1, run Tier 2 spikes, commit compat.md, grep-clean core. States the HARD requirements: durable locatable transcript (verified available for Codex rollout JSONLs and Gemini CLI session recording — no capability escape hatch), lab-owned context-file name, live verification before merge.Sequencing
Pins rules established by #75, #77, #78, #79 — blocked until those merge; re-triage to
ready-for-agentthen.Acceptance
Agent Brief
Category: enhancement
Summary: Make "passes the conformance suite + checklist" the executable definition of done for any
AgentProvideradapter, in two enforced tiers: a hermetic CI suite and a live-spike checklist evidenced by a committed compat record.All four sequencing blockers named in the issue body have merged: #75 (provider-declared attribution markers, ADR-0033), #77 (per-provider login sessions, ADR-0034), #78 (generic per-provider host config, ADR-0034), #79 (lab-owned context-file rule). Their rules are now stable and this issue pins them.
Current behavior:
The
AgentProviderseam contract lives only in interface documentation comments and ADRs (0008, 0016, 0017, 0026, 0030, 0033, 0034), plus the claude-code adapter as a worked example. Theprovidertestpackage (next to theproviderpackage) currently contains only consumer-side test doubles — a scriptableFakeand aNoLinkFake— and no conformance entry point. Nothing executable stops a new adapter (Codex #2, Gemini) from silently missing an obligation: the pattern-dialect rule for scrub/seeded-path patterns, the trailing-positional prompt shape, the.localcontext-file naming rule, exclude-entry coverage of seeded files.Desired behavior:
Tier 1 — hermetic conformance suite. A single entry point in the
providertestpackage, shaped likeConformance(t *testing.T, p provider.AgentProvider)(possibly with a small per-adapter fixture struct for things like attribution marker samples), runnable in ordinary CI with no real agent CLI present. It must assert, per adapter:SeedMeta().ScrubPatternsandSeedMeta().SeededPathPatternscompile in the BRE∩RE2 common dialect — via the same compilation path the product uses (CompileScrubPatternsand the pre-push guard's dialect), not a reimplementation.SeedMeta().ContextFileNamefollows the lab-owned.local-suffix rule from #79 (a name the CLI's upstream tooling will never track or generate itself).SeedMeta().ExcludeEntriescover every path the provider actually seeds (every seeded file must be matched by some exclude entry).SeedMeta()are defensively cloned: mutating a returned slice and calling again yields the original values.SpawnArgv(spec): the initial prompt rides as the trailing positional argument; an empty prompt appends nothing; declared spawn options (from the provider'sOptions()catalog) round-trip into argv when set on the spec.AuthFlow().Kindis one of the recognizedAuthFlow*constants.tmuxx.IsLoginSession(the #77 prefix rule).ScrubPatternsstrip that provider's attribution marker samples when run through the #75 sanitizer mechanism (each adapter supplies its real marker strings as test vectors; the union pathRegistry.UnionScrubPatternsmust also strip them).The suite runs in CI for every adapter registered in tests — claude-code today — so a new adapter gets conformance coverage by being added to one table, not by writing new assertions.
Tier 2 — required live spikes. Documented, not CI-run: the ADR-0008 bar. Per adapter, run on a host with the real CLI (in the style of the existing tagged live recipe tests) and evidenced by a committed per-adapter compat record (
compat.mdconvention):AGENTS.local.mdvia project config).ScrubPatterns.Checklist doc. An agent-facing provider-authoring doc (alongside the existing
docs/agents/guides) giving the ordered author path: implement the seam → declareSeedMeta→ register per-provider config map entries (#78) → pass Tier 1 → run Tier 2 spikes → commit the compat record → verify core stays adapter-agnostic (grep-clean of provider names outside the adapter package). It states the HARD requirements with no capability escape hatch: durable locatable transcript (verified available for Codex rollout JSONLs and Gemini CLI session recording), lab-owned context-file name, live verification before merge.ADR. A new ADR records the two-tier bar and that "suite + checklist" is the definition of done for adapters.
Key interfaces:
provider.AgentProvider,provider.SeedMeta,provider.SpawnSpec,provider.AuthFlowand theAuthFlow*kind constants — the surfaces under test; the suite must not need any real CLI binary.CompileScrubPatterns/Registry.UnionScrubPatterns(ADR-0033) — the real sanitizer path the incogni assertions must go through.tmuxx.IsLoginSession(ADR-0034) — login-session name validation.providertest.Fake— stays as-is for consumer tests; the deliberately-broken adapters used to prove the suite fails are new, private to the suite's own tests.Acceptance criteria:
.local) context-file name, prompt not trailing, exclude entries missing a seeded path — fails the suite with actionable, obligation-naming messages (asserted in the suite's own tests).Out of scope:
AgentProviderseam itself — the suite pins existing obligations; if an obligation turns out untestable as specified, flag it on the issue rather than reshaping the seam.Landing audit — PR #88 — Verdict: PASS
Verification signal: CI status was not readable from this session (no forge token /
curl), so I ran the project's own checks against the merged tree.afk/80is already up to date withmain— no merge conflict.Checks run (Go 1.26.4,
CGO_ENABLED=0):go test ./internal/provider/...— green, includingTestConformance/claude-codepassing all ten obligations (patterns-dialect, context-file-lab-owned, seedmeta-clone, catalogs, spawn-argv, auth-flow, login-session, seeding-exclude-coverage, seeding-incogni, scrub-markers) plus the suite's broken-adapter self-tests.go test ./...(untagged) — 30/31 packages green. The single failure isinternal/tmuxx(8 real-tmux D17 subprocess integration tests, "session exited immediately"), which fails identically onorigin/mainand is a sandbox-tmux limitation — not touched by this PR.gofmt -lon the three changed.gofiles — clean.Signal reach: CI's
nativejob runs theui-tagged suite; this diff touches onlyinternal/provider/*.go+ docs (no web/ui-tagged files), so the untagged run faithfully exercises the changed code.Conventions: Conventional-Commits title (
feat(provider): …); body carries a workingCloses #80; headafk/80matches the AFK contract.Diff review: two-tier design matches this issue and the referenced ADRs.
Conformancesplits error-returning check functions from the*testing.Tfront-end (enabling the self-tests);scrub-markersruns the real RE2 compile path, the registry union, and the pre-push hook's actualgrep -iBRE engine with correct exit-code handling; seeding checks run a real linked worktree + the realinternal/seederand assertgit status --porcelainempty rather than a hand-maintained path list. No divergence from stated intent.Awaiting explicit free-text merge confirmation before merging PR #88.