@productbrain/cli 0.1.0-beta.8141 → 0.1.0-beta.8142
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/__tests__/handshake-augment.test.js +2 -16
- package/dist/__tests__/handshake-augment.test.js.map +1 -1
- package/dist/__tests__/handshake-preview.test.js +2 -9
- package/dist/__tests__/handshake-preview.test.js.map +1 -1
- package/dist/__tests__/handshake-session-threading.test.js +2 -9
- package/dist/__tests__/handshake-session-threading.test.js.map +1 -1
- package/dist/commands/admin/seedRegistryEntries.generated.js +1 -1
- package/dist/commands/admin/seedRegistryEntries.generated.js.map +1 -1
- package/dist/commands/handshake.d.ts +0 -2
- package/dist/commands/handshake.d.ts.map +1 -1
- package/dist/commands/handshake.js +21 -38
- package/dist/commands/handshake.js.map +1 -1
- package/dist/formatters/handshake.d.ts +0 -5
- package/dist/formatters/handshake.d.ts.map +1 -1
- package/dist/formatters/handshake.js +0 -9
- package/dist/formatters/handshake.js.map +1 -1
- package/dist/generators/adapters.d.ts +1 -1
- package/dist/generators/adapters.d.ts.map +1 -1
- package/dist/generators/adapters.js +9 -2
- package/dist/generators/adapters.js.map +1 -1
- package/dist/generators/everyone-rules-md.d.ts +10 -0
- package/dist/generators/everyone-rules-md.d.ts.map +1 -0
- package/dist/generators/everyone-rules-md.js +27 -0
- package/dist/generators/everyone-rules-md.js.map +1 -0
- package/dist/generators/retired-projections.d.ts +14 -0
- package/dist/generators/retired-projections.d.ts.map +1 -0
- package/dist/generators/retired-projections.js +79 -0
- package/dist/generators/retired-projections.js.map +1 -0
- package/dist/generators/retired-projections.test.d.ts +2 -0
- package/dist/generators/retired-projections.test.d.ts.map +1 -0
- package/dist/generators/retired-projections.test.js +62 -0
- package/dist/generators/retired-projections.test.js.map +1 -0
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/generators/archetypes.d.ts +0 -52
- package/dist/generators/archetypes.d.ts.map +0 -1
- package/dist/generators/archetypes.js +0 -190
- package/dist/generators/archetypes.js.map +0 -1
- package/dist/generators/archetypes.test.d.ts +0 -2
- package/dist/generators/archetypes.test.d.ts.map +0 -1
- package/dist/generators/archetypes.test.js +0 -272
- package/dist/generators/archetypes.test.js.map +0 -1
- package/dist/generators/chain-classifier-kernel-client-drift.test.d.ts +0 -2
- package/dist/generators/chain-classifier-kernel-client-drift.test.d.ts.map +0 -1
- package/dist/generators/chain-classifier-kernel-client-drift.test.js +0 -41
- package/dist/generators/chain-classifier-kernel-client-drift.test.js.map +0 -1
- package/dist/generators/chain-classifier.d.ts +0 -102
- package/dist/generators/chain-classifier.d.ts.map +0 -1
- package/dist/generators/chain-classifier.js +0 -52
- package/dist/generators/chain-classifier.js.map +0 -1
- package/dist/generators/chain-rules.d.ts +0 -42
- package/dist/generators/chain-rules.d.ts.map +0 -1
- package/dist/generators/chain-rules.js +0 -256
- package/dist/generators/chain-rules.js.map +0 -1
- package/dist/generators/chain-rules.test.d.ts +0 -2
- package/dist/generators/chain-rules.test.d.ts.map +0 -1
- package/dist/generators/chain-rules.test.js +0 -448
- package/dist/generators/chain-rules.test.js.map +0 -1
- package/dist/generators/handshake-diff.d.ts +0 -67
- package/dist/generators/handshake-diff.d.ts.map +0 -1
- package/dist/generators/handshake-diff.js +0 -183
- package/dist/generators/handshake-diff.js.map +0 -1
- package/dist/generators/handshake-diff.test.d.ts +0 -2
- package/dist/generators/handshake-diff.test.d.ts.map +0 -1
- package/dist/generators/handshake-diff.test.js +0 -264
- package/dist/generators/handshake-diff.test.js.map +0 -1
- package/templates/archetypes/boundary.md +0 -23
- package/templates/archetypes/constraint.md +0 -23
- package/templates/archetypes/convention.md +0 -23
- package/templates/archetypes/policy.md +0 -23
- package/templates/archetypes/quality-gate.md +0 -23
- package/templates/archetypes/workflow.md +0 -23
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Handshake Diff — BET-286 Slice 4
|
|
3
|
-
*
|
|
4
|
-
* Persists handshake --generate state between runs and produces a diff
|
|
5
|
-
* showing what changed (added, removed, changed rules) since the last run.
|
|
6
|
-
*
|
|
7
|
-
* Chain: BET-286 (Chain-Derived Agent Configuration)
|
|
8
|
-
*/
|
|
9
|
-
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
10
|
-
import { join } from 'path';
|
|
11
|
-
// ── State file path ────────────────────────────────────────────────────
|
|
12
|
-
const STATE_FILENAME = '.handshake-state.json';
|
|
13
|
-
function stateFilePath(pbDir) {
|
|
14
|
-
return join(pbDir, STATE_FILENAME);
|
|
15
|
-
}
|
|
16
|
-
// ── State builder ─────────────────────────────────────────────────────
|
|
17
|
-
/**
|
|
18
|
-
* Build a HandshakeStateRule from a CanonicalRule and classified governance entries.
|
|
19
|
-
* Only applies to chain:// sourced rules.
|
|
20
|
-
*/
|
|
21
|
-
function buildStateRule(rule, classified) {
|
|
22
|
-
// Extract function key from sourcePath ('chain://<functionKey>')
|
|
23
|
-
const functionKey = rule.sourcePath.replace('chain://', '');
|
|
24
|
-
// Find all entries that classified to this governance function
|
|
25
|
-
const matching = classified.filter((e) => e.governanceFunction === functionKey);
|
|
26
|
-
const entryIds = matching.map((e) => e.entryId);
|
|
27
|
-
// Average confidence across contributing entries (0 if none matched)
|
|
28
|
-
const confidence = matching.length > 0
|
|
29
|
-
? Math.round((matching.reduce((sum, e) => sum + e.confidence, 0) / matching.length) * 100) / 100
|
|
30
|
-
: 0;
|
|
31
|
-
return {
|
|
32
|
-
name: rule.name,
|
|
33
|
-
functionKey,
|
|
34
|
-
sourcePath: rule.sourcePath,
|
|
35
|
-
confidence,
|
|
36
|
-
entryIds,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
// ── Public API ─────────────────────────────────────────────────────────
|
|
40
|
-
/**
|
|
41
|
-
* Build a HandshakeState in memory from rules and classified entries.
|
|
42
|
-
* Only includes chain:// sourced rules (ignores manual rules).
|
|
43
|
-
* Filters out the sentinel rule (chain://_sentinel) to avoid diff noise.
|
|
44
|
-
*/
|
|
45
|
-
export function buildCurrentState(rules, classified) {
|
|
46
|
-
const chainRules = rules.filter((r) => r.sourcePath.startsWith('chain://') && r.sourcePath !== 'chain://_sentinel');
|
|
47
|
-
return {
|
|
48
|
-
timestamp: new Date().toISOString(),
|
|
49
|
-
rules: chainRules.map((r) => buildStateRule(r, classified)),
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Save current handshake state to .productbrain/.handshake-state.json.
|
|
54
|
-
* Only persists chain:// sourced rules (ignores manual rules and sentinel).
|
|
55
|
-
*/
|
|
56
|
-
export function saveHandshakeState(pbDir, rules, classified) {
|
|
57
|
-
const state = buildCurrentState(rules, classified);
|
|
58
|
-
writeFileSync(stateFilePath(pbDir), JSON.stringify(state, null, 2) + '\n');
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Load previous handshake state from .productbrain/.handshake-state.json.
|
|
62
|
-
* Returns null if no previous state exists or the file cannot be parsed.
|
|
63
|
-
*/
|
|
64
|
-
export function loadPreviousState(pbDir) {
|
|
65
|
-
const filePath = stateFilePath(pbDir);
|
|
66
|
-
if (!existsSync(filePath))
|
|
67
|
-
return null;
|
|
68
|
-
try {
|
|
69
|
-
const raw = readFileSync(filePath, 'utf8');
|
|
70
|
-
return JSON.parse(raw);
|
|
71
|
-
}
|
|
72
|
-
catch (err) {
|
|
73
|
-
process.stderr.write(`Warning: failed to parse ${filePath} — ${err instanceof Error ? err.message : err}\n`);
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Compare current rules against previous state and produce a diff.
|
|
79
|
-
* When previous is null, all current rules are reported as added (first run).
|
|
80
|
-
*/
|
|
81
|
-
export function diffHandshakeState(current, previous) {
|
|
82
|
-
if (previous === null) {
|
|
83
|
-
return {
|
|
84
|
-
added: current.rules.map((r) => ({
|
|
85
|
-
name: r.name,
|
|
86
|
-
change: 'added',
|
|
87
|
-
details: `confidence: ${r.confidence}, ${r.entryIds.length} entries`,
|
|
88
|
-
})),
|
|
89
|
-
removed: [],
|
|
90
|
-
changed: [],
|
|
91
|
-
isFirstRun: true,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
const currentByName = new Map(current.rules.map((r) => [r.name, r]));
|
|
95
|
-
const previousByName = new Map(previous.rules.map((r) => [r.name, r]));
|
|
96
|
-
const added = [];
|
|
97
|
-
const removed = [];
|
|
98
|
-
const changed = [];
|
|
99
|
-
// Added: in current but not previous
|
|
100
|
-
for (const [name, rule] of currentByName) {
|
|
101
|
-
if (!previousByName.has(name)) {
|
|
102
|
-
added.push({
|
|
103
|
-
name,
|
|
104
|
-
change: 'added',
|
|
105
|
-
details: `confidence: ${rule.confidence}, ${rule.entryIds.length} entries`,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
// Removed: in previous but not current
|
|
110
|
-
for (const [name] of previousByName) {
|
|
111
|
-
if (!currentByName.has(name)) {
|
|
112
|
-
removed.push({
|
|
113
|
-
name,
|
|
114
|
-
change: 'removed',
|
|
115
|
-
details: 'removed — no matching entries',
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
// Changed: in both but different
|
|
120
|
-
for (const [name, curr] of currentByName) {
|
|
121
|
-
const prev = previousByName.get(name);
|
|
122
|
-
if (!prev)
|
|
123
|
-
continue; // handled as added above
|
|
124
|
-
const details = buildChangedDetails(prev, curr);
|
|
125
|
-
if (details !== null) {
|
|
126
|
-
changed.push({ name, change: 'changed', details });
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return { added, removed, changed, isFirstRun: false };
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Build a details string for a changed rule. Returns null if no meaningful change detected.
|
|
133
|
-
*/
|
|
134
|
-
function buildChangedDetails(prev, curr) {
|
|
135
|
-
const parts = [];
|
|
136
|
-
// Confidence delta — only report if it changed
|
|
137
|
-
if (prev.confidence !== curr.confidence) {
|
|
138
|
-
parts.push(`confidence: ${prev.confidence} → ${curr.confidence}`);
|
|
139
|
-
}
|
|
140
|
-
// Entry changes — compute added/removed entry IDs
|
|
141
|
-
const prevSet = new Set(prev.entryIds);
|
|
142
|
-
const currSet = new Set(curr.entryIds);
|
|
143
|
-
const addedEntries = curr.entryIds.filter((id) => !prevSet.has(id));
|
|
144
|
-
const removedEntries = prev.entryIds.filter((id) => !currSet.has(id));
|
|
145
|
-
if (addedEntries.length > 0 || removedEntries.length > 0) {
|
|
146
|
-
const entryParts = [];
|
|
147
|
-
if (addedEntries.length > 0)
|
|
148
|
-
entryParts.push(...addedEntries.map((id) => `+${id}`));
|
|
149
|
-
if (removedEntries.length > 0)
|
|
150
|
-
entryParts.push(...removedEntries.map((id) => `-${id}`));
|
|
151
|
-
parts.push(`entries: ${entryParts.join(', ')}`);
|
|
152
|
-
}
|
|
153
|
-
if (parts.length === 0)
|
|
154
|
-
return null;
|
|
155
|
-
return parts.join(', ');
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Format a HandshakeDiff for console output.
|
|
159
|
-
*/
|
|
160
|
-
export function formatDiff(diff) {
|
|
161
|
-
if (diff.isFirstRun) {
|
|
162
|
-
return 'First run — no previous state to compare.';
|
|
163
|
-
}
|
|
164
|
-
const hasChanges = diff.added.length > 0 || diff.removed.length > 0 || diff.changed.length > 0;
|
|
165
|
-
if (!hasChanges) {
|
|
166
|
-
return 'No changes.';
|
|
167
|
-
}
|
|
168
|
-
const lines = ['Handshake diff (vs previous run):'];
|
|
169
|
-
for (const rule of diff.added) {
|
|
170
|
-
const detail = rule.details ? ` (${rule.details})` : '';
|
|
171
|
-
lines.push(` + ${rule.name}${detail}`);
|
|
172
|
-
}
|
|
173
|
-
for (const rule of diff.removed) {
|
|
174
|
-
const detail = rule.details ? ` (${rule.details})` : '';
|
|
175
|
-
lines.push(` - ${rule.name}${detail}`);
|
|
176
|
-
}
|
|
177
|
-
for (const rule of diff.changed) {
|
|
178
|
-
const detail = rule.details ? ` (${rule.details})` : '';
|
|
179
|
-
lines.push(` ~ ${rule.name}${detail}`);
|
|
180
|
-
}
|
|
181
|
-
return lines.join('\n');
|
|
182
|
-
}
|
|
183
|
-
//# sourceMappingURL=handshake-diff.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"handshake-diff.js","sourceRoot":"","sources":["../../src/generators/handshake-diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"handshake-diff.test.d.ts","sourceRoot":"","sources":["../../src/generators/handshake-diff.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* handshake-diff — unit tests.
|
|
3
|
-
* BET-286 Slice 4: diff engine for handshake --generate runs.
|
|
4
|
-
*/
|
|
5
|
-
import { afterEach, describe, expect, it } from 'vitest';
|
|
6
|
-
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'fs';
|
|
7
|
-
import { join } from 'path';
|
|
8
|
-
import { tmpdir } from 'os';
|
|
9
|
-
import { saveHandshakeState, loadPreviousState, diffHandshakeState, formatDiff, } from './handshake-diff.js';
|
|
10
|
-
// ── Helpers ────────────────────────────────────────────────────────────
|
|
11
|
-
function makeTempDir() {
|
|
12
|
-
const dir = join(tmpdir(), `handshake-diff-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
13
|
-
mkdirSync(dir, { recursive: true });
|
|
14
|
-
return dir;
|
|
15
|
-
}
|
|
16
|
-
function makeCanonicalRule(overrides) {
|
|
17
|
-
return {
|
|
18
|
-
description: 'A rule description',
|
|
19
|
-
body: 'Rule body content',
|
|
20
|
-
autoApply: true,
|
|
21
|
-
level: 'core',
|
|
22
|
-
scope: undefined,
|
|
23
|
-
targets: undefined,
|
|
24
|
-
...overrides,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
function makeClassifiedEntry(overrides) {
|
|
28
|
-
return {
|
|
29
|
-
name: `Entry ${overrides.entryId}`,
|
|
30
|
-
collectionSlug: 'standards',
|
|
31
|
-
confidence: 0.65,
|
|
32
|
-
matchedSignals: ['collection \'standards\' → constraint'],
|
|
33
|
-
data: null,
|
|
34
|
-
relations: [],
|
|
35
|
-
...overrides,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
function makeHandshakeState(rules, timestamp = '2024-01-01T00:00:00.000Z') {
|
|
39
|
-
return { timestamp, rules };
|
|
40
|
-
}
|
|
41
|
-
function makeStateRule(overrides) {
|
|
42
|
-
return {
|
|
43
|
-
functionKey: 'constraint',
|
|
44
|
-
sourcePath: 'chain://constraint',
|
|
45
|
-
confidence: 0.65,
|
|
46
|
-
entryIds: ['STD-1'],
|
|
47
|
-
...overrides,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
// Track temp dirs for cleanup
|
|
51
|
-
const tempDirs = [];
|
|
52
|
-
afterEach(() => {
|
|
53
|
-
for (const dir of tempDirs) {
|
|
54
|
-
if (existsSync(dir))
|
|
55
|
-
rmSync(dir, { recursive: true, force: true });
|
|
56
|
-
}
|
|
57
|
-
tempDirs.length = 0;
|
|
58
|
-
});
|
|
59
|
-
// ── Tests ──────────────────────────────────────────────────────────────
|
|
60
|
-
describe('loadPreviousState', () => {
|
|
61
|
-
it('returns null when no state file exists', () => {
|
|
62
|
-
const dir = makeTempDir();
|
|
63
|
-
tempDirs.push(dir);
|
|
64
|
-
const result = loadPreviousState(dir);
|
|
65
|
-
expect(result).toBeNull();
|
|
66
|
-
});
|
|
67
|
-
it('returns null when state file contains invalid JSON', () => {
|
|
68
|
-
const dir = makeTempDir();
|
|
69
|
-
tempDirs.push(dir);
|
|
70
|
-
writeFileSync(join(dir, '.handshake-state.json'), 'not valid json', 'utf8');
|
|
71
|
-
const result = loadPreviousState(dir);
|
|
72
|
-
expect(result).toBeNull();
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
describe('saveHandshakeState', () => {
|
|
76
|
-
it('creates a valid JSON state file', () => {
|
|
77
|
-
const dir = makeTempDir();
|
|
78
|
-
tempDirs.push(dir);
|
|
79
|
-
const rules = [
|
|
80
|
-
makeCanonicalRule({ name: 'chain-constraints', sourcePath: 'chain://constraint' }),
|
|
81
|
-
];
|
|
82
|
-
const classified = [
|
|
83
|
-
makeClassifiedEntry({ entryId: 'STD-1', governanceFunction: 'constraint', confidence: 0.65 }),
|
|
84
|
-
];
|
|
85
|
-
saveHandshakeState(dir, rules, classified);
|
|
86
|
-
const loaded = loadPreviousState(dir);
|
|
87
|
-
expect(loaded).not.toBeNull();
|
|
88
|
-
expect(loaded.rules).toHaveLength(1);
|
|
89
|
-
expect(loaded.rules[0].name).toBe('chain-constraints');
|
|
90
|
-
expect(loaded.rules[0].functionKey).toBe('constraint');
|
|
91
|
-
expect(loaded.rules[0].sourcePath).toBe('chain://constraint');
|
|
92
|
-
expect(loaded.rules[0].entryIds).toEqual(['STD-1']);
|
|
93
|
-
expect(loaded.rules[0].confidence).toBe(0.65);
|
|
94
|
-
expect(typeof loaded.timestamp).toBe('string');
|
|
95
|
-
});
|
|
96
|
-
it('only saves chain:// rules (ignores manual rules)', () => {
|
|
97
|
-
const dir = makeTempDir();
|
|
98
|
-
tempDirs.push(dir);
|
|
99
|
-
const rules = [
|
|
100
|
-
makeCanonicalRule({ name: 'chain-constraints', sourcePath: 'chain://constraint' }),
|
|
101
|
-
makeCanonicalRule({ name: 'my-manual-rule', sourcePath: '.productbrain/rules/my-manual-rule.md' }),
|
|
102
|
-
];
|
|
103
|
-
const classified = [];
|
|
104
|
-
saveHandshakeState(dir, rules, classified);
|
|
105
|
-
const loaded = loadPreviousState(dir);
|
|
106
|
-
expect(loaded.rules).toHaveLength(1);
|
|
107
|
-
expect(loaded.rules[0].name).toBe('chain-constraints');
|
|
108
|
-
});
|
|
109
|
-
it('averages confidence across multiple entries for the same function', () => {
|
|
110
|
-
const dir = makeTempDir();
|
|
111
|
-
tempDirs.push(dir);
|
|
112
|
-
const rules = [
|
|
113
|
-
makeCanonicalRule({ name: 'chain-constraints', sourcePath: 'chain://constraint' }),
|
|
114
|
-
];
|
|
115
|
-
const classified = [
|
|
116
|
-
makeClassifiedEntry({ entryId: 'STD-1', governanceFunction: 'constraint', confidence: 0.5 }),
|
|
117
|
-
makeClassifiedEntry({ entryId: 'STD-2', governanceFunction: 'constraint', confidence: 0.9 }),
|
|
118
|
-
];
|
|
119
|
-
saveHandshakeState(dir, rules, classified);
|
|
120
|
-
const loaded = loadPreviousState(dir);
|
|
121
|
-
expect(loaded.rules[0].confidence).toBe(0.7); // (0.5 + 0.9) / 2 = 0.7
|
|
122
|
-
expect(loaded.rules[0].entryIds).toContain('STD-1');
|
|
123
|
-
expect(loaded.rules[0].entryIds).toContain('STD-2');
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
describe('diffHandshakeState', () => {
|
|
127
|
-
it('first run: isFirstRun is true, all current rules are added', () => {
|
|
128
|
-
const current = makeHandshakeState([
|
|
129
|
-
makeStateRule({ name: 'chain-constraints' }),
|
|
130
|
-
makeStateRule({ name: 'chain-boundary', functionKey: 'boundary', sourcePath: 'chain://boundary' }),
|
|
131
|
-
]);
|
|
132
|
-
const diff = diffHandshakeState(current, null);
|
|
133
|
-
expect(diff.isFirstRun).toBe(true);
|
|
134
|
-
expect(diff.added).toHaveLength(2);
|
|
135
|
-
expect(diff.removed).toHaveLength(0);
|
|
136
|
-
expect(diff.changed).toHaveLength(0);
|
|
137
|
-
expect(diff.added.map((r) => r.name)).toContain('chain-constraints');
|
|
138
|
-
expect(diff.added.map((r) => r.name)).toContain('chain-boundary');
|
|
139
|
-
});
|
|
140
|
-
it('no changes: added/removed/changed all empty', () => {
|
|
141
|
-
const rules = [makeStateRule({ name: 'chain-constraints', confidence: 0.65, entryIds: ['STD-1'] })];
|
|
142
|
-
const current = makeHandshakeState(rules);
|
|
143
|
-
const previous = makeHandshakeState(rules);
|
|
144
|
-
const diff = diffHandshakeState(current, previous);
|
|
145
|
-
expect(diff.isFirstRun).toBe(false);
|
|
146
|
-
expect(diff.added).toHaveLength(0);
|
|
147
|
-
expect(diff.removed).toHaveLength(0);
|
|
148
|
-
expect(diff.changed).toHaveLength(0);
|
|
149
|
-
});
|
|
150
|
-
it('added rule detected', () => {
|
|
151
|
-
const previous = makeHandshakeState([
|
|
152
|
-
makeStateRule({ name: 'chain-constraints' }),
|
|
153
|
-
]);
|
|
154
|
-
const current = makeHandshakeState([
|
|
155
|
-
makeStateRule({ name: 'chain-constraints' }),
|
|
156
|
-
makeStateRule({ name: 'chain-boundary', functionKey: 'boundary', sourcePath: 'chain://boundary', entryIds: ['ARCH-1'] }),
|
|
157
|
-
]);
|
|
158
|
-
const diff = diffHandshakeState(current, previous);
|
|
159
|
-
expect(diff.added).toHaveLength(1);
|
|
160
|
-
expect(diff.added[0].name).toBe('chain-boundary');
|
|
161
|
-
expect(diff.added[0].change).toBe('added');
|
|
162
|
-
expect(diff.removed).toHaveLength(0);
|
|
163
|
-
expect(diff.changed).toHaveLength(0);
|
|
164
|
-
});
|
|
165
|
-
it('removed rule detected', () => {
|
|
166
|
-
const previous = makeHandshakeState([
|
|
167
|
-
makeStateRule({ name: 'chain-constraints' }),
|
|
168
|
-
makeStateRule({ name: 'chain-workflow', functionKey: 'workflow', sourcePath: 'chain://workflow' }),
|
|
169
|
-
]);
|
|
170
|
-
const current = makeHandshakeState([
|
|
171
|
-
makeStateRule({ name: 'chain-constraints' }),
|
|
172
|
-
]);
|
|
173
|
-
const diff = diffHandshakeState(current, previous);
|
|
174
|
-
expect(diff.removed).toHaveLength(1);
|
|
175
|
-
expect(diff.removed[0].name).toBe('chain-workflow');
|
|
176
|
-
expect(diff.removed[0].change).toBe('removed');
|
|
177
|
-
expect(diff.added).toHaveLength(0);
|
|
178
|
-
expect(diff.changed).toHaveLength(0);
|
|
179
|
-
});
|
|
180
|
-
it('changed confidence detected with correct details string', () => {
|
|
181
|
-
const previous = makeHandshakeState([
|
|
182
|
-
makeStateRule({ name: 'chain-constraints', confidence: 0.5, entryIds: ['STD-1'] }),
|
|
183
|
-
]);
|
|
184
|
-
const current = makeHandshakeState([
|
|
185
|
-
makeStateRule({ name: 'chain-constraints', confidence: 0.9, entryIds: ['STD-1'] }),
|
|
186
|
-
]);
|
|
187
|
-
const diff = diffHandshakeState(current, previous);
|
|
188
|
-
expect(diff.changed).toHaveLength(1);
|
|
189
|
-
expect(diff.changed[0].name).toBe('chain-constraints');
|
|
190
|
-
expect(diff.changed[0].change).toBe('changed');
|
|
191
|
-
expect(diff.changed[0].details).toContain('confidence: 0.5 → 0.9');
|
|
192
|
-
expect(diff.added).toHaveLength(0);
|
|
193
|
-
expect(diff.removed).toHaveLength(0);
|
|
194
|
-
});
|
|
195
|
-
it('changed entries detected with +/- notation', () => {
|
|
196
|
-
const previous = makeHandshakeState([
|
|
197
|
-
makeStateRule({ name: 'chain-constraints', confidence: 0.65, entryIds: ['STD-1', 'STD-7'] }),
|
|
198
|
-
]);
|
|
199
|
-
const current = makeHandshakeState([
|
|
200
|
-
makeStateRule({ name: 'chain-constraints', confidence: 0.65, entryIds: ['STD-1', 'STD-22'] }),
|
|
201
|
-
]);
|
|
202
|
-
const diff = diffHandshakeState(current, previous);
|
|
203
|
-
expect(diff.changed).toHaveLength(1);
|
|
204
|
-
expect(diff.changed[0].details).toContain('+STD-22');
|
|
205
|
-
expect(diff.changed[0].details).toContain('-STD-7');
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
describe('formatDiff', () => {
|
|
209
|
-
it('outputs "First run" message when isFirstRun is true', () => {
|
|
210
|
-
const diff = { added: [], removed: [], changed: [], isFirstRun: true };
|
|
211
|
-
const output = formatDiff(diff);
|
|
212
|
-
expect(output).toBe('First run — no previous state to compare.');
|
|
213
|
-
});
|
|
214
|
-
it('outputs "No changes." when diff is empty', () => {
|
|
215
|
-
const diff = { added: [], removed: [], changed: [], isFirstRun: false };
|
|
216
|
-
const output = formatDiff(diff);
|
|
217
|
-
expect(output).toBe('No changes.');
|
|
218
|
-
});
|
|
219
|
-
it('formats added rules with + prefix', () => {
|
|
220
|
-
const diff = {
|
|
221
|
-
added: [{ name: 'chain-constraints', change: 'added', details: 'confidence: 0.65, 3 entries' }],
|
|
222
|
-
removed: [],
|
|
223
|
-
changed: [],
|
|
224
|
-
isFirstRun: false,
|
|
225
|
-
};
|
|
226
|
-
const output = formatDiff(diff);
|
|
227
|
-
expect(output).toContain('Handshake diff (vs previous run):');
|
|
228
|
-
expect(output).toContain(' + chain-constraints (confidence: 0.65, 3 entries)');
|
|
229
|
-
});
|
|
230
|
-
it('formats removed rules with - prefix', () => {
|
|
231
|
-
const diff = {
|
|
232
|
-
added: [],
|
|
233
|
-
removed: [{ name: 'chain-workflow', change: 'removed', details: 'removed — no matching entries' }],
|
|
234
|
-
changed: [],
|
|
235
|
-
isFirstRun: false,
|
|
236
|
-
};
|
|
237
|
-
const output = formatDiff(diff);
|
|
238
|
-
expect(output).toContain(' - chain-workflow (removed — no matching entries)');
|
|
239
|
-
});
|
|
240
|
-
it('formats changed rules with ~ prefix', () => {
|
|
241
|
-
const diff = {
|
|
242
|
-
added: [],
|
|
243
|
-
removed: [],
|
|
244
|
-
changed: [{ name: 'chain-boundary', change: 'changed', details: 'confidence: 0.50 → 0.70, entries: +ARCH-5' }],
|
|
245
|
-
isFirstRun: false,
|
|
246
|
-
};
|
|
247
|
-
const output = formatDiff(diff);
|
|
248
|
-
expect(output).toContain(' ~ chain-boundary (confidence: 0.50 → 0.70, entries: +ARCH-5)');
|
|
249
|
-
});
|
|
250
|
-
it('outputs readable console text with all change types', () => {
|
|
251
|
-
const diff = {
|
|
252
|
-
added: [{ name: 'chain-constraints', change: 'added', details: 'confidence: 0.65, 3 entries' }],
|
|
253
|
-
removed: [{ name: 'chain-workflow', change: 'removed', details: 'removed — no matching entries' }],
|
|
254
|
-
changed: [{ name: 'chain-boundary', change: 'changed', details: 'confidence: 0.50 → 0.70' }],
|
|
255
|
-
isFirstRun: false,
|
|
256
|
-
};
|
|
257
|
-
const output = formatDiff(diff);
|
|
258
|
-
expect(output).toContain('Handshake diff (vs previous run):');
|
|
259
|
-
expect(output).toContain(' + chain-constraints');
|
|
260
|
-
expect(output).toContain(' - chain-workflow');
|
|
261
|
-
expect(output).toContain(' ~ chain-boundary');
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
//# sourceMappingURL=handshake-diff.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"handshake-diff.test.js","sourceRoot":"","sources":["../../src/generators/handshake-diff.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,GAGX,MAAM,qBAAqB,CAAC;AAI7B,0EAA0E;AAE1E,SAAS,WAAW;IAClB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,uBAAuB,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACvG,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAwE;IACjG,OAAO;QACL,WAAW,EAAE,oBAAoB;QACjC,IAAI,EAAE,mBAAmB;QACzB,SAAS,EAAE,IAAI;QACf,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,SAAS;QAClB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,SAA8H;IACzJ,OAAO;QACL,IAAI,EAAE,SAAS,SAAS,CAAC,OAAO,EAAE;QAClC,cAAc,EAAE,WAAW;QAC3B,UAAU,EAAE,IAAI;QAChB,cAAc,EAAE,CAAC,uCAAuC,CAAC;QACzD,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,EAAE;QACb,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,KAA2B,EAAE,SAAS,GAAG,0BAA0B;IAC7F,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC;AAED,SAAS,aAAa,CAAC,SAAyD;IAC9E,OAAO;QACL,WAAW,EAAE,YAAY;QACzB,UAAU,EAAE,oBAAoB;QAChC,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,8BAA8B;AAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;AAE9B,SAAS,CAAC,GAAG,EAAE;IACb,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;AACtB,CAAC,CAAC,CAAC;AAEH,0EAA0E;AAE1E,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEnB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAEtC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,uBAAuB,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;QAE5E,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAEtC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEnB,MAAM,KAAK,GAAoB;YAC7B,iBAAiB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAC;SACnF,CAAC;QACF,MAAM,UAAU,GAA2B;YACzC,mBAAmB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;SAC9F,CAAC;QAEF,kBAAkB,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACxD,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC/D,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,OAAO,MAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEnB,MAAM,KAAK,GAAoB;YAC7B,iBAAiB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAC;YAClF,iBAAiB,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,uCAAuC,EAAE,CAAC;SACnG,CAAC;QACF,MAAM,UAAU,GAA2B,EAAE,CAAC;QAE9C,kBAAkB,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEnB,MAAM,KAAK,GAAoB;YAC7B,iBAAiB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAC;SACnF,CAAC;QACF,MAAM,UAAU,GAA2B;YACzC,mBAAmB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;YAC5F,mBAAmB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;SAC7F,CAAC;QAEF,kBAAkB,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,wBAAwB;QACvE,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACrD,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,OAAO,GAAG,kBAAkB,CAAC;YACjC,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;YAC5C,aAAa,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC;SACnG,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAE/C,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACrE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,KAAK,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACpG,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAE3C,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEnD,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,QAAQ,GAAG,kBAAkB,CAAC;YAClC,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;SAC7C,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,kBAAkB,CAAC;YACjC,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;YAC5C,aAAa,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;SACzH,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEnD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,QAAQ,GAAG,kBAAkB,CAAC;YAClC,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;YAC5C,aAAa,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC;SACnG,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,kBAAkB,CAAC;YACjC,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;SAC7C,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEnD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,QAAQ,GAAG,kBAAkB,CAAC;YAClC,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;SACnF,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,kBAAkB,CAAC;YACjC,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;SACnF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEnD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QACnE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,QAAQ,GAAG,kBAAkB,CAAC;YAClC,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;SAC7F,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,kBAAkB,CAAC;YACjC,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;SAC9F,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEnD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QAEvE,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAEhC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QAExE,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAEhC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,OAAgB,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC;YACxG,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,KAAK;SAClB,CAAC;QAEF,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAEhC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,mCAAmC,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qDAAqD,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,EAAE;YACT,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAkB,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;YAC3G,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,KAAK;SAClB,CAAC;QAEF,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAEhC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,oDAAoD,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,EAAE;YACT,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAkB,EAAE,OAAO,EAAE,2CAA2C,EAAE,CAAC;YACvH,UAAU,EAAE,KAAK;SAClB,CAAC;QAEF,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAEhC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gEAAgE,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,OAAgB,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC;YACxG,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAkB,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;YAC3G,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAkB,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC;YACrG,UAAU,EAAE,KAAK;SAClB,CAAC;QAEF,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAEhC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,mCAAmC,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: chain-boundaries
|
|
3
|
-
description: "{{entry_count}} system boundaries derived from Chain architecture entries"
|
|
4
|
-
autoApply: true
|
|
5
|
-
level: core
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Chain-Derived System Boundaries
|
|
9
|
-
|
|
10
|
-
These {{entry_count}} architecture and decision entries define system boundaries for this workspace. Do not cross a boundary without understanding the contract it defines.
|
|
11
|
-
|
|
12
|
-
**Boundary entries:** {{entry_ids}}
|
|
13
|
-
|
|
14
|
-
{{boundary_summary}}
|
|
15
|
-
|
|
16
|
-
## What this means
|
|
17
|
-
|
|
18
|
-
- Boundaries define what a domain owns and what it does not own.
|
|
19
|
-
- Cross-domain changes require explicit negotiation — check the Team APIs in `docs/system/domains/`.
|
|
20
|
-
- Run `pb get <ID>` to read the full boundary entry before touching cross-domain seams.
|
|
21
|
-
- If your change crosses a domain boundary, identify the owning domain first (domain-boundaries rule).
|
|
22
|
-
|
|
23
|
-
**Source entries (names):** {{entry_names}}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: chain-constraints
|
|
3
|
-
description: "{{entry_count}} implementation constraints derived from Chain governance entries"
|
|
4
|
-
autoApply: true
|
|
5
|
-
level: core
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Chain-Derived Constraints
|
|
9
|
-
|
|
10
|
-
These {{entry_count}} governance entries constrain implementation in this workspace. Before writing code that touches any affected domain, check these entries on the Chain.
|
|
11
|
-
|
|
12
|
-
**Constraint entries:** {{entry_ids}}
|
|
13
|
-
|
|
14
|
-
{{constraint_summary}}
|
|
15
|
-
|
|
16
|
-
## What this means
|
|
17
|
-
|
|
18
|
-
- These standards and rules are non-negotiable. They constrain behavior across all slices.
|
|
19
|
-
- Run `pb get <ID>` to read the full entry before implementing anything in its domain.
|
|
20
|
-
- If your change conflicts with a constraint, capture a tension before proceeding.
|
|
21
|
-
- "I didn't know" is not a valid defense when the constraint is on the Chain.
|
|
22
|
-
|
|
23
|
-
**Source entries (names):** {{entry_names}}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: chain-conventions
|
|
3
|
-
description: "{{entry_count}} conventions derived from Chain decision and pattern entries"
|
|
4
|
-
autoApply: true
|
|
5
|
-
level: core
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Chain-Derived Conventions
|
|
9
|
-
|
|
10
|
-
These {{entry_count}} decision and pattern entries establish conventions for this workspace. Follow them unless you have a decision on the Chain that says otherwise.
|
|
11
|
-
|
|
12
|
-
**Convention entries:** {{entry_ids}}
|
|
13
|
-
|
|
14
|
-
{{convention_summary}}
|
|
15
|
-
|
|
16
|
-
## What this means
|
|
17
|
-
|
|
18
|
-
- Conventions are established patterns, not suggestions. They reduce decision fatigue.
|
|
19
|
-
- Before inventing a new pattern, search the Chain — it may already be a convention.
|
|
20
|
-
- Run `pb get <ID>` to understand the rationale behind a convention before deviating.
|
|
21
|
-
- If you must deviate, capture a DEC on the Chain explaining the new direction.
|
|
22
|
-
|
|
23
|
-
**Source entries (names):** {{entry_names}}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: chain-policies
|
|
3
|
-
description: "{{entry_count}} operational policies derived from Chain policy and business-rule entries"
|
|
4
|
-
autoApply: true
|
|
5
|
-
level: core
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Chain-Derived Policies
|
|
9
|
-
|
|
10
|
-
These {{entry_count}} policy and business-rule entries govern workflows and access in this workspace. Policies apply even when they are inconvenient.
|
|
11
|
-
|
|
12
|
-
**Policy entries:** {{entry_ids}}
|
|
13
|
-
|
|
14
|
-
{{policy_summary}}
|
|
15
|
-
|
|
16
|
-
## What this means
|
|
17
|
-
|
|
18
|
-
- Policies govern who can do what and under what conditions.
|
|
19
|
-
- Security, auth, and access control policies are never optional.
|
|
20
|
-
- Run `pb get <ID>` to read the full policy before implementing anything in its domain.
|
|
21
|
-
- If a policy conflicts with a feature requirement, capture a TEN and escalate — do not quietly violate.
|
|
22
|
-
|
|
23
|
-
**Source entries (names):** {{entry_names}}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: chain-quality-gates
|
|
3
|
-
description: "{{entry_count}} quality gates derived from Chain standard and business-rule entries"
|
|
4
|
-
autoApply: true
|
|
5
|
-
level: core
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Chain-Derived Quality Gates
|
|
9
|
-
|
|
10
|
-
These {{entry_count}} standard and business-rule entries define quality gates that must pass before shipping. No exceptions without a documented reason on the Chain.
|
|
11
|
-
|
|
12
|
-
**Quality gate entries:** {{entry_ids}}
|
|
13
|
-
|
|
14
|
-
{{quality_summary}}
|
|
15
|
-
|
|
16
|
-
## What this means
|
|
17
|
-
|
|
18
|
-
- Quality gates are pass/fail. They are not approximate.
|
|
19
|
-
- Run `npm run build` and `npm run test` before every push — always.
|
|
20
|
-
- Run `pb get <ID>` to read the specific acceptance criteria for a quality gate.
|
|
21
|
-
- If a gate cannot pass due to a legitimate constraint, capture a TEN before shipping.
|
|
22
|
-
|
|
23
|
-
**Source entries (names):** {{entry_names}}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: chain-workflows
|
|
3
|
-
description: "{{entry_count}} required process flows derived from Chain flow entries"
|
|
4
|
-
autoApply: true
|
|
5
|
-
level: core
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Chain-Derived Workflows
|
|
9
|
-
|
|
10
|
-
These {{entry_count}} flow entries define required processes for this workspace. If a workflow entry exists for a process you are about to execute, follow it.
|
|
11
|
-
|
|
12
|
-
**Workflow entries:** {{entry_ids}}
|
|
13
|
-
|
|
14
|
-
{{workflow_summary}}
|
|
15
|
-
|
|
16
|
-
## What this means
|
|
17
|
-
|
|
18
|
-
- Workflows define the correct sequence of steps for key processes.
|
|
19
|
-
- Skipping a step is not the same as completing the workflow.
|
|
20
|
-
- Run `pb get <ID>` to read the full workflow before executing the process it defines.
|
|
21
|
-
- If the workflow is incomplete or outdated, capture a TEN — do not silently deviate.
|
|
22
|
-
|
|
23
|
-
**Source entries (names):** {{entry_names}}
|