@openvtc/trust-tasks 0.20.1 → 0.20.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/dist/_shared/components.d.ts +175 -0
  3. package/dist/_shared/components.d.ts.map +1 -1
  4. package/dist/git-ns/_shared/0.1/git-ns.d.ts +16 -0
  5. package/dist/git-ns/_shared/0.1/git-ns.d.ts.map +1 -0
  6. package/dist/git-ns/_shared/0.1/git-ns.js +6 -0
  7. package/dist/git-ns/_shared/0.1/git-ns.js.map +1 -0
  8. package/dist/git-ns/account/link/0.1/payload.d.ts +355 -0
  9. package/dist/git-ns/account/link/0.1/payload.d.ts.map +1 -0
  10. package/dist/git-ns/account/link/0.1/payload.js +192 -0
  11. package/dist/git-ns/account/link/0.1/payload.js.map +1 -0
  12. package/dist/git-ns/account/link-status/0.1/payload.d.ts +403 -0
  13. package/dist/git-ns/account/link-status/0.1/payload.d.ts.map +1 -0
  14. package/dist/git-ns/account/link-status/0.1/payload.js +234 -0
  15. package/dist/git-ns/account/link-status/0.1/payload.js.map +1 -0
  16. package/dist/git-ns/bridge/event/0.1/payload.d.ts +1348 -0
  17. package/dist/git-ns/bridge/event/0.1/payload.d.ts.map +1 -0
  18. package/dist/git-ns/bridge/event/0.1/payload.js +785 -0
  19. package/dist/git-ns/bridge/event/0.1/payload.js.map +1 -0
  20. package/dist/git-ns/bridge/job/0.1/payload.d.ts +1044 -0
  21. package/dist/git-ns/bridge/job/0.1/payload.d.ts.map +1 -0
  22. package/dist/git-ns/bridge/job/0.1/payload.js +564 -0
  23. package/dist/git-ns/bridge/job/0.1/payload.js.map +1 -0
  24. package/dist/git-ns/bridge/result/0.1/payload.d.ts +462 -0
  25. package/dist/git-ns/bridge/result/0.1/payload.d.ts.map +1 -0
  26. package/dist/git-ns/bridge/result/0.1/payload.js +248 -0
  27. package/dist/git-ns/bridge/result/0.1/payload.js.map +1 -0
  28. package/dist/git-ns/namespace/bind/0.1/payload.d.ts +547 -0
  29. package/dist/git-ns/namespace/bind/0.1/payload.d.ts.map +1 -0
  30. package/dist/git-ns/namespace/bind/0.1/payload.js +322 -0
  31. package/dist/git-ns/namespace/bind/0.1/payload.js.map +1 -0
  32. package/dist/git-ns/namespace/unbind/0.1/payload.d.ts +300 -0
  33. package/dist/git-ns/namespace/unbind/0.1/payload.d.ts.map +1 -0
  34. package/dist/git-ns/namespace/unbind/0.1/payload.js +168 -0
  35. package/dist/git-ns/namespace/unbind/0.1/payload.js.map +1 -0
  36. package/dist/git-ns/repo/adopt/0.1/payload.d.ts +962 -0
  37. package/dist/git-ns/repo/adopt/0.1/payload.d.ts.map +1 -0
  38. package/dist/git-ns/repo/adopt/0.1/payload.js +583 -0
  39. package/dist/git-ns/repo/adopt/0.1/payload.js.map +1 -0
  40. package/dist/git-ns/repo/archive/0.1/payload.d.ts +959 -0
  41. package/dist/git-ns/repo/archive/0.1/payload.d.ts.map +1 -0
  42. package/dist/git-ns/repo/archive/0.1/payload.js +584 -0
  43. package/dist/git-ns/repo/archive/0.1/payload.js.map +1 -0
  44. package/dist/git-ns/repo/create/0.1/payload.d.ts +1074 -0
  45. package/dist/git-ns/repo/create/0.1/payload.d.ts.map +1 -0
  46. package/dist/git-ns/repo/create/0.1/payload.js +636 -0
  47. package/dist/git-ns/repo/create/0.1/payload.js.map +1 -0
  48. package/dist/git-ns/repo/transfer/0.1/payload.d.ts +947 -0
  49. package/dist/git-ns/repo/transfer/0.1/payload.d.ts.map +1 -0
  50. package/dist/git-ns/repo/transfer/0.1/payload.js +577 -0
  51. package/dist/git-ns/repo/transfer/0.1/payload.js.map +1 -0
  52. package/dist/git-ns/right/grant/0.1/payload.d.ts +506 -0
  53. package/dist/git-ns/right/grant/0.1/payload.d.ts.map +1 -0
  54. package/dist/git-ns/right/grant/0.1/payload.js +289 -0
  55. package/dist/git-ns/right/grant/0.1/payload.js.map +1 -0
  56. package/dist/git-ns/right/revoke/0.1/payload.d.ts +492 -0
  57. package/dist/git-ns/right/revoke/0.1/payload.d.ts.map +1 -0
  58. package/dist/git-ns/right/revoke/0.1/payload.js +284 -0
  59. package/dist/git-ns/right/revoke/0.1/payload.js.map +1 -0
  60. package/dist/git-ns/view/0.1/payload.d.ts +1407 -0
  61. package/dist/git-ns/view/0.1/payload.d.ts.map +1 -0
  62. package/dist/git-ns/view/0.1/payload.js +860 -0
  63. package/dist/git-ns/view/0.1/payload.js.map +1 -0
  64. package/dist/index.d.ts +20 -0
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +20 -0
  67. package/dist/index.js.map +1 -1
  68. package/dist/vetting/attestation/0.1/payload.d.ts +690 -0
  69. package/dist/vetting/attestation/0.1/payload.d.ts.map +1 -0
  70. package/dist/vetting/attestation/0.1/payload.js +374 -0
  71. package/dist/vetting/attestation/0.1/payload.js.map +1 -0
  72. package/dist/vtc/vetting/pcs-challenge/0.1/payload.d.ts +261 -0
  73. package/dist/vtc/vetting/pcs-challenge/0.1/payload.d.ts.map +1 -0
  74. package/dist/vtc/vetting/pcs-challenge/0.1/payload.js +145 -0
  75. package/dist/vtc/vetting/pcs-challenge/0.1/payload.js.map +1 -0
  76. package/dist/vtc/vetting/vetters/event-mode/0.1/payload.d.ts +546 -0
  77. package/dist/vtc/vetting/vetters/event-mode/0.1/payload.d.ts.map +1 -0
  78. package/dist/vtc/vetting/vetters/event-mode/0.1/payload.js +290 -0
  79. package/dist/vtc/vetting/vetters/event-mode/0.1/payload.js.map +1 -0
  80. package/dist/vtc/vetting/vetters/pcs-root/0.1/payload.d.ts +336 -0
  81. package/dist/vtc/vetting/vetters/pcs-root/0.1/payload.d.ts.map +1 -0
  82. package/dist/vtc/vetting/vetters/pcs-root/0.1/payload.js +178 -0
  83. package/dist/vtc/vetting/vetters/pcs-root/0.1/payload.js.map +1 -0
  84. package/dist/vtc/vetting/vetters/pcs-tokens/0.1/payload.d.ts +402 -0
  85. package/dist/vtc/vetting/vetters/pcs-tokens/0.1/payload.d.ts.map +1 -0
  86. package/dist/vtc/vetting/vetters/pcs-tokens/0.1/payload.js +205 -0
  87. package/dist/vtc/vetting/vetters/pcs-tokens/0.1/payload.js.map +1 -0
  88. package/package.json +1 -1
  89. package/src/_shared/components.ts +181 -0
  90. package/src/git-ns/_shared/0.1/git-ns.ts +17 -0
  91. package/src/git-ns/account/link/0.1/payload.ts +242 -0
  92. package/src/git-ns/account/link-status/0.1/payload.ts +276 -0
  93. package/src/git-ns/bridge/event/0.1/payload.ts +902 -0
  94. package/src/git-ns/bridge/job/0.1/payload.ts +676 -0
  95. package/src/git-ns/bridge/result/0.1/payload.ts +321 -0
  96. package/src/git-ns/namespace/bind/0.1/payload.ts +374 -0
  97. package/src/git-ns/namespace/unbind/0.1/payload.ts +211 -0
  98. package/src/git-ns/repo/adopt/0.1/payload.ts +628 -0
  99. package/src/git-ns/repo/archive/0.1/payload.ts +626 -0
  100. package/src/git-ns/repo/create/0.1/payload.ts +689 -0
  101. package/src/git-ns/repo/transfer/0.1/payload.ts +619 -0
  102. package/src/git-ns/right/grant/0.1/payload.ts +340 -0
  103. package/src/git-ns/right/revoke/0.1/payload.ts +331 -0
  104. package/src/git-ns/view/0.1/payload.ts +906 -0
  105. package/src/index.ts +20 -0
  106. package/src/vetting/attestation/0.1/payload.ts +493 -0
  107. package/src/vtc/vetting/pcs-challenge/0.1/payload.ts +187 -0
  108. package/src/vtc/vetting/vetters/event-mode/0.1/payload.ts +375 -0
  109. package/src/vtc/vetting/vetters/pcs-root/0.1/payload.ts +241 -0
  110. package/src/vtc/vetting/vetters/pcs-tokens/0.1/payload.ts +286 -0
package/CHANGELOG.md CHANGED
@@ -11,6 +11,116 @@ The package versions over **its own API** — what a consumer compiles against
11
11
  not over `SPEC.md`. Below 1.0 a breaking change bumps the leading non-zero
12
12
  component.
13
13
 
14
+ ## 0.20.3 — 2026-09-23
15
+
16
+
17
+ ### Added
18
+
19
+ - **git-ns**: Add the git namespaces specification family (#621)
20
+
21
+ * feat(git-ns): add the git namespaces specification family
22
+
23
+ A VTC can say today that a DID may sign commits for an org or a repo, and
24
+ nothing else about git: who owns a repository, who may create one, who may
25
+ merge and who may grant commit rights all live on the forge, and drift from
26
+ the VTC as soon as someone clicks a button. git-ns makes the VTC the source of
27
+ truth for all of it. Rights are per resource, not per role; the Trust Registry
28
+ is the published projection verifiers read, and the forge is the enforced one.
29
+
30
+ Five rights, spelled as the TRQP actions the VTC publishes them under:
31
+ git.ns.admin, git.repo.create, git.repo.own, git.repo.maintain and
32
+ git.commit.sign. Resources are forge-qualified and lowercase
33
+ (github.com/acme/widgets, codeberg.org/acme), so a right never crosses forges
34
+ and a community can host where it likes.
35
+
36
+ Member- and admin-facing tasks, addressed to the VTC:
37
+
38
+ - git-ns/namespace/bind, git-ns/namespace/unbind
39
+ - git-ns/repo/create, git-ns/repo/adopt, git-ns/repo/transfer,
40
+ git-ns/repo/archive
41
+ - git-ns/right/grant, git-ns/right/revoke
42
+ - git-ns/view
43
+ - git-ns/account/link, git-ns/account/link-status
44
+
45
+ git-ns/right/grant carries the family's rights model: implied rights, the
46
+ grant-authority table, and six fixed rules a VTC enforces in its own code
47
+ before policy runs, which policy can narrow and never loosen: scope
48
+ containment, no escalation, the last-owner invariant, a last-admin invariant,
49
+ the members-only floor for namespace rights, and policy-may-only-narrow. Each
50
+ refusal has its own error code, declared once at the family level (git-ns:*).
51
+
52
+ VTC <-> bridge tasks, for the per-community service that holds the forge
53
+ credentials and the forge adapters:
54
+
55
+ - git-ns/bridge/job — seven convergent, forge-neutral job kinds
56
+ - git-ns/bridge/result — exactly one per job, per-step outcomes
57
+ - git-ns/bridge/event — nine forge-neutral event types plus drift
58
+
59
+ Shared shapes (resources, namespaces, RepoSummary, RightRecord, drift) live in
60
+ git-ns/_shared/0.1.
61
+
62
+ Bindings regenerated for Rust, TypeScript, Go and Dart; conformance checks
63
+ agree. trust-tasks-rs gains a git-ns feature, in all-specs.
64
+
65
+ ## 0.20.2 — 2026-09-23
66
+
67
+
68
+ ### Added
69
+
70
+ - **vtc/vetting/vetters/event-mode**: The exception to the constant drip (#620)
71
+
72
+ A vetter's ordinary rate is a few tokens a tick, whether or not they have
73
+ vetted anyone. That is the right rate for ordinary weeks and the wrong one for
74
+ a conference desk, and the answer is deliberately not a bigger drip under the
75
+ same key: it is a separate token label for a named event, with its own rate,
76
+ its own expiry, and a group of vetters large enough that a spend under it still
77
+ hides one.
78
+
79
+ This task carries the vetter's half of that, which is only ever a request. The
80
+ approval is an act by someone else, through the community's own administrative
81
+ surface, and the specification says why there is no Trust Task for it: a task
82
+ the vetter could send is a task a vetter could be made to send.
83
+
84
+ The response says where the request stands, and carries a group *count* rather
85
+ than a group. Who else is at the event is the anonymity set, so the number is
86
+ the most a member may be told — enough to tell "nobody has approved it" from
87
+ "not enough people have asked", which are the two reasons a request waits.
88
+
89
+ - **vetting/attestation**: The four tasks hidden-vetter admission needs (#618)
90
+
91
+ * feat(vetting/attestation): the four tasks hidden-vetter admission needs
92
+
93
+ A community can hide which of its vetters vetted an applicant: the vetter
94
+ attests under a blind class credential, the applicant proves that k distinct
95
+ holders of one attested it, and the community counts the proof with the rule
96
+ it already counts named statements with. What was missing was the wire.
97
+
98
+ Four specifications, and the split between them is the design:
99
+
100
+ - vtc/vetting/vetters/pcs-root — a vetter enrols for a class label. The
101
+ community checks its own records (a live vetter grant, no credential under
102
+ this label yet, the identifier it was bound to) and signs a commitment it
103
+ cannot open. Being named happens here, once per label, and nowhere else on
104
+ the path.
105
+ - vtc/vetting/vetters/pcs-tokens — the vetter draws its tick of attestation
106
+ tokens, unconditionally and at a published rate. A draw that tracked demand
107
+ would report activity, which is what the exchange exists to hide; the quota
108
+ is the community's to enforce, never the asker's restraint.
109
+ - vetting/attestation — vetter to applicant, carrying the facts of the session
110
+ and no issuer. The delivering identity is deliberately NOT what makes it
111
+ count, and a consumer is told not to record it beside the attestation: that
112
+ would recreate, in the applicant's own store, the link the exchange removes.
113
+ - vtc/vetting/pcs-challenge — the applicant asks the community for the
114
+ single-use nonce its proof must bind. Without it a proof verifies as often
115
+ as it is submitted, and the second submission counts as readily as the first.
116
+
117
+ vetting/attestation declares identifierScope: any. Nothing in it needs a
118
+ reusable identifier — the community never sees the document, and the applicant
119
+ only needs the identifier the session was held under — so a pair that runs the
120
+ whole vetting exchange pairwise loses nothing.
121
+
122
+ Bindings regenerated for all four languages; conformance checks agree.
123
+
14
124
  ## 0.20.1 — 2026-09-23
15
125
 
16
126
 
@@ -128,6 +128,10 @@ export type DeviceAttestation_DeviceV0_1 = WebAuthnAttestation_DeviceV0_1 | Appl
128
128
  * Producer-supplied attestation at registration time, verifiable by the maintainer against the platform's attestation infrastructure. Tagged union over the discriminator `kind`.
129
129
  */
130
130
  export type DeviceAttestation_DeviceV0_2 = WebAuthnAttestation_DeviceV0_2 | AppleAppAttest_DeviceV0_2 | PlayIntegrity_DeviceV0_2 | Tpm_DeviceV0_2 | NitroEnclave_DeviceV0_2 | NoAttestation_DeviceV0_2;
131
+ /**
132
+ * A DID, compared by exact string equality.
133
+ */
134
+ export type Did = string;
131
135
  /**
132
136
  * A cryptographic digest as a multibase-encoded multihash — the encoding the W3C Verifiable Credentials Data Model 2.0 defines for `digestMultibase`, and the one `did:webvh` uses for its SCID and entry hashes.
133
137
  *
@@ -193,6 +197,14 @@ export type FaceReach = {
193
197
  * **Superseded by `WorldColour`** — the same set, under the name the rest of the family now uses. Retained because `persona/facet/*` is retired in favour of `persona/world/*`, and a retired specification's schema is frozen, so the definition it references has to stay. New work references `WorldColour`. A colour **name**, resolved by each consumer against its own palette — never a hex value or any other literal. Two reasons, and both are about the consumer rather than the holder. A literal cannot be legible in a terminal, in a light theme and in a dark one at once, so a stored `#8B0000` is a colour that is wrong somewhere and the holder has no way to know where. And a consumer that reserves colours to mean something — an error, a warning, an irreversible act — must be able to keep a holder's decorative choice out of that channel; it cannot do that with an arbitrary value, and it can do it trivially with a closed set it maps itself. The eight members are chosen to be distinguishable from one another and deliberately carry no status connotation: none is named for success, warning or danger.
194
198
  */
195
199
  export type FacetColour = "slate" | "indigo" | "teal" | "moss" | "sand" | "clay" | "rose" | "plum";
200
+ /**
201
+ * The lowercased DNS host of a forge: `github.com`, a GitHub Enterprise Server host, `codeberg.org`, or a self-hosted Forgejo instance such as `git.example.org`. No scheme, no port, no path. The host is a segment of every resource, so a right never crosses forges.
202
+ */
203
+ export type ForgeHost = string;
204
+ /**
205
+ * An identifier the forge itself assigns — a repository id, a user or organisation id — carried as a string so a forge whose ids are not numbers needs no new version. GitHub and Forgejo ids are decimal integers written as strings (`"812736451"`). Unlike a name, it survives renames and transfers, which is why rights and bindings are keyed by it.
206
+ */
207
+ export type ForgeId = string;
196
208
  /**
197
209
  * The highest version among the records `DataCommitment` covers. `0` for a room that holds none.
198
210
  *
@@ -241,6 +253,10 @@ export type LanguageTag = string;
241
253
  * Scopes one application's records within a context, so several tools can share a context without colliding — `openvtc`, `cnm`, an agent runtime. The maintainer MUST NOT interpret the value; it is an opaque partition name. Namespaces are first-come and unreserved, so an application SHOULD pick a stable, specific one: a future per-namespace ACL would grant on this exact string, which makes renaming a namespace a migration rather than an edit.
242
254
  */
243
255
  export type Namespace = string;
256
+ /**
257
+ * The VTC's opaque identifier for a namespace, assigned when it is bound. Stable for the life of the binding; never reused for another binding.
258
+ */
259
+ export type NamespaceId = string;
244
260
  /**
245
261
  * A region or city name as the vetter writes it. Compared case-insensitively and otherwise exactly.
246
262
  */
@@ -409,10 +425,26 @@ export type RecordType = "authorization" | "recognition";
409
425
  * Absent means *not decided by the holder* and resolves from the claim-type registry, which defaults `payment.*` and `gov.*` to `stepUp`.
410
426
  */
411
427
  export type ReleaseRequirement = "consent" | "stepUp";
428
+ /**
429
+ * A forge-qualified resource naming exactly one repository: `<forge-host>/<owner>/<repo>`, lowercase.
430
+ */
431
+ export type RepoResource = string;
432
+ /**
433
+ * Repository visibility on the forge.
434
+ */
435
+ export type RepoVisibility = "public" | "private";
436
+ /**
437
+ * A forge-qualified resource: `<forge-host>/<owner>` for a namespace, or `<forge-host>/<owner>/<repo>` for one repository, all lowercase — `github.com/acme`, `github.com/acme/widgets`, `codeberg.org/acme`. The forge is never implied: `acme/widgets` alone is not a resource. Containment is by whole segment: `github.com/acme` contains `github.com/acme/widgets` and does not contain `github.com/acme-labs/x` or `codeberg.org/acme/widgets`.
438
+ */
439
+ export type Resource = string;
412
440
  /**
413
441
  * Whether a room keeps its history readable across a membership change, fixed at creation and immutable thereafter — like `Visibility`, and for the same reason: the rungs of an epoch key chain either exist for an epoch or they do not, and no later change of mind can seal key material that was never sealed or unseal what was already severed. `chained`: each advance produces an `EpochLink`, so every member reads the room's whole retained history however long they have been in it — what a **library** wants, at the cost of post-compromise security for record content, since a compromised current key then reaches every retained epoch. `fromJoin`: no rungs are produced, so a member reads only from the epoch their group state is at — what a **stream** wants, and what a room under a strict forward-secrecy obligation wants, at the cost that a joining member finds an empty-looking room and nobody can reread a record once their group state has moved past the epoch it was sealed under. Absent means `chained`; see the prose on why the absent case is the readable one.
414
442
  */
415
443
  export type RetentionPolicy = "chained" | "fromJoin";
444
+ /**
445
+ * One of the five git rights. Each string is also the TRQP `action` the VTC publishes the right under in its Trust Registry, so it is carried verbatim. `git.ns.admin` and `git.repo.create` apply to a namespace resource; `git.repo.own` and `git.repo.maintain` to a repository resource; `git.commit.sign` to either.
446
+ */
447
+ export type Right = "git.ns.admin" | "git.repo.create" | "git.repo.own" | "git.repo.maintain" | "git.commit.sign";
416
448
  /**
417
449
  * How a consent prompt reaches the approver: `wake` pushes to the approver's device for a DID-signed decision; `bridge-relay` renders it through an enrolled bridge (e.g. a numbered card in the operator's messaging app) for a bridge-attested decision.
418
450
  */
@@ -457,6 +489,10 @@ export type SecretKind_VaultV0_1 = "password" | "passkey" | "oauth-tokens" | "di
457
489
  * - `custom` — arbitrary structured fields; release-time consumer responsible for interpretation.
458
490
  */
459
491
  export type SecretKind_VaultV0_2 = "password" | "passkey" | "oauthTokens" | "didSelfIssued" | "didcommPeer" | "bearerToken" | "sshKey" | "custom";
492
+ /**
493
+ * One lowercased owner or repository name. Forges compare these case-insensitively, so the wire form is always lowercase and a producer lowercases before sending. A leading `.` is refused, which rules out `.` and `..`.
494
+ */
495
+ export type Segment = string;
460
496
  /**
461
497
  * How carefully a value is shown TO ITS OWN HOLDER. `high` means a consumer masks it by default, reveals it one attribute at a time on a deliberate act, and — the half that is not cosmetic — omits it from a listing that did not ask for sensitive values.
462
498
  *
@@ -1245,6 +1281,27 @@ export interface BackupEnvelope {
1245
1281
  */
1246
1282
  ciphertext: string;
1247
1283
  }
1284
+ /**
1285
+ * Whether each step that turns commit trust on for a repository is in place, as last reported. A step that this forge's plan does not need reads `true`.
1286
+ */
1287
+ export interface Bootstrap {
1288
+ /**
1289
+ * The verify-trust check runs on the repository's pull requests — from a workflow committed to it, or, where the forge supports it, required on it from the namespace's own bridge-managed workflow repository at a pinned commit.
1290
+ */
1291
+ workflow: boolean;
1292
+ /**
1293
+ * The exempt platform keyring for forge-signed merge commits is committed, or the forge's plan does not need one.
1294
+ */
1295
+ keyring: boolean;
1296
+ /**
1297
+ * The repository names the Trust Registry and this VTC as its trust anchors.
1298
+ */
1299
+ variables: boolean;
1300
+ /**
1301
+ * The forge refuses to merge into the default branch unless the verify-trust check passes, with no bypass, and a pull request cannot change what that check runs: an organisation-required workflow, code-owner review of workflow files, or protected workflow paths, as the forge allows.
1302
+ */
1303
+ requiredCheck: boolean;
1304
+ }
1248
1305
  /**
1249
1306
  * The self-description of a pluggable community capability: the Trust Task families it serves, the trust-registry vocabulary it reads and writes, the roles that may operate it, the membership lifecycle hooks it consumes, and the external adapters that act on its decisions. The manifest is what governance approves, what discovery advertises, and what a management UX renders.
1250
1307
  */
@@ -2237,6 +2294,28 @@ export interface DrainEntry {
2237
2294
  drainsUntil: string;
2238
2295
  ext?: Ext;
2239
2296
  }
2297
+ /**
2298
+ * One difference between the forge's observed state and the VTC's projection of a repository.
2299
+ */
2300
+ export interface DriftItem {
2301
+ /**
2302
+ * `roleAdded` — someone holds a forge role the projection does not give them. `roleRemoved` — a projected role is missing. `roleChanged` — a projected role is present at another level. `requiredCheckMissing` — the verify-trust check is no longer required. `protectionWeakened` — branch protection or a ruleset is weaker than the projection in another way (force-push allowed, bypass actors added). `bootstrapMissing` — a bootstrap file or variable is gone.
2303
+ */
2304
+ type: "roleAdded" | "roleRemoved" | "roleChanged" | "requiredCheckMissing" | "protectionWeakened" | "bootstrapMissing";
2305
+ resource: RepoResource;
2306
+ /**
2307
+ * Whose role differs, for the three role types.
2308
+ */
2309
+ account?: ForgeAccount;
2310
+ /**
2311
+ * What the forge shows, in the forge's own vocabulary (a role name such as `maintain`, a setting name). Absent when nothing is there.
2312
+ */
2313
+ observed?: string;
2314
+ /**
2315
+ * What the projection calls for, in the forge's own vocabulary. Absent when the projection calls for nothing.
2316
+ */
2317
+ expected?: string;
2318
+ }
2240
2319
  /**
2241
2320
  * One consequence of executing the pending task, authored by the executor that is about to run it. An effect is produced by dry-running the real handler against the executor's own prior state — never by the requester, and never by re-implementing the handler's semantics elsewhere. A consent surface renders ONLY effects it received under the executor's signature.
2242
2321
  */
@@ -2395,6 +2474,40 @@ export interface Exposure {
2395
2474
  export interface Ext {
2396
2475
  [k: string]: unknown | undefined;
2397
2476
  }
2477
+ /**
2478
+ * A person's account on one forge. `id` is authoritative; `login` is for display only, because logins can be renamed and re-registered.
2479
+ */
2480
+ export interface ForgeAccount {
2481
+ forge: ForgeHost;
2482
+ id: ForgeId;
2483
+ /**
2484
+ * The account's current login, as the forge reported it when last seen. Display only.
2485
+ */
2486
+ login: string;
2487
+ }
2488
+ /**
2489
+ * The VTC's binding to one owner on one forge.
2490
+ */
2491
+ export interface GitNamespace {
2492
+ id: NamespaceId;
2493
+ forge: ForgeHost;
2494
+ /**
2495
+ * The organisation or user on the forge, lowercased.
2496
+ */
2497
+ owner: Segment;
2498
+ /**
2499
+ * Whether the owner is an organisation or a personal account, as the forge reports it. Present once known: a bridge-mode namespace learns it when binding completes, and a manual-mode namespace MAY never learn it.
2500
+ */
2501
+ kind?: "organization" | "user";
2502
+ /**
2503
+ * `bridge` — a bridge service acts on the forge for this namespace (creates repositories, projects roles, reports drift). `manual` — no automation; people with forge access carry out the steps the VTC names, and the VTC governs the rights alone.
2504
+ */
2505
+ mode: "bridge" | "manual";
2506
+ /**
2507
+ * `pending` — binding has started and the forge-side proof has not arrived yet. `bound` — the VTC governs rights under this namespace.
2508
+ */
2509
+ state: "pending" | "bound";
2510
+ }
2398
2511
  /**
2399
2512
  * OpenPGP-style ASCII-armored HPKE bundle — the existing OpenVTC sealed-transfer wire form (X25519-HKDF-SHA256 KEM + ChaCha20-Poly1305 AEAD, framed in armor with Bundle-Id / Digest-Algo headers and a CRC24 checksum). Producer assertion (`did-signed` / `attested` / `pinned-only`) is the integrity / authenticity anchor.
2400
2513
  *
@@ -3652,6 +3765,27 @@ export interface RejectedKey {
3652
3765
  */
3653
3766
  reason: string;
3654
3767
  }
3768
+ /**
3769
+ * One repository as the VTC records it.
3770
+ */
3771
+ export interface RepoSummary {
3772
+ resource: RepoResource;
3773
+ /**
3774
+ * The forge's repository id. Absent until the forge has confirmed the repository exists (a `pendingCreate` repository, or one adopted in bridge mode before the first inspection).
3775
+ */
3776
+ forgeId?: ForgeId;
3777
+ visibility: RepoVisibility;
3778
+ /**
3779
+ * `pendingCreate` — the name is reserved and the repository is not yet confirmed on the forge. `active` — managed. `archived` — archived through git-ns/repo/archive; commit rights on it are revoked. `detached` — no longer governed: its namespace was unbound, or it moved outside the namespace. `orphaned` — its last owner left the community and ownership passed to the namespace admins, who have not yet named a new owner. `unmanaged` — it exists on the forge inside a bound namespace but was never created or adopted through the VTC.
3780
+ */
3781
+ state: "pendingCreate" | "active" | "archived" | "detached" | "orphaned" | "unmanaged";
3782
+ /**
3783
+ * The DIDs holding `git.repo.own` on this repository by an explicit grant. Empty only for an `unmanaged` repository, and for an `orphaned` one whose ownership rests with the namespace admins by implication.
3784
+ */
3785
+ owners: Did[];
3786
+ bootstrap: Bootstrap;
3787
+ sync: Sync;
3788
+ }
3655
3789
  /**
3656
3790
  * One held credential a deferred query asked for, and the claims of it that would be disclosed.
3657
3791
  */
@@ -3727,6 +3861,30 @@ export interface RevocationReceipt {
3727
3861
  */
3728
3862
  revokedAt: string;
3729
3863
  }
3864
+ /**
3865
+ * One recorded right. Implied rights (§4.2 of the rights model: `own` implies `maintain` implies `commit.sign` on the same resource; `ns.admin` implies `repo.create` and `own` across its namespace) are not records and never appear as RightRecords.
3866
+ */
3867
+ export interface RightRecord {
3868
+ /**
3869
+ * Who holds the right. For `git.commit.sign` this is the DID whose commit signatures the CI check accepts.
3870
+ */
3871
+ subject: Did;
3872
+ right: Right;
3873
+ resource: Resource;
3874
+ /**
3875
+ * The actor whose task caused the right: the granter, the creator of a repository (for its first `own`), the adopting admin, the transferring owner, or the binding admin (for the first `git.ns.admin`). The VTC's own DID for a right it derives from its configuration.
3876
+ */
3877
+ grantedBy: Did;
3878
+ grantedAt: string;
3879
+ /**
3880
+ * When the right lapses. Absent: no expiry.
3881
+ */
3882
+ expiresAt?: string;
3883
+ /**
3884
+ * The granter's free-text reason. Disclosed only to holders of `git.repo.own` on the resource and of `git.ns.admin` over it.
3885
+ */
3886
+ reason?: string;
3887
+ }
3730
3888
  /**
3731
3889
  * The outcome of a rollback. Distinct from ServiceMutationResult because a rollback can legitimately publish nothing: if the previous state already equals the current one there is no change to write, and `kind: "noOp"` says so with `logEntryVersionId` absent. Treating that as a failure would be wrong — the requested state holds — and treating it as an ordinary success would report a log entry that does not exist.
3732
3890
  */
@@ -4026,6 +4184,23 @@ export interface StreamDescriptor {
4026
4184
  expectedSizeBytes: ExpectedSizeBytes;
4027
4185
  expiresAt: ExpiresAt;
4028
4186
  }
4187
+ /**
4188
+ * How the forge compares with the VTC's projection for one repository.
4189
+ */
4190
+ export interface Sync {
4191
+ /**
4192
+ * `inSync` — the last comparison found no drift. `drift` — it found some, listed in `drift`. `pending` — a change has been sent to the forge and not yet confirmed. `unchecked` — nothing compares this repository (a manual-mode namespace).
4193
+ */
4194
+ state: "inSync" | "drift" | "pending" | "unchecked";
4195
+ /**
4196
+ * When the forge was last compared. Absent if never.
4197
+ */
4198
+ checkedAt?: string;
4199
+ /**
4200
+ * Outstanding drift. Empty unless `state` is `drift`.
4201
+ */
4202
+ drift: DriftItem[];
4203
+ }
4029
4204
  /**
4030
4205
  * An access token (typically short-lived JWT) paired with an optional refresh token (typically long-lived opaque string). The shapes follow OAuth 2.0 (RFC 6749 §5.1) conventions but are not coupled to any particular OAuth profile.
4031
4206
  */