# Requester Guide: Register `scheduled_http_get_batch.v1`

This is the stable Human requester guide for `scheduled_http_get_batch.v1`
version `1.0.0`. It is a `NON_NORMATIVE_DERIVED_GUIDE`; it grants no payment,
deployment, or external-write authority. The Registration UI, Origin Control
service, server validation, x402 challenge, Wallet, settlement evidence, and
committed registration readback remain authoritative.

Start here:

`https://kari.mayim-mayim.com/agent-offer-register.html`

Fixed definition identity:

- Task type: `scheduled_http_get_batch.v1`
- Task Definition version: `1.0.0`
- Task Definition digest:
  `ac1a672f92c29e54fbd6f510854a80a9da656162e4f93ab4cc497bbe9fa79e25`
- Canonical fixture SHA-256:
  `c6a65b9ed014de3c89d51afae41444044d1e360259e80eae52c6e4acfd1cc641`
- Registration route: `POST /api/bazaar/task-offers`

Read the sibling `manifest.json` and stop if its component hashes, Definition
digest, or fixture identity do not match the published files.

## Choose the correct starting path

- If you do not possess an active Offer Control Key, complete **New Offer
  Control Key: Steps 1 through 4** below.
- If you already possess an active Offer Control Key, use **Existing active
  Offer Control Key**. Do not repeat Origin verification.

## Security boundary: two different values

`PUBLIC_VERIFICATION_VALUE` is public. Copy it exactly into the verification
JSON property `nonce` at JSON Pointer `/nonce`.

`OFFER_CONTROL_KEY` is private. It is never inserted into any JSON. Never put
it in a URL, Verification JSON, Task Manifest, multipart body, browser
persistence, Cookie, log, analytics event, error text, or Preview. The page
sends it only in the approved `X-LN-Offer-Control-Key` header boundary.

The browser does not persist the key. Retain it in an appropriate secure
secret store after it is revealed; refreshing or closing the page discards the
page-memory copy.

## New Offer Control Key: Steps 1 through 4

Open **Offer Control** from the Scheduled HTTP GET Batch card and perform these
steps in order.

### Step 1 — Download the Verification JSON

Select **DOWNLOAD VERIFICATION JSON**. The downloaded filename is exactly
`ln-church-domain-sponsor.json`.

The document has exactly four properties and no additional property:

```json
{
  "schema_version": "ln_church.origin_control.v1",
  "origin_control_id": "<PAGE_GENERATED_ORIGIN_CONTROL_ID>",
  "nonce": "<PUBLIC_VERIFICATION_VALUE>",
  "expires_at": "<RFC3339_UTC_WHOLE_SECOND_Z>"
}
```

Canonical verification schema:

- `schema_version` is the exact constant `ln_church.origin_control.v1`;
- `origin_control_id` is the identifier already placed in the downloaded
  template and must match `^oc_[a-f0-9]{32}$`;
- after Step 2.5, `nonce` must be exactly 43 unpadded base64url characters
  matching `^[A-Za-z0-9_-]{43}$`; it is the only field edited; and
- `expires_at` is the template's RFC 3339 UTC whole-second timestamp ending in
  `Z`.

Do not change the generated Origin Control ID or expiry.

### Step 2 — Generate the Public Verification Value

Select **GENERATE**. The page makes one idempotent prepare request and displays
the exact public value to copy. The Copy action copies exactly the string that
belongs inside the JSON `nonce` value; no decoding, prefix removal, wrapping,
or other transformation is required.

The pending verification expires 60 minutes after the page-memory template is
created. A transient Generate failure retries the same prepare request
identity. After a successful Generate, another click does not create a
replacement value for that template. If the template expires, reload and
restart at Step 1.

The service prepares the private Offer Control Key at this boundary, but the
UI keeps it in page memory and does not reveal it yet.

### Step 2.5 — Edit and publish the exact JSON

The exact receiving property is `nonce`; its exact JSON Pointer is `/nonce`.

Before, as downloaded:

```json
{
  "schema_version": "ln_church.origin_control.v1",
  "origin_control_id": "oc_0123456789abcdef0123456789abcdef",
  "nonce": "<PUBLIC_VERIFICATION_VALUE>",
  "expires_at": "2026-08-27T08:30:00Z"
}
```

After, using the exact value copied in Step 2:

```json
{
  "schema_version": "ln_church.origin_control.v1",
  "origin_control_id": "oc_0123456789abcdef0123456789abcdef",
  "nonce": "<PASTE THE STEP 2 VALUE HERE>",
  "expires_at": "2026-08-27T08:30:00Z"
}
```

Replace only the placeholder value. Do not rename the property. The
`<PASTE THE STEP 2 VALUE HERE>` text above is an editing instruction; replace
it with the actual 43-character Step 2 value before publication. In your real
file, preserve the actual `origin_control_id` and `expires_at` downloaded in
Step 1.

Publish the completed JSON at this exact path on the site you control:

`/.well-known/ln-church-domain-sponsor.json`

The resulting full URL must therefore be:

`https://<YOUR_PUBLIC_HOST>/.well-known/ln-church-domain-sponsor.json`

Replace `<YOUR_PUBLIC_HOST>` with the real canonical public hostname. Reserved
hosts ending in `.example`, `.invalid`, `.localhost`, `.local`, `.internal`, or
`.test` are non-runnable and rejected, as are literal IP targets.

The inserted value is the public verification value. It is not the Offer
Control Key. The Offer Control Key must remain absent from the downloaded and
published JSON.

### Step 3 — Enter the full HTTPS URL and verify the Origin

Publish the completed JSON, enter its full canonical HTTPS URL in Step 3, and
select **VERIFY**. The server fetches and validates the exact document and
Origin. Local URL acceptance is not authoritative verification.

An activated Origin Control is valid for one year from authoritative
verification unless it is revoked earlier by the operator. Expired or revoked
Origin Control is inactive, and its key cannot authorize registration.

### Step 4 — Reveal and retain the Offer Control Key

The key becomes visible only after the authoritative Origin verification
returns an active result. Copy and retain it securely. It is shown through the
page-memory secret boundary and is also placed in the Offer Configuration key
input for the current page only. Never publish it or insert it into a JSON
document.

## Existing active Offer Control Key

From a fresh page:

1. Open **Scheduled HTTP GET Batch → CONFIGURE OFFER**.
2. Enter the existing active Offer Control Key.
3. Do not repeat Origin verification.
4. Prepare and upload a Manifest whose URLs use the same authorized Origin.
5. Continue through validation, Preview, explicit confirmation, and
   registration.

The backend remains authoritative for key format and verifier, `ACTIVE` state,
expiry, revocation, exact Origin binding, and Manifest Origin binding. A wrong,
expired, revoked, or different-Origin key fails visibly.

## Prepare the local Task Manifest: edit `/urls` only

Create or download `manifest.json`. It has exactly these properties:

```json
{
  "schema_version": "ln_church.http_get_batch_manifest.v1",
  "method": "GET",
  "urls": [
    "https://operator.example.org/health",
    "https://operator.example.org/api/status"
  ]
}
```

Edit only string values inside the `urls` array at JSON Pointer `/urls`.

- Include 1 through 10 unique URLs.
- Every URL must use canonical HTTPS port 443, the exact Origin authorized by
  the key, and no credentials, fragment, or literal IP target.
- Delete unused placeholders and their associated commas.
- Keep `schema_version` and `method` unchanged; do not add or rename fields.
- Do not place an Offer Control Key, Wallet value, public verification value,
  or other credential in the Manifest.
- Save valid JSON and upload the local file.

The UI visibly reports the selected filename, canonical Origin, endpoint
count, RFC 8785 Manifest SHA-256, and local validation state. Filename is
informational, not Manifest identity. Server validation remains authoritative.

## Complete Offer Configuration and registration

Use this exact Human sequence:

1. Enter the Offer Control Key.
2. Prepare and upload the local Task Manifest; edit `/urls` only.
3. Enter Requested Execution Time as a whole minute in the browser's real
   local timezone.
4. Review the displayed timezone, UTC offset, local wall time, and canonical
   UTC `scheduled_at`. A nonexistent DST wall time and an ambiguous DST
   overlap are rejected visibly.
5. Select Plan `C50`, `C500`, or `C5000`.
6. Read and accept the Agreement.
7. Complete all five checklist items: key, time, Manifest, Plan, Agreement.
8. Select **VALIDATE OFFER**. Local validation runs first.
9. The page sends one unpaid multipart request for authoritative validation.
10. The server returns the canonical x402 `402` challenge.
11. Connect a Base Wallet account. Connection is non-signing.
12. Review the complete frozen Human-visible Preview.
13. Explicitly select **CONFIRM PAYMENT**.
14. Approve the fixed Wallet authorization.
15. The page dispatches the exact frozen paid Request at most once.
16. Wait for settlement/finality and an authoritative `OPEN` result, or use
    the existing registration-intent readback path for ambiguity.

Requested Execution Time must be **strictly more than 90 minutes** after the
current instant and **no more than 7 days** after it. Exact `now + 90 minutes`
is invalid; exact `now + 7 days` is valid. The boundary is rechecked before
authorization, so an expired Preview must be validated again.

Plans and registration amounts are:

| Plan | Capacity | Base USDC amount |
| --- | ---: | ---: |
| `C50` | 50 | `1000000` atomic (1 USDC) |
| `C500` | 500 | `10000000` atomic (10 USDC) |
| `C5000` | 5,000 | `100000000` atomic (100 USDC) |

The multipart request has exactly two parts: canonical JSON `metadata` and the
local JSON `manifest`. The key remains in its header boundary and never enters
the multipart body.

## Frozen pre-payment Preview

The Preview is produced only after authoritative unpaid validation and Wallet
account connection. Before the Human selects **CONFIRM PAYMENT**, both payment
authorization count and paid dispatch count are zero.

Review every displayed field:

- canonical Origin, uploaded filename, Manifest SHA-256, endpoint count;
- local execution time, timezone, UTC offset, canonical UTC `scheduled_at`;
- Plan and capacity;
- Task type, Task Definition version and digest, fixture SHA-256;
- x402 version and scheme, network, Base USDC asset;
- exact challenge amount in atomic units and USDC, configured `pay_to`;
- paid method and resource, selected Wallet payer; and
- `registration_intent_id`.

The Preview freezes the exact Origin, Manifest bytes and digest, metadata,
schedule conversion, Plan, challenge and accepted requirement, payer,
multipart bytes, and paid Request used later. Changing an economic input,
Wallet account, network, or the validity window invalidates the Preview. The
Preview never contains the Offer Control Key or a payment authorization.

## Payment retry and recovery

- **Wallet connection failure:** reconnect using the same frozen unpaid
  intent, challenge, selected requirement, Manifest, multipart Request, and
  input revision.
- **Signature-response loss or rejection:** only another explicit Human action
  may retry. Reuse the same fixed authorization attempt, EIP-712 payload,
  nonce, and frozen Request. No paid dispatch occurs before a valid
  authorization is returned.
- **Paid-dispatch ambiguity:** use only
  `GET /api/agent/task-offer-registrations/{registration_intent_id}` with the
  same key through the existing UI recovery action. Do not re-sign, create a
  replacement intent, make a replacement payment, or dispatch a substitute
  Request.

Authoritative `business_commit_state=COMMITTED` with its Task identity, or the
exact paid response with `status=OPEN`, is success. `CONFIRMING`, `UNKNOWN`,
`UNKNOWN_EXHAUSTED`, `POTENTIALLY_SPENDABLE`, and `COMMIT_BLOCKED` are not
permission to pay again. Continue bounded readback; server state decides
settlement, finality, and commit.

The Offer Control Key, challenge, authorization attempt, signed payment, and
recovery binding stay out of URLs, JSON documents, browser persistence,
Cookies, logs, analytics, errors, and Preview. Never request or expose a Wallet
private key or seed phrase.
