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: 11 additions & 0 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[profile.ci]
fail-fast = false
# A passing retry must never hide a failure. Repeated runs are recorded separately.
retries = 0
slow-timeout = { period = "60s", terminate-after = 5 }
failure-output = "immediate-final"

[profile.ci.junit]
path = "junit.xml"
store-success-output = false
store-failure-output = false
13 changes: 13 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM rust:1.98.0-bookworm
RUN apt-get update && apt-get install -y --no-install-recommends \
libasound2-dev libssl-dev pkg-config python3 python3-venv ripgrep git ca-certificates \
&& rm -rf /var/lib/apt/lists/*
RUN useradd --create-home --shell /bin/bash cortex \
&& mkdir -p /home/cortex/.cargo /home/cortex/.rustup \
&& cp -a /usr/local/rustup/. /home/cortex/.rustup/ \
&& chown -R cortex:cortex /home/cortex
ENV RUSTUP_HOME=/home/cortex/.rustup \
CARGO_HOME=/home/cortex/.cargo
ENV PATH=/usr/local/cargo/bin:/home/cortex/.cargo/bin:${PATH}
USER cortex
WORKDIR /workspaces/cli
3 changes: 3 additions & 0 deletions .devcontainer/Dockerfile.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**
!.devcontainer/
!.devcontainer/Dockerfile
16 changes: 16 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "Cortex Rust workspace",
"build": {"dockerfile": "Dockerfile", "context": ".."},
"remoteUser": "cortex",
"updateRemoteUserUID": true,
"postCreateCommand": "bash scripts/dev-setup.sh",
"containerEnv": {
"CORTEX_HOME": "/home/cortex/.cortex",
"CARGO_BUILD_JOBS": "4"
},
"customizations": {
"vscode": {
"extensions": ["rust-lang.rust-analyzer", "tamasfe.even-better-toml"]
}
}
}
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Names only. Do not commit real credentials or put them in shell history.
# The local QA runner creates its own isolated environment and server credential.
# CORTEX_HOME=
# CORTEX_DIAGNOSTICS_DIR=
# CORTEX_SERVER_API_KEY=
# CORTEX_JWT_SECRET=
# CORTEX_API_KEY=
# CORTEX_LISTEN_ADDR=127.0.0.1:55554
22 changes: 22 additions & 0 deletions .factory/skills/local-qa/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: local-qa
description: Exercise the Cortex CLI and real loopback app server with isolated data and negative security cases, without contacting the coding service.
---

# Local functional QA

Read `docs/guides/development.md` and `docs/reference/app-server.md`.

Build the affected binaries with the locked graph, then run
`python3 scripts/readiness/qa.py`. This interacts with actual application
processes and local HTTP handlers; it does not fake model responses.

Review `target/readiness/qa/report.json` and the sanitized aggregate insights.
Report each completed flow and any failing assertion. A missing binary or
startup failure is blocked/failed evidence, never success.

For changes to the interactive TUI, this script is insufficient. Use the
existing headless tests and an available terminal interaction skill with a
dedicated approved test account. Do not invent credentials or bypass login.
If interactive or live API QA cannot run, say which flow is blocked and why.
Keep captures local. Do not publish evidence or create issues automatically.
19 changes: 19 additions & 0 deletions .factory/skills/verify-readiness/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: verify-readiness
description: Verify Cortex source policy, dependency drift, generated contracts, and local test evidence before proposing a merge.
---

# Verify readiness

Read `AGENTS.md`, `.rules/testing.md`, `docs/guides/development.md`, and
`docs/guides/quality.md`. Work only in this repository.

1. Inspect the diff and preserve unrelated work.
2. Resolve the real target branch/base commit. Never use HEAD as a regression
baseline just to pass the gate.
3. Run the narrow relevant Rust tests, policy unit tests, source/dependency
checks, schema freshness, and coverage as documented.
4. Retain reports under `target/readiness/`. Report exit statuses, failed tests,
existing debt, and unverified platforms. Do not replace failures with skips.
5. Do not commit, push, change GitHub settings, release, or post reports without
an explicit request. Never attach raw sessions, debug logs, or credentials.
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Verified repository administrator. Additional owners require their agreement.
* @echobt
4 changes: 4 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
- [ ] `cargo test --workspace` (or note the subset and why)
- [ ] TUI / snapshot tests for every surface this PR touches
- [ ] `cargo audit` (or note a documented `.cargo/audit.toml` exception)
- [ ] Source/dependency policy and generated API contracts verified against the real PR base
- [ ] Local functional/security QA and changed-line coverage passed (or explain the blocker)

## Attestation (required)

Expand All @@ -23,3 +25,5 @@ I attest that:
## Risk

<!-- Auth, exec policy, sandbox, release, or API-contract impact. -->

<!-- For a new feature flag: owner, intended lifetime, rollout/removal decision, and production consumer test. -->
15 changes: 15 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: 2
updates:
- package-ecosystem: cargo
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
open-pull-requests-limit: 5
labels: [dependencies, "area:build"]
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
labels: [dependencies, "area:build"]
104 changes: 99 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,41 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
quality:
name: Source and dependency policy
runs-on: ubuntu-latest
timeout-minutes: 15
env:
QUALITY_BASE: ${{ github.event.pull_request.base.sha || github.event.before }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- uses: dtolnay/rust-toolchain@1.98.0
with:
components: rustfmt, clippy
- uses: taiki-e/install-action@v2
with:
tool: cargo-machete@0.9.1
- run: python -m pip install -r scripts/readiness/requirements.txt
- run: python -B -m unittest discover -s scripts/readiness -p 'test_*.py'
- run: python scripts/readiness/quality.py --base "$QUALITY_BASE"
- run: cargo machete --with-metadata
- run: python scripts/readiness/release_age.py --base "$QUALITY_BASE"
- uses: actions/upload-artifact@v4
if: always()
with:
name: source-quality
path: target/readiness/quality.json
retention-days: 14

version-check:
name: CLI Version Check
runs-on: ubuntu-latest
Expand Down Expand Up @@ -67,13 +101,71 @@ jobs:
- name: Install Linux dependencies
run: |
sudo apt-get update
sudo apt-get install -y libasound2-dev libssl-dev pkg-config
sudo apt-get install -y libasound2-dev libssl-dev pkg-config git ripgrep
- uses: dtolnay/rust-toolchain@1.98.0
- uses: Swatinem/rust-cache@v2
with:
prefix-key: rust-test
- uses: taiki-e/install-action@v2
with:
tool: cargo-nextest@0.9.102
- name: Run tests
run: cargo test --workspace
run: python3 scripts/readiness/tests.py
- name: Run documentation tests
run: cargo test --locked --workspace --doc
- name: Verify generated API contracts
run: python3 scripts/readiness/schema.py
- name: Build local QA applications
run: cargo build --locked -p cortex-cli -p cortex-app-server
- name: Local functional QA and dynamic security tests
run: python3 scripts/readiness/qa.py
- uses: actions/upload-artifact@v4
if: always()
with:
name: test-performance
path: target/readiness/tests/
retention-days: 30
- uses: actions/upload-artifact@v4
if: always()
with:
name: local-qa
# Diagnostic journals and aggregates remain local to the runner.
path: target/readiness/qa/report.json
retention-days: 14

coverage:
name: Changed-line coverage
runs-on: ubuntu-latest
timeout-minutes: 30
env:
QUALITY_BASE: ${{ github.event.pull_request.base.sha || github.event.before }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: sudo apt-get update && sudo apt-get install -y libasound2-dev libssl-dev pkg-config git ripgrep
- uses: dtolnay/rust-toolchain@1.98.0
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@v2
with:
prefix-key: rust-coverage
- uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov@0.6.21,cargo-nextest@0.9.102
- name: Collect application coverage
run: |
mkdir -p target/readiness
cargo llvm-cov nextest --locked -p cortex-cli -p cortex-app-server -p cortex-common --profile ci --lcov --output-path target/readiness/lcov.info
- run: python3 scripts/readiness/coverage.py --base "$QUALITY_BASE"
- uses: actions/upload-artifact@v4
if: always()
with:
name: coverage
path: |
target/readiness/lcov.info
target/readiness/coverage.json
retention-days: 14

tui:
name: TUI checks
Expand Down Expand Up @@ -107,14 +199,14 @@ jobs:
- uses: dtolnay/rust-toolchain@1.98.0
- uses: taiki-e/install-action@v2
with:
tool: cargo-audit
tool: cargo-audit@0.22.2
- name: Audit Rust dependencies
run: cargo audit

ci-success:
name: CI Success
runs-on: ubuntu-latest
needs: [version-check, fmt, clippy, test, tui, audit]
needs: [version-check, fmt, clippy, test, tui, audit, quality, coverage]
if: always()
steps:
- name: Check all jobs
Expand All @@ -124,7 +216,9 @@ jobs:
"${{ needs.clippy.result }}" != "success" || \
"${{ needs.test.result }}" != "success" || \
"${{ needs.tui.result }}" != "success" || \
"${{ needs.audit.result }}" != "success" ]]; then
"${{ needs.audit.result }}" != "success" || \
"${{ needs.quality.result }}" != "success" || \
"${{ needs.coverage.result }}" != "success" ]]; then
echo "One or more required CI jobs failed"
exit 1
fi
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/test-stability.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Test stability
on:
schedule:
- cron: '30 5 * * 1'
workflow_dispatch:
permissions:
contents: read
jobs:
repeat:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- run: sudo apt-get update && sudo apt-get install -y libasound2-dev libssl-dev pkg-config git ripgrep
- uses: dtolnay/rust-toolchain@1.98.0
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@v2
with:
tool: cargo-nextest@0.9.102
- run: python3 scripts/readiness/tests.py --repeat 3
- uses: actions/upload-artifact@v4
if: always()
with:
name: test-stability
path: target/readiness/tests/
retention-days: 30
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ Thumbs.db
.cargo-home/
.sccache/
.rustup/
__pycache__/
*.py[cod]
66 changes: 66 additions & 0 deletions .quality/dependency-compatibility.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"src/cortex-agents/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
},
"src/cortex-app-server/Cargo.toml:dependencies:dirs": {
"declaration": "5",
"reason": "Retains dirs 5 platform path behavior until its consumers are migrated and platform-tested."
},
"src/cortex-batch/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
},
"src/cortex-compact/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
},
"src/cortex-engine/Cargo.toml:dependencies:rand": {
"declaration": "0.8",
"reason": "Retains rand 0.8 Rng/generation APIs; upgrade requires a separate compatibility change."
},
"src/cortex-ghost/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
},
"src/cortex-hooks/Cargo.toml:dependencies:dirs": {
"declaration": "5.0",
"reason": "Retains dirs 5 platform path behavior until its consumers are migrated and platform-tested."
},
"src/cortex-hooks/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
},
"src/cortex-linux-sandbox/Cargo.toml:target.cfg(target_os = \"linux\").dependencies:seccompiler": {
"declaration": "0.4",
"reason": "Retains seccompiler 0.4 sandbox filter API; changing sandbox policy needs a dedicated compatibility review."
},
"src/cortex-resume/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
},
"src/cortex-review/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
},
"src/cortex-share/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
},
"src/cortex-snapshot/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
},
"src/cortex-storage/Cargo.toml:dependencies:dirs": {
"declaration": "5",
"reason": "Retains dirs 5 platform path behavior until its consumers are migrated and platform-tested."
},
"src/cortex-storage/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
},
"src/cortex-windows-sandbox/Cargo.toml:dependencies:thiserror": {
"declaration": "1",
"reason": "Retains the existing thiserror 1 derive API until its consumers are migrated together."
}
}
9 changes: 9 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ Match CI (`.github/workflows/ci.yml`):
- TUI job for the framework + app surfaces
- `./scripts/check-cli-version.sh`
- PR attestation checklist in `.github/PULL_REQUEST_TEMPLATE.md`
- Source/dependency policy, API-contract freshness, local QA, and changed-line
coverage in CI. Use the actual PR base SHA, never a self-baseline.

Local setup and the exact reporting/coverage commands:
[`docs/guides/development.md`](docs/guides/development.md).
Policy and existing-debt handling:
[`docs/guides/quality.md`](docs/guides/quality.md).
Diagnostics stay local, opt-in, and content-free:
[`docs/guides/operations.md`](docs/guides/operations.md).

## Where to read what

Expand Down
Loading
Loading