Version. 0.1
Date. 2026-08-19
Status. Discovery arc — read-only repo investigation, executed per loomworks-boundaries-arc-cc-investigation-brief-v0_1.md. Nothing was modified in any repository; this document is the sole output.
Executed by. Claude Code (Fable 5), in the workspace holding the repositories. Operator: Marvin Percival.
Method. Direct reads plus five parallel read-only exploration passes (one per brief section A–E); section F answered by direct reads. Every finding cites repo, file path, and line range. Findings without a citation are marked as guesses.
| Repo | HEAD | Date | HEAD commit subject |
|---|---|---|---|
| foray | ad60eed | 2026-08-19 | docs: validation scope decision sheet v0.4 — R2 ruled PERMIT |
| foray-api | 19d5a74 | 2026-08-19 | docs: carry-forward register v0.4 — CF-10 and CF-11 opened |
| loomworks-engine | eb9392f | 2026-08-17 | CR-2026-225 post-merge: CI Postgres image gains pgvector |
| loom | a3ef64e | 2026-04-15 | Initial commit: Loom Protocol repo scaffold |
| grantha | 0292dcd | 2026-07-15 | grantha: ratification notice v0.2 — VERIFY-1 resolution folded in |
| loomworks-record | b2721e0 | 2026-08-18 | FORAY audit coverage: FORAY's response filed; proposal v0.3 + request v0.3; build list v1.05 |
| stele-agentic-id (supplementary, B6) | 4a87c1e | 2026-07-16 | V2 Cycle 5 — Revocation Enforced End-to-End |
| stele (supplementary, B6) | 689de41 | 2026-07-18 | Release v0.4.0 — multi-origin ceremony support |
Scope note that governs all of Section A. /Users/dunin7/foray is the specification, governance-record, and public-site repo plus one narrow reference verifier. The producing/validating/anchoring implementation lives in the sibling repo /Users/dunin7/foray-api, which the spec repo names as the reference implementation (foray spec/FORAY_Verifier_Specification-v0_2.md:13; foray verifier/README.md:10). The brief said "the FORAY implementation in our repos" — answering A1–A6 honestly required reading both, and every citation below is labelled by repo. Additional sibling FORAY repos exist (foray-build, foray-kaspathon, foray-protocol, foray-protocol-db, foray-worker, dunin7-foray, dunin7-foray-validate) and were not investigated.
Direct answer: 4.2 — but the emitting/validating code lives in foray-api, not foray. 4.1/4.0 remain accepted through a permanent legacy-conversion arm.
Citations.
foray spec/schema/foray-transaction-v4_2.schema.json:25 — "schema_version": { "const": "4.2" }; $id at line 3 is https://foray.dunin7.com/schema/foray-transaction-v4_2.schema.json. Published copy at site/spec/foray-transaction-v4_2.schema.json.foray spec/amendments/FORAY_Protocol_v4_2_F_Wire_Migration_Amendment-v0_7.md:5 — "Status: ACCEPTED — in force as of 2026-07-24."foray-api lib/foray-validate-4-2.mjs:504 — export function validateForay42(json, opts = {}); :577-600 — validateForayDual() routes '4.2' natively, '4.1'/'4.0' via the legacy arm with labels = ['legacy'].foray-api lib/foray-generate-4-2.mjs (1220 lines, the 4.2 emitter); lib/foray-migrate.mjs (migrateV41toV42).foray-api foray-worker-v0_19.js:27 (imports validateForayDual), :2751 (route list: "Validate a FORAY transaction JSON: 4.2 natively, 4.1/4.0 via the permanent legacy conversion arm")."schema_version": "4.2" (foray skill/acceptance/wire-4_2-v1_0/*.json:2).
Elaboration. The WP-1 reference verifier in the foray repo does not know 4.2 exists — it is an anchor proof-bundle verifier (Merkle path, ABH, chain lookup), not a record validator; grep schema_version verifier/lib/*.mjs returns nothing. Drift flag: foray transaction-types/index.json:5 records "validator": "/api/validate-foray, foray-api v0.7.0" and every published transaction type as "validated_against": "foray-api v0.7.0" — a pre-4.2 validator (see Surprises).
agent_activity_record with Arrangements/Accruals/Anticipations/Actions?
Direct answer: No — published-spec-and-exemplar only. No code in either repo knows agent_activity_record exists. This is partly by design: governance runs through the four standard components with zero special fields, so there is nothing type-specific to implement — and correspondingly nothing type-specific is implemented or enforced.
Citations.
foray skill/acceptance/wire-4_2-v1_0/exemplar-5-governance-agent-activity.json — the full worked record: "F26": "agent_activity_record" (line 7); authority-grant Arrangement "F4": "authority_grant" (line 12) with Principal/Agent in F5 and artifact digest in F29 (line 22); policy-evaluation Accrual with "F18": "hash_2b7e1a9c4f6d80351927c5e8a0b3d6f1" (line 31); Anticipation "F4": "expected_agent_behavior" (line 41); Action "F15": "verdict_pass" (line 54).foray scripts/regenerate-site-examples.mjs:158 — "Governance events run through the same four components with zero special fields."foray docs/decisions/foray-root-naming-ratification-decision-sheet-v1_1.md:96 — the column mapping (grants → Arrangement; policy evaluations → Accrual; expected behaviors → Anticipation; verdicts → F15; attested artifacts → F29).foray spec/schema/foray-transaction-v4_2.schema.json:46 — "F26": { "type": "string" }, no enum; :43 and :169 — F15 is an unconstrained string (no verdict vocabulary); :126-129 — F18 is structurally enforced ("pattern": "^hash_[0-9a-f]{32}$", with the F-18 rider comment "proves definition retention, never execution correctness"); :141-158 — Anticipation requires only id/F22/F23 (the "E4 posture": F27/F28 optional so the validator can name the culprit).agent_activity_record across both repos: hits only in .json exemplars, .md/.html docs, one generated site page. Zero .mjs/.js hits.
Elaboration. The remaining work is named in the record itself: foray docs/decisions/foray-root-naming-ratification-decision-sheet-v1_1.md:96 lists "attestation code lists for F15 (crosswalk open item 6)" and a "general-audit coverage pass — verify the catalog expresses Stele/GRANTHA/Loomworks/OVA operational events in practice… sequenced after migration." F15's verdict code list is catalog-governed (docs/design/foray-root-data-set-v0_7.md:195) and the code list is not in the repo. For Boundaries: the wire can carry a governance record today, but nothing rejects a malformed one at the type level — a "governance record" is any record whose F26 happens to say so.
**Direct answer: Partially — the continuity walk is implemented (verifier-side, consuming externally supplied history); the stream registry and producer-side stream encoding are not; stream scope (per-engagement / per-subsystem) has no vocabulary, schema field, or code anywhere — declaring one today is not implementable.**
Citations.
foray verifier/lib/streams.mjs:28-41 — walkContinuity(history) returns exactly 'GAP' | 'FORK' | 'CONTINUOUS' (GAP on cur.seqNo !== prev.seqNo + 1; FORK on cur.prevTxHash !== prev.txHash); :44-51 — walk runs only with stream_context present or audit mode; :71-79 — LATE_RECORDED labelling. Replay/duplication on (stream_id, seq_no): verifier/lib/registry.mjs:66-80.foray verifier/README.md:41 — "This verifier does not maintain a submitter registry, a stream-history store, or a repository — it consults an externally-supplied verification context… out of scope for WP-1." verifier/lib/streams.mjs:17-18 and verifier/lib/registry.mjs:3-12 mark the context shapes as reference choices, not spec-defined formats.foray spec/amendments/FORAY_Protocol_v4_1_3_Batch_Anchoring_Amendment-v0_21.md:333 — "a consumer declares stream_id, scope, and a continuity commitment." The word scope has no enumeration anywhere. :345 — the registry is itself designed as a FORAY registered stream (KEY_REGISTER/KEY_ROTATE/KEY_REVOKE/DISPUTE) — design only.foray-api lib/foray-abh.mjs:9-11 — "stream_segments[] encoding (§4 of the spec) is not implemented here"; :29 — every ABH is cut with an empty stream_segments[]. Grep for stream_id|seqNo|prev_tx_hash|stream_segments across foray-api/lib/ and the worker yields only those two comment lines.
Elaboration. Do not conflate registered streams with batch-lane chaining, which IS built: foray-api lib/batch-accumulator.mjs:143-149 chains per-lane batch headers by windowId + prevHeaderHashHex — that is anchoring-layer chaining, and the amendment states explicitly it activates no stream machinery (…-v0_21.md:50 — "no new wire field, no ABH format change, and specifically no activation of stream_segments"). The governing decision sheet acknowledges the split: foray docs/decisions/foray-validation-scope-decision-sheet-v0_4.md:80 — registered streams are "something a consumer declares," the continuity walk is "auditor mode."
**Direct answer: Partially — two-tier batch aggregation (per-client Tier-1 ABH beneath a Tier-2 aggregate) is fully implemented in foray-api, but dark and externally unreachable. Aggregation tiers for stream routing do not exist; the only routing rule is a spec-level rate gate for direct anchoring.**
Citations.
foray spec/amendments/…v4_1_3…-v0_21.md:50 — "§5.5 is added — client-attributable batching, a per-client Tier-1 level-0 ABH beneath a Tier-2 aggregate ABH over client header hashes"; §16 item 3 (per-domain sub-roots at Tier 2) moved to "DESIGN-RATIFIED, unbuilt", with domain instantiated as client. :84 — the only routing rule: direct anchoring permitted only for registered streams at ≤1 write/min sustained, direct-mode capped at 25% of the §9 budget. :266 — the ANCHOR-ATTRIB vector family has no coverage.foray-api lib/tier2-aggregator.mjs (619 lines) — resolveTier2Cap (:76), assertCountedSubCommitment (:116), clientHeaderHash (:184), acceptClientHeader (:264), cutAggregate (:377), buildOpenings (:468); lib/batch-sizing.mjs (cap menu, default 1024); DO routes /client/register-lane, /tier2/configure, /tier2/open/<lane>, /tier2/closed/<lane>/<windowId> at foray-worker-v0_19.js:1401-1413; tests test/tier2-aggregator.test.mjs, test/tier2-glue.test.mjs.foray-api foray-worker-v0_19.js:1399-1401 — "DO-internal, like every batch route: no external Worker route reaches the DO at all." foray-api wrangler.toml (v0.17 changelog) — "BATCH_MODE / UNIFIED_ANCHOR_PATH remain unset in EVERY environment… DISCHARGING CF-4 DOES NOT AUTHORIZE ARMING."
Direct answer: There is no validated commit path to bypass — the validator and the commit path have never been connected. FORAY's production ingestion route (POST /api/anchor in foray-api) commits opaque bytes with NO validation of any kind; POST /api/validate-foray is advisory and stateless. A cop would be a new gate, not a change to an existing one. The foray repo itself has zero write paths.
Citations — foray repo (zero write paths). Complete executable-file inventory (21 files): the WP-1 verifier is a read-only CLI (verifier/foray-verifier.mjs); scripts/ and tools/ write only site HTML/manifests; adapters/quickbooks-adapter.js and adapters/salesforce-adapter.js map to FORAY shape in memory and require('./foray-sdk') which does not exist in the repo (dead code, marked demonstration-only at quickbooks-adapter.js:6-10); web/legacy/ servers are retired. The deployed foray-site Worker has no code at all — wrangler.jsonc:26-31 serves site/ as static assets with no main script.
Citations — foray-api (the real path). Sole export default { fetch } route table at foray-worker-v0_19.js:2707-2754:
| Route | Handler | Validates? | Persists? |
|---|---|---|---|
| POST /api/generate-foray | handleGenerateForay (:998) | yes — on its own LLM output (:1190) | no |
| POST /api/validate-foray | handleValidateForay (:1279) | yes (:1304) | no — returns a verdict and forgets |
| POST /api/wp2-anchor-test | handleWp2AnchorTest (:2489) | no | signs + enqueues |
| POST /api/anchor | handleAnchorPost (:2584) | no | KV put + sign + enqueue |
| GET /api/anchor/<txHash> | handleAnchorGet (:2673) | n/a | read |
POST /api/anchor trace (foray-worker-v0_19.js:2584-2668): :2585 gate on ANCHOR_MODE !== 'on' → 404; :2588 authenticateAnchorConsumer — a single shared bearer token, constant-time compared (:2576-2582; per-consumer credentials an open item, :2568-2571); :2610-2616 size (1 MiB) and empty-body gates; :2618 the Worker computes SHA-256(body) itself; :2653 ANCHOR_BODY_STORE.put(txHashHex, bodyBuffer, { expirationTtl: 2592000 }) — the only durable record write; :2655 → signAndEnqueueAnchor (:1337-1352) → ANCHOR_SIGNER DO /sign (:1479 enqueue). No schema check is invoked anywhere on the path. The body is opaque bytes (:2555-2557 — "stores the body in KV keyed by that hash"); a 1-byte non-JSON blob anchors identically to a conformant 4.2 record.
Where the cop wires in — one seam per path:
foray-worker-v0_19.js:2616 (gates complete) and the true commit boundary at :2653 (the KV put — the code's own point of no return: ":2649-2652 — a storage failure throws here… before anything is ever signed or enqueued"). A veto immediately before :2653 and before the parallel put at :2626 (the UNIFIED_ANCHOR_PATH === 'on' branch — a second, separate commit site inside the same handler) covers the whole direct path.AnchorSigner.batchAdd (foray-worker-v0_19.js:1554), before acceptRecord (lib/batch-accumulator.mjs:54). batchAdd takes bodyHex as an opaque parameter (:1561) and never inspects it either.acceptClientHeader (lib/tier2-aggregator.mjs:264) consumes headers, not records — a record cop has nothing to say there.Every entry point that can commit (exhaustive, tests excluded):
POST /api/anchor → handleAnchorPost (:2584) — no validation; gated by ANCHOR_MODE.POST /api/anchor with UNIFIED_ANCHOR_PATH === 'on' → second branch at :2624-2647 with its own put at :2626. Unset in every environment today.POST /api/wp2-anchor-test (:2489) — no validation; gated by ANCHOR_MODE.POST /batch/add → batchAdd (:1554) — no validation; DO-internal, no external route (:1399-1401).POST /direct-unified (:1389) — reached only from (2).POST /sign (:1423-1436) — accepts a bare 32-byte hash; no record context exists by this point./custody/configure, /client/register-lane, /tier2/configure (:1392, :1401, :1404) — DO-state writes, not records.cutBatch (lib/batch-accumulator.mjs:149) and cutAggregate (lib/tier2-aggregator.mjs:377), which since Brief 19/CF-4 also enqueue in the same serialized operation. A non-request-initiated commit path: a cop living only in fetch handlers does not cover it.lib/batch-broadcast-job.mjs, broadcaster/ — downstream of commit.scripts/purge-anchor-job.mjs — operational removal of a queued job.POST /batch/sign-enqueue — REMOVED at v0.19 (:1383-1386) because "a second producer of anchor jobs is the shape that let CF-1 arise" — the closest existing artifact to the single-choke-point discipline this question asks about.Direct answer: Two readings, two answers. As "an approval ceiling in F7 on an authority-grant Arrangement": No — the wire can carry it, nothing defines or checks it, and F7 has no per-family measure semantics anywhere. As the COUNTED-SUB-COMMITMENT discipline: Yes — implemented, but it is about batch leaf counts, not approval ceilings.
Citations — reading 1 (not implemented).
foray spec/schema/foray-transaction-v4_2.schema.json:89-100 — Arrangement requires id/F4/F5/F11; F7 (WireNumber) and F8 optional. The only F7 enforcement is the magnitude shadow (:73-76, ±1e15 exclusive).skill/acceptance/wire-4_2-v1_0/exemplar-5-governance-agent-activity.json:12-23, "F25": {"grant_scope": "production deploy of service worker, single release window"}.foray docs/design/foray-root-data-set-v0_7.md:41 (F7 = "Amount, decimal" — one row, no ceiling notion), :137 ("F7 is not 'amount' on the wire — it is F7"), :142 ("the catalog entry defines it once"), :195 (closed code lists are catalog-governed for F4/F15/F16/F17 only — F7 absent). Grep for ceiling|approval limit|credit limit|bounded across transaction-types/ and the Root v0.7: nothing.docs/design/foray-root-data-set-v0_7.md:61 — "F25 is the floor-not-ceiling valve… not Root-validated").Citations — reading 2 (implemented).
foray spec/amendments/…v4_1_3…-v0_21.md:212 — "A sub-commitment passed upward to any higher level MUST be a full ABH carrying its own committed true_leaf_count. A bare tree root passed upward without a count is structurally illegal." Also :285, :50.foray-api lib/tier2-aggregator.mjs:116-135 — assertCountedSubCommitment(header) throws naming COUNTED-SUB-COMMITMENT on a naked root or a header missing any of the eight required fields incl. trueLeafCount (:100-109); :218 — assertOwnCountCommitted. Covered by test/tier2-aggregator.test.mjs. Gap: the negative conformance vector for this rule is in the unauthored ANCHOR-ATTRIB family (…-v0_21.md:266)._AGENT_KINDS: shape, call sites, and does it still match "one limit type, blocking, in the commit path"?
Direct answer: Partially. One limit type — yes. Blocking — yes. In the commit path — NO, and there is no evidence it ever was: it gates the model-room spend path (LLM complete() calls), not the memory-commit path. What changed since CR-2026-098 v0_3: _AGENT_KINDS is no longer a local literal — CR-2026-120 Step 4 re-pointed it at the shared NON_HUMAN_ACTOR_KINDS constant, unifying vocabulary with the commit/discard gate while the two gates remain separate enforcement points on separate paths.
Citations. All paths under loomworks-engine.
src/loomworks/credit/authorization.py:26 (import), :28-33 (_PERSON_KINDS, _AGENT_KINDS = NON_HUMAN_ACTOR_KINDS); src/loomworks/memory/base.py:23-30 — NON_HUMAN_ACTOR_KINDS = frozenset({"agent", "companion"}) with the cross-reference comment ("so the gate and the spend gate carry one definition of 'non-human actor'")._AGENT_KINDS (module-private, two in-file uses): credit/authorization.py:120 (is_spend_authorized), :130 (required_tier_for_kind) → credit/gate.py:35-38, :87-99 (GateDecision(refused=True, reason="unauthorized")) → credit/room_gate.py:27, :189-194 (the single production invocation, inside gated_room_complete). No other production caller of gate_room_spend exists.agents/shaping.py:310-311, :575; agents/render_specialist.py:309-310, :998; engagement/manifestation_organization.py:418; api/routers/manifestations.py:343, :391 (HTTP 402); skills/seed_extraction_core.py:258; api/routers/seed_extraction.py:62.credit/authorization.py — exactly two commits: 51e657a (CR-2026-120 Step 4: close commit/discard gate to non-human actors) and d7a8a2d (Phase 64 Step 5: split person/agent spend authorization).
Elaboration. One dimension only: a boolean per tier (person_spend_authorized, agent_spend_authorized) on credit.engagement_spend_authorization, both defaulting False with no row (authorization.py:43-68) — no rate limit, budget ceiling, or window (the tier-cascade at gate.py:101-109 is a balance check, not the authorization limit). The gate is a hard pre-spend stop (gate.py:1-27 docstring: "the PRIMARY, PRE-SPEND control for the three model-rooms"). The memory-commit path has a different, independent gate — the NON_HUMAN_ACTOR_KINDS human-authority check at engagement/assertions.py:284, engagement/creation.py:905/:959, api/deps.py:1250. The shared frozenset is the likely source of the "in the commit path" conflation. Design v0_2 should treat these as two chokepoints, not one.
Direct answer: Yes — records are actively written today, rule is in fact the DEFAULT decider kind, and rule-kind records are read back downstream. Two production writer entry points exist.
Citations. All under loomworks-engine.
DecidedBySchema — src/loomworks/api/schemas.py:3929-3983: kind: Literal["rule","contributor","agent","companion"] (:3936), rule_set_ref (:3944), matched_predicate_index (:3952), actor_id (:3960), actor_kind (:3968), actor_instruction_version (:3976).BoundaryRecordResponse — schemas.py:3986-4071: boundary_record_id, version, channel_ref, raw_material, arrival_timestamp, decision: Literal["admit","route","set-aside","deferred","retrieval-triggered-consideration"] (:4012), decision_rationale, decided_by, raised_by_actor_id/kind, routed_to, rule_set_ref, rule_set_version. List response at :4074-4082.src/loomworks/engagement/types.py:380-405: RuleDecision / ContributorDecision / AgentDecision → DecidedBy (:405); BoundaryRecord.decided_by at :581. Discrepancy: the wire schema admits "companion" (:3936) but the substrate union has no CompanionDecision variant — the wire contract is wider than anything the substrate can produce.src/loomworks/engagement/boundary.py:769-830 (_record_boundary_record, event_kind="boundary_record_created" at :812); second writer :835-905 (resolve_deferred_record, ContributorDecision at :862, event_kind="boundary_record_resolved" at :893). Dispatcher execute_admission_outcome (:100-199), rule as default at :127-130 (decided_by_override or RuleDecision(...)); all five outcome paths write (:228, :338, :487, :529, :645).engagement/channel_types/direct_input.py:67-84 — no override, so every direct-input record is kind="rule"; reached from POST /engagements/{eid}/channels/{cid}/material (api/routers/material.py:148-196). (2) agents/retrieval.py:128-147 — AgentDecision override at :136.engagement/considerations.py:1618, :1651-1666 — SQL on decided_by->>'kind' = 'rule', extracting rule_set_ref id and matched_predicate_index.Direct answer: Yes — executed and landed, in three places, with test coverage.
Citations. All under loomworks-engine.
fe6edc9 (CR-2026-128 — retract boundary Finding 1b), 3f87d45 (Commit 1, behavioral), f33bd9d (Commit 2, coverage).src/loomworks/engagement/assertions.py:96-100 (AgentCannotRetractError, docstring naming CR-2026-128 Finding 1b) and :512-518 — if actor.kind in NON_HUMAN_ACTOR_KINDS: raise AgentCannotRetractError(...), placed before the rationale check.src/loomworks/api/routers/assertions.py:512-518 — retract route depends on get_committing_resolved_actor ("retract is human-authority, same gate as commit (241) and discard (277)"); the dependency 403s non-humans at src/loomworks/api/deps.py:1250-1254 ("Commit requires a human actor (R-B20)").src/loomworks/orchestration/router.py:4218-4242 (retraction + delegation revocation re-routed: Companion proposes; the Operator's confirmation performs the durable act as human_actor), :4244-4248, :4349-4360.tests/test_cr_2026_128_retract_boundary.py (whole file); tests/test_phase_45_delegation_conversation.py:260-266.
Elaboration. Retract now sits in the identical enforcement lane as commit (assertions.py:284) and discard (assertions.py:601) — three symmetric guards on one shared frozenset plus the shared HTTP dependency. Delegation revocation is gated behaviorally (propose→confirm) rather than type-level, since it flows through assertion retraction underneath.
Direct answer: No. Every emission site calls a deliberately no-op function that writes a debug log line — without the payload — and returns. No local store, no HTTP client, no queue, no SDK dependency.
Citations. All under loomworks-engine.
src/loomworks/foray/reserved_emit.py:26-35 — the entire body of _foray_reserved_emit(event_kind, payload) is logger.debug("FORAY reserved emit (no-op today): kind=%s", event_kind). The payload is accepted and discarded. Module docstring :1-17: "Today: no-op (debug log only). Tomorrow: writes the attestation to the FORAY substrate via the dunin7-foray SDK."src/loomworks/foray/__init__.py:1-21 — exports only _ANCHOR_PRIORITY and _foray_reserved_emit; the whole package is ~158 lines. Priority registry (data only): src/loomworks/foray/anchor_priority.py:30-99 — 25 event kinds mapped critical/high/standard/low, including the three CR-2026-157 credential events (contribution_credential_issued/claimed/revoked, :85-100).{event_id, anchor_priority} at the single memory-events write site src/loomworks/memory/events.py:266-279; credit-flow shape (7 fields: flow_id, transaction_id, asset_id, quantity, from_party, to_party, turn_event_id) at credit/room_consumption.py:36-56, credit/flows.py:120-134 (issuance), :182 (provisioning), :300-315 (consumption_token), :362 (consumption_credit), :409 (suspension), :445 (reactivation), :480 (deletion), :531 (balance_zeroing), :641 (referral_credit), credit/proposal_applier.py:432-433 (corrective).orchestration/conversation_turns.py:261, api/routers/me_settings.py:163, orchestration/tune_setting.py:543, :669 — the FORAY_RESERVED_LOCATION marker convention (reserved_emit.py:6-11) is not uniformly honored.src/loomworks/foray/: 5080ff9, 87bec47, 5354812, 1785bab, cb791e1 — all scaffolding or registry data. The emitter has never been non-no-op.
Elaboration. Where records go: nowhere — they terminate in a debug logger. Naming hazard: CorrectiveForayFlow / CorrectiveForayFlowRenderSpecialist (credit/specialists.py:127-150, credit/proposal_applier.py:314-432, credit/bootstrap.py:332-370) are Loomworks-internal credit-reconciliation artifacts, not FORAY substrate records; the DB table was renamed foray_action_flows → flows (credit/models.py:11, :65).
Direct answer: No. Nothing on any commit path answers "would this succeed?" without committing. The two nearest analogues are not commit paths.
Citations. Searched preflight, dry_run, dry-run, simulate, validate_only, check_only, would_succeed, precheck, what_if, no_commit, rehearse, trial_run, plan_only across loomworks-engine/src.
dry_run — one implementation, credential re-encryption tooling, not a commit path: src/loomworks/credentials/migrate.py:106, :111-116, :147, :162.preflight — two hits, neither a runtime capability: src/loomworks/api/routers/me_lifecycle.py:99 (comment: "The frontend's own 'are you sure?' modal is the preflight" — deliberately no server-side one) and docs/cr-2026-225-preflight-audit-v0_1.md (a human document review — a naming collision, not code).validate_only/check_only/would_succeed/etc. — zero hits in src/.ManifestationPreview / preview_manifestation (src/loomworks/engagement/manifestation.py:145-202, :395-483; route api/routers/manifestations.py:355-400 — "Shows what deriving a Manifestation now would cover, without writing anything"). It answers "what would be covered," not "would this succeed"; it is scoped to Manifestation derivation only; and it spends real credits through gate_room_spend (can 402, manifestations.py:391-400).
Elaboration. Practical consequence: the human-authority gates (B3), the spend gate (B1), and the step-up gate (engagement/step_up_policy.py; creation.py:911) are discoverable only by attempting the action and catching the raise/403/402. Nothing composes them into an ahead-of-time verdict. The Boundaries preflight capability is greenfield.
Direct answer: Partially. Every action carries a frozen ActorRef with a kind discriminator — but there is no per-agent identity object, no persisted purpose field, and no freeze state in the engine. Agent identity is a ContributorRow with kind='agent' plus, in several cases, a hardcoded sentinel UUID constructed inline. A genuinely Stele-shaped per-agent lifecycle (revocation, reversible clamp) exists in the sibling repo stele-agentic-id — which nothing in the engine imports.
Citations. All under loomworks-engine unless noted.
ActorRef — src/loomworks/memory/base.py:96-153: kind: ActorKind (Literal["contributor","agent","person","companion"], :22), id: UUID, instruction_version: int | None (":147 — 'required when kind == agent'" as a comment, NOT enforced), display_name, capability_ref (delegation assertion id, :152), approval_mode (:153). Frozen (:143). Attaches via Provenance.wasAttributedTo (:194), required on every MemoryObject (:216); sanctioned exception legacy_unresolved_actor() (:156-171, sentinel at :61, 30-line rationale at :32-60).src/loomworks/api/deps.py:1060-1081 (ResolvedActor), resolver at :1084-1120+. Bearer-token agents get instruction_version=1 hardcoded — a Phase-3 carry-forward (deps.py:1099-1104). Non-member path: CredentialActor (deps.py:1264-1274).ContributorRow — src/loomworks/contributors/models.py:52-92; constraints (:64-79): kind IN ('human','agent'), agents must have bearer_token_hash IS NULL, commit_authority = false OR kind = 'human' (agents structurally cannot hold commit authority at the DB level). No purpose column, no state/freeze column, no instruction_version column.src/loomworks/agents/standard_agents.py:24-41 — StandardAgent(display_name, purpose), two catalog constants; :9-17 — "the durable identity that survives a re-instantiation is the display name + purpose, not the row id." Purpose is never persisted on the row and never carried onto an ActorRef.agents/render_dispatch.py:110-114 (RENDER_AUTO_TRIGGER_SYSTEM_ACTOR; :99 — textual actor_kind='system' lands as kind='agent' because no system kind exists); credit/grant_decision_dispatcher.py:68-72; credit/specialists.py:74-78 (unused at runtime per :67-73); credit/form_submitter.py:43-46 (FORM_SUBMITTER_ACTOR, kind="contributor" chosen at :16-24 explicitly so the commit gate would let it through); engagement/bootstrap.py:48 (_BOOTSTRAP_ACTOR, used at credit/proposal_applier.py:229, :246); also agents/render_specialist_bootstrap.py:79,148,255,293; engagement/seed_induction.py:215.src/loomworks/stele/actor.py:41-63 — actor_from_companion → ActorRef(kind="companion", id=<the person's UUID>); no separate companion table (:45-49). Companion authority provenance rides capability_ref + approval_mode on delegation-flow writes only (memory/base.py:119-141).src/loomworks/stele/actor.py:14-15 — "Agent-actor construction (kind='agent') has no single constructor and is not part of Stele's Phase 2 surface." The external stele package (/Users/dunin7/stele/src/stele/registry.py:26-43, Principal: id, display_name, auth-lifecycle timestamps) is a human-identity model only — no agent concept, no purpose, no freeze.src/ for freeze|frozen_at|freeze_state returns only immutability config (frozen=True). The nearest lever is engagement-scoped agent_spend_authorized = False (B1), which blocks spending, not acting.stele-agentic-id (HEAD 4a87c1e, 2026-07-16), verified directly: per-agent identity roots with lifecycle exist there. packages/agentic-id/src/agentic_id/registry.py:76 (class Registry), :214-243 (revoke → status='revoked', WAL lifecycle.revoked, critical-class immediate commitment), :264-266 (statement issuance refuses CLAMPED for clamped roots); packages/agentic-id/src/agentic_id/clamp.py:1-40 — ClampController, "a reversible, machine-speed narrowing of an agent's grant state… not revocation… GRANTHA lane 1", with fail-closed reachability modelling (REQ-136). A foray_mapping.py module exists in the same package. Nothing in loomworks-engine imports any of it, and it has no purpose field either.
Layer note. The loom repo is an empty scaffold: HEAD a3ef64e is its single commit, containing 2 files (README + one working note, 239 lines total); specification/, reference-designs/, tests/ exist as empty untracked directories, and the commit message says the spec "was not available at initial commit time and will be added when located." The spec lives in loomworks-record/protocols/loom/Loom_Protocol_Specification_v0_1_2026-04-12.md (133 lines). The entire real implementation is inside loomworks-engine, which substantially exceeds the spec (extra transitions discard/redirect, a 14-term relationship vocabulary vs the spec's 6, a fourth assertion state). The engine is the de-facto spec.
Direct answer: Partially — versioned + provenanced + permanently citable: yes, today, at whole-object granularity. Tree-structured: no. Limit trees would need a new assertion shape (or a new relationship term); the spec contains no notion of trees, hierarchy, or nodes.
Citations. All under loomworks-engine unless noted.
src/loomworks/memory/base.py:174-227 — MemoryObject (:202-216) enforces stable id: UUID, version: int >= 1, object_type, engagement_id, created_at, provenance at the Pydantic level; every model frozen=True — non-erasure is structural. Provenance (:186-199) is PROV-aligned (wasAttributedTo, wasGeneratedBy, wasDerivedFrom, wasRevisionOf, wasInvalidatedBy, plus wasConsideredAndRejected).MemoryRef (:174-183) — id + optional version (None = current-pointing; int = version-pinned, the spec's R-A30 distinction). Live route: GET /engagements/{eid}/assertions/{aid}/at-version/{version} (src/loomworks/api/routers/assertions.py:820-822); get_assertion_at_version / get_assertion_history (src/loomworks/engagement/assertions.py:735-800). (assertion_id, version) is a permanently citable coordinate today.Assertion.content is a plain str (src/loomworks/engagement/types.py:294); classification is scalar (grammar_element, normative_force). Grep across src/loomworks for parent_id|parent_ref|children|hierarch|tree|nested|depth|subtree: zero structural hits. AssertionGroup.member_assertion_ids: list[UUID] (types.py:779) is one level deep, non-recursive.Relationship objects (types.py:342-363), each versioned/provenanced/citable, drawn from a closed 14-term vocabulary (memory/base.py:78-93) that is provenance/deliberation-oriented — no containment/parent-of term. :76-77 — order is contract, guarded by a test: "append new terms, never reorder."loomworks-record protocols/loom/Loom_Protocol_Specification_v0_1_2026-04-12.md:27-41 (six required fields), §7.3 conformance requires relationships use the standard vocabulary.
Elaboration — the two routes for limit trees, neither free. (1) Add a containment term to RelationshipVocabulary and build the tree as node-objects + relationship edges — lower friction, and the only route where existing version-pinned citation machinery works unchanged per node; but a spec-level addition, not just code. (2) A new MemoryObject subclass with a nested payload — mechanically easy (Seed, Finding, Channel, RuleSet all subclass), but the whole tree versions as one object and "version 7, node X" would need an intra-object path-addressing scheme that exists nowhere in the codebase. The node-citability requirement favours route 1.
Direct answer: Yes and no — two different lifecycles exist. Assertions: write-time only (every transition writes a new version immediately; no proposal stage). Seeds: a genuine propose → review → commit ceremony exists, production-grade, and is the reusable template for a limit-tree amendment lifecycle.
Citations. All under loomworks-engine.
src/loomworks/engagement/assertions.py:1-10 (transition semantics), add_assertion (:157-231, v1 state='held'), commit_assertion (:232-410), revise_assertion (:411-490 — mints version+1 with wasRevisionOf prior-ref at :447-458 AND writes a second wasRevisionOf Relationship at :477-482), retract_assertion (:491-567), discard_assertion (:568-651 — explicitly not a correction; disposes a never-committed held draft). The held → committed gate is human-only (memory/base.py:24-30; spec §4's "human-attributable confirming party") but held is a draft state of a written version, not an unwritten proposal.src/loomworks/seed_amendments/models.py:32-70 (amendment_class IN ('additive','revisive'), state IN ('draft','committed','diverged')); store src/loomworks/seed_amendments/store.py:80-170; orchestrator amend_seed_with_induction (src/loomworks/engagement/seed_amendment.py:77-193 — revise_seed then loop induct_seed until convergence (zero open findings, :154-173, advances seed_ref) or divergence (:178-185, divergent version pinned as historical memory, seed_ref NOT advanced)); routes src/loomworks/api/routers/seed_amendments.py:115-163 (draft — "Drafting changes nothing; the seed moves only when the Operator commits"), :164-283 (commit, idempotent at :199-205, stale-base 409 at ~:207-222), :326-420 (version listing/fetch). Partial-update payload with required rationale: AmendedSeedFields (engagement/types.py:120-212).src/loomworks/orchestration/correction_check.py:1-160, a lenient LLM pass; its own docstring: "No embedding/similarity infrastructure exists (the semantic-meaning foundation is parked, unbuilt)."Direct answer: Yes — substantially more than partial. Both axes of time travel are implemented, tested, and used in production paths.
Citations. All under loomworks-engine.
state_of_object_at_time (R-A33) — src/loomworks/memory/queries.py:24-58; state_of_engagement_at_version (R-A35, temporally coherent snapshot) — :61-94.src/loomworks/memory/events.py:78-140 (event rows + ObjectVersionConflictError); registry replay-deserializes every type (memory/registry.py:202-214); projector replay invariant "replaying the event log reproduces the view" (memory/projector.py:634, 696, 1139, 1409).tests/test_state_at_version_random_sample.py:1-31 (50 random versions vs ground truth recomputed from the event log, 1000-event fixture); tests/test_state_at_time_random_sample.py; tests/test_cr_2026_158_replay_heal.py:1-28 (poisoned-history red/green proof); tests/test_api_version_chain_walk.py; tests/test_b70_rebuild_reproduces_display_numbers.py.engagement/post_append_dispatch.py:178; engagement/manifestation.py:213, :381.
Elaboration. For a limit tree whose nodes are MemoryObjects in the event log, "show me this tree as it stood at engagement version N" works today for free.
Direct answer: Nothing. Zero lines of executable GRANTHA exist anywhere. The grantha repo is 100% documents; the engine holds two comment-marked seams for a future GRANTHA plus two GRANTHA-shaped-but-not-GRANTHA enforcement columns.
Citations.
grantha repo: 70 files — 38 .md, 32 .html, zero source files, no src/, no manifest, no tests. HEAD 0292dcd and the whole commit stream are document carriage.loomworks-engine src/loomworks/authority/levels.py:18-21, 37-38 ("The GRANTHA seam. resolve_platform_level is the single function that turns an identity into a level… so that GRANTHA can later answer it without any caller changing") and :147 ("THE SEAM. GRANTHA replaces the body of this function"); src/loomworks/api/deps.py:805 ("so GRANTHA has a seam here when the answer stops being 'anyone signed in'").authority/levels.py (~200 lines, three-value IntEnum from host_account.platform_standing + founder lookup); gates at api/deps.py:763-765, 784-790, 809-815; deps.py:799-806 self-labels "HONEST ABOUT ITS OWN THINNESS… should not be described as new enforcement."src/loomworks/delegation/ (1,297 lines, 6 files). Capability set is exactly four (delegation/schema.py:26-56, TIER_1_CAPABILITIES: produce_specification, produce_artifact, initiate_render, commit_notes). Grant object DelegationContent (schema.py:76-100): capability, scope: "all" | list[UUID], constraints: dict, approval_mode: "per_action" | "pre_authorized", stored as JSON in an assertion in the person's personal engagement. Enforcement: verify_companion_authorization (delegation/authorization.py:98) at three call sites — orchestration/router.py:2426, :2602; notifications/service.py:703.grantha discovery/GRANTHA_DISCOVERY_RECORD-v0_12.md Part K, Decision J5 — it binds to a Stele principal-nature property that does not exist; a placeholder name was explicitly rejected.Direct answer: Partially — fully specified in doctrine, entirely absent from code. The live delegation grant is scoped-but-immortal, unsigned, and un-digested: the opposite of mandate-shaped on three of four axes.
Citations — code (no). loomworks-engine src/loomworks/delegation/schema.py:76-100 against the FORAY 4.2 authority-grant fields: principal/agent — absent as fields (implied by assertion placement); scope — present (engagement-id granularity); window/expiry — absent entirely (grep across delegation/*.py for expiry constructs: zero; a delegation lives until explicit revoke_delegation, delegation/service.py:105); signature — absent (AuthorizationResult, authorization.py:57-70, has four fields: authorized, delegation_ref, approval_mode, reason); artifact digest — absent (no hashing in the package).
Citations — doctrine (yes, precisely). grantha design/GRANTHA_GRANT_CHECK_CONTRACT-v0_2.md (2026-07-12, marked "Design draft, uncommitted"), §3 — the Grant-Check Assertion: GCA = sign_authorizer(capability_ref, principal_ref, audience, effective_scope, state_seq, issued_at, expires_at, nonce). Signed (quorum-held key, §6 item 4); dual expiry — wall-clock expires_at = issued_at + W plus a state_seq backstop (§3 "Replay bounds"); window W a per-grant attribute bounded by system ceiling W_max (§5.2, RECOMMENDED-INTERIM at §5.3); capability_ref opaque ≥64 bytes (A4 floor, ratified cb88884); requested_scope grammar [DEFERRED] (§2) — gated on the §4.1 fork which was subsequently dissolved by the ZK drop (see Surprises); fail-closed §7 ("Nothing extends past expires_at. No stale-serve, no fail-open"). Artifact digest lives not in the GCA but in the anchoring envelope's commitment: "H(event_body)". The clamp guarantee T + P + W + S (§5.1) is the mandate-expiry theorem. None of it is built.
Direct answer: No — in code, zero coupling in either direction. In doctrine, also no — and that is a deliberate, reasoned refusal, not an omission: GRANTHA's ruled position rejects the Arrangement mapping in favour of a uniform blinded envelope, and even that adoption is still OPEN/unruled.
Citations.
loomworks-engine src/loomworks/delegation/action_dispatch.py:27 — "one chokepoint that can FORAY-anchor"); the engine's FORAY emitter is the B4 no-op. foray repo → GRANTHA: grep across all non-doc files, zero hits. Engine → GRANTHA: the two D1 comments only.foray skill/FORAY_SKILL_WIRE-4_2-v1_0.md:254 (the column mapping) and the working exemplar skill/acceptance/wire-4_2-v1_0/exemplar-5-governance-agent-activity.json — ARR_AUTH_GRANT_A17 with F4 authority_grant, F5 principal+agent, F11/F14 window, F25 grant_scope, F29 sha256 digest. The mandate object D2 asks about already exists — on the FORAY side, with no GRANTHA consumer.loomworks-record protocols/grantha/GRANTHA_FORAY_ANCHORING_DECISION-v0_2.md §3a — "the rejection of the reference-chain mapping. Linking each state-change back to an issuance Arrangement via arrangement_refs[] rebuilds a readable grant lifecycle on the audit substrate; salting parties doesn't help because the linkage is the leak." Adopted v0.2 position: uniform blinded envelope, every event transaction_type: "grant_state_change" with commitment: H(event_body); "Nothing on-chain distinguishes an issuance from a clamp from a revocation"; anticipation_refs: [] always empty; "Checks never anchor. Denies never anchor." Eight anchor-worthy events enumerated (§3).grantha design/GRANTHA_FORAY_ANCHORING_DECISION-v0_3.md (2026-07-15) — "The three Operator sheets (§2 adoption, §3a envelope, §5 channel) are restated OPEN, unchanged and unruled — this revision decides nothing."
Direct answer: OVA is a decentralized, privacy-preserving access-control protocol — a yes/no authorizer specified as a based-ZK application on the Kaspa blockDAG. It is a specification project, not a codebase: no OVA implementation repo exists anywhere on this machine. The only running OVA-labelled code is a stub behind a seam inside loomworks-engine (CR-2026-157, "OVA Slice 1"), which is Loomworks's own authorizer, explicitly not OVA.
Plain English. OVA decides who may do what without letting anyone watching the network learn anything about the decision, the requester, or the shape of the permission system. Permissions live in on-chain objects called eggs; decoys (chaff and pooled nest eggs) are serialized byte-identical to real ones, so a full-chain observer cannot tell them apart without the key. A requester submits a zero-knowledge proof that they satisfy the access rules without revealing which rule or who they are; each authorization hop fans out to N addresses, only one real, hiding the permission graph's topology. OVA answers granted/rejected and nothing else — it does not hold the protected data, does not know whether the requester is human or agent, and depends on no identity system.
Citations.
loomworks-record protocols/ova/README.md:1-40 (no separate ova-record repo).protocols/ova/OVA_PROTOCOL_SPEC_V3_2.md:48-56, :60-70; glossary :96-147; tech stack (Toccata / rusty-kaspa v2.0.1) :1-40, :75-90.ova-build-pack-2026-06-22/, stele-ova-source-bundle-2026-06-20/) contain only .md/.html; grep for OVA (word-bounded) over /Users/dunin7/stele/src returns zero (earlier substring hits were "approval"/"removal"); no egg_id/chaff/nest_egg implementation in tessera, grantha, foray-protocol, loom, or stele./Users/dunin7/Downloads/ova_provisional_patent_v3.docx).[ZK-OPCODE], [SCOPEGAS], [SCALE]); the Forge-blessed spec is still V2 (2026-03-09) — re-induction held post-mainnet; running code none; verification is formal-on-paper (Parts I–II complete, III–VII drafted); external blocker Kaspa Toccata hard fork (~2026-06-30) for mainnet ZK opcodes; build plan gates nearly everything on the unrun F-3 design pass (protocols/ova/design/OVA_BUILD_PLAN-v0_2.md:1-45).loomworks-engine src/loomworks/authority/authorizer.py:1-60 ("Option E" — authorize(actor, action, resource, context) → AuthzDecision, default-deny; "when OVA proper deploys, authorize swaps its implementation without callers changing"); src/loomworks/authority/contribution_credentials.py:1-50; routes api/routers/contribution_credentials.py; migration migrations/versions/0103_contribution_credentials.py; merge 3b10ff1 (CR-2026-157, OVA Slice 1 non-member contribution pathway); 16 tests in tests/test_contribution_credentials.py.
**Direct answer: No on all four — and on identity the non-overlap is a named design commitment, not an accident. The real collision risk is not OVA-the-protocol but the two OVA seams already inside loomworks-engine, which own the "may this actor do this action" chokepoint that a Plane 2 design would otherwise duplicate.**
Per concern, with citations.
authority/authorizer.py to the actor-scoped OVA contract.OVA_PROTOCOL_SPEC_V3_2.md:301). If Boundaries wants reasons out of OVA, that breaks OVA's indistinguishability commitment — risk narrative must be built one layer up (the F-4 pattern, E3).loomworks-record candidate-seeds/ova/ova-candidate-seed-v0_1.md:41 — "Depend on no identity layer — OVA must not reach back to Stele or any principal-identity system"; :46 — "Must not know or branch on principal nature"; :69-77 ("the fence") — "OVA is not an identity system… principal-nature-blind by commitment… It does not know human from agent," written "to protect OVA from well-intentioned expansion by the products that consume it." Hard constraint for the design: never have OVA (or the OVA seam) read a Stele identity object or branch human-vs-agent. The correct shape: Stele resolves identity → mints/holds a credential → OVA proves over the credential, blind to its origin (credential set: role/attribute/time, REQ-042).OVA_PROTOCOL_SPEC_V3_2.md:219-220) — an alert whose payload is deliberately minimal (egg_id, block height, interrogating address; chain identity prohibited). Real contradiction risk: a perception layer that observes and correlates agent actions is, from OVA's threat model, an adversary (REQ-071's traffic-analysis adversary, :296). Keep the perception layer at the consumer layer, above OVA, reading decision-level records.authority/authorizer.py (Option E stub) and delegation/authorization.py (verify_companion_authorization → approval_mode ∈ {per_action, pre_authorized, denied} — per_action means "surface an approval card to a human," i.e. a risk-posture decision point). A Plane 2 design that decides when a human must approve would duplicate this. Design Boundaries to call it, or to be the thing it grows into — not a parallel mechanism. Note also the two seams overlap each other with no stated merge plan (Surprises).Direct answer: Emit only, never consume — per spec (FORAY v4.1, REQ-051–058). But finding F-4 has ruled that emission wrong-layer, downgrading it to an optional off-by-default facility and removing REQ-055/058 outright — a spec pass not yet executed, so V3_2 still carries the obsolete rows. Separately, the shipped Loomworks OVA Slice 1 code registers three FORAY-anchored events — decision-level, i.e. already following the F-4 pattern — which today terminate in the B4 no-op emitter.
Citations.
loomworks-record protocols/ova/OVA_PROTOCOL_SPEC_V3_2.md:52 ("All authorization events are logged to the FORAY Protocol audit trail without embedding topology-revealing metadata"), :63 (FORAY consumed as external dependency at v4.1), :84, :252-263 (REQ-051/052/053: emit on create/interrogate/revoke; payload = SHA-256(egg_id ‖ deployment_id) + event literal + block height; REQ-054 no egg type/chain id/fan-out/hop index; REQ-056/057 bounded retry queue 10,000; REQ-062 TLS 1.3+; REQ-066 90-day retention), :83 (proof-stitching future candidate).protocols/ova/findings/OVA_FINDING_F4_AUDIT_LAYER-v0_1.md:1-40 — OVA's trail "narrates existence, not decisions"; decision-level audit moves to the consumer layer (GRANTHA, Tessera); OVA anchoring becomes optional, off by default; REQ-055 and REQ-058 removed as leaks.loomworks-engine src/loomworks/foray/anchor_priority.py:85-100 — contribution_credential_issued / claimed / revoked at standard priority (actor and verdict captured — consumer-layer audit).candidate-seeds/loomworks/?Direct answer: v0_14.
Citations. loomworks-record candidate-seeds/loomworks/ contains loomworks-candidate-seed-v0_14.md + .html (committed 2026-08-06, 6f0a905 — "seed v0.14 — GRANTHA and OVA named by placement, not function"), alongside loomworks-candidate-seed-v0_14-amendment-v0_1.md (the v0.13→v0.14 amendment instruction sheet) and loomworks-candidate-seed-v0_13-amendment-v0_1.md; archive/ holds v0_8 through v0_13.
**Direct answer: Partially answerable — the comparison could not be completed, because solution design v0_2 is not present anywhere in this workspace (see F3/Surprises). What CAN be stated from the seed: its identity commitments are about human users and do not on their face forbid a separate agent-identity object, but they impose three constraints any Stele design must satisfy, and the seed's own discipline constrains how the Stele may be written into the seed.**
The seed's commitments, quoted. loomworks-record candidate-seeds/loomworks/loomworks-candidate-seed-v0_14.md:
:119 — "A user is identified by their UUID — a system-assigned, persistent, cryptographic identifier. The UUID is the identity. Authentication proves control of credentials bound to the UUID. The UUID is what other Loomworks records reference; it is what FORAY attests against; it is what GRANTHA authorizes against.":121 — "Email and mobile are not identity. They are user-maintained communication attributes… They never authenticate; they never key the lookup of a user's record; they never trigger identity-recovery flows.":145 — "Sign-in does not request an email address. Sign-in does not key user lookup on email. Sign-in does not offer an email-based account recovery path.":149 — recovery via credentials the user controls; "Email-based password reset is not a recovery mechanism in Loomworks.":201 — "Identity is cryptographic. Per the authentication framework above."
Constraints on the Stele that follow. (1) If agents get identity objects, references from Loomworks records, FORAY attestation, and GRANTHA authorization must run against a UUID-class cryptographic identifier, not names or channels — line 119's pattern generalizes and the engine already conforms (ActorRef.id: UUID, B6). (2) No communication-attribute may ever function as agent identity or recovery. (3) The seed-discipline constraint: v0.14 exists precisely because v0.13 wrote another protocol's mechanisms into the seed — "the seed's own stated discipline is to commit postures and defer mechanisms" (loomworks-candidate-seed-v0_14-amendment-v0_1.md:15-23), and "a seed that names only the seat cannot go stale when the occupant's internals change" (:29). If the Stele enters the seed at all, it enters as a named seat, not as identity-object/purpose-field/freeze-state mechanics. Note the seed nowhere mentions the Stele today (grep for "stele" in v0_14: zero hits).
Not verified (and marked as such): whether solution design v0_2 §6 as drafted conflicts with any of this — the document is not in loomworks-record, not in ~/Downloads, and not anywhere findable in this workspace. Any claim about §6's content would be a guess; none is made.
Direct answer: No — nothing newer. And a stronger fact the question didn't anticipate: only ONE of the five arc documents is in the record at all.
Citations. The record holds investigations/loomworks-boundaries-arc-opening-thesis-v0_1.md (+ .html), committed 2026-07-02 as b978326 ("Add discovery arc opening thesis: boundaries as operational primitive v0.1"). git log --all --since=2026-07-01 filtered for boundary-named files shows no arc documents after that; a filename sweep for boundaries-arc outside record-site/ mirrors returns only the opening thesis. The two-plane architecture, research, solution design v0_2, and build path documents are absent from loomworks-record, from ~/Downloads, and from every location searched. The Downloads bundle loomworks-boundaries-docs-2026-07-06.zip contains the CR-098/CR-128 engine-boundary documents (inventory, inspection findings, enforcement plan, standing notes) — a related but distinct body of work, all of it already in the record. BOUNDARIES_LOCATOR_PULL-v0_1.zip (2026-07-12) contains only the opening thesis plus FORAY references.
Things the questions didn't anticipate, gathered rather than woven in. Grouped by area; each carries its citation above or inline.
Arc record integrity
b978326). The two-plane architecture, research, solution design v0_2, and build path exist, as far as this workspace shows, only in the chat session. The arc's design authority currently has no committed home. (F3.)FORAY
/Users/dunin7/foray is not the implementation repo — foray-api is, and five further sibling FORAY repos exist uninvestigated. Every recent foray commit is docs:. (Section A scope note.)foray-validate-4-2.mjs implement the narrowing this reverses. The sheet states it "Blocks: all adaptor and reference-implementation work," and five further rulings (R1, R3–R7) are unchecked boxes — R1 could delete "the rule the validator catches most." (foray docs/decisions/foray-validation-scope-decision-sheet-v0_4.md:120-176, :130-138.)docs/decisions/foray-fwire-amendment-acceptance-v1_0.md:11); the only CI-gated vectors test anchoring. And the six published transaction types were validated against pre-4.2 foray-api v0.7.0 (transaction-types/index.json:5).foray-root-data-set-v0_7.md:33-63 vs foray-root-naming-ratification-decision-sheet-v1_1.md:35-48); the F8 asset-type reframe landed in the Root but the published schema still comments F8 as "Currency" (…v0_7.md:42 vs foray-transaction-v4_2.schema.json:39-42); Root R5 claims a validation check (recompute F20 from F19) that no validator function performs (foray-validation-scope-decision-sheet-v0_4.md:112).BATCH_MODE/UNIFIED_ANCHOR_PATH unset in every environment, arming an explicit separate Operator act. (foray-api wrangler.toml changelog v0.11–v0.17.)attestations component class is structurally unvalidated — anything placed there validates (foray-transaction-v4_2.schema.json:51-54). adapters/ is dead code requiring a nonexistent ./foray-sdk.foray-validation-scope-decision-sheet-v0_4.md:180) — a live trap for anyone (including this investigation's readers) inferring protocol meaning from implementation.Loomworks engine
_AGENT_KINDS no longer means only agents — it aliases {"agent","companion"}, so the Companion is charged against and blocked by the agent spend tier. (B1 citations.)FORM_SUBMITTER_ACTOR is kind="contributor" explicitly so commit_assertion lets it through (credit/form_submitter.py:16-24); _BOOTSTRAP_ACTOR follows the same precedent. Root cause: ActorKind has no system kind (memory/base.py:22; agents/render_dispatch.py:99). The B3 gates therefore have non-human processes on their permitted side — directly relevant to any Boundaries claim about who can commit.instruction_version is documented-required for agents, unenforced, and hardcoded to 1 on the live HTTP path (memory/base.py:147; api/deps.py:1099-1104) — R-A24 instruction pinning is nominal.companion kind unproducible — B2), and _record_to_schema is hand-duplicated across two routers (boundary_records.py:76-98, material.py:124-146) — a drift hazard.reserved_emit.py:33-35), the FORAY_RESERVED_LOCATION marker over-counts emission sites by four, and _ANCHOR_PRIORITY has no credit.* entries — the credit-flow emissions carry no priority signal (anchor_priority.py:30-99 vs flows.py:121-134).RECONCILIATION_SPECIALIST_ACTOR passes name= which Pydantic silently drops (no extra="forbid"), and omits instruction_version (credit/specialists.py:74-78).Loom
loom repo is an empty shell (2 files, 239 lines; empty untracked spec/test dirs) and the spec was missing from its own repo at commit time — the canonical spec lives in loomworks-record. The engine exceeds the spec substantially; the engine is the de-facto spec. (Section C layer note.)memory/base.py:76-77).GRANTHA
grantha discovery/GRANTHA_DISCOVERY_RECORD-v0_14.md).design/GRANTHA_GRANT_CHECK_CONTRACT-v0_2.md §2).delegation/schema.py:245-305: a "you can / go ahead and / i authorize you to" prefix mints authority; "without asking"/"whenever" upgrades to pre_authorized). Plus a constraint-check asymmetry: action_context=None bypasses every constraint on the grant (delegation/authorization.py:169-201, documented as intentional).OVA
verify_companion_authorization has a known signature defect ("fixes the question to delegation"), which is why CR-2026-157 generalized a different ancestor (credit/cross_engagement_memory.py's _alpha_authorizer_stub) into authority/authorizer.py instead. Also: OVA_SKILL.md describes a different OVA (a coding skill) — a naming collision; the Forge-blessed OVA spec is V2 while authoring is at V3.2.Cross-cutting
stele-agentic-id already implements the two-lane consequence model (reversible clamp / human-gated revocation) that the doctrine assigns to GRANTHA lane 1 (packages/agentic-id/src/agentic_id/clamp.py:1-40, registry.py:214-266), with a foray_mapping.py alongside — and nothing in the engine imports any of it. Three codebases (engine delegation, stele-agentic-id, GRANTHA doctrine) now hold three unconnected notions of narrowing an agent's authority.CC's judgment. Ranked by how much of the design each finding invalidates or unblocks.
POST /api/anchor) commits opaque bytes with no validation, validator never connected to commit (A5) — which confirms the cop must live in the originating system. But Loomworks-side the design's stated precedent ("one limit type, blocking, in the commit path", B1) is wrong on its third clause: the spend gate guards the model-room spend path, while the commit path has a separate human-authority gate, and the FORAY evidence channel is a no-op that has never emitted (B4). Solution design v0_2 must (a) name the real chokepoints it instruments — gated_room_complete, commit_assertion/creation, execute_admission_outcome — as plural, and (b) treat the Loomworks→FORAY emission client as a build-path prerequisite, not an assumption; and it must account for the alarm-driven commit path (A5 entry 8) and the no-idempotency /api/anchor contract if it ever writes FORAY-side.verify_companion_authorization, not a sibling. The engine already ships a risk-posture decision point (approval_mode: per_action = summon a human) behind an OVA-labelled seam, with two overlapping seams and no merge plan (E2, Surprise 23). A parallel Plane 2 mechanism would be the third authorizer. This is an architecture decision the design must make explicitly.system kind, humans-by-masquerade on the permitted side of the human-only gates, instruction_version nominal (Surprises 10–11); and stele-agentic-id, which already implements identity roots + clamp/revoke lanes with a FORAY mapping and is imported by nothing (Surprise 24). Decide: build on stele-agentic-id, or explicitly supersede it. The seed constrains form, not substance: identity stays cryptographic/UUID-class, and the Stele enters the seed (if at all) as a seat, not a mechanism (F2).stream_segments, no scope vocabulary (A3) — and the built aggregation tiers are batch-lane machinery, dark and explicitly not streams (A4). Any design element that says "declare a stream per engagement" is spec-writing, not integration, and belongs on FORAY's queue, not the Boundaries build path.agent_activity_record validates as a shape, but F26 is a free string, F15 has no verdict vocabulary, and the F15 code lists are an open catalog item (A2). Boundaries records written today would be well-formed and semantically ungoverned; the design should either author the needed catalog entries as part of the arc or scope verdict semantics inside Loomworks.End of findings v0_1. Read-only investigation; no repository was modified; this file is the sole artifact and is uncommitted — committing is an Operator act.