@rathnasgala2/schemas 3.25.0 → 3.25.1

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.
@@ -67,6 +67,12 @@ export type ProblemDocument = Readonly<{
67
67
  readonly code: ProblemProblemCode;
68
68
  readonly correlationId: ProblemStableId;
69
69
  readonly detail: ProblemPlainText;
70
+ readonly details?: Readonly<{
71
+ readonly candidatePageCount: number;
72
+ readonly lostPageCount: number;
73
+ readonly permittedLoss: number;
74
+ readonly previousPageCount: number;
75
+ }>;
70
76
  readonly domainState?: string;
71
77
  readonly errors: ReadonlyArray<ProblemFieldError>;
72
78
  readonly expectedBase?: ProblemUrlHttps;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "2.0.0",
3
3
  "sourceDesignRevision": "a53052955ceb6c1aa10c886289dc832eedfe6de0a00004df07d353ac19c4403a",
4
- "openApiDigest": "sha256:55a877835a611d3a2cbd91e8f863baeca2192a228b95de1eebc94a568ff337ac",
4
+ "openApiDigest": "sha256:5023084f9257d1180b98e8115147bfd81aafa3cf1c0a52f4cf8c8eaf84bdb350",
5
5
  "operations": [
6
6
  {
7
7
  "operationId": "getInternalHealth",
@@ -3232,5 +3232,5 @@
3232
3232
  "sourceFragment": "workloads"
3233
3233
  }
3234
3234
  ],
3235
- "digest": "sha256:38eaece75559fa90ba57b4c0b5cd69bbd7d61188007266d18a62a48e5e33f89c"
3235
+ "digest": "sha256:59a5d0108e2da074828eab414140e982903631f3d4bd2e540d6d26b5841aabc1"
3236
3236
  }
@@ -1394,6 +1394,9 @@ components:
1394
1394
  `gala/publication.json`. An absent member is preserved. `null`
1395
1395
  resets `description` to the publication title (the file requires a
1396
1396
  description); `null` clears `defaultImageRef` and `crawlers`.
1397
+ `listing`, `aiRights` and `performance` (SCHEMA-3.25.1, the
1398
+ `publication.schema.json` 3.25.0 members) follow `crawlers`: absent
1399
+ keeps the stored value, an object replaces it whole, `null` clears it.
1397
1400
  `title`, `defaultLanguage` and `socialLinks` cannot be cleared.
1398
1401
  `socialLinks` (max 32, the publication file's own limit) replaces
1399
1402
  the whole list. `canonicalBase` is never client-settable: it changes
@@ -1401,6 +1404,10 @@ components:
1401
1404
  `422 VALIDATION_FAILED` pointed at `/publicationProfile`; member
1402
1405
  failures point at `/publicationProfile/<member>`.
1403
1406
  properties:
1407
+ aiRights:
1408
+ oneOf:
1409
+ - $ref: "#/components/schemas/PortablePublicationAiRights"
1410
+ - type: "null"
1404
1411
  crawlers:
1405
1412
  oneOf:
1406
1413
  - $ref: "#/components/schemas/PortablePublicationCrawlers"
@@ -1420,6 +1427,14 @@ components:
1420
1427
  maximum: 300
1421
1428
  minimum: 1
1422
1429
  - type: "null"
1430
+ listing:
1431
+ oneOf:
1432
+ - $ref: "#/components/schemas/PortablePublicationListing"
1433
+ - type: "null"
1434
+ performance:
1435
+ oneOf:
1436
+ - $ref: "#/components/schemas/PortablePublicationPerformance"
1437
+ - type: "null"
1423
1438
  socialLinks:
1424
1439
  items:
1425
1440
  $ref: "#/components/schemas/PortablePublicationSocialLink"
@@ -1473,12 +1488,18 @@ components:
1473
1488
  `contentId` is the header's `id`; `status` is the header's `status`
1474
1489
  upper-cased to this contract's enum style. `publishAfter`
1475
1490
  (SCHEMA-3.19.0, optional and nullable) is the header's staggered-release
1476
- date.
1491
+ date. `deleteDate` (SCHEMA-3.25.1, optional and nullable) is the
1492
+ header's scheduled-removal date.
1477
1493
  properties:
1478
1494
  contentId:
1479
1495
  $ref: "#/components/schemas/PortableContentFrontmatterStableId"
1480
1496
  createdAt:
1481
1497
  $ref: "#/components/schemas/PortableContentFrontmatterRfc3339"
1498
+ deleteDate:
1499
+ description: "SCHEMA-3.25.1: the header's `deleteDate` date (`YYYY-MM-DD`) of an article scheduled for removal, `null` or absent when the header carries none."
1500
+ oneOf:
1501
+ - $ref: "#/components/schemas/PortableContentFrontmatterDeleteDate"
1502
+ - type: "null"
1482
1503
  language:
1483
1504
  $ref: "#/components/schemas/PortableContentFrontmatterBcp47"
1484
1505
  publishAfter:
@@ -1573,8 +1594,12 @@ components:
1573
1594
  as the inventory, and returned on every page of the inventory, not
1574
1595
  only the first -- the editor needs these facts regardless of which
1575
1596
  page it opened. Carries no personal data beyond what each author
1576
- file itself already publishes.
1597
+ file itself already publishes. `listing`, `aiRights` and `performance`
1598
+ (SCHEMA-3.25.1, optional) are the publication file's 3.25.0 members,
1599
+ absent when the file carries none.
1577
1600
  properties:
1601
+ aiRights:
1602
+ $ref: "#/components/schemas/PortablePublicationAiRights"
1578
1603
  authors:
1579
1604
  items:
1580
1605
  $ref: "#/components/schemas/ContentPublicationAuthorSummary"
@@ -1591,6 +1616,10 @@ components:
1591
1616
  x-gala-graphemeLength:
1592
1617
  maximum: 500
1593
1618
  minimum: 1
1619
+ listing:
1620
+ $ref: "#/components/schemas/PortablePublicationListing"
1621
+ performance:
1622
+ $ref: "#/components/schemas/PortablePublicationPerformance"
1594
1623
  socialLinks:
1595
1624
  items:
1596
1625
  $ref: "#/components/schemas/PortablePublicationSocialLink"
@@ -14924,6 +14953,28 @@ components:
14924
14953
  x-gala-graphemeLength:
14925
14954
  maximum: 500
14926
14955
  minimum: 0
14956
+ details:
14957
+ additionalProperties: false
14958
+ description: "SCHEMA-3.25.1, optional, carried by a PAGE_LOSS_GUARD problem and absent from every other: the counts behind the refusal, the same members as the `PageLossGuardDetails` operation `reasonDetails`. The candidate build has fewer pages than the last successful deployment; `lostPageCount` is `previousPageCount - candidatePageCount` and `permittedLoss` is the loss the platform settings allow."
14959
+ properties:
14960
+ candidatePageCount:
14961
+ minimum: 0
14962
+ type: integer
14963
+ lostPageCount:
14964
+ minimum: 0
14965
+ type: integer
14966
+ permittedLoss:
14967
+ minimum: 0
14968
+ type: integer
14969
+ previousPageCount:
14970
+ minimum: 0
14971
+ type: integer
14972
+ required:
14973
+ - previousPageCount
14974
+ - candidatePageCount
14975
+ - lostPageCount
14976
+ - permittedLoss
14977
+ type: object
14927
14978
  domainState:
14928
14979
  description: "SCHEMA-3.17.0, optional, carried by a CANONICAL_BASE_MISMATCH problem and absent from every other: the state of the site's custom-domain binding that decided `expectedBase` (a `DomainBindingState` value such as `CERTIFICATE_PENDING` or `ACTIVE`), absent when the site has no custom domain. A client shows a value it does not know as is."
14929
14980
  maxLength: 80
@@ -15063,6 +15114,24 @@ components:
15063
15114
  format: uri
15064
15115
  pattern: ^https://(?![^/?#]*@)
15065
15116
  type: string
15117
+ PortablePublicationAiRights:
15118
+ additionalProperties: false
15119
+ description: "SCHEMA-3.25.0: how AI systems may use the writing. `search` covers search and answer bots, `training` covers training crawlers. When present it wins over `crawlers.ai`; when absent, `crawlers.ai` allow means both allow and block means both block. `licenseUrl` is the optional https URL of the license terms."
15120
+ properties:
15121
+ licenseUrl:
15122
+ $ref: "#/components/schemas/PortablePublicationUrlHttps"
15123
+ search:
15124
+ enum:
15125
+ - allow
15126
+ - block
15127
+ training:
15128
+ enum:
15129
+ - allow
15130
+ - block
15131
+ required:
15132
+ - search
15133
+ - training
15134
+ type: object
15066
15135
  PortablePublicationBcp47:
15067
15136
  description: Structurally valid canonical BCP-47 language tag.
15068
15137
  format: gala-bcp47
@@ -15083,6 +15152,36 @@ components:
15083
15152
  required:
15084
15153
  - ai
15085
15154
  type: object
15155
+ PortablePublicationListing:
15156
+ additionalProperties: false
15157
+ description: "SCHEMA-3.25.0: listing settings. `pageSize` is the number of posts on each listing page (1 to 50); an absent member means 10."
15158
+ properties:
15159
+ pageSize:
15160
+ maximum: 50
15161
+ minimum: 1
15162
+ type: integer
15163
+ required: []
15164
+ type: object
15165
+ PortablePublicationPerformance:
15166
+ additionalProperties: false
15167
+ description: "SCHEMA-3.25.0: size budgets in bytes, each at least 1024 and optional. `htmlBytes` bounds a page's HTML, `cssBytes` and `jsBytes` bound the sum of the same-origin stylesheets and scripts a page links. A page over budget is reported; a budget never fails a build."
15168
+ properties:
15169
+ budgets:
15170
+ additionalProperties: false
15171
+ properties:
15172
+ cssBytes:
15173
+ minimum: 1024
15174
+ type: integer
15175
+ htmlBytes:
15176
+ minimum: 1024
15177
+ type: integer
15178
+ jsBytes:
15179
+ minimum: 1024
15180
+ type: integer
15181
+ required: []
15182
+ type: object
15183
+ required: []
15184
+ type: object
15086
15185
  PortablePublicationPlainLabel:
15087
15186
  description: Normalized Unicode plain text without markup, controls, or bidi overrides.
15088
15187
  format: gala-plain-label
@@ -16032,7 +16131,12 @@ components:
16032
16131
  (SCHEMA-3.19.0) is refused with `409 STAGGERED_RELEASE_DISABLED` while the
16033
16132
  publication's staggered release is off (`publishingPolicy.staggeredRelease`), and
16034
16133
  with `422 PUBLISH_AFTER_ON_PUBLISHED_POST` when its `status` is not
16035
- `draft`; `errors[].pointer` is `/documents/<path>`.
16134
+ `draft`; `errors[].pointer` is `/documents/<path>`. A document whose
16135
+ `deleteDate` (SCHEMA-3.25.0) is not later than its `publishAfter` or
16136
+ `date` is refused with the content-change rejection reason
16137
+ `DELETE_DATE_NOT_AFTER_RELEASE` (SCHEMA-3.25.1), alongside the other
16138
+ reasons the API reports for cross-document rules; those reasons are
16139
+ not an enumerated schema member.
16036
16140
  Assets are images only (PNG, JPEG, WebP, GIF, AVIF; SVG is refused):
16037
16141
  at most 20 per change, each at most 5 MiB and together at most
16038
16142
  20 MiB, measured on the decoded bytes -- `assets[].bytesBase64` is
@@ -16855,6 +16959,10 @@ components:
16855
16959
  person confirmed. The server publishes that head only while it is still
16856
16960
  the repository's head.
16857
16961
  properties:
16962
+ allowPageLoss:
16963
+ default: false
16964
+ description: "SCHEMA-3.25.0: true accepts that this publish may remove many pages from the live site. The server stores it with the operation and skips the page-loss guard; absent or false keeps the guard on (a publish that would lose too many pages ends `FAILED_NO_EFFECT` with reason `PAGE_LOSS_GUARD`)."
16965
+ type: boolean
16858
16966
  headCommit:
16859
16967
  $ref: "#/components/schemas/PortableDeploymentIntentGitObjectId"
16860
16968
  required:
@@ -18103,6 +18211,8 @@ components:
18103
18211
  format: uuid
18104
18212
  pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
18105
18213
  type: string
18214
+ performance:
18215
+ $ref: "#/components/schemas/PortableDeploymentReceiptDeploymentPerformance"
18106
18216
  provenanceDigest:
18107
18217
  pattern: ^sha256:[0-9a-f]{64}$
18108
18218
  type: string
@@ -70904,6 +71014,24 @@ paths:
70904
71014
  status: 409
70905
71015
  title: INVALID_SOURCE_STATE
70906
71016
  type: urn:gala:problem:invalid-source-state
71017
+ PAGE_LOSS_GUARD:
71018
+ summary: PAGE_LOSS_GUARD
71019
+ value:
71020
+ code: PAGE_LOSS_GUARD
71021
+ correlationId: 018f0000-0000-7000-8000-000000000001
71022
+ detail: See the operation contract.
71023
+ details:
71024
+ candidatePageCount: 40
71025
+ lostPageCount: 60
71026
+ permittedLoss: 25
71027
+ previousPageCount: 100
71028
+ errors: []
71029
+ retryable: false
71030
+ schemaId: urn:gala:schema:problem:2.0.0
71031
+ schemaVersion: 2.0.0
71032
+ status: 409
71033
+ title: PAGE_LOSS_GUARD
71034
+ type: urn:gala:problem:page-loss-guard
70907
71035
  WORKLOAD_REPLAYED:
70908
71036
  summary: WORKLOAD_REPLAYED
70909
71037
  value:
@@ -70919,7 +71047,7 @@ paths:
70919
71047
  type: urn:gala:problem:workload-replayed
70920
71048
  schema:
70921
71049
  $ref: "#/components/schemas/Problem"
70922
- description: DESTINATION_MUTATION_IN_PROGRESS, INVALID_SOURCE_STATE, WORKLOAD_REPLAYED
71050
+ description: DESTINATION_MUTATION_IN_PROGRESS, INVALID_SOURCE_STATE, PAGE_LOSS_GUARD, WORKLOAD_REPLAYED
70923
71051
  headers:
70924
71052
  Cache-Control:
70925
71053
  $ref: "#/components/headers/CacheControlNoStore"
@@ -70928,6 +71056,7 @@ paths:
70928
71056
  x-gala-problem-codes:
70929
71057
  - DESTINATION_MUTATION_IN_PROGRESS
70930
71058
  - INVALID_SOURCE_STATE
71059
+ - PAGE_LOSS_GUARD
70931
71060
  - WORKLOAD_REPLAYED
70932
71061
  "410":
70933
71062
  content:
@@ -71091,6 +71220,7 @@ paths:
71091
71220
  - DEPENDENCY_UNAVAILABLE
71092
71221
  - DESTINATION_MUTATION_IN_PROGRESS
71093
71222
  - INVALID_SOURCE_STATE
71223
+ - PAGE_LOSS_GUARD
71094
71224
  - RATE_LIMITED
71095
71225
  - REQUEST_FIELD_UNKNOWN
71096
71226
  - VALIDATION_FAILED
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rathnasgala2/schemas",
3
- "version": "3.25.0",
3
+ "version": "3.25.1",
4
4
  "description": "Executable JSON Schema and OpenAPI contracts for Galascribe",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/sbom.cdx.json CHANGED
@@ -97,8 +97,8 @@
97
97
  "type": "library",
98
98
  "name": "schemas",
99
99
  "group": "@rathnasgala2",
100
- "version": "3.25.0",
101
- "bom-ref": "@rathnasgala2/schemas@3.25.0",
100
+ "version": "3.25.1",
101
+ "bom-ref": "@rathnasgala2/schemas@3.25.1",
102
102
  "description": "Executable JSON Schema and OpenAPI contracts for Galascribe",
103
103
  "licenses": [
104
104
  {
@@ -108,7 +108,7 @@
108
108
  }
109
109
  }
110
110
  ],
111
- "purl": "pkg:npm/%40rathnasgala2/schemas@3.25.0?vcs_url=git%2Bhttps%3A%2F%2Fgithub.com%2Frathnasgala2%2Fschema.git",
111
+ "purl": "pkg:npm/%40rathnasgala2/schemas@3.25.1?vcs_url=git%2Bhttps%3A%2F%2Fgithub.com%2Frathnasgala2%2Fschema.git",
112
112
  "externalReferences": [
113
113
  {
114
114
  "url": "https://github.com/rathnasgala2/schema/issues",
@@ -153,7 +153,7 @@
153
153
  "type": "library",
154
154
  "name": "ajv-formats",
155
155
  "version": "3.0.1",
156
- "bom-ref": "@rathnasgala2/schemas@3.25.0|ajv-formats@3.0.1",
156
+ "bom-ref": "@rathnasgala2/schemas@3.25.1|ajv-formats@3.0.1",
157
157
  "licenses": [
158
158
  {
159
159
  "license": {
@@ -187,7 +187,7 @@
187
187
  "type": "library",
188
188
  "name": "ajv",
189
189
  "version": "8.20.0",
190
- "bom-ref": "@rathnasgala2/schemas@3.25.0|ajv@8.20.0",
190
+ "bom-ref": "@rathnasgala2/schemas@3.25.1|ajv@8.20.0",
191
191
  "licenses": [
192
192
  {
193
193
  "license": {
@@ -221,7 +221,7 @@
221
221
  "type": "library",
222
222
  "name": "fast-deep-equal",
223
223
  "version": "3.1.3",
224
- "bom-ref": "@rathnasgala2/schemas@3.25.0|fast-deep-equal@3.1.3",
224
+ "bom-ref": "@rathnasgala2/schemas@3.25.1|fast-deep-equal@3.1.3",
225
225
  "licenses": [
226
226
  {
227
227
  "license": {
@@ -255,7 +255,7 @@
255
255
  "type": "library",
256
256
  "name": "fast-uri",
257
257
  "version": "3.1.8",
258
- "bom-ref": "@rathnasgala2/schemas@3.25.0|fast-uri@3.1.8",
258
+ "bom-ref": "@rathnasgala2/schemas@3.25.1|fast-uri@3.1.8",
259
259
  "licenses": [
260
260
  {
261
261
  "license": {
@@ -289,7 +289,7 @@
289
289
  "type": "library",
290
290
  "name": "json-schema-traverse",
291
291
  "version": "1.0.0",
292
- "bom-ref": "@rathnasgala2/schemas@3.25.0|json-schema-traverse@1.0.0",
292
+ "bom-ref": "@rathnasgala2/schemas@3.25.1|json-schema-traverse@1.0.0",
293
293
  "licenses": [
294
294
  {
295
295
  "license": {
@@ -323,7 +323,7 @@
323
323
  "type": "library",
324
324
  "name": "require-from-string",
325
325
  "version": "2.0.2",
326
- "bom-ref": "@rathnasgala2/schemas@3.25.0|require-from-string@2.0.2",
326
+ "bom-ref": "@rathnasgala2/schemas@3.25.1|require-from-string@2.0.2",
327
327
  "licenses": [
328
328
  {
329
329
  "license": {
@@ -1064,10 +1064,10 @@
1064
1064
  ],
1065
1065
  "dependencies": [
1066
1066
  {
1067
- "ref": "@rathnasgala2/schemas@3.25.0",
1067
+ "ref": "@rathnasgala2/schemas@3.25.1",
1068
1068
  "dependsOn": [
1069
- "@rathnasgala2/schemas@3.25.0|ajv-formats@3.0.1",
1070
- "@rathnasgala2/schemas@3.25.0|ajv@8.20.0",
1069
+ "@rathnasgala2/schemas@3.25.1|ajv-formats@3.0.1",
1070
+ "@rathnasgala2/schemas@3.25.1|ajv@8.20.0",
1071
1071
  "pkg:npm/semver@7.8.5",
1072
1072
  "urn:gala:source-data:iana-ipv4-special-registry",
1073
1073
  "urn:gala:source-data:iana-ipv6-special-registry",
@@ -1089,31 +1089,31 @@
1089
1089
  ]
1090
1090
  },
1091
1091
  {
1092
- "ref": "@rathnasgala2/schemas@3.25.0|ajv-formats@3.0.1",
1092
+ "ref": "@rathnasgala2/schemas@3.25.1|ajv-formats@3.0.1",
1093
1093
  "dependsOn": [
1094
- "@rathnasgala2/schemas@3.25.0|ajv@8.20.0"
1094
+ "@rathnasgala2/schemas@3.25.1|ajv@8.20.0"
1095
1095
  ]
1096
1096
  },
1097
1097
  {
1098
- "ref": "@rathnasgala2/schemas@3.25.0|ajv@8.20.0",
1098
+ "ref": "@rathnasgala2/schemas@3.25.1|ajv@8.20.0",
1099
1099
  "dependsOn": [
1100
- "@rathnasgala2/schemas@3.25.0|fast-deep-equal@3.1.3",
1101
- "@rathnasgala2/schemas@3.25.0|fast-uri@3.1.8",
1102
- "@rathnasgala2/schemas@3.25.0|json-schema-traverse@1.0.0",
1103
- "@rathnasgala2/schemas@3.25.0|require-from-string@2.0.2"
1100
+ "@rathnasgala2/schemas@3.25.1|fast-deep-equal@3.1.3",
1101
+ "@rathnasgala2/schemas@3.25.1|fast-uri@3.1.8",
1102
+ "@rathnasgala2/schemas@3.25.1|json-schema-traverse@1.0.0",
1103
+ "@rathnasgala2/schemas@3.25.1|require-from-string@2.0.2"
1104
1104
  ]
1105
1105
  },
1106
1106
  {
1107
- "ref": "@rathnasgala2/schemas@3.25.0|fast-deep-equal@3.1.3"
1107
+ "ref": "@rathnasgala2/schemas@3.25.1|fast-deep-equal@3.1.3"
1108
1108
  },
1109
1109
  {
1110
- "ref": "@rathnasgala2/schemas@3.25.0|fast-uri@3.1.8"
1110
+ "ref": "@rathnasgala2/schemas@3.25.1|fast-uri@3.1.8"
1111
1111
  },
1112
1112
  {
1113
- "ref": "@rathnasgala2/schemas@3.25.0|json-schema-traverse@1.0.0"
1113
+ "ref": "@rathnasgala2/schemas@3.25.1|json-schema-traverse@1.0.0"
1114
1114
  },
1115
1115
  {
1116
- "ref": "@rathnasgala2/schemas@3.25.0|require-from-string@2.0.2"
1116
+ "ref": "@rathnasgala2/schemas@3.25.1|require-from-string@2.0.2"
1117
1117
  },
1118
1118
  {
1119
1119
  "ref": "pkg:npm/semver@7.8.5"
@@ -55,6 +55,23 @@
55
55
  "maxLength": 80,
56
56
  "description": "SCHEMA-3.17.0, optional, carried by a CANONICAL_BASE_MISMATCH problem and absent from every other: the state of the site's custom-domain binding that decided `expectedBase` (a `DomainBindingState` value such as `CERTIFICATE_PENDING` or `ACTIVE`), absent when the site has no custom domain. A client shows a value it does not know as is."
57
57
  },
58
+ "details": {
59
+ "type": "object",
60
+ "description": "SCHEMA-3.25.1, optional, carried by a PAGE_LOSS_GUARD problem and absent from every other: the counts behind the refusal, the same members as the `PageLossGuardDetails` operation `reasonDetails`. The candidate build has fewer pages than the last successful deployment; `lostPageCount` is `previousPageCount - candidatePageCount` and `permittedLoss` is the loss the platform settings allow.",
61
+ "required": [
62
+ "previousPageCount",
63
+ "candidatePageCount",
64
+ "lostPageCount",
65
+ "permittedLoss"
66
+ ],
67
+ "properties": {
68
+ "previousPageCount": { "type": "integer", "minimum": 0 },
69
+ "candidatePageCount": { "type": "integer", "minimum": 0 },
70
+ "lostPageCount": { "type": "integer", "minimum": 0 },
71
+ "permittedLoss": { "type": "integer", "minimum": 0 }
72
+ },
73
+ "additionalProperties": false
74
+ },
58
75
  "remedy": {
59
76
  "$ref": "#/$defs/plainText",
60
77
  "description": "SCHEMA-3.17.0, optional, carried by a CANONICAL_BASE_MISMATCH problem and absent from every other: one sentence, written for the author, saying what resolves the mismatch. A client may render it verbatim.",