Final Output Contract Implementation Plan
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Add a provider-neutral structured final output contract so Almanac operations can return a typed final report for hosted GitHub PR comments without scraping prose.
Architecture: AgentRunSpec.output becomes a harness-level JSON Schema contract, HarnessResult.output carries the parsed final value, and operation reports define the one v1 schema plus final-output instructions. Provider adapters translate the same contract to Codex and Claude; process records persist the validated output for downstream products.
Tech Stack: TypeScript, raw JSON Schema objects, Codex app-server/exec structured output, Claude Agent SDK outputFormat, Vitest.
Task 1: Harness Output Types#
Files:
- Create:
src/harness/final-output.ts - Modify:
src/harness/types.ts - Modify:
src/harness/events.ts - Test:
test/harness-types.test.ts
Add JsonValue, FinalOutputSpec, FinalOutputResult, parseJsonSchemaFinalOutputText, and helpers for text/schema results. Keep raw text for audit and expose parsed value. Keep compatibility for existing schemaPath callers only if needed at provider adapter boundaries.
Task 2: Provider Mapping#
Files:
- Modify:
src/harness/providers/codex/request.ts - Modify:
src/harness/providers/codex/app-server.ts - Modify:
src/harness/providers/codex/app-notifications.ts - Modify:
src/harness/providers/codex/result.ts - Modify:
src/harness/providers/codex/types.ts - Modify:
src/harness/providers/claude.ts - Modify:
src/harness/providers/metadata.ts - Test:
test/codex-harness-provider.test.ts
Codex app-server passes spec.output.schema, Codex exec uses schemaPath only when a legacy caller supplies that adapter hint, and root final agent text is parsed into HarnessResult.output. Claude maps the same contract to SDK outputFormat and reads structured_output from the result message when present.
Task 3: Operation Report Contract#
Files:
- Create:
src/operations/reports.ts - Modify:
src/operations/run.ts - Modify:
src/ingest/context.ts - Test: operation/process tests as needed
Define almanac_operation_report_v1 with {version: 1, summary: string} and add the two-section final-output instruction block to operation prompts when an operation report is requested. Fix GitHub ingest copy to use project knowledge / Almanac language, not memory language.
Task 4: Process Persistence#
Files:
- Modify:
src/process/types.ts - Modify:
src/process/records.ts - Modify:
src/process/manager.ts - Test:
test/process-manager.test.ts,test/process-records.test.ts
Persist operation output in run records as {version, contract, value}. Keep pageChanges.summary for compatibility, but prefer structured summary when the output contract provides one; fallback to legacy first-line summary only for runs without structured output.
Task 5: Verification#
Run:
npm test -- test/codex-harness-provider.test.ts test/harness-provider-registry.test.ts test/harness-types.test.ts test/process-manager.test.ts test/process-records.test.tsnpm run buildnpm test
Update Almanac/docs pages if the implementation changes durable harness behavior.