Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .agent/PROJECT_CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ The core cardinality is:
This document defines ownership and vocabulary. It is not a product
implementation plan.

## Primary production vertical

The first user is a company that lets an autonomous agent purchase a paid API
operation or digital result in USDC. The company approves one business
obligation; retries, restarts, queue redelivery, parallel workers, and multiple
agent instances must all converge on the same Business Intent and at most one
committed settlement.

The initial product exposes an agent API, execution worker, reconciliation
service, operator console, and audit/recovery timeline. Invoice payment,
procurement, subscriptions, and other agent-commerce workflows are later
verticals over the same durable intent contract.

## System ownership

- OneShot is authoritative for business-intent execution state, attempt state,
Expand Down
59 changes: 59 additions & 0 deletions .agent/context/20260906T201351Z-product-roadmap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Session Context: Product-First Production Roadmap

## Date/time

- UTC: 20260906T201351Z

## User goal

Rewrite OneShot as a product-first roadmap based on the final B2B paid-API-job
concept. Name the technology stack, organize delivery only by dependencies and
evidence gates, and explain how every domain component and A/B/C lane
contributes to the complete product.

## Key decisions

- The primary vertical is an autonomous B2B agent purchasing a paid API job or
digital result in USDC.
- The root plan starts with product vision, product flow, user surfaces, system
context, and the dependency-gated roadmap.
- The stack is explicit: Node.js, TypeScript, pnpm, Fastify, PostgreSQL, `pg`,
Graphile Worker, `viem`, Privy, Arc, The Graph, React/Vite, Vitest,
Testcontainers, Playwright, Matchstick, Docker Compose, and GitHub Actions.
- A/B/C lane READMEs state their technology focus. Packet metadata contains
ownership and dependencies only.
- `docs/DOMAIN_ARCHITECTURE.md` explains system context, domain records, state
ownership, component responsibilities, success and recovery sequences, port
boundaries, and A/B/C convergence.
- Post-MVP pilot stages remain separate from the P0-P6 implementation contract.

## Files/components touched

- `plan.md`
- `.agent/PROJECT_CONTEXT.md`
- `milestones/README.md`
- `milestones/coder-a/README.md`, `coder-b/README.md`, `coder-c/README.md`
- All 18 A/B/C packet files
- `docs/DOMAIN_ARCHITECTURE.md`
- This context record

## Validation

- All local Markdown links in `plan.md`, `milestones/`, and `docs/` resolve.
- Exactly 18 packet files remain.
- Packet headers contain no planning-size metadata.
- Mermaid CLI 11.17.0 rendered all 10 diagrams successfully.
- `git diff --check` passes.
- Gate A and Gate B were intentionally not run because the user explicitly
requested skipping the two-review procedure for the planning phase.

## References

- `C:\dev\thoughts\hackathon_eth_online_2026\brainstorming\11_OneShot — Privy Arc Graph Direction.md`
- `C:\dev\deeptrace\PLAN.md`

## Git state

- Branch: `milestone/product-roadmap`
- Base: `develop` at `5ef6a66313614e67b476f56c98f47c65344fb6ec`
- Pull request: `https://github.com/SWOFART/OneShot/pull/7`
264 changes: 264 additions & 0 deletions docs/DOMAIN_ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
# OneShot Domain Architecture

This document explains how each domain part contributes to the product promise:

`1 Business Intent / N Attempts / <= 1 committed Settlement`

## System context

```mermaid
flowchart LR
Operator[Company operator] -->|configures policy| Privy[Privy]
Agent[Autonomous agent] -->|creates or reuses intent| API[OneShot API]
Agent -.->|requests business job| Supplier[Paid API or supplier]
API --> Domain[OneShot domain]
Domain --> Ledger[(Authoritative ledger)]
Ledger --> Worker[Execution worker]
Worker --> Privy
Privy --> Arc[Arc USDC settlement]
Arc --> SupplierWallet[Supplier wallet]
Arc --> Index[The Graph index]
Ledger --> Recovery[Recovery service and audit view]
Recovery -->|provider lookup| Privy
Recovery -->|receipt and log lookup| Arc
Recovery -->|indexed history and freshness| Index
Recovery --> Agent
Recovery --> Operator
```

The paid service and its result remain outside OneShot's trust boundary.
OneShot guarantees payment cardinality and evidence for an approved obligation;
it does not certify supplier quality or delivery.

## Domain records and relationships

```mermaid
classDiagram
class BusinessIntent {
+business_intent_id
+payload_fingerprint
+recipient
+amount_atomic
+asset
+network
+purpose
+state
+version
}
class Attempt {
+attempt_id
+stage
+sanitized_result
+created_at
}
class Settlement {
+settlement_id
+provider_reference
+transaction_hash
+receipt_status
+transfer_log_index
}
class OutboxJob {
+job_id
+job_type
+delivery_state
}
class EvidenceObservation {
+source
+authority_class
+retrieved_at
+block_number
+freshness
+digest
}
class ReconciliationDecision {
+command
+expected_version
+reason
}

BusinessIntent "1" --> "0..*" Attempt : records execution tries
BusinessIntent "1" --> "0..1" Settlement : owns financial result
BusinessIntent "1" --> "0..*" OutboxJob : schedules work
BusinessIntent "1" --> "0..*" EvidenceObservation : collects evidence
BusinessIntent "1" --> "0..*" ReconciliationDecision : resolves uncertainty
Attempt "0..*" --> "0..1" Settlement : may produce
```

The Business Intent is the durable business identity. Attempts may repeat.
Settlement cardinality is enforced against the Business Intent, never against
an HTTP request, worker process, queue delivery, or agent session.

## State ownership

```mermaid
stateDiagram-v2
[*] --> AUTHORIZING: valid new intent
AUTHORIZING --> REJECTED: Privy policy denies
AUTHORIZING --> READY: exact action authorized
READY --> SUBMITTING: atomic ownership acquired
SUBMITTING --> COMMITTED: final receipt and Transfer verified
SUBMITTING --> FAILED_SAFE: authoritative no-effect proof
SUBMITTING --> UNKNOWN: timeout, crash, or possible submission
UNKNOWN --> COMMITTED: original payment verified
UNKNOWN --> FAILED_SAFE: authoritative final no-effect proof
UNKNOWN --> UNKNOWN: pending, absent, stale, unhealthy, or contradictory evidence
FAILED_SAFE --> AUTHORIZING: policy opens a new attempt
REJECTED --> [*]
COMMITTED --> [*]
```

Only the domain and PostgreSQL transition rules own these states. Privy, Arc,
The Graph, queues, and UI components report facts or perform bounded actions;
none may reinterpret the state machine.

## Component responsibilities

| Part | Owns | Must never own |
| --- | --- | --- |
| Agent API | Validation, create/replay/conflict response, status reads | Direct settlement or retry permission |
| Contracts package | Shared schemas, ports, enums, money and identity rules | Provider implementation |
| Domain package | State transitions, submission ownership, result classification | Network calls or UI |
| PostgreSQL storage | Durable uniqueness, versions, attempts, settlement and evidence records | Business decisions outside domain commands |
| Transactional outbox | Atomic creation of work with domain state | Duplicate-payment prevention by itself |
| Graphile Worker | Deliver execution and reconciliation jobs | Authority to pay because a job was redelivered |
| Privy adapter | Wallet authorization, policy checks, provider request identity | Durable Business Intent authority |
| Arc adapter | Transaction construction, submission, receipt and Transfer verification | Deciding whether another attempt is allowed |
| The Graph Subgraph/client | Indexed transfer history, deployment identity, freshness and health | Proof that an absent payment never happened |
| Reconciliation engine | Combine bound evidence and emit versioned safe commands | Settlement submission |
| Operator console | Explain state, evidence, policy and safe recovery actions | Force-pay or bypass controls |
| Telemetry/runbooks | Reveal failures, lag, `UNKNOWN` age and safe-disable state | Secrets or mutation of financial truth |

## Successful settlement sequence

```mermaid
sequenceDiagram
participant Agent
participant API as OneShot API
participant DB as PostgreSQL
participant Worker
participant Privy
participant Arc
participant Graph as The Graph

Agent->>API: POST Business Intent with stable ID
API->>DB: Insert intent and outbox job atomically
DB-->>API: New intent or identical replay
API-->>Agent: Authoritative intent state
Worker->>DB: Claim AUTHORIZING attempt
Worker->>Privy: Evaluate exact wallet policy
Privy-->>Worker: AUTHORIZED
Worker->>DB: Persist AUTHORIZING to READY
Worker->>DB: Atomically persist SUBMITTING and request identity
Worker->>Privy: Submit the authorized transfer
Privy->>Arc: Broadcast ERC-20 USDC transaction
Arc-->>Worker: Final receipt and logs
Worker->>Worker: Verify chain, token, recipient, amount, and Transfer
Worker->>DB: Persist COMMITTED and settlement identity
Arc-->>Graph: Transfer event indexed independently
Agent->>API: GET intent status
API-->>Agent: One committed settlement with evidence
```

## Ambiguous submission and recovery

```mermaid
sequenceDiagram
participant Worker
participant DB as PostgreSQL
participant Privy
participant Arc
participant Reconciler
participant Graph as The Graph

Worker->>DB: Persist SUBMITTING and request identity
Worker->>Privy: Submit authorized transfer
Privy->>Arc: Broadcast transaction
Arc--xWorker: Success response is lost
Worker->>DB: Persist UNKNOWN
Reconciler->>DB: Load intent, request identity, and observations
Reconciler->>Privy: Lookup original provider request
Reconciler->>Arc: Lookup exact transaction receipt and Transfer
Reconciler->>Graph: Query indexed observation plus freshness
Note over Reconciler,Graph: Graph may locate or corroborate activity but cannot authorize a retry
Reconciler->>Domain: Emit MARK_COMMITTED with expected version
Domain->>DB: Compare and set UNKNOWN to COMMITTED
Worker->>DB: Check the same intent after redelivery
DB-->>Worker: Terminal state means no second submission
```

## Port and adapter boundary

```mermaid
flowchart LR
Domain[Domain state machine]
Reconciliation[Reconciliation engine]
Command[Versioned reconciliation command]

Domain --> Auth[AuthorizationPort]
Domain --> Settle[SettlementPort]
Reconciliation --> Evidence[EvidencePort]
Reconciliation --> Index[IndexViewPort]
Reconciliation --> Command
Command --> Domain

Auth --> Privy[Privy adapter]
Settle --> ArcWrite[Arc write adapter]
Evidence --> PrivyRead[Privy lookup]
Evidence --> ArcRead[Arc receipt and log lookup]
Index --> GraphClient[Graph client]

Privy --> External1[Privy service]
ArcWrite --> External2[Arc RPC]
PrivyRead --> External1
ArcRead --> External2
GraphClient --> External3[The Graph]
```

The domain consumes stable result families. Adapters translate external SDK,
RPC, and GraphQL behavior into those results. External response shapes never
leak into the state machine.

## A/B/C ownership and convergence

```mermaid
flowchart TB
Contracts[Frozen contracts, fixtures, and simulators]

subgraph A[Coder A - authority and orchestration]
A1[Contracts and OpenAPI]
A2[PostgreSQL intent ledger]
A3[Atomic worker]
A4[Composition and operations]
A1 --> A2 --> A3 --> A4
end

subgraph B[Coder B - authorization and settlement]
B1[Privy/Arc compatibility]
B2[Request, policy, receipt]
B3[Live settlement harness]
B4[Ambiguity-safe adapters]
B1 --> B2 --> B3 --> B4
end

subgraph C[Coder C - evidence and recovery]
C1[Subgraph and health]
C2[Reconciliation engine]
C3[Failure injection]
C4[Recovery service]
C1 --> C2 --> C3 --> C4
end

Contracts --> A1
Contracts --> B1
Contracts --> C1
A4 --> P4[P4 composition]
B4 --> P4
C4 --> P4
P4 --> UI[Composed product interface]
UI --> Release[Release evidence]
```

Each coder closes backend packets against frozen simulators. P4 is where exact
reviewed packages replace simulators. Integration failures return to the owning
lane instead of producing shared ad hoc edits.
4 changes: 2 additions & 2 deletions milestones/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ Use these states in the PR or project tracker:
- Never depend on another coder’s active branch.
- Never import another coder’s private implementation path.
- Consume only frozen schemas, fixtures, simulators, or reviewed package exports.
- Preserve backward compatibility within a delivery wave.
- Preserve backward compatibility within a delivery phase.
- Convert breaking proposals into additive versioned contracts.
- A project integration failure creates a focused ticket for the owning lane; it does not reopen unrelated completed packets.
- Status meetings and review availability do not gate coding. Record assumptions and continue fail-closed.

## Small-task sizing

Every numbered task inside a packet should fit one coherent commit, normally two to six focused hours. If a task cannot be reviewed independently, split it by observable behavior, not by internal layer.
Every numbered task inside a packet should produce one coherent, independently reviewable commit. If it cannot be reviewed independently, split it by observable behavior, not by internal layer.

Good split: schema + migration, replay behavior, conflict behavior, concurrency proof.
Bad split: “all database code,” “all tests,” or “finish integration.”
Expand Down
1 change: 0 additions & 1 deletion milestones/coder-a/A01-foundation-contracts.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# A01 — Foundation and Contract Runtime

Owner: Coder A
Forecast: 3 working days
Branch: `milestone/a01-foundation-contracts`
Depends on: frozen `milestones/CONTRACTS.md` only
Next: A02 immediately after closure
Expand Down
1 change: 0 additions & 1 deletion milestones/coder-a/A02-durable-intents.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# A02 — Durable Intent Ledger and API

Owner: Coder A
Forecast: 3 working days
Branch: `milestone/a02-durable-intents`
Depends on: A01 only
Next: A03 immediately after closure
Expand Down
1 change: 0 additions & 1 deletion milestones/coder-a/A03-atomic-worker.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# A03 — Atomic At-Most-Once Worker

Owner: Coder A
Forecast: 3 working days
Branch: `milestone/a03-atomic-worker`
Depends on: A02 only
Next: A04 immediately after closure
Expand Down
1 change: 0 additions & 1 deletion milestones/coder-a/A04-restart-operations-composition.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# A04 — Restart Safety, Operations, and Simulator Composition

Owner: Coder A
Forecast: 4 working days
Branch: `milestone/a04-restart-operations-composition`
Depends on: A03 only
Next: hold A05 until project Gate P4; improve backend evidence while waiting
Expand Down
Loading
Loading