Skip to content

refactor: migrate story draft, import, and probe onto the skill runner - #75

Merged
aksOps merged 2 commits into
mainfrom
feat-ai-runner-migration
Aug 17, 2026
Merged

refactor: migrate story draft, import, and probe onto the skill runner#75
aksOps merged 2 commits into
mainfrom
feat-ai-runner-migration

Conversation

@aksOps

@aksOps aksOps commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Completes the rig migration started in #74: story draft, import preview, drift, and the probe now run on the skill runner, and the legacy single-shot JSON pipeline is deleted. internal/server has zero openai-go imports — rig is the only path to an LLM.

What changed

  • Story draft (POST /api/ai/story): runs the new story-draft skill (read-only tool scope, one propose_card, 4096-token budget). The flat StoryDraft response and all error codes are unchanged — the frozen UI needs no changes.
  • Import preview (POST /api/import/preview): runs the new import-transform skill. propose_card gained an optional source integer so drafts map back to numbered forge issues; the Source N packing, provenance attachment, issues[:sourceCount] authorization invariant, and model-invented link:: stripping are all preserved. New: a transform cut short by the iteration cap is surfaced in the existing note field instead of silently truncating, and duplicate source numbers can no longer claim the same external key (pre-existing defect, fixed in passing).
  • Drift summary: a tool-less single-iteration rig run — still exactly one bounded, secret-free upstream request (the test asserting that still passes), still degrades to "" on any failure.
  • Probe (POST /api/ai/test): rig.ProbeToolCalling with the same user-visible mapping (400 "model must support tool calling", 422 truncated, opaque 502). A reasoning model that burns the probe budget now correctly gets the truncation error.
  • Runner: runSkill takes a per-flow token budget, clamped to the 8192 ceiling.
  • Deleted: chat, chatCompletion, sdkMessages, aiSDKOptions, the response-body middleware, decodeJSONObject/thinkBlockRe, coerceDraft/coerceDrafts, the per-feature system prompts (now skill files), aiBudget, and the probe plumbing. Net −843 lines against +857 (most additions are skill files and runner-path tests).

Testing

  • Full suite: 1244 tests, 6 packages, 0 failed; race-clean; gofmt clean; Go coverage 97.1% (gate 96.4%), every package above the 95% floor.
  • Live smoke against Ollama Cloud (gemma4:31b): probe ok in 0.6s; story create returned a correct flat draft in 3.4s; story update honored the instruction (effort M→S, added the requested check, kept existing tags) in 1.6s; ADR split regression returned 9 stories from the 9-deliverable test ADR in 6.9s.
  • Adversarial review findings fixed pre-PR: budget ceiling unenforced on the runner path, silent import truncation, a skill-body/system-prompt contradiction that made healthy story runs 502, duplicate-source provenance sharing.
  • Known limitation (rejected as out of scope here): rig v0.1.0 collapses "200 with no choices" into ErrNoToolCalling on the probe path — a distinct sentinel belongs in rig v0.2.0.

Closes #69.

aksOps added 2 commits August 16, 2026 07:40
#69)

Move the remaining single-shot AI flows onto rig and delete the legacy
JSON-scraping pipeline. openai-go no longer appears in internal/server;
rig is the only path to an LLM.

- story draft: story-draft skill on the runner (read-only scope, one
  propose_card, per-flow token budget); flat response contract unchanged
- import preview: import-transform skill; propose_card gains an optional
  source field so drafts map back to numbered forge issues; provenance,
  authorization, and link-stripping invariants unchanged; a transform cut
  short by the iteration cap is reported in the response note; duplicate
  source numbers can no longer share one external key
- drift summary: tool-less single-iteration rig run, still exactly one
  bounded upstream request, still degrades to empty on failure
- probe: rig ProbeToolCalling with the same status mapping (400 no tool
  calling, 422 truncated, opaque 502)
- runSkill takes a per-flow max token budget, clamped to the ceiling
- deleted: chat, chatCompletion, sdkMessages, aiSDKOptions, response-body
  middleware, decodeJSONObject, coerceDraft(s), per-feature system
  prompts, aiBudget, probe plumbing
@sonarqubecloud

Copy link
Copy Markdown

@aksOps
aksOps merged commit faa30e5 into main Aug 17, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AI: move story draft and import onto the skill runner

1 participant