---
name: ingest-repo
description: Scan an existing product repository read-only and emit a DRAFT OKF reference layer (architecture, per-table, capability ledger, integrations, conventions, ADR seeds) + register the repo, so a build agent starts warm. Use when a PM brings a product that already ships and has a repo. Never writes the tenant repo; never emits secrets.
version: 1.0.0
owner: wawan
risk: medium
category: onboarding
scope: read:tenant-repo, write:tenant-okf-drafts, write:product_repos
---

# ingest-repo — Warm-start an existing product from its code

This skill is the **existing-repo on-ramp**: a PM arrives with a product that already ships and already
has a repo, and PMOS needs knowledge of it so a build agent doesn't cold-start on every run (re-deriving
the stack, assuming wrong, producing work the PM must heavily correct — the north-star cost). It is the
**inverse** of deriving an infrastructure spec from a PRD (PRD → what the product *needs*):
ingest-repo goes **code → what the product *is***. It emits a **draft** OKF
reference layer + a repo registration and then **stops for PM approval**.

> **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)). L1
> frontmatter above is the trigger; this L2 body is the full procedure.
> **Where it runs:** in **the interactive agent runtime** (any capable coding agent; PMOS-self uses
> Claude Code), in the tenant's own conversation, read-only — never a server-side scanner
> ([D51](/okf/products/pmos/adr/d51-scan-location.md); heavy reasoning runs in the interactive agent
> per [D09](/okf/products/pmos/adr/d09-skills-execute-in-claude-code.md), amended 2026-07-23).

## Non-negotiable stance

- **Read-only, at control altitude ([D01](/okf/products/pmos/adr/d01-control-plane.md)).** Zero writes
  to the tenant repo — no files, no branches, no commits. If `git status` is not clean after the run,
  that is a defect.
- **No secrets, ever ([D08](/okf/products/pmos/adr/d08-never-log-request-headers.md)).** Read only env
  var *names* (`.env.example`, config keys). **Secret-scan the repo content AND git history** (real
  repos leak keys in committed code/history); if a secret value is found, **never** place it in a doc,
  a log, or the registry — note only that a leak exists and where, by path, so the PM can rotate it.
- **Default-to-refute on capability** (the [design-reconcile](/skills/design-reconcile.skill)
  stance applied to code): a control/route is **watermelon** until a concrete backend read/write path
  is found in the code. Unbacked controls land in **§D**, not invented as capability.
- **Everything is a DRAFT ([D37](/okf/products/pmos/adr/d37-tenant-okf-db-native.md)/[D12](/okf/products/pmos/adr/d12-three-tier-eval-gate.md)).**
  `save_okf_doc(... status:'draft')`. The agent proposes; the **PM approves in-app**. Retrieval note:
  a PM's own build agent *can* read its own tenant drafts (get_okf_concepts returns owner-scoped drafts,
  the ratified 2026-07-02 draft-visible-to-own-agent stance), so warm-start works immediately; approval
  governs promotion/trust, not visibility to the owner's own agent.
- **Tenant-only.** `save_okf_doc` rejects `pmos`; this never writes the PMOS-self git bundle.
- **Idempotent.** Re-running upserts docs (on `id`) and reconciles the registry (on `product_slug`) —
  no duplicates.

## Procedure

1. **Read [AGENTS.md](/AGENTS.md)** and confirm the target `product_slug` (owner-scoped; one product).
2. **Read-only scan** of the tenant repo, gathering *cited* evidence (every claim will carry the repo
   path it came from):
   - **Stack & app surface** — manifests/lockfiles (`package.json`, `pyproject.toml`, `go.mod`, …),
     framework config, entrypoints.
   - **Architecture** — directory tree, entrypoints, module boundaries.
   - **Data model** — migrations / schema / ORM models: one asset per table/model (columns + RLS/perm
     shape where expressed).
   - **Capability map** — trace **routes ↔ handlers ↔ queries**: which UI control/route reaches which
     backend read/write. This is the raw material for the ledger.
   - **Integrations** — config + SDK imports + `.env.example` **names only** (maps, transcription,
     push, payments, storage, …).
   - **Decisions & conventions** — README / ADRs / CHANGELOG / commit history (existing decisions);
     CI config, lint rules, observed patterns (conventions).
3. **Secret-scan** repo content + git history (e.g. high-entropy strings, known key prefixes). Emit
   **no** value; record only "possible secret at `<path>`" for the PM.
4. **Emit the reference layer** — via `save_okf_doc(..., status:'draft', product_slug:<slug>)`,
   namespaced `products/<slug>/...`, **each body carrying situating context + the exact repo path(s)**
   it was derived from (the [source-to-concept](/skills/source-to-concept.skill) rule + the
   analyze-product-infra cited-line bar, applied to code). Minimum six kinds:

   | Doc | OKF `type` | id (under `products/<slug>/`) | derived from |
   |---|---|---|---|
   | Architecture / stack overview | `Concept` | `concepts/architecture` | manifests + tree + entrypoints |
   | Per-table/model schema (one each) | `Reference` | `data-model/<table>` | migrations / ORM models |
   | **Capability ledger** | `Reference` | `references/capability-ledger` | routes ↔ handlers ↔ queries |
   | Integration map | `Reference` | `references/integrations` | config + SDK imports + .env.example names |
   | Conventions | `Concept` | `concepts/conventions` | CI/lint config + observed patterns |
   | ADR seed(s) | `ADR` | `adr/<slug>-<n>-<topic>` | README / ADRs / commit history |

5. **Bootstrap the per-tenant capability ledger** (the artifact
   [design-reconcile](/skills/design-reconcile.skill) consumes, [D50](/okf/products/pmos/adr/d50-design-loop-product-scoped.md)
   pattern — generic method, per-tenant instance). Classify **every** user-facing control/route into
   exactly one bucket; each §A/§B entry **names the concrete read/write path** in the code:
   - **§A — read-backed:** maps to a real backend read (query/endpoint) — cite it.
   - **§B — write-backed:** maps to a real backend write (mutation/endpoint) — cite it.
   - **§C — data-exists-unsurfaced:** the data exists but no control surfaces it (opt-in opportunity).
   - **§D — no-backing (watermelon):** a control with no backend path found — flagged, not invented.
6. **Register the repo** — `register_product_repo({ product_slug, repo:'owner/name',
   app_surface:<observed>, backend_model:<observed>, status:'active', irs_ref:<repo-profile doc id>,
   webhook_secret_ref: <name-or-null> })`. Fields are **observed** here (not IRS-derived); pass **no
   secret value**. Add an "observed, not IRS-derived" provenance note.
7. **STOP for PM approval.** Present the drafted layer + the ledger's §D watermelon list + any secret
   findings. The PM approves docs in-app; you do not self-approve. Log the run + friction.

## Guardrails

- **Provenance is a hard gate.** An emitted doc with an un-sourced assertion is a defect — the
  evaluator's provenance dimension hunts for exactly this ([rubric](/planning/evals/ingest-repo-eval-rubric.md)).
- **Large/polyglot monorepos:** flag scope to the PM and do a per-package pass; do **not** emit a
  shallow single profile.
- **`register_product_repo` semantics:** designed for provisioning output — here `app_surface`/
  `backend_model` are *observed*, a usage-only difference (no schema change); note it.
- **B5 measurability:** the value thesis is "warm start → fewer corrections"; the first post-ingest
  build run should retrieve these concepts. That real correction-delta, not the doc count, is the
  win — measure it as corrections on the first post-ingest run versus the cold-start baseline.
  (The hosted `v_knowledge_reuse` view that automated this count went with the backend in D66.)

## Level 3 — references

- The write path + PM gate: write the docs into the product's own repo as drafts and let the PM
  approve them in PR review — the file-mode form of draft→approved. (D37's database-native tenant OKF
  and its `save_okf_doc` tool were retired by [D66](/DECISIONS.md).)
- The ledger method: [design-loop concept](/okf/core/concepts/design-loop.md),
  [design-reconcile](/skills/design-reconcile.skill), [watermelon-flag](/okf/core/concepts/watermelon-flag.md).
- Extraction discipline: [source-to-concept](/skills/source-to-concept.skill).
- Scan location: [D51](/okf/products/pmos/adr/d51-scan-location.md). There is no longer a central
  registry to register into — the hosted `product_repos` table and `register_product_repo` went with
  the backend (D66); the product repo that carries the kit IS the registration.
- Sibling on-ramp: [product-onboarding playbook](/okf/core/playbooks/product-onboarding.md).
