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
88 changes: 88 additions & 0 deletions .agent/context/20260906T180746Z-expanded-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Session Context: Expanded Independent Milestone Plan

## Date/time

- UTC: 2026-09-06T18:07:46Z

## User goal

Create a new branch, expand `plan.md`, and split the delivery plan into many smaller milestones for three coders so each coder can work asynchronously and close their work without waiting for another coder. Keep frontend work at the end.

## Original prompt/request

The user asked in Russian for a new branch and a substantially more detailed `plan.md`, followed by a `milestones` folder containing many small tasks assigned across three coders. The essential scheduling constraint is asynchronous progress with no cross-coder waiting to close a milestone; frontend remains last.

## Assumptions

- The requested branch should start from the current reviewed `agents-setup` merge commit because it contains the existing plan and reconciled agent policy.
- The correctly spelled directory is `milestones/`.
- Absolute independence is impossible for the final integrated product, so coder work-packet closure is independent while project Gates P4–P6 perform convergence without reopening completed packets.
- Existing same-day primary-source integration research remains the technical basis; this task adds no new version-sensitive integration claim.

## Plan

1. Load canonical policy, project/security/sponsor/test documents, repository skills, existing research, context, and the complete current plan.
2. Create `milestone/expand-product-plan` from the clean reviewed setup commit.
3. Replace the phase-oriented plan with a detailed three-lane operating plan and frozen contract pack.
4. Add 18 independently closable milestone packets, six per coder, containing small commit-sized tasks, acceptance evidence, tests, contract handoffs, and no-wait continuation.
5. Validate links, ownership, dependency rules, frontend ordering, Markdown, secrets, and Git scope.
6. Run required independent review against the exact candidate tree before any commit.

## Key decisions

- Replaced shared phase milestones with 18 independently closable work packets: A01–A06, B01–B06, and C01–C06.
- Each packet has at least five commit-sized tasks, explicit local acceptance evidence, a contract-pack handoff, non-goals, and a no-wait continuation instruction.
- A packet may depend only on the frozen v1 contract pack, the same coder's previous packet, and—only for frontend—the project Gate P4.
- Cross-coder artifacts are consumed through immutable contracts, schemas, fixtures, simulators, and public package entry points, never active branches or private implementation imports.
- A04/B04/C04 close against simulators. Project Gate P4 later composes exact reviewed packages and live testnet evidence without reopening the completed packets.
- Production frontend remains last: A05/B05/C05 cannot start until P4 freezes OpenAPI and recovery semantics.
- Added explicit path ownership, compatibility protocol, execution environments, project gates, integration procedure, escalation policy, scope-cut order, evidence manifest, and final readiness audit.

## Files/components touched

- `plan.md` — expanded 579-line master delivery plan.
- `milestones/README.md` — operating instructions for asynchronous packet execution.
- `milestones/CONTRACTS.md` — frozen v1 product/port/state/fixture contract pack.
- `milestones/coder-a/` — lane README and six domain/orchestration packets.
- `milestones/coder-b/` — lane README and six Privy/Arc packets.
- `milestones/coder-c/` — lane README and six reconciliation/Graph packets.
- `.agent/context/20260906T180746Z-expanded-plan.md` — this durable context record.

## Commands/checks

- Initial `git status --short --branch` — clean on `agents-setup`.
- Canonical policy, planning references, all three required repository skills, research, context policy, and existing `plan.md` — read completely.
- `git switch -c milestone/expand-product-plan` — branch created from reviewed merge commit `fcc48d37bd46f9ed727b33e1cc62fcc6a75f9a07`.
- Structural plan validator — PASS: 18 uniquely indexed packets, exactly six per coder, required sections present, at least five small tasks per packet, no cross-coder metadata dependency, all local links resolve, frontend-last guard present, and no placeholder/secret-shaped content.
- Planning-set measurement — 2,004 lines and 13,285 words; master `plan.md` is 579 lines and 4,870 words.
- Markdown/Git whitespace validation — PASS after formatting-only removal of Markdown hard-break spaces.
- Repository agent-policy validation — PASS.
- Conflict-marker and credential-shaped secret scans — PASS.
- Staged scope — 25 intended files: expanded `plan.md`, 23 files under `milestones/`, and this context record; no product code or unrelated file is included.

## External-doc findings

- No new browsing required. The expanded plan relies on `.agent/research/20260906-integration-decisions.md`, produced from primary sources earlier the same day.

## Unresolved questions

- None. The plan explicitly separates independently closable coder packets from unavoidable final product-integration gates.

## Git and PR state

- Branch: `milestone/expand-product-plan`
- Starting commit: `fcc48d37bd46f9ed727b33e1cc62fcc6a75f9a07`
- Candidate state: all 25 intended files staged; exact tree is captured again after this final context update.
- Commit: not created; Gate A must pass first.
- Push/PR: not performed.

## Review gates

- Gate A: local validation passed; fresh independent review pending the final staged tree identity.
- Gate B: not applicable; no PR requested.

## Handoff/next steps

1. Stage this final context update and capture the exact candidate tree.
2. Run one fresh Gate A review against that tree.
3. If PASS, commit without changing the reviewed tree; do not push or create a PR unless requested.
186 changes: 186 additions & 0 deletions milestones/CONTRACTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# Frozen v1 Contract Pack

Status: proposed freeze for project Gate P0
Owners: A owns canonical schemas; B and C own additive provider/recovery extensions
Change rule: expand-migrate-contract only

## 1. Immutable product semantics

- Cardinality: `1 Business Intent / N Attempts / <= 1 committed Settlement`.
- `business_intent_id` is stable across retries, redelivery, restarts, workers, and agents.
- OneShot durable state grants submission ownership.
- Privy authorizes and constrains the wallet action but is not the durable duplicate lock.
- Arc receipt plus expected ERC-20 Transfer evidence establishes committed settlement.
- The Graph is non-authoritative recovery/history evidence.
- Any possibly submitted but unconfirmed outcome is `UNKNOWN`; reconciliation precedes another submission.

## 2. Canonical identifiers and money

| Field | Rule | Redaction |
| --- | --- | --- |
| `business_intent_id` | caller-supplied UUID/opaque stable string; length bounded | safe operational ID |
| `attempt_id` | server-generated UUID; append-only attempt identity | safe operational ID |
| `correlation_id` | validated inbound or generated; never grants idempotency | safe if non-secret |
| `payload_fingerprint` | deterministic hash of normalized immutable payload | safe hash |
| `amount_atomic` | canonical unsigned base-10 integer string, no sign/decimal/exponent/whitespace | safe business datum; do not over-log |
| `asset` | exactly `USDC` | public |
| `network` | exactly `eip155:5042002` | public |
| `token_contract` | exactly `0x3600000000000000000000000000000000000000` | public |
| `recipient` | normalized EVM address; allowlist/policy checked | display only where required |
| `privy_idempotency_key` | stable derivative of intent identity; same key requires same body | never log raw if classified sensitive |
| `privy_reference_id` | stable lookup identity derived from intent | sanitized evidence only |

`purpose` is a bounded, non-secret display/audit string. It participates in the immutable payload fingerprint and is redacted from routine logs by default.

## 3. Create-intent command

```json
{
"business_intent_id": "018f-example-stable-id",
"recipient": "0x1111111111111111111111111111111111111111",
"amount_atomic": "1250000",
"asset": "USDC",
"network": "eip155:5042002",
"purpose": "Invoice INV-1001"
}
```

Normalization order is fixed: validate types and bounds; normalize EVM address; retain canonical integer string; encode asset/network constants; normalize the permitted purpose representation; serialize with a deterministic field order; hash the canonical bytes.

Identical ID and fingerprint is a replay. Identical ID with a different fingerprint is `INTENT_PAYLOAD_CONFLICT` and creates no new settlement right.

## 4. Public HTTP seam

| Operation | Success behavior | Stable error families |
| --- | --- | --- |
| `POST /v1/intents` | `202` accepted; `200` identical replay | `400 INVALID_REQUEST`, `401/403 UNAUTHORIZED`, `409 INTENT_PAYLOAD_CONFLICT`, `429 RATE_LIMITED` |
| `GET /v1/intents/{id}` | authoritative intent, attempts, settlement, sanitized evidence, version | `404 INTENT_NOT_FOUND` |
| `POST /v1/intents/{id}/reconcile` | enqueue/read-trigger only; never submit | `404 INTENT_NOT_FOUND`, `409 RECONCILIATION_NOT_ALLOWED` |
| `GET /v1/intents/{id}/recovery-view` | local authority plus labeled provider/index observations | `404 INTENT_NOT_FOUND`, `503 EVIDENCE_UNAVAILABLE` with local state retained |
| `GET /health/live` | process liveness only | `503` when process cannot serve |
| `GET /health/ready` | DB/config ready and Arc identity checks satisfied | `503 NOT_READY` with sanitized reason |

Mutations require service authentication, schema validation, request-size limits, correlation IDs, rate limits, and sanitized stable errors.

## 5. Port contracts

### AuthorizationPort.evaluate

Input includes intent/attempt identity, immutable request fingerprint, wallet/policy expectation, recipient, amount, network, token, method, native value, and correlation identity.

Results:

- `AUTHORIZED`: exact expected scope is permitted.
- `DENIED`: no submission; terminal authorization rejection for this attempt.
- `UNAVAILABLE`: retryable only before submission ownership crosses the external boundary.

### SettlementPort.submit

Input includes persisted Privy idempotency key/reference ID and exact request fingerprint.

Results:

- `CONFIRMED`: verified final Arc receipt and exactly matching Transfer evidence.
- `DEFINITELY_NOT_SUBMITTED`: narrow documented proof that no broadcast or external effect occurred.
- `POSSIBLY_SUBMITTED`: timeout, lost/truncated response, uncertain provider/RPC failure, crash window, or any doubt.

### EvidencePort.lookup

Results:

- `FINAL_SUCCESS`
- `FINAL_REVERT`
- `PENDING`
- `NOT_FOUND`
- `UNAVAILABLE`

`NOT_FOUND` alone never proves that no payment occurred.

### IndexViewPort.lookup

Returns observations plus indexed block, block timestamp, deployment ID, chain-head comparison, lag, `hasIndexingErrors`, retrieval time, and health classification: `FRESH`, `LAGGING`, `UNHEALTHY`, `UNAVAILABLE`, or `UNKNOWN_FRESHNESS`.

No IndexViewPort result grants settlement permission.

## 6. Durable state machine

| Current | Trigger | Next | Submission permission |
| --- | --- | --- | --- |
| `NONE` | validated intent accepted | `AUTHORIZING` | No |
| `AUTHORIZING` | policy authorizes | `READY` | No |
| `AUTHORIZING` | policy denies | `REJECTED` | No; terminal |
| `READY` | atomic owner grant persists request identity | `SUBMITTING` | Exactly one owner crosses boundary |
| `SUBMITTING` | verified final receipt/Transfer | `COMMITTED` | No; terminal |
| `SUBMITTING` | authoritative proof of no submission/final failure | `FAILED_SAFE` | Policy may schedule a new attempt |
| `SUBMITTING` | possible submission, crash, timeout, doubt | `UNKNOWN` | No |
| `UNKNOWN` | verified success | `COMMITTED` | No; terminal |
| `UNKNOWN` | authoritative matching final revert/no-effect proof | `FAILED_SAFE` | Policy may schedule a new attempt |
| `UNKNOWN` | pending/not found/unavailable/lag/error/contradiction | `UNKNOWN` | No; escalate by age |

All transitions are compare-and-set with monotonic versioning. No database transaction remains open during a provider/RPC call. Startup treats orphaned `SUBMITTING` work as reconciliation-required `UNKNOWN`, never as a new lease to submit.

## 7. Required durable records

- Business Intent primary identity and immutable fingerprint.
- Append-only Attempts with stage, timestamps, sanitized error class, and correlation ID.
- At most one Settlement row per Business Intent; provider transaction hash unique when present.
- Transactional outbox/job record.
- Persisted request body fingerprint, Privy request identities, wallet/policy identity, chain/token/recipient/amount, provider transaction ID/hash/nonce when learned.
- Receipt block/hash/status and verified Transfer log transaction hash plus log index.
- Append-only evidence observations with source, retrieval time, block/freshness, sanitized payload or digest, and authority label.

## 8. Fixture catalog

The canonical fixture root is `packages/contracts/fixtures/v1/`. Every fixture has a JSON Schema validation test and explicit expected durable transition and external-submission count.

| Fixture | Required expectation |
| --- | --- |
| `intent/accepted.json` | new intent, one queued execution, zero settlement at API boundary |
| `intent/replay-identical.json` | same durable intent, no duplicate job/right |
| `intent/replay-conflict.json` | `409`, explicit conflict, zero additional right |
| `authorization/allowed.json` | exact scope authorized |
| `authorization/denied-*.json` | wrong chain/token/method/recipient/value/amount denied, zero submission |
| `settlement/confirmed.json` | matching final receipt and one Transfer |
| `settlement/final-revert.json` | final failure, zero committed settlement |
| `settlement/pending.json` | remain unresolved, no resubmission |
| `settlement/lost-response.json` | `POSSIBLY_SUBMITTED` -> durable `UNKNOWN` |
| `settlement/mismatched-transfer.json` | not confirmed, hold safely |
| `evidence/not-found.json` | no permission change |
| `graph/empty.json` | labeled observation through indexed block, no permission change |
| `graph/lagging.json` | `LAGGING`, no permission change |
| `graph/indexing-error.json` | `UNHEALTHY`, no permission change |
| `graph/unavailable.json` | `UNAVAILABLE`, local authority still returned |

## 9. Simulator behavior

- Domain simulator exposes the HTTP seam and deterministic clock/IDs with an external-submission counter.
- Settlement simulator consumes canonical requests and emits each SettlementPort/EvidencePort result family without network access.
- Recovery simulator consumes local state plus provider/Arc/Graph fixtures and emits deterministic commands and labeled recovery view.
- Simulators reject unknown fixture versions and schema drift.
- Simulators never silently default an unknown enum to a successful or retryable result.

## 10. Public test seams

1. HTTP API plus returned durable state.
2. Worker task plus durable state and external-submission counter.
3. Adapter ports plus official-response fixtures.
4. Reconciliation command plus durable transition and evidence record.
5. Subgraph mapping/GraphQL query plus entity and `_meta` classification.
6. Browser UI through frozen OpenAPI/mock server after Gate P4.

## 11. Compatibility and ownership

- A owns base schemas, OpenAPI, error codes, state vocabulary, and fixture validation tooling.
- B owns provider-specific optional evidence fields and response-to-port classification fixtures.
- C owns index/recovery observation fields and reconciliation-decision fixtures.
- Optional fields must not change existing result meaning.
- Unknown enum values fail closed at boundaries.
- A breaking change requires ADR, new fixture version, dual-form simulator support, independent consumer migration, and later removal.

## 12. Freeze exit checklist

- Every field has type, normalization, authority, and redaction rules.
- Every terminal result has a durable transition and external-submission expectation.
- Every lane can run a simulator with no credentials.
- No unresolved item can change settlement cardinality, monetary precision, Privy enforcement, Arc identity, or `UNKNOWN` semantics.
- Human approval records the exact Git tree containing this contract pack.
Loading
Loading