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
26 changes: 25 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.2.0] - 2026-06-30

### Fixed
- **Soundness — preview-maturity rules now gate (and baseline) exactly like stable
rules** (wardline-4ada23bb09). The `--fail-on` gate predicate silently excluded
`maturity: preview` findings, so six ERROR-severity rules — `PY-WL-118` (SQL
injection), `PY-WL-119` (no-op/degenerate trust boundary), `PY-WL-120` (stored
taint reaches trusted state), `PY-WL-121` (XXE), `PY-WL-122` (SSTI), and
`PY-WL-124` (native-library load) — fired as active ERROR defects but
`wardline scan --fail-on ERROR` passed **green** on them (`would_trip_at: null`).
`maturity` is now purely informational ("predicates may still sharpen"), matching
the long-standing documented contract that preview rules "participate in the gate,
baseline, waivers, and judge exactly like stable rules". Preview findings are also
now baselineable, so a preview false-positive has the usual escape hatch.
**Behavior change:** a repository that scans clean today but contains one of these
flows will now correctly **fail** `--fail-on`. Fix the boundary/sink, or reach for
an escape hatch — but mind the secure default: the gate evaluates the *unsuppressed*
population, so a committed baseline/waiver clears it only under `--trust-suppressions`
(a trusted local checkout). In **CI**, scope with `--new-since <merge-base>`; a
baselined or waived finding alone will not turn the build green. This applies at
every threshold, not just ERROR: the WARN-severity preview rules
(`PY-WL-116`/`117`/`123`/`126`) now gate under `--fail-on WARN`, and `PY-WL-125`
(INFO) under `--fail-on INFO` — a CI pinned below ERROR is affected too.

## [1.1.0] - 2026-06-29

### Changed
- **BREAKING (unreleased contract):** attest bundle schema bumped `wardline-attest-1` → `wardline-attest-2`; each boundary now carries `content_hash` (entity-body span blake3 binding key, null when unresolved). `wardline-attest-1` bundles no longer verify.
- **BREAKING:** attest bundle schema bumped `wardline-attest-1` → `wardline-attest-2`; each boundary now carries `content_hash` (entity-body span blake3 binding key, null when unresolved). `wardline-attest-1` bundles no longer verify.
- Default scan artifacts now anchor to the weft-project root (the `weft.toml` directory)
rather than the scan cwd, so a subdirectory scan writes to `<project-root>/.wardline/`.
Retention is therefore project-root-wide across heterogeneous subdir/root scans sharing
Expand Down
24 changes: 24 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

Migration notes for changes that can alter a previously-green run. Newest first.

## To the next release (recommended v1.2) — preview rules now gate (soundness)

`wardline-4ada23bb09`. The `--fail-on` gate previously **ignored** any rule whose
`maturity` is `preview`, so a scan could pass green while an active ERROR defect
was present. `maturity` is now purely informational; **preview rules gate (and
are baselineable) exactly like stable rules**, matching the documented contract.

**Who is affected.** A repository that scans green today but contains one of the
previously-non-gating preview findings will now correctly **fail**. At
`--fail-on ERROR`: `PY-WL-118` (SQL injection), `PY-WL-119` (no-op/degenerate
trust boundary), `PY-WL-120` (stored taint → trusted), `PY-WL-121` (XXE),
`PY-WL-122` (SSTI), `PY-WL-124` (native-library load). At lower thresholds also
`PY-WL-116`/`117`/`123`/`126` (WARN) and `PY-WL-125` (INFO).

**What to do.** This is a real finding, not noise — fix it at the boundary/sink.
If you must defer, mind the secure default: the gate evaluates the *unsuppressed*
population, so a committed baseline or waiver clears it **only** under
`--trust-suppressions` (a trusted local checkout), not in a default CI run. In
**CI**, scope the gate with `--new-since <merge-base>` so it fires only on changed
code; a baselined/waived finding alone will not turn the build green. (`wardline
baseline` / the `waiver_add` MCP tool still record the suppression for the
trusted-checkout and `--new-since` paths.) There is no config flag to restore the
old "preview never gates" behavior.

## To v1.0 — Weft config/store consolidation (BREAKING)

Wardline's operator config and machine state moved onto the Weft federation
Expand Down
39 changes: 25 additions & 14 deletions docs/product/current-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
`roadmap.md` → Now) — **UNCHANGED**. The open frontier remains the **seam-health probe** —
PRD-0002 criteria 1 + 2 (Layer-1 `doctor --seams` self-check with a mandatory
machine-readable `reason`; Layer-2 consumer round-trip that never trusts a self-reported
status field). *This session did NOT advance the seam bet* — it was an **owner-directed
examination** of the parked Q4 strategic question (now resolved, below). The seam probe is
still the highest-blast-radius core unbuilt.
status field). *The last two sessions did NOT advance the seam bet* — the Q4 examination
(resolved, below) and this session's reactive **install-friction fix** (PDR-0010) were both
detours. The seam probe is still the highest-blast-radius core unbuilt.

- *Metric it moves:* **G2-seam** (`metrics.md`): `BASELINE (2026-06-15): 3 of 6 surfaces
lie or can't self-report → TARGET: 0 of 6 by 2026-07-31`. crit-3 closed the
Expand Down Expand Up @@ -52,10 +52,13 @@ No vision change (anti-goal unchanged); the instrumentation was within grant.
## Open questions / blocked-on-owner

1. **PR #69 merge + release (owner gate) — SCOPE GREW AGAIN.** PR #69
(`release/consolidation-2026-06-26` → main, HEAD now `53a1424d`) carries the prior detour
(Part A + pack-bridge + layering `cfe546ed`) **plus** the concurrent session's Part B
(`release/consolidation-2026-06-26` → main, HEAD now `8c950e02`) carries the prior detour
(Part A + pack-bridge + layering `cfe546ed`), the concurrent session's Part B
(`652d3bf3`), Part C (`b5170e22`), de-elspeth refactor (`9886280c`), glossary re-sync
(`53a1424d`). Merging to main / any PyPI release are outward-facing — your call.
(`53a1424d`), the **v1.1.0 release prep** (`adb42a0e` version bump + CHANGELOG, `35401454`),
**plus this session's install-friction fix** (`87f13b0d`/`8c950e02`, PDR-0010). The
install fix is **unpublished** — it reaches users only via the owner-gated release.
Merging to main / any PyPI publish are outward-facing — your call.
2. **Install the pack in elspeth + relay corrected guidance (cross-repo / owner).** "blake3 will
NOT fix the gate; install the pack." Pack-bridge + Part C both shipped generically wardline-side.
3. **3.12 fingerprint release note (owner).** Carry-over from PDR-0006 — one-line note on release.
Expand All @@ -68,12 +71,19 @@ No vision change (anti-goal unchanged); the instrumentation was within grant.

## What this checkpoint did

- **PDR-0009** — Q4 owner decision A+C (hold vision, instrument); metric-bound non-self-sealing
reversal trigger (≥ 5; baseline = 1).
- **metrics.md** — dated G3 reading (inert-gate prevalence; no trigger crossed).
- **roadmap.md** — added option B to Later as PARKED+gated; Now unchanged.
- **Reconciled drift** — Part B/C were stale-as-"open" in the prior brief; now recorded DONE+
committed; `bd9d1e65cb` recorded CLOSED. Grant re-confirmed 2026-06-29 (date-only).
- **PDR-0010** — install-friction fix: scan-pipeline extras self-include scanner (the
`loomweave` whack-a-mole under `uv tool install`) + a shared install-hint helper naming
both installers + a regression guard. Commits `87f13b0d`/`8c950e02` (pushed); also
installed the fixed build into the local uv tool (single `[loomweave]` install now keeps
scanner — verified).
- **metrics.md** — dated G4 reading (per-release extras re-check; base stays 0-dep; no
trigger crossed).
- **Tracker** — filed + closed `wardline-c8d7e020e8` (the dogfood install defect).
- **Cross-repo (not wardline's to own):** this session was primarily the plainweave↔warpline
requirements-enrichment federation gate + an exit-code investigation; those product records
live in the sibling workspaces (plainweave PDR-017, warpline PDR-0008), not here.
- The **Now bet was not advanced** (reactive install-fix detour). `roadmap.md` untouched;
grant unchanged (re-confirmed 2026-06-29 by the prior session).

## Where the next session starts

Expand All @@ -86,5 +96,6 @@ No vision change (anti-goal unchanged); the instrumentation was within grant.

Decisions: `0001` bootstrap, `0002` Now rotation, `0003` doctor seam, `0004` ACCEPT PRD-0001,
`0005` ACCEPT crit-3 + source-drift CI, `0006` fingerprint determinism, `0007` inert-gate
visibility, `0008` elspeth pack-bridge, `0009` Q4 hold-vision+instrument. Tactical truth is the
tracker; intent lives here and in `roadmap.md`.
visibility, `0008` elspeth pack-bridge, `0009` Q4 hold-vision+instrument, `0010` extras
self-include scanner (install-friction fix). Tactical truth is the tracker; intent lives here
and in `roadmap.md`.
64 changes: 64 additions & 0 deletions docs/product/decisions/0010-extras-self-include-scanner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# PDR-0010: Scan-pipeline extras self-include scanner (fix uv-tool install-friction)

Date: 2026-06-29
Status: accepted
Author: agent:claude (engineering session; recorded at /product-checkpoint)
Owner sign-off: autonomous within grant — a repo-local, reversible defect fix on the
install surface (the grant authorizes accept/dispatch of reversible repo-local work).
Committed + pushed on `release/consolidation-2026-06-26` (PR #69). Reaching users via a
**PyPI publish is owner-gated** and is NOT performed here.
Related: `vision.md` thesis invariant #1 (plug-and-play install); G4 (extras/weight
discipline) + G3 (zero-config activation) in `metrics.md`; tracker `wardline-c8d7e020e8`
(filed + closed this session); PDR-0007/0008 (the elspeth dogfood that surfaced
install-surface friction).

## Context

A dogfood report from `~/elspeth` (installed wardline 1.0.7, uv-tool install) hit an
install whack-a-mole: `uv tool install wardline[loomweave]` *uninstalled* the scanner deps
(pyyaml/jsonschema/click) and installed only blake3, so `wardline init`/`scan` then errored
"requires the scanner extra"; reinstalling scanner dropped blake3 again. Root cause: `uv
tool install` REPLACES the tool env with exactly the named extras (it does not merge), and
`loomweave = ["blake3>=1.0"]` was not self-sufficient — unlike the `rust` extra, which
already self-includes `wardline[scanner]` for exactly this reason. This breaks thesis
invariant #1 ("install it and it stands itself up"): installing a capability extra broke
the tool.

## Options considered

1. **Guidance only** — tell users to combine extras (`wardline[scanner,loomweave]`).
Rejected: pushes the uv-tool gotcha onto every user; the single-extra install (the
natural action, and what the doctor hint advised) stays broken.
2. **Make scan-pipeline extras self-sufficient** (CHOSEN) — `loomweave` self-includes
`wardline[scanner]`, mirroring `rust`; a single-extra install carries its prerequisites.
3. **Collapse loomweave into base/scanner** — rejected: violates G4 (capability stays
behind opt-in extras) and the zero-dep base.

## The call

**Make scan-pipeline extras self-sufficient.** `loomweave = ["wardline[scanner]",
"blake3>=1.0"]` (loomweave's taint-store writes fire only during `wardline scan`, so it
genuinely needs the pipeline; there is no loomweave-without-scanner path — the CLI refuses
to start without scanner). Plus a shared `extra_install_hint(extra)` naming both installers
(`uv tool install` vs `pip install`, since pip targets the wrong env for a uv-tool install)
across every extra hint, and a regression guard (`test_extras_composition.py`) pinning the
self-sufficiency invariant. Verified: built-wheel METADATA resolves `loomweave →
blake3+click+jsonschema+pyyaml`; a single `[loomweave]` install now keeps scanner (no
whack-a-mole, confirmed live in the uv tool); 256 install+cli tests + layering conformance
green. Commits `87f13b0d` + `8c950e02`.

## Rationale

Serves invariant #1 directly — the install surface is part of "plug-and-play." The fix is
the established in-repo pattern (`rust`), keeps the base zero-dep and capability opt-in (G4
holds), and closes a previously **untested** invariant. Engineering-tracked in
`wardline-c8d7e020e8`; recorded as a product decision because the install surface is a
thesis-invariant-#1 concern, not incidental hygiene.

## Reversal trigger

Reopen the bundling decision if a legitimate consumer needs `wardline[loomweave]` WITHOUT
the scanner pipeline (none exists today), or if the extras-composition guard is ever
relaxed — watched under G4's per-release extras re-check (`metrics.md`). The
install-friction class itself reopens if a single-extra `uv tool install` whack-a-moles
again on any extra after this fix.
8 changes: 8 additions & 0 deletions docs/product/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ gates) enters the tool.
- `BASELINE → TARGET`: `BASELINE: base = 0 runtime deps at 1.0.6 → TARGET: base
stays 0 runtime deps; new deps only behind a named extra, re-checked each
release`
- **Reading 2026-06-29 (PDR-0010):** per-release extras re-check — base package stays
**0 runtime deps** (G4 holds); capability stays behind named extras. Fixed an
install-friction defect: the `loomweave` extra was not self-sufficient under `uv tool
install` (which replaces, not merges, extras), so a bare `wardline[loomweave]` dropped
the scanner deps and broke the CLI (whack-a-mole). Now `loomweave` self-includes
`wardline[scanner]` (mirrors `rust`) so single-extra installs carry their prerequisites.
**No weight creep** (loomweave still opt-in; base unchanged) and **no G4 trigger
crossed**. Pinned by `test_extras_composition.py`; tracker `wardline-c8d7e020e8`.

## Notes

Expand Down
Loading
Loading