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
11 changes: 4 additions & 7 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: Repository Checks

# Manual only for now. The gate is green on a maintainer workstation but red on a
# Full qualification remains manual. Core Python CI runs its named subset on PRs.
# This broader gate is green on a maintainer workstation but red on a
# GitHub-hosted runner, and the differences are environmental rather than code:
# ubuntu-latest carries Podman 4.9, whose Quadlet generator rejects the `Pod=`
# key that Podman 5 accepts, and the file-publication and workspace-restore
# receipts classify a restored path differently there than on the developer's
# filesystem. Restore the push and pull_request triggers once those are settled;
# leaving them on now only teaches everyone to ignore a red mark.
# filesystem. Resolve those prerequisites before expanding automatic coverage.
on:
workflow_dispatch:

Expand Down Expand Up @@ -124,10 +124,7 @@ jobs:

documentation:
name: Hexanomicon build
# Main already performs this clean build while producing the Pages artifact.
# Keep the independent check here for pull requests without rebuilding twice
# after the same revision lands.
if: github.event_name == 'pull_request'
# Include documentation in manual qualification; Pages builds main separately.
runs-on: ubuntu-latest
timeout-minutes: 15
env:
Expand Down
44 changes: 44 additions & 0 deletions .github/workflows/core-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Core Python CI

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

concurrency:
group: core-python-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
core:
name: Core Python checks (no host or containers)
runs-on: ubuntu-24.04
timeout-minutes: 20
env:
UV_LOCKED: "1"
UV_CACHE_DIR: .cache/uv
PYTEST_BASETEMP: .cache/pytest/core-${{ github.run_id }}-${{ github.run_attempt }}
steps:
- name: Check out source
uses: actions/checkout@v7
with:
persist-credentials: false

- name: Install Python and uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
version: "0.12.10"
python-version: "3.13"
enable-cache: true
cache-suffix: core-python

- name: Check lint, formatting and types
run: make lint format-check type-check

- name: Test core contracts
run: make test-ci
24 changes: 19 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,25 @@ pytest's native compact report, capture logs, and allocate a unique scratch dire
`.cache/pytest`; set `PYTEST_BASETEMP` to an explicit current-user-owned path only when a caller
must own that location.

Pull requests run four independent repository checks: the Python umbrella, the disposable
PostgreSQL receipts, the Altar check/build plus generated-diff guard, and a clean documentation
build. Pushes to `main` repeat the first three while the deployment workflow's clean documentation
build supplies the fourth gate and its Pages artifact. The tag/manual release-candidate workflow
remains a separate non-publishing artifact receipt.
Pull requests and pushes to `main` run **Core Python CI**: repository lint, formatting and strict
typing, followed by `make test-ci`. This explicit selection covers configuration, database model
contracts, animation/dispatch/orchestration, core Run logic, extensions, agents and web contracts,
plus the configuration workflow tests. It uses in-process substitutes, requires no container
daemon, running database, systemd service, model or GPU, and does not prove host operation.
`CI_PYTEST_TARGETS` in the Makefile owns the exact selection. Reproduce it locally with:

```bash
make lint format-check type-check
make test-ci
```

The **Repository Checks** workflow remains manually dispatched: full `make check`, disposable
PostgreSQL, Altar check/build with the generated-diff guard, and a clean documentation build.
Host-dependent Quadlet/filesystem differences on GitHub runners remain unresolved; a core-CI
pass does not waive these broader checks for a change that needs them. The Pages workflow builds
documentation on `main`; the tag/manual release-candidate workflow remains a separate
non-publishing artifact receipt. `make test` and `make check` retain their full non-container
selection; `make test-ci` does not replace them for final verification.

Disposable PostgreSQL receipts are an explicit host-integration profile, not part of ordinary
`make check`:
Expand Down
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ MAKEFLAGS += --no-print-directory
N ?= 0
VERBOSE ?= 0
PYTEST_TARGETS ?= tests
# Automatic CI covers these in-process contracts; host/filesystem qualification
# and disposable PostgreSQL remain separate. Keep the full test/check defaults.
CI_PYTEST_TARGETS := tests/unit/config tests/unit/db \
tests/unit/domain/animation tests/unit/domain/cortex \
tests/unit/domain/orchestration tests/unit/domain/web \
tests/unit/extensions tests/unit/lib tests/agents tests/web \
tests/integration/test_configuration_workflows.py
CONTAINER_TEST_TARGETS ?= tests/integration/test_db_consent_pg.py \
tests/integration/test_database_authority_pg.py \
tests/integration/test_db_atlas_pg.py \
Expand Down Expand Up @@ -55,14 +62,14 @@ ifeq ($(RTK_ACTIVE),1)
RUN := $(UV_DEV_RUN) $(RTK) run
ERR := $(UV_DEV_RUN) $(RTK) err
RUFF := $(UV_DEV_RUN) $(RTK) ruff
TYPECHECK := $(UV_DEV_RUN) --group typing $(RTK) err basedpyright
TYPECHECK := $(UV_DEV_RUN) --group typing --group container-test $(RTK) err basedpyright
CURL := $(RTK) curl
GREP := $(RTK) grep
else
RUN :=
ERR :=
RUFF := $(UV_DEV_RUN) ruff
TYPECHECK := $(UV_DEV_RUN) --group typing basedpyright
TYPECHECK := $(UV_DEV_RUN) --group typing --group container-test basedpyright
CURL := curl
GREP := grep
endif
Expand Down Expand Up @@ -240,6 +247,10 @@ test-containers: ## Run explicit disposable-PostgreSQL receipts; requires a Dock
fi
@$(UV_DEV_RUN) --group container-test pytest $(CONTAINER_PYTEST_ARGS) --basetemp "$$basetemp" $(CONTAINER_TEST_TARGETS)

.PHONY: test-ci
test-ci: ## Run the core CI selection without real host services, models or containers
@$(MAKE) test PYTEST_TARGETS="$(CI_PYTEST_TARGETS)" M="not container" N=0

.PHONY: test-config
test-config: ## Run configurable/runes focused tests only
@$(MAKE) test PYTEST_TARGETS="tests/unit/config/runes tests/unit/system/services/test_codex.py"
Expand Down
11 changes: 7 additions & 4 deletions docs/adr/03-quality.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ The Python umbrella does not silently run frontend work. Both frontend gates reg
contract; the build also changes the tracked static projection, which belongs in review with the
source that produced it. A generated diff guard catches disagreement.

Pull requests expose all four lanes independently. A push to `main` repeats the first three;
the Pages workflow supplies the clean documentation gate and deployment artifact in one build.
The tag/manual release-candidate workflow remains separate: a green source change does not bind
release archives or prove installation on a host.
Automatic pull-request and `main` checks run repository lint, formatting, strict typing and the
explicit core test selection owned by `make test-ci`. That selection uses in-process substitutes
and excludes real host and container qualification. The full four-lane Repository Checks workflow
remains manual while host-runner compatibility is unresolved; changes still require the broader
gates appropriate to their boundary. The Pages workflow separately supplies the clean documentation
gate and deployment artifact on `main`. The tag/manual release-candidate workflow remains separate:
a green core check does not bind release archives or prove installation on a host.

[Frontend](15-frontend.md#decision-lock-and-reopening-gate) owns the exact Node/npm pins and
single client vocabulary. Bun, a second lock/runtime, Tailwind, or another styling compiler must
Expand Down
7 changes: 5 additions & 2 deletions docs/adr/04-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,11 @@ structural exclusions. `make coverage` enforces it serially with the ordinary `n
selection. Default tests, the Python umbrella, pull-request checks, and release-candidate CI do
not pass `--cov`. Coverage is an opt-in gate, not an implicitly passed release condition.

Pull-request and `main` workflows run ordinary tests and disposable PostgreSQL receipts in
separate jobs. Their results remain separate even when both are green.
Pull-request and `main` Core Python CI runs the explicit `make test-ci` selection, using
in-process substitutes without a real host, model or container daemon. Full ordinary tests and
disposable PostgreSQL receipts remain separate jobs in the manually dispatched Repository Checks
workflow. A core-CI pass does not establish those broader results or waive affected-boundary
verification. The normal `make test` and `make check` selections remain unchanged.

### 5. Runtime Surface Probes

Expand Down