DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path investigations/loomworks-foray-integration-grounding-investigation-v0_1.md

Loomworks FORAY Integration Grounding — Investigation v0.1

Version. 0.1 Date. 2026-05-29 Status. Investigation / grounding record. Captures the concrete facts about how a future FORAY integration would attach to Loomworks, established by direct reading of the live dunin7-foray SDK, the FORAY protocol/attestation material, and the adapter deep-read. Produced to ground the source-identification (Memory-completion item C) scoping note so it does not re-derive these facts. Provenance. Claude.ai session 2026-05-29, with Claude Code retrieving verbatim source from the M4 (/Users/dunin7/dunin7-foray, /Users/dunin7/dunin7-workforce) and the record's foray-reference/. Operator: Marvin Percival. Relationship to existing docs. Distinct from loomworks-foray-ova-integration-strategy-investigation-v0_1 (which concerns the Loom/FORAY/OVA protocol triangle). This note concerns the concrete SDK contract and the data-completeness requirement it implies. Companion to the record's foray-reference/ deep-reads (protocol, adapter, challenge, primer).


Plain-language summary

This note records what a future FORAY integration actually needs from Loomworks, established by reading the real shipped SDK rather than the protocol spec or demo code. The headline finding: the live dunin7-foray SDK is far thinner than the FORAY v4.1 spec or the Manuka example suggests. Its entire notion of "who did this" is a single free-text string. Everything richer — actor kind, identity, credentials, the held-then-commit chain — has no typed home in the SDK and would travel inside an opaque JSON payload.

The consequence for Loomworks is clarifying, not complicating: Loomworks remains the system of record for the rich actor and provenance model; FORAY anchors a tamper-evident reflection of it. FORAY is a reflection layer, not a system of record — it can only structure and anchor data that already exists. So the design requirement for foundation work is data completeness: every source-and-commit point in Loomworks must natively capture, durably and in Loomworks' own terms, everything a FORAY attestation would need — so that when integration opens, the work is deriving the FORAY call from existing data, not discovering the data was never captured. This note states what that data is, against the real SDK surface.

It also records the FORAY attestation conceptual model (what attestation proves and does not prove), and the adapter finding (the demo adapters are not the integration target; the live in-process SDK is).


1. FORAY is a reflection layer, not a system of record

The load-bearing principle, from the FORAY adapter material (foray-reference/foray-adapter-deep-read-v0_1, 2026-05-24) and the live integration documentation: FORAY does not create, modify, or insert data. It reads what a source system already holds, structures it, and anchors a tamper-evident reflection. "FORAY can only organize, structure, and anchor data that already exists in your systems."

This sets the entire design posture for Loomworks. Loomworks does not bend its native data model to FORAY's shape. Loomworks perfects its own record — who asserted what, under what authority, when — and a future FORAY integration reflects that record. The work of "preparing for FORAY" is therefore making the Loomworks record FORAY-complete: ensuring the data a reflection needs is present and durable, and marking the points where the reflection will be emitted. It is not building FORAY structures inside Loomworks (a pattern the substrate-hygiene cleanup arc already removed).

2. The integration target is the live in-process SDK, not the demo adapters

There are two distinct things called "adapter" in FORAY material, and conflating them designs the wrong thing:

The integration target is the second. The steer (from the adapter deep-read's Loomworks-implications section, and confirmed by reading the live code) is application-layer integration: the Loomworks engine imports ForayClient and calls it inline at lifecycle events, the way dunin7-workforce does. There is no separate adapter process; the application is the adapter. The Kaspathon createArrangement-style code is descriptive illustration, not a deployment template.

3. The real SDK contract (dunin7-foray v3.0.0)

Verbatim from /Users/dunin7/dunin7-foray/lib/foray-client.mjs (373 lines), read 2026-05-29.

3.1 The write surface


emit(chainId, eventType, triggeredBy, payload = {})

attest(chainId, attestation)

attest() is a thin wrapper over emit(). It does no validation and enforces no schema. It reads attestation.attestor (falling back to 'system') for the actor string, then stores the entire attestation object verbatim as the JSONB payload under event_type = 'attestation'. The documented attestation shape is a JSDoc literal only: { type, attestor, attestor_type, subject_refs, outcome, summary, evidence, metadata }.

3.2 The storage schema


CREATE TABLE IF NOT EXISTS foray_events (
  id             SERIAL PRIMARY KEY,
  frame_id       TEXT        NOT NULL,
  sequence       INTEGER     NOT NULL,
  event_type     TEXT        NOT NULL,
  triggered_by   TEXT        NOT NULL,
  payload        JSONB       NOT NULL DEFAULT '{}',
  prev_hash      TEXT        NOT NULL,
  hash           TEXT        NOT NULL,
  hash_timestamp TEXT        NULL,
  created_at     TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  UNIQUE (frame_id, sequence)
);

3.3 The read surface (attestations)

getAttestations(chainId, {type, attestor, outcome, limit, offset}), getAttestationsFor(chainId, subjectType, subjectId), getAttestationsByType(chainId, type), getAttestationsByAttestor(chainId, attestor). Retrieval only ever filters on payload->>'type', payload->>'attestor', payload->>'outcome', and payload->'subject_refs' (JSONB containment, where a subject ref is {type, id}). Those four are the de-facto queryable attestation fields; anything else in the payload is stored but not indexed for query.

3.4 The controlled vocabularies (exported, not enforced)

lib/attestation.mjs exports, for callers to use (the SDK does not check payloads against them):

3.5 Obfuscation boundary

The SDK does not hash or obfuscate payload identifiers; it stores the payload as-is. The only hashing it does is the chain-integrity hash (tamper-evidence, not party-obfuscation). Party-identifier hashing or amount obfuscation, if needed, is the caller's responsibility, done before emit/attest. The package provides opt-in helpers (hashObject, subjectRef, evidenceRef) the caller may use.

3.6 Production usage (dunin7-workforce)

One ForayClient per product, resolved via foray.for(product). Real call sites use a small free-text actor vocabulary — role labels, not IDs or structured actors:


forayClient.emit(frameId, 'frame.open', 'conductor', { brief_title, budget_ceiling, requirements_count })
foray.workforce.emit(GOV, 'project.created', 'system', { ... })
forayClient.emit(frameId, 'frame.rollback', 'human', { ... })
ctx.foray.emit(ctx.frameId, 'strategist.estimate_complete', 'strategist', { ... })

attest() is not exercised anywhere in dunin7-workforce — production uses emit() exclusively. So the attestation surface, while present in the SDK, has no live production precedent; Loomworks would be an early/first user of it.

4. The actor gap — the central fact for source-identification

The SDK's entire model of "who" is one free-text string (triggeredBy). Loomworks already has a far richer actor model — ActorRef with kind ∈ {contributor, agent, person, companion}, an actor UUID, instruction_version, and (Phase 45) capability_ref/approval_mode. None of that has a typed home in the SDK.

The implication is not a problem to solve in the SDK; it is a division of responsibility to honor:

This is what "FORAY-complete" means concretely: the Loomworks-native record must be rich enough, at every source-and-commit point, to derive both the triggeredBy string and whatever structured actor/attestation payload a future integration anchors — at any time, including retroactively. If a datum FORAY would want (the model version that produced AI content, the Domain Expert's recognition basis, the commit's WebAuthn attestation) is not captured natively at the moment of the event, the reflection has a permanent hole, because FORAY cannot create data that was never recorded.

5. What FORAY attestation proves — and does not (the conceptual model)

From the FORAY attestation material (foray-reference/foray-protocol-deep-read-v0_1, foray-protocol-primer-for-loomworks-substrate-v0_1), grounded in the Manuka Honey example.

The pivotal framing: FORAY does not certify the honey is Manuka — it certifies that the lab analyzed it, that the certifier certified the lab's analysis, and that the regulator approved the certification for export. Attestation records who made a specific claim, at a specific time, under specific credentials, and that it has not been altered since. It is a Type 2 transaction — claims about reality made by identified parties.

| Attestation proves | Attestation does NOT prove | |---|---| | A specific party made a specific claim at a specific time | The claim is true | | The claim has not been altered since anchoring | The attestor is competent | | The attestor's credentials are recorded | Physical reality matches the digital record |

Two structural facts that matter for Loomworks:

6. The honest boundary of what this foundation provides

Source identification plus FORAY-completeness gives accountability and tamper-evidence — who asserted what, under what authority, unaltered, with a chained trajectory through to commit. It does not give correctness (that the claim is true) or competence (that the source was qualified). That boundary should be stated wherever the foundation's value is described, so it is not overclaimed.

7. What this note settles for the source-identification (item C) scope

  1. Target is the live in-process SDK (ForayClient.emit/attest), called application-layer inside the engine — not the demo adapters, not blockchain anchoring (which dunin7-foray v3.0.0 does not yet implement).
  2. Loomworks stays the system of record for the rich actor model; FORAY reflects. Do not bend the native model to the SDK's thin shape.
  3. "FORAY-complete" = data completeness at every source-and-commit point, sufficient to derive triggeredBy + a structured payload at any time, retroactively included.
  4. Held-then-commit is an attestation chain (contribution event → commit event referencing it).
  5. Source-kinds map to attestor types/acts; AI is barred from the commit/approval attestation by the existing five-layer enforcement.
  6. No dependency on dunin7-foray is taken in item C (option (a)): item C ensures data completeness and places reserved-location seams; the actual ForayClient wiring is a later, separately-scoped FORAY-integration phase.
  7. Obfuscation is a caller concern, deferred to the integration phase; item C need only ensure the un-obfuscated source data exists to be obfuscated later.

8. Open items this note does not settle


Changelog

v0.1 (2026-05-29). Initial grounding record. Captures the live dunin7-foray v3.0.0 SDK contract verbatim, the reflection-layer principle, the adapter finding (demo vs. live target), the actor-string-vs-ActorRef gap, the attestation conceptual model from the Manuka example, and the seven items this grounds for source-identification scoping.


DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks FORAY Integration Grounding — Investigation v0.1 — 2026-05-29