Skip to content

Latest commit

 

History

History
147 lines (99 loc) · 14.1 KB

File metadata and controls

147 lines (99 loc) · 14.1 KB

Weft — cross-product contract index

Status: Authoritative as an index, not as a schema. This lists every live cross-product contract and points to the owning project's authoritative doc. Route shapes / tool names are quick references for orientation; the owning doc is authoritative if they ever disagree. weft does not restate full schemas — that is how the old hub drifted.

Identity is the spine. Every binding below keys on SEI (opaque, Loomweave-minted). A binding still keyed on a locator is legacy to migrate.

Two kinds of contract now live here. §1–10 are pairwise bindings (member X composes with member Y). §0 below is the first federation-wide hub-blessed contract — a discipline every member conforms to, not a join between two of them. PDR-0023 (the seams are the product) makes this class first-class: the cross-cutting conventions are the glue's standards.

Building a whole member, not one binding? The Federation SDK is the member-builder's companion to this index — same surfaces, organized by the obligations a new tool must meet to drop in.

Machine-readable canonical twin. This markdown is the human index; contracts/seam-index.json is its hub-owned machine-readable catalog + blessing registry — every cross-member seam, its contract URI, producer/consumer, and hub blessing PDR. It is a catalog + blessing registry, not a live verdict store: conformance verdicts stay distributed in each member's own CI (PDR-0043). Wardline's tests/conformance/seam_registry.json is a producer-contributed conformance mirror of it, not federation canon. Declared canon by PDR-0045 (hub reclaims the seam-index + dissolves the wardline steward role — closing PDR-0038 conditions 1–3).

Launch freeze set. The clean-break launch freezes the cross-member contracts listed in this index, plus the executable conformance fixtures they point to. ADR-049, the Rust qualname dialect shared by Loomweave and Wardline, is explicitly out of that core freeze set: it versions with the Rust feature and both members adopt its corpus together. PDR-0014 makes Rust-gold a cutover quality gate, but it does not turn ADR-049 into a frozen core API contract; a post-launch ADR-049 amendment is valid only as a versioned Rust-feature change with Loomweave and Wardline moving in lockstep.


0. The weft-reason honesty contract — hub-blessed, every member conforms (G1)

The honesty invariant made machine-readable. Every cross-member result that is not a clean, complete true-negative carries a three-part carrier { reason_class, cause, fix }; a clean result carries reason_class: "clean" and omits cause/fix. reason_class is drawn from a canonical set of 11 (clean, disabled, unresolved_input, rejected, dead_path, unreachable, misrouted, error, scheme_mismatch, stale, partial). This is the first hub-blessed federation contract (owner gate, 2026-06-15) and the protected moat-guard of PDR-0023: no result without its provenance. It exists because the four 2026-06-15 seam-honesty strikes each minted a different "why empty" dialect — the contract constrains them to one vocabulary so a join-miss can never read as a true-negative.

  • No shared runtime dependency. Members stay independent repos and conform by convention + a per-member conformance TEST that asserts their emitted reason surface against the canonical list — preserving the no-shared-dep posture. The shared test vector IS weft-e295ec3be3 Part 1 (the honesty guardrail's last limb).
  • Rollout is staged (do not over-claim). The value vocabulary (the 11 reason_class strings) is standardized now, across all members, additive/non-breaking. The full carrier shape (cause + reason_class + fix triple) is the target, adopted as far as each member can without a re-shock — new surfaces use the full triple from day one; full convergence lands with G3 (loomweave typed output) and, for filigree, inside the held 3.0.0 (additive, never a 3.1.x re-break). As of 2026-06-15 members emit reason_class on status/failure/resolution carriers; per-finding triple coverage is still converging.
  • Authoritative: contracts/weft-reason-vocab.json (machine-readable canonical list) + pm/2026-06-15-weft-reason-contract-G1.md (the doctrine + per-class examples). The G4 scheme-echo handshake will be the next hub-authored seam contract joining this family.

1. Entity associations — Filigree ↔ Loomweave (Filigree ADR-029)

Bind a Filigree issue to a Loomweave entity. The entity_associations table lives on Filigree's side; the entity id is an opaque string (an SEI going forward) Filigree never parses; drift detection is the consumer's job via content_hash_at_attach.

  • Filigree HTTP (classic generation — note: /api/issue/…, not /api/weft/…): GET|POST /api/issue/{issue_id}/entity-associations, DELETE /api/issue/{issue_id}/entity-associations?entity_id=…, GET /api/entity-associations?entity_id=… (reverse lookup).
  • Filigree MCP: entity_association_add, entity_association_remove, entity_association_list, entity_association_list_by_entity.
  • Loomweave side: issues_for(entity_id, include_contained) / the entity_issue_list MCP tool returns bound issues with drift status.
  • Authoritative: ~/filigree/docs/federation/contracts.md + Filigree ADR-029; Loomweave ADR-029 (~/loomweave/docs/loomweave/adr/ADR-029-entity-associations-binding.md). See members/filigree.md.

2. SEI identity resolution — Loomweave (authority) → all consumers

Loomweave's HTTP read API exposes identity resolution: resolve(locator), resolve_sei(sei), lineage(sei), and _capabilities advertising sei: {supported, version}. Opaque on the wire; fail-closed on non-locator input (reserved loomweave:eid: prefix).

  • Authoritative: sei-standard.md (the contract) + Loomweave ADR-038 (token form) + ~/loomweave/docs/federation/contracts.md. Conformance fixtures at ~/loomweave/docs/federation/fixtures/sei-conformance-oracle.json.

3. Wardline taint-fact store — Wardline ↔ Loomweave (Loomweave ADR-036)

Wardline computes per-entity taint facts and persists them to Loomweave; Loomweave stores the wardline_json blob opaque (never parses it). Routes on Loomweave: POST /api/wardline/taint-facts (write, disabled by default), GET /api/wardline/taint-facts?qualname=, POST /api/wardline/taint-facts:batch-get, POST /api/wardline/taint-facts/by-sei.

  • Authoritative: ~/loomweave/docs/federation/contracts.md + Loomweave ADR-036. Wire terms in glossary.md.

4. Wardline findings → Filigree (native emitter shipped; A-1 live pending composition test)

Wardline findings reach Filigree's scan-results intake. The legacy path routes through Loomweave's loomweave sarif import translator into the classic POST /api/v1/scan-results — this is asterisk A-1. Wardline's native Filigree emitter has now shipped (~/wardline/src/wardline/core/filigree_emit.py), posting directly to the federation generation (POST /api/weft/scan-results); A-1 stays live until the Loomweave-absent Wardline+Filigree composition is demonstrated end-to-end (see the asterisk for the exact evidence level).

The emit pins the finding's suppression provenance: a non-active finding carries its state under metadata.wardline.suppression_state (exactly one of baselined | waived | judged) plus an optional metadata.wardline.suppression_reason; an active finding omits the key entirely — absent ⇒ active, never the literal "active" on this seam. This is precisely what lets Filigree's ingest preserve the suppression signal so finding_promote refuses/warns on a baselined finding rather than minting a fresh P1. Pinning it here closes the Wardline side of the hub follow-up C-10(b).

Filigree's finding_list / files API suppression filter uses Wardline's SuppressionState vocabulary plus the Filigree-local all sentinel. That filter grammar is pinned by the Wardline-owned vector ~/wardline/tests/conformance/filigree_suppression_filter_contract.json, vendored to Filigree as ~/filigree/tests/fixtures/contracts/wardline-suppression-filter-contract.json.

  • Authoritative: Loomweave ADR-015 Rev 2; ~/wardline/docs/integration/2026-05-29-wardline-weft-integration-brief.md; Filigree scan-results intake in ~/filigree/docs/federation/contracts.md.

5. Qualname normalization — Wardline → Loomweave (Loomweave ADR-018)

Wardline emits a pre-composed dotted qualname as metadata.wardline.qualname = module_dotted_name(file_path) + "." + __qualname__; Loomweave reconciles it to entity IDs/SEIs (owning the catalog that makes qualnames meaningful — doctrine §6).

  • Authoritative: ~/loomweave/docs/federation/contracts.md (§ qualname normalization) + Loomweave ADR-018; Wardline integration brief.

6. Legis governance consumption + git-rename provider seam — Legis ↔ Loomweave

Legis is a pull-only consumer of Loomweave's SEI surface (resolve / resolve_sei / lineage) for SEI-keyed attestations and an audit spine; it re-establishes lineage integrity at its own boundary (SEI REQ-L-01, Option 3). Legis also supplies the git-rename signal via GET /git/renames?rev_range=…; Loomweave consumes it through the typed GitRenameSource / LegisGitRenameSource seam (REQ-C-05). Operative enablement is jointly gated on Loomweave driving a committed rev-range.

  • Authoritative: ~/legis/docs/federation/sei-conformance.md + ~/loomweave/docs/federation/contracts.md (§ legis governance consumption / WS9). See members/legis.md.

7. Legis ↔ Filigree — SEI-keyed sign-off binding

Legis binds governed sign-offs to Filigree issues using the entity-association surface (§1) plus its own signoff endpoints (POST /signoff/request, …/bind-issue, …/sign). Filigree retains issue-lifecycle authority; Legis adds governance.

  • Authoritative: Legis (src/legis/filigree/client.py, signoff binding) + ~/filigree/docs/federation/contracts.md.

8. Legis ↔ Wardline — findings routing through enforcement

Legis routes Wardline findings (POST /wardline/scan-results on Legis) through its 2×2 enforcement cells (chill / coached / structured / protected). The signed Wardline artifact contract carries a required findings key; a present empty list means a clean scan, while an absent/renamed key is malformed and must not silently govern zero findings. Wardline emits the key from src/wardline/core/legis.py; Legis validates it in src/legis/wardline/ingest.py, with the golden vector at ~/legis/tests/contract/weft/vectors/wardline_scan_artifact.v1.json. Trust vocabulary passes through verbatim — "Wardline analyses, Legis governs"; Legis never re-adjudicates trust.

The unsigned dev-artifact path is also a pinned wire contract: Wardline emits top-level dirty: true when scan --format legis --allow-dirty runs on a dirty working tree, and Legis consumes that exact key to distinguish keyless dev governance, configured-CI SKIPPED_DIRTY_TREE, and explicit dev-mode governance. The shared vector is ~/legis/tests/contract/weft/vectors/wardline_dirty_scan_artifact.v1.json (vendored in Wardline as tests/conformance/legis_dirty_scan_wire.golden.json). Wardline owns the emitted key; Legis owns the consumer posture.

  • Authoritative: Legis (src/legis/service/wardline.py, wardline/*) + ~/loomweave/docs/federation/contracts.md (§ trust-vocabulary convergence).

9. Charter preflight-fact envelope — Charter → Legis (Charter ADR-006)

Charter exposes a versioned weft.charter.preflight_facts.v1 envelope (requirement impact, verification freshness, baseline drift, traceability gaps). Legis alone decides enforcement; Charter provides facts only. Designed, adapter pending — no emitter shipped. Canonical namespace is weft.charter.* — landed in charter code on main (commit cbbcb2f, 2026-06-07; 54 weft.charter.* / 0 loom.charter.* in src). Still designed, adapter pending — no emitter shipped. See conflict-register.md §A-12.

  • Authoritative: Charter ADR-006 (~/charter/docs/architecture/decisions/ADR-006-legis-preflight-fact-envelope.md). See members/charter.md.

10. Charter SEI consumer contract — Charter ↔ Loomweave (Charter ADR-005)

Charter stores SEI as an opaque peer identifier on trace links, never minting/parsing; marks links stale on lineage change; falls back to fragile file/symbol refs when Loomweave is absent. Designed, adapter pending.

  • Authoritative: Charter ADR-005 (~/charter/docs/architecture/decisions/ADR-005-clarion-sei-consumer-contract.md).

Filigree HTTP generations (the federation transport)

Filigree publishes named, pinnable HTTP generations; siblings pin to a generation and evolution is by introducing a new generation, never mutating an existing one.

  • classic — the pre-federation surface (mostly un-prefixed /api/…, with a /api/v1/scan-results outlier). Frozen; bug-fixes only. The entity-association routes (§1) live here.
  • weft/api/weft/*, the federation-era generation (unified BatchResponse[T]/ListResponse[T] envelopes, closed ErrorCode enum, composed verbs). Carries e.g. GET /api/weft/changes.
  • Loose cooperation (Filigree ADR-002): every weft-generation endpoint must be fully functional with other federation components absent.
  • Authoritative: ~/filigree/docs/federation/contracts.md + Filigree ADR-002 (~/filigree/docs/architecture/decisions/ADR-002-api-generations-and-federation-posture.md).

The weft generation is a transport/envelope naming discipline — it is not the closed weft:// URI scheme (see uri-scheme.md). Same word, different things; both are catalogued so the collision is explicit.