# Touchdown InferGuard agent ingest skill

Use this when a coding agent, local proxy, or CLI needs to measure an AI coding workflow with Touchdown InferGuard. Do not ask the human to upload a file by hand unless automation is unavailable.

## Goal

Find the redacted trace, validate it locally, submit it to the Touchdown control-plane API, poll the session, and return the report link.

## Rules

- Prefer CLI/API ingest over browser upload.
- Never submit raw prompts, source code blobs, private keys, API keys, bearer tokens, or credential-shaped strings.
- Stop and report the exact error if the API returns `raw_prompt_rejected`, `secrets_detected`, `invalid_jsonl_line`, `empty_trace`, or `trace_too_large`.
- Do not try a different trace file unless the user explicitly provides one.

## Find the trace

If the user gave a path, use it. Otherwise search:

```bash
find "$PWD" "$HOME/Projects" \
  -path '*/out/traces/*.jsonl' -o \
  -path '*/out/evidence/*.jsonl' -o \
  -name 'proxy-events.jsonl' \
  2>/dev/null | sort
```

Common Touchdown dogfood trace:

```text
/Users/chen/Projects/Touchdown-Labs/inferguard/out/traces/proxy-events.jsonl
```

## Validate locally

```bash
TRACE_PATH="/absolute/path/to/trace.jsonl"

test -s "$TRACE_PATH"
test "$(wc -c < "$TRACE_PATH")" -le 20971520

python3 - "$TRACE_PATH" <<'PY'
import json, re, sys
path = sys.argv[1]
patterns = [
    re.compile(r"sk-[A-Za-z0-9_-]{16,}"),
    re.compile(r"AKIA[A-Z0-9]{12,}"),
    re.compile(r"ghp_[A-Za-z0-9]{20,}"),
    re.compile(r"-----BEGIN [A-Z ]*PRIVATE KEY"),
]
text = open(path, "r", encoding="utf-8").read()
for pattern in patterns:
    if pattern.search(text):
        raise SystemExit("secrets_detected")
events = 0
for line_no, line in enumerate(text.splitlines(), 1):
    if not line.strip():
        continue
    try:
        row = json.loads(line)
    except Exception:
        raise SystemExit(f"invalid_jsonl_line:{line_no}")
    if isinstance(row.get("prompt"), str) and row["prompt"].strip():
        raise SystemExit(f"raw_prompt_rejected:{line_no}")
    events += 1
if events == 0:
    raise SystemExit("empty_trace")
print(f"ok events={events}")
PY
```

## Submit

Production endpoint:

```text
POST https://api.touchdown-labs.com/v1/traces
Content-Type: application/x-ndjson
Authorization: Bearer <Touchdown session token>
```

Use the first available non-secret auth path:

- `TOUCHDOWN_API_TOKEN` for a machine-token flow once available.
- `TD_SESSION_TOKEN` for a short-lived signed-in user session token.
- Future CLI flow: `td auth login && td trace submit "$TRACE_PATH" --open`.

Do not print tokens.

```bash
: "${TD_SESSION_TOKEN:?Set TD_SESSION_TOKEN or use the Touchdown CLI auth flow first.}"

curl -sS \
  -X POST "https://api.touchdown-labs.com/v1/traces" \
  -H "Authorization: Bearer ${TD_SESSION_TOKEN}" \
  -H "Content-Type: application/x-ndjson" \
  --data-binary @"$TRACE_PATH"
```

## Poll and verify

```bash
SESSION_ID="session_..."

curl -sS \
  -H "Authorization: Bearer ${TD_SESSION_TOKEN}" \
  "https://api.touchdown-labs.com/v1/sessions/${SESSION_ID}"
```

Poll until `session.status` is `analyzed` or `failed`. If analyzed and a `report_id` exists:

```bash
REPORT_ID="report_..."

curl -sS \
  -H "Authorization: Bearer ${TD_SESSION_TOKEN}" \
  "https://api.touchdown-labs.com/v1/reports/${REPORT_ID}"
```

Success requires:

- session status `analyzed`
- metrics rows exist
- report fetch succeeds
- totals include calls, tokens in, and tokens out
- `cost_status` may be `unavailable_pricing` when pricing is not configured

## Return to the user

```text
Trace submitted: <path>
Session: https://touchdown-labs.com/app/sessions/session.html?id=<session_id>
Status: analyzed
Report: https://touchdown-labs.com/app/reports/report.html?id=<report_id>
Totals: <calls> calls, <tokens_in> in, <tokens_out> out
Cost: unavailable_pricing
```
