2,553 prompts from top AI collections
← Back to Market
[BjornMelin/codex-prompt-refinery] Product Requirements Document — `codex-prompt-refinery`
ChatGPT API Leak/ChatGPT
19,296 characters
# Product Requirements Document — `codex-prompt-refinery` Author: Bjorn Melin ## 1) Summary Local tool that ingests **OpenAI Codex CLI** history under `~/.codex/**`, extracts prompts and nearby assistant replies, deduplicates and groups related prompts, and auto-synthesizes **atomic** and **workflow** prompts via the **OpenAI Responses API** using **Structured Outputs**. Single **SQLite** database with **FTS5** keyword search and **sqlite-vec** semantic search. Minimal **Streamlit** UI to search, view, specialize, and copy prompts. Optional daily automation via **systemd** on WSL2. * Codex CLI: [https://github.com/openai/codex](https://github.com/openai/codex) · Docs: [https://developers.openai.com/codex/cli/](https://developers.openai.com/codex/cli/) * Responses API: [https://platform.openai.com/docs/api-reference/responses](https://platform.openai.com/docs/api-reference/responses) * Structured Outputs: [https://platform.openai.com/docs/guides/structured-outputs](https://platform.openai.com/docs/guides/structured-outputs) * Embeddings guide: [https://platform.openai.com/docs/guides/embeddings](https://platform.openai.com/docs/guides/embeddings) * `text-embedding-3-small` announcement: [https://openai.com/index/new-embedding-models-and-api-updates/](https://openai.com/index/new-embedding-models-and-api-updates/) * SQLite FTS5: [https://www.sqlite.org/fts5.html](https://www.sqlite.org/fts5.html) * sqlite-vec (Python): [https://alexgarcia.xyz/sqlite-vec/python.html](https://alexgarcia.xyz/sqlite-vec/python.html) · Repo: [https://github.com/asg017/sqlite-vec](https://github.com/asg017/sqlite-vec) * Streamlit API: [https://docs.streamlit.io/develop/api-reference](https://docs.streamlit.io/develop/api-reference) * Typer: [https://typer.tiangolo.com/](https://typer.tiangolo.com/) * RapidFuzz: [https://rapidfuzz.github.io/RapidFuzz/](https://rapidfuzz.github.io/RapidFuzz/) * WSL2 systemd: [https://learn.microsoft.com/windows/wsl/systemd](https://learn.microsoft.com/windows/wsl/systemd) * systemd timers: [https://www.freedesktop.org/software/systemd/man/systemd.timer.html](https://www.freedesktop.org/software/systemd/man/systemd.timer.html) ## 2) Objectives * Distill reusable, one-shot prompts to cut repeated follow-ups. * Local-only. One developer. One-day build. * Hybrid search: exact (FTS5) + semantic (sqlite-vec). * Clean UI to browse, edit lightly, copy or download. ## 3) Out of scope Multi-user, auth/RBAC, cloud deploy, agent frameworks, external vector DBs, permanent daemons. ## 4) Operating assumptions * Codex CLI config at `~/.codex/config.toml`; histories live under `~/.codex/**` as JSON/JSONL. Upstream notes config here: [README Configuration](https://github.com/openai/codex#readme) and mentions `~/.codex/config.toml`. * WSL2 Ubuntu with zsh; optional systemd user services: [WSL systemd](https://learn.microsoft.com/windows/wsl/systemd). * OpenAI API key via env for embeddings and synthesis. ## 5) Functional requirements ### F1. Ingest * Inputs: default glob `~/.codex/**` for `*.json` and `*.jsonl`. * Tolerant JSON/JSONL parsing; extract `ts` (ISO8601 or epoch), `role` (`user|assistant|system`), `text`, `session_id`/`conversation_id` when present, and raw line. * Pair `user` with next `assistant` in same session (forward scan). * Store raw JSON for provenance. ### F2. Canonicalize & dedupe * Canonical text: lowercase, collapse whitespace, strip timestamps/UUIDs, truncate stack traces to N lines. * Exact dedupe: `sha256(canonical_text)`. * Near-dup gate: RapidFuzz `partial_ratio >= 90`; suppress unless length delta > 15%. ### F3. Embeddings * Embed `user` prompts and optimized prompts with `text-embedding-3-small` (default 1536-D; allow `dimensions` override). Guides: [Embeddings](https://platform.openai.com/docs/guides/embeddings), update post: [New models](https://openai.com/index/new-embedding-models-and-api-updates/). ### F4. Grouping (KISS) * Per day greedy clustering by cosine ≥ 0.86 using sqlite-vec KNN. Seed by time; attach neighbors above threshold. Save `cluster_hint` from first prompt’s keywords. ### F5. Synthesis (LLM) * For each cluster, send 3–10 related `user` prompts plus selected `assistant` snippets to **Responses API** using **Structured Outputs** JSON Schema (see §12). * Return: * `optimized_atomic_prompts[]` * `optimized_workflow_prompt` * `rationale` * Each prompt includes: `title`, `prompt_markdown` (fenced, copy-ready), `variables[] {name,type,example,description}`, `io_contract {inputs,outputs}`, and `citations[]` of source raw IDs. * Default model: `gpt-5-mini`. Allow `--model gpt-5`. ### F6. Storage & search Schema (day-1): ```sql CREATE TABLE prompt_raw ( id INTEGER PRIMARY KEY, source_path TEXT NOT NULL, session_id TEXT, conversation_id TEXT, role TEXT CHECK(role IN ('user','assistant','system')), ts TEXT, text TEXT NOT NULL, canonical_hash TEXT NOT NULL, raw_json TEXT ); CREATE TABLE prompt_optimized ( id INTEGER PRIMARY KEY, kind TEXT CHECK(kind IN ('atomic','workflow')) NOT NULL, title TEXT, text_md TEXT NOT NULL, variables_json TEXT, io_contract_json TEXT, rationale TEXT, created_at TEXT, cluster_hint TEXT, gpt_meta_json TEXT ); CREATE TABLE prompt_link ( optimized_id INTEGER, raw_id INTEGER, PRIMARY KEY (optimized_id, raw_id) ); CREATE VIRTUAL TABLE prompt_raw_fts USING fts5(text); CREATE VIRTUAL TABLE prompt_opt_fts USING fts5(text_md); CREATE VIRTUAL TABLE embeddings USING vec0( embedding FLOAT[1536], kind TEXT CHECK(kind IN ('raw','optimized')), item_id INTEGER ); ``` * FTS5: [https://www.sqlite.org/fts5.html](https://www.sqlite.org/fts5.html) * sqlite-vec usage: declare `vec0`, insert serialized vectors, query with `MATCH` and `ORDER BY distance`: [https://alexgarcia.xyz/sqlite-vec/python.html](https://alexgarcia.xyz/sqlite-vec/python.html) Vector query example: ```sql SELECT item_id, distance FROM embeddings WHERE kind='raw' AND embedding MATCH ? ORDER BY distance LIMIT 20; ``` ### F7. UI (Streamlit) * Single page. Search box runs hybrid search (union of FTS top-N and vector top-K) with simple scoring. * Tabs: **Raw**, **Optimized**. Cards show title/date and actions: **Copy**, **Edit**, **Download**. * Detail pane shows fenced markdown in `st.code`, a “Specialize” text area, live preview, and Copy/Download. Streamlit API: [https://docs.streamlit.io/develop/api-reference](https://docs.streamlit.io/develop/api-reference) Optional components: * Copy button: `st-copy-to-clipboard` [https://github.com/mmz-001/st-copy-to-clipboard](https://github.com/mmz-001/st-copy-to-clipboard) * Editors: `streamlit-ace` [https://github.com/okld/streamlit-ace](https://github.com/okld/streamlit-ace) or `streamlit-code-editor` [https://github.com/bouzidanas/streamlit-code-editor](https://github.com/bouzidanas/streamlit-code-editor) ### F8. CLI (Typer) ```bash pdr ingest [--date YYYY-MM-DD | --since N] [--path GLOB...] pdr synthesize [--date YYYY-MM-DD] [--model gpt-5|gpt-5-mini] pdr ui [--port 8501] ``` Typer docs: [https://typer.tiangolo.com/](https://typer.tiangolo.com/) ### F9. Optional scheduling (WSL2) * Provide a systemd user service and timer to run `ingest` then `synthesize` daily. Enable systemd in WSL2: [https://learn.microsoft.com/windows/wsl/systemd](https://learn.microsoft.com/windows/wsl/systemd) Timers manual: [https://www.freedesktop.org/software/systemd/man/systemd.timer.html](https://www.freedesktop.org/software/systemd/man/systemd.timer.html) ## 6) Non-functional * Local-first. DB < 1 GB for initial days. * ≤ 5 minutes for \~100 prompts/day. * Secret redaction via regex before storage and LLM calls. * Structured logs to stdout; optional rotating file handler. ## 7) Quality gates * `ruff` and `pylint` clean. * `pytest` minimal suite passes. * UI query latency < 150 ms on 10k-row DB. * CLI idempotent. * Synthesis JSON validates against the schema in §12. ## 8) Risks & mitigations * **Log format drift** → tolerant parsing; keep `raw_json`. * **False merges** → conservative threshold; UI shows cluster sources. * **Rate limits** → batch embeddings; retry/backoff; small clusters; default to mini model. ## 9) Decision log (KISS/DRY/YAGNI) * **SQLite + FTS5 + sqlite-vec** over external vector DBs. One file, no servers. FTS5: [https://www.sqlite.org/fts5.html](https://www.sqlite.org/fts5.html) · sqlite-vec: [https://github.com/asg017/sqlite-vec](https://github.com/asg017/sqlite-vec) * **Greedy clustering** over sklearn. Fewer deps; good enough at this scale. * **Streamlit** over custom web stack. Faster single-day delivery: [https://docs.streamlit.io/](https://docs.streamlit.io/) * **Typer** over argparse. Better DX: [https://typer.tiangolo.com/](https://typer.tiangolo.com/) * **RapidFuzz** for near-dupe: [https://rapidfuzz.github.io/RapidFuzz/](https://rapidfuzz.github.io/RapidFuzz/) ## 10) Decision framework (weighted) | Decision | Option | Leverage 35% | Value 30% | Load 25% | Adapt 10% | Total | | ---------------------------------------------------------------------------------- | ---------- | -----------: | --------: | -------: | --------: | ------: | | Vector store | sqlite-vec | 9 | 8 | 8 | 8 | **8.5** | | | FAISS | 7 | 7 | 5 | 7 | 6.6 | | UI | Streamlit | 8 | 8 | 8 | 7 | **7.9** | | | Flask+JS | 6 | 7 | 4 | 8 | 6.1 | | CLI | Typer | 8 | 8 | 8 | 7 | **7.9** | | | argparse | 6 | 7 | 7 | 7 | 6.7 | | **Rationale:** Highest leverage with lowest maintenance. Library-first. No server. | | | | | | | ## 11) Data model * `prompt_raw`: one row per ingested message with provenance and canonical hash. * `prompt_optimized`: synthesized atomic/workflow prompts and metadata. * `prompt_link`: many-to-many mapping from optimized prompts to source raw rows. * `prompt_raw_fts`, `prompt_opt_fts`: duplicated text for FTS. * `embeddings`: `vec0` table with vectors for `raw` and `optimized`. ## 12) Structured Outputs JSON Schema ```json { "type": "object", "additionalProperties": false, "required": ["optimized_atomic_prompts","optimized_workflow_prompt","rationale"], "properties": { "optimized_atomic_prompts": { "type": "array", "items": { "type": "object", "required": ["title","prompt_markdown","variables","io_contract","citations"], "properties": { "title": {"type":"string"}, "prompt_markdown": {"type":"string"}, "variables": {"type":"array","items":{"type":"object","required":["name"],"properties":{ "name":{"type":"string"}, "type":{"type":"string"}, "example":{"type":"string"}, "description":{"type":"string"} }}}}, "io_contract": {"type":"object","required":["inputs","outputs"],"properties":{ "inputs":{"type":"string"}, "outputs":{"type":"string"} }}, "citations":{"type":"array","items":{"type":"integer"}} } } }, "optimized_workflow_prompt": { "type":"object", "required":["title","prompt_markdown","variables","io_contract","citations"], "properties":{ "title":{"type":"string"}, "prompt_markdown":{"type":"string"}, "variables":{"type":"array","items":{"type":"object","required":["name"],"properties":{ "name":{"type":"string"}, "type":{"type":"string"}, "example":{"type":"string"}, "description":{"type":"string"} }}}}, "io_contract":{"type":"object","required":["inputs","outputs"],"properties":{ "inputs":{"type":"string"}, "outputs":{"type":"string"} }}, "citations":{"type":"array","items":{"type":"integer"}} } }, "rationale":{"type":"string"} } } ``` * Responses API: [https://platform.openai.com/docs/api-reference/responses](https://platform.openai.com/docs/api-reference/responses) * Structured Outputs guide: [https://platform.openai.com/docs/guides/structured-outputs](https://platform.openai.com/docs/guides/structured-outputs) ## 13) Algorithms * **Canonicalize(text):** lowercase → strip ISO timestamps/UUIDs → trim stack trace to N lines → collapse whitespace. * **Near-dup:** `RapidFuzz.partial_ratio(a,b) >= 90` and `abs(|a|-|b|)/|b| ≤ 0.15` → suppress. * **Clustering:** for each seed id, KNN via sqlite-vec; approximate cosine from L2 for unit-normalized vectors; attach neighbors ≥ 0.86. ## 14) Security and privacy * Redact secrets (`sk-…`, AWS AKIA keys, long numeric tokens) before storage or LLM calls. * Store raw JSON for provenance; mark source path and session ids. * Optional “ZDR” upstream reference for Codex usage: [https://github.com/openai/codex#readme](https://github.com/openai/codex#readme) ## 15) Telemetry and logging * Structured logs to stdout. Optional rotating file handler. * Record ingestion counts, embeddings batches, synthesis success/failure, UI search timings. ## 16) CLI UX * `pdr ingest --date YYYY-MM-DD` or `--since N` and `--path` globs. * `pdr synthesize --date YYYY-MM-DD --model gpt-5-mini|gpt-5`. * `pdr ui --port 8501`. ## 17) UI UX * Search box. Tabs **Raw**/**Optimized**. * Card → details pane with fenced markdown, “Specialize” text area, live preview, Copy button, and `.md` download. ## 18) Acceptance criteria (Gherkin) **Feature: Ingest Codex logs** Scenario: Parse a day’s logs Given Codex JSON/JSONL files under `~/.codex/` for a specific date When I run `pdr ingest --date YYYY-MM-DD` Then rows are inserted into `prompt_raw` and `prompt_raw_fts` without duplicates And each row stores `source_path`, `role`, `ts`, `text`, `canonical_hash`, and `raw_json` And the command exits with code 0. **Feature: Dedupe and near-dup gate** Scenario: Re-ingest the same files Given the DB already contains prompts from the files When I re-run `pdr ingest` on the same paths Then duplicate canonical hashes are skipped And near-duplicates with `partial_ratio ≥ 90` are suppressed unless length delta > 15%. **Feature: Embeddings** Scenario: Embed new raw prompts Given new `user` prompts exist without vectors When I run `pdr synthesize --date YYYY-MM-DD` Then `embeddings` rows are created with kind=`raw` and 1536-D vectors And API errors are handled with retry/backoff. **Feature: Grouping** Scenario: Greedy clustering Given embedded prompts for the day When grouping runs with threshold 0.86 Then clusters contain semantically related prompts And each cluster stores a `cluster_hint`. **Feature: Synthesis** Scenario: Generate optimized prompts Given grouped clusters with ≥3 related prompts When synthesis runs via Responses API with Structured Outputs Then JSON conforms to the schema in §12 And `prompt_optimized` rows are inserted for atomic and workflow prompts And back-links are written to `prompt_link`. **Feature: Search** Scenario: Hybrid search returns relevant rows Given prompts exist with FTS and vectors When I search with a keyword and natural language Then results include FTS matches and cosine-nearest items And results are ranked by a simple weighted score. **Feature: UI** Scenario: Browse, edit, copy Given the Streamlit app is running When I search, open a prompt, and type a specialization Then a live preview updates And I can copy to clipboard and download a `.md` snippet. **Feature: CLI and runbook** Scenario: Commands work end-to-end Given Python 3.11+ When I run the runbook commands Then the DB is created, ingest and synthesize complete, and the UI is reachable on the given port. **Feature: Tooling** Scenario: Lint and tests Given the repo root When I run `ruff` and `pytest` Then both succeed. ## 19) Runbook (WSL2, zsh) ```bash uv venv && source .venv/bin/activate uv pip install -e ".[dev]" pdr ingest --since 1 pdr synthesize --date "$(date -I)" --model gpt-5-mini pdr ui --port 8501 ``` Enable systemd for daily automation: [WSL systemd](https://learn.microsoft.com/windows/wsl/systemd) Create user units under `~/.config/systemd/user/`; timers ref: [systemd.timer](https://www.freedesktop.org/software/systemd/man/systemd.timer.html) ## 20) References * Codex CLI repo: [https://github.com/openai/codex](https://github.com/openai/codex) · Product page: [https://developers.openai.com/codex/cli/](https://developers.openai.com/codex/cli/) * Responses API: [https://platform.openai.com/docs/api-reference/responses](https://platform.openai.com/docs/api-reference/responses) · Migration guide: [https://platform.openai.com/docs/guides/migrate-to-responses](https://platform.openai.com/docs/guides/migrate-to-responses) * Structured Outputs: [https://platform.openai.com/docs/guides/structured-outputs](https://platform.openai.com/docs/guides/structured-outputs) * Embeddings: [https://platform.openai.com/docs/guides/embeddings](https://platform.openai.com/docs/guides/embeddings) · New model post: [https://openai.com/index/new-embedding-models-and-api-updates/](https://openai.com/index/new-embedding-models-and-api-updates/) * SQLite FTS5: [https://www.sqlite.org/fts5.html](https://www.sqlite.org/fts5.html) * sqlite-vec Python usage: [https://alexgarcia.xyz/sqlite-vec/python.html](https://alexgarcia.xyz/sqlite-vec/python.html) · Repo: [https://github.com/asg017/sqlite-vec](https://github.com/asg017/sqlite-vec) * Streamlit: [https://docs.streamlit.io/develop/api-reference](https://docs.streamlit.io/develop/api-reference) * Typer: [https://typer.tiangolo.com/](https://typer.tiangolo.com/) * RapidFuzz: [https://rapidfuzz.github.io/RapidFuzz/](https://rapidfuzz.github.io/RapidFuzz/) * WSL systemd: [https://learn.microsoft.com/windows/wsl/systemd](https://learn.microsoft.com/windows/wsl/systemd) * systemd timers: [https://www.freedesktop.org/software/systemd/man/systemd.timer.html](https://www.freedesktop.org/software/systemd/man/systemd.timer.html) * Optional Streamlit components: * Copy: [https://github.com/mmz-001/st-copy-to-clipboard](https://github.com/mmz-001/st-copy-to-clipboard) * Editor (Ace): [https://github.com/okld/streamlit-ace](https://github.com/okld/streamlit-ace) * Editor (react-ace): [https://github.com/bouzidanas/streamlit-code-editor](https://github.com/bouzidanas/streamlit-code-editor) **K/D/Y:** * KISS: single SQLite file; no servers. * DRY: shared ingest/canonicalize utils; duplicated text into FTS by design for day-1. * YAGNI: no background daemon; greedy clustering instead of sklearn.
Download .txt