kibi-cli 0.11.1 → 0.12.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/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +1 -1
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +2 -3
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +7 -2
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/sync/manifest.d.ts +1 -1
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +7 -4
- package/dist/commands/sync/staging.d.ts.map +1 -1
- package/dist/commands/sync/staging.js +2 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +3 -1
- package/dist/extractors/manifest.d.ts.map +1 -1
- package/dist/extractors/manifest.js +3 -1
- package/dist/extractors/symbol-coordinates.d.ts.map +1 -1
- package/dist/extractors/symbol-coordinates.js +1 -1
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +2 -1
- package/dist/extractors/symbols-ts.d.ts.map +1 -1
- package/dist/extractors/symbols-ts.js +3 -1
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +14 -1
- package/dist/public/ignore-policy.d.ts.map +1 -1
- package/dist/public/ignore-policy.js +8 -4
- package/dist/public/operational-artifacts.d.ts.map +1 -1
- package/dist/public/operational-artifacts.js +1 -0
- package/dist/public/schemas/entity.d.ts +1 -127
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +79 -2
- package/dist/public/schemas/relationship.d.ts.map +1 -1
- package/dist/public/schemas/relationship.js +1 -0
- package/dist/public/skills/kibi-usage/SKILL.md +80 -0
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +78 -0
- package/dist/public/skills/kibi-usage/resources/workflows.md +0 -7
- package/dist/public/skills.d.ts.map +1 -1
- package/dist/public/skills.js +12 -4
- package/dist/schemas/entity.schema.json +81 -4
- package/dist/search-ranking.d.ts.map +1 -1
- package/dist/traceability/evidence-model.d.ts.map +1 -1
- package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
- package/dist/traceability/staged-diagnostics.js +1 -1
- package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
- package/dist/traceability/staged-symbols-manifest.js +8 -2
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +4 -1
- package/dist/types/entities.d.ts +11 -2
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/types/relationships.d.ts +1 -1
- package/dist/types/relationships.d.ts.map +1 -1
- package/dist/utils/config.d.ts +3 -18
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +4 -40
- package/dist/utils/manifest-paths.d.ts.map +1 -1
- package/dist/utils/manifest-paths.js +3 -1
- package/dist/utils/schema-version.d.ts.map +1 -1
- package/dist/utils/strict-modeling.d.ts +1 -1
- package/dist/utils/strict-modeling.d.ts.map +1 -1
- package/dist/utils/strict-modeling.js +13 -3
- package/package.json +3 -13
- package/schema/config.json +0 -68
- package/src/public/ignore-policy.ts +26 -10
- package/src/public/operational-artifacts.ts +2 -1
- package/src/public/schemas/entity.ts +89 -5
- package/src/public/schemas/relationship.ts +1 -0
- package/src/public/skills/kibi-usage/SKILL.md +80 -0
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +78 -0
- package/src/public/skills/kibi-usage/resources/workflows.md +0 -7
- package/src/public/skills.ts +93 -25
- package/src/schemas/entity.schema.json +81 -4
- package/src/schemas/relationship.schema.json +1 -0
- package/dist/public/brief-config.d.ts +0 -4
- package/dist/public/brief-config.d.ts.map +0 -1
- package/dist/public/brief-config.js +0 -21
- package/src/public/brief-config.ts +0 -25
package/dist/utils/config.js
CHANGED
|
@@ -22,25 +22,9 @@ import { LATEST_KB_SCHEMA_VERSION } from "./schema-version.js";
|
|
|
22
22
|
/**
|
|
23
23
|
* Default configuration values for new repositories.
|
|
24
24
|
*/
|
|
25
|
-
const DEFAULT_BRIEFS_CONFIG = {
|
|
26
|
-
enabled: true,
|
|
27
|
-
retention: {
|
|
28
|
-
maxPerBranch: 200,
|
|
29
|
-
maxAgeDays: 14,
|
|
30
|
-
keepUnread: true,
|
|
31
|
-
},
|
|
32
|
-
channels: {
|
|
33
|
-
vscode: true,
|
|
34
|
-
tui: true,
|
|
35
|
-
},
|
|
36
|
-
tui: {
|
|
37
|
-
toast: true,
|
|
38
|
-
appendPrompt: true,
|
|
39
|
-
idleDelayMs: 1500,
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
25
|
// implements REQ-003
|
|
43
26
|
export const DEFAULT_CONFIG = {
|
|
27
|
+
// implements REQ-003
|
|
44
28
|
$schema: "https://raw.githubusercontent.com/Looted/kibi/master/packages/cli/schema/config.json",
|
|
45
29
|
schemaVersion: LATEST_KB_SCHEMA_VERSION,
|
|
46
30
|
paths: {
|
|
@@ -53,13 +37,13 @@ export const DEFAULT_CONFIG = {
|
|
|
53
37
|
facts: "documentation/facts",
|
|
54
38
|
symbols: "documentation/symbols.yaml",
|
|
55
39
|
},
|
|
56
|
-
briefs: DEFAULT_BRIEFS_CONFIG,
|
|
57
40
|
checks: DEFAULT_CHECKS_CONFIG,
|
|
58
41
|
};
|
|
59
42
|
/**
|
|
60
43
|
* Default paths used by sync command (backward compatible glob patterns).
|
|
61
44
|
*/
|
|
62
45
|
export const DEFAULT_SYNC_PATHS = {
|
|
46
|
+
// implements REQ-003
|
|
63
47
|
requirements: "requirements/**/*.md",
|
|
64
48
|
scenarios: "scenarios/**/*.md",
|
|
65
49
|
tests: "tests/**/*.md",
|
|
@@ -69,24 +53,6 @@ export const DEFAULT_SYNC_PATHS = {
|
|
|
69
53
|
facts: "facts/**/*.md",
|
|
70
54
|
symbols: "symbols.yaml",
|
|
71
55
|
};
|
|
72
|
-
function mergeBriefsConfig(userBriefs) {
|
|
73
|
-
return {
|
|
74
|
-
...DEFAULT_BRIEFS_CONFIG,
|
|
75
|
-
...userBriefs,
|
|
76
|
-
channels: {
|
|
77
|
-
...DEFAULT_BRIEFS_CONFIG.channels,
|
|
78
|
-
...userBriefs?.channels,
|
|
79
|
-
},
|
|
80
|
-
tui: {
|
|
81
|
-
...DEFAULT_BRIEFS_CONFIG.tui,
|
|
82
|
-
...userBriefs?.tui,
|
|
83
|
-
},
|
|
84
|
-
retention: {
|
|
85
|
-
...DEFAULT_BRIEFS_CONFIG.retention,
|
|
86
|
-
...userBriefs?.retention,
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
56
|
function readUserConfig(configPath) {
|
|
91
57
|
if (!existsSync(configPath)) {
|
|
92
58
|
return {
|
|
@@ -124,12 +90,11 @@ export function loadConfig(cwd = process.cwd()) {
|
|
|
124
90
|
...DEFAULT_CONFIG.paths,
|
|
125
91
|
...userConfig.paths,
|
|
126
92
|
},
|
|
127
|
-
...(
|
|
93
|
+
...(userConfig.schemaVersion !== undefined || useDefaultSchemaVersion
|
|
128
94
|
? {
|
|
129
95
|
schemaVersion: userConfig.schemaVersion ?? DEFAULT_CONFIG.schemaVersion,
|
|
130
96
|
}
|
|
131
97
|
: {}),
|
|
132
|
-
briefs: mergeBriefsConfig(userConfig.briefs),
|
|
133
98
|
...(userConfig.defaultBranch !== undefined
|
|
134
99
|
? { defaultBranch: userConfig.defaultBranch }
|
|
135
100
|
: {}),
|
|
@@ -164,12 +129,11 @@ export function loadSyncConfig(cwd = process.cwd()) {
|
|
|
164
129
|
...DEFAULT_SYNC_PATHS,
|
|
165
130
|
...userConfig.paths,
|
|
166
131
|
},
|
|
167
|
-
...(
|
|
132
|
+
...(userConfig.schemaVersion !== undefined || useDefaultSchemaVersion
|
|
168
133
|
? {
|
|
169
134
|
schemaVersion: userConfig.schemaVersion ?? DEFAULT_CONFIG.schemaVersion,
|
|
170
135
|
}
|
|
171
136
|
: {}),
|
|
172
|
-
briefs: mergeBriefsConfig(userConfig.briefs),
|
|
173
137
|
...(userConfig.defaultBranch !== undefined
|
|
174
138
|
? { defaultBranch: userConfig.defaultBranch }
|
|
175
139
|
: {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest-paths.d.ts","sourceRoot":"","sources":["../../src/utils/manifest-paths.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,oBAAoB,+BAA+B,CAAC;AACjE,eAAO,MAAM,wBAAwB,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest-paths.d.ts","sourceRoot":"","sources":["../../src/utils/manifest-paths.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,oBAAoB,+BAA+B,CAAC;AACjE,eAAO,MAAM,wBAAwB,0CAA0C,CAAC;AAkFhF,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CASlD;AAGD,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAER"}
|
|
@@ -42,7 +42,9 @@ function resolveDefaultSymbolsPath(workspaceRoot) {
|
|
|
42
42
|
path.join(workspaceRoot, "symbols.yaml"),
|
|
43
43
|
path.join(workspaceRoot, "symbols.yml"),
|
|
44
44
|
];
|
|
45
|
-
return candidates.find((candidate) => existsSync(candidate)) ??
|
|
45
|
+
return (candidates.find((candidate) => existsSync(candidate)) ??
|
|
46
|
+
candidates[0] ??
|
|
47
|
+
path.join(workspaceRoot, DEFAULT_SYMBOLS_PATH));
|
|
46
48
|
}
|
|
47
49
|
function deriveCoordinatesPath(symbolsPath) {
|
|
48
50
|
return path.join(path.dirname(symbolsPath), path.basename(DEFAULT_COORDINATES_PATH));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-version.d.ts","sourceRoot":"","sources":["../../src/utils/schema-version.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IAC9D,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,KAAK,mBAAmB,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAG9E,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAChD,MAAM,GAAG,IAAI,CAgBf;AAGD,wBAAgB,sBAAsB,CACpC,MAAM,CAAC,EAAE,mBAAmB,GAC3B,mBAAmB,
|
|
1
|
+
{"version":3,"file":"schema-version.d.ts","sourceRoot":"","sources":["../../src/utils/schema-version.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IAC9D,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,KAAK,mBAAmB,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAG9E,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAChD,MAAM,GAAG,IAAI,CAgBf;AAGD,wBAAgB,sBAAsB,CACpC,MAAM,CAAC,EAAE,mBAAmB,GAC3B,mBAAmB,CA6CrB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type KbConfigPaths } from "./config.js";
|
|
2
1
|
import type { BaseEntity, FactFields } from "../types/entities.js";
|
|
3
2
|
import type { BaseRelationship } from "../types/relationships.js";
|
|
3
|
+
import { type KbConfigPaths } from "./config.js";
|
|
4
4
|
export interface SemanticClaim {
|
|
5
5
|
source: string;
|
|
6
6
|
subjectKey: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strict-modeling.d.ts","sourceRoot":"","sources":["../../src/utils/strict-modeling.ts"],"names":[],"mappings":"AAoBA,OAAO,
|
|
1
|
+
{"version":3,"file":"strict-modeling.d.ts","sourceRoot":"","sources":["../../src/utils/strict-modeling.ts"],"names":[],"mappings":"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"}
|
|
@@ -90,7 +90,11 @@ export function buildStrictWriteSet(input) {
|
|
|
90
90
|
status: "active",
|
|
91
91
|
source: buildEntitySourcePath(sourcePaths.facts, ids.observationFactId),
|
|
92
92
|
text_ref: textRef,
|
|
93
|
-
tags: buildUniqueTags([
|
|
93
|
+
tags: buildUniqueTags([
|
|
94
|
+
...metadataTags,
|
|
95
|
+
"lane:observation",
|
|
96
|
+
"review:required",
|
|
97
|
+
]),
|
|
94
98
|
fact_kind: "observation",
|
|
95
99
|
subject_key: ids.normalizedSubjectKey,
|
|
96
100
|
property_key: ids.normalizedPropertyKey,
|
|
@@ -138,7 +142,11 @@ export function buildStrictWriteSet(input) {
|
|
|
138
142
|
status: "active",
|
|
139
143
|
source: buildEntitySourcePath(sourcePaths.facts, ids.propertyFactId),
|
|
140
144
|
text_ref: textRef,
|
|
141
|
-
tags: buildUniqueTags([
|
|
145
|
+
tags: buildUniqueTags([
|
|
146
|
+
...metadataTags,
|
|
147
|
+
"lane:strict",
|
|
148
|
+
"fact:property_value",
|
|
149
|
+
]),
|
|
142
150
|
fact_kind: "property_value",
|
|
143
151
|
subject_key: ids.normalizedSubjectKey,
|
|
144
152
|
property_key: ids.normalizedPropertyKey,
|
|
@@ -176,7 +184,9 @@ export function modelRequirementClaims(inputs) {
|
|
|
176
184
|
const modeled = [];
|
|
177
185
|
for (const input of inputs) {
|
|
178
186
|
const writeSet = buildStrictWriteSet(input);
|
|
179
|
-
const stableId = writeSet.isStrict
|
|
187
|
+
const stableId = writeSet.isStrict
|
|
188
|
+
? writeSet.req.id
|
|
189
|
+
: writeSet.observationFact.id;
|
|
180
190
|
if (seen.has(stableId)) {
|
|
181
191
|
continue;
|
|
182
192
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Kibi CLI for knowledge base management",
|
|
6
6
|
"engines": {
|
|
@@ -11,13 +11,7 @@
|
|
|
11
11
|
"bin": {
|
|
12
12
|
"kibi": "bin/kibi"
|
|
13
13
|
},
|
|
14
|
-
"files": [
|
|
15
|
-
"dist",
|
|
16
|
-
"bin",
|
|
17
|
-
"schema",
|
|
18
|
-
"src/schemas",
|
|
19
|
-
"src/public"
|
|
20
|
-
],
|
|
14
|
+
"files": ["dist", "bin", "schema", "src/schemas", "src/public"],
|
|
21
15
|
"scripts": {
|
|
22
16
|
"build": "tsc -p tsconfig.json && mkdir -p dist/public/skills && cp -r src/public/skills/. dist/public/skills/",
|
|
23
17
|
"prepack": "npm run build"
|
|
@@ -75,10 +69,6 @@
|
|
|
75
69
|
"types": "./dist/public/check-types.d.ts",
|
|
76
70
|
"default": "./dist/public/check-types.js"
|
|
77
71
|
},
|
|
78
|
-
"./brief-config": {
|
|
79
|
-
"types": "./dist/public/brief-config.d.ts",
|
|
80
|
-
"default": "./dist/public/brief-config.js"
|
|
81
|
-
},
|
|
82
72
|
"./schema-version": {
|
|
83
73
|
"types": "./dist/public/schema-version.d.ts",
|
|
84
74
|
"default": "./dist/public/schema-version.js"
|
|
@@ -105,7 +95,7 @@
|
|
|
105
95
|
"fast-glob": "^3.2.12",
|
|
106
96
|
"gray-matter": "^4.0.3",
|
|
107
97
|
"js-yaml": "^4.1.0",
|
|
108
|
-
"kibi-core": "^0.
|
|
98
|
+
"kibi-core": "^0.6.0",
|
|
109
99
|
"ts-morph": "^23.0.0",
|
|
110
100
|
"ignore": "^5.3.0"
|
|
111
101
|
},
|
package/schema/config.json
CHANGED
|
@@ -61,74 +61,6 @@
|
|
|
61
61
|
"description": "[DEPRECATED] No longer used. Branch lifecycle now follows git naturally without requiring a configured default. This field is ignored but kept for backward compatibility.",
|
|
62
62
|
"deprecated": true
|
|
63
63
|
},
|
|
64
|
-
"briefs": {
|
|
65
|
-
"type": "object",
|
|
66
|
-
"description": "Configuration for shared brief delivery defaults",
|
|
67
|
-
"properties": {
|
|
68
|
-
"enabled": {
|
|
69
|
-
"type": "boolean",
|
|
70
|
-
"default": true
|
|
71
|
-
},
|
|
72
|
-
"retention": {
|
|
73
|
-
"type": "object",
|
|
74
|
-
"properties": {
|
|
75
|
-
"maxPerBranch": {
|
|
76
|
-
"type": "integer",
|
|
77
|
-
"minimum": 1,
|
|
78
|
-
"maximum": 10000,
|
|
79
|
-
"default": 200
|
|
80
|
-
},
|
|
81
|
-
"maxAgeDays": {
|
|
82
|
-
"type": "integer",
|
|
83
|
-
"minimum": 1,
|
|
84
|
-
"maximum": 3650,
|
|
85
|
-
"default": 14
|
|
86
|
-
},
|
|
87
|
-
"keepUnread": {
|
|
88
|
-
"type": "boolean",
|
|
89
|
-
"default": true
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
"additionalProperties": false
|
|
93
|
-
},
|
|
94
|
-
"channels": {
|
|
95
|
-
"type": "object",
|
|
96
|
-
"properties": {
|
|
97
|
-
"vscode": {
|
|
98
|
-
"type": "boolean",
|
|
99
|
-
"default": true
|
|
100
|
-
},
|
|
101
|
-
"tui": {
|
|
102
|
-
"type": "boolean",
|
|
103
|
-
"default": true
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
"additionalProperties": false
|
|
107
|
-
},
|
|
108
|
-
"tui": {
|
|
109
|
-
"type": "object",
|
|
110
|
-
"properties": {
|
|
111
|
-
"toast": {
|
|
112
|
-
"type": "boolean",
|
|
113
|
-
"default": true
|
|
114
|
-
},
|
|
115
|
-
"appendPrompt": {
|
|
116
|
-
"type": "boolean",
|
|
117
|
-
"default": true
|
|
118
|
-
},
|
|
119
|
-
"idleDelayMs": {
|
|
120
|
-
"type": "integer",
|
|
121
|
-
"minimum": 0,
|
|
122
|
-
"maximum": 60000,
|
|
123
|
-
"default": 1500,
|
|
124
|
-
"description": "Delay in milliseconds after session.idle before idle-brief generation is attempted"
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
"additionalProperties": false
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
"additionalProperties": false
|
|
131
|
-
},
|
|
132
64
|
"checks": {
|
|
133
65
|
"type": "object",
|
|
134
66
|
"description": "Configuration for KB validation rules",
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type Dirent,
|
|
3
|
+
existsSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
readdirSync,
|
|
6
|
+
statSync,
|
|
7
|
+
} from "node:fs";
|
|
2
8
|
import * as path from "node:path";
|
|
3
9
|
import ignore from "ignore";
|
|
4
10
|
|
|
@@ -51,7 +57,7 @@ export function createRepoIgnorePolicy(workspaceRoot: string): IgnorePolicy {
|
|
|
51
57
|
const nestedPatterns = new Map<string, string[]>();
|
|
52
58
|
|
|
53
59
|
function walk(dirAbs: string) {
|
|
54
|
-
let entries;
|
|
60
|
+
let entries: Dirent[];
|
|
55
61
|
try {
|
|
56
62
|
entries = readdirSync(dirAbs, { withFileTypes: true });
|
|
57
63
|
} catch {
|
|
@@ -95,7 +101,9 @@ export function createRepoIgnorePolicy(workspaceRoot: string): IgnorePolicy {
|
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
// Prepare nested directories sorted by specificity (longest first)
|
|
98
|
-
const nestedDirsSorted = Array.from(nestedIgnoreMap.keys()).sort(
|
|
104
|
+
const nestedDirsSorted = Array.from(nestedIgnoreMap.keys()).sort(
|
|
105
|
+
(a, b) => b.length - a.length,
|
|
106
|
+
);
|
|
99
107
|
|
|
100
108
|
function isPathOutsideWorkspace(absPath: string): boolean {
|
|
101
109
|
const rel = path.relative(root, absPath);
|
|
@@ -111,9 +119,14 @@ export function createRepoIgnorePolicy(workspaceRoot: string): IgnorePolicy {
|
|
|
111
119
|
return false;
|
|
112
120
|
}
|
|
113
121
|
|
|
114
|
-
function isIgnoredInternal(inputPath: string): {
|
|
122
|
+
function isIgnoredInternal(inputPath: string): {
|
|
123
|
+
ignored: boolean;
|
|
124
|
+
reason?: string;
|
|
125
|
+
} {
|
|
115
126
|
// Resolve to absolute and relative path inside workspace
|
|
116
|
-
const abs = path.isAbsolute(inputPath)
|
|
127
|
+
const abs = path.isAbsolute(inputPath)
|
|
128
|
+
? path.resolve(inputPath)
|
|
129
|
+
: path.resolve(root, inputPath);
|
|
117
130
|
|
|
118
131
|
if (path.isAbsolute(inputPath) && isPathOutsideWorkspace(abs)) {
|
|
119
132
|
return { ignored: true, reason: "outside_workspace" };
|
|
@@ -123,7 +136,8 @@ export function createRepoIgnorePolicy(workspaceRoot: string): IgnorePolicy {
|
|
|
123
136
|
const relPosix = toPosix(rel);
|
|
124
137
|
|
|
125
138
|
// Hard denylist always wins
|
|
126
|
-
if (matchesHardDeny(relPosix))
|
|
139
|
+
if (matchesHardDeny(relPosix))
|
|
140
|
+
return { ignored: true, reason: "hard_deny" };
|
|
127
141
|
|
|
128
142
|
// Root .gitignore
|
|
129
143
|
try {
|
|
@@ -147,11 +161,13 @@ export function createRepoIgnorePolicy(workspaceRoot: string): IgnorePolicy {
|
|
|
147
161
|
for (const dirRel of nestedDirsSorted) {
|
|
148
162
|
// dirRel is '.' for nested at root which we skipped, so dirRel will be like 'docs'
|
|
149
163
|
if (dirRel === ".") continue;
|
|
150
|
-
if (relPosix === dirRel || relPosix.startsWith(dirRel
|
|
151
|
-
const sub =
|
|
152
|
-
|
|
164
|
+
if (relPosix === dirRel || relPosix.startsWith(`${dirRel}/`)) {
|
|
165
|
+
const sub =
|
|
166
|
+
relPosix === dirRel ? "." : relPosix.slice(dirRel.length + 1);
|
|
167
|
+
const ig = nestedIgnoreMap.get(dirRel);
|
|
168
|
+
if (!ig) continue;
|
|
153
169
|
try {
|
|
154
|
-
if (ig
|
|
170
|
+
if (ig.ignores(sub)) return { ignored: true, reason: "gitignored" };
|
|
155
171
|
} catch (e) {
|
|
156
172
|
// noop
|
|
157
173
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export function isOperationalArtifactPath(pathLike: string): boolean {
|
|
1
|
+
export function isOperationalArtifactPath(pathLike: string): boolean {
|
|
2
|
+
// implements REQ-001
|
|
2
3
|
const normalized = pathLike.replaceAll("\\", "/");
|
|
3
4
|
|
|
4
5
|
return /(^|\/)\.sisyphus\//.test(normalized);
|
|
@@ -17,12 +17,67 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
// Typed fact field enums per proposal
|
|
20
|
-
type FactKind =
|
|
20
|
+
type FactKind =
|
|
21
|
+
| "subject"
|
|
22
|
+
| "property_value"
|
|
23
|
+
| "observation"
|
|
24
|
+
| "meta"
|
|
25
|
+
| "predicate_schema"
|
|
26
|
+
| "predicate";
|
|
21
27
|
type Operator = "eq" | "neq" | "lt" | "lte" | "gt" | "gte";
|
|
22
28
|
type ValueType = "string" | "int" | "number" | "bool";
|
|
23
|
-
type Polarity = "require" | "forbid";
|
|
29
|
+
type Polarity = "require" | "forbid" | "assert" | "deny";
|
|
24
30
|
|
|
25
|
-
const
|
|
31
|
+
const factConditionals = JSON.parse(`[
|
|
32
|
+
{
|
|
33
|
+
"if": {
|
|
34
|
+
"properties": {
|
|
35
|
+
"type": { "const": "fact" },
|
|
36
|
+
"fact_kind": { "const": "predicate_schema" }
|
|
37
|
+
},
|
|
38
|
+
"required": ["type", "fact_kind"]
|
|
39
|
+
},
|
|
40
|
+
"then": {
|
|
41
|
+
"required": [
|
|
42
|
+
"predicate_name",
|
|
43
|
+
"predicate_arity",
|
|
44
|
+
"argument_names",
|
|
45
|
+
"argument_types"
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"if": {
|
|
51
|
+
"properties": {
|
|
52
|
+
"type": { "const": "fact" },
|
|
53
|
+
"fact_kind": { "const": "predicate" }
|
|
54
|
+
},
|
|
55
|
+
"required": ["type", "fact_kind"]
|
|
56
|
+
},
|
|
57
|
+
"then": {
|
|
58
|
+
"required": ["predicate_name", "predicate_args", "canonical_key"],
|
|
59
|
+
"properties": {
|
|
60
|
+
"polarity": { "enum": ["assert", "deny"] }
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"if": {
|
|
66
|
+
"properties": {
|
|
67
|
+
"type": { "const": "fact" },
|
|
68
|
+
"fact_kind": { "const": "property_value" }
|
|
69
|
+
},
|
|
70
|
+
"required": ["type", "fact_kind"]
|
|
71
|
+
},
|
|
72
|
+
"then": {
|
|
73
|
+
"properties": {
|
|
74
|
+
"polarity": { "enum": ["require", "forbid"] }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
]`) as Array<Record<string, unknown>>;
|
|
79
|
+
|
|
80
|
+
const entitySchema: Record<string, unknown> = {
|
|
26
81
|
$id: "entity.schema.json",
|
|
27
82
|
title: "Entity",
|
|
28
83
|
type: "object",
|
|
@@ -79,7 +134,14 @@ const entitySchema = {
|
|
|
79
134
|
// Typed fact fields - only valid when type === "fact"
|
|
80
135
|
fact_kind: {
|
|
81
136
|
type: "string",
|
|
82
|
-
enum: [
|
|
137
|
+
enum: [
|
|
138
|
+
"subject",
|
|
139
|
+
"property_value",
|
|
140
|
+
"observation",
|
|
141
|
+
"meta",
|
|
142
|
+
"predicate_schema",
|
|
143
|
+
"predicate",
|
|
144
|
+
] satisfies FactKind[],
|
|
83
145
|
},
|
|
84
146
|
subject_key: { type: "string" },
|
|
85
147
|
property_key: { type: "string" },
|
|
@@ -91,11 +153,23 @@ const entitySchema = {
|
|
|
91
153
|
value_bool: { type: "boolean" },
|
|
92
154
|
unit: { type: "string" },
|
|
93
155
|
scope: { type: "string" },
|
|
94
|
-
polarity: {
|
|
156
|
+
polarity: {
|
|
157
|
+
type: "string",
|
|
158
|
+
enum: ["require", "forbid", "assert", "deny"] satisfies Polarity[],
|
|
159
|
+
},
|
|
95
160
|
closed_world: { type: "boolean" },
|
|
96
161
|
valid_from: { type: "string" },
|
|
97
162
|
valid_to: { type: "string" },
|
|
98
163
|
canonical_key: { type: "string" },
|
|
164
|
+
predicate_name: { type: "string" },
|
|
165
|
+
predicate_namespace: { type: "string" },
|
|
166
|
+
predicate_arity: { type: "integer", minimum: 1 },
|
|
167
|
+
argument_names: { type: "array", items: { type: "string" } },
|
|
168
|
+
argument_types: { type: "array", items: { type: "string" } },
|
|
169
|
+
argument_descriptions: { type: "array", items: { type: "string" } },
|
|
170
|
+
aliases: { type: "array", items: { type: "string" } },
|
|
171
|
+
examples: { type: "array", items: { type: "string" } },
|
|
172
|
+
predicate_args: { type: "array", items: { type: "string" } },
|
|
99
173
|
},
|
|
100
174
|
required: [
|
|
101
175
|
"id",
|
|
@@ -133,10 +207,20 @@ const entitySchema = {
|
|
|
133
207
|
{ required: ["valid_from"] },
|
|
134
208
|
{ required: ["valid_to"] },
|
|
135
209
|
{ required: ["canonical_key"] },
|
|
210
|
+
{ required: ["predicate_name"] },
|
|
211
|
+
{ required: ["predicate_namespace"] },
|
|
212
|
+
{ required: ["predicate_arity"] },
|
|
213
|
+
{ required: ["argument_names"] },
|
|
214
|
+
{ required: ["argument_types"] },
|
|
215
|
+
{ required: ["argument_descriptions"] },
|
|
216
|
+
{ required: ["aliases"] },
|
|
217
|
+
{ required: ["examples"] },
|
|
218
|
+
{ required: ["predicate_args"] },
|
|
136
219
|
],
|
|
137
220
|
},
|
|
138
221
|
},
|
|
139
222
|
},
|
|
223
|
+
...factConditionals,
|
|
140
224
|
],
|
|
141
225
|
additionalProperties: false,
|
|
142
226
|
};
|
|
@@ -48,6 +48,24 @@ Relationship direction is fixed and semantic. Getting it wrong breaks traceabili
|
|
|
48
48
|
|
|
49
49
|
See `resources/relationship-directions.md` for detailed payload examples.
|
|
50
50
|
|
|
51
|
+
## Symbol-First Traceability
|
|
52
|
+
|
|
53
|
+
Trace code through `symbol` entities, not inline legacy comments. Do not use legacy `// implements REQ-xxx` comments as the primary marker for new or modified code. If a symbol is new or its requirement ownership changes, create or update the `symbol` entity and add an `implements` relationship from the symbol to the requirement.
|
|
54
|
+
|
|
55
|
+
Use comments only as a temporary backward-compatibility fallback when the symbol manifest cannot be updated in the same task. Prefer durable symbol coordinates in `documentation/symbols.yaml` and `documentation/symbol-coordinates.yaml`, then link those symbols through MCP relationships.
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
# Preferred traceability model
|
|
59
|
+
symbol:
|
|
60
|
+
id: SYM-admin-billing-policy
|
|
61
|
+
title: Admin billing policy check
|
|
62
|
+
status: active
|
|
63
|
+
relationships:
|
|
64
|
+
- type: implements
|
|
65
|
+
from: SYM-admin-billing-policy
|
|
66
|
+
to: REQ-ADMIN-BILLING-POLICY
|
|
67
|
+
```
|
|
68
|
+
|
|
51
69
|
## Strict Fact Lane
|
|
52
70
|
|
|
53
71
|
Normative requirements that must participate in contradiction blocking use the strict fact lane. Create a `fact_kind: subject` fact and link it from the requirement via `constrains`. Create a `fact_kind: property_value` fact and link it via `requires_property`.
|
|
@@ -75,6 +93,67 @@ relationships:
|
|
|
75
93
|
|
|
76
94
|
See `resources/fact-lanes.md` for the full strict vs observation lane comparison.
|
|
77
95
|
|
|
96
|
+
### Granular fact examples for coherence checks
|
|
97
|
+
|
|
98
|
+
Model one semantic claim per strict `property_value` fact. Reusing the same `subject_key` and `property_key` lets `domain-contradictions` compare requirements mechanically.
|
|
99
|
+
|
|
100
|
+
Incoherent role-set example: `REQ-ROLE-SET-2` says the allowed user roles are exactly `[user, admin]`, while `REQ-ROLE-SET-3` says the same property is exactly `[user, admin, superadmin]`. Both constrain `FACT-USER-ROLES` and require different values for `user.roles.allowed_set`, so they cannot both be current.
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
subject:
|
|
104
|
+
id: FACT-USER-ROLES
|
|
105
|
+
fact_kind: subject
|
|
106
|
+
subject_key: user.roles
|
|
107
|
+
|
|
108
|
+
property_values:
|
|
109
|
+
- id: FACT-USER-ROLES-ALLOWED-2
|
|
110
|
+
fact_kind: property_value
|
|
111
|
+
subject_key: user.roles
|
|
112
|
+
property_key: user.roles.allowed_set
|
|
113
|
+
operator: eq
|
|
114
|
+
value_type: list
|
|
115
|
+
value_json: '["user", "admin"]'
|
|
116
|
+
- id: FACT-USER-ROLES-ALLOWED-3
|
|
117
|
+
fact_kind: property_value
|
|
118
|
+
subject_key: user.roles
|
|
119
|
+
property_key: user.roles.allowed_set
|
|
120
|
+
operator: eq
|
|
121
|
+
value_type: list
|
|
122
|
+
value_json: '["user", "admin", "superadmin"]'
|
|
123
|
+
|
|
124
|
+
requirements:
|
|
125
|
+
- id: REQ-ROLE-SET-2
|
|
126
|
+
relationships:
|
|
127
|
+
- { type: constrains, from: REQ-ROLE-SET-2, to: FACT-USER-ROLES }
|
|
128
|
+
- { type: requires_property, from: REQ-ROLE-SET-2, to: FACT-USER-ROLES-ALLOWED-2 }
|
|
129
|
+
- id: REQ-ROLE-SET-3
|
|
130
|
+
relationships:
|
|
131
|
+
- { type: constrains, from: REQ-ROLE-SET-3, to: FACT-USER-ROLES }
|
|
132
|
+
- { type: requires_property, from: REQ-ROLE-SET-3, to: FACT-USER-ROLES-ALLOWED-3 }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Incoherent permission example: `REQ-ADMIN-CAN-MANAGE-BILLING` says `admin` can manage billing, while `REQ-ONLY-SUPERADMIN-MANAGES-BILLING` says the only allowed actor is `superadmin`. Model both against `billing.manage.allowed_actor` with `operator: eq` so the conflict is explicit.
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
property_values:
|
|
139
|
+
- id: FACT-BILLING-MANAGE-ACTOR-ADMIN
|
|
140
|
+
fact_kind: property_value
|
|
141
|
+
subject_key: billing.manage
|
|
142
|
+
property_key: billing.manage.allowed_actor
|
|
143
|
+
operator: eq
|
|
144
|
+
value_type: string
|
|
145
|
+
value_string: admin
|
|
146
|
+
- id: FACT-BILLING-MANAGE-ACTOR-SUPERADMIN
|
|
147
|
+
fact_kind: property_value
|
|
148
|
+
subject_key: billing.manage
|
|
149
|
+
property_key: billing.manage.allowed_actor
|
|
150
|
+
operator: eq
|
|
151
|
+
value_type: string
|
|
152
|
+
value_string: superadmin
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
If a new requirement intentionally changes a value, create a replacement requirement and link the old requirement to the new one with `supersedes` instead of leaving two current contradictory requirements.
|
|
156
|
+
|
|
78
157
|
## Fact vs Flag
|
|
79
158
|
|
|
80
159
|
Use `flag` for runtime or config gates only. Feature flags, kill-switches, and deferred capabilities are valid `flag` entities.
|
|
@@ -110,6 +189,7 @@ Call `kb_status` when you suspect the branch KB is stale or when switching conte
|
|
|
110
189
|
| Anti-Pattern | Problem | Remediation |
|
|
111
190
|
|-------------|---------|-------------|
|
|
112
191
|
| Reversed relationship direction | Traceability queries break | Verify direction against the relationship table above |
|
|
192
|
+
| Legacy implements comments | Comments are not durable queryable symbols | Create or update a `symbol` entity and link it to the requirement |
|
|
113
193
|
| Bug-as-flag | `flag` misused for defect tracking | Use `fact` with `fact_kind: observation` or `meta` |
|
|
114
194
|
| Parallel upserts | Lock contention and nondeterminism | Execute `kb_upsert` calls sequentially |
|
|
115
195
|
| Embedded scenarios in reqs | Violates canonical traceability chain | Create separate `req`, `scen`, and `test` entities |
|