-
Notifications
You must be signed in to change notification settings - Fork 0
Phase 1: Storage and Schema #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
b30d9c0
c34bbcf
1f9f057
3dc8b88
fc5fb2f
ee64b04
467e0b7
3f4e066
081f8fe
d54200a
c1c35f5
5c3f016
544b180
a325e8f
cf1bdd2
a626708
c1d6ba8
a1410ac
f6ebe96
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,52 @@ | ||
| # [PR Title] | ||
|
|
||
| ## Summary | ||
|
|
||
| <!-- Two parts, in order: | ||
| 1. Lead: a high-level 2-3 line overview in plain English — what this branch delivers and why the | ||
| pieces hang together. Make it self-contained: a reader shouldn't need to already know the | ||
| architecture or internal package/module names (e.g. a bare `rag_core`) to follow it. Don't lean | ||
| on an internal identifier to carry the meaning — say what it is in plain terms (name it "the | ||
| shared retrieval library" rather than assuming the reader knows `rag_core`). Favor understandable | ||
| over exhaustive; don't pad with definitions. No commit hashes here; this is the altitude read. | ||
| 2. Walkthrough: a bulleted list one level deeper that elaborates the lead. Each bullet names a facet | ||
| of the change and cites the commit(s) it traces to by short-hash in parens, e.g. (fc5fb2f) — pull | ||
| hashes from the actual commit log, don't invent them. Name the unique or non-obvious parts (a new | ||
| protocol, an architectural decision, an automation), not obvious scaffolding (don't give "added | ||
| tests" a bullet if tests are just expected). Commits are titled `#<issue> <subject>`; those | ||
| without a leading #<issue> (chore/doc housekeeping) usually don't earn their own bullet. | ||
| Don't add a separate Changes section — the walkthrough lives here under Summary. Don't mention ADRs | ||
| or decision records here; they have their own dedicated section at the end. --> | ||
|
|
||
| ## Motivation | ||
|
|
||
| <!-- Why this change, in a sentence or two — the issue or ADR driving it, not a restatement of the | ||
| Summary. --> | ||
|
|
||
| ## Type | ||
|
|
||
| <!-- Check exactly the boxes that fit, based on what the commits actually do. --> | ||
|
|
||
| - [ ] Bug | ||
| - [ ] Feature | ||
| - [ ] Improvement | ||
|
|
||
| ## Related issues | ||
|
|
||
| <!-- Closes #<N> if this branch finishes the issue; Relates to #<N> if it's partial. --> | ||
|
|
||
| ## Verification | ||
|
|
||
| <!-- Numbered, command-first: each item leads with the exact command, then what it confirms. | ||
| Items 1 and 2 are the standard CI gate as two umbrellas — don't split the individual | ||
| lint/format/typecheck checks into their own points: | ||
| 1. `pre-commit run --all-files` (hygiene hooks + ruff lint/format + mypy) and the docs build | ||
| `uv run sphinx-build -b html docs site -W`. | ||
| 2. the full test suite `uv run pytest` (with `docker compose up -d` for the DB-backed tests). | ||
| Every item after 2 is specific to THIS PR: the exact commands or behaviors that exercise what this | ||
| branch actually changed (a new test module, a schema round-trip, a manual repro) — not generic | ||
| checks already covered by items 1-2. If you ran them, report pass/fail; if not, present them as the | ||
| commands to run before merging. --> | ||
|
|
||
| ## Decision records / ADRs | ||
|
|
||
| <!-- Link any docs/decisions/*.md files this branch touches. If none apply, keep this heading and | ||
| leave the section empty. --> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| name: PR Agent (Gemini) | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: [opened, reopened, ready_for_review] | ||
| issue_comment: | ||
|
|
||
| jobs: | ||
| pr_agent_job: | ||
| if: ${{ github.event.sender.type != 'Bot' && !github.event.pull_request.draft }} | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| issues: write | ||
| pull-requests: write | ||
| contents: write | ||
| checks: write | ||
|
Comment on lines
+12
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- .github/workflows/pr_agent.yaml ---'
sed -n '1,220p' .github/workflows/pr_agent.yaml
echo
echo '--- PR Agent references in repo ---'
rg -n "pr-agent|pr_agent|permiss|checks: write|contents: write|pull-requests: write|issues: write" .github README* docs* . || true
echo
echo '--- workflow file list ---'
git ls-files '.github/workflows/*'Repository: sid-ak/study_assistant Length of output: 1819 🌐 Web query:
💡 Result: To successfully run PR-Agent as a GitHub Action, the standard recommended configuration requires specific permissions to interact with your repository effectively [1][2][3]. The official documentation specifies that your workflow file should include the following permissions block [1][3]: permissions: issues: write pull-requests: write contents: write These permissions are necessary for the bot to perform actions such as posting review comments, updating pull request descriptions, and applying labels [2][4][3]. Important Considerations: 1. Permission Denied Errors: If you encounter a "Permission denied" error during execution, ensure that this permissions block is explicitly defined in your workflow file [1][2][3]. 2. Restricted Mode: If you cannot or do not wish to grant contents: write access, you can enable "restricted mode" in your PR-Agent configuration (setting config.restricted_mode = true) [1]. In this mode, the required permissions are reduced to: permissions: issues: write pull-requests: write 3. Security Context: While these permissions are required for full functionality, be aware that granting write access to the GITHUB_TOKEN allows the action to modify repository components [5][6]. Always follow the principle of least privilege appropriate for your organization's security policies [6]. 4. GitHub App Installation: If you are setting up PR-Agent as a GitHub App (rather than a simple GitHub Action workflow), the required permissions are configured directly in the GitHub App settings, which generally include: - Pull requests: Read & write - Issue comment: Read & write - Metadata: Read-only - Contents: Read-only [2][3] Citations:
🌐 Web query:
💡 Result: To run Qodo AI PR-Agent as a GitHub Action, your workflow must have specific permissions to interact with your repository, such as posting comments and managing PR information [1][2]. The recommended permissions for the job are as follows [1][2]: permissions: issues: write pull-requests: write contents: write Explanation of Permissions: - issues: write: Required for the agent to post comments on pull requests or issues [1][2]. - pull-requests: write: Necessary for the agent to perform actions on pull requests, such as adding labels, describing the PR, or requesting reviews [1][2]. - contents: write: Often required for actions that involve modifying code or repository contents, though some configurations may work with read-only access depending on the specific features enabled [1][3]. It is important to note that these permissions are applied to the Citations:
🌐 Web query:
💡 Result: When using PR-Agent as a GitHub Action, the "checks: write" permission is required specifically if you want the tool to publish its results—such as reviews, descriptions, or code improvements—as a GitHub Check Run rather than as a standard PR comment [1][2]. To configure this, you must explicitly grant the necessary permission in your GitHub Actions workflow YAML file [3][2]. Example configuration for your workflow file: jobs: pr_agent_job: runs-on: ubuntu-latest permissions: issues: write pull-requests: write contents: write checks: write # Required for publishing results to the Checks tab steps: - name: PR Agent action step uses: the-pr-agent/pr-agent@main env: OPENAI_KEY: ${{ secrets.OPENAI_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} Additionally, you must set the configuration parameter github.publish_as_check_run to true, as the default behavior is to post results as comments [2]. You can set this via environment variables in your workflow or in your.pr_agent.toml configuration file [2][4]. Note: The "checks: write" permission allows the GitHub Action to manage check runs via the GitHub REST API, which is a requirement for integrating with the Checks tab [5][2]. If this permission is missing while the feature is enabled, the action will likely fail due to insufficient privileges [3][6]. Citations:
Drop the unused PR Agent’s default GitHub Action setup uses 🤖 Prompt for AI Agents |
||
| name: Run PR Agent (Gemini free tier) on pull requests and comments | ||
| steps: | ||
| - name: PR Agent action step | ||
| uses: the-pr-agent/pr-agent@main | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Inspect available immutable refs for PR Agent before choosing a pinned version.
git ls-remote --tags https://github.com/the-pr-agent/pr-agent.git | tail -n 20
git ls-remote https://github.com/the-pr-agent/pr-agent.git refs/heads/mainRepository: sid-ak/study_assistant Length of output: 1372 🏁 Script executed: sed -n '1,80p' .github/workflows/pr_agent.yaml | cat -nRepository: sid-ak/study_assistant Length of output: 1373 Pin 🤖 Prompt for AI Agents |
||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| # Free-tier Gemini models via Google AI Studio — no OpenAI cost. | ||
| config.model: "gemini/gemini-2.5-flash" | ||
| config.fallback_models: '["gemini/gemini-2.5-flash-lite"]' | ||
| GOOGLE_AI_STUDIO.GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} | ||
| # Auto-run on new/updated PRs. | ||
| github_action_config.auto_review: "true" | ||
| github_action_config.auto_describe: "true" | ||
| github_action_config.auto_improve: "true" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,23 +9,42 @@ Anthropic API. | |
|
|
||
| - Read [`docs/architecture.md`](docs/architecture.md), it is the full design. | ||
| - Read ADRs under [`docs/decisions/`](docs/decisions/), locked decisions live there. | ||
| - Read the [GitHub issues](https://github.com/sid-ak/study_assistant/issues), work is tracked as phases there. | ||
| - Read the [GitHub issues](https://github.com/sid-ak/study_assistant/issues), work is tracked as | ||
| phases there. | ||
| - Read [`README.md`](README.md), Status blurb states intent. | ||
| - Compare against repo, which is the ground truth. | ||
| - Scan with `ls` and compare with directory structure in `architecture.md` to gauge progress. | ||
| - Use `git log` to reveal further current progress whether in between phases or mid-phase. | ||
| - Fetch the current issue being worked on from the GitHub repo, read its full content. | ||
| - Also read the full content of the current issue's sub issues (if any). | ||
|
|
||
| ## Governance model | ||
| ## Governance | ||
|
|
||
| Canonical context lives in `AGENTS.md` files (tool-neutral). Each `CLAUDE.md` is a one-line | ||
| `@AGENTS.md` import stub so Claude Code's directory-walk loading picks up the same content. Edit | ||
| `AGENTS.md`, never the stub. Each package/service carries its own scoped `AGENTS.md` describing its | ||
| surface; agents read the nearest file in the tree, so the closest one wins. This file is the root | ||
| entry point — keep package-specific detail in the package's own `AGENTS.md`. | ||
|
|
||
| ## Dev environment tips | ||
| ## Development | ||
|
|
||
| - Strict TDD, in three passes (binding, not a preference). For any new feature or issue: pass one | ||
| writes tests only — fully describing the expected behavior — with no interface or implementation | ||
| code, run and expect red. Pass two defines the interface(s) the code will satisfy — the `Protocol` | ||
| types and signatures, per the interface-first architecture | ||
| ([ADR 0006](docs/decisions/0006-interface-first-architecture.md)) — with no implementation logic. | ||
| Pass three adds the implementation behind those interfaces until the tests pass (green). This | ||
| applies to both unit and integration tests, per the `@pytest.mark.integration` marker in | ||
| `pyproject.toml`. | ||
| - As much as possible, write parametrized tests against the protocol. Use the `rag_core` module as | ||
| an example. | ||
| - Docstrings are mandatory on every module, class, and function repo-wide — including fixtures and | ||
| pytest hooks in `conftest.py`. This is machine-enforced: ruff's pydocstyle presence rules | ||
| (`D100`–`D107`) run in the same `ruff check` the CI gate uses, so a missing docstring fails the | ||
| build. A test's docstring states what behavior it pins; a fixture's states what it provides. Keep | ||
| them to one line unless the why is non-obvious. | ||
|
|
||
| ## Environment | ||
|
|
||
| - Python 3.12 on a `uv` workspace. Run `uv sync` once to resolve and install every workspace member | ||
| (root + `packages/*`) into a single `.venv`. | ||
|
|
@@ -42,40 +61,47 @@ entry point — keep package-specific detail in the package's own `AGENTS.md`. | |
| - Install hooks once with `pre-commit install`; `pre-commit run --all-files` runs lint + format + | ||
| typecheck across the tree. | ||
|
|
||
| ## Testing instructions | ||
| ## Testing | ||
|
|
||
| - The CI plan is in `.github/workflows/ci.yaml`: a `checks` job (ruff lint, ruff format check, mypy, | ||
| pytest against a pgvector service) and a `docs` job that builds the Sphinx site | ||
| (`uv run sphinx-build -b html docs site -W`, build-only — deployment lives in `docs-deploy.yaml`). | ||
| - Run the whole suite with `uv run pytest`. Integration tests need the database — run | ||
| `docker compose up -d` first or they fail to connect. | ||
| - Integration tests are marked `@pytest.mark.integration`. Scope a run with | ||
| `uv run pytest -m "not integration"` (fast, no DB) or `-m integration` (DB-backed); target one | ||
| test with `uv run pytest -k "<name>"`. | ||
| - Integration tests are marked `@pytest.mark.integration`. Scope a run with `uv run pytest -m unit` | ||
| (fast, no DB) or `-m integration` (DB-backed); target one test with `uv run pytest -k "<name>"`. | ||
| The `unit` marker is auto-applied to every non-integration test by the root `conftest.py`, so | ||
| `-m unit` always selects the full fast suite — mark only integration tests explicitly. | ||
| - Integration tests run against a separate database (`TEST_DATABASE_URL`, e.g. | ||
| `study_assistant_test`), never the app's `DATABASE_URL`, and truncate their tables between tests. | ||
| `docker compose up -d` remains the only setup step — the test database is created automatically by | ||
| `infra/postgres/init.sql` on first init, so a fresh clone needs nothing extra. | ||
| - Lint, format, and typecheck must also be green: | ||
| `uv run ruff check . && uv run ruff format --check . && uv run mypy`. Fix every error and type | ||
| failure until the whole suite is green before you merge. | ||
| - Docs must build clean: `uv run sphinx-build -b html docs site -W` (CI runs this too — `-W` turns | ||
| Sphinx warnings into errors, catching broken toctrees, anchors, and autodoc import failures). | ||
| - Add or update tests for the code you change, even if nobody asked. | ||
| - Tests come first, not alongside. Writing or updating tests for the code you change is mandatory | ||
| (even if nobody asked), and under the three-pass rule above it happens in pass one — before the | ||
| interface or implementation exists — not in the same pass as the code. | ||
| - Schema changes need a fresh DB: `initialize_schema()` is `CREATE ... IF NOT EXISTS` and will not | ||
| retrofit constraints, so run `docker compose down -v && docker compose up -d` after editing | ||
| `store/schema.py`. | ||
|
Comment on lines
87
to
89
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 4. Root agents.md leaks paths Root-level AGENTS.md includes concrete, package-specific implementation references (e.g., rag_core and store/schema.py) rather than staying purely cross-cutting. This reduces clarity of global guidance and should be moved to the package-scoped AGENTS.md. Agent Prompt
|
||
|
|
||
| ## Code style | ||
| ## Style | ||
|
|
||
| - `ruff` formats and lints (line length 100, rule set `E,F,I,UP,B`); `mypy` runs in `strict` mode. | ||
| Both must pass — do not silence them without cause. | ||
| - Type every function signature; `mypy --strict` rejects untyped defs. Prefer explicit, narrow types | ||
| over `Any`. | ||
|
|
||
| ## Binding decisions (ADRs) | ||
| ## Decisions (ADRs) | ||
|
|
||
| The locked architectural decisions are recorded as ADRs, indexed in | ||
| [`docs/decisions/`](docs/decisions/). They are binding and the source of truth — read the relevant | ||
| ADR before changing what it governs, and do not restate its rules here. | ||
|
|
||
| ## PR instructions | ||
| ## PRs | ||
|
|
||
| - Branch from `dev`, naming the branch with its GitHub issue number first (e.g. `4-embeddings` for | ||
| issue #4) so the branch links back to its issue. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| # Dev Cheatsheet | ||
|
|
||
| ## Start the DB | ||
|
|
||
| ```bash | ||
| docker compose up -d | ||
| ``` | ||
|
|
||
| ## Stop / reset DB (after schema changes) | ||
|
|
||
| ```bash | ||
| docker compose down -v && docker compose up -d | ||
| ``` | ||
|
|
||
| ## Install deps | ||
|
|
||
| ```bash | ||
| uv sync | ||
| ``` | ||
|
|
||
| ## Tests | ||
|
|
||
| ```bash | ||
| uv run pytest # everything | ||
| uv run pytest -m unit # fast, no DB | ||
| uv run pytest -m integration # DB-backed | ||
| uv run pytest -k "<test_name>" # one test | ||
| ``` | ||
|
|
||
| ## Lint / format / typecheck | ||
|
|
||
| ```bash | ||
| uv run ruff check . | ||
| uv run ruff format --check . | ||
| uv run mypy | ||
| ``` | ||
|
|
||
| ## Docs preview (clean rebuild + serve) | ||
|
|
||
| ```bash | ||
| rm -rf site && uv run sphinx-build -E -a -b html docs site -W | ||
| uv run python -m http.server -d site 8000 | ||
| ``` | ||
|
|
||
| ## Full pre-PR gate | ||
|
|
||
| ```bash | ||
| uv run ruff check . && uv run ruff format --check . && uv run mypy && uv run pytest && uv run sphinx-build -b html docs site -W | ||
| ``` | ||
|
|
||
| ## DB connection | ||
|
|
||
| | Field | Value | | ||
| | -------- | --------------- | | ||
| | Type | PostgreSQL | | ||
| | Host | localhost | | ||
| | Port | 5432 | | ||
| | Database | study_assistant | | ||
| | User | study | | ||
| | Password | change-me | | ||
|
|
||
| URL: `postgresql://study:change-me@localhost:5432/study_assistant` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| """Root pytest configuration shared across every workspace package. | ||
|
|
||
| Auto-applies the ``unit`` marker to any test not marked ``integration``, so ``uv run pytest -m | ||
| unit`` selects the fast, DB-free suite without each test file opting in, and keeps doing so as tests | ||
| are added. Integration tests opt in explicitly with ``@pytest.mark.integration`` (or a module-level | ||
| ``pytestmark``); everything else is unit by default. | ||
| """ | ||
|
|
||
| import pytest | ||
|
|
||
|
|
||
| def pytest_collection_modifyitems(items: list[pytest.Item]) -> None: | ||
| """Tag every collected test lacking the ``integration`` mark with the ``unit`` mark.""" | ||
| for item in items: | ||
| if item.get_closest_marker("integration") is None: | ||
| item.add_marker(pytest.mark.unit) |
Uh oh!
There was an error while loading. Please reload this page.