> ## Documentation Index
> Fetch the complete documentation index at: https://dupcanon.sebslight.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get started

> End-to-end setup and first run for dupcanon (beginner and advanced tracks).

<Info>
  This guide is written for both first-time operators and experienced engineers. If you just want a fast success path, use the <b>Beginner track</b> below.
</Info>

## What you’ll do

By the end of this guide, you will:

1. install and configure `dupcanon`
2. run the full duplicate pipeline on a real repo
3. generate a safe close plan in dry-run mode
4. understand how to move from manual runs to workflow-driven automation

<CardGroup cols={2}>
  <Card title="Beginner track (recommended first run)">
    Follow the exact commands in order and get a working pipeline in \~15–30 minutes.
  </Card>

  <Card title="Advanced track">
    Use provider/model overrides, tune worker settings, and integrate with GitHub workflows.
  </Card>
</CardGroup>

## Prerequisites

* `uv` installed
* `gh` CLI installed and authenticated (`gh auth status`)
* Docker Desktop / Docker Engine (for local Supabase)
* Supabase CLI (for migrations and local DB)
* reachable Postgres DSN (Supabase recommended)
* API credentials for the providers you plan to use

<AccordionGroup>
  <Accordion title="Required credentials by default stack">
    Default runtime stack:

    * embeddings: `openai` / `text-embedding-3-large`
    * judge: `openai-codex` via `pi --mode rpc`

    Minimum env requirements for that default:

    * `SUPABASE_DB_URL`
    * `OPENAI_API_KEY` (for embeddings)
    * `pi` CLI on PATH (for `openai-codex` judge path)

    Optional but commonly used:

    * `GITHUB_TOKEN` (if not relying on existing `gh` auth)
    * `LOGFIRE_TOKEN` (for remote log sink)
  </Accordion>

  <Accordion title="Alternative provider requirements">
    * If embedding/judge provider is `gemini` -> `GEMINI_API_KEY`
    * If judge provider is `openai` -> `OPENAI_API_KEY`
    * If judge provider is `openrouter` -> `OPENROUTER_API_KEY`
  </Accordion>
</AccordionGroup>

## 1) Set up Supabase database first (local Docker recommended)

<Tabs>
  <Tab title="Local Supabase (Docker)">
    Install Supabase CLI (macOS example):

    ```bash theme={null}
    brew install supabase/tap/supabase
    ```

    Start local Supabase services from repo root:

    ```bash theme={null}
    supabase start
    ```

    Apply and validate schema locally:

    ```bash theme={null}
    supabase db reset
    supabase db lint
    ```

    Use local Postgres DSN in `.env`:

    ```dotenv theme={null}
    SUPABASE_DB_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
    ```
  </Tab>

  <Tab title="Hosted Supabase">
    Use local validation first, then push migrations:

    ```bash theme={null}
    supabase db reset
    supabase db lint
    supabase db push
    ```

    Use your hosted Postgres DSN in `.env` (prefer pooler DSN for runtime).
  </Tab>
</Tabs>

<Warning>
  Do not use the Supabase project HTTPS URL as `SUPABASE_DB_URL`; use a Postgres DSN (`postgresql://...` or `postgres://...`).
</Warning>

## 2) Install and configure dupcanon

```bash theme={null}
uv sync
cp .env.example .env
```

Edit `.env` and set at minimum:

```dotenv theme={null}
SUPABASE_DB_URL=postgresql://...
OPENAI_API_KEY=...
```

<Warning>
  `SUPABASE_DB_URL` must be a <b>Postgres DSN</b> (`postgresql://` or `postgres://`), not a Supabase HTTPS project URL.
</Warning>

Validate setup:

```bash theme={null}
uv run dupcanon init
```

You should see runtime checks with ✅/⚠️ plus DSN guidance.

## 3) First successful pipeline run (Beginner track)

Use a repo you can safely test against.

```bash theme={null}
# 1) ingest recent items
uv run dupcanon sync --repo openclaw/openclaw --since 3d

# 2) extract intent cards (default modeling source)
uv run dupcanon analyze-intent --repo openclaw/openclaw --type issue --state open

# 3) embed changed/new intent cards
uv run dupcanon embed --repo openclaw/openclaw --type issue --only-changed

# 4) build candidate sets (open-only by default for operations)
uv run dupcanon candidates --repo openclaw/openclaw --type issue --include open

# 5) run duplicate judge
uv run dupcanon judge --repo openclaw/openclaw --type issue --thinking low

# 6) compute canonical stats (optional but recommended)
uv run dupcanon canonicalize --repo openclaw/openclaw --type issue

# 7) generate close plan safely (dry run)
uv run dupcanon plan-close --repo openclaw/openclaw --type issue --dry-run
```

<Note>
  If you want to skip intent extraction, use raw embeddings instead: add `--source raw` to `embed`, `candidates`, and `judge` (and omit `analyze-intent`).
</Note>

<Note>
  Every command prints a summary table with counters, making it easy to verify each stage before moving on.
</Note>

## 4) LLM command reference (optional)

Use `llm` to emit a compact JSON reference that explains the command surface, defaults, guardrails, and example flows.

```bash theme={null}
uv run dupcanon llm
```

Need the full Click help/type metadata? Use:

```bash theme={null}
uv run dupcanon llm --full
```

## 5) Safe mutation path (only when ready)

Persist a real plan:

```bash theme={null}
uv run dupcanon plan-close --repo openclaw/openclaw --type issue
```

Then review plan rows in DB and apply explicitly:

```bash theme={null}
uv run dupcanon apply-close --close-run <plan_run_id> --yes
```

<Warning>
  `apply-close` is intentionally gated: it requires an existing <code>mode=plan</code> run and explicit <code>--yes</code>.
</Warning>

## 6) Online path (entryway for automation)

`detect-new` is the online single-item entrypoint used for workflow-driven automation.

```bash theme={null}
uv run dupcanon detect-new --repo openclaw/openclaw --type issue --number 123 --thinking low
```

Workflow-friendly output:

```bash theme={null}
uv run dupcanon detect-new \
  --repo openclaw/openclaw \
  --type issue \
  --number 123 \
  --json-out .local/artifacts/detect-new.json
```

Current GitHub Actions shadow workflow:

* `.github/workflows/detect-new-shadow.yml`

## 7) Advanced track (overrides and tuning)

<Tabs>
  <Tab title="Provider/model overrides">
    ```bash theme={null}
    # OpenAI judge
    uv run dupcanon judge --repo openclaw/openclaw --type issue --provider openai --model gpt-5-mini

    # OpenRouter judge
    uv run dupcanon judge --repo openclaw/openclaw --type issue --provider openrouter --model minimax/minimax-m2.5

    # Embedding override
    uv run dupcanon embed --repo openclaw/openclaw --type issue --only-changed --provider openai --model text-embedding-3-large
    ```
  </Tab>

  <Tab title="Concurrency tuning">
    ```bash theme={null}
    # candidates concurrency override
    uv run dupcanon candidates --repo openclaw/openclaw --type issue --workers 8

    # judge concurrency override
    uv run dupcanon judge --repo openclaw/openclaw --type issue --workers 8
    ```
  </Tab>

  <Tab title="Audit and gate simulation">
    ```bash theme={null}
    # cheap-vs-strong sampled audit
    uv run dupcanon judge-audit \
      --repo openclaw/openclaw \
      --type issue \
      --sample-size 100 \
      --seed 42 \
      --cheap-provider gemini --cheap-thinking low \
      --strong-provider openai --strong-thinking high

    # report existing audit + simulate non-LLM gates
    uv run dupcanon report-audit --run-id <id> --simulate-gates --gate-gap-min 0.02
    ```
  </Tab>

  <Tab title="Semantic search (read-only)">
    ```bash theme={null}
    # query-driven search (intent is default source)
    uv run dupcanon search --repo openclaw/openclaw --query "oauth error" --type issue

    # anchor-driven search with include/exclude constraints
    uv run dupcanon search \
      --repo openclaw/openclaw \
      --similar-to 1234 \
      --include "websocket" \
      --exclude "android" \
      --include-mode boost \
      --include-weight 0.15 \
      --debug-constraints
    ```
  </Tab>
</Tabs>

## Common troubleshooting

<AccordionGroup>
  <Accordion title="Supabase CLI / Docker setup issues">
    * Ensure Docker is running before `supabase start`.
    * If local services fail to start, restart Docker and run `supabase stop && supabase start`.
    * Confirm CLI is installed: `supabase --version`.
    * Rebuild local schema state with `supabase db reset`.
  </Accordion>

  <Accordion title="init fails with DSN message">
    Use a Postgres DSN (`postgresql://...`), not Supabase HTTPS URL. Prefer Supabase IPv4 pooler DSN if direct DB is unreachable.
  </Accordion>

  <Accordion title="judge says provider key/CLI missing">
    Ensure env matches selected provider:

    * `gemini` -> `GEMINI_API_KEY`
    * `openai` -> `OPENAI_API_KEY`
    * `openrouter` -> `OPENROUTER_API_KEY`
    * `openai-codex` -> `pi` CLI on PATH
  </Accordion>

  <Accordion title="No candidates or low yield">
    Check that:

    * sync and embed completed
    * candidate retrieval used expected type/state filters
    * threshold is not too strict for your corpus
  </Accordion>

  <Accordion title="High-confidence duplicate still rejected">
    This is expected when deterministic gates fail (for example: target not open, score gap below `0.015`, structural mismatch vetoes).
  </Accordion>
</AccordionGroup>

## From manual to automated operations

A practical scheduled sequence is:

1. `refresh --refresh-known`
2. `analyze-intent --only-changed`
3. `embed --only-changed`
4. `candidates --include open`
5. `judge`
6. `canonicalize`
7. `plan-close` (and apply only under review policy)

For event-driven online checks, trigger `detect-new` from issue/pr opened events.

## Next docs to read

* Overview: `/`
* Semantic search: `/search`
* Internal runbook/specs: `docs/internal/`
