# SignalCompact agent guide

SignalCompact deterministically condenses logs, test output, build errors, and command output. It does not run an AI model and does not execute submitted text. Its output is lossy by design. Recognized secrets are redacted, but no deterministic redactor can promise to detect every unknown secret format.

## Count and quote before uploading

Pricing counts Unicode code points in the decoded `content`, including whitespace. Headers, the JSON wrapper, options, and generated output are excluded. JavaScript strings use UTF-16, so do not use `text.length`:

~~~js
const inputCharacters = [...text].length;
const quote = await fetch(origin + "/v1/quote", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    inputCharacters,
    maxPriceAtomic: "250000"
  })
}).then(r => r.json());

if (!quote.withinBudget) throw new Error("SignalCompact quote exceeds budget");
~~~

Python already counts Unicode code points:

~~~python
import requests

input_characters = len(text)
quote = requests.post(
    origin + "/v1/quote",
    json={"inputCharacters": input_characters, "maxPriceAtomic": "250000"},
).json()
if not quote["withinBudget"]:
    raise RuntimeError("SignalCompact quote exceeds budget")
~~~

A quote is free, contains no source content, is signed, expires after five minutes, and requires no server-side database record. The formula is:

~~~text
2,000 + ceil(inputCodePoints / 5) atomic USDC
~~~

One atomic USDC is $0.000001. Examples: 100,000 characters cost 22,000 atomic ($0.022000); 1,000,000 cost 202,000 atomic ($0.202000); 10,000,000 cost 2,002,000 atomic ($2.002000).

## Condense

Send a UUIDv4 `Idempotency-Key`. Always send the same key for retries of the same content and options. Set an explicit `maxPriceAtomic`; SignalCompact never silently exceeds it.

~~~js
const response = await fetch(origin + "/v1/condense", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "accept": "application/json",
    "idempotency-key": crypto.randomUUID(),
    "payment-signature": paymentSignature
  },
  body: JSON.stringify({
    content: text,
    mode: "auto",
    maxOutputCharacters: 12000,
    quoteId: quote.quoteId,
    maxPriceAtomic: "250000"
  })
});
~~~

For `text/plain; charset=utf-8`, put options in query parameters or these headers:

- `X-SignalCompact-Mode`
- `X-SignalCompact-Max-Output-Characters`
- `X-SignalCompact-Quote`
- `X-SignalCompact-Max-Price-Atomic`

Modes are `auto`, `log`, `test`, `build`, and `command`. Output limits range from 2,000 through 32,000 characters and default to 12,000. Input is limited to both 10 million decoded code points and 10 MiB of UTF-8, whichever is reached first. Compression is rejected. Split larger files and quote each chunk independently.

If a client cannot count locally, it may omit `quoteId`. The server strictly decodes and counts the content, returns an exact fresh quote with `402`, and does not parse, redact, group, cache, or charge it.

When payments are enabled, authorize the quote-specific amount using x402 v2 `upto` and send `PAYMENT-SIGNATURE`. Settlement happens only after the complete result is produced. Malformed, oversized, expired, changed-content, over-budget, saturated, timed-out, and failed requests are not settled.

Use `Accept: text/markdown` for an equivalent Markdown response. Otherwise JSON is returned.

## Reading the result

Failures and failed tests rank first, then errors, warnings, unknown events, informational output, and debug output. Each group includes severity, frequency, first/last occurrence boundaries, exact occurrence line ranges, grouping method, and an exact redacted representative. Groups with up to 60 occurrences return every location. Higher-frequency groups return the first 50 and last 10 exact ranges plus `occurrenceLocationsOmitted`; this bound prevents location metadata from recreating the original log. Notices explicitly identify clipping, omitted groups, uncertain classification, and fallback parsing.

Grouping normalizes only structured variable fields such as timestamps, UUIDs, labeled request/process identifiers, durations, and memory addresses. It does not normalize unknown words, exception names, status codes, paths, arbitrary numbers, or error identifiers. Version 1 uses no fuzzy or semantic grouping.

A successful idempotency retry within five minutes returns the cached redacted result and receipt without another charge. If a settled result has left memory, the service returns `410` with its receipt rather than charging again. Reusing a key for different content or options returns `409`.

Consult `GET /v1/capabilities`, `GET /openapi.json`, and `GET /terms` before automated use.
