From 127114105de9f674c3667b13239e77da59f86423 Mon Sep 17 00:00:00 2001 From: Sidharth Anandkumar Date: Wed, 1 Jul 2026 22:30:24 -0400 Subject: [PATCH] Removed checkpoints and issues tracking as it is redundant. --- .github/scripts/checkpoint.py | 120 ------------------- .github/scripts/sync_issues.py | 92 -------------- .github/workflows/docs-deploy.yaml | 4 +- .github/workflows/sync-checkpoints.yaml | 56 --------- .github/workflows/sync-issues.yaml | 43 ------- AGENTS.md | 9 +- CONTRIBUTING.md | 8 +- README.md | 2 +- docs/checkpoints.md | 22 ---- docs/decisions/0005-documentation-tooling.md | 23 ++-- docs/index.md | 2 - docs/issues.md | 28 ----- 12 files changed, 19 insertions(+), 390 deletions(-) delete mode 100644 .github/scripts/checkpoint.py delete mode 100644 .github/scripts/sync_issues.py delete mode 100644 .github/workflows/sync-checkpoints.yaml delete mode 100644 .github/workflows/sync-issues.yaml delete mode 100644 docs/checkpoints.md delete mode 100644 docs/issues.md diff --git a/.github/scripts/checkpoint.py b/.github/scripts/checkpoint.py deleted file mode 100644 index 1110e94..0000000 --- a/.github/scripts/checkpoint.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python3 -"""Append a row to ``docs/checkpoints.md`` when a pull request is merged into the default branch. - -Run by ``.github/workflows/sync-checkpoints.yaml`` on ``pull_request`` closed+merged. A row is -added when the merged PR either: - -* closes a ``phase``-labeled issue → checkpoint = the PR title, or -* carries a commit whose subject is ``checkpoint: `` → checkpoint = ```` (one row per - such commit). An optional ``#-`` / ``-`` prefix (e.g. ``#2-checkpoint:``) sets the - Issue column; without it the Issue comes from the PR branch's leading number. - -Recording only on merge means a checkpoint lands in the log exactly when its commit reaches the -default branch — never while it is still on a feature branch. Columns: -``Date | Branch | Issue | Checkpoint``; Branch is the PR head ref. Appends are idempotent: an -identical row is not added twice. -""" - -from __future__ import annotations - -import json -import os -import re -import subprocess -import sys -from datetime import date -from pathlib import Path - -DEFAULT_DOC = Path(__file__).resolve().parents[2] / "docs" / "checkpoints.md" -DOC = Path(os.environ.get("CHECKPOINTS_FILE", str(DEFAULT_DOC))) -# Checkpoint commit subjects look like `checkpoint: drafted store schema`, optionally with an -# issue-number prefix like `#1-checkpoint: ...` or `1-checkpoint: ...` (the `#` and the `-` are -# both optional; `#` auto-links the issue on GitHub). The number, when present, sets the Issue -# column; otherwise it falls back to the PR branch. -CHECKPOINT_RE = re.compile(r"^(?:#?(?P\d+)-)?checkpoint:\s*(?P.*)$", re.IGNORECASE) - - -def gh(*args: str) -> str: - """Run a ``gh`` command and return stdout.""" - return subprocess.run(["gh", *args], capture_output=True, text=True, check=True).stdout - - -def issue_from_branch(branch: str) -> str: - """Leading issue number of the branch name, or '' (e.g. ``1-foundations`` → ``1``).""" - match = re.match(r"(\d+)", branch) - return match.group(1) if match else "" - - -def pr_closes_phase_issue(repo: str, pr_number: str) -> bool: - """True if the PR closes at least one issue carrying the ``phase`` label.""" - refs = json.loads( - gh("pr", "view", pr_number, "--repo", repo, "--json", "closingIssuesReferences") - )["closingIssuesReferences"] - for ref in refs: - labels = json.loads( - gh("issue", "view", str(ref["number"]), "--repo", repo, "--json", "labels") - )["labels"] - if any(label["name"] == "phase" for label in labels): - return True - return False - - -def pr_checkpoint_commits(repo: str, pr_number: str) -> list[tuple[str, str]]: - """(issue, text) for each commit on the PR whose subject is a ``checkpoint:`` commit. - - Reads the PR's own commits, so it is unaffected by the merge strategy (merge/squash/rebase). - """ - raw = gh("pr", "view", pr_number, "--repo", repo, "--json", "commits") - commits = json.loads(raw)["commits"] - out: list[tuple[str, str]] = [] - for commit in commits: - match = CHECKPOINT_RE.match(commit.get("messageHeadline", "").strip()) - if match: - out.append((match.group("issue") or "", match.group("text").strip())) - return out - - -def esc(value: str) -> str: - """Flatten and escape text so it stays inside one table cell.""" - return value.replace("|", "\\|").replace("\n", " ").strip() - - -def append_row(when: str, branch: str, issue: str, checkpoint: str) -> None: - row = f"| {when} | `{branch}` | {issue} | {esc(checkpoint)} |" - text = DOC.read_text() - if row in text: - print("Checkpoint row already present; skipping.") - return - if not text.endswith("\n"): - text += "\n" - DOC.write_text(text + row + "\n") - print(f"Appended checkpoint: {row}") - - -def main() -> int: - repo = os.environ["GITHUB_REPOSITORY"] - pr_number = os.environ["PR_NUMBER"] - branch = os.environ["PR_HEAD_REF"] - title = os.environ["PR_TITLE"] - today = date.today().isoformat() - - recorded = False - - # A merged PR that closes a phase-labeled issue → one row built from the PR itself. - if pr_closes_phase_issue(repo, pr_number): - append_row(today, branch, issue_from_branch(branch), title) - recorded = True - - # Any `checkpoint:` commit that rode in on the PR → one row each. Issue comes from the commit's - # own `#-` prefix when present, else the PR branch's leading number. - for issue, text in pr_checkpoint_commits(repo, pr_number): - append_row(today, branch, issue or issue_from_branch(branch), text) - recorded = True - - if not recorded: - print("PR closes no phase issue and has no checkpoint commit; nothing to record.") - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/.github/scripts/sync_issues.py b/.github/scripts/sync_issues.py deleted file mode 100644 index bfc7b44..0000000 --- a/.github/scripts/sync_issues.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python3 -"""Regenerate ``docs/issues.md`` from this repo's GitHub issues. - -GitHub is the source of truth. This is run by ``.github/workflows/sync-issues.yaml`` on -issue events, and can also be run locally (requires ``gh`` to be authenticated). Issue -bodies are not mirrored — only number, title, state, labels, and the sub-issue parent. -""" - -from __future__ import annotations - -import json -import os -import subprocess -from pathlib import Path - -OUT = Path(__file__).resolve().parents[2] / "docs" / "issues.md" - - -def gh(*args: str) -> str: - """Run a ``gh`` command and return stdout.""" - return subprocess.run(["gh", *args], capture_output=True, text=True, check=True).stdout - - -def repo_slug() -> str: - """``OWNER/REPO`` from the Actions env, falling back to ``gh`` for local runs.""" - slug = os.environ.get("GITHUB_REPOSITORY") - if slug: - return slug - return gh("repo", "view", "--json", "nameWithOwner", "-q", ".nameWithOwner").strip() - - -def esc(value: str) -> str: - """Escape table-breaking pipes and trim surrounding whitespace.""" - return value.replace("|", "\\|").strip() - - -def main() -> None: - repo = repo_slug() - issues = json.loads( - gh( - "issue", - "list", - "--repo", - repo, - "--state", - "all", - "--limit", - "500", - "--json", - "number,title,state,labels", - ) - ) - - # Build a child-number -> parent-number map from the sub-issue graph. - parent_of: dict[int, int] = {} - for issue in issues: - number = issue["number"] - try: - children = json.loads( - gh("api", f"repos/{repo}/issues/{number}/sub_issues", "--jq", "[.[].number]") - ) - except subprocess.CalledProcessError: - children = [] # issue has no sub-issues (endpoint 404s) - for child in children: - parent_of[child] = number - - rows = [] - for issue in sorted(issues, key=lambda i: i["number"]): - number = issue["number"] - title = esc(issue["title"]) - state = issue["state"].lower() - labels = esc(", ".join(sorted(label["name"] for label in issue["labels"]))) - parent = parent_of.get(number, "") - rows.append(f"| {number} | {title} | {state} | {labels} | {parent} |") - - preamble = ( - "# Issues\n" - "\n" - "> Auto-generated — do not edit by hand. This table mirrors the GitHub issues for\n" - f"> [`{repo}`](https://github.com/{repo}/issues) and is regenerated by the `sync-issues`\n" - "> workflow (`.github/workflows/sync-issues.yaml`) on every issue event. GitHub is the\n" - "> source of truth — manage issues there, not here. Issue bodies are not mirrored.\n" - "\n" - "| # | Title | State | Labels | Parent |\n" - "| --- | ----- | ----- | ------ | ------ |\n" - ) - OUT.write_text(preamble + "\n".join(rows) + "\n") - print(f"Wrote {len(rows)} issues to {OUT}") - - -if __name__ == "__main__": - main() diff --git a/.github/workflows/docs-deploy.yaml b/.github/workflows/docs-deploy.yaml index 6e1f68a..62f5897 100644 --- a/.github/workflows/docs-deploy.yaml +++ b/.github/workflows/docs-deploy.yaml @@ -1,7 +1,7 @@ name: Deploy docs -# Build the Sphinx site and publish it to GitHub Pages on push to main or dev. Kept separate from -# ci.yaml (like sync-issues / sync-checkpoints) so CI stays build-and-test only, with no deploy. +# Build the Sphinx site and publish it to GitHub Pages on push to main or dev. Kept as its own +# workflow (not a job in ci.yaml) so CI stays build-and-test only, with no deploy. on: push: branches: [main, dev] diff --git a/.github/workflows/sync-checkpoints.yaml b/.github/workflows/sync-checkpoints.yaml deleted file mode 100644 index 4a58b3a..0000000 --- a/.github/workflows/sync-checkpoints.yaml +++ /dev/null @@ -1,56 +0,0 @@ -name: Sync checkpoints log - -# Append a row to docs/checkpoints.md when a PR is merged into the default branch (dev): -# - the merged PR closes a `phase`-labeled issue (checkpoint = PR title), or -# - the merged PR carries a `checkpoint: ` commit (checkpoint = ; an optional -# `#-` / `-` prefix is accepted). -# Checkpoints are recorded only on merge, never from feature-branch pushes. -on: - pull_request: - types: [closed] - -permissions: - contents: write - issues: read - pull-requests: read - -# Shared group with sync-issues so the two doc-sync workflows never push to the default -# branch at the same time (merging a phase PR fires both `issues` and `pull_request`). -concurrency: - group: repo-docs-sync - cancel-in-progress: false - -jobs: - checkpoint: - runs-on: ubuntu-latest - # Only a PR merged into the default branch (dev). checkpoint.py decides whether it warrants a - # row (closes a phase issue, or carries a `checkpoint:` commit). - if: >- - github.event.pull_request.merged == true && - github.event.pull_request.base.ref == github.event.repository.default_branch - steps: - - uses: actions/checkout@v5 - with: - # Commit the log to the default branch (dev). The row's Branch column records the PR head. - ref: ${{ github.event.repository.default_branch }} - - - name: Append checkpoint row (if applicable) - env: - GH_TOKEN: ${{ github.token }} - GITHUB_REPOSITORY: ${{ github.repository }} - PR_NUMBER: ${{ github.event.pull_request.number }} - PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} - PR_TITLE: ${{ github.event.pull_request.title }} - run: python3 .github/scripts/checkpoint.py - - - name: Commit if changed - run: | - if git diff --quiet -- docs/checkpoints.md; then - echo "No checkpoint change." - exit 0 - fi - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add docs/checkpoints.md - git commit -m "chore: append checkpoint to docs/checkpoints.md [skip ci]" - git push diff --git a/.github/workflows/sync-issues.yaml b/.github/workflows/sync-issues.yaml deleted file mode 100644 index 9aa6384..0000000 --- a/.github/workflows/sync-issues.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: Sync issues mirror - -# Regenerate docs/issues.md from GitHub issues whenever issues change. GitHub is the -# source of truth; this keeps the in-repo mirror in step and commits it back. -on: - issues: - types: [opened, closed, reopened, edited, labeled, unlabeled, deleted, transferred] - -permissions: - contents: write - issues: read - -# Shared group with sync-checkpoints so the two doc-sync workflows never push to the -# default branch at the same time (e.g. when merging a phase PR fires both at once). -concurrency: - group: repo-docs-sync - cancel-in-progress: false - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - with: - # Always operate on the default branch (dev) — that is where the mirror lives. - ref: ${{ github.event.repository.default_branch }} - - - name: Regenerate docs/issues.md - env: - GH_TOKEN: ${{ github.token }} - run: python3 .github/scripts/sync_issues.py - - - name: Commit if changed - run: | - if git diff --quiet -- docs/issues.md; then - echo "docs/issues.md already up to date." - exit 0 - fi - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add docs/issues.md - git commit -m "chore: sync docs/issues.md from GitHub issues [skip ci]" - git push diff --git a/AGENTS.md b/AGENTS.md index 365667a..74f3960 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,8 +9,7 @@ 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 [`docs/issues.md`](docs/issues.md), work is tracked as phases there. -- Read [`docs/checkpoints.md`](docs/checkpoints.md), completed work is tracked 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. @@ -79,12 +78,12 @@ ADR before changing what it governs, and do not restate its rules here. ## PR instructions - Branch from `dev`, naming the branch with its GitHub issue number first (e.g. `4-embeddings` for - issue #4) so `docs/checkpoints.md` attributes correctly. + issue #4) so the branch links back to its issue. - PR title format: `[] ` — e.g. `[rag_core/store] Add schema + CRUD`. - Run the full gate green before handing off (with `docker compose up -d`): `uv run ruff check . && uv run ruff format --check . && uv run mypy && uv run pytest && uv run sphinx-build -b html docs site -W`. -- Update the `README.md` Status blurb in the same change — current status lives there (and in - `docs/issues.md` / `docs/checkpoints.md`), not in this file. +- Update the `README.md` Status blurb in the same change — current status lives there (and in the + GitHub issues), not in this file. - Never commit; only stage. Do not run `git commit`. At the end of a set of changes, `git add` the relevant files and leave them staged for the human to review — but only if 0 files are currently staged. If anything is already staged, do not stage at all; leave the working tree as-is. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 695edf8..83635e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,8 +34,6 @@ pre-commit install # installs the git hooks valid in branch names.) - Commit message: prefix with `#<number>` so GitHub auto-links the issue, e.g. `#1 add pgvector schema`. - - Checkpoint commit messages: `checkpoint: <text>` (optional `#<number>-` prefix). Recorded when - the commit is merged into `dev`, not on the feature-branch push. ## Governance (`AGENTS.md`) @@ -52,7 +50,5 @@ changing direction. ## Issues / roadmap -Work is tracked as phases on GitHub Issues, which are the source of truth. `docs/issues.md` is an -auto-generated mirror: the `sync-issues` workflow (`.github/workflows/sync-issues.yaml`) regenerates -and commits it whenever an issue is opened, closed, edited, or relabeled. Manage issues on GitHub — -don't hand-edit `docs/issues.md`. Issue bodies are not mirrored. +Work is tracked as phases on [GitHub Issues](https://github.com/sid-ak/study_assistant/issues), +which are the source of truth — manage them there. diff --git a/README.md b/README.md index b627f0c..87024f1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ free; only answer generation calls the Anthropic API. - Design: [`docs/architecture.md`](docs/architecture.md) - Decisions: [`docs/decisions/`](docs/decisions/) (ADRs) -- Roadmap: [`docs/issues.md`](docs/issues.md) (phased) +- Roadmap: [GitHub issues](https://github.com/sid-ak/study_assistant/issues) (phased) ## Status diff --git a/docs/checkpoints.md b/docs/checkpoints.md deleted file mode 100644 index c722f47..0000000 --- a/docs/checkpoints.md +++ /dev/null @@ -1,22 +0,0 @@ -# Checkpoints - -An append-only log of project checkpoints — one row per major iteration. It gives a human or a fresh -agent a quick history of how the project advanced and where it was left off. - -Rows are appended automatically by the `sync-checkpoints` workflow -(`.github/workflows/sync-checkpoints.yaml`) when a pull request is merged into `dev`; don't -hand-edit this file. A row is added when the merged PR either: - -- closes a `phase`-labeled issue (checkpoint = the PR title), or -- carries a `checkpoint: <text>` commit (checkpoint = `<text>`, one row per such commit); an - optional `#<number>-` prefix sets the Issue column, otherwise it comes from the PR branch. - -The Issue column is the leading number of the branch name, which must be the GitHub issue number -(e.g. `1-foundations` → `1`), or blank when the branch starts with no number (see -`CONTRIBUTING.md`). - -| Date | Branch | Issue | Checkpoint | -| ---------- | --------------- | ----- | -------------------------------------------------------------- | -| 2026-06-27 | `1-foundations` | 1 | #1 Phase 0 — Foundations: uv workspace, pgvector stack, and CI | -| 2026-07-02 | `2-phase-1-add-docs` | 2 | docs site test | -| 2026-07-02 | `2-phase-1-add-docs` | 2 | testing sync-checkpoints. | diff --git a/docs/decisions/0005-documentation-tooling.md b/docs/decisions/0005-documentation-tooling.md index c835e84..786abc0 100644 --- a/docs/decisions/0005-documentation-tooling.md +++ b/docs/decisions/0005-documentation-tooling.md @@ -5,14 +5,12 @@ ## Context -The narrative docs (`architecture.md`, ADRs, `issues.md`, `checkpoints.md`) are already a -Markdown-only, docs-as-code tree. Once `rag_core` carries real typed modules (`config.py`, `store/`, -and later `ingest/`, `embed/`, `rerank/`, `retrieve/`), a second need shows up: a browsable API -reference generated from docstrings and the `mypy --strict` type hints already required by -`AGENTS.md`, rather than hand-written and prone to drifting from the code. Both halves — narrative -and generated reference — are wanted in one static site, deployed the same way the rest of the -project's automation works (a GitHub Actions workflow, alongside `sync-issues` and -`sync-checkpoints`). +The narrative docs (`architecture.md` and the ADRs) are already a Markdown-only, docs-as-code tree. +Once `rag_core` carries real typed modules (`config.py`, `store/`, and later `ingest/`, `embed/`, +`rerank/`, `retrieve/`), a second need shows up: a browsable API reference generated from docstrings +and the `mypy --strict` type hints already required by `AGENTS.md`, rather than hand-written and +prone to drifting from the code. Both halves — narrative and generated reference — are wanted in one +static site, deployed by a GitHub Actions workflow like the rest of the project's automation. An initial pass adopted MkDocs + `mkdocstrings` + Material for MkDocs and got as far as a working `mkdocs.yml`, a generated API reference page, and a deploy workflow. That work surfaced a governance @@ -82,8 +80,8 @@ production site depending on it yet, so this is the cheapest point at which to s and its tooling in one language and one workspace ([ADR 0000](0000-stack.md)) — no Node runtime (as Starlight/VitePress/Docusaurus would require) or separate binary (as Quarto would require) enters the toolchain. -- `myst-parser` means `architecture.md`, the ADRs, `issues.md`, and `checkpoints.md` are wired into - a Sphinx `toctree` as-is; no content is rewritten into reStructuredText. +- `myst-parser` means `architecture.md` and the ADRs are wired into a Sphinx `toctree` as-is; no + content is rewritten into reStructuredText. - Gives up things this project doesn't currently need: Docusaurus-grade versioning/i18n, Starlight's zero-client-JS search speed, and Quarto's live code execution. Quarto in particular is a candidate to revisit later, under a documentation "Future Scope," once retrieval/generation output exists to @@ -91,6 +89,5 @@ production site depending on it yet, so this is the cheapest point at which to s - Some Sphinx configuration and cross-referencing (`conf.py`, roles like `:py:class:`) is still reST-flavored under the hood even though page content is authored in Markdown — an accepted friction in exchange for governance stability and native `autodoc`/type-hint integration. -- Deployment follows the same pattern as the rest of the project's automation: a GitHub Actions - workflow builds the site and publishes to GitHub Pages, split out from `ci.yaml` the same way - `sync-issues` and `sync-checkpoints` already are. +- Deployment is a GitHub Actions workflow that builds the site and publishes to GitHub Pages, kept + as its own workflow rather than a job in `ci.yaml`. diff --git a/docs/index.md b/docs/index.md index 045261a..81088b0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -9,8 +9,6 @@ :caption: Project architecture.md -issues.md -checkpoints.md ``` ```{toctree} diff --git a/docs/issues.md b/docs/issues.md deleted file mode 100644 index 47079ea..0000000 --- a/docs/issues.md +++ /dev/null @@ -1,28 +0,0 @@ -# Issues - -> Auto-generated — do not edit by hand. This table mirrors the GitHub issues for -> [`sid-ak/study_assistant`](https://github.com/sid-ak/study_assistant/issues) and is regenerated by -> the `sync-issues` workflow (`.github/workflows/sync-issues.yaml`) on every issue event. GitHub is -> the source of truth — manage issues there, not here. Issue bodies are not mirrored. - -| # | Title | State | Labels | Parent | -| --- | ------------------------------------------------------------------- | ------ | ----------------------------- | ------ | -| 1 | Phase 0 — Foundations | closed | phase | | -| 2 | Phase 1 — Storage + schema (rag_core/store) | open | phase | | -| 3 | Phase 2 — Ingestion + CLI (rag_core/ingest + cli/) | open | phase | | -| 4 | Phase 3 — Embeddings + dense retrieval (rag_core/embed) | open | phase | | -| 5 | Phase 4 — Hybrid retrieval + reranking (rag_core/retrieve + rerank) | open | phase | | -| 6 | Phase 5 — MCP server | open | phase | | -| 7 | Phase 6 — FastAPI + LangGraph + streaming | open | phase | | -| 8 | Phase 7 — Human-in-the-loop checkpoints | open | phase | | -| 9 | Phase 8 — React frontend | open | phase | | -| 10 | Phase 9 — CI/CD hardening + full-stack e2e | open | phase | | -| 11 | Cap per-turn retrieval calls and cache rerank scores | open | improvement, priority: high | 7 | -| 12 | Document ts_rank as BM25 approximation and validate before pg_bm25 | open | improvement, priority: medium | 5 | -| 13 | Define per-content-type chunking strategy | open | improvement, priority: medium | 3 | -| 14 | Add manifest table for idempotent ingestion | open | improvement, priority: low | 3 | -| 15 | Record embedder model/dimension and stub re-embed migration | open | improvement, priority: medium | 4 | -| 16 | Isolate Anthropic SDK calls in a single generation module | open | improvement, priority: low | 7 | -| 17 | Define explicit SSE event types for HITL streaming | open | improvement, priority: medium | 8 | -| 18 | Add /health endpoint reporting model load status | open | improvement, priority: low | 6 | -| 19 | Augment golden eval set with synthetic query variations | open | improvement, priority: low | 4 |