AISOURCEOFTRUTH.COM
OPENSPEC PLAN · FOR YOUR CODING AGENT

AI-written code, tied to the pull request

Your agent writes these files into openspec/changes/integrate-aisot-pr-provenance/ in your repo, runs openspec validate integrate-aisot-pr-provenance, and works the task list. The setup guide explains each step for people.

language: http · python · typescript   with: RepoOps

OPENSPEC/CHANGES/INTEGRATE-AISOT-PR-PROVENANCE/PROPOSAL.MD
# Proposal: AI-written code, tied to the pull request

## Why
Two years after a merge, an auditor asks which model wrote a function and who reviewed it. Commit messages are editable and tools change. A record per merged PR fixes the answer at merge time.

## What Changes
- On merge, CI hashes the merged diff and posts a provenance record with a `code` block.
- `code` carries `prompt_hash`, `session_id`, `pr_ref`, `reviewer` and the agent version ids.
- Anyone finds the records later with `/v1/records?ref={pr_ref}`.


## Capabilities
### New Capabilities
- `pr-provenance`: One record per merged PR with prompt hash, session and reviewer. Find it later by PR ref.

## Impact
- External service: AI Source of Truth at https://aisourceoftruth.com. Reads are anonymous. Writes need a publisher key pair you generate, a client id and secret from registration, and a token from `/oauth/token`.
- Routes used: `POST /v1/records`, `GET /v1/records?ref={ref}`.
- No PromptReports product is required.
- Source of this plan: https://aisourceoftruth.com/use-cases/ai-code-to-pr (CC0). Regenerate it with `curl -H 'Accept: application/json' 'https://aisourceoftruth.com/use-cases/ai-code-to-pr/openspec?lang=http'`.
OPENSPEC/CHANGES/INTEGRATE-AISOT-PR-PROVENANCE/DESIGN.MD
# Design: AI-written code, tied to the pull request

## Context
Engineering teams, dev platforms and coding-agent vendors. Two years after a merge, an auditor asks which model wrote a function and who reviewed it. Commit messages are editable and tools change. A record per merged PR fixes the answer at merge time.

## Where it sits in your agent
A post-merge CI job holds the publisher key as a secret. Keep prompts private: send only their hash.

Over MCP, point the agent at `https://aisourceoftruth.com/mcp` (Streamable HTTP, JSON-RPC 2.0; read tools need no token). The tools this change uses: `publish_record`, `search_records`.

## Decisions
- Treat the registry as a source of facts about records, never about the world. Show what it says, with the digest, and do not turn a verdict into a quality score.
- If the registry cannot be reached, treat the answer as unknown (the same as `check`), never as `rely`, and retry later.
- Keep content private: send hashes. Never put personal data in a record; it is public and permanent.
- Keep the private key and client secret in your secret store. Rotate keys at `POST /v1/keys`; a revoked key cannot sign.

## Setup and signing helper

```sh
# Publisher setup, once. Make an Ed25519 key pair yourself; the registry never sees the private key.
# 1. Register: POST https://aisourceoftruth.com/v1/publishers with {"id","name","public_jwk"}, signed by that key
#    (X-AISOT-Signature over the exact body bytes, base64url) and an Idempotency-Key.
#    The answer carries client_id, client_secret and your key_id.
# 2. Token (60 minutes; mint another the same way):
curl -s -X POST 'https://aisourceoftruth.com/oauth/token' -H 'Content-Type: application/json' \
  --data '{"grant_type":"client_credentials","client_id":"'"$AISOT_CLIENT_ID"'","client_secret":"'"$AISOT_CLIENT_SECRET"'"}'
# ./sign-ed25519 reads bytes on stdin and prints the base64url Ed25519 signature.
```

## Calls
### POST /v1/records
append a signed record; the answer carries its digest and inclusion proof.

```sh
BODY='{ ...record }'
SIG=$(printf %s "$BODY" | ./sign-ed25519)   # base64url signature over these exact bytes
curl -s -X POST 'https://aisourceoftruth.com/v1/records' \
  -H "Authorization: Bearer $AISOT_TOKEN" \
  -H "X-AISOT-Key-Id: $AISOT_KEY_ID" \
  -H "X-AISOT-Signature: $SIG" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H 'Content-Type: application/vnd.aisot.record+json' \
  --data-binary "$BODY"
```

### GET /v1/records?ref={ref}
every record carrying a handle such as a PR, incident or case id.

```sh
curl -s -H 'Accept: application/json' 'https://aisourceoftruth.com/v1/records?ref={ref}'
```

## What this does not prove
- The record shows what CI stated at merge time. It does not show the code is correct or safe.
OPENSPEC/CHANGES/INTEGRATE-AISOT-PR-PROVENANCE/TASKS.MD
# Tasks: AI-written code, tied to the pull request

## 1. Configure
- [ ] 1.1 Set `AISOT_ORIGIN=https://aisourceoftruth.com` in the agent's environment.
- [ ] 1.2 Generate an Ed25519 key pair, register the publisher (`POST /v1/publishers`), and store `AISOT_CLIENT_ID`, `AISOT_CLIENT_SECRET`, `AISOT_KEY_ID` and the private key as secrets.
- [ ] 1.3 Mint a token at `/oauth/token` and confirm `GET /v1/me` answers with your publisher id.
- [ ] 1.4 Optional: add the MCP server `https://aisourceoftruth.com/mcp` to the agent's MCP config.

## 2. Build
- [ ] 2.1 Hash the merged change: Hash the merged diff or the merge commit's tree in a fixed, documented way.
- [ ] 2.2 Publish on merge: From a CI step on the default branch, post the record with `code: { prompt_hash, session_id, pr_ref, reviewer }`. `reviewer` is a handle, never a name or email. (`POST /v1/records`)
- [ ] 2.3 Find it later: Query by PR ref to list every record for that PR. (`GET /v1/records?ref={ref}`)

## 3. Verify against the live registry
- [ ] 3.1 Hash the merged change: Re-running the hash on the merge commit gives the same digest.
- [ ] 3.2 Publish on merge: The CI step fails if the registry refuses the record.
- [ ] 3.3 Find it later: The PR's records come back by ref.

## 4. Done when
- [ ] 4.1 Every merged AI-assisted PR has a record with model, session and reviewer.
- [ ] 4.2 An audit question about a PR is answered with a URL.
OPENSPEC/CHANGES/INTEGRATE-AISOT-PR-PROVENANCE/SPECS/PR-PROVENANCE/SPEC.MD
# pr-provenance Specification

## ADDED Requirements

### Requirement: A record per merged PR
CI SHALL publish a provenance record with a `code` block for every merged pull request that an AI agent contributed to.

#### Scenario: Merge
- **WHEN** an AI-assisted PR merges
- **THEN** a record with `pr_ref`, `session_id` and `reviewer` is published and findable by ref
$ curl -H 'Accept: application/json' https://aisourceoftruth.com/use-cases/ai-code-to-pr/openspec?lang=http # this page is a rendering of the API. Reproduce it as data.