Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
2d1d9a8
product: ship 1.4.0 (north-star → 0, post-gold honesty bet WON); PDR-…
tachyon-beep Jul 1, 2026
ce75b4a
product: DECIDE next Now bet — federation offline contract hardening …
tachyon-beep Jul 1, 2026
6f2e49d
fix: expose Plainweave preflight continuation
tachyon-beep Jul 10, 2026
aa06f5d
docs: design Plainweave doctor binding repair
tachyon-beep Jul 10, 2026
9c372d6
docs: plan Plainweave doctor binding repair
tachyon-beep Jul 10, 2026
97d545a
feat(doctor): discover initialized Plainweave projects
tachyon-beep Jul 11, 2026
3e1a61d
fix(doctor): contain Plainweave discovery scope
tachyon-beep Jul 11, 2026
270e8a3
feat(doctor): repair project Plainweave binding
tachyon-beep Jul 11, 2026
07c1e53
fix(doctor): make project binding repair race safe
tachyon-beep Jul 11, 2026
6a6bfdb
fix(doctor): fail closed on unsupported anchored IO
tachyon-beep Jul 11, 2026
8af7a08
feat(doctor): repair Codex Plainweave binding
tachyon-beep Jul 11, 2026
9e9a5f4
fix(doctor): parse quoted Codex TOML headers
tachyon-beep Jul 11, 2026
f498c2c
fix(doctor): align Codex config targeting
tachyon-beep Jul 11, 2026
1267c90
fix(doctor): reject Codex OAuth transport conflicts
tachyon-beep Jul 11, 2026
61abd02
feat(doctor): check Plainweave launch bindings
tachyon-beep Jul 11, 2026
311ad21
fix(doctor): preserve unsafe MCP operator config
tachyon-beep Jul 11, 2026
39e3d41
docs: explain Plainweave doctor binding repair
tachyon-beep Jul 11, 2026
599d748
docs: clarify Plainweave doctor repair scope
tachyon-beep Jul 11, 2026
a66eb86
style: format Plainweave doctor changes
tachyon-beep Jul 11, 2026
8a5fc28
test: guard Plainweave binding coverage
tachyon-beep Jul 11, 2026
5544a1d
fix(doctor): preserve project JSON newlines
tachyon-beep Jul 11, 2026
1e442e1
fix(doctor): canonicalize Plainweave project root
tachyon-beep Jul 11, 2026
b7bcabf
fix(doctor): trust Plainweave executables
tachyon-beep Jul 11, 2026
104729b
fix(doctor): reject ambiguous MCP JSON
tachyon-beep Jul 11, 2026
c53d95f
fix(doctor): report unsupported Codex TOML honestly
tachyon-beep Jul 11, 2026
238b2cd
fix(doctor): detect project path swaps
tachyon-beep Jul 11, 2026
8da7aef
fix(doctor): bind MCP repair safety to snapshot
tachyon-beep Jul 11, 2026
e8c0bc7
fix(ci): fail closed on missing coverage measurements
tachyon-beep Jul 11, 2026
23ce5b2
fix(doctor): coordinate configuration writers
tachyon-beep Jul 11, 2026
3e8e67f
fix(doctor): bound Plainweave discovery input
tachyon-beep Jul 11, 2026
01c3187
docs(release): describe conditional live oracle gate
tachyon-beep Jul 11, 2026
76a762a
docs(platform): declare POSIX safety boundary
tachyon-beep Jul 11, 2026
8b5e65a
docs(doctor): disclose project JSON normalization
tachyon-beep Jul 11, 2026
22b143f
docs(release): align public version metadata
tachyon-beep Jul 11, 2026
9ffaa3a
test(format): gate changed Python files
tachyon-beep Jul 11, 2026
43d6e74
fix: anchor doctor-safe MCP registration
tachyon-beep Jul 11, 2026
36b6e1d
fix: reject blocking Plainweave config targets
tachyon-beep Jul 11, 2026
24f337f
fix: bound MCP JSON nesting
tachyon-beep Jul 11, 2026
101ec2e
fix: revalidate config lock after flock
tachyon-beep Jul 11, 2026
3fa0503
fix: bound Plainweave binding config reads
tachyon-beep Jul 11, 2026
4123267
fix: make config replacements crash-durable
tachyon-beep Jul 11, 2026
092f4cd
fix: avoid process-wide umask mutation
tachyon-beep Jul 11, 2026
494ee40
test: clear whole-tree Ruff violations
tachyon-beep Jul 11, 2026
25acf6b
fix(doctor): harden project MCP integration checks
tachyon-beep Jul 11, 2026
a9d6963
feat(doctor): accept python -m plainweave.mcp_server launcher
tachyon-beep Jul 11, 2026
cfd3090
fix(ci): make changed-format gate surrogate-safe on non-UTF-8 names
tachyon-beep Jul 11, 2026
eb871bf
fix(doctor): fail closed on deeply-nested Codex config.toml
tachyon-beep Jul 11, 2026
5cff4dd
fix(install): git-ignore orphaned .mcp.json repair temp files
tachyon-beep Jul 11, 2026
3ed0c74
chore(release): bump to 1.5.0
tachyon-beep Jul 11, 2026
ad1c802
docs: design Plainweave runtime autodiscovery
tachyon-beep Jul 11, 2026
4cce445
docs: plan Plainweave runtime autodiscovery
tachyon-beep Jul 11, 2026
44ec037
fix(mcp): discover Plainweave from active project
tachyon-beep Jul 11, 2026
fd24d11
test(mcp): isolate Plainweave runtime discovery
tachyon-beep Jul 11, 2026
dccdfcf
fix(doctor): remove legacy project Plainweave binding
tachyon-beep Jul 11, 2026
e3cde57
fix(doctor): remove global Plainweave project binding
tachyon-beep Jul 11, 2026
2aa6389
fix(doctor): make Codex binding removal helper idempotent
tachyon-beep Jul 11, 2026
57c5508
fix(doctor): converge Plainweave bindings across projects
tachyon-beep Jul 11, 2026
8c4d7fd
fix(doctor): make Plainweave migration project-independent
tachyon-beep Jul 11, 2026
fa30f7b
fix(install): reject relative global MCP commands
tachyon-beep Jul 11, 2026
5f75689
docs: explain Plainweave runtime autodiscovery
tachyon-beep Jul 11, 2026
2265601
docs: correct Plainweave autodiscovery contract
tachyon-beep Jul 11, 2026
c27998a
test(docs): reject active Plainweave environment claims
tachyon-beep Jul 11, 2026
472ff91
style: format Plainweave autodiscovery changes
tachyon-beep Jul 11, 2026
37c66aa
fix(mcp): close runtime autodiscovery review gaps
tachyon-beep Jul 11, 2026
51295ff
test(mcp): close autodiscovery proof gaps
tachyon-beep Jul 11, 2026
6f3fbf3
docs: define Plainweave fallback precedence
tachyon-beep Jul 11, 2026
2f7fc89
docs: apply Plainweave precedence across guides
tachyon-beep Jul 11, 2026
75be321
fix(mcp): validate configured global command path
tachyon-beep Jul 11, 2026
3a221da
test(doctor): isolate global Codex config
tachyon-beep Jul 11, 2026
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
55 changes: 52 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,51 @@ versions per [PEP 440](https://peps.python.org/pep-0440/) /

_Post-1.0.0 work lands here; legis versions independently from the Weft 1.0 launch on._

## [1.5.0] — 2026-07-12

### Added

- **Plainweave runtime autodiscovery restores multi-project convergence and
removes binding oscillation (legis-3622e80f2e).** Legis MCP now discovers
Plainweave once at startup from the active project cwd. It accepts either a
valid root-pinned local Plainweave MCP entry by itself, or
`.plainweave/plainweave.db` plus a trusted non-project-local
`plainweave-mcp` on `PATH`. For an initialized project, a present malformed
`.mcp.json` or invalid local Plainweave entry fails closed and disables the
trusted `PATH` fallback. The database-plus-`PATH` fallback is considered only
when local config presents no Plainweave configuration issue. The global Codex
Legis registration stays tool-only and never carries a Plainweave root.
This converges across projects instead of rewriting one global project target
back and forth. `PLAINWEAVE_MCP_CMD` is now a retired 1.5.0 legacy migration
key. `install.plainweave_project_binding` verifies active-project discovery
and the legacy key's absence while `install.mcp_json` retains
project-registration ownership. `install.plainweave_codex_binding`
independently inspects only an
existing global registration; absence is healthy and it never creates one.
`legis doctor --fix` semantically changes only the retired key, post-verifies,
and requests an MCP reconnect or restart. Project `.mcp.json` removal
reserializes the whole document with two-space indentation while preserving
unrelated JSON values, the detected newline sequence, final-newline presence,
and file mode rather than arbitrary whitespace; global Codex TOML removal is
text-surgical. Project repair refuses unsafe or secret-bearing `.mcp.json`
environment tables and leaves the file unchanged. Global remove-only repair
accepts string-valued environment entries and preserves every unrelated
entry, including secret-shaped names; it refuses malformed, unsupported, or
mixed-transport shapes. Fixed global `cwd` remains operator-owned and
unchanged, including the partial `[fixed] [operator]` outcome when legacy
cleanup succeeds but the fixed `cwd` remains.

### Changed

- **Platform support narrowed to POSIX.** The package now declares
`Operating System :: POSIX` instead of `OS Independent`. Configuration
inspection and repair rely on directory-relative, no-follow file operations
and advisory `flock` locking, which protect against path swaps and
cooperating-writer races on POSIX hosts (including supported Linux and macOS).
Windows is not currently supported; on a host lacking these primitives,
Plainweave discovery and binding checks fail closed and automatic MCP
configuration repair is unavailable.

## [1.4.0] — 2026-06-29

Two internal hardenings on top of 1.3.0: a `policy_boundary_check` scan-root
Expand Down Expand Up @@ -127,8 +172,9 @@ advisory-preflight **consumer**.
mirroring the Warpline advisory-preflight read exactly: injectable
`PlainweaveMcpClient` + `StdioMcpInvoke`, every fault fails closed →
`unavailable`, GV-LG-3 validated against Plainweave's real `authority_boundary`
shape, configured via `PLAINWEAVE_MCP_CMD` (default unconfigured →
`unavailable`). Enrich-only; governance verdicts stay byte-identical with or
shape, originally configured via the now-retired legacy
`PLAINWEAVE_MCP_CMD` key (default unconfigured → `unavailable`). Enrich-only;
governance verdicts stay byte-identical with or
without Plainweave. The conformance oracle drives a constructed golden (live
end-to-end capture is a flagged follow-up).

Expand Down Expand Up @@ -846,7 +892,10 @@ WP-M1 service-layer extraction, consolidated behind a stable version.
`HTTPException`, so both HTTP and the forthcoming MCP adapter drive one code
path. Behavior-preserving; FastAPI handlers are now thin adapters.

[Unreleased]: https://github.com/foundryside-dev/legis/compare/v1.1.1...HEAD
[Unreleased]: https://github.com/foundryside-dev/legis/compare/v1.5.0...HEAD
[1.5.0]: https://github.com/foundryside-dev/legis/compare/v1.4.0...v1.5.0
[1.4.0]: https://github.com/foundryside-dev/legis/compare/v1.2.0...v1.4.0
[1.2.0]: https://github.com/foundryside-dev/legis/compare/v1.1.1...v1.2.0
[1.1.1]: https://github.com/foundryside-dev/legis/compare/v1.1.0...v1.1.1
[1.1.0]: https://github.com/foundryside-dev/legis/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/foundryside-dev/legis/compare/v1.0.0rc4...v1.0.0
Expand Down
66 changes: 58 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,69 @@ Legis is the fourth Weft product: the git/CI and governance side of the suite's

## Status

Legis is at **`1.1.1`** — the gold release line with post-launch posture, install, and release-gate hardening. The standalone git/CI surfaces, the graded 2x2 enforcement engine, the agent-programmable policy grammar, SEI-keyed attestations, and the Wardline/Filigree suite combinations are built and tested. The git-rename provider to Loomweave is contract-locked, operative pending Loomweave's committed-range driving.
Legis is at **`1.5.0`** — the current gold release with post-launch posture,
install, release-gate, policy-boundary, dependency, and package-layering
hardening. The standalone git/CI surfaces, the graded 2x2 enforcement engine,
the agent-programmable policy grammar, SEI-keyed attestations, and the
Wardline/Filigree suite combinations are built and tested. The git-rename
provider to Loomweave is contract-locked, operative pending Loomweave's
committed-range driving.

The transport-agnostic service layer (WP-M1) and the agent-facing MCP surface on top of it have landed (`legis mcp`). The MCP surface now declares output schemas across its tools, exposes read-side governance/diagnostic tools (`doctor_get`, `override_list`, `policy_boundary_check`, lineage-honesty reads, `check_report`, `signoff_bind_issue`), and keeps the API/MCP/CLI paths routed through the same service layer instead of duplicating governance decisions.

Legis stands itself up with `legis install`: instruction block, `legis-workflow` skill pack, SessionStart hook, `.mcp.json` registration, and the Legis-only `.weft/legis/` ignore rule. `legis doctor [--fix]` provides an operator health view and safe repair for the install + config layer, tagging each problem `[auto-fixable]` or `[operator]` so it is clear what `--fix` will and will not touch. Doctor names enablement paths when governance is unwired (policy cells, Wardline routing), but it reports rather than auto-enabling policy surfaces or touching signing keys.

Gold was earned, not declared: 1.0.0 was first cut on 2026-06-09, then re-opened when a P0 governance-honesty false-green (G1 — an absent Wardline `findings` key routing zero defects under a green status) was caught *after* the cut. The 1.1.x line keeps that surface hardened: posture floors fail closed, operator sessions are signed, rekey recovery preserves the standing floor, and release publication is gated on live Loomweave conformance. See the combination matrix below for per-pairing status and `CHANGELOG.md` for the full release notes.

### Last week in practical terms

The last week moved Legis from "feature-complete release candidate" to "operationally hardened gold":

- **Release and conformance.** PyPI publishing is gated on live Loomweave SEI conformance with required `LOOMWEAVE_URL`, `LOOMWEAVE_LIVE_ORACLE_LOCATOR`, and `LEGIS_LOOMWEAVE_HMAC_KEY`; optional CI-only skips no longer decide release integrity.
Legis MCP runtime autodiscovery resolves Plainweave once at startup from the
active project working directory. It accepts either a valid root-pinned local
Plainweave MCP entry by itself, or `.plainweave/plainweave.db` plus a trusted
non-project-local `plainweave-mcp` on `PATH`. It creates no new manifest.
For an initialized project, a present malformed `.mcp.json` or invalid local
Plainweave entry fails closed and disables the trusted `PATH` fallback. The
database-plus-`PATH` fallback is considered only when local config presents no
Plainweave configuration issue.
Global Codex Legis configuration stays tool-only and
project-agnostic: it carries no Plainweave root, fixed `cwd`, or
`PLAINWEAVE_MCP_CMD`, which is a retired 1.5.0 legacy migration key rather than
active configuration.

`legis doctor` verifies active-project discovery and checks both the project
Legis registration and any existing global Codex Legis registration for the
retired key. `legis doctor --fix` semantically changes only the retired
`PLAINWEAVE_MCP_CMD` key in a safe project Legis environment table, but it
reserializes the whole `.mcp.json` document with two-space indentation. It
preserves unrelated JSON values, the detected newline sequence, final-newline
presence, and file mode; it does not preserve arbitrary whitespace formatting.
Project repair refuses unsafe or secret-bearing `.mcp.json` environment tables
and leaves the file unchanged. Global remove-only repair accepts string-valued
environment entries and preserves every unrelated entry, including
secret-shaped names; it refuses malformed, unsupported, or mixed-transport
shapes. `install.mcp_json` continues to own project registration; the global
check inspects only an existing registration and never creates one. Doctor
leaves a fixed global `cwd` operator-owned. A combined cleanup can report
`[fixed] [operator]`: remove the reported fixed `cwd` manually, reconnect or
restart the MCP client, and rerun doctor. See the
[Plainweave runtime-autodiscovery configuration guide](docs/guide/configuration.md#plainweave-mcp-runtime-autodiscovery-and-legacy-migration)
and the [`legis doctor` CLI reference](docs/guide/cli-reference.md#doctor).

### Platform support

Legis currently supports POSIX hosts with directory-relative, no-follow file
operations and advisory `flock` locking (including supported Linux and macOS
hosts). These primitives protect configuration inspection and repair against
path swaps and cooperating-writer races. Windows is not currently supported;
the package metadata therefore declares POSIX rather than OS-independent
compatibility. On a host without the required primitives, Plainweave discovery
and binding checks fail closed and automatic MCP configuration repair is
unavailable.

Gold was earned, not declared: 1.0.0 was first cut on 2026-06-09, then re-opened when a P0 governance-honesty false-green (G1 — an absent Wardline `findings` key routing zero defects under a green status) was caught *after* the cut. The 1.5.x line keeps that surface hardened: posture floors fail closed, operator sessions are signed, rekey recovery preserves the standing floor, and release publication runs live Loomweave conformance when live oracle configuration is provisioned. Missing configuration skips conformance without blocking publish; a provisioned oracle failure blocks the release. See the combination matrix below for per-pairing status and `CHANGELOG.md` for the full release notes.

### Recent hardening in practical terms

Recent releases moved Legis from "feature-complete release candidate" to
"operationally hardened gold":

- **Release and conformance.** PyPI publishing keeps a conditional live Loomweave SEI gate. When `LOOMWEAVE_URL`, `LOOMWEAVE_LIVE_ORACLE_LOCATOR`, and `LEGIS_LOOMWEAVE_HMAC_KEY` are all provisioned, the live oracle runs and any failure blocks publication. If any one is absent, the release job records a notice and passes without running the oracle, preserving the owner-approved skip-not-fail policy.
- **Doctor and install hardening.** Doctor validates `.mcp.json` as an executable Legis stdio server, rejects repo-local SessionStart hooks, handles missing roots without crashing, and keeps audit-chain checks report-only instead of initializing truncated stores. Instruction refresh compares the whole owned block to the packaged block, not just the marker token.
- **Governance honesty.** Wardline dirty unsigned artifacts no longer return transport success when nothing was governed; malformed or missing scan fields fail as malformed input rather than routing zero findings under green. Policy-boundary evidence fingerprints now include semantic decorators such as `pytest.mark.skip`, `parametrize`, and wrapper decorators.
- **Configuration custody.** Repo `weft.toml` can no longer redirect Legis governance stores; explicit `LEGIS_*_DB` environment variables are the relocation mechanism. The root `.gitignore` ignores only `.weft/legis/`, not the whole shared `.weft/` namespace.
Expand Down
47 changes: 47 additions & 0 deletions docs/guide/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ selector flag installs only the named steps. Each step prints `[OK]` or
| `--mcp` | register the legis MCP server in `.mcp.json` only |
| `--agent-id` | agent id stamped in the `.mcp.json` legis entry (default: `claude-code`, or preserve an existing entry's id) |

Atomic updates preserve an existing target's mode. A newly created managed text
file uses fixed mode `0600`; Legis does not inspect or temporarily change the
process-wide umask.

**Exit codes**

| code | meaning |
Expand Down Expand Up @@ -226,6 +230,49 @@ the read-only counterpart — it never repairs; fixes stay on this CLI.)
| `--fix` / `--repair` | off | apply safe repairs, then re-check |
| `--format` | `text` | `text` (human) or `json` (machine-readable) |

**Plainweave checks and outcomes**

| Check or outcome | Meaning |
|---|---|
| `install.mcp_json` | Owns missing or stale project Legis registration repair. In a `--fix` run it may create or rebuild `command`, `args`, `type`, and safe `env` before Plainweave binding runs. |
| `install.plainweave_project_binding` | Verifies active-project runtime discovery and absence of the retired legacy `PLAINWEAVE_MCP_CMD` key. Removal semantically changes only that key, but reserializes the whole `.mcp.json` document with two-space indentation; it preserves unrelated JSON values, the detected newline sequence, final-newline presence, and file mode rather than arbitrary whitespace. |
| `install.plainweave_codex_binding` | Independently inspects only an existing global Codex Legis entry for the retired key and fixed `cwd`. No registration is healthy and not applicable; the check never creates one. |
| `[auto-fixable]` | A safe retired key is present, or a project registration is safely missing or stale. |
| `[fixed]` | That check repaired and post-verified its own scope. If registration and legacy cleanup both changed, inspect `[fixed]` on both `install.mcp_json` and `install.plainweave_project_binding`. |
| `[operator]` | A fixed global `cwd`; malformed, unsupported, or mixed-transport global config; or unsafe/secret-bearing project config remains unchanged. A safe global legacy cleanup plus fixed `cwd` can report `[fixed] [operator]`. |
| healthy, non-applicable | The project is uninitialized or not configured for Plainweave; or no global Codex Legis entry exists for the global check. |

Run `legis doctor` to inspect, `legis doctor --fix` to apply safe repairs, and
`legis doctor --format json` for automation. The project and global binding
checks are independent. Success means no check has `status: "error"`; do not
depend on an exact check count.

Legis MCP runtime autodiscovery runs once at startup from the active project
cwd. It accepts either a valid root-pinned local Plainweave MCP entry by itself,
or `.plainweave/plainweave.db` plus a trusted non-project-local
`plainweave-mcp` on `PATH`; no new manifest is created.
For an initialized project, a present malformed `.mcp.json` or invalid local
Plainweave entry fails closed and disables the trusted `PATH` fallback. The
database-plus-`PATH` fallback is considered only when local config presents no
Plainweave configuration issue.
Global Codex Legis config is tool-only and carries no Plainweave root, retired
legacy `PLAINWEAVE_MCP_CMD`, or fixed `cwd`.

Project repair refuses unsafe or secret-bearing `.mcp.json` environment tables
and leaves the file unchanged. Global remove-only repair accepts string-valued
environment entries and preserves every unrelated entry, including
secret-shaped names. It refuses malformed, unsupported, or mixed-transport
global shapes.

For migration, run `legis doctor`, run `legis doctor --fix`, manually remove a
fixed global `cwd` if doctor reports it, reconnect or restart MCP clients, then
rerun `legis doctor`. `doctor_get` is report-only. Doctor does not initialize
Plainweave, create a global registration, remove fixed `cwd`, restart clients,
or repair malformed/unsafe project config or malformed/unsupported global
shapes. See the
[Plainweave configuration procedure](configuration.md#plainweave-mcp-runtime-autodiscovery-and-legacy-migration)
for prerequisites, remediation, and safety boundaries.

**Exit codes**

| code | meaning |
Expand Down
Loading
Loading