diff --git a/.github/workflows/lsc.yml b/.github/workflows/lsc.yml new file mode 100644 index 0000000..d41b106 --- /dev/null +++ b/.github/workflows/lsc.yml @@ -0,0 +1,75 @@ +# LeanSpec PR check (estate standard; Linear EST-1169, parent CER-2890). +# +# Runs on the internal estate fleet, never on a GitHub-hosted runner. This repository is public, +# so the job runs only for pull requests from branches of this repository: code from a fork never +# runs on an internal runner. The spec-link step is WARNING ONLY and always exits 0. It becomes a +# required check only after the Linear backfill, on a separate operator go. +name: lsc + +on: + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + lsc: + name: lsc + if: github.event.pull_request.head.repo.full_name == github.repository + runs-on: {group: ent-default, labels: [ci-rust]} + timeout-minutes: 10 + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + - name: spec-check (structural) + run: | + test -f .lean-spec || { echo "::error::.lean-spec is missing"; exit 1; } + n=0 + for f in specs/SPEC-[0-9][0-9][0-9][0-9]-*.md; do + [ -e "$f" ] || continue + n=$((n + 1)) + if [ "$(head -n 1 "$f")" != "---" ] || ! grep -q '^status:' "$f"; then + echo "::error file=$f::spec has no front matter or no status" + exit 1 + fi + done + [ "$n" -gt 0 ] || { echo "::error::no specs/SPEC-NNNN-*.md found"; exit 1; } + echo "spec-check: ok ($n specs validated; .lean-spec present)" + # Stub: installs nothing. The estate `lsc` binary is not installed on runners yet. + # The vilicus pinned lsc and its reusable job will replace this step. + - name: lsc check specs/ (stub) + run: | + if command -v lsc >/dev/null 2>&1; then + lsc check specs/ + else + echo "::notice::lsc is not installed yet; the vilicus pinned lsc and reusable job will replace this stub." + fi + - name: spec-link (warning only) + env: + PR_TITLE: ${{ github.event.pull_request.title }} + PR_BODY: ${{ github.event.pull_request.body }} + BASE_REF: ${{ github.event.pull_request.base.ref }} + run: | + # Title, body and base ref arrive only through env: above, never interpolated here. + # Here-strings, not pipes: under pipefail a pipe into grep -q can fail on SIGPIPE. + if ! grep -Eq '^(feat|fix)(\([^)]*\))?!?:' <<<"$PR_TITLE"; then + echo "not a feat or fix title; spec-link check skipped" + exit 0 + fi + changed=$(git diff --name-only "origin/$BASE_REF...HEAD") + touched=0 + if grep -Eq '^(specs/|\.lean-spec$)' <<<"$changed"; then + touched=1 + fi + named=0 + if grep -Eiq 'spec[ -][0-9]{4}|specs/(00|spec-)|REQ-[0-9]{4}|LeanSpec spec' <<<"$PR_TITLE"$'\n'"$PR_BODY"; then + named=1 + fi + if [ "$touched" = 0 ] && [ "$named" = 0 ]; then + echo "::warning::spec-link: a feat or fix PR must touch a spec under specs/ (or .lean-spec) or name one (SPEC-NNNN or a REQ id) in its title or body. Warning only until the Linear backfill is done." + else + echo "spec-link ok (touched=$touched named=$named)" + fi + exit 0 diff --git a/.lean-spec b/.lean-spec new file mode 100644 index 0000000..79f7864 --- /dev/null +++ b/.lean-spec @@ -0,0 +1 @@ +methodology: LeanSpec (spec-driven development); registry of record in specs/ (see specs/README.md) diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e109fd8 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,11 @@ +# AGENTS.md — dgr + +Agent-facing repo brief. Read this before editing. + +## Rules that bind + +- **Specs first (LeanSpec).** A feat or fix creates or updates a LeanSpec spec under `specs/` + before code, and the PR names that spec (for example `SPEC-0001` or `REQ-0001-02`). The + registry, lifecycle and EARS conventions are in `specs/README.md`. +- **Gates:** `cargo test --release --locked`, as CI runs it. Commits are signed. Changes land + through PRs into `main`; no direct pushes. diff --git a/docs/leanspec-history-triage.md b/docs/leanspec-history-triage.md new file mode 100644 index 0000000..e45f28e --- /dev/null +++ b/docs/leanspec-history-triage.md @@ -0,0 +1,16 @@ +# LeanSpec history triage (2026-10-18) + +This applies the estate standard's "check previous commits" step (Linear EST-1169, parent CER-2890). It covers the whole first-parent history of `main` at `5fb4a38`, which is 6 commits, three of them merged PRs. + +| Commit or PR | Title | Disposition | Reason | +|---|---|---|---| +| `b0f33db` (direct push) | feat(dgr): extract dagr runtime and flow representation kernel as dgr 0.4.0 | Retro-linked to SPEC-0001 | SPEC-0001 Horizon 1, "Mathematical Representation Kernel (Delivered — v0.4.0)", and REQ-0001-01 to 08 specify the kernel this commit delivered. | +| `dbcaf28` (direct push) | refactor(dgr): decouple from herdr and dagr into standalone mathematical DAG engine | Retro-linked to SPEC-0001 | SPEC-0001 describes the standalone engine that results from this decoupling. | +| PR 1 (`5dec57c`) | docs: add license badge and principles link per conformity directive | Exempt | Documentation only. | +| PR 3 (`524fdcf`) | chore(package): exclude dev workflows and scripts from crates.io tarball | Exempt | Packaging metadata only; no behaviour change. | +| PR 4 (`50eac9e`) | docs(specs): add LeanSpec SPEC-0001 initial architecture and roadmap | Linked | It adds SPEC-0001 itself. | +| `5fb4a38` (direct push) | docs(dgr): codify workflow execution as compiled microcode on silicon | Exempt | Documentation only. | + +**Counts:** 1 linked, 2 retro-linked, 3 exempt, 0 needing a new retro spec. + +**Note:** three of these commits reached `main` as direct pushes, not PRs. The branch rules on `main` block force-push and deletion, but they do not require a PR.