kg-ssot 4.17.2 → 4.18.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 +109 -49
- package/cli.mjs +56 -9
- package/package.json +2 -2
- package/run.mjs +7 -1
- package/spec/release.json +9 -2
- package/spec/verdict.schema.json +2 -2
package/README.md
CHANGED
|
@@ -1,85 +1,145 @@
|
|
|
1
1
|
# kg-ssot
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/kg-ssot)
|
|
4
|
+
[](https://github.com/marciocar/kg-ssot/blob/main/LICENSE)
|
|
5
|
+
[](https://github.com/marciocar/kg-ssot)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
- o **núcleo do leitor**, sem `fs` e sem processo;
|
|
9
|
-
- os **validadores do contrato pré-compilados**, MUST e SHOULD, que não usam `new Function` nem `eval`. Por isso rodam
|
|
10
|
-
em motores sem geração de código, como o Hermes do React Native e do Expo, e no Node;
|
|
11
|
-
- os **schemas** do contrato e do veredito.
|
|
7
|
+
**The JavaScript reader for the KG-SSOT contract, the verifiable knowledge graph. Every claim says where it came
|
|
8
|
+
from, when someone verified it, and what depends on it.**
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
pelo pacote instalado a cada mudança no leitor.
|
|
10
|
+
`kg-ssot` checks a `.kg.yaml` or `.kg.json` graph against the current contract (v4). It returns the MUST verdict and
|
|
11
|
+
the SHOULD warnings, with the stable codes of the conformance suite. The package ships:
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
- **The reader core**, which uses neither `fs` nor `process`.
|
|
14
|
+
- **Precompiled contract validators**, MUST and SHOULD, that never call `new Function` or `eval`. They run on engines
|
|
15
|
+
without runtime code generation, like Hermes in React Native and Expo, and on Node.
|
|
16
|
+
- **The schemas** of the contract and of the verdict.
|
|
17
|
+
|
|
18
|
+
The reference reader is the Python package [`kg-ssot`](https://pypi.org/project/kg-ssot/). This reader passes every
|
|
19
|
+
case in the conformance suite (`latest/`) with the expected verdict, codes, and warnings. On every change to the
|
|
20
|
+
reader, CI runs the whole suite against the installed tarball.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
18
23
|
|
|
19
24
|
```bash
|
|
20
25
|
npm install kg-ssot
|
|
21
26
|
```
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
On Node, you need version 22.12 or later. The package is ESM and ships its own TypeScript types.
|
|
29
|
+
|
|
30
|
+
## Use it in code
|
|
24
31
|
|
|
25
32
|
```js
|
|
26
33
|
import { verdict } from 'kg-ssot';
|
|
27
34
|
|
|
28
|
-
verdict(
|
|
29
|
-
verdict(
|
|
35
|
+
verdict(text); // .kg.yaml (the default)
|
|
36
|
+
verdict(text, { format: 'json' }); // .kg.json
|
|
30
37
|
// { verdict: 'accept', codes: [], warnings: [], detail: '' }
|
|
31
38
|
// { verdict: 'accept', codes: [], warnings: ['yaml.unquoted-date'], detail: '' }
|
|
32
|
-
// { verdict: 'reject', codes: ['form.range.node.impact'], warnings: [], detail: '' }
|
|
39
|
+
// { verdict: 'reject', codes: ['form.range.node.impact', 'form.type.node.impact'], warnings: [], detail: '' }
|
|
33
40
|
```
|
|
34
41
|
|
|
35
|
-
- `verdict(
|
|
36
|
-
`reject`, `codes`
|
|
37
|
-
|
|
38
|
-
- `check(
|
|
39
|
-
{ format })`
|
|
40
|
-
- `
|
|
41
|
-
|
|
42
|
-
`
|
|
42
|
+
- `verdict(text, { format, corpus })` returns the verdict in the suite's runner contract. `verdict` is `accept` or
|
|
43
|
+
`reject`, `codes` lists the MUST codes, and `warnings` lists the SHOULD codes. Both lists are sorted, with no
|
|
44
|
+
duplicates. A warning never fails a graph: a graph with warnings is still `accept`.
|
|
45
|
+
- `check(text, { format, corpus })` returns only the MUST codes (empty when the graph passes).
|
|
46
|
+
`checkWarnings(text, { format, corpus })` returns only the warnings.
|
|
47
|
+
- `corpus` lets the reader verify the far end of each `external_edges` entry. It is a
|
|
48
|
+
`Map<path, Set<nodeId>>`. Build it with `corpusIndex(dir)` from `kg-ssot/node`, or, without a file system, with
|
|
49
|
+
`indexTexts([[path, text], ...])` from the main entry.
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
casos da suíte, e desde a 4.13.0 trata o `\r` como quebra de linha, como a referência. 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.
|
|
51
|
+
### Entry points
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
| Import | What you get |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `kg-ssot` | `verdict`, `check`, `checkWarnings`, the precompiled `validateMust` and `validateShould`, and the core |
|
|
56
|
+
| `kg-ssot/core` | The core without the validators, for when you compile the schema yourself (`verdictOf`, `codes`, `warnings`, `parse`, `indexTexts`) |
|
|
57
|
+
| `kg-ssot/must`, `kg-ssot/should` | The precompiled MUST and SHOULD validators alone |
|
|
58
|
+
| `kg-ssot/node` | Node helpers: `corpusIndex(dir)` indexes the `.kg.yaml` and `.kg.json` graphs under a directory (the tracked ones, in a git repository); `compileMust()` compiles the schema with `ajv` at runtime |
|
|
59
|
+
| `kg-ssot/spec/*` | The contract and verdict schemas |
|
|
49
60
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
Since 4.10.0, this reader also measures the SHOULD warnings, with the same codes as the reference reader on every
|
|
62
|
+
suite case. Since 4.13.0, it treats `\r` as a line break, like the reference. Since 4.11.0, the three rare YAML
|
|
63
|
+
constructs where it used to diverge from the reference (the unnamed `!` tag, a `!!timestamp` whose text is not a
|
|
64
|
+
date, and a tab outside quotes) now fail in both, and the suite has cases for them. Only the Python reference reader
|
|
65
|
+
reports the line of each finding and the fix hints.
|
|
53
66
|
|
|
54
|
-
##
|
|
67
|
+
## TypeScript and CommonJS
|
|
68
|
+
|
|
69
|
+
The package ships types (`index.d.mts`, `core.d.mts`, `node.d.mts`, and `validator.d.mts`). It works with
|
|
70
|
+
`moduleResolution` set to `bundler` or `nodenext`, which covers the Expo TypeScript template. It is an ESM package.
|
|
71
|
+
In a CommonJS project, `require('kg-ssot')` works from Node 22.12, the minimum declared in `engines`.
|
|
72
|
+
|
|
73
|
+
## Use it from the command line
|
|
55
74
|
|
|
56
75
|
```bash
|
|
57
|
-
npx kg-ssot-validate
|
|
76
|
+
npx kg-ssot-validate decisions.kg.yaml graph.kg.yaml other.kg.json
|
|
58
77
|
```
|
|
59
78
|
|
|
60
79
|
```text
|
|
61
|
-
|
|
80
|
+
PASS decisions.kg.yaml
|
|
81
|
+
PASS graph.kg.yaml
|
|
82
|
+
WARNING yaml.unquoted-date
|
|
83
|
+
FAIL other.kg.json
|
|
84
|
+
MUST form.range.node.impact · form.type.node.impact
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The exit code is 0 when every file passes, 1 when any file fails, and 2 on broken input: an unreadable file, invalid
|
|
88
|
+
UTF-8, an unknown option, or a `--corpus` that is not a directory. Warnings never change the exit code.
|
|
89
|
+
|
|
90
|
+
- `--json` prints one JSON line per file, in the suite's runner contract:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
{"file":"graph.kg.yaml","verdict":"accept","codes":[],"warnings":["yaml.unquoted-date"],"detail":""}
|
|
94
|
+
{"file":"other.kg.json","verdict":"reject","codes":["form.range.node.impact","form.type.node.impact"],"warnings":[],"detail":""}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
- `--corpus DIR` verifies the far end of each `external_edges` entry against the `.kg.yaml` and `.kg.json` graphs
|
|
98
|
+
under `DIR`.
|
|
99
|
+
|
|
100
|
+
The human output is in English. The CLI speaks Brazilian Portuguese when you set `KG_SSOT_LANG=pt-BR` (or when your
|
|
101
|
+
locale is `pt_BR`):
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
KG_SSOT_LANG=pt-BR npx kg-ssot-validate decisions.kg.yaml graph.kg.yaml other.kg.json
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
PASSA decisions.kg.yaml
|
|
109
|
+
PASSA graph.kg.yaml
|
|
62
110
|
AVISO yaml.unquoted-date
|
|
63
|
-
REPROVA
|
|
64
|
-
MUST form.range.node.impact ·
|
|
111
|
+
REPROVA other.kg.json
|
|
112
|
+
MUST form.range.node.impact · form.type.node.impact
|
|
65
113
|
```
|
|
66
114
|
|
|
67
|
-
|
|
68
|
-
mudam o rc. Com `--json`, sai uma linha JSON por
|
|
69
|
-
arquivo. Com `--corpus DIR`, a ponta externa das `external_edges` é conferida contra os `.kg.yaml` sob `DIR`.
|
|
115
|
+
The codes and the `--json` output are data, so they never change language.
|
|
70
116
|
|
|
71
|
-
##
|
|
117
|
+
## Use it in a React Native or Expo app
|
|
118
|
+
|
|
119
|
+
The package is ESM, and the main entry imports nothing from Node. Your bundler (Metro, esbuild) resolves the two
|
|
120
|
+
dependencies, `yaml` and the `ajv` runtime. The validators come precompiled, so nothing has to generate code on the
|
|
121
|
+
device. We ran the conformance suite on Hermes, and it returns the same verdicts as Node.
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
import { verdict, indexTexts } from 'kg-ssot';
|
|
125
|
+
|
|
126
|
+
const corpus = indexTexts([['other.kg.yaml', otherText]]); // optional, for external_edges
|
|
127
|
+
const result = verdict(graphText, { corpus });
|
|
128
|
+
if (result.verdict === 'reject') console.warn(result.codes);
|
|
129
|
+
```
|
|
72
130
|
|
|
73
|
-
|
|
74
|
-
runtime do `ajv`. O validador já vem compilado, então nada precisa gerar código no aparelho. O comportamento foi
|
|
75
|
-
medido no Hermes: os mesmos vereditos do Node.
|
|
131
|
+
## Documentation
|
|
76
132
|
|
|
77
|
-
|
|
133
|
+
- [Manual](https://github.com/marciocar/kg-ssot/tree/main/docs/manual): the format, the contract, the tools, and
|
|
134
|
+
common problems
|
|
135
|
+
- [Conformance suite](https://github.com/marciocar/kg-ssot/blob/main/spec/conformance/README.md)
|
|
136
|
+
- [Adoption guide](https://github.com/marciocar/kg-ssot/blob/main/ADOPTING.md)
|
|
137
|
+
- [Changelog](https://github.com/marciocar/kg-ssot/blob/main/CHANGELOG.md)
|
|
138
|
+
- [Issues](https://github.com/marciocar/kg-ssot/issues)
|
|
78
139
|
|
|
79
|
-
|
|
80
|
-
- [Suíte de conformidade](https://github.com/marciocar/kg-ssot/blob/main/spec/conformance/README.md)
|
|
81
|
-
- [Guia de adoção](https://github.com/marciocar/kg-ssot/blob/main/ADOPTING.md)
|
|
140
|
+
## License
|
|
82
141
|
|
|
83
|
-
|
|
142
|
+
Apache-2.0. See [`LICENSE`](https://github.com/marciocar/kg-ssot/blob/main/LICENSE) and
|
|
143
|
+
[`NOTICE`](https://github.com/marciocar/kg-ssot/blob/main/NOTICE).
|
|
84
144
|
|
|
85
|
-
|
|
145
|
+
Documentação em português: [README.pt-BR](https://github.com/marciocar/kg-ssot/blob/main/README.pt-BR.md).
|
package/cli.mjs
CHANGED
|
@@ -4,14 +4,60 @@
|
|
|
4
4
|
// kg-ssot-validate <arquivo>... [--json] [--corpus DIR]
|
|
5
5
|
//
|
|
6
6
|
// rc 0 quando todos passam no MUST, 1 quando algum reprova, 2 com entrada quebrada (arquivo ilegível, UTF-8
|
|
7
|
-
// inválido). Os avisos SHOULD saem numa linha
|
|
7
|
+
// inválido). Os avisos SHOULD saem numa linha WARNING e não mudam o rc. --json imprime uma linha JSON por arquivo, no contrato de runner da suíte. --corpus confere a ponta
|
|
8
8
|
// externa das external_edges contra os .kg.yaml e .kg.json sob DIR.
|
|
9
|
+
//
|
|
10
|
+
// A saída humana sai em inglês (a língua-fonte) ou na tradução pt-BR, negociada como no kg_i18n do Python:
|
|
11
|
+
// KG_SSOT_LANG, LANGUAGE, LC_ALL, LC_MESSAGES e LANG, parando na primeira definida; C, POSIX e vazio são o inglês.
|
|
12
|
+
// Como no gettext, o LANGUAGE só vale quando o locale efetivo (LC_ALL, LC_MESSAGES, LANG) não é o C.
|
|
13
|
+
// As frases ficam também no catálogo locale/pt_BR/LC_MESSAGES/kg-ssot.po (referência #: packaging/npm/cli.mjs), para o tradutor ter um lugar
|
|
14
|
+
// só. A saída --json é dado e não se traduz.
|
|
9
15
|
import { readFileSync } from 'node:fs';
|
|
10
16
|
|
|
11
17
|
import { verdict } from './index.mjs';
|
|
12
18
|
import { corpusIndex } from './run.mjs';
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
// A tradução pt-BR (igual às entradas do cli.mjs no kg-ssot.po); a chave é o msgid em inglês.
|
|
21
|
+
const PT_BR = {
|
|
22
|
+
'usage: kg-ssot-validate <file.kg.yaml|file.kg.json>... [--json] [--corpus DIR]':
|
|
23
|
+
'uso: kg-ssot-validate <arquivo.kg.yaml|arquivo.kg.json>... [--json] [--corpus DIR]',
|
|
24
|
+
'BROKEN INPUT': 'ENTRADA QUEBRADA',
|
|
25
|
+
'--corpus without a directory': '--corpus sem diretório',
|
|
26
|
+
'unknown option: {option}': 'opção desconhecida: {option}',
|
|
27
|
+
'corpus {root} is not a directory': 'corpus {root} não é um diretório',
|
|
28
|
+
PASS: 'PASSA',
|
|
29
|
+
FAIL: 'REPROVA',
|
|
30
|
+
ERROR: 'ERRO',
|
|
31
|
+
WARNING: 'AVISO',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// true quando a língua do ambiente é o português (pt, pt_BR e afins); o inglês e língua sem tradução dão false.
|
|
35
|
+
function wantsPortuguese(vars) {
|
|
36
|
+
const isC = (v) => { const t = v.trim().split('.')[0].split('@')[0].toLowerCase(); return !t || t === 'c' || t === 'posix'; };
|
|
37
|
+
const effective = ['LC_ALL', 'LC_MESSAGES', 'LANG'].map((n) => vars[n]).find((v) => v);
|
|
38
|
+
const localeIsC = !effective || isC(effective);
|
|
39
|
+
for (const name of ['KG_SSOT_LANG', 'LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG']) {
|
|
40
|
+
const value = vars[name];
|
|
41
|
+
if (!value || (name === 'LANGUAGE' && localeIsC)) continue;
|
|
42
|
+
for (const raw of name === 'LANGUAGE' ? value.split(':') : [value]) {
|
|
43
|
+
const tag = raw.trim().split('.')[0].split('@')[0].replace(/-/g, '_').toLowerCase();
|
|
44
|
+
if (!tag || tag === 'c' || tag === 'posix') return false;
|
|
45
|
+
const lang = tag.split('_')[0];
|
|
46
|
+
if (lang === 'pt') return true;
|
|
47
|
+
if (lang === 'en') return false;
|
|
48
|
+
}
|
|
49
|
+
return false; // a variável definida decide, mesmo sem tradução: o inglês
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const TABLE = wantsPortuguese(process.env) ? PT_BR : {};
|
|
55
|
+
const _ = (msgid, vals = {}) =>
|
|
56
|
+
(TABLE[msgid] ?? msgid).replace(/\{(\w+)\}/g, (m, k) => (k in vals ? String(vals[k]) : m));
|
|
57
|
+
// o rótulo da linha do arquivo, com a coluna do nome alinhada
|
|
58
|
+
const label = (msgid) => `${_(msgid).padEnd(7)} `;
|
|
59
|
+
|
|
60
|
+
const USAGE = `${_('usage: kg-ssot-validate <file.kg.yaml|file.kg.json>... [--json] [--corpus DIR]')}\n`;
|
|
15
61
|
const args = process.argv.slice(2);
|
|
16
62
|
let json = false;
|
|
17
63
|
let corpusDir = null;
|
|
@@ -25,12 +71,12 @@ for (let i = 0; i < args.length; i += 1) {
|
|
|
25
71
|
else if (a === '--corpus') {
|
|
26
72
|
corpusDir = args[++i];
|
|
27
73
|
if (!corpusDir) {
|
|
28
|
-
process.stdout.write(
|
|
74
|
+
process.stdout.write(`${_('BROKEN INPUT')} ${_('--corpus without a directory')}\n${USAGE}`);
|
|
29
75
|
process.exit(2);
|
|
30
76
|
}
|
|
31
77
|
} else if (a === '--') files.push(...args.slice(i + 1)), (i = args.length);
|
|
32
78
|
else if (a.startsWith('-')) {
|
|
33
|
-
process.stdout.write(
|
|
79
|
+
process.stdout.write(`${_('BROKEN INPUT')} ${_('unknown option: {option}', { option: a })}\n${USAGE}`);
|
|
34
80
|
process.exit(2);
|
|
35
81
|
} else files.push(a);
|
|
36
82
|
}
|
|
@@ -43,7 +89,8 @@ let corpus = null;
|
|
|
43
89
|
try {
|
|
44
90
|
corpus = corpusDir ? corpusIndex(corpusDir) : null;
|
|
45
91
|
} catch (exc) {
|
|
46
|
-
|
|
92
|
+
const msg = exc?.kgMsgid ? _(exc.kgMsgid, exc.kgArgs) : exc?.message;
|
|
93
|
+
process.stdout.write(`${_('BROKEN INPUT')} ${msg}\n`);
|
|
47
94
|
process.exit(2);
|
|
48
95
|
}
|
|
49
96
|
for (const file of files) {
|
|
@@ -57,9 +104,9 @@ for (const file of files) {
|
|
|
57
104
|
if (out.verdict === 'error') rc = 2;
|
|
58
105
|
else if (out.verdict === 'reject' && rc === 0) rc = 1;
|
|
59
106
|
if (json) process.stdout.write(`${JSON.stringify({ file, ...out })}\n`);
|
|
60
|
-
else if (out.verdict === 'accept') process.stdout.write(
|
|
61
|
-
else if (out.verdict === 'reject') process.stdout.write(
|
|
62
|
-
else process.stdout.write(
|
|
63
|
-
if (!json && out.warnings?.length) process.stdout.write(`
|
|
107
|
+
else if (out.verdict === 'accept') process.stdout.write(`${label('PASS')}${file}\n`);
|
|
108
|
+
else if (out.verdict === 'reject') process.stdout.write(`${label('FAIL')}${file}\n MUST ${out.codes.join(' · ')}\n`);
|
|
109
|
+
else process.stdout.write(`${label('ERROR')}${file}\n ${out.detail}\n`);
|
|
110
|
+
if (!json && out.warnings?.length) process.stdout.write(` ${_('WARNING')} ${out.warnings.join(' · ')}\n`);
|
|
64
111
|
}
|
|
65
112
|
process.exit(rc);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kg-ssot",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "4.18.0",
|
|
4
|
+
"description": "JavaScript reader for the KG-SSOT verifiable knowledge graph contract (.kg.yaml and .kg.json): a precompiled validator, no eval, for Node and React Native/Expo.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"knowledge-graph",
|
|
7
7
|
"provenance",
|
package/run.mjs
CHANGED
|
@@ -56,7 +56,13 @@ function corpusFiles(root) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
export function corpusIndex(root) {
|
|
59
|
-
if (!statSync(root, { throwIfNoEntry: false })?.isDirectory())
|
|
59
|
+
if (!statSync(root, { throwIfNoEntry: false })?.isDirectory()) {
|
|
60
|
+
// a mensagem sai em inglês (a língua-fonte); o msgid e os argumentos vão junto, para o cli.mjs traduzir
|
|
61
|
+
const exc = new Error(`corpus ${root} is not a directory`);
|
|
62
|
+
exc.kgMsgid = 'corpus {root} is not a directory';
|
|
63
|
+
exc.kgArgs = { root };
|
|
64
|
+
throw exc;
|
|
65
|
+
}
|
|
60
66
|
const items = [];
|
|
61
67
|
for (const name of corpusFiles(root)) {
|
|
62
68
|
const p = join(root, name);
|
package/spec/release.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.
|
|
3
|
-
"tag": "kg-ssot-v4.
|
|
2
|
+
"version": "4.18.0",
|
|
3
|
+
"tag": "kg-ssot-v4.18.0",
|
|
4
4
|
"contract": {
|
|
5
5
|
"must": "spec/kg-contract-v4.schema.json",
|
|
6
6
|
"should": "spec/kg-contract-v4.should.schema.json"
|
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
"NOTICE",
|
|
10
10
|
"LICENSE",
|
|
11
11
|
"README.md",
|
|
12
|
+
"README.pt-BR.md",
|
|
12
13
|
"llms.txt",
|
|
13
14
|
"llms-full.txt",
|
|
14
15
|
"ADOPTING.md",
|
|
16
|
+
"ADOPTING.pt-BR.md",
|
|
15
17
|
"CHANGELOG.md",
|
|
16
18
|
"CHANGELOG.pt-BR.md",
|
|
17
19
|
"docs/manual/",
|
|
@@ -23,9 +25,12 @@
|
|
|
23
25
|
"spec/query.schema.json",
|
|
24
26
|
"spec/diff.schema.json",
|
|
25
27
|
"spec/conformance/README.md",
|
|
28
|
+
"spec/conformance/README.pt-BR.md",
|
|
26
29
|
"spec/conformance/manifest.schema.json",
|
|
27
30
|
"spec/conformance/fixtures/",
|
|
28
31
|
"spec/conformance/metaschema-tests/",
|
|
32
|
+
"tools/kg_i18n.py",
|
|
33
|
+
"locale/",
|
|
29
34
|
"tools/kg_validate.py",
|
|
30
35
|
"tools/kg_conformance.py",
|
|
31
36
|
"tools/kg_gate.py",
|
|
@@ -62,6 +67,8 @@
|
|
|
62
67
|
"spec/release.json",
|
|
63
68
|
"spec/kg-contract-v4.schema.json",
|
|
64
69
|
"spec/kg-contract-v4.should.schema.json",
|
|
70
|
+
"tools/kg_i18n.py",
|
|
71
|
+
"locale/",
|
|
65
72
|
"tools/kg_validate.py",
|
|
66
73
|
"tools/kg_gate.py",
|
|
67
74
|
"tools/kg_vendor.py",
|
package/spec/verdict.schema.json
CHANGED
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"place": {"type": "string", "description": "o lugar legível: 'nó X', 'aresta #3 (A -> B)', 'meta', 'topo' ou 'arquivo'"},
|
|
58
58
|
"path": {"type": "string", "description": "o caminho no documento, como nodes[7].provenance.method; vazio quando é o arquivo inteiro"},
|
|
59
59
|
"line": {"type": ["integer", "null"], "minimum": 1, "description": "a linha (contando de 1) do ponto mais fundo do caminho que existe: no objeto ou mapa, a linha da chave; na lista, o início do item. Vale para o .kg.yaml e, desde a 4.8.2, para o .kg.json; null quando o documento não varre, quando a ocorrência não tem caminho (a chave desconhecida no topo, por exemplo) e no erro de parse sem marca"},
|
|
60
|
-
"message": {"type": "string", "description": "a frase
|
|
61
|
-
"hint": {"type": "string", "description": "a correção canônica, quando o código tem uma"}
|
|
60
|
+
"message": {"type": "string", "description": "a frase para pessoas, na língua do ambiente (inglês por padrão, pt-BR com KG_SSOT_LANG=pt-BR ou locale pt_BR; desde a 4.18.0); pode mudar entre versões e línguas: compare pelo code"},
|
|
61
|
+
"hint": {"type": "string", "description": "a correção canônica, quando o código tem uma, na língua do ambiente como o message"}
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
},
|