From bb7af3cb48aaccbf0df314a9f5c0f3e984c69de0 Mon Sep 17 00:00:00 2001 From: Shawn Hartsock Date: Sun, 31 May 2026 12:11:29 -0400 Subject: [PATCH] docs: remove private/internal references for the public repo WHAT: Genericize every reference to private repos/infra that would confuse external readers of this public repo: - gilabot / gila-plugin-git-tend / gila_plugin_git_tend / "gila git-tend" -> the generic "git-tend" tool + its GitService read surface (no private repo named). - Dropped the gilabot GitHub URL and the "pin to gilabot CI / .ci/tool-versions" note (-> "a recent stable Rust toolchain"). - gnuc / "the bastion" / ~/venv -> generic build instructions. - my_home#46 -> the incident described without the private issue number. - Private class/module names (StatusService, ScanService, TendService, PRService, models.SyncState, status_service.py) -> "the status roll-up" / check_repo / "higher-level services". WHY: gitxtend is public; gilabot and the rest are private. Those references were dead links / unexplained internals for anyone outside the workspace. All technical content (gix mappings, API surface, SyncState tree) is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- Cargo.toml | 2 +- README.md | 41 +++++++++++++++++++---------------------- docs/API.md | 16 ++++++++-------- docs/DESIGN.md | 12 ++++++------ docs/PORTING.md | 6 +++--- docs/ROADMAP.md | 12 ++++++------ src/python.rs | 2 +- src/status.rs | 2 +- 8 files changed, 45 insertions(+), 48 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0a4a2e9..60aaf30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ python = ["dep:pyo3"] extension-module = ["python", "pyo3/extension-module"] [dependencies] -# gitoxide read side. Pinned to a recent release on gnuc (rustc 1.93). Features +# gitoxide read side. Pinned to a recent release (rustc 1.93). Features # are added per method: status (is_clean/status_counts), revision (ahead_behind/ # rev_list_count/log_subjects), dirwalk (untracked), blocking-network-client # (fetch — M1's one network call). diff --git a/README.md b/README.md index 4b31a76..4199e43 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,17 @@ many repositories — backed by [gitoxide (`gix`)][gix] and exposed to Python through [PyO3]/[maturin]. > **Status: scaffold / specification.** This repository currently contains the -> design, the API contract, and build stubs. The Rust implementation is built -> on **gnuc** (the development machine), not on the bastion. See +> design, the API contract, and build stubs. See > [`docs/DESIGN.md`](docs/DESIGN.md) and [`docs/PORTING.md`](docs/PORTING.md) > for exactly what to implement. ## Why this exists -The [`gila git-tend`][gittend] plugin already does repository tending well, but +A Python repository-*tending* tool (`git-tend`) already does this well, but every git operation forks the `git` CLI via `subprocess.run(["git", ...])`. -A `git-tend status` / `scan` across a workspace of N repos spawns dozens of -short-lived `git` processes per run, and the tool's behaviour is coupled to -whatever `git` binary and version happens to be on `PATH`. +A `status` / `scan` across a workspace of N repos spawns dozens of short-lived +`git` processes per run, and the tool's behaviour is coupled to whatever `git` +binary and version happens to be on `PATH`. `gitxtend` replaces that seam with **in-process git** via gitoxide: @@ -25,12 +24,13 @@ whatever `git` binary and version happens to be on `PATH`. - **No `git` on `PATH` dependency.** The git logic is compiled in. - **One artifact.** A single compiled module (`.so` wheel) — or, optionally, a standalone CLI binary — carries the whole git layer. -- **Same contract.** It re-implements the exact method surface of git-tend's - `GitService` so the Python plugin can adopt it with a one-line import swap. +- **Same contract.** It re-implements the exact method surface of the Python + `GitService` git layer it replaces, so the tending tool can adopt it with a + one-line import swap. -The motivating incident: while merging `my_home#46`, a local-only **unpushed** -commit on `main` was nearly lost during a merge+reset. Tending is the discipline -that catches that; `gitxtend` makes tending fast enough to run constantly. +The motivating incident: a local-only **unpushed** commit on `main` was nearly +lost during a merge+reset. Tending is the discipline that catches that; +`gitxtend` makes tending fast enough to run constantly. ## What it will do (v1 scope) @@ -49,10 +49,10 @@ work that needs attention, without mutating any repo: | Last commit date (ISO 8601) | `last_commit_date` | `last_commit_date(path)` | | Modified / untracked counts | `status_counts` | `status_counts(path)` | | Fetch from remote | `fetch` | `fetch(path, remote=None)` | -| **Roll-up** | `StatusService.check_repo` | `repo_status(path, fetch=True) -> RepoStatus` | +| **Roll-up** | `check_repo` | `repo_status(path, fetch=True) -> RepoStatus` | The **write side** (`pull --ff-only`, `push`, `add`, `commit`, `stash`, -`branch`, `reset --hard`) stays in the Python plugin shelling out to `git` until +`branch`, `reset --hard`) stays in the host tool shelling out to `git` until the read path is proven in production. See [`docs/ROADMAP.md`](docs/ROADMAP.md). ## Layout @@ -74,24 +74,22 @@ gitxtend/ └── ROADMAP.md # milestones; read-side first, write-side later ``` -## Building (on gnuc) +## Building ```bash -# from a checkout on gnuc, inside ~/venv +# from a checkout, inside your Python virtualenv maturin develop --release # build + install into the active venv # or, to produce a distributable wheel: maturin build --release ``` -Toolchain: Rust (pin to the gilabot CI toolchain — see -`.ci/tool-versions.toml` in gilabot), `maturin`, Python 3.11+. +Toolchain: a recent stable Rust, `maturin`, Python 3.11+. ## Integration target -Drop-in for `gila_plugin_git_tend.services.git_service.GitService`'s read -methods. The plugin keeps its CLI, config, forge (gh/glab), and board logic; -only the git layer changes. See [`docs/API.md`](docs/API.md) for the adapter -shape. +Drop-in for a Python `GitService` git layer's read methods. The host tool keeps +its CLI, config, forge (gh/glab), and board logic; only the git layer changes. +See [`docs/API.md`](docs/API.md) for the adapter shape. ## License @@ -100,4 +98,3 @@ Apache License 2.0 — see [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE). [gix]: https://github.com/Byron/gitoxide [PyO3]: https://pyo3.rs [maturin]: https://www.maturin.rs -[gittend]: https://github.com/hartsock/gilabot (gila-plugin-git-tend) diff --git a/docs/API.md b/docs/API.md index be21d9c..dd8b685 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,8 +1,8 @@ # gitxtend — Python API Contract This is the exact Python-visible surface the compiled module must expose. It -mirrors `gila_plugin_git_tend.services.git_service.GitService` (read side) plus -one roll-up that mirrors `StatusService.check_repo`. +mirrors the `git-tend` tool's `GitService` (read side) plus one roll-up that +mirrors its `check_repo`. Type stubs live in [`../python/gitxtend/__init__.pyi`](../python/gitxtend/__init__.pyi). @@ -68,7 +68,7 @@ def fetch(path, remote=None) -> bool # Python caller must not care which. ``` -## Roll-up (port of StatusService.check_repo) +## Roll-up (port of check_repo) ```python class RepoStatus: @@ -85,7 +85,7 @@ class RepoStatus: error: str | None def repo_status(path, fetch=True) -> RepoStatus - # Mirrors StatusService.check_repo exactly: + # Mirrors check_repo exactly: # 1. not a repo -> state="error", error set # 2. no upstream -> state="no-remote", is_dirty filled # 3. fetch (if requested) @@ -93,11 +93,11 @@ def repo_status(path, fetch=True) -> RepoStatus # 5. decide state via the tree below ``` -### SyncState values (exact strings, from models.SyncState) +### SyncState values (exact strings) `"up-to-date" | "ahead" | "behind" | "diverged" | "dirty" | "no-remote" | "error"` -### State decision tree (must match status_service.py) +### State decision tree ``` ahead>0 and behind>0 -> "diverged" @@ -112,7 +112,7 @@ else -> "up-to-date" git-tend can adopt this with a shim that keeps the old class name: ```python -# gila_plugin_git_tend/services/git_service.py (read side) +# services/git_service.py (read side) import gitxtend class GitService: @@ -133,6 +133,6 @@ class GitService: # write methods (pull/push/add/commit/stash/branch/reset) unchanged for now ``` -Or, better, route `StatusService` straight at `gitxtend.repo_status()` and +Or, better, route the status roll-up straight at `gitxtend.repo_status()` and delete the per-method round-trips. Both are acceptable; the per-method shim is the lowest-risk first step. diff --git a/docs/DESIGN.md b/docs/DESIGN.md index d0ff90c..c6e523a 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -9,10 +9,10 @@ import swap in the Python plugin. ## Background: the seam we are replacing -In `gila-plugin-git-tend`, **all** git operations funnel through one class: +In the `git-tend` tool, **all** git operations funnel through one class: ```python -# gila_plugin_git_tend/services/git_service.py +# services/git_service.py class GitService: def run(self, path, args): return subprocess.run(["git"] + args, cwd=path, @@ -23,8 +23,8 @@ class GitService: # last_commit_date, status_counts ``` -Everything above `GitService` (`StatusService`, `ScanService`, `TendService`, -`PRService`, config, board, CLI) is untouched by this project. They consume +Everything above `GitService` (the higher-level services, config, board, CLI) +is untouched by this project. They consume `GitService` purely through its method surface. That surface is our contract. ## Why gitoxide @@ -66,7 +66,7 @@ src/lib.rs #[pymodule] — registers the Python-visible functions/classes, src/repo.rs The gix-backed primitives, one per GitService read method. Pure Rust, no PyO3 — unit-testable with gix fixtures. -src/status.rs repo_status(): the StatusService.check_repo roll-up, including +src/status.rs repo_status(): the check_repo roll-up, including the SyncState decision tree, expressed in Rust over repo.rs. ``` @@ -86,6 +86,6 @@ and reused by an optional CLI `bin` target. ## Non-goals - Reimplementing the CLI, YAML config, forge (gh/glab) integration, the - knowledge-board logic, or the systemd timer. Those stay in Python. + board logic, or the systemd timer. Those stay in Python. - Replacing the write/merge/conflict machinery in v1. - Being a general-purpose git library. Scope is exactly git-tend's needs. diff --git a/docs/PORTING.md b/docs/PORTING.md index 3b644ac..f0bee2e 100644 --- a/docs/PORTING.md +++ b/docs/PORTING.md @@ -3,7 +3,7 @@ Per-method mapping from git-tend's `GitService` (which shells out to `git`) to gitoxide (`gix`) calls. This is the implementation checklist for `src/repo.rs` and `src/status.rs`. Crate versions are not pinned here — pin `gix` to a recent -release in `Cargo.toml` and align the Rust toolchain with gilabot CI. +release in `Cargo.toml` and use a recent stable Rust toolchain. Legend: **CLI** = what git-tend runs today · **gix** = intended approach. @@ -90,7 +90,7 @@ Legend: **CLI** = what git-tend runs today · **gix** = intended approach. ## repo_status(path, fetch) -> RepoStatus (src/status.rs) -Port `StatusService.check_repo` verbatim: +Port `check_repo` verbatim: ``` status = RepoStatus(path) @@ -123,5 +123,5 @@ tests assert on them. - **Python smoke tests** post-`maturin develop`: import the module, run `repo_status()` on a fixture, assert fields. -See gilabot's rule: every behaviour needs a regression test; mock/contain +Rule of thumb: every behaviour needs a regression test; mock/contain external resources. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 0fc48f6..ec4607e 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -5,7 +5,7 @@ - README, DESIGN, API contract, PORTING guide. - Build stubs: `Cargo.toml`, `pyproject.toml`, `src/lib.rs` (signatures + `todo!()`), `.pyi` type stubs. -- **Outcome:** gnuc can `git clone`, `maturin develop`, and get an importable +- **Outcome:** you can `git clone`, `maturin develop`, and get an importable module whose functions raise `NotImplementedError`/`todo!()`. ## M1 — Read side (the unpushed-work detector) @@ -17,16 +17,16 @@ Implement, with parity tests vs the `git` CLI, in this order: 5. `remote_urls`, `last_commit_date`. 6. `repo_status()` roll-up + full SyncState tree. - **Acceptance:** every method agrees with `git` on the fixture matrix; - `repo_status()` reproduces `StatusService.check_repo` on diverged/ahead/ + `repo_status()` reproduces `check_repo` on diverged/ahead/ behind/dirty/no-remote/error fixtures. - **Note:** `fetch()` may ship as a contained shell-out if gix fetch is unstable (see PORTING.md). Everything else is pure gix. ## M2 — Plugin adoption -- Add the `GitService` read-method shim (API.md) in gila-plugin-git-tend, or - point `StatusService` straight at `gitxtend.repo_status()`. +- Add the `GitService` read-method shim (API.md) in the git-tend tool, or + point the status roll-up straight at `gitxtend.repo_status()`. - Gate behind a feature flag / env var so it can be rolled back instantly. -- Run `gila git-tend scan` / `status` across the real workspace; compare +- Run the git-tend `scan` / `status` across the real workspace; compare output to the subprocess implementation byte-for-byte. ## M3 — Standalone CLI (optional) @@ -41,4 +41,4 @@ Implement, with parity tests vs the `git` CLI, in this order: ## Out of scope (stays in Python, indefinitely) - CLI/UX, YAML config, forge integration (gh/glab PR/MR auto-merge), - knowledge-board conflict resolution, systemd timer. + board conflict resolution, systemd timer. diff --git a/src/python.rs b/src/python.rs index f7fa15b..217781c 100644 --- a/src/python.rs +++ b/src/python.rs @@ -10,7 +10,7 @@ use pyo3::prelude::*; use std::collections::HashMap; -/// Roll-up mirroring `StatusService.check_repo` / `models.RepoStatus`. +/// Roll-up mirroring `check_repo` / `RepoStatus`. /// /// `skip_from_py_object`: this type is returned to Python, never parsed from it, /// so we opt out of the (now-opt-in) `FromPyObject` derive. diff --git a/src/status.rs b/src/status.rs index 88b3d0c..1c13ec0 100644 --- a/src/status.rs +++ b/src/status.rs @@ -1,4 +1,4 @@ -//! Pure-Rust roll-up mirroring `StatusService.check_repo`. NO PyO3 here. +//! Pure-Rust roll-up mirroring `check_repo`. NO PyO3 here. //! //! Implement `repo_status(path, fetch) -> RepoStatusData` following the exact //! sequence and SyncState decision tree in docs/PORTING.md / docs/API.md: