The catalog of who may see and do what in the record, as a pure function of role, record class, and governing section, never as an administrator's toggle. Every policy below cites its anchor in the published governing instruments at techne.coop/legal. The document governs; the policy migration it emits distills, and flips the rls-audit suite from deny-all to the real matrix.
This map is the document a build agent cites instead of inventing a permission, per Law V and BP v2 §4. It is drawn against the governing instruments as actually published: Bylaws v2.1 at techne.coop/legal/bylaws, the Membership Agreement v2.3, and the Community Supporter Agreement, with the Hub Membership Agreement under counsel review and the Investor rider Anticipated. It absorbs the estate's C7 probe matrix in shape, with roles and tables re-derived for the launch schema of IM v0.1, and the RLS conventions in discipline: every policy carries its anchor, and a policy without an anchor does not merge.
The bylaws document at techne.coop/legal/bylaws declares itself v2.1, Ratified July 2026, effective July 2026. The legal index at techne.coop/legal, which states that it is the source of truth for document status, marks the bylaws v.2, Drafted. This map cannot resolve that conflict and does not try; it cites the v2.1 text, wears the question openly, and defers the mark's flip to the G-R proof of VS v2 §5, which requires re-verification of every anchor whenever the status changes hands. Until the index and the instrument agree, no surface downstream of this map displays Ratified. Open · the members' vote, then G-R
Amended 2026-09-03 (X-36). The disagreement above closed on 2026-08-12 under FORMATION-01 (PR #120): the instrument page at /legal/bylaws/ reads Drafted, not yet in effect, and the legal shelf marks it Drafted. The index and the instrument now agree. The flip to Ratified still waits on the members' vote under Article XII and the G-R re-verification; the paragraph above is kept as it was written. A later ruling moved the standing again: on 2026-09-03 the steward ruled the Bylaws are in effect, and /legal/bylaws/ now reads in effect on board adoption, so the not-yet-in-effect reading recorded here is the standing as of 2026-08-12 and not the current one (ruling events b73a1ef1, 378775246952).
One resolution arrived with the fetch and is recorded gladly: the open deficit-restoration question is answered in the instrument itself. Bylaws §5.3.4 provides a qualified income offset and §5.6 disclaims any obligation to restore a negative capital account, which reads as QIO without DRO. That constant moves from open to drafted-in-instrument, subject to CPA confirmation. Drafted · QIO per §5.3.4, §5.6; CPA to confirm
What an agent may see is visible(agent, record) = f( role, record class, governing § ), structural rather than configured. The default runs toward disclosure to members, and the exceptions are carried by the instrument, not by preference.
The disclosure ground is concrete in v2.1. Any member may request the membership list, alphabetical with addresses, available electronically (§2.9). Every member receives the bylaws and their amendments (Art. XVI). The annual benefit report is posted publicly on the website (Art. XV). A member's own record travels with information rights under §18.1 and their own tax reporting under §6.2.1. These four anchors are why the directory, the agreements shelf, and the self-views exist as member defaults rather than privileges.
The restriction ground is equally concrete. The member record includes tax identification numbers where required (§1.13), and those never enter an application-level policy at all, per §4 below. Confidential information is defined and bound by §18.2. Deliberative records, board hearings under §1.8 and dispute proceedings under Art. XI, carry their own confidentiality. The function honors all three without a toggle anywhere.
Roles come in two kinds, and the map keeps them distinct: membership classes, which the bylaws define at §1.1, and appointments, which the bylaws create and the board grants. Role names follow the live reference: patron_member, director, steward, applicant.
patron_member with the class held on the membership row.Three kinds of record are restricted by structure, not by policy fine print, and no role below director-with-purpose reaches them.
The C7 shape, re-derived: the thirteen launch tables, and the profiles addendum of §9, against the map's roles, expectations sourced from this document and checked by the rls-audit suite. R is read, W is write, and every cell is scoped by the policies of §6; self means the row concerns the agent asking.
| table | public | applicant | member | director | officer | steward |
|---|---|---|---|---|---|---|
| agents | – | self | R · self W | R | R | R |
| agreements | – | R | R | R | R · W | R |
| memberships | – | self | R | R · W | R | R · W |
| stock_ledger | – | – | self | R | R · W | – |
| signatures | – | self W | self · self W | R | R | – |
| applications | – | self · self W | self | R | R | R · W |
| events | – | – | self · scoped W | R | R | R · W |
| gatherings | – | – | R · host W | R | R | R · W |
| sessions | – | – | R · host W | R | R | R · W |
| registrations | – | – | self · self W · host R | R | R | R |
| attendance | – | – | self · host W | R | R | R · W |
| opportunities | – | – | R · author W | R | R | R |
| responses | – | – | scoped R · self W | R | R | R |
| profiles | – | self | R · self W | R | R | R |
public reads nothing in the database: the public surface is the website, per Art. XV and the legal page, not an anonymous database role · responses are visible to the responder and the opportunity's author · the capital view folds only what the events policy already shows the asker · the profiles row (addendum, 2026-07-22, B-06) carries one guarded cell: email rides no client select and is served by profile_email() on the owner's visibility choice, to active members only
Each policy family, with the section that authorizes it. The emission carries the SQL; this register is the citation trail an auditor or an agent follows.
Reads are broad by design; writes are narrow by the same design. Every write that the bylaws assign to a person or the Board requires a recorded human actor, and no instrument holds a write grant of its own.
The acts that belong to people, with their anchors: admission by Board vote (§1.3.1(e)); withdrawal by the member's own notice (§1.7.1); suspension and termination by Board process with notice and hearing (§1.8); signatures by the signer (§1.3.1(d), §2.8); proof attestations by organizers (VS v2 §6). Each lands in the record as an event whose actor_agent_id is a person, per Laws VI and X, and the substrate's lifecycle trigger refuses any transition the automaton does not permit regardless of who asks.
Build agents write only through the repository under BP v2; the runtime instrument writes nothing, drafts everything, and reads as the member it serves. The service paths that maintain derived structures run as definer functions owned by the schema, which is a custody arrangement, not a role.
Reading v2.1 against the draft-era anchors carried in the estate found real movement, recorded here so the correction is chosen rather than slipped.
The vote anchors moved: the old mapping cited §1.6 and §1.14 for votes, which in v2.1 govern transfer restrictions and certificates; voting now grounds in §1.4, §1.11, §1.12.2, and §2.6. The membership anchors held (§1.1 to 1.4), as did capital accounts (§5.1) and notices (§2.4, Art. X). Attendance's old anchor §2.7 now reads as quorum, which is the purpose attendance serves, so the citation stands with its meaning sharpened. The IM v0.1 emission's comments remain accurate under this re-reading; the estate documents that cite the moved vote anchors are corrected at the reconciliation merge.
The standing duty: at G-R, or whenever the legal index and the instrument agree on a status flip per §1a, every anchor in this map and in the schema comments is re-verified against the governing text, and the map's own mark changes only through that gate.
The migration 0002_policies.sql distills this map: the helper functions, every policy with its anchor within reach of the schema-lint, and the grants that make deny-by-default become the matrix of §5. Applying it flips the rls-audit suite live.
Two schema additions ride in the emission because the map cannot function without them, and both are flagged as IM addenda rather than slipped in: an identity binding on agents (auth_user_id), since the visibility function must know who is asking, and a role_grants table for appointments (director, officer, steward), since classes live on memberships but offices do not. Both are Tier B changes under BP v2 §6, recorded here for adoption into IM v0.2. Open · IM v0.2 addenda, Todd's nod
A third addendum joins them by the steward's direction of 2026-07-22 (B-06): a profiles table, the self-description satellite of agents, emitted by 0009_profiles.sql with its matrix row in §5 and its policy family in §6. Two of its choices are carried openly: profile edits are presentation state and are not evented, and the profile view declares no crafts, inferring practice from the record instead (and, when the Share train opens, from contributions and patronage activity). Its avatars ride a private storage shelf under the same self-write, member-read cells. Tier B, recorded for adoption into IM v0.2.
Deferred with their instruments: Investor-rider specifics, the Community Participant governance hook, the Hub Participation Agreement's Class Two and Three terms, and every post-launch table family. Amendments to this map are Tier B at the policy level and Tier C at the document level, prospective, with supersession explicit.
Authority here is cited, time-bound, and event-based, never assumed. When a needed permission has no row in this map, the answer is an escalation card and, if warranted, an amendment with an anchor, because the alternative, a permission that exists only in code, is exactly the unexplained boundary the fourth principle forbids.
P-08 reported defects against this map on 2026-08-10 and none is fixed on the record. They are recorded here rather than in a pull request comment, because a defect that lives only in a merged conversation is a defect the map does not carry. The three answers below are drafts. Two of them now carry an approved direction and still await application; nothing here is applied to the live record, and no cell of §5 has changed.
gatherings_host_write omits app_is_member() from its WITH CHECK, so an authenticated agent bound to an agents row but holding no active membership can insert a gathering that names them host. The applicant cell on the gatherings row of §5 is a dash; the policy is wider than the document it distills.pg_policies for gatherings: the WITH CHECK is ((host_agent_id = app_agent_id()) OR app_has_role('steward'::appointment)), the same text 0002_policies.sql emits. app_agent_id() resolves the binding and asks nothing about membership state.opportunities_author_write carries the membership test in its WITH CHECK and not in its USING, so an author keeps the row they own while a non-member creates nothing. The draft brings gatherings to that pattern and changes nothing else, which makes it a narrowing: no cell gains a capability.0023_gatherings_host_write_bound.sql. Not applied, not in the migration chain the probe matrix stands in CI. 0021 and 0022 are reserved by the almanac for V-01 and V-02, so the draft takes 0023. Direction approved · not yet appliedsessions_host_write needs no companion change: its subquery against gatherings runs under gatherings_member_read, which already requires membership, so a bound non-member sees no gathering to hang a session on. The adjacent events_scoped_insert width this draft named and left open is now answered as the third finding below.events_scoped_insert (0002_policies.sql, the events block) admits any bound agent as actor for the signature, registration, opportunity, and gathering kind families without a membership test. So the applicant who cannot create a gathering under the corrected gatherings_host_write could still write a gathering.scheduled event into the log about a row they never made. The applicant cells on the gatherings and opportunities rows of §5 are dashes; the policy is wider than the document, in the same way and for the same reason as the first finding.pg_policies for events: the deployed WITH CHECK is the text 0002 emits, verbatim. Repo and database agree.events row was read before the draft was written. All of them but three are definer functions or definer triggers, which do not consult this policy at all: apply_for_membership (0007, definer at line 17), sign_agreement (0003, line 16), and the two X-12 notice triggers that write registration.* and opportunity.responded (0015, definer at lines 61 and 32). Read live the same day, pg_proc gives each of them prosecdef true and owner postgres, and pg_class gives events as owned by postgres with relforcerowsecurity false, so a definer owned by the table owner is not subject to the table's policies. The three client call sites that do consult it write only gathering.scheduled, gathering.archived, and opportunity. plus a resolution state, and in each the actor must already be a member to have written the row the event is about. The narrowing therefore costs no working path.gathering.* and opportunity.*, gain app_is_member(). The signature and registration families keep their branch untouched, because they have no client-side writer at all and removing them would be a wider claim than the direction carries; that they are dead width is recorded for the steward, not acted on. The overseer branch and every read path are untouched.anon column stays empty: 0002's grants give the write surface to authenticated only, so the posture is enforced at the grant as well as at the policy.0024_events_scoped_insert_narrowed.sql, with seven matching cells in DRAFT_P. Not applied, not in the chain CI stands. Direction approved · not yet applied#intranet-dev on 2026-08-17 at 19:00:50 UTC, event 5964c4ce86f71bac1714f55cc7683f90359a0aed86475181b2b368ce4243334e. The same message delegated the proceed call, and Nou exercised that delegated call the same day in the same thread. That pair, the steward's delegation and Nou's exercised call, is the authority these drafts cite. There was no board vote and none is claimed. Application to the live record remains Nou's act, not a build agent's.anon role, which reads nothing; the applicant column presumes both an agents binding and a membership in state applied. A person who signs in before any record exists for them sits between the two, which the participation stories name as arrival class A-5. Its refusal is asserted nowhere, so the probe matrix has been proving a boundary it never tested.DRAFT_P, in scripts/rls_probe.py in the repository, reached with --drafts and not run by CI. Twelve assert that the unbound session reads nothing anywhere; three assert that it writes nothing; four hold the gatherings row against the first finding; seven hold the events log against the third. Three of them fail against the deployed chain on purpose, because a finding stated as an assertion is the only kind that stays fixed. --drafts --no-fix stands the chain as deployed and shows those failures. Direction approved · not yet appliedMIGRATIONS and are applied to the live record, the 0003 pattern; the draft cells join P and become CI; and §5 gains its seventh column, since a persona the probes assert is a persona the matrix owes a row. The A-5 persona itself carries no direction yet and stays a plain open finding. Until application the map states the gap and claims no fix.