@peasant-labs/schema 0.1.0-rc11 → 0.1.0-rc13

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.
@@ -179,7 +179,7 @@ export interface paths {
179
179
  };
180
180
  get?: never;
181
181
  put?: never;
182
- /** @description Publish a transcript with session entries to the village. */
182
+ /** @description Publish exact transcript bytes with typed JSON metadata. Creation returns 201 and replacement returns 200; both carry the complete authoritative receipt. */
183
183
  post: operations["publishTranscript"];
184
184
  delete?: never;
185
185
  options?: never;
@@ -200,7 +200,7 @@ export interface paths {
200
200
  delete?: never;
201
201
  options?: never;
202
202
  head?: never;
203
- /** @description Update an owned transcript's metadata and governance axes. Every field is optional and an omitted field is left unchanged, resolved against the locked stored row so a concurrent edit is not reverted. License is three-valued: omit to preserve, send the empty string to clear, send a menu license to replace. Clearing a license that was actually granted is refused with 400 because a granted Creative Commons license is irrevocable. Only the owner may call this; anyone else receives 403 and neither the transcript nor its governance audit changes. Visibility accepts private and public; organization-scoped visibility is deferred. The village additionally accepts and stores a legacy 'shared' value that is deliberately NOT declared: it is not a member of this contract's Visibility enum at all, whose third member is 'group', and the village refuses 'group'. Declaring 'shared' would mean inventing an enum member to expose the deferred organization-ACL capability, so its absence is a decision. The transcript id is likewise narrower than the server: uuid.Parse also accepts uppercase, brace-wrapped, urn:uuid-prefixed and 32-undashed-hex spellings that the declared pattern rejects. Those stay undeclared because the village only ever emits the canonical lowercase form, so no client holds another unless it manufactures one, and accepting five spellings for one identity is itself a defect surface. Note this document now describes one transcript id two ways: this operation constrains it to the canonical pattern, while the older pull operations still declare a bare string. That difference is not a contradiction about what the village accepts, only about what each operation declares; the pull operations are deliberately untouched here. Omit a field to leave it unchanged; send an empty string to clear a title, a description, or a license. Explicit null is refused on every field, because the server would read it as preserve rather than the clear a caller usually intends, and an unknown field is refused because the server would accept and silently discard it. 400 covers five distinct refusals: an unparseable transcript id, an undecodable body, a visibility outside the accepted set, a license outside the canonical menu, and the attempt to clear a granted license. 401 is returned by the authentication boundary before the handler runs, and is distinct from 403: 401 means the credential is missing or expired and the caller should re-authenticate, while 403 means the caller is authenticated but does not own this transcript. 404 covers both a transcript that does not exist and a lookup that failed, so it must not be read as proof of absence. 500 has two forms and only one carries this body: the handler's own failure returns the envelope, while a panic recovered by the router's middleware returns 500 with an EMPTY body, so a client must tolerate an absent body on 500 rather than assuming the envelope is always present. The refusals are declared while the 200 body is NOT, and that asymmetry is deliberate rather than an oversight. A client must distinguish 403 from 404 from each 400 to tell a user anything useful, so those distinctions are exactly what this contract is for. The success body has no such consumer: the applied state is read back through GET /api/v1/pull/transcripts/{id}. The village does return a 200 body, but it currently serves an untyped object wrapping the stored row's internal columns (owner_id, blob_key, project_hash, source_file_path and others) at backend/internal/handler/transcripts.go:723-727, and those columns serialize through pgtype wrappers, so a consumer would receive {"String":"x","Valid":true} where it expects a string. Declaring a projection the village does not serve would break the property that the served and declared contracts cannot drift, so nothing is declared until the handler serves a shape worth declaring. Tracked at https://github.com/peasant-labs/village/issues/55; adding the response schema later is additive. Do not 'harmonize' this by inventing a success body. */
203
+ /** @description Update an owned transcript's metadata and governance axes. Every field is optional: omission preserves stored state; empty title, description, or tags clear those fields; license null requests clear; and a canonical license replaces. Explicit null for title, description, tags, or visibility is rejected, as are unknown fields and invalid or duplicate tags. Clearing an already granted Creative Commons license remains subject to the server's irrevocability rule. Only the owner may call this operation. A successful update returns the complete typed authoritative editable state, including the canonical transcript URL and positive update timestamp. Visibility accepts private and public; organization-scoped visibility remains deferred. */
204
204
  patch: operations["updateTranscript"];
205
205
  trace?: never;
206
206
  };
@@ -216,19 +216,29 @@ export interface components {
216
216
  * @enum {string}
217
217
  */
218
218
  BestiaryHarness: Schema.Harness;
219
- OpenapiTranscriptPublishRequest: {
220
- diagnostics?: components["schemas"]["SchemaDiagnosticsInfo"];
221
- entries?: components["schemas"]["SchemaSessionEntry"][];
222
- git?: components["schemas"]["SchemaGitContext"];
223
- identity?: components["schemas"]["SchemaSessionIdentity"];
219
+ FormDataOpenapiTranscriptPublishMultipartRequest: {
220
+ /** @description PublishRequest JSON encoded with Content-Type application/json. */
221
+ metadata: components["schemas"]["OpenapiAuthoritativeTranscriptPublishRequest"];
222
+ /** @description Exact transcript bytes whose SHA3-256 digest equals metadata.contentHash. */
223
+ transcript_file: components["schemas"]["MultipartFileHeader"];
224
+ };
225
+ /** Format: binary */
226
+ MultipartFileHeader: string;
227
+ OpenapiAuthoritativeTranscriptPublishRequest: {
228
+ contentHash: components["schemas"]["SchemaTranscriptContentHash"];
229
+ diagnostics?: components["schemas"]["SchemaAuthoritativeDiagnosticsInfo"];
230
+ entries?: components["schemas"]["SchemaAuthoritativeSessionEntry"][];
231
+ git?: components["schemas"]["SchemaAuthoritativeGitContext"];
232
+ identity?: components["schemas"]["SchemaAuthoritativeSessionIdentity"];
224
233
  license?: components["schemas"]["SchemaLicense"];
225
- model: components["schemas"]["SchemaModelInfo"];
226
- project?: components["schemas"]["SchemaProjectContext"];
227
- quality?: components["schemas"]["SchemaQualityMetrics"];
228
- source?: components["schemas"]["SchemaSourceInfo"];
229
- stats?: components["schemas"]["SchemaSessionStats"];
230
- subagents?: components["schemas"]["SchemaSubagentRef"][];
231
- timestamp?: components["schemas"]["SchemaTimestampInfo"];
234
+ model: components["schemas"]["SchemaAuthoritativeModelInfo"];
235
+ project?: components["schemas"]["SchemaAuthoritativeProjectContext"];
236
+ quality?: components["schemas"]["SchemaAuthoritativeQualityMetrics"];
237
+ source?: components["schemas"]["SchemaAuthoritativeSourceInfo"];
238
+ stats?: components["schemas"]["SchemaAuthoritativeSessionStats"];
239
+ subagents?: components["schemas"]["SchemaAuthoritativeSubagentRef"][];
240
+ timestamp?: components["schemas"]["SchemaAuthoritativeTimestampInfo"];
241
+ visibilityIntent?: components["schemas"]["SchemaVisibilityIntent"];
232
242
  };
233
243
  OpenapiTranscriptUpdateErrorResponse: {
234
244
  error: string;
@@ -264,9 +274,20 @@ export interface components {
264
274
  * @example assoc-20260726:session-a:commit-1
265
275
  */
266
276
  SchemaAssociationID: Schema.AssociationID;
267
- SchemaCommitInfo: Schema.CommitInfo;
268
- SchemaDiagnosticEntry: Schema.DiagnosticEntry;
269
- SchemaDiagnosticsInfo: Schema.DiagnosticsInfo;
277
+ SchemaAuthoritativeCommitInfo: Schema.AuthoritativeCommitInfo;
278
+ SchemaAuthoritativeDiagnosticEntry: Schema.AuthoritativeDiagnosticEntry;
279
+ SchemaAuthoritativeDiagnosticsInfo: Schema.AuthoritativeDiagnosticsInfo;
280
+ SchemaAuthoritativeGitContext: Schema.AuthoritativeGitContext;
281
+ SchemaAuthoritativeModelInfo: Schema.AuthoritativeModelInfo;
282
+ SchemaAuthoritativeProjectContext: Schema.AuthoritativeProjectContext;
283
+ SchemaAuthoritativePublishResponse: Schema.AuthoritativePublishResponse;
284
+ SchemaAuthoritativeQualityMetrics: Schema.AuthoritativeQualityMetrics;
285
+ SchemaAuthoritativeSessionEntry: Schema.AuthoritativeSessionEntry;
286
+ SchemaAuthoritativeSessionIdentity: Schema.AuthoritativeSessionIdentity;
287
+ SchemaAuthoritativeSessionStats: Schema.AuthoritativeSessionStats;
288
+ SchemaAuthoritativeSourceInfo: Schema.AuthoritativeSourceInfo;
289
+ SchemaAuthoritativeSubagentRef: Schema.AuthoritativeSubagentRef;
290
+ SchemaAuthoritativeTimestampInfo: Schema.AuthoritativeTimestampInfo;
270
291
  /**
271
292
  * Entry Type
272
293
  * @description Classification of a single entry within an agent session transcript
@@ -278,7 +299,6 @@ export interface components {
278
299
  SchemaEntryType: Schema.EntryType;
279
300
  SchemaExchangeCodeRequest: Schema.ExchangeCodeRequest;
280
301
  SchemaExchangeCodeResponse: Schema.ExchangeCodeResponse;
281
- SchemaGitContext: Schema.GitContext;
282
302
  /**
283
303
  * Host Slug
284
304
  * @description Sanitized, filesystem-safe identifier derived from git remote; contains only [a-zA-Z0-9._<>-]
@@ -301,8 +321,10 @@ export interface components {
301
321
  * @example codex-mini-latest
302
322
  */
303
323
  SchemaModelID: Schema.ModelID;
304
- SchemaModelInfo: Schema.ModelInfo;
305
- SchemaProjectContext: Schema.ProjectContext;
324
+ SchemaOwnerTranscriptUpdateRequest: Schema.OwnerTranscriptUpdateRequest;
325
+ SchemaOwnerTranscriptUpdateResponse: Schema.OwnerTranscriptUpdateResponse;
326
+ /** @description Omitted preserves, null requests clear, and a canonical license replaces */
327
+ SchemaOwnerUpdateLicenseIntent: Schema.OwnerUpdateLicenseIntent;
306
328
  /**
307
329
  * Project Hash
308
330
  * @description SHA-256 hex digest of the project's origin URL or local path
@@ -310,7 +332,13 @@ export interface components {
310
332
  */
311
333
  SchemaProjectHash: Schema.ProjectHash;
312
334
  SchemaProvenance: Schema.Provenance;
313
- SchemaPublishResponse: Schema.PublishResponse;
335
+ SchemaPublishAppliedState: Schema.PublishAppliedState;
336
+ SchemaPublishNormalizedValues: Schema.PublishNormalizedValues;
337
+ /**
338
+ * Publish Request Fingerprint
339
+ * @description SHA3-256 digest of the canonical domain-separated publish operation
340
+ */
341
+ SchemaPublishRequestFingerprint: Schema.PublishRequestFingerprint;
314
342
  SchemaPublishedAssociation: Schema.PublishedAssociation;
315
343
  SchemaPullAnnotation: Schema.PullAnnotation;
316
344
  SchemaPullListResponse: Schema.PullListResponse;
@@ -319,7 +347,6 @@ export interface components {
319
347
  SchemaPullSkipGateResponse: Schema.PullSkipGateResponse;
320
348
  SchemaPullSkipGateResult: Schema.PullSkipGateResult;
321
349
  SchemaPullTranscriptInfo: Schema.PullTranscriptInfo;
322
- SchemaQualityMetrics: Schema.QualityMetrics;
323
350
  /**
324
351
  * Role
325
352
  * @description Sender role of a message turn
@@ -329,7 +356,6 @@ export interface components {
329
356
  */
330
357
  SchemaRole: Schema.Role;
331
358
  SchemaSchemaVersionResponse: Schema.SchemaVersionResponse;
332
- SchemaSessionEntry: Schema.SessionEntry;
333
359
  /**
334
360
  * Session ID
335
361
  * Format: session-id
@@ -342,7 +368,6 @@ export interface components {
342
368
  * @example ABCDEFGHIJKLMNOPQRST234567
343
369
  */
344
370
  SchemaSessionID: Schema.SessionID;
345
- SchemaSessionIdentity: Schema.SessionIdentity;
346
371
  /**
347
372
  * Session Outcome
348
373
  * @description Resolution status of the session
@@ -352,7 +377,6 @@ export interface components {
352
377
  * @enum {string}
353
378
  */
354
379
  SchemaSessionOutcome: Schema.SessionOutcome;
355
- SchemaSessionStats: Schema.SessionStats;
356
380
  /**
357
381
  * Source Format
358
382
  * @description Transcript file format
@@ -361,7 +385,6 @@ export interface components {
361
385
  * @enum {string}
362
386
  */
363
387
  SchemaSourceFormat: Schema.SourceFormat;
364
- SchemaSourceInfo: Schema.SourceInfo;
365
388
  /**
366
389
  * Stop Reason
367
390
  * @description Reason why a session or turn ended (ACP-aligned)
@@ -370,7 +393,6 @@ export interface components {
370
393
  * @enum {string}
371
394
  */
372
395
  SchemaStopReason: Schema.StopReason;
373
- SchemaSubagentRef: Schema.SubagentRef;
374
396
  /**
375
397
  * Target Kind
376
398
  * @description What is being annotated: session-level, entry-level (turn/tool call), meta-annotation, project-level, a specific file version (content-hash keyed read-state receipt), or a durable session-to-commit association
@@ -381,7 +403,6 @@ export interface components {
381
403
  * @enum {string}
382
404
  */
383
405
  SchemaTargetKind: Schema.TargetKind;
384
- SchemaTimestampInfo: Schema.TimestampInfo;
385
406
  /**
386
407
  * Tool Call Kind
387
408
  * @description Classification of a tool call, aligned with ACP ToolCallUpdate.kind
@@ -391,6 +412,11 @@ export interface components {
391
412
  * @enum {string}
392
413
  */
393
414
  SchemaToolCallKind: Schema.ToolCallKind;
415
+ /**
416
+ * Transcript Content Hash
417
+ * @description SHA3-256 digest of the exact transcript file bytes
418
+ */
419
+ SchemaTranscriptContentHash: Schema.TranscriptContentHash;
394
420
  /**
395
421
  * Transcript ID
396
422
  * Format: uuid
@@ -398,15 +424,6 @@ export interface components {
398
424
  * @example 99d59925-36bc-424c-a789-8be54d9702ba
399
425
  */
400
426
  SchemaTranscriptID: Schema.TranscriptID;
401
- /**
402
- * TranscriptUpdateLicense
403
- * @description License value for the owner transcript update operation: a canonical menu license, or the empty string to clear. Clearing a license that was actually granted is refused, because a granted Creative Commons license is irrevocable.
404
- * @example CC-BY-4.0
405
- * @example
406
- * @enum {string}
407
- */
408
- SchemaTranscriptUpdateLicense: Schema.TranscriptUpdateLicense;
409
- SchemaTranscriptUpdateRequest: Schema.TranscriptUpdateRequest;
410
427
  /**
411
428
  * TranscriptUpdateVisibility
412
429
  * @description Visibility values accepted by the owner transcript update operation. Organization-scoped visibility is deferred and is deliberately not offered here.
@@ -423,6 +440,14 @@ export interface components {
423
440
  * @enum {string}
424
441
  */
425
442
  SchemaVisibility: Schema.Visibility;
443
+ /**
444
+ * Visibility Intent
445
+ * @description Optional desired final access for legacy compatibility; content replacement remains private and widening occurs separately
446
+ * @example private
447
+ * @example public
448
+ * @enum {string}
449
+ */
450
+ SchemaVisibilityIntent: Schema.VisibilityIntent;
426
451
  /**
427
452
  * Visibility
428
453
  * @description Access control level for a published transcript
@@ -669,9 +694,9 @@ export interface operations {
669
694
  path?: never;
670
695
  cookie?: never;
671
696
  };
672
- requestBody?: {
697
+ requestBody: {
673
698
  content: {
674
- "application/json": components["schemas"]["OpenapiTranscriptPublishRequest"];
699
+ "multipart/form-data": components["schemas"]["FormDataOpenapiTranscriptPublishMultipartRequest"];
675
700
  };
676
701
  };
677
702
  responses: {
@@ -681,7 +706,16 @@ export interface operations {
681
706
  [name: string]: unknown;
682
707
  };
683
708
  content: {
684
- "application/json": components["schemas"]["SchemaPublishResponse"];
709
+ "application/json": components["schemas"]["SchemaAuthoritativePublishResponse"];
710
+ };
711
+ };
712
+ /** @description Created */
713
+ 201: {
714
+ headers: {
715
+ [name: string]: unknown;
716
+ };
717
+ content: {
718
+ "application/json": components["schemas"]["SchemaAuthoritativePublishResponse"];
685
719
  };
686
720
  };
687
721
  };
@@ -698,7 +732,7 @@ export interface operations {
698
732
  };
699
733
  requestBody: {
700
734
  content: {
701
- "application/json": components["schemas"]["SchemaTranscriptUpdateRequest"];
735
+ "application/json": components["schemas"]["SchemaOwnerTranscriptUpdateRequest"];
702
736
  };
703
737
  };
704
738
  responses: {
@@ -707,7 +741,9 @@ export interface operations {
707
741
  headers: {
708
742
  [name: string]: unknown;
709
743
  };
710
- content?: never;
744
+ content: {
745
+ "application/json": components["schemas"]["SchemaOwnerTranscriptUpdateResponse"];
746
+ };
711
747
  };
712
748
  /** @description Bad Request */
713
749
  400: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peasant-labs/schema",
3
- "version": "0.1.0-rc11",
3
+ "version": "0.1.0-rc13",
4
4
  "description": "Generated TypeScript contract bindings for the peasant-labs schema module",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -68,7 +68,7 @@
68
68
  "generate": "openapi-ts -f openapi-ts.config.mjs && node scripts/generate-contract-support.mjs",
69
69
  "build": "node scripts/build.mjs",
70
70
  "typecheck": "pnpm run build && tsc --noEmit -p tsconfig.test.json",
71
- "test": "pnpm run build && node --test tests/*.test.mjs",
71
+ "test": "pnpm run build && node --test --test-concurrency=1 tests/*.test.mjs",
72
72
  "package:audit": "pnpm run build && node scripts/package-audit.mjs",
73
73
  "package:smoke": "pnpm run build && node scripts/package-smoke.mjs"
74
74
  }