Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,36 @@ jobs:

- name: Build and validate distribution
run: task build

leak-guard-new-commits:
name: task leak-guard:history (new commits)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout with full history
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Task
uses: arduino/setup-task@v2
with:
version: 3.x
repo-token: ${{ secrets.GITHUB_TOKEN }}

- name: Install uv with cache
uses: astral-sh/setup-uv@v6
with:
version: "0.10.12"
python-version: "3.13.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
pyproject.toml

# History published before the leak guard existed cannot be cleaned,
# so CI scans only the commits this pull request or push adds.
- name: Scan the commits this pull request or push adds
env:
REVISIONS: ${{ github.event_name == 'pull_request' && format('origin/{0}..HEAD', github.base_ref) || format('{0}..{1}', github.event.before, github.sha) }}
run: task leak-guard:history -- "$REVISIONS"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -219,5 +219,7 @@ __marimo__/

# custom
private/
# Leak guard: maintainers' private patterns, which name the material they guard
/.leak-patterns.private
notebooks/forecast.csv
config.yaml
11 changes: 11 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ repos:
entry: uv run cz check --commit-msg-file
language: system
stages: [commit-msg]
- id: leak-guard-message
name: leak guard (commit message)
entry: uv run python scripts/leak_guard.py message
language: system
stages: [commit-msg]
- id: leak-guard
name: leak guard (working tree)
entry: task leak-guard
language: system
pass_filenames: false
always_run: true
- id: ruff-check
name: ruff check
entry: uv run ruff check .
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"chat.editing.revealNextChangeOnResolve": false,
"python.defaultInterpreterPath": ".venv/bin/python",
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"python-envs.pythonProjects": [
{
"path": ".",
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Agents must ground their thoughts in facts, not assumptions: before planning, claiming, or editing, read the relevant material — source, configs, data, docs, test output — and only act on beliefs backed by something just read or run. Agents must run ad-hoc Python and CLI commands through `task run -- <command>` (which wraps `uv run` with the project's canonical parameters), never bare `python` or hand-written `uv run` invocations — this keeps every invocation from accidentally re-resolving or mutating the `.venv` and `uv.lock`. Agents must explain what each command will do and why it is being run before running it. Before asking the user a question, agents must first explain the corresponding context and terminology — what the question concerns, why it arises, and what any project-specific terms mean — so the user can answer without digging through the code themselves. Agents must run `task pre-commit` and fix all reported issues before reporting success to the user. After `task pre-commit` succeeds, show the diff and explain why each change is necessary before reporting success to the user. Agents must lead a response with its outcome — what now works, what the answer is, and anything the user must decide or act on — within the first few lines, so a reader who stops there misses nothing that changes what they do next; the evidence and the mechanism follow underneath, ordered by what the user cannot reconstruct alone, and what the user can already see is left out: no restatement of the request, no narration of the steps taken or the files visited, no walk through a diff that is shown anyway, and no closing summary that repeats the opening. That focus governs only what is *not* written — it never removes a `module.py:120` citation, a measured number, a side-effect or migration impact, an unrelated defect the agent noticed, or a question the user must answer; when focus and justification collide, the prose goes and the evidence stays. When what an agent reports is a set of items measured or classified along the same few dimensions — files and their status, config keys and their values, metrics before and after, options and their trade-offs — it must be presented as a Markdown table instead of prose or a bullet list, with short cells and only the columns that carry information; prose stays the right form for a single item, a narrative explanation, or an ordered procedure, because a one-row table, or one whose cells are sentences, is harder to read than the paragraph it replaced. Agents must never perform destructive or state-changing git operations unless the user explicitly instructs the agent to run that specific operation — no `git push --force`, no `git reset --hard`, no `git stash` (which hides uncommitted work), no branch/tag deletion, no history rewrites (`rebase`, `commit --amend` on published commits, `filter-branch`), no `git clean -fdx`, no `--no-verify` to bypass hooks, and no discarding of uncommitted work. Read-only inspection commands (`git status`, `git diff`, `git log`, `git show`) are always allowed. If a task seems to require a state-changing git operation and the user has not explicitly asked for it, stop and ask the user to run it. Agents must never mention temporary planning identifiers — phase names or numbers such as "Phase 3g", milestone, sprint, or ticket codes — in docstrings, comments, help or description strings, error messages, or test docstrings; those labels are deleted when the plan is retired and leave readers with a dangling reference nobody can decode, so describe the concept by its lasting behavior or stable configuration key instead (phase names belong only in roadmap and planning docs, and linking to such a doc by its actual filename is fine). Agents must not mention or recommend key rotation (rotating API keys, tokens, or other credentials) — the user takes care of key rotation themselves. Agents must keep comments in configuration files value-independent: a comment attached to a configuration parameter — in `config.yaml`/`config.sample.yaml`, a `Taskfile`, `pyproject.toml`, or any other settings file — may only state what remains true whatever the value is (what the parameter controls, what its options mean, which invariant or trade-off it participates in), and must never restate the current value, derive from it, or do arithmetic on it (`# 64 of 576 rows`, `# 2x the 288-step horizon`, `# keeps 90% of draws at full context`); configuration is retuned constantly, so such a comment turns false the moment somebody edits the value on the line below it and nothing catches the drift, so express a needed derivation as a rule over the parameter or record concrete numbers in a dated notes doc where they read as a historical observation. ripgrep (`rg`) is available (installed by `task setup` via `task install:ripgrep`); prefer it for fast code and text search.
Agents must ground their thoughts in facts, not assumptions: before planning, claiming, or editing, read the relevant material — source, configs, data, docs, test output — and only act on beliefs backed by something just read or run. Agents must run ad-hoc Python and CLI commands through `task run -- <command>` (which wraps `uv run` with the project's canonical parameters), never bare `python` or hand-written `uv run` invocations — this keeps every invocation from accidentally re-resolving or mutating the `.venv` and `uv.lock`. Agents must explain what each command will do and why it is being run before running it. Before asking the user a question, agents must first explain the corresponding context and terminology — what the question concerns, why it arises, and what any project-specific terms mean — so the user can answer without digging through the code themselves. Agents must run `task pre-commit` and fix all reported issues before reporting success to the user. After `task pre-commit` succeeds, show the diff and explain why each change is necessary before reporting success to the user. Agents must lead a response with its outcome — what now works, what the answer is, and anything the user must decide or act on — within the first few lines, so a reader who stops there misses nothing that changes what they do next; the evidence and the mechanism follow underneath, ordered by what the user cannot reconstruct alone, and what the user can already see is left out: no restatement of the request, no narration of the steps taken or the files visited, no walk through a diff that is shown anyway, and no closing summary that repeats the opening. That focus governs only what is *not* written — it never removes a `module.py:120` citation, a measured number, a side-effect or migration impact, an unrelated defect the agent noticed, or a question the user must answer; when focus and justification collide, the prose goes and the evidence stays. When what an agent reports is a set of items measured or classified along the same few dimensions — files and their status, config keys and their values, metrics before and after, options and their trade-offs — it must be presented as a Markdown table instead of prose or a bullet list, with short cells and only the columns that carry information; prose stays the right form for a single item, a narrative explanation, or an ordered procedure, because a one-row table, or one whose cells are sentences, is harder to read than the paragraph it replaced. Agents must never perform destructive or state-changing git operations unless the user explicitly instructs the agent to run that specific operation — no `git push --force`, no `git reset --hard`, no `git stash` (which hides uncommitted work), no branch/tag deletion, no history rewrites (`rebase`, `commit --amend` on published commits, `filter-branch`), no `git clean -fdx`, no `--no-verify` to bypass hooks, and no discarding of uncommitted work. Read-only inspection commands (`git status`, `git diff`, `git log`, `git show`) are always allowed. If a task seems to require a state-changing git operation and the user has not explicitly asked for it, stop and ask the user to run it. Agents must never mention temporary planning identifiers — phase names or numbers, milestone, sprint, or ticket codes — in docstrings, comments, help or description strings, error messages, or test docstrings; those labels are deleted when the plan is retired and leave readers with a dangling reference nobody can decode, so describe the concept by its lasting behavior or stable configuration key instead (phase names belong only in roadmap and planning docs, and linking to such a doc by its actual filename is fine). Agents must not mention or recommend key rotation (rotating API keys, tokens, or other credentials) — the user takes care of key rotation themselves. Agents must keep comments in configuration files value-independent: a comment attached to a configuration parameter — in `config.yaml`/`config.sample.yaml`, a `Taskfile`, `pyproject.toml`, or any other settings file — may only state what remains true whatever the value is (what the parameter controls, what its options mean, which invariant or trade-off it participates in), and must never restate the current value, derive from it, or do arithmetic on it (`# 64 of 576 rows`, `# 2x the 288-step horizon`, `# keeps 90% of draws at full context`); configuration is retuned constantly, so such a comment turns false the moment somebody edits the value on the line below it and nothing catches the drift, so express a needed derivation as a rule over the parameter or record concrete numbers in a dated notes doc where they read as a historical observation. ripgrep (`rg`) is available (installed by `task setup` via `task install:ripgrep`); prefer it for fast code and text search. This repository is public: `task leak-guard` (a pre-commit hook), a `commit-msg` hook, and a CI scan of every commit a pull request or push adds fail on private material, adding a maintainer's git-ignored `.leak-patterns.private` rules when present (see the README's *Leak guard* section); a passing guard does not make a change safe to publish, and agents must never weaken a rule to get a change through but remove the material instead.
Loading
Loading