Skip to content

Commit 7a9c713

Browse files
authored
Merge pull request #14 from saagpatel/chore/codex-scaffolding-and-main-guard
chore: add Codex harness scaffolding and cli __main__ guard
2 parents 1c28b41 + f2d6255 commit 7a9c713

3 files changed

Lines changed: 90 additions & 22 deletions

File tree

AGENTS.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# AGENTS.md
22

3+
<!-- comm-contract:start -->
4+
## Communication Contract (Global)
5+
- Follow `/Users/d/.codex/policies/communication/BigPictureReportingV1.md` for all user-facing updates.
6+
- Use exact section labels from `BigPictureReportingV1.md` for default status/progress updates.
7+
- Keep default updates beginner-friendly, big-picture, and low-noise.
8+
- Keep technical details in internal artifacts unless explicitly requested by the user.
9+
- Honor toggles literally: `simple mode`, `show receipts`, `tech mode`, `debug mode`.
10+
<!-- comm-contract:end -->
11+
312
## Project goal
413

514
Build a personal, local-only RAG system for macOS with a CLI-first workflow. The system must remain simple, inspectable, and testable from day one.
@@ -75,6 +84,16 @@ ruff check . --fix
7584
- When a dependency is optional or heavyweight, isolate it behind a module boundary
7685
- Treat `ingestion_runs` as SQLite-inspectable operational history unless a task explicitly adds a first-class CLI view for them
7786

87+
## Codex App Usage
88+
89+
- Use Codex App Projects for repo-specific implementation, review, and verification in this checkout.
90+
- Use a Worktree when changing retrieval behavior, storage schemas, CLI contracts, desktop wiring, or model-runtime boundaries.
91+
- Use the in-app browser or Playwright for desktop UI and FastAPI-backed browser workflow checks.
92+
- Use computer use only for GUI-only macOS/Tauri behavior that cannot be verified through tests, browser tooling, MCP, or CLI commands.
93+
- Use artifacts for reusable evaluation notes, retrieval examples, screenshots, and handoff packets.
94+
- Keep connectors read-first and task-scoped. Do not introduce cloud services, hosted databases, external API keys, or connector-backed app behavior unless explicitly requested.
95+
- Keep `.codex/verify.commands` as the verification authority; Codex App tools add evidence but do not replace the required local gates.
96+
7897
## Done criteria
7998

8099
A task is done only when all of the following are true:
@@ -83,3 +102,46 @@ A task is done only when all of the following are true:
83102
- Relevant tests were run, or the exact reason they were not run is stated
84103
- Docs or repo rules were updated when behavior or workflow changed
85104
- Assumptions, risks, and next steps were summarized
105+
106+
<!-- portfolio-context:start -->
107+
# Portfolio Context
108+
109+
## What This Project Is
110+
111+
GPT_RAG is an active local project in the /Users/d/Projects portfolio.
112+
113+
## Current State
114+
115+
Portfolio truth currently marks this project as `recent` with `boilerplate` context. Phase 104 recovered minimum-viable context so future sessions can resume without rediscovery.
116+
117+
## Stack
118+
119+
| Layer | Technology |
120+
|-------|------------|
121+
| Language | Python 3.11+ |
122+
| CLI | Typer + Rich |
123+
| Database | SQLite (FTS5) + LanceDB |
124+
| Embeddings / inference | Ollama |
125+
| Reranker | sentence-transformers (Qwen3-Reranker-4B) |
126+
| Document parsing | pypdf, BeautifulSoup4 |
127+
| Desktop shell | Tauri v2 + React + TypeScript |
128+
| Desktop API | FastAPI + Uvicorn |
129+
| Validation | Pydantic v2 |
130+
131+
## How To Run
132+
133+
```bash
134+
rag init
135+
rag ingest ~/Documents/my-notes
136+
rag ask "What did I write about distributed systems?"
137+
```
138+
139+
## Known Risks
140+
141+
- This repo only has minimum-viable recovery context today; deeper handoff details may still live in the README and supporting docs.
142+
143+
## Next Recommended Move
144+
145+
Use this context plus the README and supporting docs to resume the next active task, then promote the repo beyond minimum-viable by capturing a dedicated handoff, roadmap, or discovery artifact.
146+
147+
<!-- portfolio-context:end -->

src/gpt_rag/cli.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3977,3 +3977,7 @@ def eval_answer_diff(
39773977

39783978
def main() -> None:
39793979
app()
3980+
3981+
3982+
if __name__ == "__main__":
3983+
main()

tests/test_cli.py

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import json
4+
import re
45
from dataclasses import dataclass
56
from pathlib import Path
67

@@ -653,11 +654,15 @@ def fail_if_called(settings):
653654
assert saved_report["status"] == "status"
654655

655656

657+
_ANSI_ESCAPE_RE = re.compile(r"\x1b\[[0-9;]*m")
658+
659+
656660
def test_reindex_vectors_status_rejects_mutating_flags() -> None:
657661
result = runner.invoke(app, ["reindex-vectors", "--status", "--batch-size", "2"])
658662

659663
assert result.exit_code == 2
660-
assert "--status cannot be combined" in result.output
664+
stripped_output = _ANSI_ESCAPE_RE.sub("", result.output)
665+
assert "--status cannot be combined" in stripped_output
661666

662667

663668
def test_reindex_vectors_status_does_not_create_state_on_fresh_home(
@@ -1010,9 +1015,7 @@ def test_diff_command_compares_saved_trace_to_current_results(tmp_path: Path, mo
10101015
reranker.scores_by_text[
10111016
"# Socket Timeout Guide\n\nSocket timeout troubleshooting and startup checks."
10121017
] = 0.7
1013-
reranker.scores_by_text[
1014-
"Socket Notes\n\nThe socket timeout happens during startup."
1015-
] = 0.99
1018+
reranker.scores_by_text["Socket Notes\n\nThe socket timeout happens during startup."] = 0.99
10161019

10171020
diff_result = runner.invoke(
10181021
app,
@@ -1114,9 +1117,7 @@ def test_ask_command_can_persist_trace_artifact(tmp_path: Path, monkeypatch) ->
11141117
assert trace_payload["retrieval_snapshot"]["diversity"]["document_capped_count"] >= 0
11151118
assert trace_payload["retrieval_snapshot"]["diversity"]["unique_document_count"] >= 1
11161119
assert trace_payload["retrieval_results"]
1117-
assert (
1118-
trace_payload["generated_answer"]["retrieval_summary"]["cited_chunk_count"] == 2
1119-
)
1120+
assert trace_payload["generated_answer"]["retrieval_summary"]["cited_chunk_count"] == 2
11201121
assert trace_payload["answer_context_diversity"]["used_chunk_count"] == 2
11211122
assert trace_payload["answer_context_diversity"]["unique_document_count"] == 2
11221123
assert trace_payload["generated_answer"]["citations"][0]["chunk_id"] > 0
@@ -1262,9 +1263,7 @@ def test_answer_diff_command_compares_ask_traces(tmp_path: Path, monkeypatch) ->
12621263
reranker.scores_by_text[
12631264
"# Socket Timeout Guide\n\nSocket timeout troubleshooting and startup checks."
12641265
] = 0.7
1265-
reranker.scores_by_text[
1266-
"Socket Notes\n\nThe socket timeout happens during startup."
1267-
] = 0.99
1266+
reranker.scores_by_text["Socket Notes\n\nThe socket timeout happens during startup."] = 0.99
12681267
monkeypatch.setattr("gpt_rag.cli.build_generation_client", lambda settings: after_generator)
12691268

12701269
after_result = runner.invoke(
@@ -2397,18 +2396,21 @@ def test_trace_verify_reports_invalid_artifacts(tmp_path: Path, monkeypatch) ->
23972396
issues_by_path = {
23982397
Path(report["path"]).name: report["issues"] for report in payload["reports"]
23992398
}
2400-
assert "could not read a JSON object" in issues_by_path[
2401-
"20260101T000000Z-inspect-broken.json"
2402-
]
2403-
assert "ask trace must contain generated_answer" in issues_by_path[
2404-
"20260101T000100Z-ask-wrong.json"
2405-
]
2406-
assert "ask trace must contain retrieval_snapshot" in issues_by_path[
2407-
"20260101T000100Z-ask-wrong.json"
2408-
]
2409-
assert "ask trace must contain retrieval_results" in issues_by_path[
2410-
"20260101T000100Z-ask-wrong.json"
2411-
]
2399+
assert (
2400+
"could not read a JSON object" in issues_by_path["20260101T000000Z-inspect-broken.json"]
2401+
)
2402+
assert (
2403+
"ask trace must contain generated_answer"
2404+
in issues_by_path["20260101T000100Z-ask-wrong.json"]
2405+
)
2406+
assert (
2407+
"ask trace must contain retrieval_snapshot"
2408+
in issues_by_path["20260101T000100Z-ask-wrong.json"]
2409+
)
2410+
assert (
2411+
"ask trace must contain retrieval_results"
2412+
in issues_by_path["20260101T000100Z-ask-wrong.json"]
2413+
)
24122414
finally:
24132415
load_settings.cache_clear()
24142416

0 commit comments

Comments
 (0)