Skip to content

Commit 2a3d16d

Browse files
V31 Gate 6: Add organization policy authority
Own the organization/team/role/policy authority projection in @bitcode/btd, map it through Auxillaries contracts, and share it with Auxillaries Profile and Terminal detail surfaces. Add fail-closed BTD tests, API contract coverage, UI projection tests, Gate 6 spec/docs updates, and the Gate 6 checker/workflow hook.
1 parent 0f17d0c commit 2a3d16d

25 files changed

Lines changed: 1223 additions & 66 deletions

.github/workflows/bitcode-gate-quality.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ jobs:
100100
node scripts/check-v31-gate3-profile-account-state.mjs --skip-branch-check
101101
node scripts/check-v31-gate4-connects-provider-readiness.mjs --skip-branch-check
102102
node scripts/check-v31-gate5-wallet-btd-pane-readiness.mjs --skip-branch-check
103+
node scripts/check-v31-gate6-organization-team-role-policy-authority.mjs --skip-branch-check
103104
else
104105
echo "Unexpected BITCODE_SPEC.txt pointer: $POINTER" >&2
105106
exit 1

BITCODE_SPEC_V31.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ Gate 6 policy precision:
261261
- Organization authority binds organization id, team/member id, role, grant set, wallet binding requirement, policy id/hash, action, decision, denial reason, and recovery route.
262262
- Multi-sig posture may be represented as readiness and required-action state; it is not value-bearing mainnet approval.
263263
- Protected-source actions fail closed unless account, organization, role, grant, wallet, policy, settlement, and interface admission state all admit them.
264+
- `@bitcode/btd` owns `BtdOrganizationPolicyAuthority`. It wraps the existing `BtdOrganizationInterfaceAuthorityDecision` with account admission, team/member identity, explicit grant set, policy id/hash, wallet binding state, multi-sig posture, policy-level decision, denial reasons, recovery route, source-visibility state, and aggregate authority root.
265+
- `packages/api` maps `BtdOrganizationPolicyAuthority` into `OrganizationPolicyAuthority` for `/api/auxillaries/data`; Auxillaries panes and Terminal detail projections consume that object and may not rederive organization policy law locally.
264266

265267
Gate 7 Interfaces precision:
266268

@@ -588,6 +590,11 @@ Organization permission authority is a BTD primitive, not a per-interface conven
588590
The canonical decision is `BtdOrganizationInterfaceAuthorityDecision`.
589591
It binds actor id, organization id, organization role, organization permission grants, interface surface, action, wallet binding, registry read-access decision, settlement state, explicit confirmation state, repair approval state, target anchor, source visibility, and proof roots.
590592

593+
V31 Gate 6 adds the package-owned `BtdOrganizationPolicyAuthority` projection as the user and support-plane carrier around that decision.
594+
The projection binds actor/account admission, organization id, team id, member id, role, raw permission grants, explicit grant set for the action, wallet-binding requirement/state, policy id/hash, interface surface, action, multi-sig readiness, policy decision, denial reason(s), recovery route, source visibility, and authority root.
595+
Settlement-adjacent and protected-source actions fail closed when any of account admission, organization, role, explicit grant, wallet binding, policy identity/hash, multi-sig readiness, settlement/read-license state, confirmation, repair approval, or interface admission is missing or denied.
596+
Auxillaries Profile/organization support and Terminal selected-activity authority must read the same object so support UI, transaction cockpit, telemetry, and proof hooks explain one shared policy state.
597+
591598
Gate 7 defines the current action set:
592599

593600
- `read_transaction`

BITCODE_SPEC_V31_DELTA.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ Closure acceptance:
161161
- protected-source and settlement-adjacent actions fail closed unless all authority inputs admit them;
162162
- Terminal organization authority and Auxillaries organization surfaces consume the same package-owned authority object.
163163

164+
Gate 6 implementation centers:
165+
166+
- `packages/btd/src/authority.ts` owns `BtdOrganizationPolicyAuthority`, `BtdOrganizationPolicyMultiSigInput`, and `buildBtdOrganizationPolicyAuthority`, deriving policy-level admission from account admission, organization/team/member identity, role, explicit grants, wallet binding, policy id/hash, multi-sig readiness, settlement/read-license/confirmation posture, interface admission, denial reasons, recovery route, source visibility, and aggregate authority root;
167+
- `packages/api/src/routes/auxillaries-contract.ts` maps the BTD authority projection into `OrganizationPolicyAuthority` for `/api/auxillaries/data` so route handlers serialize one JSON-safe authority object instead of route-local role heuristics;
168+
- `uapi/app/auxillaries/components/AuxillariesProfilePane.tsx` renders organization authority, team/member, wallet binding, policy action/hash, multi-sig posture, explicit grants, denial reasons, recovery route, and authority root from the package object;
169+
- `uapi/app/terminal/terminal-organization-authority.ts` projects both the policy wrapper and underlying interface decision so selected-activity detail, blockers, proof roots, and raw payload inspection agree with Auxillaries;
170+
- focused BTD, API, Profile pane, and Terminal tests prove allowed settlement-adjacent posture, protected-source fail-closed behavior, JSON-safe route emission, shared UI consumption, multi-sig readiness, and proof roots.
171+
164172
### Gate 7: Interfaces Pane Admission And Cross-Surface Contracts
165173

166174
Gate 7 makes the Interfaces pane a source-safe admission catalog.

BITCODE_SPEC_V31_NOTES.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,11 @@ Gate 5 is closed only when Wallet/BTD support is package-owned and source-safe.
102102
`@bitcode/btd` must derive no-custody wallet capability, signer posture, network readiness, BTD range/read-right counts, account treasury posture, settlement blockers, and support roots.
103103
`packages/api` may map that projection into `AuxillariesWalletBtdPaneState`, but UI and routes must not rederive BTD read-access, settlement, rights-transfer, or no-custody law locally.
104104
The Wallet pane must consume `walletBtdPaneState` from `/api/auxillaries/data`, render signer/network/range/read-right/settlement/treasury readiness, keep protected source invisible before paid unlock, and state that account treasury support is not Exchange market state.
105+
106+
## Gate 6 closure note
107+
108+
Gate 6 is closed only when organization policy authority is package-owned, source-safe, and shared by Auxillaries and Terminal.
109+
`@bitcode/btd` must own `BtdOrganizationPolicyAuthority` and derive it from account admission, organization/team/member identity, role, explicit grants, wallet binding, policy id/hash, multi-sig readiness, interface surface, action, settlement/read-license/confirmation posture, denial reasons, recovery route, source visibility, and proof root.
110+
Protected-source and settlement-adjacent actions must fail closed unless every required authority input admits the action.
111+
`packages/api` may map the BTD object into `OrganizationPolicyAuthority`, but routes, Profile panes, Terminal detail cards, telemetry, and proof hooks must not rederive the authority decision from local heuristics.
112+
The support UI may show policy measurements, blockers, recovery routes, and roots; it must not reveal protected source or treat multi-sig readiness as value-bearing mainnet approval.

BITCODE_SPEC_V31_PARITY_MATRIX.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ No `_legacy/` source is active source truth.
5959
| Roadmap truth | Gate 1 | `SPECIFICATIONS_ROADMAP.md`, README, PR template, workflow posture | drafted | Roadmap states V30 active, V31 draft, and coherent V32-V37 responsibilities. |
6060
| Auxillaries package and route contracts | Gate 2 | `packages/api/src/routes/auxillaries-contract.ts`, `packages/api/src/routes/auxillaries.ts`, package docs, route tests | drafted | Shared Profile, Connects, Interfaces, Wallet, BTD, organization, readiness, and recovery objects are package-owned and JSON-safe. |
6161
| Profile and account state | Gate 3 | `packages/api/src/routes/auxillaries-contract.ts`, `packages/api/src/routes/auxillaries.ts`, `uapi/app/auxillaries/components/AuxillariesProfilePane.tsx`, route/pane tests | drafted | Profile, account identity, wallet binding, preferences, notification posture, and completeness blockers are typed and recoverable. |
62-
| Connects provider readiness and recovery | Gate 4 | Provider packages, connection routes, readiness/recovery tests | pending | Provider readiness names credential posture without secrets, scopes class, readback status, blocker, repair action, and before/after roots. |
63-
| Wallet and BTD pane readiness | Gate 5 | `packages/btd`, Wallet/BTD panes, settlement/read-right tests | pending | Wallet and BTD panes consume V30 no-custody, signer, read-right, treasury, and settlement-readiness primitives. |
64-
| Organization team role policy authority | Gate 6 | Organization packages/routes, policy authority tests, Terminal/Auxillaries projections | pending | Organization, team, role, grants, multi-sig readiness, policy decisions, denials, and recovery routes are typed and fail closed. |
62+
| Connects provider readiness and recovery | Gate 4 | Provider packages, connection routes, readiness/recovery tests | drafted | Provider readiness names credential posture without secrets, scopes class, readback status, blocker, repair action, and before/after roots. |
63+
| Wallet and BTD pane readiness | Gate 5 | `packages/btd`, Wallet/BTD panes, settlement/read-right tests | drafted | Wallet and BTD panes consume V30 no-custody, signer, read-right, treasury, and settlement-readiness primitives. |
64+
| Organization team role policy authority | Gate 6 | `packages/btd/src/authority.ts`, `packages/api/src/routes/auxillaries-contract.ts`, `uapi/app/auxillaries/components/AuxillariesProfilePane.tsx`, `uapi/app/terminal/terminal-organization-authority.ts`, focused BTD/API/UI tests | drafted | Organization, team, role, grants, multi-sig readiness, policy decisions, denials, and recovery routes are typed and fail closed. |
6565
| Interfaces pane admission and cross-surface contracts | Gate 7 | Interfaces pane, API/MCP/ChatGPT App interface records, tests | pending | Interface admission records name auth mode, supported actions, policy constraints, source-safety class, blockers, and readiness. |
6666
| Auxillaries UX accessibility and responsive proof | Gate 8 | Auxillaries components, focused Jest/Playwright/a11y evidence | pending | Guided low-detail and expandable audit UX works across Profile, Connects, Interfaces, Wallet/BTD, and organization panes. |
6767
| Auxillaries telemetry proof and recovery runs | Gate 9 | Telemetry/proof packages, recovery routes, readback tests | pending | Profile, connection, interface, wallet, BTD, organization, policy, readiness, and recovery events emit source-safe proof hooks. |
@@ -129,9 +129,10 @@ No `_legacy/` source is active source truth.
129129

130130
| Requirement | Source evidence | Current V31 judgment |
131131
| --- | --- | --- |
132-
| Organization authority is package-owned | organization/policy packages and route tests | pending |
133-
| Role, grants, policy, wallet binding, and denial reasons are typed | package tests and Auxillaries organization pane tests | pending |
134-
| Protected actions fail closed unless all authority inputs admit them | policy/authorization tests | pending |
132+
| Organization authority is package-owned | `BtdOrganizationPolicyAuthority` and `buildBtdOrganizationPolicyAuthority` in `packages/btd/src/authority.ts`; `OrganizationPolicyAuthority` aliases that object in `packages/api/src/routes/auxillaries-contract.ts` | drafted |
133+
| Role, grants, policy, wallet binding, and denial reasons are typed | BTD tests cover allowed settlement-adjacent policy authority and protected-source denial; API tests assert organization/team/member/grant/policy/multi-sig route emission; Profile pane tests render the shared authority object | drafted |
134+
| Protected actions fail closed unless all authority inputs admit them | `packages/btd/__tests__/btd.test.ts` covers missing grant, wallet, policy, interface admission, multi-sig, settlement, read access, and confirmation denial reasons with blocked source visibility | drafted |
135+
| Terminal and Auxillaries consume one authority object | `uapi/hooks/useUserData.ts`, `uapi/app/auxillaries/components/AuxillariesSurface.tsx`, `uapi/app/auxillaries/components/AuxillariesProfilePane.tsx`, and `uapi/app/terminal/terminal-organization-authority.ts` consume/project `organizationAuthority` without route-local policy rederivation | drafted |
135136

136137
## Gate 7 Parity
137138

SPECIFICATIONS_ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
- Current active canonical pointer: `BITCODE_SPEC.txt` -> `V30`
66
- Current active canon: `BITCODE_SPEC_V30.md`
77
- Current draft target: `BITCODE_SPEC_V31.md`
8-
- Current working gate: V31 Gate 5 Wallet and BTD pane readiness, which connects Auxillaries Wallet/BTD UI to package-owned V30 wallet, signer, network, BTD range, read-right, treasury, no-custody, and settlement-readiness projections without protected source leakage or Exchange market inference.
8+
- Current working gate: V31 Gate 6 Organization Team Role Policy Authority, which binds account, organization, team, member, role, explicit grants, wallet binding, policy id/hash, multi-sig readiness, policy decision, denial reason, and recovery route into one package-owned authority object consumed by Auxillaries and Terminal.
99
- Purpose: concise running index of Bitcode/ENGI specification history, current work, and planned work.
1010

1111
This roadmap is not an active system specification.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"check:v31-gate3": "node scripts/check-v31-gate3-profile-account-state.mjs",
7070
"check:v31-gate4": "node scripts/check-v31-gate4-connects-provider-readiness.mjs",
7171
"check:v31-gate5": "node scripts/check-v31-gate5-wallet-btd-pane-readiness.mjs",
72+
"check:v31-gate6": "node scripts/check-v31-gate6-organization-team-role-policy-authority.mjs",
7273
"check:spec-quality": "node scripts/run-bitcode-spec-quality.mjs --mode basic",
7374
"check:spec-quality:title": "node scripts/run-bitcode-spec-quality.mjs --mode strict-from-title",
7475
"check:spec-quality:v24": "node scripts/run-bitcode-spec-quality.mjs --mode strict-version --version V24",

packages/api/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ come from the BTD projection. API responses must keep protected AssetPack source
5050
hidden, keep wallet private material out of JSON, and mark the Wallet/BTD
5151
treasury support state as separate from Exchange market state.
5252

53+
Organization authority state is package-owned through `@bitcode/btd` and mapped
54+
here as `OrganizationPolicyAuthority`. Route payloads may hydrate organization,
55+
team, member, role, grants, wallet, policy, and multi-sig facts, but
56+
`buildBtdOrganizationPolicyAuthority` owns the policy decision, fail-closed
57+
denial reasons, source visibility, recovery route, and proof root. API
58+
responses must expose only the source-safe authority object shared by
59+
Auxillaries and Terminal.
60+
5361
In V26 fourth-gate this package is where merged-world Bitcode becomes concrete:
5462
- `/conversations` continuity
5563
- `/executions` compatibility and pipeline-run APIs

packages/api/src/routes/__tests__/auxillaries-contract.test.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ describe('Auxillaries package route contracts', () => {
2020
is_verified: true,
2121
company_name: 'Bitcode',
2222
role: 'admin',
23+
organization_id: 'org-bitcode',
24+
team_id: 'team-core',
25+
member_id: 'member-operator',
26+
organization_permission_grants: ['settlement:pay_btc_fee'],
27+
organization_policy_confirmed: true,
28+
multi_sig_required: true,
29+
multi_sig_required_signatures: 2,
30+
multi_sig_present_signatures: 2,
31+
multi_sig_approver_ids: ['member-operator', 'member-reviewer'],
2332
wallet_binding: {
2433
address: 'tb1pauxcontract',
2534
provider: 'leather',
@@ -186,7 +195,34 @@ describe('Auxillaries package route contracts', () => {
186195
settlementReadiness: 'ready',
187196
settlementBlockers: [],
188197
});
189-
expect(payload.organizationAuthority.policyDecision).toBe('allowed');
198+
expect(payload.organizationAuthority).toMatchObject({
199+
kind: 'btd_organization_policy_authority',
200+
organizationId: 'org-bitcode',
201+
teamId: 'team-core',
202+
memberId: 'member-operator',
203+
role: 'admin',
204+
explicitGrantSet: ['settlement:pay_btc_fee'],
205+
walletBindingRequired: true,
206+
walletBindingState: 'bound',
207+
policyDecision: 'allowed',
208+
denialReason: null,
209+
sourceSafetyClass: 'source_safe',
210+
policy: {
211+
policyId: 'org-bitcode:auxillaries-policy',
212+
action: 'pay_btc_fee',
213+
interfaceSurface: 'terminal',
214+
},
215+
multiSigPosture: {
216+
state: 'ready',
217+
required: true,
218+
requiredSignatures: 2,
219+
presentSignatures: 2,
220+
requiredAction: 'none',
221+
},
222+
});
223+
expect(payload.organizationAuthority.policy.policyHash).toMatch(/^[0-9a-f]{64}$/);
224+
expect(payload.organizationAuthority.actionDecision?.decision).toBe('allowed');
225+
expect(payload.organizationAuthority.authorityRoot).toMatch(/^btd-proof-root:organization-policy-authority:/);
190226
expect(payload.auxillariesContract.contractVersion).toBe(AUXILLARIES_CONTRACT_VERSION);
191227
expect(validateAuxillariesContractSnapshot(payload.auxillariesContract)).toEqual({
192228
valid: true,

0 commit comments

Comments
 (0)