kg-ssot 4.10.0 → 4.11.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.
package/README.md CHANGED
@@ -42,8 +42,8 @@ verdict(texto, { format: 'json' }); // .kg.json
42
42
  `external_edges`. Os schemas ficam em `kg-ssot/spec/*`.
43
43
 
44
44
  Desde a 4.10.0, este leitor também mede os avisos SHOULD, com os mesmos códigos do leitor de referência em todos os
45
- casos da suíte. Fora da suíte há diferenças conhecidas no parse de três construções raras do YAML (a tag `!` sem nome,
46
- `!!timestamp` com texto que não é data e o tab entre a data e a hora), registradas como pergunta de contrato. A linha de cada ocorrência e as dicas de correção continuam só no leitor de referência em Python.
45
+ casos da suíte. Desde a 4.11.0, as três construções raras do YAML em que ele divergia da referência (a tag `!` sem
46
+ nome, o `!!timestamp` com texto que não é data e o tab fora de aspas) reprovam nos dois, com casos na suíte. A linha de cada ocorrência e as dicas de correção continuam só no leitor de referência em Python.
47
47
 
48
48
  ## TypeScript e CommonJS
49
49
 
package/index.d.mts CHANGED
@@ -46,7 +46,7 @@ export function checkWarnings(text: string, options?: { format?: Format }): stri
46
46
  export function verdictOf(text: string, validate: MustValidator,
47
47
  options?: Options & { validateShould?: MustValidator }): Verdict;
48
48
 
49
- /** Os avisos de coerência de um documento já lido (integrity.testimony-in-prod, verified-before-fact, untraced-decision). */
49
+ /** Os avisos de coerência de um documento já lido (integrity.testimony-in-prod, verified-before-fact, untraced-decision, refutes-unreconciled). */
50
50
  export function coherenceCodes(doc: Record<string, unknown>): string[];
51
51
 
52
52
  /** Os avisos do perfil JSON num .kg.yaml já lido (yaml.unsafe-integer, yaml.lone-surrogate, yaml.depth-over-128). */
package/kg.mjs CHANGED
@@ -13,7 +13,7 @@
13
13
  // - warnings: os avisos SHOULD (warnings da referência): o schema SHOULD sem o que o MUST já acusa, a data sem
14
14
  // aspas, os três avisos do perfil no .kg.yaml (yaml.unsafe-integer, yaml.lone-surrogate, yaml.depth-over-128)
15
15
  // e os de coerência (coherence_located).
16
- import { parseAllDocuments, isAlias, isMap, isPair, isScalar, isSeq } from 'yaml';
16
+ import { Composer, Parser, isAlias, isMap, isPair, isScalar, isSeq } from 'yaml';
17
17
 
18
18
  // format: date é asserção (ADR 002): AAAA-MM-DD que existe no calendário, ano de 0001 a 9999, como o
19
19
  // datetime.date.fromisoformat do leitor de referência. É uma regex, e não uma função, para que o validador
@@ -40,6 +40,10 @@ const YAML11_TIMESTAMP = new RegExp('^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0
40
40
  + '|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?(?:[Tt]|[ \\t]+)[0-9][0-9]?:[0-9][0-9]:[0-9][0-9](?:\\.[0-9]*)?'
41
41
  + '(?:[ \\t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$');
42
42
 
43
+ // O !!timestamp explícito aceito pelo perfil (STRICT_TIMESTAMP da referência): a interseção do construtor do PyYAML com
44
+ // o do yaml, sem tab entre a data e a hora (decisão de contrato de 2026-10-19).
45
+ const STRICT_TIMESTAMP = /^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}(?:(?:[Tt]| +)[0-9]{1,2}:[0-9]{2}:[0-9]{2}(?:\.[0-9]+)?(?: *(?:Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$/;
46
+
43
47
  class ParseError extends Error {
44
48
  constructor(code) { super(code); this.code = code; }
45
49
  }
@@ -104,7 +108,11 @@ function scalarOf(node) {
104
108
  const big = src.startsWith('0o') ? BigInt(src) : BigInt(src.replace(/^\+/, ''));
105
109
  return { value: Number(big), key: big.toString(), int: true };
106
110
  }
107
- if (tag === `${Y}timestamp`) return { value: String(node.source ?? value), key: String(node.source ?? value) };
111
+ if (tag === `${Y}timestamp`) {
112
+ const src = String(node.source ?? value);
113
+ if (!STRICT_TIMESTAMP.test(src)) throw new ParseError('parse.yaml-error'); // !!timestamp sem data na forma estrita
114
+ return { value: src, key: src };
115
+ }
108
116
  if (tag === `${Y}binary`) return { value: BYTES, key: "b''" };
109
117
  if (value === null || value === undefined) return { value: null, key: 'null' };
110
118
  if (typeof value === 'boolean') return { value, key: String(value) };
@@ -233,17 +241,36 @@ const codePoints = (text) => {
233
241
  return n;
234
242
  };
235
243
 
244
+ // O que o perfil recusa já na leitura dos tokens, como o parser puro do PyYAML da referência
245
+ // (decisão de contrato de 2026-10-19, «o mais estrito nos três»): o tab fora de aspas, de bloco e de comentário (no
246
+ // espaço entre tokens ou dentro de um escalar plain) e a tag ! sem nome, também na forma !<!>. Sem recursão.
247
+ function strictTokenError(tokens) {
248
+ const stack = [...tokens];
249
+ while (stack.length) {
250
+ const t = stack.pop();
251
+ if (Array.isArray(t)) { for (const x of t) stack.push(x); continue; } // sem spread: lista enorme estoura a pilha
252
+ if (t === null || typeof t !== 'object') continue;
253
+ if (typeof t.source === 'string') {
254
+ if ((t.type === 'space' || t.type === 'scalar' || t.type === 'directive') && t.source.includes('\t')) return true;
255
+ if (t.type === 'tag' && (t.source === '!' || t.source === '!<!>')) return true;
256
+ }
257
+ for (const v of Object.values(t)) if (v !== null && typeof v === 'object') stack.push(v);
258
+ }
259
+ return false;
260
+ }
261
+
236
262
  /** O parse do .kg.yaml no perfil do contrato: { doc, unquotedDate } ou { code: 'parse.*' }. */
237
263
  export function parseYaml(text) {
238
264
  let docs;
239
265
  try {
240
- docs = parseAllDocuments(text, {
241
- version: '1.2', schema: 'core', uniqueKeys: false, merge: false, maxAliasCount: -1, prettyErrors: false,
242
- });
266
+ const tokens = Array.from(new Parser().parse(text));
267
+ if (strictTokenError(tokens)) return { code: 'parse.yaml-error' };
268
+ docs = Array.from(new Composer({
269
+ version: '1.2', schema: 'core', uniqueKeys: false, merge: false, maxAliasCount: -1,
270
+ }).compose(tokens));
243
271
  } catch {
244
272
  return { code: 'parse.yaml-error' }; // aninhamento que estoura a pilha do parser, entre outros
245
273
  }
246
- if (!Array.isArray(docs)) docs = [docs]; // EmptyStream é lista; um documento só também vem como lista
247
274
  const raw = [];
248
275
  const marks = {};
249
276
  try {
@@ -609,12 +636,15 @@ function containsValue(value, hit) {
609
636
  }
610
637
 
611
638
  /** Os avisos de coerência, que cruzam campos ou arestas (coherence_located da referência), um por ocorrência:
612
- * integrity.testimony-in-prod, integrity.verified-before-fact e integrity.untraced-decision. */
639
+ * integrity.testimony-in-prod, integrity.verified-before-fact, integrity.untraced-decision e
640
+ * integrity.refutes-unreconciled. */
613
641
  export function coherenceCodes(doc) {
614
642
  const out = [];
615
643
  const edges = Array.isArray(doc.edges) ? doc.edges : [];
616
644
  const traced = new Set(edges.filter((e) => isObj(e) && get(e, 'edge_type') === 'TRACES_TO' && typeof get(e, 'from') === 'string')
617
645
  .map((e) => e.from));
646
+ const refuted = new Set(edges.filter((e) => isObj(e) && get(e, 'edge_type') === 'REFUTES' && typeof get(e, 'to') === 'string')
647
+ .map((e) => e.to));
618
648
  for (const n of located(doc, 'nodes')) {
619
649
  const prov = isObj(get(n, 'provenance')) ? n.provenance : {};
620
650
  const method = get(prov, 'method');
@@ -634,6 +664,11 @@ export function coherenceCodes(doc) {
634
664
  && !(typeof get(n, 'id') === 'string' && traced.has(n.id))) {
635
665
  out.push('integrity.untraced-decision');
636
666
  }
667
+ const status = get(n, 'status');
668
+ if (typeof get(n, 'id') === 'string' && refuted.has(n.id) && !['superseded', 'refuted'].includes(status)
669
+ && !(status === 'done' && get(n, 'node_type') === 'question')) {
670
+ out.push('integrity.refutes-unreconciled');
671
+ }
637
672
  }
638
673
  return out;
639
674
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kg-ssot",
3
- "version": "4.10.0",
3
+ "version": "4.11.0",
4
4
  "description": "Leitor JS do contrato do grafo de conhecimento verificável KG-SSOT (.kg.yaml e .kg.json): validador pré-compilado, sem eval, para Node e React Native/Expo.",
5
5
  "keywords": [
6
6
  "knowledge-graph",
package/should.mjs CHANGED
@@ -1 +1 @@
1
- "use strict";export const validate = validate20;export default validate20;const schema31 = {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"urn:kg-ssot:spec:kg-contract-v4.should.schema.json","title":"kg.yaml — contrato v4, nível SHOULD","description":"O contrato v4 do .kg.yaml, nível SHOULD (alerta, não reprova), o vigente. É o SHOULD v3 menos o que o v4 promoveu a MUST: a chave desconhecida sem x_ no topo, no meta, no nó e na aresta e o nó confirmed ou PROD sem provenance. Segue alertando: nome de chave que não é slug ([A-Za-z_][A-Za-z0-9_-]*), como form.pattern.<escopo>.key, que sem x_ também reprova no MUST; nó PROD sem verified_at; label do nó acima de 280 caracteres, form.range.node.label, porque a narrativa vai para narrative; a chave desconhecida dentro de provenance, fechada em source, locator, method e x_; e o grafo sem nós (nodes: []), como form.range.top.nodes: é válido, como o primeiro uso de um app, mas o aviso pega o parse que falhou em silêncio. No v4, provenance.method alerta (form.pattern.node.provenance.method) quando não segue a forma canônica '<classe>: <detalhe>', com a classe em medição, leitura, juízes, derivado, testemunho; reprova no v5. Medição feita por terceiro e lida pelo autor do grafo é testemunho. No v4.1 entram quatro avisos que o próprio arquivo decide. O schema acusa a claim com verified_at e sem verified_against (form.required.node.verified_against): carimbo sem alvo não distingue verificado de declarado. Só a claim: evidence é a própria âncora, artifact nomeia o alvo, question não afirma e a origem da decision é cobrada por integrity.untraced-decision. O leitor acusa três avisos que cruzam campos ou arestas, por isso não cabem no schema: integrity.testimony-in-prod (nó PROD cuja base é testemunho), integrity.verified-before-fact (verified_at anterior a valid_from) e integrity.untraced-decision (decision viva sem trace, sem provenance e sem aresta TRACES_TO saindo dela). No v4.2 entra provenance.locality, opcional, com o enum repo (arquivo versionado no próprio repo), web (endereço público), host (só existe numa máquina: journal local, caminho fora do repo) ou pessoa (relato de alguém): o valor fora do enum alerta como form.enum.node.provenance.locality. Serve para medir o que é reverificável por terceiros e para barrar host na publicação.","type":"object","propertyNames":{"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"},"properties":{"meta":{"type":"object","propertyNames":{"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"}},"nodes":{"type":"array","items":{"type":"object","propertyNames":{"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"},"properties":{"label":{"maxLength":280},"provenance":{"propertyNames":{"allOf":[{"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"},{"anyOf":[{"enum":["locality","locator","method","source"]},{"pattern":"^x_"}]}]},"properties":{"method":{"pattern":"^(?:medição|leitura|juízes|derivado|testemunho): [^ \t\n\r]"},"locality":{"enum":["host","pessoa","repo","web"]}}}},"allOf":[{"if":{"properties":{"plane":{"const":"PROD"}},"required":["plane"]},"then":{"required":["verified_at"]}},{"if":{"properties":{"node_type":{"const":"claim"}},"required":["node_type","verified_at"]},"then":{"required":["verified_against"]}}]},"minItems":1},"edges":{"type":"array","items":{"type":"object","propertyNames":{"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"}}}}};const pattern4 = new RegExp("^[A-Za-z_][A-Za-z0-9_-]*$", "u");const pattern8 = new RegExp("^x_", "u");const pattern9 = new RegExp("^(?:medição|leitura|juízes|derivado|testemunho): [^ \t\n\r]", "u");import func1_mod from "ajv/dist/runtime/ucs2length.js";const func1 = func1_mod.default;function validate20(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){/*# sourceURL="urn:kg-ssot:spec:kg-contract-v4.should.schema.json" */;let vErrors = null;let errors = 0;const evaluated0 = validate20.evaluated;if(evaluated0.dynamicProps){evaluated0.props = undefined;}if(evaluated0.dynamicItems){evaluated0.items = undefined;}if(data && typeof data == "object" && !Array.isArray(data)){for(const key0 in data){const _errs1 = errors;if(typeof key0 === "string"){if(!pattern4.test(key0)){const err0 = {instancePath,schemaPath:"#/propertyNames/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z_][A-Za-z0-9_-]*$"},message:"must match pattern \""+"^[A-Za-z_][A-Za-z0-9_-]*$"+"\"",schema:"^[A-Za-z_][A-Za-z0-9_-]*$",parentSchema:schema31.propertyNames,data:key0,propertyName:key0};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}}var valid0 = _errs1 === errors;if(!valid0){const err1 = {instancePath,schemaPath:"#/propertyNames",keyword:"propertyNames",params:{propertyName: key0},message:"property name must be valid",schema:schema31.propertyNames,parentSchema:schema31,data};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}}if(data.meta !== undefined){let data0 = data.meta;if(data0 && typeof data0 == "object" && !Array.isArray(data0)){for(const key1 in data0){const _errs4 = errors;if(typeof key1 === "string"){if(!pattern4.test(key1)){const err2 = {instancePath:instancePath+"/meta",schemaPath:"#/properties/meta/propertyNames/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z_][A-Za-z0-9_-]*$"},message:"must match pattern \""+"^[A-Za-z_][A-Za-z0-9_-]*$"+"\"",schema:"^[A-Za-z_][A-Za-z0-9_-]*$",parentSchema:schema31.properties.meta.propertyNames,data:key1,propertyName:key1};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}}var valid2 = _errs4 === errors;if(!valid2){const err3 = {instancePath:instancePath+"/meta",schemaPath:"#/properties/meta/propertyNames",keyword:"propertyNames",params:{propertyName: key1},message:"property name must be valid",schema:schema31.properties.meta.propertyNames,parentSchema:schema31.properties.meta,data:data0};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}}}else {const err4 = {instancePath:instancePath+"/meta",schemaPath:"#/properties/meta/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.properties.meta.type,parentSchema:schema31.properties.meta,data:data0};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}}if(data.nodes !== undefined){let data1 = data.nodes;if(Array.isArray(data1)){if(data1.length < 1){const err5 = {instancePath:instancePath+"/nodes",schemaPath:"#/properties/nodes/minItems",keyword:"minItems",params:{limit: 1},message:"must NOT have fewer than 1 items",schema:1,parentSchema:schema31.properties.nodes,data:data1};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}const len0 = data1.length;for(let i0=0; i0<len0; i0++){let data2 = data1[i0];const _errs10 = errors;let valid6 = true;const _errs11 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){let missing0;if((data2.plane === undefined) && (missing0 = "plane")){const err6 = {};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}else {if(data2.plane !== undefined){if("PROD" !== data2.plane){const err7 = {};if(vErrors === null){vErrors = [err7];}else {vErrors.push(err7);}errors++;}}}}var _valid0 = _errs11 === errors;errors = _errs10;if(vErrors !== null){if(_errs10){vErrors.length = _errs10;}else {vErrors = null;}}if(_valid0){const _errs13 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.verified_at === undefined){const err8 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/allOf/0/then/required",keyword:"required",params:{missingProperty: "verified_at"},message:"must have required property '"+"verified_at"+"'",schema:schema31.properties.nodes.items.allOf[0].then.required,parentSchema:schema31.properties.nodes.items.allOf[0].then,data:data2};if(vErrors === null){vErrors = [err8];}else {vErrors.push(err8);}errors++;}}var _valid0 = _errs13 === errors;valid6 = _valid0;}if(!valid6){const err9 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/allOf/0/if",keyword:"if",params:{failingKeyword: "then"},message:"must match \"then\" schema",schema:schema31.properties.nodes.items.allOf[0].if,parentSchema:schema31.properties.nodes.items.allOf[0],data:data2};if(vErrors === null){vErrors = [err9];}else {vErrors.push(err9);}errors++;}const _errs15 = errors;let valid8 = true;const _errs16 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){let missing1;if(((data2.node_type === undefined) && (missing1 = "node_type")) || ((data2.verified_at === undefined) && (missing1 = "verified_at"))){const err10 = {};if(vErrors === null){vErrors = [err10];}else {vErrors.push(err10);}errors++;}else {if(data2.node_type !== undefined){if("claim" !== data2.node_type){const err11 = {};if(vErrors === null){vErrors = [err11];}else {vErrors.push(err11);}errors++;}}}}var _valid1 = _errs16 === errors;errors = _errs15;if(vErrors !== null){if(_errs15){vErrors.length = _errs15;}else {vErrors = null;}}if(_valid1){const _errs18 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.verified_against === undefined){const err12 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/allOf/1/then/required",keyword:"required",params:{missingProperty: "verified_against"},message:"must have required property '"+"verified_against"+"'",schema:schema31.properties.nodes.items.allOf[1].then.required,parentSchema:schema31.properties.nodes.items.allOf[1].then,data:data2};if(vErrors === null){vErrors = [err12];}else {vErrors.push(err12);}errors++;}}var _valid1 = _errs18 === errors;valid8 = _valid1;}if(!valid8){const err13 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/allOf/1/if",keyword:"if",params:{failingKeyword: "then"},message:"must match \"then\" schema",schema:schema31.properties.nodes.items.allOf[1].if,parentSchema:schema31.properties.nodes.items.allOf[1],data:data2};if(vErrors === null){vErrors = [err13];}else {vErrors.push(err13);}errors++;}if(data2 && typeof data2 == "object" && !Array.isArray(data2)){for(const key2 in data2){const _errs19 = errors;if(typeof key2 === "string"){if(!pattern4.test(key2)){const err14 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/propertyNames/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z_][A-Za-z0-9_-]*$"},message:"must match pattern \""+"^[A-Za-z_][A-Za-z0-9_-]*$"+"\"",schema:"^[A-Za-z_][A-Za-z0-9_-]*$",parentSchema:schema31.properties.nodes.items.propertyNames,data:key2,propertyName:key2};if(vErrors === null){vErrors = [err14];}else {vErrors.push(err14);}errors++;}}var valid10 = _errs19 === errors;if(!valid10){const err15 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/propertyNames",keyword:"propertyNames",params:{propertyName: key2},message:"property name must be valid",schema:schema31.properties.nodes.items.propertyNames,parentSchema:schema31.properties.nodes.items,data:data2};if(vErrors === null){vErrors = [err15];}else {vErrors.push(err15);}errors++;}}if(data2.label !== undefined){let data5 = data2.label;if(typeof data5 === "string"){if(func1(data5) > 280){const err16 = {instancePath:instancePath+"/nodes/" + i0+"/label",schemaPath:"#/properties/nodes/items/properties/label/maxLength",keyword:"maxLength",params:{limit: 280},message:"must NOT have more than 280 characters",schema:280,parentSchema:schema31.properties.nodes.items.properties.label,data:data5};if(vErrors === null){vErrors = [err16];}else {vErrors.push(err16);}errors++;}}}if(data2.provenance !== undefined){let data6 = data2.provenance;if(data6 && typeof data6 == "object" && !Array.isArray(data6)){for(const key3 in data6){const _errs22 = errors;if(typeof key3 === "string"){if(!pattern4.test(key3)){const err17 = {instancePath:instancePath+"/nodes/" + i0+"/provenance",schemaPath:"#/properties/nodes/items/properties/provenance/propertyNames/allOf/0/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z_][A-Za-z0-9_-]*$"},message:"must match pattern \""+"^[A-Za-z_][A-Za-z0-9_-]*$"+"\"",schema:"^[A-Za-z_][A-Za-z0-9_-]*$",parentSchema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[0],data:key3,propertyName:key3};if(vErrors === null){vErrors = [err17];}else {vErrors.push(err17);}errors++;}}const _errs25 = errors;let valid14 = false;const _errs26 = errors;if(!((((key3 === "locality") || (key3 === "locator")) || (key3 === "method")) || (key3 === "source"))){const err18 = {instancePath:instancePath+"/nodes/" + i0+"/provenance",schemaPath:"#/properties/nodes/items/properties/provenance/propertyNames/allOf/1/anyOf/0/enum",keyword:"enum",params:{allowedValues: schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1].anyOf[0].enum},message:"must be equal to one of the allowed values",schema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1].anyOf[0].enum,parentSchema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1].anyOf[0],data:key3,propertyName:key3};if(vErrors === null){vErrors = [err18];}else {vErrors.push(err18);}errors++;}var _valid2 = _errs26 === errors;valid14 = valid14 || _valid2;const _errs27 = errors;if(typeof key3 === "string"){if(!pattern8.test(key3)){const err19 = {instancePath:instancePath+"/nodes/" + i0+"/provenance",schemaPath:"#/properties/nodes/items/properties/provenance/propertyNames/allOf/1/anyOf/1/pattern",keyword:"pattern",params:{pattern: "^x_"},message:"must match pattern \""+"^x_"+"\"",schema:"^x_",parentSchema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1].anyOf[1],data:key3,propertyName:key3};if(vErrors === null){vErrors = [err19];}else {vErrors.push(err19);}errors++;}}var _valid2 = _errs27 === errors;valid14 = valid14 || _valid2;if(!valid14){const err20 = {instancePath:instancePath+"/nodes/" + i0+"/provenance",schemaPath:"#/properties/nodes/items/properties/provenance/propertyNames/allOf/1/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1].anyOf,parentSchema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1],data:key3,propertyName:key3};if(vErrors === null){vErrors = [err20];}else {vErrors.push(err20);}errors++;}else {errors = _errs25;if(vErrors !== null){if(_errs25){vErrors.length = _errs25;}else {vErrors = null;}}}var valid12 = _errs22 === errors;if(!valid12){const err21 = {instancePath:instancePath+"/nodes/" + i0+"/provenance",schemaPath:"#/properties/nodes/items/properties/provenance/propertyNames",keyword:"propertyNames",params:{propertyName: key3},message:"property name must be valid",schema:schema31.properties.nodes.items.properties.provenance.propertyNames,parentSchema:schema31.properties.nodes.items.properties.provenance,data:data6};if(vErrors === null){vErrors = [err21];}else {vErrors.push(err21);}errors++;}}if(data6.method !== undefined){let data7 = data6.method;if(typeof data7 === "string"){if(!pattern9.test(data7)){const err22 = {instancePath:instancePath+"/nodes/" + i0+"/provenance/method",schemaPath:"#/properties/nodes/items/properties/provenance/properties/method/pattern",keyword:"pattern",params:{pattern: "^(?:medição|leitura|juízes|derivado|testemunho): [^ \t\n\r]"},message:"must match pattern \""+"^(?:medição|leitura|juízes|derivado|testemunho): [^ \t\n\r]"+"\"",schema:"^(?:medição|leitura|juízes|derivado|testemunho): [^ \t\n\r]",parentSchema:schema31.properties.nodes.items.properties.provenance.properties.method,data:data7};if(vErrors === null){vErrors = [err22];}else {vErrors.push(err22);}errors++;}}}if(data6.locality !== undefined){let data8 = data6.locality;if(!((((data8 === "host") || (data8 === "pessoa")) || (data8 === "repo")) || (data8 === "web"))){const err23 = {instancePath:instancePath+"/nodes/" + i0+"/provenance/locality",schemaPath:"#/properties/nodes/items/properties/provenance/properties/locality/enum",keyword:"enum",params:{allowedValues: schema31.properties.nodes.items.properties.provenance.properties.locality.enum},message:"must be equal to one of the allowed values",schema:schema31.properties.nodes.items.properties.provenance.properties.locality.enum,parentSchema:schema31.properties.nodes.items.properties.provenance.properties.locality,data:data8};if(vErrors === null){vErrors = [err23];}else {vErrors.push(err23);}errors++;}}}}}else {const err24 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.properties.nodes.items.type,parentSchema:schema31.properties.nodes.items,data:data2};if(vErrors === null){vErrors = [err24];}else {vErrors.push(err24);}errors++;}}}else {const err25 = {instancePath:instancePath+"/nodes",schemaPath:"#/properties/nodes/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema31.properties.nodes.type,parentSchema:schema31.properties.nodes,data:data1};if(vErrors === null){vErrors = [err25];}else {vErrors.push(err25);}errors++;}}if(data.edges !== undefined){let data9 = data.edges;if(Array.isArray(data9)){const len1 = data9.length;for(let i1=0; i1<len1; i1++){let data10 = data9[i1];if(data10 && typeof data10 == "object" && !Array.isArray(data10)){for(const key4 in data10){const _errs34 = errors;if(typeof key4 === "string"){if(!pattern4.test(key4)){const err26 = {instancePath:instancePath+"/edges/" + i1,schemaPath:"#/properties/edges/items/propertyNames/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z_][A-Za-z0-9_-]*$"},message:"must match pattern \""+"^[A-Za-z_][A-Za-z0-9_-]*$"+"\"",schema:"^[A-Za-z_][A-Za-z0-9_-]*$",parentSchema:schema31.properties.edges.items.propertyNames,data:key4,propertyName:key4};if(vErrors === null){vErrors = [err26];}else {vErrors.push(err26);}errors++;}}var valid18 = _errs34 === errors;if(!valid18){const err27 = {instancePath:instancePath+"/edges/" + i1,schemaPath:"#/properties/edges/items/propertyNames",keyword:"propertyNames",params:{propertyName: key4},message:"property name must be valid",schema:schema31.properties.edges.items.propertyNames,parentSchema:schema31.properties.edges.items,data:data10};if(vErrors === null){vErrors = [err27];}else {vErrors.push(err27);}errors++;}}}else {const err28 = {instancePath:instancePath+"/edges/" + i1,schemaPath:"#/properties/edges/items/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.properties.edges.items.type,parentSchema:schema31.properties.edges.items,data:data10};if(vErrors === null){vErrors = [err28];}else {vErrors.push(err28);}errors++;}}}else {const err29 = {instancePath:instancePath+"/edges",schemaPath:"#/properties/edges/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema31.properties.edges.type,parentSchema:schema31.properties.edges,data:data9};if(vErrors === null){vErrors = [err29];}else {vErrors.push(err29);}errors++;}}}else {const err30 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.type,parentSchema:schema31,data};if(vErrors === null){vErrors = [err30];}else {vErrors.push(err30);}errors++;}validate20.errors = vErrors;return errors === 0;}validate20.evaluated = {"props":{"meta":true,"nodes":true,"edges":true},"dynamicProps":false,"dynamicItems":false};
1
+ "use strict";export const validate = validate20;export default validate20;const schema31 = {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"urn:kg-ssot:spec:kg-contract-v4.should.schema.json","title":"kg.yaml — contrato v4, nível SHOULD","description":"O contrato v4 do .kg.yaml, nível SHOULD (alerta, não reprova), o vigente. É o SHOULD v3 menos o que o v4 promoveu a MUST: a chave desconhecida sem x_ no topo, no meta, no nó e na aresta e o nó confirmed ou PROD sem provenance. Segue alertando: nome de chave que não é slug ([A-Za-z_][A-Za-z0-9_-]*), como form.pattern.<escopo>.key, que sem x_ também reprova no MUST; nó PROD sem verified_at; label do nó acima de 280 caracteres, form.range.node.label, porque a narrativa vai para narrative; a chave desconhecida dentro de provenance, fechada em source, locator, method e x_; e o grafo sem nós (nodes: []), como form.range.top.nodes: é válido, como o primeiro uso de um app, mas o aviso pega o parse que falhou em silêncio. No v4, provenance.method alerta (form.pattern.node.provenance.method) quando não segue a forma canônica '<classe>: <detalhe>', com a classe em medição, leitura, juízes, derivado, testemunho; reprova no v5. Medição feita por terceiro e lida pelo autor do grafo é testemunho. No v4.1 entram quatro avisos que o próprio arquivo decide. O schema acusa a claim com verified_at e sem verified_against (form.required.node.verified_against): carimbo sem alvo não distingue verificado de declarado. Só a claim: evidence é a própria âncora, artifact nomeia o alvo, question não afirma e a origem da decision é cobrada por integrity.untraced-decision. O leitor acusa três avisos que cruzam campos ou arestas, por isso não cabem no schema: integrity.testimony-in-prod (nó PROD cuja base é testemunho), integrity.verified-before-fact (verified_at anterior a valid_from) e integrity.untraced-decision (decision viva sem trace, sem provenance e sem aresta TRACES_TO saindo dela). No v4.2 entra provenance.locality, opcional, com o enum repo (arquivo versionado no próprio repo), web (endereço público), host (só existe numa máquina: journal local, caminho fora do repo) ou pessoa (relato de alguém): o valor fora do enum alerta como form.enum.node.provenance.locality. Serve para medir o que é reverificável por terceiros e para barrar host na publicação. No v4.4 entra o quarto aviso do leitor, integrity.refutes-unreconciled: nó que recebe REFUTES e segue vivo (nem superseded nem refuted; a question done já está respondida, e não alerta). O grafo afirma e refuta a mesma coisa; o radar do framework onde o formato nasceu reprova o caso como contradição. Aqui é SHOULD agora e vira MUST numa versão futura, depois que os adotantes medirem a própria dívida.","type":"object","propertyNames":{"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"},"properties":{"meta":{"type":"object","propertyNames":{"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"}},"nodes":{"type":"array","items":{"type":"object","propertyNames":{"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"},"properties":{"label":{"maxLength":280},"provenance":{"propertyNames":{"allOf":[{"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"},{"anyOf":[{"enum":["locality","locator","method","source"]},{"pattern":"^x_"}]}]},"properties":{"method":{"pattern":"^(?:medição|leitura|juízes|derivado|testemunho): [^ \t\n\r]"},"locality":{"enum":["host","pessoa","repo","web"]}}}},"allOf":[{"if":{"properties":{"plane":{"const":"PROD"}},"required":["plane"]},"then":{"required":["verified_at"]}},{"if":{"properties":{"node_type":{"const":"claim"}},"required":["node_type","verified_at"]},"then":{"required":["verified_against"]}}]},"minItems":1},"edges":{"type":"array","items":{"type":"object","propertyNames":{"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"}}}}};const pattern4 = new RegExp("^[A-Za-z_][A-Za-z0-9_-]*$", "u");const pattern8 = new RegExp("^x_", "u");const pattern9 = new RegExp("^(?:medição|leitura|juízes|derivado|testemunho): [^ \t\n\r]", "u");import func1_mod from "ajv/dist/runtime/ucs2length.js";const func1 = func1_mod.default;function validate20(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){/*# sourceURL="urn:kg-ssot:spec:kg-contract-v4.should.schema.json" */;let vErrors = null;let errors = 0;const evaluated0 = validate20.evaluated;if(evaluated0.dynamicProps){evaluated0.props = undefined;}if(evaluated0.dynamicItems){evaluated0.items = undefined;}if(data && typeof data == "object" && !Array.isArray(data)){for(const key0 in data){const _errs1 = errors;if(typeof key0 === "string"){if(!pattern4.test(key0)){const err0 = {instancePath,schemaPath:"#/propertyNames/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z_][A-Za-z0-9_-]*$"},message:"must match pattern \""+"^[A-Za-z_][A-Za-z0-9_-]*$"+"\"",schema:"^[A-Za-z_][A-Za-z0-9_-]*$",parentSchema:schema31.propertyNames,data:key0,propertyName:key0};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}}var valid0 = _errs1 === errors;if(!valid0){const err1 = {instancePath,schemaPath:"#/propertyNames",keyword:"propertyNames",params:{propertyName: key0},message:"property name must be valid",schema:schema31.propertyNames,parentSchema:schema31,data};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}}if(data.meta !== undefined){let data0 = data.meta;if(data0 && typeof data0 == "object" && !Array.isArray(data0)){for(const key1 in data0){const _errs4 = errors;if(typeof key1 === "string"){if(!pattern4.test(key1)){const err2 = {instancePath:instancePath+"/meta",schemaPath:"#/properties/meta/propertyNames/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z_][A-Za-z0-9_-]*$"},message:"must match pattern \""+"^[A-Za-z_][A-Za-z0-9_-]*$"+"\"",schema:"^[A-Za-z_][A-Za-z0-9_-]*$",parentSchema:schema31.properties.meta.propertyNames,data:key1,propertyName:key1};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}}var valid2 = _errs4 === errors;if(!valid2){const err3 = {instancePath:instancePath+"/meta",schemaPath:"#/properties/meta/propertyNames",keyword:"propertyNames",params:{propertyName: key1},message:"property name must be valid",schema:schema31.properties.meta.propertyNames,parentSchema:schema31.properties.meta,data:data0};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}}}else {const err4 = {instancePath:instancePath+"/meta",schemaPath:"#/properties/meta/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.properties.meta.type,parentSchema:schema31.properties.meta,data:data0};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}}if(data.nodes !== undefined){let data1 = data.nodes;if(Array.isArray(data1)){if(data1.length < 1){const err5 = {instancePath:instancePath+"/nodes",schemaPath:"#/properties/nodes/minItems",keyword:"minItems",params:{limit: 1},message:"must NOT have fewer than 1 items",schema:1,parentSchema:schema31.properties.nodes,data:data1};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}const len0 = data1.length;for(let i0=0; i0<len0; i0++){let data2 = data1[i0];const _errs10 = errors;let valid6 = true;const _errs11 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){let missing0;if((data2.plane === undefined) && (missing0 = "plane")){const err6 = {};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}else {if(data2.plane !== undefined){if("PROD" !== data2.plane){const err7 = {};if(vErrors === null){vErrors = [err7];}else {vErrors.push(err7);}errors++;}}}}var _valid0 = _errs11 === errors;errors = _errs10;if(vErrors !== null){if(_errs10){vErrors.length = _errs10;}else {vErrors = null;}}if(_valid0){const _errs13 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.verified_at === undefined){const err8 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/allOf/0/then/required",keyword:"required",params:{missingProperty: "verified_at"},message:"must have required property '"+"verified_at"+"'",schema:schema31.properties.nodes.items.allOf[0].then.required,parentSchema:schema31.properties.nodes.items.allOf[0].then,data:data2};if(vErrors === null){vErrors = [err8];}else {vErrors.push(err8);}errors++;}}var _valid0 = _errs13 === errors;valid6 = _valid0;}if(!valid6){const err9 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/allOf/0/if",keyword:"if",params:{failingKeyword: "then"},message:"must match \"then\" schema",schema:schema31.properties.nodes.items.allOf[0].if,parentSchema:schema31.properties.nodes.items.allOf[0],data:data2};if(vErrors === null){vErrors = [err9];}else {vErrors.push(err9);}errors++;}const _errs15 = errors;let valid8 = true;const _errs16 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){let missing1;if(((data2.node_type === undefined) && (missing1 = "node_type")) || ((data2.verified_at === undefined) && (missing1 = "verified_at"))){const err10 = {};if(vErrors === null){vErrors = [err10];}else {vErrors.push(err10);}errors++;}else {if(data2.node_type !== undefined){if("claim" !== data2.node_type){const err11 = {};if(vErrors === null){vErrors = [err11];}else {vErrors.push(err11);}errors++;}}}}var _valid1 = _errs16 === errors;errors = _errs15;if(vErrors !== null){if(_errs15){vErrors.length = _errs15;}else {vErrors = null;}}if(_valid1){const _errs18 = errors;if(data2 && typeof data2 == "object" && !Array.isArray(data2)){if(data2.verified_against === undefined){const err12 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/allOf/1/then/required",keyword:"required",params:{missingProperty: "verified_against"},message:"must have required property '"+"verified_against"+"'",schema:schema31.properties.nodes.items.allOf[1].then.required,parentSchema:schema31.properties.nodes.items.allOf[1].then,data:data2};if(vErrors === null){vErrors = [err12];}else {vErrors.push(err12);}errors++;}}var _valid1 = _errs18 === errors;valid8 = _valid1;}if(!valid8){const err13 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/allOf/1/if",keyword:"if",params:{failingKeyword: "then"},message:"must match \"then\" schema",schema:schema31.properties.nodes.items.allOf[1].if,parentSchema:schema31.properties.nodes.items.allOf[1],data:data2};if(vErrors === null){vErrors = [err13];}else {vErrors.push(err13);}errors++;}if(data2 && typeof data2 == "object" && !Array.isArray(data2)){for(const key2 in data2){const _errs19 = errors;if(typeof key2 === "string"){if(!pattern4.test(key2)){const err14 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/propertyNames/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z_][A-Za-z0-9_-]*$"},message:"must match pattern \""+"^[A-Za-z_][A-Za-z0-9_-]*$"+"\"",schema:"^[A-Za-z_][A-Za-z0-9_-]*$",parentSchema:schema31.properties.nodes.items.propertyNames,data:key2,propertyName:key2};if(vErrors === null){vErrors = [err14];}else {vErrors.push(err14);}errors++;}}var valid10 = _errs19 === errors;if(!valid10){const err15 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/propertyNames",keyword:"propertyNames",params:{propertyName: key2},message:"property name must be valid",schema:schema31.properties.nodes.items.propertyNames,parentSchema:schema31.properties.nodes.items,data:data2};if(vErrors === null){vErrors = [err15];}else {vErrors.push(err15);}errors++;}}if(data2.label !== undefined){let data5 = data2.label;if(typeof data5 === "string"){if(func1(data5) > 280){const err16 = {instancePath:instancePath+"/nodes/" + i0+"/label",schemaPath:"#/properties/nodes/items/properties/label/maxLength",keyword:"maxLength",params:{limit: 280},message:"must NOT have more than 280 characters",schema:280,parentSchema:schema31.properties.nodes.items.properties.label,data:data5};if(vErrors === null){vErrors = [err16];}else {vErrors.push(err16);}errors++;}}}if(data2.provenance !== undefined){let data6 = data2.provenance;if(data6 && typeof data6 == "object" && !Array.isArray(data6)){for(const key3 in data6){const _errs22 = errors;if(typeof key3 === "string"){if(!pattern4.test(key3)){const err17 = {instancePath:instancePath+"/nodes/" + i0+"/provenance",schemaPath:"#/properties/nodes/items/properties/provenance/propertyNames/allOf/0/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z_][A-Za-z0-9_-]*$"},message:"must match pattern \""+"^[A-Za-z_][A-Za-z0-9_-]*$"+"\"",schema:"^[A-Za-z_][A-Za-z0-9_-]*$",parentSchema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[0],data:key3,propertyName:key3};if(vErrors === null){vErrors = [err17];}else {vErrors.push(err17);}errors++;}}const _errs25 = errors;let valid14 = false;const _errs26 = errors;if(!((((key3 === "locality") || (key3 === "locator")) || (key3 === "method")) || (key3 === "source"))){const err18 = {instancePath:instancePath+"/nodes/" + i0+"/provenance",schemaPath:"#/properties/nodes/items/properties/provenance/propertyNames/allOf/1/anyOf/0/enum",keyword:"enum",params:{allowedValues: schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1].anyOf[0].enum},message:"must be equal to one of the allowed values",schema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1].anyOf[0].enum,parentSchema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1].anyOf[0],data:key3,propertyName:key3};if(vErrors === null){vErrors = [err18];}else {vErrors.push(err18);}errors++;}var _valid2 = _errs26 === errors;valid14 = valid14 || _valid2;const _errs27 = errors;if(typeof key3 === "string"){if(!pattern8.test(key3)){const err19 = {instancePath:instancePath+"/nodes/" + i0+"/provenance",schemaPath:"#/properties/nodes/items/properties/provenance/propertyNames/allOf/1/anyOf/1/pattern",keyword:"pattern",params:{pattern: "^x_"},message:"must match pattern \""+"^x_"+"\"",schema:"^x_",parentSchema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1].anyOf[1],data:key3,propertyName:key3};if(vErrors === null){vErrors = [err19];}else {vErrors.push(err19);}errors++;}}var _valid2 = _errs27 === errors;valid14 = valid14 || _valid2;if(!valid14){const err20 = {instancePath:instancePath+"/nodes/" + i0+"/provenance",schemaPath:"#/properties/nodes/items/properties/provenance/propertyNames/allOf/1/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf",schema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1].anyOf,parentSchema:schema31.properties.nodes.items.properties.provenance.propertyNames.allOf[1],data:key3,propertyName:key3};if(vErrors === null){vErrors = [err20];}else {vErrors.push(err20);}errors++;}else {errors = _errs25;if(vErrors !== null){if(_errs25){vErrors.length = _errs25;}else {vErrors = null;}}}var valid12 = _errs22 === errors;if(!valid12){const err21 = {instancePath:instancePath+"/nodes/" + i0+"/provenance",schemaPath:"#/properties/nodes/items/properties/provenance/propertyNames",keyword:"propertyNames",params:{propertyName: key3},message:"property name must be valid",schema:schema31.properties.nodes.items.properties.provenance.propertyNames,parentSchema:schema31.properties.nodes.items.properties.provenance,data:data6};if(vErrors === null){vErrors = [err21];}else {vErrors.push(err21);}errors++;}}if(data6.method !== undefined){let data7 = data6.method;if(typeof data7 === "string"){if(!pattern9.test(data7)){const err22 = {instancePath:instancePath+"/nodes/" + i0+"/provenance/method",schemaPath:"#/properties/nodes/items/properties/provenance/properties/method/pattern",keyword:"pattern",params:{pattern: "^(?:medição|leitura|juízes|derivado|testemunho): [^ \t\n\r]"},message:"must match pattern \""+"^(?:medição|leitura|juízes|derivado|testemunho): [^ \t\n\r]"+"\"",schema:"^(?:medição|leitura|juízes|derivado|testemunho): [^ \t\n\r]",parentSchema:schema31.properties.nodes.items.properties.provenance.properties.method,data:data7};if(vErrors === null){vErrors = [err22];}else {vErrors.push(err22);}errors++;}}}if(data6.locality !== undefined){let data8 = data6.locality;if(!((((data8 === "host") || (data8 === "pessoa")) || (data8 === "repo")) || (data8 === "web"))){const err23 = {instancePath:instancePath+"/nodes/" + i0+"/provenance/locality",schemaPath:"#/properties/nodes/items/properties/provenance/properties/locality/enum",keyword:"enum",params:{allowedValues: schema31.properties.nodes.items.properties.provenance.properties.locality.enum},message:"must be equal to one of the allowed values",schema:schema31.properties.nodes.items.properties.provenance.properties.locality.enum,parentSchema:schema31.properties.nodes.items.properties.provenance.properties.locality,data:data8};if(vErrors === null){vErrors = [err23];}else {vErrors.push(err23);}errors++;}}}}}else {const err24 = {instancePath:instancePath+"/nodes/" + i0,schemaPath:"#/properties/nodes/items/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.properties.nodes.items.type,parentSchema:schema31.properties.nodes.items,data:data2};if(vErrors === null){vErrors = [err24];}else {vErrors.push(err24);}errors++;}}}else {const err25 = {instancePath:instancePath+"/nodes",schemaPath:"#/properties/nodes/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema31.properties.nodes.type,parentSchema:schema31.properties.nodes,data:data1};if(vErrors === null){vErrors = [err25];}else {vErrors.push(err25);}errors++;}}if(data.edges !== undefined){let data9 = data.edges;if(Array.isArray(data9)){const len1 = data9.length;for(let i1=0; i1<len1; i1++){let data10 = data9[i1];if(data10 && typeof data10 == "object" && !Array.isArray(data10)){for(const key4 in data10){const _errs34 = errors;if(typeof key4 === "string"){if(!pattern4.test(key4)){const err26 = {instancePath:instancePath+"/edges/" + i1,schemaPath:"#/properties/edges/items/propertyNames/pattern",keyword:"pattern",params:{pattern: "^[A-Za-z_][A-Za-z0-9_-]*$"},message:"must match pattern \""+"^[A-Za-z_][A-Za-z0-9_-]*$"+"\"",schema:"^[A-Za-z_][A-Za-z0-9_-]*$",parentSchema:schema31.properties.edges.items.propertyNames,data:key4,propertyName:key4};if(vErrors === null){vErrors = [err26];}else {vErrors.push(err26);}errors++;}}var valid18 = _errs34 === errors;if(!valid18){const err27 = {instancePath:instancePath+"/edges/" + i1,schemaPath:"#/properties/edges/items/propertyNames",keyword:"propertyNames",params:{propertyName: key4},message:"property name must be valid",schema:schema31.properties.edges.items.propertyNames,parentSchema:schema31.properties.edges.items,data:data10};if(vErrors === null){vErrors = [err27];}else {vErrors.push(err27);}errors++;}}}else {const err28 = {instancePath:instancePath+"/edges/" + i1,schemaPath:"#/properties/edges/items/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.properties.edges.items.type,parentSchema:schema31.properties.edges.items,data:data10};if(vErrors === null){vErrors = [err28];}else {vErrors.push(err28);}errors++;}}}else {const err29 = {instancePath:instancePath+"/edges",schemaPath:"#/properties/edges/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema31.properties.edges.type,parentSchema:schema31.properties.edges,data:data9};if(vErrors === null){vErrors = [err29];}else {vErrors.push(err29);}errors++;}}}else {const err30 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object",schema:schema31.type,parentSchema:schema31,data};if(vErrors === null){vErrors = [err30];}else {vErrors.push(err30);}errors++;}validate20.errors = vErrors;return errors === 0;}validate20.evaluated = {"props":{"meta":true,"nodes":true,"edges":true},"dynamicProps":false,"dynamicItems":false};
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "urn:kg-ssot:spec:kg-contract-v4.should.schema.json",
4
4
  "title": "kg.yaml — contrato v4, nível SHOULD",
5
- "description": "O contrato v4 do .kg.yaml, nível SHOULD (alerta, não reprova), o vigente. É o SHOULD v3 menos o que o v4 promoveu a MUST: a chave desconhecida sem x_ no topo, no meta, no nó e na aresta e o nó confirmed ou PROD sem provenance. Segue alertando: nome de chave que não é slug ([A-Za-z_][A-Za-z0-9_-]*), como form.pattern.<escopo>.key, que sem x_ também reprova no MUST; nó PROD sem verified_at; label do nó acima de 280 caracteres, form.range.node.label, porque a narrativa vai para narrative; a chave desconhecida dentro de provenance, fechada em source, locator, method e x_; e o grafo sem nós (nodes: []), como form.range.top.nodes: é válido, como o primeiro uso de um app, mas o aviso pega o parse que falhou em silêncio. No v4, provenance.method alerta (form.pattern.node.provenance.method) quando não segue a forma canônica '<classe>: <detalhe>', com a classe em medição, leitura, juízes, derivado, testemunho; reprova no v5. Medição feita por terceiro e lida pelo autor do grafo é testemunho. No v4.1 entram quatro avisos que o próprio arquivo decide. O schema acusa a claim com verified_at e sem verified_against (form.required.node.verified_against): carimbo sem alvo não distingue verificado de declarado. Só a claim: evidence é a própria âncora, artifact nomeia o alvo, question não afirma e a origem da decision é cobrada por integrity.untraced-decision. O leitor acusa três avisos que cruzam campos ou arestas, por isso não cabem no schema: integrity.testimony-in-prod (nó PROD cuja base é testemunho), integrity.verified-before-fact (verified_at anterior a valid_from) e integrity.untraced-decision (decision viva sem trace, sem provenance e sem aresta TRACES_TO saindo dela). No v4.2 entra provenance.locality, opcional, com o enum repo (arquivo versionado no próprio repo), web (endereço público), host (só existe numa máquina: journal local, caminho fora do repo) ou pessoa (relato de alguém): o valor fora do enum alerta como form.enum.node.provenance.locality. Serve para medir o que é reverificável por terceiros e para barrar host na publicação.",
5
+ "description": "O contrato v4 do .kg.yaml, nível SHOULD (alerta, não reprova), o vigente. É o SHOULD v3 menos o que o v4 promoveu a MUST: a chave desconhecida sem x_ no topo, no meta, no nó e na aresta e o nó confirmed ou PROD sem provenance. Segue alertando: nome de chave que não é slug ([A-Za-z_][A-Za-z0-9_-]*), como form.pattern.<escopo>.key, que sem x_ também reprova no MUST; nó PROD sem verified_at; label do nó acima de 280 caracteres, form.range.node.label, porque a narrativa vai para narrative; a chave desconhecida dentro de provenance, fechada em source, locator, method e x_; e o grafo sem nós (nodes: []), como form.range.top.nodes: é válido, como o primeiro uso de um app, mas o aviso pega o parse que falhou em silêncio. No v4, provenance.method alerta (form.pattern.node.provenance.method) quando não segue a forma canônica '<classe>: <detalhe>', com a classe em medição, leitura, juízes, derivado, testemunho; reprova no v5. Medição feita por terceiro e lida pelo autor do grafo é testemunho. No v4.1 entram quatro avisos que o próprio arquivo decide. O schema acusa a claim com verified_at e sem verified_against (form.required.node.verified_against): carimbo sem alvo não distingue verificado de declarado. Só a claim: evidence é a própria âncora, artifact nomeia o alvo, question não afirma e a origem da decision é cobrada por integrity.untraced-decision. O leitor acusa três avisos que cruzam campos ou arestas, por isso não cabem no schema: integrity.testimony-in-prod (nó PROD cuja base é testemunho), integrity.verified-before-fact (verified_at anterior a valid_from) e integrity.untraced-decision (decision viva sem trace, sem provenance e sem aresta TRACES_TO saindo dela). No v4.2 entra provenance.locality, opcional, com o enum repo (arquivo versionado no próprio repo), web (endereço público), host (só existe numa máquina: journal local, caminho fora do repo) ou pessoa (relato de alguém): o valor fora do enum alerta como form.enum.node.provenance.locality. Serve para medir o que é reverificável por terceiros e para barrar host na publicação. No v4.4 entra o quarto aviso do leitor, integrity.refutes-unreconciled: nó que recebe REFUTES e segue vivo (nem superseded nem refuted; a question done já está respondida, e não alerta). O grafo afirma e refuta a mesma coisa; o radar do framework onde o formato nasceu reprova o caso como contradição. Aqui é SHOULD agora e vira MUST numa versão futura, depois que os adotantes medirem a própria dívida.",
6
6
  "type": "object",
7
7
  "propertyNames": {
8
8
  "pattern": "^[A-Za-z_][A-Za-z0-9_-]*$"
package/spec/release.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "4.10.0",
3
- "tag": "kg-ssot-v4.10.0",
2
+ "version": "4.11.0",
3
+ "tag": "kg-ssot-v4.11.0",
4
4
  "contract": {
5
5
  "must": "spec/kg-contract-v4.schema.json",
6
6
  "should": "spec/kg-contract-v4.should.schema.json"