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
79 changes: 79 additions & 0 deletions .agent/context/20260907T134104Z-a01-foundation-contracts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Session Context: A01 foundation contracts

## Date/time

- UTC: 2026-09-07T13:41:04Z

## User goal

Implement Coder A's first milestone so B and C can consume stable contracts,
fixtures, and a deterministic simulator from `develop`.

## Original prompt/request

Start implementing the plan as Coder A.

## Assumptions

- A01 is the first dependency-free Coder A milestone.
- Arc Testnet is the enabled launch profile; mainnet support is future work.
- Provider integrations remain outside A01.

## Plan

1. Complete local validation and review of the A01 candidate tree.
2. Publish the reviewed contract pack through a pull request to `develop`.
3. Continue with A02 after A01 closes.

## Key decisions

- Money crosses JSON boundaries as canonical unsigned integer strings.
- Parsers reject unknown enum members and unexpected request fields.
- Generated OpenAPI, JSON Schema, and TypeScript artifacts share one source.
- The simulator injects time and IDs and counts external submissions explicitly.

## Files/components touched

- Root workspace/toolchain configuration and locked dependencies.
- `packages/contracts`: runtime parsers, OpenAPI, schemas, fixtures, validators.
- `packages/testkit-domain`: deterministic in-memory domain simulator.
- Stack CI: contract drift, fixture validation, compilation, and tests.

## Commands/checks

- `pnpm install --frozen-lockfile` - pass.
- `pnpm format:check` - pass.
- `pnpm lint` - pass.
- `pnpm typecheck` - pass.
- `pnpm check:generated` - pass after deterministic regeneration.
- `pnpm validate:fixtures` - pass, 9 fixtures.
- `pnpm test` - pass, 4 files and 30 tests.
- `contracts.schema.json` SHA-256 -
`4436ED9992662D749A9E41779453513E2A3DAFCF3B4306146D87593132BB6297`.

## External-doc findings

- None; implementation follows the frozen repository contract pack.

## Unresolved questions

- None for A01.

## Git and PR state

- Branch: `milestone/a01-foundation-contracts`
- Base: `develop` at `8be8d09b8ab5da19031af28fcee9da128a16f82b`
- Commit: uncommitted candidate
- PR: not created
- CI: not run

## Review gates

- Gate A: NOT RUN
- Gate B: NOT RUN

## Handoff/next steps

1. Stage and inspect the complete candidate tree.
2. Run the configured pre-push reviewer against the immutable tree.
3. Commit, push, and open the draft pull request after Gate A passes.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Bug report
description: Create a report to help reproduce and fix a defect.
title: "[Bug]: "
title: '[Bug]: '
body:
- type: textarea
id: description
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/milestone-proposal.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Milestone or feature proposal
description: Propose a measurable product, engineering, or feature outcome.
title: "[Proposal]: "
title: '[Proposal]: '
body:
- type: textarea
id: outcome
Expand Down
16 changes: 14 additions & 2 deletions .github/workflows/stack-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: "22"
node-version-file: '.nvmrc'

- name: Lint Markdown
run: npx --yes markdownlint-cli2@0.18.1 "**/*.md" "#node_modules"
Expand Down Expand Up @@ -74,7 +74,7 @@ jobs:
- uses: actions/setup-node@v4
if: steps.workspace.outputs.enabled == 'true'
with:
node-version: "22"
node-version-file: '.nvmrc'
cache: pnpm

- name: Install locked dependencies
Expand All @@ -94,3 +94,15 @@ jobs:
- name: Run TypeScript compiler
if: steps.workspace.outputs.enabled == 'true'
run: pnpm typecheck

- name: Check generated contracts
if: steps.workspace.outputs.enabled == 'true'
run: pnpm check:generated

- name: Validate contract fixtures
if: steps.workspace.outputs.enabled == 'true'
run: pnpm validate:fixtures

- name: Run tests
if: steps.workspace.outputs.enabled == 'true'
run: pnpm test
11 changes: 4 additions & 7 deletions .markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
"config": {
"MD013": false,
"MD024": {
"siblings_only": true
"siblings_only": true,
},
"MD033": false,
"MD041": false,
"MD060": false
"MD060": false,
},
"ignores": [
".git/**",
"node_modules/**"
]
}
"ignores": [".git/**", "node_modules/**"],
}
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24.19.0
7 changes: 7 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dist
coverage
node_modules
pnpm-lock.yaml
packages/contracts/generated
packages/contracts/openapi
packages/contracts/src/generated
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 100,
"semi": true,
"singleQuote": true,
"trailingComma": "all"
}
23 changes: 23 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import eslint from '@eslint/js';
import globals from 'globals';
import tseslint from 'typescript-eslint';

export default tseslint.config(
{
ignores: ['**/coverage/**', '**/dist/**', '**/generated/**'],
},
eslint.configs.recommended,
...tseslint.configs.recommended,
{
languageOptions: {
globals: globals.node,
},
},
{
files: ['**/*.ts'],
rules: {
'@typescript-eslint/consistent-type-imports': 'error',
'@typescript-eslint/no-import-type-side-effects': 'error',
},
},
);
34 changes: 34 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "oneshot",
"version": "0.1.0",
"private": true,
"type": "module",
"packageManager": "pnpm@11.19.0",
"engines": {
"node": "24.19.0",
"pnpm": "11.19.0"
},
"scripts": {
"build": "tsc -b",
"check:generated": "pnpm --filter @oneshot/contracts check:generated",
"clean": "tsc -b --clean",
"format": "prettier --write \"**/*.{ts,mts,mjs,json,jsonc,yml,yaml}\"",
"format:check": "prettier --check \"**/*.{ts,mts,mjs,json,jsonc,yml,yaml}\"",
"generate": "pnpm --filter @oneshot/contracts generate",
"lint": "eslint .",
"test": "pnpm build && vitest run",
"typecheck": "tsc -b --pretty false",
"validate:fixtures": "pnpm --filter @oneshot/contracts validate:fixtures"
},
"devDependencies": {
"@eslint/js": "10.0.1",
"@types/node": "24.13.3",
"eslint": "10.10.0",
"globals": "17.4.0",
"prettier": "3.9.6",
"typescript": "6.0.3",
"typescript-eslint": "8.69.0",
"vite": "8.0.0",
"vitest": "5.0.0"
}
}
17 changes: 17 additions & 0 deletions packages/contracts/fixtures/v1/authorization/allowed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "v1",
"kind": "authorization.allowed",
"intent": {
"business_intent_id": "018f-example-stable-id",
"recipient": "0x1111111111111111111111111111111111111111",
"amount_atomic": "1250000",
"asset": "USDC",
"network": "eip155:5042002",
"purpose": "Invoice INV-1001"
},
"result_kind": "AUTHORIZED",
"expected": {
"intent_state": "READY",
"external_submission_count": 0
}
}
18 changes: 18 additions & 0 deletions packages/contracts/fixtures/v1/authorization/denied-recipient.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": "v1",
"kind": "authorization.denied",
"intent": {
"business_intent_id": "018f-example-stable-id",
"recipient": "0x1111111111111111111111111111111111111111",
"amount_atomic": "1250000",
"asset": "USDC",
"network": "eip155:5042002",
"purpose": "Invoice INV-1001"
},
"result_kind": "DENIED",
"expected": {
"intent_state": "REJECTED",
"external_submission_count": 0,
"error_code": "FORBIDDEN"
}
}
17 changes: 17 additions & 0 deletions packages/contracts/fixtures/v1/evidence/not-found.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "v1",
"kind": "evidence.not-found",
"intent": {
"business_intent_id": "018f-example-stable-id",
"recipient": "0x1111111111111111111111111111111111111111",
"amount_atomic": "1250000",
"asset": "USDC",
"network": "eip155:5042002",
"purpose": "Invoice INV-1001"
},
"result_kind": "NOT_FOUND",
"expected": {
"intent_state": "UNKNOWN",
"external_submission_count": 0
}
}
21 changes: 21 additions & 0 deletions packages/contracts/fixtures/v1/index/candidate-one.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": "v1",
"kind": "index.candidate-one",
"intent": {
"business_intent_id": "018f-example-stable-id",
"recipient": "0x1111111111111111111111111111111111111111",
"amount_atomic": "1250000",
"asset": "USDC",
"network": "eip155:5042002",
"purpose": "Invoice INV-1001"
},
"result_kind": "FRESH",
"expected": {
"intent_state": "UNKNOWN",
"external_submission_count": 0
},
"observation": {
"candidate_count": 1,
"health": "FRESH"
}
}
17 changes: 17 additions & 0 deletions packages/contracts/fixtures/v1/intent/accepted.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "v1",
"kind": "intent.accepted",
"intent": {
"business_intent_id": "018f-example-stable-id",
"recipient": "0x1111111111111111111111111111111111111111",
"amount_atomic": "1250000",
"asset": "USDC",
"network": "eip155:5042002",
"purpose": "Invoice INV-1001"
},
"result_kind": "ACCEPTED",
"expected": {
"intent_state": "AUTHORIZING",
"external_submission_count": 0
}
}
18 changes: 18 additions & 0 deletions packages/contracts/fixtures/v1/intent/replay-conflict.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": "v1",
"kind": "intent.replay-conflict",
"intent": {
"business_intent_id": "018f-example-stable-id",
"recipient": "0x1111111111111111111111111111111111111111",
"amount_atomic": "1250000",
"asset": "USDC",
"network": "eip155:5042002",
"purpose": "Invoice INV-1001"
},
"result_kind": "INTENT_PAYLOAD_CONFLICT",
"expected": {
"intent_state": "AUTHORIZING",
"external_submission_count": 0,
"error_code": "INTENT_PAYLOAD_CONFLICT"
}
}
17 changes: 17 additions & 0 deletions packages/contracts/fixtures/v1/intent/replay-identical.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "v1",
"kind": "intent.replay-identical",
"intent": {
"business_intent_id": "018f-example-stable-id",
"recipient": "0x1111111111111111111111111111111111111111",
"amount_atomic": "1250000",
"asset": "USDC",
"network": "eip155:5042002",
"purpose": "Invoice INV-1001"
},
"result_kind": "REPLAY_IDENTICAL",
"expected": {
"intent_state": "AUTHORIZING",
"external_submission_count": 0
}
}
23 changes: 23 additions & 0 deletions packages/contracts/fixtures/v1/settlement/confirmed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"version": "v1",
"kind": "settlement.confirmed",
"intent": {
"business_intent_id": "018f-example-stable-id",
"recipient": "0x1111111111111111111111111111111111111111",
"amount_atomic": "1250000",
"asset": "USDC",
"network": "eip155:5042002",
"purpose": "Invoice INV-1001"
},
"result_kind": "CONFIRMED",
"expected": {
"intent_state": "COMMITTED",
"external_submission_count": 1
},
"settlement": {
"provider_reference_id": "provider-ref-001",
"transaction_hash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"block_number": "100",
"transfer_log_index": 0
}
}
17 changes: 17 additions & 0 deletions packages/contracts/fixtures/v1/settlement/lost-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "v1",
"kind": "settlement.lost-response",
"intent": {
"business_intent_id": "018f-example-stable-id",
"recipient": "0x1111111111111111111111111111111111111111",
"amount_atomic": "1250000",
"asset": "USDC",
"network": "eip155:5042002",
"purpose": "Invoice INV-1001"
},
"result_kind": "POSSIBLY_SUBMITTED",
"expected": {
"intent_state": "UNKNOWN",
"external_submission_count": 1
}
}
Loading
Loading