diff --git a/.agent/AGENTS.md b/.agent/AGENTS.md index 3b61e2d..c8073b3 100644 --- a/.agent/AGENTS.md +++ b/.agent/AGENTS.md @@ -1,142 +1,119 @@ # OneShot Agent Policy -This file defines mandatory behavior for every coding, documentation, -infrastructure, data, and model agent working in this repository. +This policy applies to code, documentation, infrastructure, data, and agent +work in this repository. ## Instruction order 1. Follow system and user instructions. -2. Follow the root `AGENTS.md` and this file. -3. Follow `.agent/MILESTONE_IMPLEMENTATION_LOOP.md` for milestone work. -4. Follow the narrowest applicable repository documentation and configuration. +2. Follow root `AGENTS.md` and this policy. +3. Follow the task-specific documents and repo skills routed by root + `AGENTS.md`. +4. Follow the narrowest applicable repository configuration. -If instructions conflict, stop and surface the conflict. Do not silently choose -the most convenient interpretation. +Surface conflicts. Never silently weaken an invariant, review gate, or security +boundary. ## Tool neutrality -- Shared policy must remain independent of agent vendor, model, operating - system, and editor. -- Codex, Claude, Antigravity, Cursor, or another capable agent may implement or - review a change. -- Tool-specific repository files must be thin adapters pointing to the - canonical `AGENTS.md` and `.agent/` documents. Do not copy policy into them. -- Personal prompts, permissions, model choices, and machine-specific commands - belong in ignored local files. -- A gate reviewer must use a fresh read-only session, must not be the - implementation agent, and must identify its tool and platform-reported model - in the verdict. Record `not exposed by platform` when no model identifier is - available. -- Different tools may perform Gate A and Gate B. Both must use the canonical - prompts and required verdict format. - -## Before making changes - -- Read the task, acceptance criteria, relevant code, and related documentation. -- Inspect `git status`, the current branch, and the diff before editing. -- Preserve unrelated user changes and never include them in a commit. -- Identify the milestone, the smallest reviewable outcome, and explicit non-goals. -- State assumptions that can materially affect behavior, security, privacy, - cost, licensing, or architecture. -- Prefer evidence from the repository and official primary documentation over - memory for version-sensitive technical decisions. - -## Scope and architecture - -- One branch and pull request must represent one milestone or one tightly - related correction. -- Keep scope lean and focused. Do not introduce speculative features, unused - dependencies, or unnecessary abstractions unless the active milestone explicitly - requires them. -- Preserve clean separation of concerns: presentation/interface, orchestration, - domain logic, and external service adapters. -- Validate all untrusted input at boundaries. -- Handle state transitions, loading, empty states, and errors predictably. - -## Implementation rules - -- Write strict, readable code adhering to established style conventions. -- Do not weaken compiler, lint, or type-check configurations to make a change pass. -- Prefer small, typed interfaces at subsystem boundaries. -- Add or update tests for behavior changes and regression fixes. +- Codex, Claude, Antigravity, Cursor, or another capable agent may implement + work, but all tools follow the same canonical repository policy. +- Tool adapters remain short pointers to root `AGENTS.md`; personal prompts, + permissions, models, and machine-specific commands stay in ignored files. +- Gate A and Gate B use separate fresh, read-only FreePi processes. Each verdict + records the reviewer tool, platform-reported model (or `not exposed by + platform`), and immutable Git identities required by + `.agent/IMPLEMENTATION_LOOP.md`. + +## Product boundary + +OneShot's core promise is: `One job. Many retries. One settlement.` + +- OneShot owns authoritative Business Intent, Attempt, and Settlement state and + prevents duplicate committed settlements. +- Privy provides corporate wallet access and scoped authorization, policy, and + spending permissions. +- Arc is the USDC settlement rail. +- The Graph provides live indexed history and recovery context. It is never the + duplicate-payment lock or authority for creating another Settlement. + +Read `.agent/PROJECT_CONTEXT.md`, `.agent/SECURITY_INVARIANTS.md`, and +`.agent/SPONSOR_REQUIREMENTS.md` before changing these boundaries. + +## Non-negotiable invariants + +- `1 business intent -> at most 1 committed settlement`. +- Keep one stable `business_intent_id` across retries, restarts, parallel + attempts, workers, and agent instances. +- Treat `UNKNOWN` settlement state as a reconciliation requirement. Never + blindly repay. +- Make state durable and transitions atomic and concurrency-safe. +- Represent money as integer atomic units or `bigint`, never JavaScript + floating point. +- Graph absence or indexing delay is not proof that payment did not happen. +- Normal execution must not bypass Privy policy or OneShot controls. +- Use testnet only unless the user explicitly authorizes another network. +- Never log, expose, persist, commit, or send secrets, private keys, seed + phrases, tokens, wallet credentials, or sensitive runtime configuration. + +## Before changing files + +- Inspect the current branch, status, task acceptance criteria, relevant code, + existing diff, and any merge/rebase state. +- Preserve unrelated user work and keep it out of commits. +- Record material assumptions and active context in `.agent/context/`. +- Use current primary documentation for version-sensitive integrations. +- Do not create or materially revise the product implementation `plan.md` until + required skills and integration research are ready. + +## Implementation quality + +- Keep one branch and PR focused on one milestone or tightly related change. +- Preserve clear ownership among interface, orchestration, domain state, and + external adapters. +- Validate untrusted input at boundaries. +- Do not weaken compiler, lint, type, test, or security settings to get a pass. +- Add tests for behavior changes and regression fixes. Payment-related changes + select applicable cases from `.agent/TEST_MATRIX.md`. - Do not leave dead code, unexplained suppressions, placeholder credentials, or - untracked follow-up work hidden in comments. -- Update documentation when behavior or architectural patterns change. + hidden follow-up work. +- Update documentation when behavior, contracts, or architecture change. -## Quality policy +## Repository skills -Before Review Gate A, run the full local validation suite: +- `oneshot-idempotency`: mandatory for intent, retry, worker, payment, + reconciliation, or settlement work. +- `oneshot-failure-injection`: mandatory for external-effect failure + boundaries. +- `sponsor-qualification`: mandatory before sponsor, demo, or release claims. -```bash -# Project quality checks (configure as codebase components are introduced) -# e.g., lint, type check, unit tests, integration checks -``` +Personal workflow and review skills may supplement these rules. They never +replace OneShot policy or FreePi Gate A/B. -Run additional focused tests required by the changed subsystem. A passing build -does not replace behavioral tests, security checks, or manual verification. - -Do not bypass a failed check with `--force`, `--no-verify`, broad ignore rules, -lowered thresholds, or dependency overrides. Fix the cause or document a genuine -blocker for the user. - -## Git and GitHub +## Git and review policy - Never implement directly on `main` or `develop`. -- The default development and integration branch is `develop`. -- All milestone and feature pull requests must target `develop`. -- Use a descriptive branch such as `milestone/-`, `feature/`, or - `fix/`. -- Never force-push, delete a protected branch, rewrite shared history, or use a - destructive reset without explicit user authorization. -- Stage only files belonging to the active milestone and review the staged diff - before committing. -- Draft pull requests may be created only after Review Gate A passes. -- A draft may be marked ready for user review only after required CI and Review - Gate B pass for the exact current head commit. -- Agents must never merge a pull request. The user performs the final review and - explicitly decides whether to merge. - -## Mandatory independent reviews - -Follow `.agent/MILESTONE_IMPLEMENTATION_LOOP.md` exactly. - -- Review Gate A is a fresh, independent review of the complete workspace change - before the draft pull request is created. It evaluates the staged candidate - tree against the exact target base SHA, covering acceptance criteria, - correctness, edge cases, security, and test coverage. -- Review Gate B is a second fresh, independent review after the draft PR exists - and required CI is green. Gate B is bound to the exact PR head commit SHA and verifies - PR readiness, diff integrity, and check results. -- The implementation agent must not act as its own independent reviewer. Reviewers - must be invoked in an independent session using `.agent/review-prompts/implementation-review.md` - for Gate A and `.agent/review-prompts/draft-pr-review.md` for Gate B. -- No specific review vendor or model is mandatory unless a milestone explicitly - requires one. Missing reviewer tool or reviewed Git identity is a failure. -- Do not reuse or resume the Gate A session for Gate B. -- Any content change after Gate A invalidates Gate A. -- Any commit after Gate B invalidates Gate B. -- `WARN`, an incomplete response, unavailable tooling, authentication failure, - or an ambiguous verdict is not a pass. - -## Security, privacy, and secrets - -- Never commit secrets, API keys, tokens, credentials, private certificates, or personal data. -- Maintain a comprehensive `.gitignore` for secrets, local environments, and temporary artifacts. -- Validate input sizes and payloads before running expensive operations. -- Treat dependency and code licensing as core release criteria. - -## Definition of agent-complete - -Work is ready for user review only when: - -- Milestone acceptance criteria are fully met; -- The branch contains only intended changes; -- Local checks and required GitHub checks pass; -- Review Gate A and Review Gate B pass for the current head commit; -- All blocking findings are fixed and re-reviewed; -- The draft PR has been marked ready, but not merged; -- The PR description details scope, risk, validation evidence, and both review verdicts; -- Documentation is updated and accurate. - -When handing off, report the branch, commit SHA, PR URL, checks run, review verdicts, -known limitations, and the exact decision required from the user. +- Branch from current `develop`; target `develop` from short-lived + `feature/*`, `fix/*`, or `milestone/*` branches unless the user explicitly + names another short-lived branch. +- Never direct-push or force-push protected branches or rewrite shared history + without explicit user authorization. +- Follow `.agent/IMPLEMENTATION_LOOP.md` for local checks, staged-tree identity, + both independent FreePi reviews, CI, PR readiness, and invalidation rules. +- Only explicit `VERDICT: PASS` passes a gate. Missing, ambiguous, truncated, + stale, unauthenticated, or failed review output fails closed. +- Agents never merge a PR. A human reviews and explicitly authorizes the merge. + +## Context retention + +Follow `.agent/context/README.md`. Update the active record at milestone +boundaries, before handoff/session end, and before deliberate context reset or +compaction when possible. Never store secrets there. + +## Agent-complete + +Handoff only after intended scope is complete, local checks pass, the diff is +cleanly scoped, and current gate state is recorded. A change is ready for human +review only after Gate A, required CI, and Gate B pass for the exact applicable +tree/head. Report branch, commit, PR, checks, gate evidence, and remaining +risks. Never merge. diff --git a/.agent/IMPLEMENTATION_LOOP.md b/.agent/IMPLEMENTATION_LOOP.md new file mode 100644 index 0000000..cdca5e6 --- /dev/null +++ b/.agent/IMPLEMENTATION_LOOP.md @@ -0,0 +1,144 @@ +# OneShot Implementation Loop + +This is the required path from a focused change to human review. `develop` is +the base. Gate A binds to one immutable candidate tree before the first push; +Gate B binds to the exact draft-PR head SHA and the same tree after required CI. + +## 1. Scope and branch + +1. Start from current `develop`. +2. Create one short-lived `feature/*`, `fix/*`, or `milestone/*` branch unless + the user explicitly names another short-lived branch. +3. Record goal, acceptance criteria, assumptions, non-goals, and branch state in + `.agent/context/`. +4. Never implement directly on `develop` or `main`. + +## 2. Implement and validate + +1. Make the smallest coherent change. +2. Use applicable repo skills and `.agent/TEST_MATRIX.md`. +3. Run local format, lint, type, test, build, and focused failure-injection + checks that exist for affected components. +4. Inspect tracked, staged, unstaged, ignored, and intended untracked changes + for scope, generated files, secrets, and unrelated work. Never open or send + ignored secret files to a reviewer. +5. Stage every intended file and only intended files. Gate A reviews a single + candidate tree, not a partially staged workspace. +6. Record concise command/result evidence in the active context. Keep full logs + only for failures that require diagnosis. + +Do not bypass failures with force flags, skipped checks, broad ignores, lower +thresholds, or disabled hooks. + +## 3. Capture immutable Gate A evidence + +Refresh the base and record exact identities: + +```bash +git fetch origin develop +git rev-parse origin/develop +git write-tree +git status --short +git diff --cached --check +git diff --cached +``` + +- `recorded-base-sha` is the printed full SHA, not a moving ref. +- `git write-tree` is the candidate tree SHA. +- For an already-created but unpushed merge commit, use + `git rev-parse "HEAD^{tree}"` and `git diff HEAD`; the + commit must have no additional workspace changes. +- Confirm no intended change is absent from the candidate and no unrelated file + is present. + +## 4. FreePi Gate A: pre-push review + +1. From the repository root, start exactly one fresh process: + + ```bash + npx free-pi-cli + ``` + +2. In one message, tell the new session to read + `.agent/review-prompts/freepi-prepush-review.md`; provide only the task + acceptance criteria, recorded base SHA, candidate tree SHA, and whether the + tree is staged or the exact unpushed `HEAD` tree. +3. Let the reviewer inspect the candidate diff and routed repository documents + with its tools. Do not paste duplicate policy, complete file bodies, repeated + terminal output, or secrets into the prompt. +4. Accept only an explicit `VERDICT: PASS` containing the required reviewer, + model, base, target, and tree identities. + +Each attempt uses a new `npx free-pi-cli` process. Never resume or reuse a +reviewer context. Any candidate-tree change invalidates Gate A and requires +local checks plus a new process. Missing evidence, ambiguity, truncation, +authentication/tool failure, or any verdict other than explicit PASS fails +closed. + +## 5. Commit, push, and draft PR + +Only after Gate A passes for the candidate tree: + +1. If the tree is staged, commit it without changing content. If Gate A reviewed + an existing unpushed commit, do not amend it. +2. Confirm `git rev-parse "HEAD^{tree}"` equals the reviewed candidate tree. +3. Push the short-lived branch without force. +4. Create a draft PR targeting `develop`, never `main` for feature work. +5. Fill `.github/PULL_REQUEST_TEMPLATE.md`, including Gate A evidence. + +## 6. Required CI + +Wait for every required check on the exact draft-PR head SHA. Pending, skipped, +missing, or failing required checks are not green. + +If a fix changes content, rerun local validation and fresh Gate A, commit, push, +and wait for CI again. + +## 7. FreePi Gate B: exact PR review + +1. Capture PR URL/number, base, head branch, exact full head SHA, head tree SHA, + full diff, required check results, and Gate A candidate tree. +2. Start a second fresh process from the repository root: + + ```bash + npx free-pi-cli + ``` + +3. In one message, tell it to read + `.agent/review-prompts/freepi-pr-review.md` and provide only the captured + identities, PR URL, concise CI summary, acceptance criteria, and Gate A + verdict. Let the reviewer obtain the diff and public evidence with tools. +4. Accept only explicit `VERDICT: PASS` bound to the exact current PR head SHA + whose tree equals the Gate A candidate tree. + +Any content change after Gate B invalidates both tree equality and Gate B. +Return to local validation, fresh Gate A, commit/push, green CI, then fresh Gate +B. + +## 8. Human review and merge + +After Gate A, required CI, and Gate B pass for the current tree/head: + +1. Record both verdicts and evidence in the PR and context file. +2. Mark the draft ready for human review. +3. Report branch, SHA, tree SHA, PR URL, checks, gates, and residual risks. +4. Stop. Agents never merge; only a human may authorize and perform the merge. + +## Review token discipline + +- Canonical policy is linked, not copied into tool adapters or review prompts. +- Send each reviewer one compact instruction message. The reviewer reads only + documents routed by root `AGENTS.md` and files relevant to the diff. +- Reference immutable Git identities and concise check results instead of + pasting whole diffs, policy files, or successful logs into chat. +- Reviewers inspect silently and return one structured verdict. They do not + narrate file reads, repeat the task, or restate unchanged policy. +- Never reduce scope, skip evidence, or hide failures to save tokens. Token + discipline removes duplication, not review coverage. + +## Privacy boundary + +FreePi may review the candidate diff, tests, public documentation, and +non-sensitive check evidence only. Never provide `.env*`, ignored files, +private keys, seed phrases, access tokens, API secrets, wallet credentials, or +sensitive runtime configuration. If safe review is impossible, fail the gate. diff --git a/.agent/MILESTONE_IMPLEMENTATION_LOOP.md b/.agent/MILESTONE_IMPLEMENTATION_LOOP.md deleted file mode 100644 index 0cb89a3..0000000 --- a/.agent/MILESTONE_IMPLEMENTATION_LOOP.md +++ /dev/null @@ -1,190 +0,0 @@ -# Milestone Implementation Loop - -This is the mandatory lifecycle for every milestone and feature implementation in OneShot. -Gate A is bound to reviewed file content against the base branch (`develop`). -Gate B and final readiness are bound to the exact pull-request head commit. - -## Lifecycle - -```mermaid -flowchart LR - A["Phase 1: Scope milestone"] --> B["Phase 2: Implement"] - B --> C["Phase 3: Local validation"] - C --> D["Phase 4: Review Gate A"] - D -->|"FAIL"| B - D -->|"PASS"| E["Phase 5: Commit and create draft PR"] - E --> F["Phase 6: Required CI"] - F -->|"FAIL"| B - F -->|"PASS"| G["Phase 7: Review Gate B"] - G -->|"FAIL"| B - G -->|"PASS"| H["Phase 8: Mark ready for user"] - H --> I["User review"] - I -->|"Changes requested"| B - I -->|"Approved"| J["User-authorized merge"] -``` - -## Phase 1 - Scope the milestone - -Create an implementation plan / proposal record containing: - -- Outcome and user value; -- Acceptance criteria; -- In-scope and out-of-scope behavior; -- Affected components and interfaces; -- Test and measurement plan; -- Security, privacy, operational, and cost risks; -- Rollback or safe-disable strategy. - -Exit gate: The work is scoped small enough for one focused pull request and has -objective, testable acceptance criteria. - -## Phase 2 - Implement - -1. Create a branch from the latest base branch (`develop`): - ```bash - git checkout develop - git pull origin develop - git checkout -b feature/ - ``` - Use `fix/` or `milestone/-` when appropriate. -2. Make the smallest coherent change satisfying the milestone. -3. Add or update tests and documentation alongside code. -4. Inspect the full workspace diff (`git status`, `git diff`, untracked files) - for scope drift, generated files, secrets, and unrelated edits. -5. Stage only the complete intended candidate. Leave no intended change - unstaged or untracked before Gate A. - -The implementation may remain uncommitted through Gate A. Do not push a branch -or create a PR yet. - -Exit gate: The workspace contains one coherent candidate change and no unrelated work. - -## Phase 3 - Local validation - -Run repository validation commands from the project root: - -```bash -# Execute local quality checks (lint, format check, type check, test suites) -``` - -Record each command and its result. Fix failures and repeat until clean. Do not -classify an expected failure as a pass. - -Exit gate: All applicable local checks pass for the current workspace content. - -## Phase 4 - Review Gate A: workspace implementation review - -Refresh the base, then copy the two printed SHAs into the review evidence: - -```bash -git fetch origin develop -git rev-parse origin/develop -git write-tree -git diff --cached -``` - -`` is the immutable output from `git rev-parse -origin/develop`, not the mutable remote-tracking ref itself. - -Run a fresh, read-only independent review session using -`.agent/review-prompts/implementation-review.md`. Any capable review tool may be -used. Record its tool and platform-reported model name. -If the platform does not expose a model identifier, record -`not exposed by platform`. - -The reviewer evaluates: -- Complete staged candidate tree against the recorded `develop` SHA; -- Acceptance criteria coverage; -- Edge cases, error handling, regressions; -- Security, secrets, and licensing; -- Test adequacy and architecture fit. - -Gate decision: -- `PASS`: No blocking correctness, security, data-loss, architecture, test, or - acceptance-criteria findings. -- `FAIL`: At least one blocking finding, missing evidence, incomplete review, or - ambiguous verdict. - -On `FAIL`, resolve every blocking finding, rerun local validation, and repeat Gate A -in a fresh session. - -Exit gate: Gate A returns an explicit `VERDICT: PASS` containing reviewer tool, -model, base SHA, and candidate tree SHA. - -## Phase 5 - Commit and create draft pull request - -Only after Gate A passes: - -1. Confirm `git write-tree` still equals the reviewed candidate tree SHA. -2. Commit the reviewed staged change without modifying its content. -3. Confirm `git rev-parse "HEAD^{tree}"` equals the reviewed candidate tree SHA. -4. Push the branch to origin: - ```bash - git push -u origin HEAD - ``` -5. Create a **draft** pull request against `develop`. -6. Fill out `.github/PULL_REQUEST_TEMPLATE.md` with: - - Milestone outcome & scope; - - Acceptance criteria checklist; - - Risk assessment; - - Validation evidence; - - Review Gate A verdict and reviewer evidence. -7. Keep the pull request in draft state. - -Exit gate: The draft PR is created against `develop` with complete Gate A evidence. - -## Phase 6 - Required CI - -Wait for all required GitHub Actions checks to finish on the draft PR head commit. - -If CI fails or requires a content change: -1. Fix the issue locally; -2. Rerun local validation (Phase 3); -3. Rerun Review Gate A (Phase 4) for the updated content; -4. Commit, push, and wait for CI. - -Exit gate: All required status checks are green for the exact PR head commit. - -## Phase 7 - Review Gate B: exact draft PR review - -Gate B runs in an independent reviewer session after CI passes, evaluating the draft PR -using `.agent/review-prompts/draft-pr-review.md`. - -Gate B may use any capable review tool, including a different tool from Gate A. -It must run in a fresh read-only session and record its tool and -platform-reported model, or `not exposed by platform`. - -The reviewer independently inspects: -- PR title, description, and diff against `develop`; -- Commits and file changes; -- Required CI status and check logs; -- Gate A evidence and resolution of earlier findings; -- Equality of the PR head tree and Gate A candidate tree; -- Merge readiness and residual risks. - -On `FAIL`, return to Phase 2. Any content change requires rerunning Phases 3 through 7. - -Exit gate: Gate B returns an explicit `VERDICT: PASS` for the exact current PR head SHA. - -## Phase 8 - Ready for user review - -After Gate A, CI, and Gate B all pass: - -1. Add the Gate B verdict and evidence link to the PR description or comment. -2. Mark the draft pull request as ready for review (`gh pr ready `). -3. Notify the user with: - - Branch name & head commit SHA; - - PR URL; - - Checks run & Gate A / B verdicts; - - Known limitations or risks. -4. Stop. **Do not merge.** - -The user performs the final review and explicitly decides whether to merge into `develop`. - -## Fail-closed conditions - -Do not advance a gate when: -- Review output is truncated or lacks an explicit `VERDICT: PASS`; -- Target base branch or PR head SHA is ambiguous; -- Required CI is missing, pending, skipped, or failing; -- Unresolved blocking findings remain. diff --git a/.agent/PROJECT_CONTEXT.md b/.agent/PROJECT_CONTEXT.md new file mode 100644 index 0000000..1189146 --- /dev/null +++ b/.agent/PROJECT_CONTEXT.md @@ -0,0 +1,73 @@ +# OneShot Project Context + +## Product statement + +`One job. Many retries. One settlement.` + +OneShot executes an approved business obligation safely despite retries, +crashes, lost responses, parallel workers, or multiple agent instances. + +The core cardinality is: + +`1 intent / N attempts / <=1 committed settlement` + +This document defines ownership and vocabulary. It is not a product +implementation plan. + +## System ownership + +- OneShot is authoritative for business-intent execution state, attempt state, + settlement state, and permission to create another external settlement. +- Privy is the corporate wallet and scoped authorization boundary. OneShot must + use its policies and spending permissions on the normal execution path. +- Arc is the real USDC settlement rail used by the demo. +- The Graph supplies live indexed recovery/history context and agent decision + support after ambiguous outcomes. It can corroborate or locate activity, but + cannot authorize a duplicate payment. + +When an external submission may have happened but the result is uncertain, +OneShot records `UNKNOWN` and reconciles. Missing Graph data never converts +`UNKNOWN` into permission to submit again. + +## Glossary + +### Business Intent + +The durable identity of one approved business obligation. Its +`business_intent_id` remains stable across retries, process restarts, queue +redelivery, parallel workers, and multiple agents. Payload differences do not +create a second settlement right when the identifier is the same. + +### Attempt + +One execution try for a Business Intent. Attempts are expendable and may fail or +repeat. Any number of Attempts can belong to one Business Intent. + +### Settlement + +The committed external USDC payment for a Business Intent. A Business Intent may +have zero or one committed Settlement, never more than one. + +### Reconciliation + +The process that resolves an ambiguous external effect using durable local +state, provider identifiers and receipts, Arc state, and indexed evidence. +Reconciliation precedes any decision to retry payment when settlement state is +`UNKNOWN`. + +### Recovery View + +A derived, non-authoritative view assembled from durable OneShot records and +live indexed history, including The Graph. It helps operators and agents explain +and recover work but does not grant permission to create a Settlement. + +## Decision test + +Any design affecting retries or payments must answer: + +1. What stable Business Intent does this Attempt belong to? +2. Which durable atomic transition grants the right to submit an external + Settlement? +3. How is an ambiguous submission reconciled without a blind retry? +4. How do parallel workers converge on at most one committed Settlement? +5. Which evidence is authoritative, and which evidence is only a Recovery View? diff --git a/.agent/SECURITY_INVARIANTS.md b/.agent/SECURITY_INVARIANTS.md new file mode 100644 index 0000000..c9c8aa3 --- /dev/null +++ b/.agent/SECURITY_INVARIANTS.md @@ -0,0 +1,55 @@ +# OneShot Security Invariants + +These rules fail closed. A feature, demo, or deadline does not override them. + +## Settlement safety + +- One Business Intent produces at most one committed Settlement. +- Persist a stable `business_intent_id` before any external effect. +- Use durable, atomic, concurrency-safe transitions for settlement ownership. +- A timeout, crash, disconnect, lost response, or provider error after possible + submission creates `UNKNOWN`; reconcile before any payment retry. +- Never infer non-payment from an empty or delayed Graph result. +- Preserve a successful payment result even if a later supplier or API step + fails. +- Do not offer a normal code path that bypasses OneShot state controls or Privy + authorization. + +## Money and authorization + +- Store, compare, calculate, and serialize money as integer atomic units or + `bigint`. Never use JavaScript floating point for monetary values. +- Validate asset, network, recipient, amount, and policy scope before signing or + submitting. +- Privy denial, expired authorization, or an amount above policy produces no + settlement. +- Default to testnet. A non-testnet operation requires explicit user + authorization for that operation. + +## Secrets and privacy + +- Never log, display, persist in context files, commit, or transmit private keys, + seed phrases, access tokens, API secrets, wallet credentials, signing material, + or sensitive runtime configuration. +- Keep secrets in approved runtime secret stores or ignored local environment + files. Commit only safe examples with placeholder values. +- Review staged and untracked files for secret material before every commit. +- FreePi receives only code, intended diffs, tests, public documentation, and + non-sensitive validation evidence. It must not read or receive `.env*`, local + credentials, wallet files, ignored files, or sensitive runtime configuration. +- If a review cannot be completed without sensitive data, the review fails. Do + not send the data. + +## Dependencies and boundaries + +- Prefer official SDKs and primary documentation for Privy, Arc, and The Graph. +- Pin and review dependencies in line with repository conventions. +- Validate all untrusted external data at adapter boundaries. +- Treat provider and indexer output as evidence with explicit freshness and + finality limits, not as implicit authorization. + +## Required response to doubt + +Stop external effects when identity, authorization, amount, network, prior +submission, or settlement state is ambiguous. Persist evidence, enter a safe +state, and reconcile or request human input. diff --git a/.agent/SPONSOR_REQUIREMENTS.md b/.agent/SPONSOR_REQUIREMENTS.md new file mode 100644 index 0000000..6116c2f --- /dev/null +++ b/.agent/SPONSOR_REQUIREMENTS.md @@ -0,0 +1,40 @@ +# Sponsor Requirements + +Use this document before sponsor-facing implementation, demo preparation, +release, or submission claims. + +## Privy + +- Privy must be core corporate wallet authorization, not login-only branding. +- The working path must demonstrate scoped authorization, policies, or spending + permissions that constrain settlement. +- Policy denial or an amount above policy must produce zero settlement. +- The normal agent path must not bypass Privy authorization. + +## Arc + +- The demo must execute a real USDC settlement on the authorized Arc testnet. +- Showing an Arc network label, wallet address, explorer page, or mocked payment + alone does not qualify. +- OneShot must retain the settlement identity and result through retries and + downstream failures. + +## The Graph + +- The integration must use live indexed data for recovery, history, or agent + decision support. +- The demo should show how indexed evidence helps resolve or explain an + ambiguous outcome. +- The Graph must never be the sole duplicate-payment lock, authoritative intent + state, or proof that another settlement may be submitted. +- Empty results and indexing delay must preserve safe behavior. + +## Claim standard + +Do not state or imply sponsor qualification unless the integration exists in +working code and the demo proves the required behavior. Plans, placeholders, +mockups, environment variables, dependency declarations, and network labels are +not implementation evidence. + +Use the `sponsor-qualification` skill to report each sponsor as `QUALIFIED`, +`NOT QUALIFIED`, or `NOT VERIFIED`, with code, test, and demo evidence. diff --git a/.agent/TEST_MATRIX.md b/.agent/TEST_MATRIX.md new file mode 100644 index 0000000..8d60369 --- /dev/null +++ b/.agent/TEST_MATRIX.md @@ -0,0 +1,33 @@ +# OneShot Test Matrix + +Select every applicable case for changes to intents, retries, workers, queues, +payments, settlements, reconciliation, Privy, Arc, or The Graph. Prefer tests at +the public domain boundary plus focused adapter tests. A test must assert durable +state and external settlement count, not only an HTTP response. + +| Case | Fault or concurrency setup | Required result | +| --- | --- | --- | +| Normal job | One valid intent and one worker | Exactly 1 committed settlement | +| Same request twice | Deliver identical request twice | Exactly 1 committed settlement | +| Conflicting payload, same ID | Different request payloads share one `business_intent_id` | At most 1 committed settlement; conflict is explicit | +| Sequential retry storm | Run 10 sequential attempts for one intent | Exactly 1 committed settlement | +| Parallel worker storm | Run 10 workers concurrently for one intent | Exactly 1 committed settlement | +| Crash before submission | Kill process before any external submission | 0 settlements; retry is allowed from durable state | +| Crash after submission | Kill process after possible submission but before local confirmation | Enter `UNKNOWN`; reconcile; no blind retry | +| Lost payment response | Payment succeeds but HTTP response is lost | Exactly 1 committed settlement after reconciliation | +| Graph delay or absence | The Graph temporarily returns nothing or lags | No duplicate settlement; absence is not non-payment proof | +| Privy denial | Policy denies or amount exceeds permission | 0 settlements and explicit authorization failure | +| Service restart | Restart after durable intent creation or in-flight work | Intent and settlement state survive; invariant holds | +| Downstream failure after payment | Supplier/API step fails after settlement | Payment result remains durable; no replacement payment | +| Two agent instances | Same business obligation reaches two agents | Exactly 1 committed settlement | + +## Cross-cutting assertions + +- `business_intent_id` is stable across all attempts. +- Monetary values use integer atomic units or `bigint` end to end. +- State transitions are atomic under real concurrency, not only mocked sequence. +- External submission identifiers and reconciliation evidence survive restart. +- Logs and test fixtures contain no real secrets or wallet material. +- Tests use testnet or isolated fakes; never create unauthorized mainnet effects. + +Record selected cases and results in the session context and pull request. diff --git a/.agent/context/20260906T115948Z-agents-setup.md b/.agent/context/20260906T115948Z-agents-setup.md new file mode 100644 index 0000000..42511ea --- /dev/null +++ b/.agent/context/20260906T115948Z-agents-setup.md @@ -0,0 +1,107 @@ +# Session Context: Agent Infrastructure Setup + +## Date/time + +- UTC: 2026-09-06T11:59:48Z + +## User goal + +Create the `agents-setup` branch from current `develop` and install durable, +OneShot-specific agent policy, skills, context retention, and two independent +FreePi review gates without merging to `develop` or `main`. + +## Original prompt/request + +High-fidelity restatement: work directly in `SuPuHe/OneShot`; preserve the +OneShot invariant `1 business intent -> at most 1 committed settlement`; encode +Privy, Arc, and The Graph ownership; remove superseded review tooling; use two fresh fail-closed +FreePi reviews through actual `npx free-pi-cli` syntax; add project context, +security, sponsor, test, PR, branch, review-prompt, and retention docs; install +the eight selected `mattpocock/skills` plus token-saving Caveman; create three +repo skills; validate, commit, push, and create a draft PR only after Gate A. +Follow-up clarified that the repository is `/home/supuhe/OneShot` in WSL and +Caveman means the token-saving coding-agent skill. + +## Assumptions + +- The user-authorized branch name `agents-setup` is a naming exception only; + all other branch and review rules remain mandatory. +- This task creates agent infrastructure only and no product `plan.md`. +- User-level skills belong in WSL user scope; repo-specific skills belong in + `.agents/skills` per current OpenAI documentation. + +## Plan + +1. Install and verify selected user-level skills. +2. Create `agents-setup` from updated `origin/develop`. +3. Replace stale agent/review policy and add durable context plus repo skills. +4. Validate content and scripts; inspect complete diff. +5. Run fresh FreePi Gate A, fix and repeat until explicit pass. +6. Commit, push, open draft PR to `develop`, wait for required CI, then run fresh + Gate B if CI and available tooling permit. + +## Key decisions + +- Use `.agents/skills` for repo skills because current official Codex docs scan + that path. +- Use `JuliusBrussee/caveman`, not unrelated projects named Caveman, because it + explicitly provides token-saving Codex communication mode. +- Do not install optional `code-review`; FreePi remains the only mandatory Gate + A/B mechanism and generic review could confuse evidence. +- Start each review with bare `npx free-pi-cli`; its 0.2.19 help exposes no review + flags and states every invocation creates a fresh session. + +## Files/components touched + +- Agent policy, context, security, sponsor requirements, test matrix, review + prompts, branch/PR policy, secret ignores, context helper, and repo skills. + +## Commands/checks + +- `git fetch origin develop` - passed; base `6ea00fd0257fb6531184dab7104bacd7a1100b7a`. +- `npx skills add ... --global --agent codex` - installed eight Matt Pocock + skills and Caveman. +- `npx skills list --global --agent codex --json` - all nine discovered. +- `npx free-pi-cli --help` - confirmed interactive command convention. +- `bash -n .agent/context/new-session.sh` - passed. +- Isolated `new-session.sh smoke-test` - created an exact template copy; passed. +- `quick_validate.py` for all three repo skills - passed. +- `git diff --cached --check` - passed. +- Stale review-tool/name search and `plan.md` search - passed; no matches. +- Repository contains policy/docs only, so no application lint, type, test, or + build command exists yet. + +## External-doc findings + +- Official OpenAI Codex docs: repo skills use `.agents/skills//SKILL.md`; + Codex scans from working directory to repository root. +- `skills` CLI 1.5.23 installed selected skills from `mattpocock/skills` HEAD + `3cca18b368ae95cdbdebbff572ccafa662551015` and + `JuliusBrussee/caveman` HEAD + `5184b3d11ac6a1acb7d44b9bfaa31698157cff97` observed at install time. +- `free-pi-cli` 0.2.19 supports `npx free-pi-cli`, `logout`, `--version`, and + `--help`; its README says each run starts a fresh session. + +## Unresolved questions + +- Whether FreePi authentication is already complete and can return a valid Gate + A verdict. +- GitHub CLI is not installed; use an authenticated GitHub web flow after push. + +## Git and PR state + +- Branch: `agents-setup` +- Base: `develop` at `6ea00fd0257fb6531184dab7104bacd7a1100b7a` +- Commit: uncommitted +- PR: not created +- CI: not run + +## Review gates + +- Gate A: NOT RUN +- Gate B: NOT RUN; requires draft PR and green required CI + +## Handoff/next steps + +1. Apply and validate repository changes. +2. Run Gate A in a fresh FreePi process without exposing sensitive files. diff --git a/.agent/context/20260906T134707Z-product-plan.md b/.agent/context/20260906T134707Z-product-plan.md new file mode 100755 index 0000000..89babea --- /dev/null +++ b/.agent/context/20260906T134707Z-product-plan.md @@ -0,0 +1,88 @@ +# Session Context: Product Implementation Plan + +## Date/time + +- UTC: 2026-09-06T13:47:07Z + +## User goal + +Create a detailed `plan.md` with milestones for exactly three people, minimize cross-person blocking, defer frontend work until the end, run exactly one FreePi review after the plan is complete, and do not create a pull request. + +## Original prompt/request + +The user provided the `SuPuHe/OneShot` `agents-setup` branch URL, noted that the repository may also be found in WSL, requested use of all relevant planning skills, required a single FreePi review after plan creation, prohibited creating a PR, and requested English-only chat responses. + +## Assumptions + +- The application is greenfield because the current repository contains agent/repository policy but no product code. +- The first deliverable is a testnet backend plus minimal late-stage frontend, not a production mainnet system. +- Three implementers work in independent packages/worktrees and converge only after their isolated contract suites pass. +- The current task may add required research and durable context alongside `plan.md`; it does not commit, push, open a PR, or merge. + +## Plan + +1. Load repository policy and applicable repository/user skills. +2. Research current official Privy, Arc, The Graph, PostgreSQL, and worker behavior. +3. Write the cited integration decisions and a detailed three-person milestone plan. +4. Validate scope, links, Markdown, dependencies, invariants, and secrets. +5. Start exactly one fresh `npx free-pi-cli` process for a pre-push-style independent review. +6. Record/report the review result without creating a PR. + +## Key decisions + +- Use three parallel tracks: domain/storage/API; Privy/Arc settlement; reconciliation/The Graph/reliability. +- Freeze port results, state transitions, JSON fixtures, and test seams before implementation so M1–M3 have no cross-person blockers. +- Use PostgreSQL plus Graphile Worker; the queue is at-least-once, while database transitions remain authoritative. +- Use Arc Testnet's six-decimal ERC-20 USDC interface for payments and keep native USDC gas precision separate. +- Treat The Graph as freshness-labeled recovery/history evidence only. +- Begin frontend only after the integrated backend and failure matrix pass. + +## Files/components touched + +- `plan.md` — detailed product architecture, contracts, milestones, ownership, dependencies, tests, risks, and release gates. +- `.agent/research/20260906-integration-decisions.md` — primary-source integration research. +- `.agent/context/20260906T134707Z-product-plan.md` — this durable context record. + +## Commands/checks + +- `git branch --show-current` — `agents-setup`. +- `git status --short` before changes — clean. +- `git rev-parse develop` — `6ea00fd0257fb6531184dab7104bacd7a1100b7a`. +- Repository policy, security, sponsor, test-matrix, implementation-loop, context, and applicable skill documents — read completely. +- Primary-source research — completed; citations saved in the research note. +- Markdown structure, trailing-whitespace, placeholder, obvious-secret-pattern, ownership, dependency, and scope checks — passed. +- One fresh FreePi process/session reviewed `agents-setup` plus the three intended untracked files against `develop` — `VERDICT: PASS`; no blocking findings. +- FreePi non-blocking cautions: keep the cited research note with `plan.md`; external links were not live-revalidated by the reviewer; implementation evidence is intentionally unavailable at planning stage. +- No product lint/type/test/build command exists because the repository still contains no application code. + +## External-doc findings + +- Privy wallet policies constrain authorized wallet actions; request idempotency lasts 24 hours and is only a supplemental duplicate guard. +- Arc Testnet is `eip155:5042002`; ERC-20 USDC is `0x3600000000000000000000000000000000000000` at six decimals, while native USDC gas accounting uses a different precision. +- Arc receipt inclusion is deterministically final, but lost submission responses still require durable UNKNOWN reconciliation. +- The Graph supports `arc-testnet`; `_meta`, indexed block, deployment, health, and lag must accompany recovery evidence. +- PostgreSQL conditional transitions/constraints plus transactional Graphile work delivery fit the at-most-once settlement design. + +## Unresolved questions + +- Exact Node/TypeScript/SDK versions will be pinned after the M1 compatibility tests. +- Privy production webhook availability and Arc-specific rolling-spend policy behavior are optional and must be verified before enablement. + +## Git and PR state + +- Branch: `agents-setup` +- Base: `develop` at `6ea00fd0257fb6531184dab7104bacd7a1100b7a` +- Commit: current HEAD `a304274412f080817e6da2967e444b31ccd2f864`; new planning files uncommitted +- PR: not created by explicit user instruction +- CI: not run; no product code or CI exists yet + +## Review gates + +- Gate A: PASS for reviewed base `develop` (`6ea00fd0257fb6531184dab7104bacd7a1100b7a`) and target `agents-setup` (HEAD `a304274412f080817e6da2967e444b31ccd2f864`) plus `plan.md`, `.agent/research/20260906-integration-decisions.md`, and this context file as it existed before this review-evidence update. Blocking findings: none. This context-only bookkeeping update means the gate must be treated as invalid for any future push; the user limited this task to one review and prohibited a PR, so no rerun is permitted or needed here. +- Gate B: NOT RUN and not applicable because the user prohibited creating a PR. + +## Handoff/next steps + +1. Present `plan.md`, the research note, local validation, and the single FreePi PASS to the user. +2. Do not edit `plan.md`, rerun FreePi, commit, push, or create a PR in this task. +3. Before any future implementation, obtain human plan approval and merge the prerequisite planning/agent-infrastructure work to `develop` under normal repository policy. diff --git a/.agent/context/20260906T164444Z-merge-agent-workflow.md b/.agent/context/20260906T164444Z-merge-agent-workflow.md new file mode 100644 index 0000000..c9bc137 --- /dev/null +++ b/.agent/context/20260906T164444Z-merge-agent-workflow.md @@ -0,0 +1,77 @@ +# Session Context: Merge Unified Agent Workflow + +## Date/time + +- UTC: 2026-09-06T16:44:44Z + +## User goal + +Merge current `develop` into `agents-setup`, resolve the `.agent` conflicts, retain the agreed `.antigravity` and `.claude` integrations, remove redundant policy, reduce excessive review/check token usage where practical, finish the merge on `agents-setup`, and run a fresh independent FreePi review at the end. + +## Original prompt/request + +The user reported a teammate conflict in `.agent` that prevents a clean PR to `develop`. They requested comparison of `develop` and their setup branch, a merge into the setup branch with only necessary content retained, preservation of `.antigravity` and `.claude`, review-token optimization, and a final `npx free-pi-cli` review. + +## Assumptions + +- The actual branch name is `agents-setup` (plural), as shown by Git. +- `origin/develop` at `982b705` is the current integration source; local `develop` at `6ea00fd` is stale. +- OneShot-specific product, settlement, security, sponsor, test, context, and FreePi policies remain canonical because they encode stricter requirements absent from the generic workflow. +- `.antigravity` and `.claude` remain as thin adapters, not duplicate policy sources. +- The Agent policy workflow remains deterministic and does not invoke an AI model. + +## Key decisions + +- Merged `origin/develop` into `agents-setup` without rebasing or rewriting branch history. +- Kept root `AGENTS.md` and `.agent/AGENTS.md` as the canonical shared policy entry points. +- Preserved `.antigravity/README.md`, `.agents/rules/repository-policy.md`, and `.claude/CLAUDE.md` as short adapters that route to root policy. +- Kept the stricter OneShot-specific implementation loop and mandatory fresh FreePi Gate A/Gate B reviews. +- Removed the generic milestone loop, generic review prompts, and historical M0 workflow document because they duplicated or contradicted the canonical FreePi path. +- Kept a small GitHub Actions policy check that validates required files, adapters, obsolete-file removal, conflict markers, and whitespace without consuming model tokens. +- Reduced reviewer token waste through selective document routing, one compact request per fresh review, immutable Git identities instead of pasted diffs/logs, silent inspection, and one structured verdict. Coverage and fail-closed behavior remain unchanged. + +## Files/components touched + +- Canonical policy: `AGENTS.md`, `.agent/AGENTS.md`, `.agent/IMPLEMENTATION_LOOP.md`. +- Independent review: `.agent/review-prompts/freepi-prepush-review.md`, `.agent/review-prompts/freepi-pr-review.md`. +- Tool adapters: `.agents/rules/repository-policy.md`, `.antigravity/README.md`, `.claude/CLAUDE.md`. +- Repository controls: `.github/BRANCH_POLICY.md`, `.github/PULL_REQUEST_TEMPLATE.md`, `.github/workflows/agent-policy.yml`, `.gitignore`. +- Removed obsolete duplicates: `.agent/MILESTONE_IMPLEMENTATION_LOOP.md`, `.agent/milestones/M0_UNIFIED_AGENT_WORKFLOW.md`, `.agent/review-prompts/draft-pr-review.md`, `.agent/review-prompts/implementation-review.md`. + +## Commands/checks + +- `git fetch origin develop agents-setup` — PASS; `origin/develop` advanced to `982b705`. +- Branch/history/tree comparison — PASS; the working tree was clean before the merge. +- Applicable repository policy and merge-conflict skill — read completely. +- Merge conflict scan (`git diff --name-only --diff-filter=U`) — PASS; no unresolved paths. +- Staged whitespace/error scan (`git diff --cached --check`) — PASS. +- Agent policy validation (required files, adapters, obsolete paths, conflict markers, adapter size, shell syntax) — PASS after correcting repo-skill paths to `.agents/skills/*/SKILL.md`. +- Workflow YAML parse (`python3` with installed PyYAML) — PASS. + +## External-doc findings + +- None required; this is repository workflow reconciliation. + +## Unresolved questions + +- None. + +## Git and PR state + +- Branch: `agents-setup` +- Base/source merged: `origin/develop` at `982b705` +- Pre-merge HEAD: `b643206` +- Merge state: conflicts resolved and staged; merge commit pending final validation. +- PR: not created or modified. +- Push: not performed. + +## Review gates + +- Requested final independent review: pending until the merge commit exists, so it can bind to the exact unpushed commit tree. +- Gate B: NOT RUN; no PR was created or requested. + +## Handoff/next steps + +1. Revalidate the final staged tree and create the merge commit. +2. Run one fresh `npx free-pi-cli` review against the exact unpushed merge commit. +3. Report the verdict and immutable Git identities without modifying the reviewed tree or creating a PR. diff --git a/.agent/context/README.md b/.agent/context/README.md new file mode 100644 index 0000000..4a99e03 --- /dev/null +++ b/.agent/context/README.md @@ -0,0 +1,41 @@ +# Durable Session Context + +Store one Markdown record per meaningful work session so another agent can +continue after a context-window limit, handoff, interruption, or restart. + +## When to update + +- At milestone boundaries or after a material decision. +- Before handoff or end of session. +- Before a deliberate context reset or compaction, when possible. +- After checks, commits, pushes, PR changes, CI results, and Gate A/B results. + +Use `SESSION_TEMPLATE.md`. Keep one active record current rather than creating +many partial notes. Name it `YYYYMMDDTHHMMSSZ-short-topic.md` in UTC. + +To create a record without extra dependencies: + +```bash +.agent/context/new-session.sh short-topic +``` + +The helper copies the template and prints the path. Fill mandatory fields +immediately. Paste the exact original request when safe and practical; otherwise +write a high-fidelity restatement and link the issue or PR. + +## Mandatory fields + +Every record must include date/time, user goal, original prompt/request, +assumptions, plan, key decisions, files/components touched, commands/checks, +external-doc findings, unresolved questions, branch/commit/PR state, Gate A/B +state, and handoff/next steps. + +## Security + +NEVER store secrets or sensitive runtime configuration. Do not include `.env` +contents, private keys, seed phrases, tokens, API secrets, wallet credentials, +authentication responses, or private customer data. Redact sensitive command +output and record only the safe conclusion. + +Context files are operational memory, not authority. Current code, tests, Git +state, provider evidence, and repository policy remain authoritative. diff --git a/.agent/context/SESSION_TEMPLATE.md b/.agent/context/SESSION_TEMPLATE.md new file mode 100644 index 0000000..95d920c --- /dev/null +++ b/.agent/context/SESSION_TEMPLATE.md @@ -0,0 +1,58 @@ +# Session Context: + +## Date/time + +- UTC: + +## User goal + + + +## Original prompt/request + + + +## Assumptions + +- + +## Plan + +1. + +## Key decisions + +- + +## Files/components touched + +- + +## Commands/checks + +- `` - + +## External-doc findings + +- + +## Unresolved questions + +- + +## Git and PR state + +- Branch: +- Base: +- Commit: +- PR: +- CI: + +## Review gates + +- Gate A: +- Gate B: + +## Handoff/next steps + +1. diff --git a/.agent/context/new-session.sh b/.agent/context/new-session.sh new file mode 100755 index 0000000..7880f4f --- /dev/null +++ b/.agent/context/new-session.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -euo pipefail + +topic="${1:-session}" +if [[ ! "$topic" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then + printf 'Topic must use lowercase letters, digits, and hyphens.\n' >&2 + exit 2 +fi + +context_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +timestamp="$(date -u +%Y%m%dT%H%M%SZ)" +target="$context_dir/$timestamp-$topic.md" + +if [[ -e "$target" ]]; then + printf 'Context file already exists: %s\n' "$target" >&2 + exit 1 +fi + +cp "$context_dir/SESSION_TEMPLATE.md" "$target" +printf 'Created %s\n' "$target" diff --git a/.agent/milestones/M0_UNIFIED_AGENT_WORKFLOW.md b/.agent/milestones/M0_UNIFIED_AGENT_WORKFLOW.md deleted file mode 100644 index c01974a..0000000 --- a/.agent/milestones/M0_UNIFIED_AGENT_WORKFLOW.md +++ /dev/null @@ -1,43 +0,0 @@ -# M0: Unified agent workflow - -## Outcome - -Every contributor follows one repository workflow while remaining free to use -Codex, Claude, Antigravity, Cursor, or another capable agent. - -## Acceptance criteria - -- `AGENTS.md` and `.agent/` remain the only canonical shared policy. -- Tool-specific files point to canonical policy instead of copying it. -- Personal agent configuration is ignored. -- Gate A records reviewer, available model identity, exact base SHA, and - candidate tree SHA. -- Gate B records reviewer, available model identity, exact PR head SHA, and - equality with the Gate A candidate tree after required CI. -- Pull requests run a minimal `Agent policy` status check. -- Feature work targets `develop`; humans retain merge authority. - -## Scope - -In scope: shared policy, portable Git evidence, review prompts, PR evidence -fields, Antigravity adapter, ignore rules, and minimal policy CI. - -Out of scope: product implementation, selecting a mandatory review provider, -Windows-only automation, branch-protection mutation, and merging existing -`agents-setup` or Claude adapter branches. - -## Validation - -- Inspect complete diff against the recorded immutable `develop` base SHA. -- Confirm Markdown links and referenced paths exist. -- Confirm only intended files are staged. -- Run the policy workflow checks locally where practical. -- Run independent Gate A before commit and Gate B after draft PR checks. - -## Risks and rollback - -Risk: a tool may not auto-load `AGENTS.md`. Thin adapters handle known tools; -the PR template and human review expose missing gate evidence. - -Rollback: revert this documentation-only commit. No runtime or data migration -exists. diff --git a/.agent/research/20260906-integration-decisions.md b/.agent/research/20260906-integration-decisions.md new file mode 100755 index 0000000..f9554dc --- /dev/null +++ b/.agent/research/20260906-integration-decisions.md @@ -0,0 +1,49 @@ +# OneShot Integration Research + +Date: 2026-09-06 +Scope: primary-source facts needed to make the first product implementation plan decision-complete. +Target: Privy-authorized USDC settlement on Arc Testnet with The Graph as a non-authoritative recovery view. + +## Decisions + +### Privy: authorization must constrain the settlement path + +- Use a Privy execution wallet owned by an application authorization key or key quorum. Attach one explicit, fail-closed wallet policy when the wallet is created. Privy owners authorize wallet actions, while wallet policies constrain the actions that an otherwise valid signer may take ([wallet policies and controls](https://docs.privy.io/security/wallet-infrastructure/policy-and-controls), [execution wallets](https://docs.privy.io/recipes/wallets/execution-wallets)). +- Permit only the Arc Testnet ERC-20 USDC `transfer(address,uint256)` path: chain `5042002`, contract `0x3600000000000000000000000000000000000000`, approved recipient, amount at or below the configured cap, and zero native transaction value. Keep key export and all unrelated methods denied. Privy documents default-deny policy behavior and Ethereum transaction conditions ([policy overview](https://docs.privy.io/controls/policies/overview), [Ethereum policy examples](https://docs.privy.io/controls/policies/example-policies/ethereum)). +- Persist the exact Privy request identity and body before submission. Reuse the same `privy-idempotency-key` for the same Business Intent. Privy deduplicates a matching request for only 24 hours, so this is a supplemental guard and never replaces OneShot's durable state and uniqueness constraints ([idempotency keys](https://docs.privy.io/api-reference/idempotency-keys)). +- Attach a stable Privy transaction `reference_id` derived from `business_intent_id` for lookup and reconciliation, not as the authoritative duplicate lock ([transaction reference IDs](https://docs.privy.io/transaction-management/transactions/reference-id)). +- Polling transaction status is the baseline. Webhooks are an optional optimization because availability may depend on the Privy plan; if enabled, verify signatures and process deliveries idempotently ([webhook overview](https://docs.privy.io/api-reference/webhooks/overview)). + +### Arc: use the six-decimal ERC-20 interface for settlement + +- Arc Testnet uses chain ID `5042002`, CAIP-2 `eip155:5042002`, RPC `https://rpc.testnet.arc.network`, WebSocket `wss://rpc.testnet.arc.network`, and explorer `https://testnet.arcscan.app` ([RPC endpoints](https://docs.arc.io/arc/references/rpc-endpoints)). +- Arc's USDC ERC-20 interface is `0x3600000000000000000000000000000000000000`. Application settlement amounts use its six-decimal precision. Arc also exposes the same underlying USDC as an 18-decimal native gas balance, so payment amounts and gas accounting must remain separate and the UI must not double-count the two views ([infrastructure integration](https://docs.arc.io/integrate/infrastructure), [stablecoin-native model](https://docs.arc.io/arc/concepts/stablecoin-native-model)). +- Arc transactions are pending until included, then immediately and deterministically final; there is no accumulating-confirmation state. A receipt with `status: 1` is final success only after validating the expected USDC `Transfer` log. A receipt with `status: 0` is final execution failure and zero settlement ([transaction lifecycle](https://docs.arc.io/integrate/wallets/transaction-lifecycle), [deterministic finality](https://docs.arc.io/arc/concepts/deterministic-finality)). +- Deterministic finality does not eliminate submission ambiguity. A lost Privy/RPC response or process crash after a possible broadcast still becomes `UNKNOWN`; a new-nonce payment is forbidden until reconciliation proves a safe terminal result. + +### The Graph: live recovery evidence, never settlement authority + +- The Graph lists Arc Testnet as `arc-testnet`, protocol Ethereum, CAIP-2 `eip155:5042002` ([Arc Testnet support](https://thegraph.com/docs/en/supported-networks/arc-testnet/)). +- Build a custom Subgraph over the unified USDC `Transfer` event. Identify each event by transaction hash plus log index and retain block number, block timestamp, sender, recipient, and amount as Graph `BigInt` ([Arc event indexing](https://docs.arc.io/integrate/infrastructure/indexing-events), [Subgraph quick start](https://thegraph.com/docs/en/subgraphs/quick-start/)). +- Every query must request `_meta` block data, deployment ID, and `hasIndexingErrors`. Operational health must also compare indexed `latestBlock` with `chainHeadBlock`; `synced` only means the deployment caught up at least once ([GraphQL API](https://thegraph.com/docs/en/subgraphs/querying/graphql-api/), [indexing health](https://thegraph.com/docs/en/subgraphs/developing/deploying-publishing/multiple-networks/)). +- Missing, empty, lagging, or unhealthy indexed results mean only that no matching event was observed through a known indexed block. They never prove non-payment or authorize another submission. Direct Arc receipts plus durable OneShot state remain authoritative. +- Use a deployment-pinned query endpoint for schema-stable demo evidence. Do not claim sponsor qualification until a deployed endpoint returns live Arc data and lag/error behavior is demonstrated ([Subgraph ID versus deployment ID](https://thegraph.com/docs/en/subgraphs/querying/subgraph-id-vs-deployment-id/)). + +### Durable state and work delivery + +- PostgreSQL is the authoritative store. Use primary/unique constraints on `business_intent_id` and one settlement row per intent; use `INSERT ... ON CONFLICT` plus an immutable payload fingerprint to distinguish a replay from a same-ID conflict ([constraints](https://www.postgresql.org/docs/current/ddl-constraints.html), [`INSERT`](https://www.postgresql.org/docs/current/sql-insert.html)). +- Grant submission ownership with a row lock or conditional state transition. Do not keep a database transaction open during Privy or RPC calls. Persist `SUBMITTING`, the request fingerprint, and provider identifiers before crossing the external-effect boundary ([explicit locking](https://www.postgresql.org/docs/current/explicit-locking.html)). +- Use Graphile Worker over the same PostgreSQL database to avoid a second queue datastore. It supports transactional enqueueing and explicitly provides at-least-once delivery ([Graphile Worker](https://worker.graphile.org/docs), [transactional enqueueing](https://worker.graphile.org/docs/sql-add-job)). +- Configure the external-effect `submit_settlement` job for one queue attempt. The task itself classifies the outcome and returns after durably recording `COMMITTED`, `FAILED_SAFE`, or `UNKNOWN`; the queue must never blindly repeat a possibly submitted payment. Read-only reconciliation jobs may retry. `jobKey` is scheduling hygiene, not the settlement lock ([job options](https://worker.graphile.org/docs/library/add-job), [job-key caveats](https://worker.graphile.org/docs/job-key)). + +## Verification gates left for implementation + +1. Pin exact SDK and runtime versions only after a compatibility spike validates Privy request signing, Arc chain support, and policy condition syntax. +2. Assert `eth_chainId == 5042002` and bytecode exists at the configured USDC address during testnet startup checks. +3. Prove the chosen Privy policy denies wrong chain, wrong contract, wrong recipient, wrong method, non-zero native value, and above-cap amount with zero settlement. +4. Prove The Graph deployment health and lag thresholds against live Arc Testnet before sponsor qualification. +5. Keep Privy webhooks outside the critical path until plan availability and signature verification are demonstrated. + +## Planning consequence + +The work can be split into three independent backend tracks after one contract freeze: (A) domain/storage/API, (B) Privy/Arc settlement, and (C) indexing/reconciliation. Each track must ship its own contract simulator and tests so progress does not depend on another track's implementation. Frontend begins only after the integrated backend contract and recovery semantics are stable. diff --git a/.agent/review-prompts/draft-pr-review.md b/.agent/review-prompts/draft-pr-review.md deleted file mode 100644 index c3f4b49..0000000 --- a/.agent/review-prompts/draft-pr-review.md +++ /dev/null @@ -1,73 +0,0 @@ -# Review Gate B - Draft Pull Request Review - -You are the second independent senior reviewer. Review only; do not edit files, -commit, push, change pull-request state, leave comments, approve, merge, deploy, -or mutate any external system. -Do not attempt to fix a finding yourself. Report findings and return the required verdict. - -This must be a fresh review. Do not rely on memory or a resumed Gate A session. - -## Review target - -- Read the repository `AGENTS.md` and `.agent/AGENTS.md`. -- Verify draft pull request number, base branch (`develop`), head branch, and head SHA. -- Read the PR description, full GitHub PR diff, commits, required status checks, - and Review Gate A evidence. -- Confirm CI and Gate B evidence refer to the exact current PR head SHA. -- Gate A evidence is bound to its base SHA and candidate tree SHA. Verify the - current PR head tree equals the Gate A candidate tree before accepting it. - -## Required analysis - -Independently evaluate: -- Whether the PR delivers the stated milestone without hidden scope or creep; -- Every issue class evaluated in Gate A; -- Whether previous findings from Gate A were fully resolved; -- Whether CI covers changed behavior and all required checks are green; -- Whether documentation, config, and migration paths are complete; -- Whether the PR description provides sufficient detail for human review; -- Whether the current PR head tree and base still match Gate A evidence; -- Whether the PR is safe to mark ready for human review (not whether it should be merged). - -## Verdict standard - -Return `PASS` only if the exact draft head is ready for user review. A stale Gate A -verdict, failing CI, ambiguous evidence, or any blocking finding is `FAIL`. - -Use this exact structure: - -```text -VERDICT: PASS | FAIL -REVIEWER_TOOL: -REVIEWER_MODEL: -PR: -REVIEWED_HEAD: -REVIEWED_HEAD_TREE: -REVIEWED_BASE: develop () -GATE_A_TREE: - -BLOCKING_FINDINGS: -- - -- None - -NON_BLOCKING_FINDINGS: -- - -- None - -CI_AND_REVIEW_EVIDENCE: -- - -MILESTONE_READINESS: -- Scope and acceptance criteria - PASS | FAIL -- Tests and required checks - PASS | FAIL -- Security, privacy, and secrets - PASS | FAIL -- Documentation and operations - PASS | FAIL -- Ready for user review - PASS | FAIL - -RESIDUAL_RISKS: -- -- None - -SUMMARY: - -``` diff --git a/.agent/review-prompts/freepi-pr-review.md b/.agent/review-prompts/freepi-pr-review.md new file mode 100644 index 0000000..eaba6bd --- /dev/null +++ b/.agent/review-prompts/freepi-pr-review.md @@ -0,0 +1,80 @@ +# FreePi Gate B: Exact Draft-PR Review + +You are a second fresh, independent senior reviewer. Review only. Do not edit +files, commit, push, change PR state, comment, approve, merge, deploy, or mutate +external state. Do not fix findings and do not reuse Gate A context. + +## Safety boundary + +Inspect only repository-tracked files, the public PR/diff, tests, public +documentation, and non-sensitive CI/Gate A evidence. Never read or request +ignored files, `.env*`, private keys, seed phrases, tokens, API secrets, wallet +credentials, or sensitive runtime configuration. Fail closed if safe inspection +is impossible. + +## Target + +- Read root `AGENTS.md`, then only the policies and skills it routes. +- Verify PR number/URL, base `develop`, head branch, exact full head SHA, and head + tree SHA. +- Inspect the full PR diff, commits, description, required checks, Gate A + verdict, and resolved findings. +- Confirm the current head tree equals Gate A's candidate tree. + +## Review + +Independently evaluate milestone scope and acceptance coverage, all Gate A issue +classes, documentation/config/migrations, required CI, previous findings, +security/privacy, and readiness for human review. For settlement-related work, +enforce `.agent/SECURITY_INVARIANTS.md` and `.agent/TEST_MATRIX.md`. + +Return PASS only for the exact current head with green required CI, valid Gate A +evidence, equal tree identities, no blocking finding, and sufficient evidence. +Anything missing, ambiguous, stale, truncated, or failed is FAIL. + +Inspect with tools without narrating progress. Return one final structured +verdict; do not repeat file bodies, task text, or unchanged policy. Keep the +answer concise unless blocking findings require detail. + +Use exactly this structure: + +```text +VERDICT: PASS | FAIL +REVIEWER_TOOL: free-pi-cli +REVIEWER_MODEL: +PR: +REVIEWED_BASE: develop () +REVIEWED_HEAD: +REVIEWED_HEAD_TREE: +GATE_A_TREE: + +BLOCKING_FINDINGS: +- - +- None + +NON_BLOCKING_FINDINGS: +- - +- None + +CI_AND_REVIEW_EVIDENCE: +- + +MILESTONE_READINESS: +- Scope and acceptance criteria - PASS | FAIL +- Tests and required checks - PASS | FAIL +- Security, privacy, and secrets - PASS | FAIL +- Documentation and operations - PASS | FAIL +- Ready for human review - PASS | FAIL + +SECURITY_AND_INVARIANTS: +- One intent / at most one settlement - PASS | FAIL | NOT APPLICABLE +- UNKNOWN reconciles without blind retry - PASS | FAIL | NOT APPLICABLE +- Secrets and FreePi privacy boundary - PASS | FAIL + +RESIDUAL_RISKS: +- +- None + +SUMMARY: + +``` diff --git a/.agent/review-prompts/freepi-prepush-review.md b/.agent/review-prompts/freepi-prepush-review.md new file mode 100644 index 0000000..02dc1a1 --- /dev/null +++ b/.agent/review-prompts/freepi-prepush-review.md @@ -0,0 +1,76 @@ +# FreePi Gate A: Pre-Push Candidate Review + +You are a fresh, independent senior reviewer. Review only. Do not edit files, +stage, commit, push, create a PR, comment, approve, merge, deploy, or mutate +external state. Do not fix findings. + +## Safety boundary + +Inspect only repository-tracked files, the stated candidate tree/diff, tests, +public documentation, and non-sensitive check evidence. Never read or request +ignored files, `.env*`, private keys, seed phrases, tokens, API secrets, wallet +credentials, or sensitive runtime configuration. Fail closed if safe inspection +is impossible. + +## Target + +- Read root `AGENTS.md`, then only the policies, skills, and context it routes + for this change. +- Verify the recorded `develop` base is an exact full SHA. +- Verify the candidate tree SHA using the staged index or exact unpushed HEAD, + as stated by the caller. +- Inspect the complete candidate diff against the recorded base. +- Check status to confirm no intended file is omitted and no unrelated file is + included. + +## Review + +Evaluate acceptance coverage, correctness, regressions, state transitions, +error handling, security, privacy, secrets, concurrency, retry/idempotency, +external effects, money representation, architecture, dependencies, +documentation, and test adequacy. For settlement-related work, enforce +`.agent/SECURITY_INVARIANTS.md` and `.agent/TEST_MATRIX.md`. + +Return PASS only with no blocking finding and sufficient evidence. Incomplete, +ambiguous, stale, or failed inspection is FAIL. + +Inspect with tools without narrating progress. Return one final structured +verdict; do not repeat file bodies, task text, or unchanged policy. Keep the +answer concise unless blocking findings require detail. + +Use exactly this structure: + +```text +VERDICT: PASS | FAIL +REVIEWER_TOOL: free-pi-cli +REVIEWER_MODEL: +REVIEWED_BASE: develop () +REVIEWED_TARGET: +REVIEWED_TREE: + +BLOCKING_FINDINGS: +- - +- None + +NON_BLOCKING_FINDINGS: +- - +- None + +VALIDATION_EVIDENCE: +- + +ACCEPTANCE_CRITERIA: +- - PASS | FAIL | NOT VERIFIED + +SECURITY_AND_INVARIANTS: +- One intent / at most one settlement - PASS | FAIL | NOT APPLICABLE +- UNKNOWN reconciles without blind retry - PASS | FAIL | NOT APPLICABLE +- Secrets and FreePi privacy boundary - PASS | FAIL + +RESIDUAL_RISKS: +- +- None + +SUMMARY: + +``` diff --git a/.agent/review-prompts/implementation-review.md b/.agent/review-prompts/implementation-review.md deleted file mode 100644 index bd2b776..0000000 --- a/.agent/review-prompts/implementation-review.md +++ /dev/null @@ -1,63 +0,0 @@ -# Review Gate A - Implementation Review - -You are an independent senior reviewer. Review only; do not edit files, commit, -push, create pull requests, comment on GitHub, or mutate repository state. -Do not attempt to fix a finding yourself. Report findings and return the required verdict. - -## Review target - -- Read the repository `AGENTS.md` and `.agent/AGENTS.md`. -- Target base branch: `develop` (or designated milestone base). -- Review the complete staged candidate tree against the recorded base SHA. -- Verify `git status` contains no intended unstaged or untracked change omitted - from the candidate. -- Read the milestone acceptance criteria, requirements, and relevant docs. - -## Required analysis - -Review for: -- Correctness and acceptance-criteria coverage; -- Regressions, edge cases, state transitions, and error handling; -- Security, input validation, secrets, and data safety; -- Concurrency, retry, idempotency, and API boundaries; -- Code clarity, architectural fit, and scope discipline; -- Test adequacy (coverage of new behavior and regressions); -- Configuration, dependencies, and environment assumptions; -- Secrets, credentials, or generated files accidentally tracked. - -## Verdict standard - -Return `PASS` only when there are no blocking findings and evidence is sufficient. -Missing evidence, an ambiguous diff, or an incomplete review is `FAIL`. - -Use this exact structure: - -```text -VERDICT: PASS | FAIL -REVIEWER_TOOL: -REVIEWER_MODEL: -REVIEWED_TARGET: -REVIEWED_BASE: develop () -REVIEWED_TREE: - -BLOCKING_FINDINGS: -- - -- None - -NON_BLOCKING_FINDINGS: -- - -- None - -VALIDATION_EVIDENCE: -- - -ACCEPTANCE_CRITERIA: -- - PASS | FAIL | NOT VERIFIED - -RESIDUAL_RISKS: -- -- None - -SUMMARY: - -``` diff --git a/.agents/rules/repository-policy.md b/.agents/rules/repository-policy.md index d67dd0e..80f402c 100644 --- a/.agents/rules/repository-policy.md +++ b/.agents/rules/repository-policy.md @@ -1,11 +1,5 @@ -# OneShot repository policy +# OneShot repository policy adapter -Load and follow these canonical repository policies before planning, editing, -reviewing, committing, pushing, or opening a pull request: +Load and follow `@../../AGENTS.md` before changing this repository. -@../../AGENTS.md -@../../.agent/AGENTS.md -@../../.agent/MILESTONE_IMPLEMENTATION_LOOP.md - -This file is an Antigravity adapter only. Personal rules belong in local -ignored files and must not override repository policy. +The root policy routes the canonical, task-specific documents under `.agent/`. This file is only the Antigravity-compatible entry point and does not override or duplicate repository policy. diff --git a/.agents/skills/oneshot-failure-injection/SKILL.md b/.agents/skills/oneshot-failure-injection/SKILL.md new file mode 100644 index 0000000..6ef3fc9 --- /dev/null +++ b/.agents/skills/oneshot-failure-injection/SKILL.md @@ -0,0 +1,28 @@ +--- +name: oneshot-failure-injection +description: Design or test OneShot failure boundaries around external effects, including timeouts, lost responses, process kills, duplicate delivery, retries, and parallel execution before, during, or after payment submission. +--- + +# OneShot Failure Injection + +Read `.agent/SECURITY_INVARIANTS.md` and `.agent/TEST_MATRIX.md`. Map each +external effect into three boundaries: definitely before submission, possibly +submitted, and definitely confirmed. + +## Mandatory checks + +- Inject failure before submission and prove zero settlement plus safe retry. +- Inject timeout/process kill/lost response during or after submission and prove + durable `UNKNOWN`, reconciliation, and no blind retry. +- Deliver the same request repeatedly and from 10 parallel workers; prove at + most one committed settlement. +- Restart services between durable transitions and external responses. +- Delay or empty The Graph results; prove no duplicate settlement. +- Deny Privy policy and exceed spending amount; prove zero settlement. +- Fail a supplier/API action after payment; prove settlement result remains. +- Assert external settlement count, durable intent/attempt/settlement state, and + stable identifiers. Do not rely only on returned HTTP status. + +Use testnet or isolated fakes. Never inject failures against unauthorized live +funds or expose secrets in fixtures/logs. Record exact injection points and +results in session context and PR evidence. diff --git a/.agents/skills/oneshot-idempotency/SKILL.md b/.agents/skills/oneshot-idempotency/SKILL.md new file mode 100644 index 0000000..38312b9 --- /dev/null +++ b/.agents/skills/oneshot-idempotency/SKILL.md @@ -0,0 +1,31 @@ +--- +name: oneshot-idempotency +description: Enforce OneShot's at-most-once settlement invariant when work touches business intents, payments, retries, settlements, reconciliation, workers, queues, jobs, invoices, or duplicate delivery. +--- + +# OneShot Idempotency + +Read `.agent/PROJECT_CONTEXT.md`, `.agent/SECURITY_INVARIANTS.md`, and +`.agent/TEST_MATRIX.md` before editing. + +## Mandatory checks + +- Preserve `1 intent / N attempts / <=1 committed settlement`. +- Create and persist one stable `business_intent_id` before external effects; + reuse it across retries, restarts, workers, and agents. +- Keep authoritative intent and settlement state in OneShot durable storage. +- Grant submission rights through an atomic, concurrency-safe transition or + equivalent uniqueness guarantee. +- Use a stable provider idempotency/submission key tied to the Business Intent + where the provider supports it. This supplements, not replaces, OneShot state. +- Treat any possibly submitted but unconfirmed payment as `UNKNOWN`. Reconcile + from durable/provider/Arc evidence before retrying. +- Never use Graph absence or indexing delay as permission to pay. +- Keep money in integer atomic units or `bigint`; validate asset, network, + recipient, amount, and Privy policy before submission. +- Preserve payment results when later supplier/API work fails. + +Select applicable matrix cases, including duplicate input, 10 sequential +retries, 10 parallel workers, process restart, two agents, and ambiguous +submission. Report any invariant that cannot be proven; do not claim safety from +happy-path tests alone. diff --git a/.agents/skills/sponsor-qualification/SKILL.md b/.agents/skills/sponsor-qualification/SKILL.md new file mode 100644 index 0000000..6624883 --- /dev/null +++ b/.agents/skills/sponsor-qualification/SKILL.md @@ -0,0 +1,25 @@ +--- +name: sponsor-qualification +description: Validate Privy, Arc, and The Graph integration evidence before OneShot demos, releases, submissions, sponsor checklists, or qualification claims. +--- + +# Sponsor Qualification + +Read `.agent/SPONSOR_REQUIREMENTS.md`, `.agent/PROJECT_CONTEXT.md`, and relevant +code/tests/demo instructions. Review actual working evidence, not plans. + +## Mandatory checks + +- Privy: prove corporate wallet authorization constrains the normal settlement + path through scoped policy or spending permission. Login-only is insufficient. +- Arc: prove the demo performs a real USDC settlement on the authorized testnet. + A network label, address, explorer link, or mock alone is insufficient. +- The Graph: prove live indexed data supports recovery/history/agent decisions, + while OneShot durable state remains authoritative and empty/indexing-delayed + results cannot unlock another settlement. +- Verify the demo preserves `1 intent / N attempts / <=1 settlement` and never + exposes secrets. + +For each sponsor, report `QUALIFIED`, `NOT QUALIFIED`, or `NOT VERIFIED`, citing +code, tests, live demo evidence, network, and known limitations. Never upgrade +missing or mocked evidence into a qualification claim. diff --git a/.antigravity/README.md b/.antigravity/README.md index 37f4a57..8190cc1 100644 --- a/.antigravity/README.md +++ b/.antigravity/README.md @@ -1,9 +1,5 @@ # Antigravity adapter -Antigravity loads `.agents/rules/repository-policy.md`, which points to the -canonical repository policy and implementation loop. +Antigravity agents must load `.agents/rules/repository-policy.md`, which delegates to the canonical root `AGENTS.md` policy and its task-specific `.agent/` documents. -Use the shared prompts in `.agent/review-prompts/` for Gate A and Gate B. -Personal Antigravity configuration and review logs stay local. - -Reference: https://www.antigravity.google/docs/rules-workflows/ +Use the shared FreePi prompts under `.agent/review-prompts/` for mandatory independent review gates. Keep personal configuration under ignored local paths; do not commit it. diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index b101e21..ba2ca36 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -1,46 +1,5 @@ -# OneShot +# OneShot Claude adapter -Before planning, editing, reviewing, or publishing any change, read -`AGENTS.md`, `.agent/AGENTS.md`, and `.agent/MILESTONE_IMPLEMENTATION_LOOP.md` -completely and follow them as mandatory repository policy. +Before working in this repository, read and follow `../AGENTS.md` completely. -Those files are authoritative. Nothing in this file overrides them; the list below -is a reminder, not a replacement. If a policy file is missing or unreadable, stop -and report it. Do not guess the review or publishing process. - -## Project - -OneShot — Payment Intent Firewall. A `businessIntentId` binds organization, -supplier, invoice number, amount, currency, purchase order, and document version, -so one invoice settles exactly once even across competing agents, distinct -mandates, differing transaction nonces, and repeated retries after a lost -response. Built as a recovery/audit layer over existing payment rails -(EIP-3009 / x402), not as a replacement payment primitive. - -Strategy notes and bounty analysis live in a separate vault repo: -`~/Documents/thoughts`. Do not commit vault notes here — event-window commit -history in this repo is inspected by hackathon judges. - -## Non-negotiables - -- Never implement directly on `main` or `develop`. Branch from `develop` as - `milestone/-`, `feature/`, or `fix/`. -- All pull requests target `develop` and start as **draft**. -- Review Gate A (pre-PR, full workspace diff against `develop`) and Review Gate B - (post-CI, bound to the exact PR head SHA) are both mandatory. -- Gates run in **independent sessions**. The implementation agent must never - review its own work, and a Gate A session must never be reused for Gate B. -- Any content change invalidates Gate A. Any commit invalidates Gate B. -- `WARN`, truncated output, unavailable tooling, an auth failure, or an ambiguous - verdict is a FAIL, not a pass. -- Never bypass a failing check with `--force`, `--no-verify`, broadened ignore - rules, lowered thresholds, or dependency overrides. Fix the cause or report a - genuine blocker. -- Never merge a pull request. The user performs final review and merges. -- Never commit secrets, keys, tokens, credentials, or personal data. - -## Handoff format - -When work is agent-complete, report: branch name, head commit SHA, PR URL, checks -run, Gate A and Gate B verdicts, known limitations, and the exact decision -required from the user. +The root policy routes the canonical, task-specific documents under `.agent/`. Nothing in this adapter overrides them. Keep personal Claude settings local and ignored. diff --git a/.github/BRANCH_POLICY.md b/.github/BRANCH_POLICY.md index c71f006..47955cb 100644 --- a/.github/BRANCH_POLICY.md +++ b/.github/BRANCH_POLICY.md @@ -1,44 +1,36 @@ -# Branch and Quality Policy +# Branch and review policy -## Branch architecture +## Protected branches -- `main`: Production/release branch. Contains only stable, released code. Merges to `main` occur from `develop` through release PRs or tags. -- `develop`: Integration branch. The default base branch for ongoing development, milestones, and features. -- `milestone/-`, `feature/`, `fix/`: Short-lived branches targeting `develop`. +- `develop` is the integration branch. +- `main` is the release branch. +- Do not push directly to either protected branch. +- Do not merge a pull request as an agent. A human owner merges after the required reviews and checks pass. -## Pull request workflow +## Working branches -1. All milestone and feature branches originate from `develop` and create pull requests targeting `develop`. -2. Every pull request begins as a **Draft** PR. -3. Every pull request requires passing: - - Local validation checks (Phase 3); - - Review Gate A (independent pre-PR implementation review); - - All required CI status checks; - - Review Gate B (independent post-PR draft review); - - Human review and approval. -4. Agents must never merge pull requests. Final approval and merging is performed exclusively by the user. +Create a focused branch from the latest target branch and keep commits scoped to one concern. Before opening or updating a pull request, follow `.agent/IMPLEMENTATION_LOOP.md` and confirm the exact candidate tree has passed the pre-push FreePi gate. -## Agent review evidence +## Required pull-request evidence -Canonical agent and review rules live in `AGENTS.md`, `.agent/AGENTS.md`, and -`.agent/MILESTONE_IMPLEMENTATION_LOOP.md`. Pull requests record their required -evidence through `.github/PULL_REQUEST_TEMPLATE.md`. +Every pull request must record: -GitHub status checks and branch protection enforce merge readiness. Local agent -instructions alone are not enforcement. +- the base and head commit SHAs; +- the candidate tree SHA reviewed before push; +- the independent reviewer tool and model; +- the exact `VERDICT: PASS` result for Gate A; +- the validation commands and results; +- security and product-invariant impact; +- any residual risks or follow-up work. -## Required status checks +After push, run the PR-head FreePi gate against the exact remote head. A pass for a different tree or commit is stale and does not satisfy the gate. -The initial required check for `develop` and `main` is: +## Required checks -- `Agent policy`. +The following checks must pass before human merge: -Add lint, test, and build checks as executable project components appear. +- `Agent policy / repository-policy`; +- all applicable build, test, lint, type-check, and security checks; +- independent FreePi Gate A and Gate B reviews as defined in `.agent/IMPLEMENTATION_LOOP.md`. -## Protection rules - -The `develop` and `main` branches should be protected against: -- Direct pushes (all changes must pass through pull requests); -- Force pushes; -- Branch deletions; -- Merging with unresolved conversations or failing checks. +If a required check cannot run, stop and document the blocker. Do not weaken, bypass, or silently substitute a gate. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8fdb14d..b1b4685 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,67 +1,65 @@ -## Milestone outcome +## Summary - + -## Scope +## Scope and acceptance criteria -### In scope +- [ ] The change is limited to the stated milestone or issue. +- [ ] Acceptance criteria are listed and satisfied. +- [ ] No unrelated cleanup is included. -- +## Product and security invariants -### Out of scope +- [ ] Tenant isolation remains fail-closed. +- [ ] Sponsor authorization, auditability, and daily caps remain enforced where applicable. +- [ ] Recipients cannot modify sponsor controls or access sponsor-only data. +- [ ] No secret, token, production identifier, or personal data is committed or pasted into review prompts. +- [ ] Any non-applicable invariant is explained below. -- +Invariant notes: -## Acceptance criteria + -- [ ] +## Validation -## Risk review +Commands and results: -- Security & secrets: -- Data safety & privacy: -- Architecture & performance: -- Rollback or safe disablement: +```text + +``` -## Validation evidence +## Independent review evidence -| Command or check | Result | -| --- | --- | -| `` | | -| `` | | -| `` | | +### Gate A — exact candidate tree before push -## Review Gate A - implementation - -- Reviewed base SHA: -- Reviewed candidate tree SHA: -- Reviewer tool: +- Base commit SHA: +- Candidate tree SHA: +- Candidate commit SHA (if already committed but unpushed): +- Reviewer tool: `free-pi-cli` - Reviewer model: -- Verdict: -- Blocking findings resolved: -- Evidence / review summary: - -## Required CI +- Verdict: `VERDICT: PASS` / `VERDICT: FAIL` +- Findings or residual risks: -- [ ] `Agent policy` -- [ ] All project checks applicable to this change -- [ ] No required check is missing, pending, skipped, or failing +- [ ] The reviewed tree equals the committed tree. -## Review Gate B - draft PR +### Gate B — exact remote PR head -- Reviewed PR head SHA: -- Reviewed PR head tree SHA: -- Matching Gate A candidate tree SHA: -- Reviewer tool: +- Pull request URL/number: +- Remote head commit SHA: +- Remote head tree SHA: +- Reviewer tool: `free-pi-cli` - Reviewer model: -- Verdict: -- Blocking findings resolved: -- Evidence / review summary: +- Verdict: `VERDICT: PASS` / `VERDICT: FAIL` +- Findings or residual risks: + +- [ ] Gate B reviewed the current remote head and matches Gate A's approved tree, or a fresh Gate A was run for the changed tree. +- [ ] `Agent policy / repository-policy` and all applicable CI checks pass. + +## Risk and rollback + +- Residual risks: +- Rollback or recovery plan: -## User review +## Human merge -- [ ] Review Gate A passed for the current change. -- [ ] Required CI checks are green for the current head. -- [ ] Review Gate B passed for the current head. -- [ ] The PR is marked ready for user review. -- [ ] The user explicitly approved merge. Agents must leave this unchecked. +- [ ] A human owner has reviewed the evidence and will perform the merge. diff --git a/.github/workflows/agent-policy.yml b/.github/workflows/agent-policy.yml index a314ce5..ad7768e 100644 --- a/.github/workflows/agent-policy.yml +++ b/.github/workflows/agent-policy.yml @@ -2,6 +2,7 @@ name: Agent policy on: pull_request: + push: branches: - develop - main @@ -10,39 +11,72 @@ permissions: contents: read jobs: - validate: - name: Agent policy + repository-policy: runs-on: ubuntu-latest - timeout-minutes: 2 - steps: - - name: Check out repository - uses: actions/checkout@v6 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Validate shared policy + - name: Validate canonical agent workflow shell: bash - env: - BASE_SHA: ${{ github.event.pull_request.base.sha }} run: | set -euo pipefail - for path in \ - AGENTS.md \ - .agent/AGENTS.md \ - .agent/MILESTONE_IMPLEMENTATION_LOOP.md \ - .agent/review-prompts/implementation-review.md \ - .agent/review-prompts/draft-pr-review.md \ - .agents/rules/repository-policy.md \ + required_paths=( + AGENTS.md + .agent/AGENTS.md + .agent/PROJECT_CONTEXT.md + .agent/SECURITY_INVARIANTS.md + .agent/SPONSOR_REQUIREMENTS.md + .agent/TEST_MATRIX.md + .agent/IMPLEMENTATION_LOOP.md + .agent/review-prompts/freepi-prepush-review.md + .agent/review-prompts/freepi-pr-review.md + .agents/skills/oneshot-failure-injection/SKILL.md + .agents/skills/oneshot-idempotency/SKILL.md + .agents/skills/sponsor-qualification/SKILL.md + .agents/rules/repository-policy.md + .antigravity/README.md + .claude/CLAUDE.md + .github/BRANCH_POLICY.md .github/PULL_REQUEST_TEMPLATE.md - do - test -f "$path" + ) + + for path in "${required_paths[@]}"; do + test -f "$path" || { echo "Missing required policy file: $path"; exit 1; } + done + + obsolete_paths=( + .agent/MILESTONE_IMPLEMENTATION_LOOP.md + .agent/milestones/M0_UNIFIED_AGENT_WORKFLOW.md + .agent/review-prompts/draft-pr-review.md + .agent/review-prompts/implementation-review.md + .antigravity/review.md + ) + + for path in "${obsolete_paths[@]}"; do + test ! -e "$path" || { echo "Obsolete policy file must be removed: $path"; exit 1; } done grep -Fq '@../../AGENTS.md' .agents/rules/repository-policy.md - grep -Fq '@../../.agent/AGENTS.md' .agents/rules/repository-policy.md - grep -Fq '@../../.agent/MILESTONE_IMPLEMENTATION_LOOP.md' \ - .agents/rules/repository-policy.md - test ! -e .antigravity/review.md - git diff --check "$BASE_SHA" HEAD + grep -Fq '../AGENTS.md' .claude/CLAUDE.md + grep -Fq '.agents/rules/repository-policy.md' .antigravity/README.md + grep -Fq '.agent/IMPLEMENTATION_LOOP.md' AGENTS.md + grep -Fq 'free-pi-cli' .agent/IMPLEMENTATION_LOOP.md + + test "$(wc -l < .agents/rules/repository-policy.md)" -le 12 + test "$(wc -l < .claude/CLAUDE.md)" -le 12 + test "$(wc -l < .antigravity/README.md)" -le 12 + + if git grep -nE '^(<<<<<<<|=======|>>>>>>>)' -- . ':!*.lock'; then + echo 'Unresolved merge marker found.' + exit 1 + fi + + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + base_sha="${{ github.event.pull_request.base.sha }}" + git diff --check "$base_sha" HEAD + else + git diff --check HEAD^ + fi diff --git a/.gitignore b/.gitignore index 496e426..af28f7b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,9 +6,24 @@ Thumbs.db .env .env.* !.env.example +.envrc +.direnv/ *.local *.key *.pem +*.p12 +*.pfx +*.jks +*.keystore +*.seed +*.mnemonic +*.token +.npmrc +!.npmrc.example +secrets/ +credentials/ +.free-pi/ +.pi/ # Editor and IDE .vscode/ @@ -34,6 +49,8 @@ dist/ build/ coverage/ node_modules/ +.venv/ +venv/ __pycache__/ .pytest_cache/ .ruff_cache/ diff --git a/AGENTS.md b/AGENTS.md index 7e1ceea..5c7494b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,18 +1,29 @@ -# Repository Agent Instructions +# OneShot Agent Entry Point -These instructions apply to the entire repository. +Read `.agent/AGENTS.md` before any repository work. -Before planning, editing, reviewing, or publishing any change, read -`.agent/AGENTS.md` and `.agent/MILESTONE_IMPLEMENTATION_LOOP.md` completely and -follow them as mandatory repository policy. +Then load only the documents needed for the task: -Agents supporting `AGENTS.md` load this root file. Detailed policies and -milestone loops live under `.agent/` so repository rules remain maintainable -without inflating the top-level prompt. +- Architecture or domain work: `.agent/PROJECT_CONTEXT.md` and + `.agent/SECURITY_INVARIANTS.md`. +- Privy, Arc, The Graph, demo, release, or submission work: + `.agent/SPONSOR_REQUIREMENTS.md`. +- Intent, payment, retry, worker, queue, job, invoice, settlement, or + reconciliation work: the `oneshot-idempotency` repo skill and + `.agent/TEST_MATRIX.md`. +- Failure handling or reliability work: the `oneshot-failure-injection` repo + skill and `.agent/TEST_MATRIX.md`. +- Any implementation, review, commit, push, or pull request: + `.agent/IMPLEMENTATION_LOOP.md`. +- Demo/release sponsor claims: the `sponsor-qualification` repo skill. +- Handoff, milestone boundary, session end, or deliberate context reset: + `.agent/context/README.md` and the current context record. -Tool-specific files may only point to these canonical policies. They must not -duplicate or override them. Personal agent preferences belong in ignored local -files, not shared branches. +Canonical shared policy lives only in this file and `.agent/`. Tool-specific +files such as `.claude/CLAUDE.md` and `.agents/rules/repository-policy.md` are +thin adapters: they point here and must not duplicate or override policy. -If either detailed policy file is missing or cannot be read, stop and report the -problem. Do not guess at the review or publishing process. +Repository skills live in `.agents/skills/`. Personal workflow skills may help, +but they never replace OneShot policy or mandatory FreePi Gate A and Gate B. + +If a required document cannot be read, stop and report the missing policy. diff --git a/plan.md b/plan.md new file mode 100755 index 0000000..d6b0dca --- /dev/null +++ b/plan.md @@ -0,0 +1,521 @@ +# OneShot Product Implementation Plan + +Status: implementation-ready proposal +Team: exactly three engineers +Planning horizon: 20 working days, recalibrated after Milestone 1 +Base for implementation: current `develop` after the agent-infrastructure work is human-reviewed and merged +Research basis: `.agent/research/20260906-integration-decisions.md` + +## 1. Outcome + +Deliver a testnet application that accepts one approved Business Intent, safely survives retries, crashes, duplicate delivery, parallel workers, and ambiguous provider responses, and produces at most one committed USDC settlement on Arc Testnet through a Privy-controlled corporate wallet. The Graph supplies live indexed history and recovery evidence without becoming an authorization source. + +The release claim is: + +`1 Business Intent / N Attempts / <= 1 committed Settlement` + +The milestone plan is deliberately backend-first. No production frontend work begins until the backend integration and failure suite pass in Milestone 4. + +## 2. Success criteria + +- A caller creates a Business Intent with a stable `business_intent_id`; identical replays return the same durable result and conflicting payloads under the same ID fail explicitly. +- Privy authorization and wallet policy constrain every normal settlement path. Wrong network, asset, recipient, method, or above-cap amount results in zero settlement. +- A valid intent produces a real ERC-20 USDC transfer on Arc Testnet and stores the final receipt and transfer identity. +- A timeout, lost response, or crash after possible submission produces durable `UNKNOWN`; no new settlement submission is allowed until reconciliation resolves it. +- Ten sequential retries, ten parallel workers, a restart, and two agent instances cannot produce more than one committed settlement. +- Live The Graph data explains settlement history and supports recovery. Empty, delayed, or unhealthy indexed data never unlocks another payment. +- Money remains an integer string/`bigint` in six-decimal ERC-20 USDC atomic units from API through policy evaluation, storage, calldata, indexing, and UI. +- The final demo proves Privy, Arc, and The Graph requirements with testnet evidence and exposes no secrets. + +## 3. Scope + +### In scope + +- TypeScript backend, worker, shared contracts, PostgreSQL state, and migrations. +- Privy execution-wallet authorization and a fail-closed wallet policy. +- Arc Testnet ERC-20 USDC submission, receipt verification, and explorer evidence. +- Durable reconciliation using OneShot state, Privy identifiers/status, Arc RPC receipts, and The Graph evidence. +- A custom Subgraph plus freshness and indexing-health classification. +- Failure injection, concurrency tests, service restart tests, audit-safe structured logs, metrics, and a demo runbook. +- A minimal operator/user frontend only after backend acceptance. + +### Explicit non-goals + +- Mainnet, multi-chain, multi-asset, swaps, bridging, fiat on/off ramps, or custody beyond the configured Privy testnet wallet. +- Treating The Graph as authoritative settlement state or as permission to retry. +- Automatic same-nonce transaction replacement in the first release. +- General workflow automation, arbitrary supplier integrations, accounting/ERP integrations, or production compliance certification. +- Production-scale multi-region deployment, high availability, or a native mobile client. + +## 4. Fixed technical decisions + +These decisions are frozen for the first implementation. Changing one requires a short ADR, updated contract fixtures, and approval from all affected owners. + +| Area | Decision | Reason | +| --- | --- | --- | +| Runtime | Node.js LTS + strict TypeScript; exact versions pinned in Milestone 1 | One language across API, worker, Privy, Arc, Subgraph tooling, and frontend | +| Repository | `pnpm` workspace with independently testable packages | Each owner can build and test without waiting for root integration | +| API | HTTP JSON described by OpenAPI; generated schemas are checked for drift | Stable seam for simulators and the late frontend | +| Durable state | PostgreSQL | Atomic conditional transitions, constraints, transactional enqueueing | +| Work delivery | Graphile Worker in the same PostgreSQL database | At-least-once work without adding Redis; transactional enqueueing | +| Money | Decimal-free integer strings at boundaries and `bigint` internally | Prevents floating-point loss and JSON `bigint` ambiguity | +| Settlement asset | Arc Testnet ERC-20 USDC at `0x3600000000000000000000000000000000000000`, six decimals | One canonical payment representation; native USDC is gas accounting only | +| Privy | Execution wallet with authorization owner/key quorum and one fail-closed policy | Privy remains a real authorization boundary, not branding | +| Chain access | Arc RPC with startup checks for chain ID `5042002` and USDC bytecode | Fails closed on misconfiguration | +| Indexed view | Custom Subgraph on `arc-testnet`, queried with `_meta` and explicit freshness | Live recovery/history with visible limitations | +| External-effect queueing | `submit_settlement` gets one queue attempt; reconciliation reads may retry | Prevents the queue from blindly repeating an ambiguous payment | + +## 5. Architecture and ownership boundaries + +```text +Caller / late frontend + | + v +HTTP API ---------> PostgreSQL authoritative ledger <------ Worker claims + | | | + | +---- durable outbox/jobs ---+ + | + +--> AuthorizationPort --> Privy policy + wallet + +--> SettlementPort ----> Arc ERC-20 USDC + +--> EvidencePort ------> Privy status + Arc RPC + +--> IndexViewPort -----> The Graph (non-authoritative) +``` + +### Person A — Domain, storage, API, and work delivery + +Owns `packages/contracts`, `packages/domain`, `packages/storage-postgres`, `apps/api`, `apps/worker`, migrations, OpenAPI, and the domain adapter simulator. Person A does not implement Privy, Arc, or The Graph clients. + +### Person B — Privy authorization and Arc settlement + +Owns `packages/privy-adapter`, `packages/arc-adapter`, policy fixtures, Arc chain configuration, transaction construction, receipt verification, provider error classification, and the settlement-adapter simulator. Person B does not change domain states or database tables directly. + +### Person C — Reconciliation, The Graph, and reliability evidence + +Owns `packages/reconciliation`, `packages/graph-client`, `subgraph`, recovery-view contracts, freshness/health classification, and the failure-injection harness. Person C may propose state transitions only through the frozen reconciliation command port. + +### Shared files and conflict rule + +- Only Person A edits root workspace/build configuration after Milestone 1. +- Every package must have a package-local test command so Persons B and C can run independently before root composition exists. +- Contract changes are additive during a milestone. Breaking changes require an ADR and all three owners' approval; consumers retain the old form until migration is complete. +- No owner imports another owner's implementation package. Integration happens only through ports and JSON fixtures defined below. + +## 6. Contract freeze — the mechanism that removes day-to-day blockers + +The following semantics are the Milestone 0 contract. Implementation details may vary, but no track may reinterpret them. + +### 6.1 Create-intent command + +Required input: + +- `business_intent_id`: caller-supplied UUID/opaque stable ID. +- `recipient`: checksummed or normalized EVM address. +- `amount_atomic`: canonical base-10, non-negative integer string; no signs, decimals, exponent, or leading whitespace. +- `asset`: exactly `USDC`. +- `network`: exactly `eip155:5042002`. +- `purpose`: non-secret, length-bounded human description used only for display/audit. + +The server computes an immutable payload fingerprint from normalized recipient, amount, asset, network, and purpose. Reusing the ID with the same fingerprint is a replay; reusing it with a different fingerprint is a conflict and never creates another settlement right. + +### 6.2 Public HTTP seam + +| Operation | Required behavior | +| --- | --- | +| `POST /v1/intents` | Create or replay an intent; return `202` for accepted, `200` for identical replay, `409` for same-ID conflict, and no external effect in the request transaction | +| `GET /v1/intents/{id}` | Return intent, attempts, settlement state, sanitized evidence, and stable version | +| `POST /v1/intents/{id}/reconcile` | Enqueue/read-trigger reconciliation only; never directly submit settlement | +| `GET /v1/intents/{id}/recovery-view` | Return authoritative local state plus clearly labeled indexed/provider evidence and freshness | +| `GET /health/live` | Process liveness without external dependency claims | +| `GET /health/ready` | Database plus configuration readiness; fail on wrong Arc chain ID or invalid required configuration | + +Every mutation uses service authentication, request-size limits, schema validation, a correlation ID, and rate limiting. API errors use stable machine codes and never expose provider secrets or raw authorization material. + +### 6.3 Port result contracts + +| Port | Terminal result families | Required meaning | +| --- | --- | --- | +| `AuthorizationPort.evaluate` | `AUTHORIZED`, `DENIED`, `UNAVAILABLE` | `DENIED` and invalid scope produce zero submission; `UNAVAILABLE` is retryable only before submission | +| `SettlementPort.submit` | `CONFIRMED`, `DEFINITELY_NOT_SUBMITTED`, `POSSIBLY_SUBMITTED` | The adapter must never collapse an ambiguous response into a safe retry | +| `EvidencePort.lookup` | `FINAL_SUCCESS`, `FINAL_REVERT`, `PENDING`, `NOT_FOUND`, `UNAVAILABLE` | `NOT_FOUND` alone cannot authorize a new submission | +| `IndexViewPort.lookup` | evidence plus indexed block, timestamp, deployment, lag, health | Data is explanatory; missing/unhealthy data cannot transition `UNKNOWN` to retryable | + +All port requests contain the stable Business Intent ID, immutable payload fingerprint, Arc/USDC identifiers, persisted provider idempotency key, correlation ID, and attempt ID. Simulators must read and emit the same checked JSON fixtures as production adapters. + +### 6.4 Durable state model + +Keep separate records for Business Intent, Attempt, and Settlement. A compact settlement state machine is: + +| Current | Trigger | Next | External submission allowed? | +| --- | --- | --- | --- | +| `NONE` | validated intent accepted | `AUTHORIZING` | No | +| `AUTHORIZING` | Privy policy authorizes | `READY` | No | +| `AUTHORIZING` | policy denies | `REJECTED` | No, terminal | +| `READY` | atomic owner grant persists request identity | `SUBMITTING` | Exactly one owner may cross the boundary | +| `SUBMITTING` | verified final receipt and expected Transfer log | `COMMITTED` | No, terminal | +| `SUBMITTING` | narrow proof of no broadcast | `FAILED_SAFE` | A new attempt may be scheduled by policy | +| `SUBMITTING` | timeout, disconnect, lost response, crash, or doubt | `UNKNOWN` | No | +| `UNKNOWN` | reconciliation finds verified success | `COMMITTED` | No, terminal | +| `UNKNOWN` | reconciliation proves final revert/no settlement with authoritative evidence | `FAILED_SAFE` | Only then may policy schedule a new attempt | +| `UNKNOWN` | pending, not found, lagging, unhealthy, or contradictory evidence | `UNKNOWN` | No; operator attention if deadline exceeded | + +Mandatory storage constraints and records: + +- Primary/unique Business Intent ID plus immutable fingerprint. +- At most one Settlement row per Business Intent; provider transaction hash unique when present. +- N append-only Attempt rows with stage, timestamps, sanitized error class, and correlation ID. +- Persisted Privy idempotency key, reference ID, request fingerprint, wallet ID, recipient, amount, chain, token contract, transaction ID/hash/nonce when learned, receipt block/hash/status, and verified Transfer log identity. +- Compare-and-set state transitions with a monotonically increasing version. No database transaction spans an external network call. +- Transactional outbox/job insertion. Queue delivery and API retries are assumed duplicate and out of order. +- On worker startup, any orphaned `SUBMITTING` record is conservatively moved/treated as `UNKNOWN` for reconciliation; lease expiry never grants a blind resubmission. + +### 6.5 Agreed test seams + +Tests observe behavior through these public seams only: + +1. HTTP API plus returned durable state. +2. Worker task input/output plus durable state and external-submission counter. +3. Adapter ports with official-response fixtures. +4. Reconciliation command plus durable transition and evidence record. +5. Subgraph mappings/GraphQL query plus indexed entity and `_meta` classification. +6. Browser UI through the public API contract in Milestone 5. + +Each implementation ticket uses one red-green vertical slice at a time. Tests must assert both durable state and settlement count; HTTP status alone is insufficient. + +## 7. Milestone overview and dependency graph + +| Milestone | Days | Exit outcome | +| --- | ---: | --- | +| M0 — Contract and safety freeze | 0.5 | This plan, research, ports, fixtures, states, ownership, and test seams accepted | +| M1 — Three independent walking skeletons | 1–4 | Each track runs locally with its own simulator and no cross-track implementation import | +| M2 — Safety-critical vertical slices | 5–8 | Domain concurrency, real policy/transaction adapter, and reconciliation logic pass independently | +| M3 — Failure and operational hardening | 9–12 | Each track passes its assigned fault, restart, and observability evidence | +| M4 — Integrated backend and live testnet proof | 13–15 | All adapters compose; full matrix passes; one real authorized settlement is recorded and indexed | +| M5 — Frontend, last | 16–18 | Minimal intent, status, and recovery UI works against the stable backend | +| M6 — Demo qualification and release candidate | 19–20 | Scripted demo, sponsor evidence, runbooks, and release checks pass | + +```text +A1 -> A2 -> A3 --\ +B1 -> B2 -> B3 ----> M4 integrated backend -> M5 frontend -> M6 demo/release +C1 -> C2 -> C3 --/ +``` + +There are no cross-person blockers through M3. Each task depends only on the same owner's prior task. M4 is the first convergence dependency; its build work can continue against simulators, but its exit test requires all three artifacts. This is intentional and cannot be removed without pretending integration is optional. + +## 8. Detailed milestones + +### M0 — Contract and safety freeze (all three, half day) + +Deliverables: + +- Accept Sections 4–6 as the initial ADR-equivalent contract. +- Create versioned JSON fixtures for identical replay, conflicting replay, authorization denial, confirmed transfer, final revert, pending transaction, lost response, empty Graph result, lagging Graph result, and indexing error. +- Confirm package/file ownership and the no-cross-implementation-import rule. +- Record required environment-variable names in `.env.example` with placeholders only; classify each as secret or public. +- Confirm the six public test seams before any test is written. + +Exit criteria: + +- Each person can run their package tests with local fakes and no credentials. +- Every contract field has one owner, type, normalization rule, and redaction rule. +- No unresolved decision can change settlement cardinality, money representation, or the classification of `UNKNOWN`. + +### M1 — Three independent walking skeletons (days 1–4) + +#### A1 — Durable intent skeleton (Person A; blockers: M0 only) + +What it delivers: an intent can be accepted, replayed, queried, queued, and observed end to end using fake authorization/settlement ports. + +Work: + +- Create the workspace, strict compiler/lint/test/build commands, API/worker entry points, OpenAPI validation, and package-local commands. +- Add PostgreSQL migrations for intents, attempts, settlements, outbox/jobs, evidence, and schema versioning. +- Implement normalized fingerprinting, create/replay/conflict behavior, GET status, atomic state transitions, and a fake adapter with an external-settlement counter. +- Add containerized PostgreSQL test support and deterministic clock/ID seams. + +Acceptance: + +- Identical request twice returns the same Business Intent and one queued execution. +- Conflicting payload under the same ID returns `409`, records the conflict safely, and creates zero extra settlement rights. +- State survives API and worker restarts. +- Package tests prove constraints using a real PostgreSQL transaction, not only mocks. + +#### B1 — Privy/Arc adapter skeleton (Person B; blockers: M0 only) + +What it delivers: a standalone adapter can validate configuration, build exactly one canonical ERC-20 transfer request, classify official-response fixtures, and verify receipts without a real domain service. + +Work: + +- Pin and validate the Privy Node SDK plus Arc client library in a package-local compatibility test. +- Define Arc Testnet configuration and readiness checks for chain ID, USDC contract code, wallet address, and amount precision. +- Build six-decimal ERC-20 transfer calldata and the Privy request with stable idempotency/reference identifiers. +- Implement receipt verification: chain, sender, token contract, status, recipient, amount, transaction hash, block, and unique Transfer log. +- Draft the fail-closed Privy wallet policy fixture; do not store credentials. + +Acceptance: + +- Golden fixtures produce byte-for-byte stable request fingerprints and calldata. +- Wrong chain, token, recipient, amount format, or native value is rejected before signing. +- `status: 1` without the expected Transfer log is not `CONFIRMED`; `status: 0` is final revert. +- Timeout/lost-response fixtures return `POSSIBLY_SUBMITTED`, never safe retry. + +#### C1 — Indexed recovery skeleton (Person C; blockers: M0 only) + +What it delivers: a standalone Subgraph and recovery package map Arc USDC Transfer fixtures and expose a freshness-labeled recovery view against a fake domain/evidence host. + +Work: + +- Create Subgraph schema, manifest, mapping, and Matchstick/unit fixtures for the Arc USDC contract. +- Create the Graph client query including `_meta`, deployment, block, timestamp, and indexing errors. +- Implement freshness states: `FRESH`, `LAGGING`, `UNHEALTHY`, `UNAVAILABLE`, `UNKNOWN_FRESHNESS`. +- Create the reconciliation decision table and a simulator for local state, Privy evidence, Arc receipts, and indexed evidence. + +Acceptance: + +- Mapping identity is transaction hash plus log index; amount remains Graph `BigInt`/decimal string. +- Empty or lagging Graph fixtures never return permission to resubmit. +- Recovery output labels which facts are authoritative and which are indexed observations. +- Package tests run with no network or credentials. + +M1 exit: all three package suites pass independently. Re-estimate M2–M6 from actual SDK, chain, and Subgraph friction; do not reduce safety acceptance to preserve the date. + +### M2 — Safety-critical vertical slices (days 5–8) + +#### A2 — Atomic at-most-once engine (Person A; blockers: A1 only) + +What it delivers: duplicate deliveries and concurrent workers converge on one submission owner and at most one committed settlement in the fake-adapter system. + +Work and acceptance: + +- Implement transactional authorization-to-ready and ready-to-submitting compare-and-set transitions. +- Configure `submit_settlement` with one queue attempt and catch/classify all adapter results into durable states before returning. +- Prove one normal job, 10 sequential retries, 10 parallel workers, and two worker/agent instances produce exactly one external submission/commit. +- Kill before external call: zero settlement and safe retry. Kill after the boundary: durable `UNKNOWN` and no new submission. +- Preserve a committed Settlement when a downstream/supplier simulation fails. + +#### B2 — Authorized Arc Testnet settlement (Person B; blockers: B1 only) + +What it delivers: the adapter executes one policy-constrained testnet USDC settlement from the standalone harness and returns verified normalized evidence. + +Work and acceptance: + +- Provision the execution wallet, owner/key quorum, and one attached policy through a human-run setup procedure; write secrets only to ignored runtime storage/approved CI secrets. +- Test policy allow and deny cases against Arc Testnet: wrong chain, wrong contract/method, wrong recipient, above cap, non-zero native value, expired authorization. +- Submit via Privy with `eip155:5042002`, persisted idempotency key, and stable reference ID; capture Privy transaction ID/hash and Arc receipt. +- Prove one allowed transfer commits once and every denial produces zero settlement. +- Produce sanitized fixtures from real response shapes for Person A and C without exposing secrets. + +#### C2 — UNKNOWN reconciliation engine (Person C; blockers: C1 only) + +What it delivers: a deterministic read-only reconciliation decision engine resolves authoritative evidence or holds safely without ever submitting a payment. + +Work and acceptance: + +- Implement evidence precedence: durable committed record and verified Arc receipt are authoritative; Privy status locates provider activity; Graph corroborates/history only. +- Resolve verified receipt success to `COMMITTED` and final revert with matching identity to `FAILED_SAFE`. +- Keep `UNKNOWN` for pending, provider unavailable, RPC unavailable, Graph empty/lagging/unhealthy, identity mismatch, or contradictory evidence. +- Persist every observation with source, retrieval time, block height, health, and sanitized reason. +- Prove repeated reconciliation and duplicate webhook/provider events are idempotent and create zero submissions. + +### M3 — Failure and operational hardening (days 9–12) + +#### A3 — Restart-safe orchestration and auditability (Person A; blockers: A2 only) + +What it delivers: the API/worker system recovers after process/database interruptions, exposes useful safe telemetry, and has a deterministic safe-disable path. + +Acceptance: + +- Restart after intent creation, job claim, `SUBMITTING` persistence, and adapter return; invariant holds at every point. +- Stale/orphaned work becomes reconciliation work, not a new submission lease. +- Structured logs carry Business Intent/Attempt IDs and state transitions but redact payload purpose as configured and never include credentials, authorization signatures, raw provider bodies, or private wallet material. +- Metrics cover state counts, transition failures, queue lag, UNKNOWN age, reconciliation outcomes, policy denials, and duplicate/conflict counts. +- A kill switch stops new submissions while status and reconciliation reads remain available. + +#### B3 — Provider ambiguity and policy hardening (Person B; blockers: B2 only) + +What it delivers: provider/RPC outcomes are conservatively classified across realistic failures and the policy remains effective after restart/config changes. + +Acceptance: + +- Inject DNS failure, connection refusal, timeout before response, truncated response, 429/5xx, malformed payload, lost success response, pending/evicted transaction, final revert, and mismatched receipt. +- Only documented, proven pre-broadcast failures become `DEFINITELY_NOT_SUBMITTED`; every doubtful result becomes `POSSIBLY_SUBMITTED`. +- Reusing the persisted Privy idempotency key and identical body is tested; its 24-hour limit is documented and never treated as permanent protection. +- Policy fingerprint/ID and expected restrictions are checked at readiness; mismatch fails closed. +- If webhooks are available, signature verification and duplicate/out-of-order delivery tests pass; otherwise polling remains complete and webhooks stay disabled. + +#### C3 — Indexer lag, contradiction, and chaos evidence (Person C; blockers: C2 only) + +What it delivers: recovery remains safe when The Graph or other evidence sources are delayed, empty, unhealthy, inconsistent, or unavailable. + +Acceptance: + +- Delay and empty The Graph results, set `hasIndexingErrors`, trail chain head, remove `_meta`, fail the query, and return duplicate/out-of-order events; none unlock a payment. +- Inject crash/lost response after possible submission and show the record remains `UNKNOWN` until authoritative evidence resolves it. +- Verify recovery evidence survives service restart and can be replayed for audit without provider secrets. +- Define UNKNOWN-age alerts and a human escalation runbook; the runbook never tells an operator to “just retry.” +- Produce a single command that runs the cross-source fixture matrix against the reconciliation package. + +M3 exit: each owner passes their package suite and provides a versioned artifact plus fixtures. No cross-track package implementation is required to reach this exit. + +### M4 — Integrated backend and live testnet proof (days 13–15) + +This is the first cross-track convergence. Each person prepares against simulators immediately; only the final acceptance run waits for all three M3 artifacts. + +#### A4 — Composition and migration integration (Person A) + +- Wire production ports without importing provider details into the domain package. +- Run migrations from an empty database and from the previous schema; verify rollback/safe-disable behavior. +- Validate OpenAPI, generated contract fixtures, root lint/type/test/build, and service readiness. +- Own conflict resolution only in shared/root files; provider owners resolve their packages. + +#### B4 — Live authorization/settlement evidence (Person B) + +- Run one allowed Arc Testnet transfer through the integrated worker. +- Run policy-denied and above-cap intents and prove zero settlement. +- Capture sanitized transaction ID/hash, receipt, expected Transfer log, chain, policy identity, and explorer link for demo evidence. +- Trace an intentionally lost local response into `UNKNOWN` without permitting a second transaction. + +#### C4 — Integrated reconciliation and matrix (Person C) + +- Reconcile the lost-response scenario to the original final transaction using durable/Privy/Arc evidence. +- Demonstrate live Subgraph history with `_meta`, then simulate lag/empty/error and show safe behavior. +- Run the full `.agent/TEST_MATRIX.md` suite and publish a sanitized results table with durable state and external settlement count. +- Verify alerts and recovery-view output distinguish authoritative and indexed evidence. + +M4 exit criteria: + +- All lint, static analysis, type, unit, integration, contract, build, migration, and focused failure-injection checks pass from the repository root. +- Every required test-matrix row records stable ID, final durable state, and external settlement count. +- Real testnet happy path has exactly one committed settlement; denial paths have zero; ambiguous path has no duplicate. +- Backend API/OpenAPI and recovery semantics are frozen for the frontend. Breaking changes after this point use expand-migrate-contract. + +### M5 — Frontend, last (days 16–18) + +Frontend work starts only after M4 passes. All three slices use the frozen OpenAPI and mock server, so component work remains parallel. + +#### F-A — Intent shell and status (Person A) + +- App shell, service-auth handoff suitable for the demo environment, create-intent form, exact atomic-amount parsing/formatting, and status polling. +- Show replay and same-ID conflict clearly; never generate a new Business Intent ID on a retry unless the user starts a genuinely new obligation. +- Display only USDC, Arc Testnet, and six payment decimals; keep native gas details separate. + +#### F-B — Authorization and settlement details (Person B) + +- Policy scope summary, authorization denied state, submission/pending/final state, sanitized transaction details, and Arc explorer link. +- No bypass button and no “force pay” action. `UNKNOWN` disables new settlement submission. +- Do not show a confirmation counter: Arc is pending or final. + +#### F-C — Recovery timeline and indexed history (Person C) + +- Attempt/reconciliation timeline, authoritative local state, Privy/Arc evidence, Graph observations, indexed-through block/time, lag, and health. +- Empty Graph data is labeled “not observed through block N,” never “not paid.” +- UNKNOWN state provides safe explanation/escalation, not a retry shortcut. + +M5 exit criteria: + +- Browser tests cover create, identical replay, conflict, denial, committed, UNKNOWN, reconciliation, Graph lag/error, and service-unavailable paths. +- Accessibility smoke tests, responsive layout, lint/type/build, and no-secret/source-map checks pass. +- The UI cannot invoke an unguarded settlement path. + +### M6 — Demo qualification and release candidate (days 19–20) + +#### Person A — Invariant and operational demo + +- Script duplicate requests, 10 parallel workers, restart, lost response, and downstream failure; show durable states and settlement count. +- Verify clean database bootstrap, safe-disable switch, logs/metrics, README, architecture diagram, and operator runbook. + +#### Person B — Privy and Arc evidence + +- Demonstrate policy-constrained corporate wallet execution, one real authorized USDC transfer on Arc Testnet, and zero-settlement denials. +- Record sanitized policy scope, transaction/receipt/Transfer proof, network, explorer URL, and limitations. + +#### Person C — The Graph and recovery evidence + +- Demonstrate live indexed Arc data in the recovery view and the same flow under delayed/empty/unhealthy indexed data. +- Run sponsor qualification against working code/tests/demo evidence and report each sponsor `QUALIFIED`, `NOT QUALIFIED`, or `NOT VERIFIED`; never promote missing evidence. + +Release-candidate exit: + +- Full test matrix and root checks pass on the exact candidate content. +- Secret scan and intended-file review pass; `.env*`, credentials, wallet material, and authorization responses are absent from review inputs. +- Each implementation change follows `.agent/IMPLEMENTATION_LOOP.md`: local checks, a fresh FreePi Gate A, draft PR to `develop`, green required CI, a separate fresh Gate B, then human review. Agents never merge. +- Demo can be reset and repeated using testnet-only funds without manual database surgery. + +## 9. Test ownership matrix + +| Required case | Primary owner | Independent harness | Integrated verifier | +| --- | --- | --- | --- | +| Normal job | A | Fake settlement counter | B | +| Same request twice / conflicting payload | A | HTTP + PostgreSQL | C observes recovery output | +| 10 sequential retries | A | Worker + fake port | B validates one adapter call | +| 10 parallel workers | A | Real PostgreSQL concurrency | C captures evidence timeline | +| Crash before submission | A | Worker kill point | B proves zero call | +| Crash after possible submission | B | Adapter fault point | C reconciles; A verifies state | +| Lost payment response | B | Proxy/fixture fault | C resolves original transaction | +| Graph delay or absence | C | Graph simulator | A verifies no submission grant | +| Privy denial / above policy | B | Policy testnet harness | A verifies zero settlement | +| Service restart | A | Process orchestration | C verifies evidence durability | +| Downstream failure after payment | A | Supplier fake | B verifies original receipt retained | +| Two agent instances | A | Two workers/processes | C verifies one settlement history | + +The primary owner builds the failure fixture and focused proof. Integrated verification is a Milestone 4 responsibility, not a prerequisite for the owner to finish M1–M3. + +## 10. Branching, review, and merge train + +- Do not implement product code on `agents-setup`, `develop`, or `main`. Once this planning/infrastructure change is human-merged to `develop`, create short-lived `milestone/a-*`, `milestone/b-*`, and `milestone/c-*` branches from the same `develop` SHA. +- One branch/PR delivers one task above. Within M1–M3, each branch is blocked only by the prior branch in the same lettered track. +- Merge independent package PRs before root composition. If two changes touch a shared contract, use expand-migrate-contract: add the new form, migrate all consumers in independent PRs, then remove the old form. +- Only Person A edits root composition files during M4. Persons B/C supply reviewed package commits and fixtures, preventing three-way conflicts. +- Every PR lists exact blockers, acceptance evidence, selected test-matrix cases, invariant impact, safe-disable strategy, and both required review gates. +- A human controls merge order and performs every merge. + +## 11. Human-only configuration plan + +Person B owns a repeatable interactive setup wizard after B1 fixes the variable contract. It must guide a human through Privy application/wallet/key-quorum/policy creation, Arc testnet funding, The Graph Studio deployment credentials, and CI secret entry. It must: + +- Open current official URLs before each instruction. +- Capture secrets with hidden input and write them only to ignored `.env` or approved CI secrets. +- Keep public chain/contract/deployment identifiers in non-secret variables. +- Confirm before policy replacement, wallet ownership change, funding, deployment, or any irreversible action. +- Be statically validated but never run end to end by an agent without the human. + +The backend must still boot in fake/local mode with no third-party credentials, so configuration work never blocks Persons A or C. + +## 12. Observability and safe operation + +- Correlation keys: Business Intent ID, Attempt ID, settlement version, Privy reference/transaction ID, Arc transaction hash, and Graph deployment/indexed block. Never log authorization signatures, credentials, private keys, or raw sensitive payloads. +- Alerts: oldest UNKNOWN age, count of UNKNOWN intents, repeated reconciliation failures, Graph block lag/health, policy denials, provider/RPC failure rate, queue lag, and state-transition conflicts. +- Safe disable: stop accepting/claiming new settlement submissions while keeping GET status, evidence ingestion, and reconciliation reads operational. +- Manual escalation: operators inspect durable request identity and evidence; there is no generic retry button. Any future override requires a separate audited design and is outside this plan. + +## 13. Risks and mitigations + +| Risk | Mitigation / fail-closed response | Owner | +| --- | --- | --- | +| Privy idempotency expires after 24 hours | Durable OneShot constraint remains authoritative; reuse stored key/body only as supplemental protection | A/B | +| SDK or policy syntax changes | Pin after B1 compatibility test; readiness verifies policy ID/fingerprint and network; deny on mismatch | B | +| Arc native/ERC-20 precision confusion or double counting | Settlement uses six-decimal ERC-20 only; native balance is gas; verify one canonical Transfer identity | B/C | +| Lost response or process crash after broadcast | Persist request identity before call, enter UNKNOWN, reconcile, forbid new nonce/payment | All | +| Arc transaction pending/evicted with no receipt | Hold UNKNOWN; no automatic replacement in v1; escalate after threshold | B/C | +| Graph lag, error, endpoint version drift, or empty result | Query `_meta`, compare chain head, pin deployment for demo, label stale/unhealthy, never authorize from absence | C | +| Queue redelivery | One queue attempt for submission, domain CAS/unique constraints, idempotent reconciliation | A | +| Shared-file merge conflicts | File ownership plus independent package commands; root composition owned by A | A | +| Credential/setup delays | Fakes unblock all tracks; human wizard and live setup occur in B2, before M4 | B | +| Schedule pressure | Preserve safety acceptance; cut optional webhooks, rolling policies, visual polish, and nonessential telemetry first | All | + +## 14. Definition of done for every implementation task + +- Outcome and non-goals match the task above; no hidden follow-up is required for claimed behavior. +- Public-seam test is written red first, then the smallest vertical behavior is implemented; tests avoid private implementation coupling. +- Relevant unit, contract, integration, concurrency, failure-injection, migration, lint, type, and build checks pass. +- Durable state and external settlement count are asserted where money or retries are involved. +- Security boundaries, input validation, integer money, logging redaction, testnet restriction, and safe-disable behavior are reviewed. +- Documentation, OpenAPI/fixtures, runbooks, and `.env.example` are updated without secrets. +- The branch/diff is focused and passes the repository's FreePi/CI/human-review policy. No agent merges. + +## 15. First implementation actions after plan approval + +1. Human merges the planning/agent-infrastructure change to `develop`; record the exact base SHA. +2. All three people complete M0 together and create their independent branches/worktrees. +3. Person A starts A1; Person B starts B1; Person C starts C1 simultaneously. +4. Hold one 15-minute daily contract check limited to proposed breaking changes, UNKNOWN classification, and risks. Status reporting must not become an approval dependency. +5. At M1 exit, re-estimate the calendar from evidence while preserving M2–M6 acceptance criteria and the rule that frontend remains last.