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
61 changes: 61 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## Summary

<!-- Explain the problem solved and the resulting behavior. -->

-

## Related issues

<!-- Use "Closes #..." only when every acceptance criterion is satisfied. -->

- Closes/Refs #

## Scope

### Included

-

### Explicitly out of scope

-

## Contract impact

- Public or versioned contract changed: No
- Compatibility or migration impact: None

## Verification

| Check | Command | Result |
|---|---|---|
| Locked environment | `uv sync --frozen` | |
| Formatting | `uv run --frozen ruff format --check .` | |
| Linting | `uv run --frozen ruff check .` | |
| Type checking | `uv run --frozen mypy src` | |
| Tests | `uv run --frozen pytest` | |
| Documentation links | `uv run --frozen python scripts/check_markdown_links.py` | |
| Package build | `uv build` | |
| Installed-wheel smoke test | Describe the command | |

## Security and data handling

- [ ] No credential, private log, personal data, or generated secret was committed.
- [ ] Untrusted input is not executed or interpolated into shell commands.
- [ ] Workflow permissions follow least privilege.
- [ ] Third-party actions are pinned to immutable commit SHAs.
- [ ] Errors and logs do not expose sensitive values.
- [ ] Security checks are not applicable; the reason is documented below.

Security notes:

-

## Risks and rollback

- Risk:
- Rollback:

## Reviewer focus

-
142 changes: 142 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: CI

on:
pull_request:
branches:
- main
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
UV_VERSION: "0.11.16"

jobs:
quality:
name: Quality
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Install uv and Python
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
version: ${{ env.UV_VERSION }}
python-version: "3.11"
enable-cache: true
cache-dependency-glob: uv.lock

- name: Synchronize locked environment
run: uv sync --frozen

- name: Check formatting
run: uv run --frozen ruff format --check .

- name: Run lint checks
run: uv run --frozen ruff check .

- name: Run static type checks
run: uv run --frozen mypy src

- name: Validate local Markdown links
run: uv run --frozen python scripts/check_markdown_links.py

tests:
name: Tests / Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
timeout-minutes: 10

strategy:
fail-fast: false
matrix:
python-version:
- "3.11"
- "3.14"

steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Install uv and Python
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
version: ${{ env.UV_VERSION }}
python-version: ${{ matrix.python-version }}
enable-cache: true
cache-dependency-glob: uv.lock

- name: Synchronize locked environment
run: uv sync --frozen

- name: Run tests
run: uv run --frozen pytest

package:
name: Package
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Install uv and Python
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
version: ${{ env.UV_VERSION }}
python-version: "3.11"
enable-cache: true
cache-dependency-glob: uv.lock

- name: Build wheel and source distribution
run: uv build --no-sources

- name: Verify distribution artifacts
shell: bash
run: |
set -euo pipefail
python - <<'PY'
from pathlib import Path

wheels = sorted(Path("dist").glob("*.whl"))
sdists = sorted(Path("dist").glob("*.tar.gz"))
if len(wheels) != 1 or len(sdists) != 1:
raise SystemExit(
f"Expected one wheel and one sdist, found {wheels=} and {sdists=}"
)
print(f"Wheel: {wheels[0]}")
print(f"Source distribution: {sdists[0]}")
PY

- name: Smoke-test installed wheel outside repository
shell: bash
run: |
set -euo pipefail

wheel="$(find dist -maxdepth 1 -type f -name '*.whl' -print -quit)"
uv venv .venv-smoke --python "3.11"
uv pip install --python .venv-smoke/bin/python "$wheel"

temporary_directory="$(mktemp -d)"
trap 'rm -rf "$temporary_directory"' EXIT
cd "$temporary_directory"

"$GITHUB_WORKSPACE/.venv-smoke/bin/runsift" --help
"$GITHUB_WORKSPACE/.venv-smoke/bin/runsift" --version
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.venv/
build/
dist/
*.egg-info/

__pycache__/
*.py[cod]
.pytest_cache/
.mypy_cache/
.ruff_cache/

.coverage
coverage.xml
htmlcov/

.DS_Store
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.11
30 changes: 30 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Contributing

RunSift is in an early, contract-driven development stage. Keep changes narrow, evidence-backed, and aligned with an existing issue.

## Requirements

- Python 3.11 or newer
- [uv](https://docs.astral.sh/uv/)
- Git

## Setup

```bash
uv sync --frozen
```

## Local quality gate

Run the same checks used by CI:

```bash
uv run --frozen ruff format --check .
uv run --frozen ruff check .
uv run --frozen mypy src
uv run --frozen pytest
uv run --frozen python scripts/check_markdown_links.py
uv build
```

Do not mark a check as passing unless that command was executed. Changes that alter a public or versioned contract must update the relevant document under `docs/` and include focused tests.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Dyu20705

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,24 @@ Blind reruns waste time and can hide genuine regressions. Manual triage also fai

## Current status

RunSift is in **foundation and contract design**. No working triage capability or measured product result is claimed yet.
RunSift is in **foundation implementation**. The repository now contains an installable typed Python package, a minimal CLI entry point, locked development tooling, tests, package smoke checks, and progressive CI quality gates.

The next implementation target is a local CLI with deterministic rules, safe redaction, stable output contracts, offline fixtures, and optional read-only GitHub API collection.
Only `runsift --help` and `runsift --version` are implemented. Failure collection, parsing, classification, and reporting remain contracted or planned; no working triage capability or measured product result is claimed yet.

## Development

```bash
uv sync --frozen
uv run --frozen runsift --help
uv run --frozen ruff format --check .
uv run --frozen ruff check .
uv run --frozen mypy src
uv run --frozen pytest
uv run --frozen python scripts/check_markdown_links.py
uv build
```

Python 3.11 is the default development interpreter. CI also verifies the package on Python 3.14.

## MVP workflow

Expand Down Expand Up @@ -69,7 +84,7 @@ runsift collect --repo owner/name --run-id 123456789
runsift analyze --input .runsift/runs/123456789 --format json
```

The command names are a maintained contract for implementation, not evidence that the CLI already exists. See the [CLI MVP contract](docs/cli-contract.md).
These command names are maintained implementation contracts, not evidence that the commands already exist. See the [CLI MVP contract](docs/cli-contract.md).

## Safety principles

Expand Down
Loading