feat: no-index MCP chirp + ADR-044 ephemeral port + dogfood/v1.1 cleanups (1.1.0-rc2)#55
feat: no-index MCP chirp + ADR-044 ephemeral port + dogfood/v1.1 cleanups (1.1.0-rc2)#55tachyon-beep wants to merge 27 commits into
Conversation
…sing DB When `.loomweave/loomweave.db` is absent, `loomweave serve` did a hard `ensure!(db_path.exists())` and exited 1 before the MCP protocol started. An MCP stdio client (Claude Code) just saw the server die at startup with the real reason buried in stderr — it read as "loomweave mcp failing" with no actionable signal. Now `serve` starts a degraded "no-index" stdio session instead: - `initialize` succeeds so the client connects cleanly; the `instructions` field leads with the run-`install`+`analyze` chirp (mirrors the SessionStart hook wording). - Every `tools/call` returns the same chirp as a tool result with `isError: true` — the load-bearing channel, since not every client surfaces `initialize.instructions`. - `tools/list` and the static `loomweave-workflow` prompt still answer so the surface looks healthy. - No HTTP read API bind, no LLM/embedding providers, no Filigree client, no ReaderPool — nothing to back them without a DB. One warn line to stderr (never stdout) at degraded startup. loomweave-mcp gains `handle_json_rpc_no_index` + `serve_stdio_no_index` plus chirp helpers; serve.rs swaps the exit for a `serve_no_index` branch. Closes clarion-ac36f51c2b. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf5f39721b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // staring at a server that died at startup with the reason buried in | ||
| // stderr — serve a degraded stdio session that answers `initialize` and | ||
| // chirps "run analyze" from every tool call. clarion-ac36f51c2b. | ||
| return serve_no_index(path, &db_path); |
There was a problem hiding this comment.
Validate the project path before degraded mode
When --path is mistyped, deleted, or points at a non-directory, this derived DB path also does not exist, so serve now starts a long-lived degraded MCP server instead of surfacing the bad project path. The recovery text then tells the user to run loomweave install --path <bad path> even though install::run rejects nonexistent targets, making stale MCP registrations look like merely missing indexes. Canonicalize/validate the project root before taking the no-index branch, and only degrade when the root is valid but the DB is absent.
Useful? React with 👍 / 👎.
…oling Read-API port deconfliction (clarion-7f574bc34f): - ADR-044 (Proposed): serve publishes .loomweave/ephemeral.port with a per-project deterministic port + ephemeral fallback and a loomweave-side resolver (twin of filigree_url), so concurrent projects stop colliding on the hardcoded 9111; installer stops pinning the port. Indexed in the ADR README. - Stopgap so this project coexists with others on 9111 until the ADR lands: loomweave.yaml serve.http.bind -> 127.0.0.1:9112 and wardline.yaml loomweave.url -> :9112. Wardline tooling: - .mcp.json: drop the hardcoded --loomweave-url/--filigree-url from the wardline MCP args (resolved from wardline.yaml instead); normalize server entries. - .pre-commit-config.yaml: add a local wardline-scan hook. - .agents/skills/wardline-gate: add the wardline-gate skill pack. - .gitignore: ignore the raw wardline scan output (findings.jsonl). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 49a6753d6e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| serve: | ||
| http: | ||
| bind: 127.0.0.1:9111 | ||
| bind: 127.0.0.1:9112 |
There was a problem hiding this comment.
Keep dogfood binding constants in sync
With this repo-local bind changed to 127.0.0.1:9112, the checked-in dogfood bindings no longer converge with the code that manages them: integration_bindings::loomweave_yaml_ok() still requires LOOMWEAVE_HTTP_BIND (127.0.0.1:9111) and wardline_yaml_ok() still requires LOOMWEAVE_HTTP_URL (http://127.0.0.1:9111). In this project, running loomweave doctor after the change reports the bindings as stale, and loomweave doctor --fix / loomweave install --all rewrites them back to 9111, undoing the new port and reintroducing the collision this config change is trying to avoid.
Useful? React with 👍 / 👎.
| "args": [ | ||
| "mcp", | ||
| "--root", | ||
| ".", | ||
| "--loomweave-url", | ||
| "http://127.0.0.1:9111", | ||
| "--filigree-url", | ||
| "http://127.0.0.1:8542/api/weft/scan-results" | ||
| ], | ||
| "command": "/home/john/.local/bin/wardline", | ||
| "type": "stdio" | ||
| "." | ||
| ] |
There was a problem hiding this comment.
Pass peer URLs to Wardline MCP
For the repo-local Wardline MCP server, this now starts Wardline with only mcp --root ., dropping both peer URL flags. The installer/doctor code in integration_bindings::desired_wardline_args() still treats --loomweave-url and --filigree-url as the desired contract, and the install/doctor tests assert those flags, so this checked-in MCP config is immediately classified as stale and Wardline MCP scans launched from this file no longer get the Loomweave/Filigree endpoints needed for the three-way dogfood integration.
Useful? React with 👍 / 👎.
| - id: wardline-scan | ||
| name: wardline scan | ||
| entry: wardline scan |
There was a problem hiding this comment.
Make the Wardline hook fail on findings
This hook runs only wardline scan, but the Wardline workflow added in this commit documents the gating invocation as wardline scan . --fail-on ERROR, with exit code 0 also used when the gate is not requested and exit code 1 only when a non-suppressed defect is at/above --fail-on. As written, commits with Python changes can run the scan without tripping pre-commit on ERROR findings, so the new hook does not actually enforce the trust-boundary gate it is installing.
Useful? React with 👍 / 👎.
… contract Incorporates the Wardline (consumer-side) review. The interop surface is the file, not loomweave's Rust resolver — Wardline implements its own Python reader against it (SEI-style "consumers conform"). Pins, as normative: - File contract: <project>/.loomweave/ephemeral.port, plain-ASCII port only, optional trailing newline, host/scheme implied, atomic temp+rename, created on loopback bind / removed on clean shutdown. - Loopback-only publication: a non-loopback bind (allow_non_loopback, ADR-034) publishes no file, so the port-only format never under-specifies the host. - Resolution precedence (consume-time, per read): explicit flag/env > published file > configured url > none. The file self-heals stale/default config but never overrides a deliberate explicit target. - Fail-soft: validate 1..=65535; malformed or resolved-but-refused (stale file / crashed serve) degrades, never errors. Instance-ID guard (ADR-034) is the correctness backstop so the reader can be simple. - Related follow-up: consume-time resolution applies to both sibling legs; Wardline's filigree leg (install-time today) should unify Wardline-side. Tracking: clarion-7f574bc34f Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ic publish (ADR-044) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eans temp on rename failure Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s per-project port (ADR-044) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…; drop misleading # Panics docs (ADR-044) Replace the two .expect() unwraps in validate_loopback_trust and validate_auth_trust with compiler-enforced pattern matching, and delete the # Panics doc sections (a # Panics heading documenting when a method will *not* panic inverts the rustdoc convention). Behavior is identical. Also add a field doc comment to HttpReadConfig.bind and two tests: the auth-trust None path and explicit YAML-null bind parsing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…sh .loomweave/ephemeral.port (ADR-044) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t is taken (ADR-044) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mweave URL, no fixed bind (ADR-044) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… on repair (ADR-044) Older `install --all` runs unconditionally stamped a fixed bind. Task 5 stopped writing it but left existing stamps in place, so re-install kept `bind: 9111`, serve honored it verbatim (no auto-port), and the collision returned invisibly (loomweave_yaml_ok no longer inspected bind). Strip exactly the old auto-default literal on repair and treat its presence as not-ok so doctor/binding_state flags and fixes it. Operator-chosen binds (any other value) are preserved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ead-API port (ADR-044) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…weave_url (ADR-044) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…112 stopgap Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…read-API report, reconcile ADR precedence
- install.rs GITIGNORE_CONTENTS now ignores .loomweave/ephemeral.port so
freshly-installed projects do not show the runtime port file as untracked
while serving; install test asserts the new rule.
- project_status_get reports loomweave_read_api (resolved_url +
resolution_source) via a query-time resolve_loomweave_url(None, project_root),
the second in-repo consumer named by ADR-044 alongside doctor. Additive field;
existing project_status tests unaffected. Two new tests cover published-port
and no-file ("none") cases.
- ADR-044: clarify precedence level 1 is an operator's deliberately-supplied
target (typed flag/env), while an installer-seeded --loomweave-url in .mcp.json
is config-tier (precedence 3) so the published file self-heals it; added a
Related follow-up bullet for Wardline (clarion-7f574bc34f).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7f253000b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| impl Drop for PublishedPortGuard { | ||
| fn drop(&mut self) { | ||
| loomweave_federation::loomweave_port::remove_published_port(&self.project_root); |
There was a problem hiding this comment.
Keep other live port publishers from being unlinked
When two loomweave serve instances are started for the same project with auto HTTP enabled, the first one publishes the deterministic port and the second falls back to an ephemeral port and overwrites .loomweave/ephemeral.port; when the first instance later shuts down, this unconditional removal deletes the second instance’s still-live discovery file. That leaves consumers unable to resolve the running read API until the second server restarts, so the guard should only remove the file if it still contains the port this server published (or otherwise use an ownership token).
Useful? React with 👍 / 👎.
| let port = loomweave_federation::loomweave_port::deterministic_port(project_root); | ||
| let loomweave_url = format!("http://127.0.0.1:{port}"); |
There was a problem hiding this comment.
Match peer URL to preserved custom binds
When an existing loomweave.yaml uses an explicit custom loopback bind, install_loomweave_yaml now intentionally preserves it, but the desired Wardline URL is still always derived from the deterministic auto-port here. After loomweave install --all / doctor --fix, Wardline config and MCP args point at a port that loomweave serve will never bind in that custom-bind project, so the three-way integration is repaired into a broken state unless the user removes their explicit bind.
Useful? React with 👍 / 👎.
| let _published_port_guard = if local_addr.ip().is_loopback() { | ||
| if let Err(err) = | ||
| loomweave_federation::loomweave_port::publish_port(&project_root, local_addr.port()) |
There was a problem hiding this comment.
Do not publish IPv6 loopback as 127.0.0.1
If an operator explicitly binds the read API to IPv6 loopback, e.g. [::1]:9412, is_loopback() is true so this publishes only the port, but every consumer composes http://127.0.0.1:<port>. On systems where that listener is IPv6-only, Wardline and status consumers are routed to an address where Loomweave is not listening; restrict publication to the IPv4 loopback address or make the published contract preserve the bound host.
Useful? React with 👍 / 👎.
| # ADR-044: pinned to this project's deterministic read-API port. The published | ||
| # .loomweave/ephemeral.port overrides this once Wardline resolves consume-time | ||
| # (clarion-7f574bc34f follow-up). Until then this keeps local wardline->loomweave working. | ||
| url: http://127.0.0.1:10196 |
There was a problem hiding this comment.
Avoid committing path-derived Wardline ports
Fresh evidence is that the desired Loomweave URL is now derived from deterministic_port(project_root), which hashes the canonical checkout path, while this tracked config hard-codes one checkout’s resulting port. In any clone whose path hashes differently, loomweave doctor reports the checked-in dogfood binding as stale and doctor --fix / install --all rewrites this tracked file to a different port, so the repo no longer converges cleanly across developer machines until Wardline resolves .loomweave/ephemeral.port itself.
Useful? React with 👍 / 👎.
Workspace + Python plugin in lockstep. Cross-ecosystem version normalization in check-workspace-version-lockstep.py (SemVer prerelease 1.1.0-rc1 == PEP 440 1.1.0rc1). CHANGELOG: ADR-044 ephemeral-port deconfliction + no-index MCP chirp. No package published for release candidates. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…mit hazard (ADR-005) The shipped .loomweave/.gitignore (ADR-005) excluded WAL/shadow/logs but not the per-project `instance_id` fingerprint or the analyze advisory lock (`loomweave.lock`, fs2), so `git add -A` staged live runtime state into demo repos. Add `instance_id` and `*.lock` to GITIGNORE_CONTENTS and refresh ADR-005's verbatim block + Excluded list (also reconciling ephemeral.port/embeddings.db). The install test now asserts both rules ship. ADR-005 also gains a "Committing a live index" note: the on-disk loomweave.db lags its pending WAL while serve runs, so commit a consistent copy via `loomweave db backup` (or stop serve) rather than git-add-ing the live file. Closes clarion-7381e6382d. Refs clarion-cdee445ed8. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ace db backup After a successful CommitRun the writer-actor now runs `PRAGMA wal_checkpoint(TRUNCATE)` so the on-disk loomweave.db reflects committed state while the writer is still alive — previously the WAL only truncated on last-connection close, leaving a multi-MB pending sidecar that made the .db an unreliable point-in-time artifact for commit. The checkpoint is best-effort: failure logs a warning and leaves committed frames durable. `loomweave analyze --help` now points at `loomweave db backup` for committing the index as a versioned artifact (the verb already exists; this is discoverability). Closes clarion-cdee445ed8. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ee verdict (ADR-045)
project_status_get reported staleness:"fresh" while the working tree held
un-indexed source, so the session-start banner ("index is fresh, ask Loomweave")
lied about uncommitted code. Make staleness worktree-aware:
- Snapshot gains indexed_at_commit + worktree_dirty; a new Staleness::StaleWorktree
verdict fires when an otherwise-fresh index has untracked source on disk.
- Detection uses loomweave_core::list_untracked_files — hardened, hash-free
`git ls-files --others --exclude-standard`, scoped to ingested source extensions
so a scratch notes.txt does not flag (false-positive guard). Fail-soft outside
a git work tree.
- Surfaced on loomweave://context, project_status_get (worktree_dirty +
staleness_note), and the session-start banner with a concrete re-analyze remedy;
orientation treats StaleWorktree as stale.
- ADR-045 records the maintainer-authorized security boundary: `git status` is
forbidden (filter.clean RCE on hashed content; clarion-4b5a8aff54), but
ls-files --others is hash-free — proven by the new
ls_files_others_does_not_run_clean_filter security test, not reasoning alone.
Closes clarion-26c7e52027 and clarion-d9cf8bcfa9.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-04) Release archives are unsigned (ADR-033), so macOS Gatekeeper blocks the downloaded loomweave binary on first launch. Add a Troubleshooting entry with the `xattr -d com.apple.quarantine` fix and the GUI "Open Anyway" alternative. Closes clarion-03dfa1f94d. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v1.0.0 was the first externally-published build; 0001_initial_schema.sql is byte-identical at v1.0.0 and HEAD, and all schema changes since are additive 0002+ migrations. Backfilling the marker activates scripts/check-migration-retirement.py's guard (previously pre-trigger despite shipped releases): in-place edits to 0001 now fail CI, enforcing additive-only. Closes clarion-b20448b3ac. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…47d395e03c) release.yml's `verify` job was Linux-only, so a macOS-only clippy/--all-targets regression — caught on PRs by ci.yml's rust-macos job but not re-verified at release — could pass `verify` and proceed to the build/publish jobs (the aarch64 build leg only builds --bins, not tests/all-targets). Add a `verify-macos` job mirroring ci.yml's rust-macos (clippy + bin build on macos-14) and add it to the needs chain of build-rust, build-wheels, and build-plugin. No new runner dependency — build-rust already uses macos-14. Closes clarion-47d395e03c. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…9, V11-STO-06) content_text shipped in 0001 reserved for an on-demand source-text projection that was never built: the entities_ai trigger always wrote '', the entities_au trigger never touched it, and no query reads it (search MATCHes the table, not the column). It was permanently-empty schema drift; content search is served by the ADR-040 embeddings sidecar. FTS5 has no ALTER DROP COLUMN, so migration 0009 recreates entity_fts and its triggers without it and rebuilds the index from entities. Behaviour-preserving — only a never-populated, never-read column goes. Bumps CURRENT_SCHEMA_VERSION to 9; updates the schema_migrations expectation tests and the authoritative detailed-design.md FTS block; adds a regression test asserting content_text is gone and MATCH search still works. Closes clarion-716449c371. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Workspace + Python plugin in lockstep. rc2 rolls up the dogfood-friction fixes and deferred v1.1 engineering items landed on this branch: worktree-aware staleness (ADR-045), .gitignore instance_id/*.lock (ADR-005), WAL checkpoint(TRUNCATE), entity_fts.content_text drop (migration 0009), the macOS aarch64 release verify gate, the Gatekeeper doc, and the ADR-024 marker backfill. No package published for release candidates. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nstall + doctor) `loomweave install` now pushes a managed Loomweave block into the always-loaded CLAUDE.md / AGENTS.md context, mirroring Filigree's instruction injection, so an agent learns to ask Loomweave's MCP tools before re-grepping the tree. `loomweave doctor` verifies it and, with --fix, repairs it via the same idempotent installer. New `instructions.rs` manages a `<!-- loomweave:instructions -->`… `<!-- /loomweave:instructions -->` span and edits ONLY its own bytes — it never truncates to EOF, so a co-resident Filigree/Wardline block in the same file survives every create/append/replace/malformed operation. Drift is a body content hash (not the marker version, so a version bump on identical content is not drift), and the malformed-repair strips all orphan start markers so it stays safe and converges in a single pass. - install: --instructions flag + InstallPlan plumbing; bare `install` does it. - doctor: Missing=warning (optional surface), Drifted/Malformed=problem; wired into both the text and JSON report paths with a next-action remediation. - thin embedded asset: a pointer to the MCP tools + the loomweave-workflow skill. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a93731f72
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| http.get("enabled").and_then(Value::as_bool) == Some(true) | ||
| && http.get("bind").and_then(Value::as_str) == Some(LOOMWEAVE_HTTP_BIND) | ||
| && http.get("wardline_taint_write").and_then(Value::as_bool) == Some(true) | ||
| && http.get("bind").and_then(Value::as_str) != Some(STALE_DEFAULT_BIND) |
There was a problem hiding this comment.
Validate custom HTTP binds before marking bindings healthy
When loomweave.yaml contains an explicit but invalid bind such as bind: not-a-socket (or a non-string value), this predicate now treats the config as healthy because anything other than the stale 127.0.0.1:9111 literal passes. The actual config loader rejects invalid binds in deserialize_optional_socket_addr, so loomweave serve will fail while doctor / doctor --fix report the integration bindings as present and do not repair or remove the broken value. Preserve valid custom binds, but parse/validate this field before returning Present.
Useful? React with 👍 / 👎.
| Some((span_start, body_start)) if trimmed == END_MARKER => { | ||
| // Body is everything between the start-marker line and the | ||
| // end-marker line; trim a single trailing newline so it round-trips | ||
| // against `canonical_body` (which has no trailing newline). | ||
| let raw_body = &content[body_start..line_start]; | ||
| let body = raw_body.strip_suffix('\n').unwrap_or(raw_body).to_owned(); | ||
| return Span::WellFormed { |
There was a problem hiding this comment.
Treat nested start markers as malformed
If a file has an orphaned Loomweave start marker before a later well-formed Loomweave block (for example after a bad merge, with Filigree/Wardline prose between them), this accepts the first later end marker as closing the orphaned start. doctor --fix then classifies the whole intervening region as a drifted Loomweave span and splice_span replaces it, deleting the neighboring tool block or user text. Detect a second START_PREFIX before the matching end marker as malformed so the safe orphan-stripping path is used instead.
Useful? React with 👍 / 👎.
| "Index does NOT reflect the working tree: untracked source files of \ | ||
| already-indexed types are present (new modules not yet analyzed). \ | ||
| Run `loomweave analyze {}` before relying on graph answers \ | ||
| (e.g. \"what calls X\").", |
There was a problem hiding this comment.
Flag stale-worktree snapshots in doctor JSON
For a StaleWorktree snapshot, this new banner no longer contains the substring may be stale, but check_index_freshness_json still classifies freshness by searching only for that phrase. As a result, loomweave doctor --json reports index.freshness as ok even when untracked source is present and the index does not reflect the working tree, which can let JSON-based gates miss exactly the stale condition added here.
Useful? React with 👍 / 👎.
This PR bundles related
loomweave serveimprovements plus a batch of dogfood-friction fixes and deferred v1.1 engineering cleanups (see commit groups). Ships as 1.1.0-rc2.1. No-index MCP chirp (cf5f397)
serveno longer exits 1 when there is no index. It serves a degraded MCP stdio session that answersinitializeand chirps "runloomweave install+loomweave analyze" from every tool call, so the MCP client connects and is told how to recover instead of staring at a server that died at startup.2. ADR-044 — read-API ephemeral port publication (a0731d4..c7f2530)
Fixes the cross-project
127.0.0.1:9111collision: every project'sloomweave servebound the same hardcoded port, so two could not run concurrently and consumers mis-targeted each other's instances.loomweave_port::deterministic_port, blake3 band9400–10399, disjoint from Filigree's8400–9399) with an OS-ephemeral:0fallback when the deterministic port is taken (auto only — an explicit operator bind in use stays a hard error)..loomweave/ephemeral.port— a normative cross-product file contract (port-only ASCII + optional\n, atomic temp+rename, loopback-only, RAII-removed on clean shutdown/error/panic). Stale-file/crash cases are tolerated; the ADR-034 instance-ID guard is the correctness backstop.HttpReadConfig.bind: Option<SocketAddr>—None(the new default) auto-selects;Some(addr)is honored verbatim.resolve_loomweave_url(precedence: explicit > published file > config > none), the reference reader Wardline's Python twin mirrors. Reported bydoctorandproject_status_get.bind;integration_bindingswrites the per-project deterministic URL and self-heals the oldbind: 127.0.0.1:9111stamp on repair..filigree/ephemeral.port). Closes clarion-7f574bc34f.Wardline-side consume-time resolution remains a separate follow-up (its own repo), captured in ADR-044's Related follow-up.
3. Dogfood-friction fixes + deferred v1.1 cleanups (7ff84b2..5675f4a)
Resolves the actionable loomweave-impacting tickets from the 2026-06-06 dogfood report and several deferred v1.1 gap-register items. Each is its own commit.
project_status_get/loomweave://context/session-start banner gainindexed_at_commit+worktree_dirty; a newStaleness::StaleWorktreeverdict fires when an otherwise-fresh index has untracked source. Detection uses a hardened, hash-freegit ls-files --othersscoped to ingested source extensions (false-positive guard), proven filter-RCE-safe by thels_files_others_does_not_run_clean_filtertest. Closes clarion-26c7e52027 + clarion-d9cf8bcfa9..loomweave/.gitignoreinstance_id + .lock (ADR-005, 7ff84b2).git add -Ano longer stages the serve fingerprint or analyze lock; ADR-005 documents the live-index commit hazard →loomweave db backup. Closes clarion-7381e6382d..dbreflects committed state whileserveis alive. Closes clarion-cdee445ed8.entity_fts.content_text(migration 0009, 8be269d). Never populated, never read (content search is ADR-040 embeddings);CURRENT_SCHEMA_VERSION→ 9. Closes clarion-716449c371.ci.yml, wired into build/publishneeds. Closes clarion-47d395e03c.Verification
Full CI floor green:
fmt/clippy -D warnings/build/nextest1209 passed /doc -D warnings/cargo deny; Pythonruff/ruff format/mypy --strict/pytest166 passed (85%); version-lockstep + ADR-024 migration-retirement guards pass at1.1.0-rc2;wardline scan --fail-on ERRORclean on changed crates.🤖 Generated with Claude Code