@tiinex/core 0.18.0 → 0.20.0

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 (38) hide show
  1. package/package.json +8 -6
  2. package/src/schemas/creation.contracts.js +1 -1
  3. package/src/schemas/party/role/tiinex.party.role.v1.schema.js +5 -0
  4. package/src/schemas/party/role/tiinex.party.role.v1.schema.json +2 -2
  5. package/src/schemas/party/role/tiinex.party.role.v1.schema.md +313 -0
  6. package/src/schemas/party/role/tiinex.party.role.v1.schema.runtime.json +18 -6
  7. package/src/schemas/party/role/tiinex.party.role.v1.validate.js +36 -0
  8. package/src/schemas/schema.reference.js +29 -0
  9. package/src/tooling/portable/adapters/cli/cli.command-input.js +8 -1
  10. package/src/tooling/portable/adapters/cli/cli.common-author.js +117 -6
  11. package/src/tooling/portable/adapters/cli/cli.common-output.js +26 -0
  12. package/src/tooling/portable/adapters/cli/cli.handoff-manufacture.js +33 -17
  13. package/src/tooling/portable/adapters/cli/cli.handoff-sibling-allocation.js +139 -2
  14. package/src/tooling/portable/adapters/cli/cli.help.js +1 -1
  15. package/src/tooling/portable/adapters/node/handoff.manufacture.js +30 -5
  16. package/src/tooling/portable/adapters/node/handoff.manufacture.packageParent.js +123 -0
  17. package/src/tooling/portable/audit/audit.capability.js +10 -4
  18. package/src/tooling/portable/grounding/grounding.capsule.js +33 -2
  19. package/src/tooling/portable/grounding/grounding.delegationArtifactAuthority.js +220 -0
  20. package/src/tooling/portable/grounding/grounding.delegationReadiness.js +241 -0
  21. package/src/tooling/portable/grounding/grounding.holderAssignmentModes.js +125 -0
  22. package/src/tooling/portable/grounding/grounding.holderBindingAuthorization.js +80 -0
  23. package/src/tooling/portable/grounding/grounding.implementationSourceAuthority.js +109 -0
  24. package/src/tooling/portable/grounding/grounding.participantAuthority.js +1 -1
  25. package/src/tooling/portable/grounding/grounding.readiness.authority.js +15 -0
  26. package/src/tooling/portable/grounding/grounding.readiness.js +86 -13
  27. package/src/tooling/portable/grounding/grounding.readiness.support.js +2 -2
  28. package/src/tooling/portable/handoff/carrierProjection.routeQualification.js +20 -4
  29. package/src/tooling/portable/handoff/coldStartQualification.grounding.js +116 -5
  30. package/src/tooling/portable/handoff/coldStartQualification.materials.js +92 -10
  31. package/src/tooling/portable/handoff/delegationReturnReservation.js +4 -2
  32. package/src/tooling/portable/handoff/manufacture.js +1 -0
  33. package/src/tooling/portable/handoff/recipientV2.endpointRolePointers.js +1 -1
  34. package/src/tooling/portable/handoff/recipientV2.inspect.projection.js +7 -1
  35. package/src/tooling/portable/handoff/recipientV2.packageV1.build.js +2 -2
  36. package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.js +1 -1
  37. package/src/tooling/portable/handoff/recipientV2.topology.js +5 -3
  38. package/src/tooling/portable/handoff/recipientV2.topology.materials.js +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiinex/core",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Shared host-neutral Tiinex implementation core for artifacts, schemas, validation, lineage, grounding, Handoffs, provenance and deterministic workflows.",
5
5
  "type": "module",
6
6
  "sideEffects": true,
@@ -79,6 +79,7 @@
79
79
  "./tooling/portable/grounding/grounding.capsule.js": "./src/tooling/portable/grounding/grounding.capsule.js",
80
80
  "./tooling/portable/grounding/grounding.participantAuthority.js": "./src/tooling/portable/grounding/grounding.participantAuthority.js",
81
81
  "./tooling/portable/grounding/grounding.processApplicability.js": "./src/tooling/portable/grounding/grounding.processApplicability.js",
82
+ "./tooling/portable/grounding/grounding.implementationSourceAuthority.js": "./src/tooling/portable/grounding/grounding.implementationSourceAuthority.js",
82
83
  "./tooling/portable/grounding/grounding.readiness.js": "./src/tooling/portable/grounding/grounding.readiness.js",
83
84
  "./tooling/portable/grounding/grounding.workProvenance.js": "./src/tooling/portable/grounding/grounding.workProvenance.js",
84
85
  "./tooling/portable/handoff/carrierLineage.js": "./src/tooling/portable/handoff/carrierLineage.js",
@@ -138,7 +139,8 @@
138
139
  "./tooling/portable/source/sourceEligibility.js": "./src/tooling/portable/source/sourceEligibility.js",
139
140
  "./tooling/portable/comparison/sourceFrontierComparison.js": "./src/tooling/portable/comparison/sourceFrontierComparison.js",
140
141
  "./tooling/portable/adapters/node/sourceFrontierComparison.js": "./src/tooling/portable/adapters/node/sourceFrontierComparison.js",
141
- "./tooling/portable/handoff/recoveryAcceptanceAudit.js": "./src/tooling/portable/handoff/recoveryAcceptanceAudit.js"
142
+ "./tooling/portable/handoff/recoveryAcceptanceAudit.js": "./src/tooling/portable/handoff/recoveryAcceptanceAudit.js",
143
+ "./tooling/portable/grounding/grounding.delegationReadiness.js": "./src/tooling/portable/grounding/grounding.delegationReadiness.js"
142
144
  },
143
145
  "files": [
144
146
  "src",
@@ -170,12 +172,12 @@
170
172
  "type": "git",
171
173
  "url": "git+https://github.com/Tiinex/core.git"
172
174
  },
173
- "gitHead": "12321ec2a8d09722b464ef7977afa2dcdc924718",
175
+ "gitHead": "75e2e1e324fbe2e652a5c94f877ce6bf68e4a521",
174
176
  "tiinexRelease": {
175
177
  "policy": "tiinex.master-npm-release.v1",
176
- "sourceCommit": "12321ec2a8d09722b464ef7977afa2dcdc924718",
177
- "sourceTree": "eba0d10ad8f5fc20cc1c98ee88c328fbd4dafa4c",
178
+ "sourceCommit": "75e2e1e324fbe2e652a5c94f877ce6bf68e4a521",
179
+ "sourceTree": "3138e1fdb8c064ec3417a55a731310aa8efd66b8",
178
180
  "repository": "Tiinex/core",
179
- "previousVersion": "0.17.0"
181
+ "previousVersion": "0.19.0"
180
182
  }
181
183
  }
@@ -181,7 +181,7 @@ export function validateArtifactCreationResult(draft = {}, parentRecord = {}, op
181
181
  const parentSchemaAuthority = parentRecord.schemaReferenceAuthority || {};
182
182
  const parentSchemaReference = qualifySchemaReferenceValue(parent.schema?.raw || '', parentSchemaAuthority, { requireExactTargetWhenQualified: true });
183
183
  for (const [index, message] of (parentSchemaReference.findings || []).entries()) findings.push(error(`creation.parent-schema-reference.${index + 1}`, message));
184
- if (parentSchemaAuthority.resolutionState !== 'qualified') findings.push(error('creation.parent-schema-reference.unresolved', 'Exact continuation requires the declared Parent Schema reference authority to be resolver-qualified.'));
184
+ if (parentSchemaAuthority.resolutionState !== 'qualified') findings.push(error('creation.parent-schema-reference.unresolved', 'Exact continuation requires qualified Parent Schema reference authority at the strength actually known: either an exact target or a qualified historical schema identifier.'));
185
185
  } else if (!rootCreation) findings.push(error('creation.parent.required', 'Continuation creation requires an exact supplied Parent authority.'));
186
186
 
187
187
  if (draft.status !== 'local') findings.push(error('creation.result.status.not-local', 'Creation result must stay local until explicit publication/export.'));
@@ -1,6 +1,9 @@
1
1
  import { defineSchemaModule } from '../../contracts.js';
2
+ import { genericArtifactCreationImplementation } from '../../creation.renderer.js';
3
+ import { defineArtifactCreationCapability } from '../../creation.capability.js';
2
4
  import binding from './tiinex.party.role.v1.schema.json' with { type: 'json' };
3
5
  import { schemaSource } from './tiinex.party.role.v1.schema.source.js';
6
+ import { partyRoleValidate } from './tiinex.party.role.v1.validate.js';
4
7
 
5
8
  export const partyRoleSchemaModule = defineSchemaModule({
6
9
  id: 'tiinex.party.role.v1',
@@ -11,6 +14,8 @@ export const partyRoleSchemaModule = defineSchemaModule({
11
14
  summary: "Schema for a bounded role, capacity, responsibility, or authority-facing position without treating the role as proof that a particular person holds it.",
12
15
  binding,
13
16
  schemaSource,
17
+ artifactCreation: defineArtifactCreationCapability(binding, Object.freeze({ ...genericArtifactCreationImplementation, transitionTypes: Object.freeze(['create-artifact', 'continue-from-record']) })),
18
+ validate: partyRoleValidate,
14
19
  capabilities: Object.freeze({
15
20
  supportedSurfaces: Object.freeze(['feed', 'tree', 'detail', 'lineage', 'preview', 'share']),
16
21
  canRenderFallback: true,
@@ -10,10 +10,10 @@
10
10
  "sourcePath": ".topics/.schemas/party/role/tiinex.party.role.v1.schema.md",
11
11
  "sourceRepository": "Tiinex/docs",
12
12
  "sourceCommit": "3988951208eb9a8926e84ab42625d4b42fa00c2d",
13
- "sourceBlobSha": "16687051579d5c850591d4bf4e2dbd9705f83983",
13
+ "sourceBlobSha": "ba134b998fb3d04a59a3bd5cd951115ea272ebda",
14
14
  "checksum": {
15
15
  "algorithm": "sha256",
16
- "value": "16b6bd63b9ba6044906aa9daa9bd289881171ddc875b3b9e7c2158470ad27828"
16
+ "value": "2887aef16cf827b78fe38c1a2ba97cb5820d79049729d2cf8696ecf1de828871"
17
17
  },
18
18
  "capabilityContract": "tiinex.schema.module.v1",
19
19
  "snapshotCompleteness": "exact-axiom-canonical-unpublished-bounded-workspace-contract",
@@ -0,0 +1,313 @@
1
+ # Continuity Context
2
+
3
+ - Envelope Schema: [tiinex.root.v1](../../tiinex.root.v1.schema.md)
4
+ - Parent
5
+ - Parent Schema: [tiinex.party.v1](../tiinex.party.v1.schema.md)
6
+ - Created At: 2026-06-30 00:00:00
7
+ - Trace: [tiinex.party.v1.schema.md](../tiinex.party.v1.schema.md)
8
+ - Origin:
9
+ - [relative](../tiinex.party.v1.schema.md)
10
+ - [browse + git](https://github.com/Tiinex/docs/blob/2a40646640f7468bcd250df6988b69e9f047f1bb/.topics/.schemas/party/tiinex.party.v1.schema.md)
11
+ - Current
12
+ - Current Schema: [tiinex.party.role.v1](tiinex.party.role.v1.schema.md)
13
+ - Created At: 2026-06-30 00:00:00
14
+ - Summary: Schema for a bounded role, capacity, responsibility, or authority-facing position without treating the role as proof that a particular person holds it.
15
+
16
+ ---
17
+
18
+ # Party Role
19
+
20
+ - Status: draft schema note
21
+
22
+ ## Summary
23
+
24
+ Schema for a bounded role, capacity, responsibility, or authority-facing position without treating the role as proof that a particular person holds it.
25
+
26
+ This schema is human-first. It should be readable by a person who knows the parent schema but does not know a specialized app, programming language, management tool, calendar tool, or database.
27
+
28
+ ## Schema Validation Contract
29
+
30
+ ### Party Role Scope
31
+
32
+ Applies To
33
+
34
+ - artifacts whose `Current -> Current Schema` is `tiinex.party.role.v1`
35
+
36
+ Rules
37
+
38
+ - `tiinex.party.role.v1` identifies artifacts whose main job is to preserve party role semantics.
39
+ - A party role artifact should state its identity, boundary, state, related targets, and interpretation limits in human-readable form.
40
+ - A party role artifact must not silently become proof, consent, authority, attendance, allocation, validation, or truth unless those claims are separately supported by the appropriate schema or method.
41
+ - Prose outside `Schema Validation Contract` may explain the schema, but it does not add required validation rules.
42
+
43
+ ### Parent Party Specialization
44
+
45
+ Rules
46
+
47
+ - Party role artifacts specialize the inherited `Party Body` for artifacts whose `Current -> Current Schema` is `tiinex.party.role.v1`.
48
+ - The child body replaces the parent party body sections for `tiinex.party.role.v1` artifacts.
49
+ - `Role Body` is the local body contract for this child schema.
50
+ - Role Identity specializes Party Identity.
51
+ - Role Boundary specializes Party Boundary.
52
+ - Authority And Responsibility Boundary specializes Role Or Capacity without proving authority by itself.
53
+ - Holder Relationship preserves related-party semantics without becoming identity proof.
54
+ - Parent party specialization applies to the artifact body only; it does not alter root continuity, integrity, or parent-origin requirements.
55
+
56
+ Inheritance Overrides
57
+
58
+ - party-role-party-body-structure
59
+ - Merge Operation: override
60
+ - Parent Schema: tiinex.party.v1
61
+ - Parent Node: Schema Validation Contract / Party Body / Required Shape
62
+ - Child Node: Schema Validation Contract / Party Role Body / Required Shape
63
+ - Reason: Party Role specializes Party by replacing only the generic Party artifact-body structure while retaining compatible non-structural Party semantics and provenance.
64
+ - Effective Result: Party Role body structure is authoritative for Party Role artifacts; parent-only structural body groups become inactive, while compatible parent contributions targeting surviving Party Role sections remain active.
65
+
66
+ ### Party Role Body
67
+
68
+ Required Shape
69
+
70
+ - first body heading after the continuity envelope
71
+ - `## Role Identity` section
72
+ - `## Role Boundary` section
73
+ - `## Authority And Responsibility Boundary` section
74
+ - `## Holder Relationship` section
75
+ - `## Interpretation Limits` section
76
+
77
+ Optional Sections
78
+
79
+ - Related Artifacts
80
+ - References
81
+
82
+ Rules
83
+
84
+ - A party role artifact should begin with a human-readable title.
85
+ - Required sections should be readable without specialized tooling.
86
+ - Required sections should be structured enough that a reader, tool, or LLM can extract boundaries without guessing.
87
+ - Follow-up sections must not replace the declared boundary and interpretation limits.
88
+ ### Role Identity
89
+
90
+ Required Fields
91
+
92
+ - Role Label
93
+ - Role Kind
94
+
95
+ Optional Fields
96
+
97
+ - Canonical Identifier
98
+ - Organization
99
+ - Project
100
+ - Group
101
+
102
+ Rules
103
+
104
+ - `Role Identity` must remain human-readable and bounded.
105
+ - `Role Identity` must state what is known, what is unknown, and what must not be inferred when those limits matter.
106
+ - `Role Identity` may reference relation, evidence, attestation, validation, privacy, source, access, resource, party, event, project, or instrument artifacts when those artifacts own companion semantics.
107
+
108
+ ### Role Boundary
109
+
110
+ Required Fields
111
+
112
+ - In Scope
113
+ - Out Of Scope
114
+
115
+ Optional Fields
116
+
117
+ - Valid From
118
+ - Valid Until
119
+ - Context
120
+
121
+ Rules
122
+
123
+ - `Role Boundary` must remain human-readable and bounded.
124
+ - `Role Boundary` must state what is known, what is unknown, and what must not be inferred when those limits matter.
125
+ - `Role Boundary` may reference relation, evidence, attestation, validation, privacy, source, access, resource, party, event, project, or instrument artifacts when those artifacts own companion semantics.
126
+
127
+ ### Authority And Responsibility Boundary
128
+
129
+ Required Fields
130
+
131
+ - May Do
132
+ - Does Not Authorize
133
+
134
+ Optional Fields
135
+
136
+ - Required Instrument
137
+ - Delegation
138
+ - Review Boundary
139
+
140
+ Rules
141
+
142
+ - `Authority And Responsibility Boundary` must remain human-readable and bounded.
143
+ - `Authority And Responsibility Boundary` must state what is known, what is unknown, and what must not be inferred when those limits matter.
144
+ - `Authority And Responsibility Boundary` may reference relation, evidence, attestation, validation, privacy, source, access, resource, party, event, project, or instrument artifacts when those artifacts own companion semantics.
145
+
146
+ ### Holder Relationship
147
+
148
+ Required Fields
149
+
150
+ - Holder State
151
+ - Assignment Modes
152
+
153
+ Optional Fields
154
+
155
+ - Current Holder
156
+ - Possible Holder
157
+ - Unknown Holder
158
+ - Relation Artifact
159
+
160
+ Rules
161
+
162
+ - `Holder Relationship` must remain human-readable and bounded.
163
+ - `Holder State` is the human-readable bounded holder summary. It must not be used as positive machine authority for holder assignment.
164
+ - `Assignment Modes` is the canonical machine-readable holder-assignment authorization field for artifacts qualified against this current schema revision.
165
+ - Canonical `Assignment Modes` values are: `explicit-session`, `explicit-user-session`, `explicit-role-invocation`, `handoff`, `explicit-participation`.
166
+ - The canonical serialized field value is a comma-separated list of plain canonical tokens, using `, ` as the separator and the canonical token order shown above when more than one mode is present. Aliases, prose, code-span quoting, duplicate values, unknown tokens, and lexical near-matches are not canonical values.
167
+ - A current operational Role that is intended to authorize bounded holder assignment must declare at least one canonical mode. Missing or empty `Assignment Modes` cannot positively authorize a holder binding.
168
+ - `Assignment Modes` authorizes only the named bounded assignment mechanisms. It does not assert a current holder, establish durable holder identity, create participation, make a process applicable, delegate work, authorize source mutation, prove Handoff acceptance, or widen `Possible Holder` and Role-boundary constraints.
169
+ - `handoff` as an assignment mode does not make a Handoff endpoint or package recipient a holder by itself; separately qualified Handoff-bounded assignment evidence is still required.
170
+ - `explicit-user-session` must not be widened to `explicit-session`; `explicit-participation` must not be converted into session or invocation authorization; `explicit-session` and `explicit-role-invocation` remain separate modes.
171
+ - `Holder Relationship` must state what is known, what is unknown, and what must not be inferred when those limits matter.
172
+ - `Holder Relationship` may reference relation, evidence, attestation, validation, privacy, source, access, resource, party, event, project, or instrument artifacts when those artifacts own companion semantics.
173
+
174
+ ### Interpretation Limits
175
+
176
+ Required Fields
177
+
178
+ - Does Not Prove
179
+ - Must Not Be Treated As
180
+
181
+ Optional Fields
182
+
183
+ - Employment Limits
184
+ - Consent Limits
185
+
186
+ Rules
187
+
188
+ - `Interpretation Limits` must remain human-readable and bounded.
189
+ - `Interpretation Limits` must state what is known, what is unknown, and what must not be inferred when those limits matter.
190
+ - `Interpretation Limits` may reference relation, evidence, attestation, validation, privacy, source, access, resource, party, event, project, or instrument artifacts when those artifacts own companion semantics.
191
+
192
+ ### Allowed Or Common Shapes
193
+
194
+ Allowed Shapes
195
+
196
+ - project lead
197
+ - reviewer
198
+ - maintainer
199
+ - facilitator
200
+ - witness
201
+ - safety officer
202
+ - resource owner
203
+ - on-call role
204
+
205
+ Rules
206
+
207
+ - Allowed shapes are guidance for common reading and grouping, not an exhaustive vocabulary.
208
+ - Local artifacts may use another precise human-readable shape when the declared boundaries remain clear.
209
+
210
+ ### File Naming
211
+
212
+ Allowed Shapes
213
+
214
+ - `<lineage>.trace.md`
215
+ - `<lineage>-party-role.trace.md`
216
+ - `<lineage>-<party-role-slug>.trace.md`
217
+
218
+ Rules
219
+
220
+ - Artifacts should keep the lineage label first.
221
+ - The optional slug should describe the bounded artifact role rather than a low-signal implementation detail.
222
+ - Ordinary lineage artifacts should keep the `.trace.md` suffix stable.
223
+
224
+ ### Interpretation Boundaries
225
+
226
+ Rules
227
+
228
+ - Use `tiinex.party.role.v1` when the main artifact value is the declared party role role.
229
+ - Do not use `tiinex.party.role.v1` to replace evidence, attestation, validation, consent, relation, task, decision, event, party, resource, or instrument artifacts when those schemas own the main role.
230
+ - Parent remains direct continuity ancestry; related targets should be represented through relation or target fields unless direct continuation is being declared.
231
+
232
+ ## Artifact Creation Contract
233
+
234
+ ### Creation Fields
235
+
236
+ Required Fields
237
+
238
+ - Role Label
239
+ - Role Kind
240
+ - In Scope
241
+ - Out Of Scope
242
+ - May Do
243
+ - Does Not Authorize
244
+ - Holder State
245
+ - Assignment Modes
246
+ - Does Not Prove
247
+ - Must Not Be Treated As
248
+
249
+ ### Creation Rules
250
+
251
+ Rules
252
+
253
+ - Creation tools should keep the artifact human-readable and bounded.
254
+ - Creation tools creating or revising a current `tiinex.party.role.v1` artifact must emit `Assignment Modes` directly in `Holder Relationship`; they must not substitute `Holder State` prose, a Decision-side legacy mapping, filename identity, or Tooling-local compatibility data.
255
+ - Creation tools should serialize multiple Assignment Modes as plain canonical tokens separated by `, ` in canonical token order and should reject aliases, duplicate tokens, unknown tokens, code-span quoting, and arbitrary prose in that field.
256
+ - Creation tools should preserve unknown, partial, contested, private, unsafe, unavailable, or ambiguous state instead of inventing certainty. When holder-assignment authorization is unresolved, the artifact must not be treated as authorizing a bounded holder merely because `Holder State` prose appears familiar.
257
+ ## Minimal Example
258
+
259
+ ```md
260
+ # Party Role Example
261
+
262
+ ## Role Identity
263
+
264
+ - Role Label: bounded example for tiinex.party.role.v1
265
+ - Role Kind: bounded example for tiinex.party.role.v1
266
+
267
+ ## Role Boundary
268
+
269
+ - In Scope: bounded example for tiinex.party.role.v1
270
+ - Out Of Scope: bounded example for tiinex.party.role.v1
271
+
272
+ ## Authority And Responsibility Boundary
273
+
274
+ - May Do: bounded example for tiinex.party.role.v1
275
+ - Does Not Authorize: bounded example for tiinex.party.role.v1
276
+
277
+ ## Holder Relationship
278
+
279
+ - Holder State: bounded example for tiinex.party.role.v1
280
+ - Assignment Modes: explicit-session, handoff
281
+
282
+ ## Interpretation Limits
283
+
284
+ - Does Not Prove: truth, consent, authority, attendance, allocation, or final outcome by itself
285
+ - Must Not Be Treated As: tiinex.party.role.v1 example must not be treated as proof outside its declared boundary
286
+ ```
287
+
288
+ ## Validation-Friendly Shape
289
+
290
+ Keep this schema note in the exact section order already used here: `Summary`, `Schema Validation Contract`, `Artifact Creation Contract`, `Minimal Example`, `Validation-Friendly Shape`, and `Interpretation Notes`.
291
+
292
+ Maintain the section headings exactly in this schema note. Free markdown inside those sections is allowed, but adding undeclared new section headings should be treated as schema drift.
293
+
294
+ The body headings required for artifacts using this schema are: `## Role Identity`, `## Role Boundary`, `## Authority And Responsibility Boundary`, `## Holder Relationship`, `## Interpretation Limits`.
295
+
296
+ ## Interpretation Notes
297
+
298
+ - role is not the person holding it
299
+ - role does not prove authority unless authority is separately supported
300
+ - `Assignment Modes` is the only current machine-authoritative holder-assignment representation in this schema revision; `Holder State` remains human-readable context
301
+ - historical artifacts may remain auditable against the exact schema/source revision they originally declared, but historical compatibility does not create current holder-assignment authorization
302
+
303
+ ---
304
+
305
+ # Continuity Integrity
306
+
307
+ - sha256-base64url-c14n-v1
308
+ - Towards: [tiinex.party.v1.schema.md](https://github.com/Tiinex/docs/blob/2a40646640f7468bcd250df6988b69e9f047f1bb/.topics/.schemas/party/tiinex.party.v1.schema.md)
309
+ - Value: m-C4EsPECe8ZZ4rJ_99MlV5ougMsI_gIDtCCDk1MLWY
310
+
311
+ - sha256-base64url-c14n-v2
312
+ - Towards: self
313
+ - Value: rA6BGI_Af8Ggy74sZGxtBXH9U9we0Q8f4GH19QsmT2U
@@ -2,10 +2,10 @@
2
2
  "schema": "tiinex.site.schema-runtime-projection.v1",
3
3
  "generator": "schema-runtime-projection-v1",
4
4
  "schemaId": "tiinex.party.role.v1",
5
- "sourceChecksum": "16b6bd63b9ba6044906aa9daa9bd289881171ddc875b3b9e7c2158470ad27828",
6
- "sourceBlobSha": "16687051579d5c850591d4bf4e2dbd9705f83983",
7
- "sourceBytes": 10364,
8
- "bindingChecksum": "16b6bd63b9ba6044906aa9daa9bd289881171ddc875b3b9e7c2158470ad27828",
5
+ "sourceChecksum": "2887aef16cf827b78fe38c1a2ba97cb5820d79049729d2cf8696ecf1de828871",
6
+ "sourceBlobSha": "ba134b998fb3d04a59a3bd5cd951115ea272ebda",
7
+ "sourceBytes": 13216,
8
+ "bindingChecksum": "2887aef16cf827b78fe38c1a2ba97cb5820d79049729d2cf8696ecf1de828871",
9
9
  "validationContract": {
10
10
  "schema": "tiinex.site.compact-portable-validation-contract.v1",
11
11
  "schemaId": "tiinex.party.role.v1",
@@ -413,7 +413,8 @@
413
413
  "findings": []
414
414
  },
415
415
  "requiredFields": [
416
- "Holder State"
416
+ "Holder State",
417
+ "Assignment Modes"
417
418
  ],
418
419
  "optionalFields": [
419
420
  "Current Holder",
@@ -426,7 +427,8 @@
426
427
  "sourceSchemaId": "tiinex.party.role.v1",
427
428
  "group": "Holder Relationship",
428
429
  "requiredFields": [
429
- "Holder State"
430
+ "Holder State",
431
+ "Assignment Modes"
430
432
  ],
431
433
  "optionalFields": [
432
434
  "Current Holder",
@@ -1996,6 +1998,7 @@
1996
1998
  "May Do",
1997
1999
  "Does Not Authorize",
1998
2000
  "Holder State",
2001
+ "Assignment Modes",
1999
2002
  "Does Not Prove",
2000
2003
  "Must Not Be Treated As"
2001
2004
  ],
@@ -2066,6 +2069,15 @@
2066
2069
  "sourceSchemaId": "tiinex.party.role.v1",
2067
2070
  "requirement": "required"
2068
2071
  },
2072
+ {
2073
+ "input": "Assignment Modes",
2074
+ "kind": "ordinary-field",
2075
+ "section": "Holder Relationship",
2076
+ "group": "Holder Relationship",
2077
+ "field": "Assignment Modes",
2078
+ "sourceSchemaId": "tiinex.party.role.v1",
2079
+ "requirement": "required"
2080
+ },
2069
2081
  {
2070
2082
  "input": "Does Not Prove",
2071
2083
  "kind": "ordinary-field",
@@ -0,0 +1,36 @@
1
+ const ASSIGNMENT_MODE_ORDER = Object.freeze([
2
+ 'explicit-session',
3
+ 'explicit-user-session',
4
+ 'explicit-role-invocation',
5
+ 'handoff',
6
+ 'explicit-participation'
7
+ ]);
8
+ const ASSIGNMENT_MODE_SET = new Set(ASSIGNMENT_MODE_ORDER);
9
+
10
+ export function partyRoleValidate(artifact = {}) {
11
+ if (artifact?.envelope?.current?.schema?.id !== 'tiinex.party.role.v1') return [{ severity: 'warning', code: 'party.role.schema.mismatch', messageKey: 'party.role.schema.mismatch', message: 'Party Role validator invoked for a non-Role current schema.', source: 'tiinex.party.role.v1' }];
12
+ const section = sectionBody(String(artifact?.body?.text || ''), 'Holder Relationship');
13
+ const values = fieldValues(section, 'Assignment Modes');
14
+ if (values.length !== 1) return [{ severity: 'error', code: values.length ? 'party.role.assignmentModes.duplicate-field' : 'party.role.assignmentModes.missing', messageKey: values.length ? 'party.role.assignmentModes.duplicate-field' : 'party.role.assignmentModes.missing', message: values.length ? 'Holder Relationship must contain exactly one Assignment Modes field.' : 'Holder Relationship must declare Assignment Modes directly.', source: 'tiinex.party.role.v1', fixability: 'manual' }];
15
+ const raw = values[0];
16
+ if (!raw) return [{ severity: 'error', code: 'party.role.assignmentModes.empty', messageKey: 'party.role.assignmentModes.empty', message: 'Assignment Modes must contain at least one canonical assignment-mode token.', source: 'tiinex.party.role.v1', fixability: 'manual' }];
17
+ const tokens = raw.split(', ');
18
+ const canonical = tokens.length > 0
19
+ && tokens.every((token) => ASSIGNMENT_MODE_SET.has(token))
20
+ && new Set(tokens).size === tokens.length
21
+ && tokens.every((token, index) => index === 0 || ASSIGNMENT_MODE_ORDER.indexOf(tokens[index - 1]) < ASSIGNMENT_MODE_ORDER.indexOf(token))
22
+ && tokens.join(', ') === raw;
23
+ if (!canonical) return [{ severity: 'error', code: 'party.role.assignmentModes.invalid', messageKey: 'party.role.assignmentModes.invalid', message: `Assignment Modes must be plain canonical tokens separated by ", " in canonical order. Allowed values: ${ASSIGNMENT_MODE_ORDER.join(', ')}.`, source: 'tiinex.party.role.v1', fixability: 'manual', params: { field: 'Assignment Modes', allowedValues: ASSIGNMENT_MODE_ORDER.join(', ') } }];
24
+ return [{ severity: 'info', code: 'party.role.assignmentModes.canonical', messageKey: 'party.role.assignmentModes.canonical', message: 'Assignment Modes is present and canonical.', source: 'tiinex.party.role.v1', params: { field: 'Assignment Modes' } }];
25
+ }
26
+
27
+ function sectionBody(markdown = '', heading = '') {
28
+ const escaped = escapeRegExp(heading);
29
+ const match = String(markdown || '').match(new RegExp(`^##\\s+${escaped}\\s*$([\\s\\S]*?)(?=^##\\s+|\\Z)`, 'm'));
30
+ return match?.[1] || '';
31
+ }
32
+ function fieldValues(section = '', label = '') {
33
+ const escaped = escapeRegExp(label);
34
+ return [...String(section || '').matchAll(new RegExp(`^\\s*-\\s*${escaped}:\\s*(.*?)\\s*$`, 'gm'))].map((match) => match[1]);
35
+ }
36
+ function escapeRegExp(value = '') { return String(value).replace(/[.*+?^${}()|[\\]\\]/g, '\\$&'); }
@@ -106,6 +106,35 @@ function materialIdentitiesMatch(semantic = {}, resolved = {}) {
106
106
  return true;
107
107
  }
108
108
 
109
+
110
+ export function qualifiedIdentifierOnlyHistoricalSchemaReferenceAuthority(schemaId = '', evidence = {}) {
111
+ const id = String(schemaId || '').trim();
112
+ if (!id) return Object.freeze({ schema: SCHEMA_REFERENCE_AUTHORITY_SCHEMA_ID, schemaId: '', exactTargets: Object.freeze([]), semanticSourceTargets: Object.freeze([]), materialBoundTarget: false, preferredTarget: '', targetAuthority: 'schema-id-only', resolutionState: 'unavailable', resolutionEvidence: Object.freeze({}), semanticMaterialIdentity: Object.freeze({ state: 'unavailable' }), exactSourceTargets: Object.freeze({ state: 'unavailable', targets: Object.freeze([]), findings: Object.freeze(['Historical schema identifier is unavailable.']) }), historicalReferenceAuthority: Object.freeze({ state: 'unavailable', kind: 'identifier-only', exactRevisionState: 'unresolved', evidence: Object.freeze({ ...evidence }) }) });
113
+ return Object.freeze({
114
+ schema: SCHEMA_REFERENCE_AUTHORITY_SCHEMA_ID,
115
+ schemaId: id,
116
+ exactTargets: Object.freeze([]),
117
+ semanticSourceTargets: Object.freeze([]),
118
+ materialBoundTarget: false,
119
+ preferredTarget: '',
120
+ targetAuthority: 'schema-id-only',
121
+ resolutionState: 'qualified',
122
+ resolutionEvidence: Object.freeze({ state: 'qualified', kind: 'historical-declared-schema-identifier-only', schemaId: id, ...evidence }),
123
+ semanticMaterialIdentity: Object.freeze({ state: 'unavailable', schemaId: id }),
124
+ exactSourceTargets: Object.freeze({ state: 'unavailable', targets: Object.freeze([]), findings: Object.freeze(['No exact historical schema representation target is declared or independently qualified.']) }),
125
+ historicalReferenceAuthority: Object.freeze({ state: 'qualified', kind: 'identifier-only', exactRevisionState: 'unresolved', evidence: Object.freeze({ ...evidence }) })
126
+ });
127
+ }
128
+
129
+ export function isQualifiedIdentifierOnlyHistoricalSchemaReferenceAuthority(authority = {}) {
130
+ return String(authority?.resolutionState || authority?.state || '') === 'qualified'
131
+ && String(authority?.targetAuthority || '') === 'schema-id-only'
132
+ && String(authority?.historicalReferenceAuthority?.kind || '') === 'identifier-only'
133
+ && String(authority?.historicalReferenceAuthority?.exactRevisionState || '') === 'unresolved'
134
+ && !String(authority?.preferredTarget || authority?.target || '').trim()
135
+ && !(authority?.exactTargets || []).some((item) => String(item || '').trim());
136
+ }
137
+
109
138
  export function parseSchemaReferenceValue(value = '') {
110
139
  const raw = String(value ?? '');
111
140
  if (!raw) return Object.freeze({ raw: '', form: 'empty', schemaId: '', target: '' });
@@ -117,7 +117,7 @@ export async function commandInput(parsed, runtime = {}) {
117
117
  packageSourcePath: packagePath,
118
118
  includeLegacyTopics: Boolean(flags['include-legacy-topics']),
119
119
  includeRequiredContext: flags['include-required-context'] || '',
120
- holderBinding: { roleLabel: flags['holder-role'] || '', holderId: flags['holder-id'] || '' },
120
+ holderBinding: { roleLabel: flags['holder-role'] || '', holderId: flags['holder-id'] || '', sourceLocator: holderBindingCliSource(flags) },
121
121
  host,
122
122
  recoveryAcceptance
123
123
  },
@@ -471,4 +471,11 @@ function mergeLoadedMaterial(primary = {}, secondary = {}) {
471
471
  }
472
472
 
473
473
  function normalizeRuntimePaths(value) { const paths = Array.isArray(value) ? value : value ? [value] : []; return paths.map((entry) => String(entry || '').trim()).filter(Boolean); }
474
+ function holderBindingCliSource(flags = {}) {
475
+ const fields = [];
476
+ if (Object.prototype.hasOwnProperty.call(flags, 'holder-role')) fields.push('--holder-role');
477
+ if (Object.prototype.hasOwnProperty.call(flags, 'holder-id')) fields.push('--holder-id');
478
+ return fields.length ? `cli:${fields.join(',')}` : '';
479
+ }
480
+
474
481
  function splitFlag(value) { return !value || value === true ? [] : String(value).split(',').map((item) => item.trim()).filter(Boolean); }