@mmnto/cli 1.105.0 → 1.107.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/doctor-qbd.d.ts +40 -0
- package/dist/commands/doctor-qbd.d.ts.map +1 -0
- package/dist/commands/doctor-qbd.js +156 -0
- package/dist/commands/doctor-qbd.js.map +1 -0
- package/dist/commands/doctor-qbd.test.d.ts +13 -0
- package/dist/commands/doctor-qbd.test.d.ts.map +1 -0
- package/dist/commands/doctor-qbd.test.js +548 -0
- package/dist/commands/doctor-qbd.test.js.map +1 -0
- package/dist/commands/mail-degraded-e4.test.d.ts +43 -0
- package/dist/commands/mail-degraded-e4.test.d.ts.map +1 -0
- package/dist/commands/mail-degraded-e4.test.js +317 -0
- package/dist/commands/mail-degraded-e4.test.js.map +1 -0
- package/dist/commands/orient.d.ts.map +1 -1
- package/dist/commands/orient.js +23 -0
- package/dist/commands/orient.js.map +1 -1
- package/dist/commands/qbd-seam.d.ts +77 -0
- package/dist/commands/qbd-seam.d.ts.map +1 -0
- package/dist/commands/qbd-seam.js +150 -0
- package/dist/commands/qbd-seam.js.map +1 -0
- package/dist/commands/qbd-seam.test.d.ts +16 -0
- package/dist/commands/qbd-seam.test.d.ts.map +1 -0
- package/dist/commands/qbd-seam.test.js +339 -0
- package/dist/commands/qbd-seam.test.js.map +1 -0
- package/dist/commands/review-fan.d.ts.map +1 -1
- package/dist/commands/review-fan.js +26 -0
- package/dist/commands/review-fan.js.map +1 -1
- package/dist/commands/run-compiled-rules.d.ts.map +1 -1
- package/dist/commands/run-compiled-rules.js +137 -5
- package/dist/commands/run-compiled-rules.js.map +1 -1
- package/dist/commands/run-compiled-rules.test.js +359 -1
- package/dist/commands/run-compiled-rules.test.js.map +1 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +15 -0
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/shield.d.ts.map +1 -1
- package/dist/commands/shield.js +34 -0
- package/dist/commands/shield.js.map +1 -1
- package/dist/commands/spec.d.ts.map +1 -1
- package/dist/commands/spec.js +16 -0
- package/dist/commands/spec.js.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single place the query-before-derive seams resolve their ledger directory
|
|
3
|
+
* (mmnto-ai/totem#2510).
|
|
4
|
+
*
|
|
5
|
+
* ## Why this exists
|
|
6
|
+
*
|
|
7
|
+
* The seams originally each did `path.join(cwd, config.totemDir)`. That is
|
|
8
|
+
* wrong, and silently so. `resolveConfigPath` does NOT walk up the tree — it
|
|
9
|
+
* checks the cwd and then falls back to the global `~/.totem/` profile — so
|
|
10
|
+
* running a derive-class command from a subdirectory of a project resolves a
|
|
11
|
+
* config successfully (the command works) while the seam targets
|
|
12
|
+
* `<subdir>/.totem`, which does not exist. The core writer then skips, and the
|
|
13
|
+
* derive vanishes from the denominator: exactly the #2510 falsifier-1 failure,
|
|
14
|
+
* arrived at by accident instead of by gaming.
|
|
15
|
+
*
|
|
16
|
+
* The fix is to resolve the ledger directory the way this command family's
|
|
17
|
+
* EXISTING ledger writes already do — from the config root, e.g. `shield.ts`'s
|
|
18
|
+
* `path.join(configRoot, config.totemDir)` for `override` events — so QBD rows
|
|
19
|
+
* land in the same ledger as every other event the same command emits.
|
|
20
|
+
*
|
|
21
|
+
* Every seam and the doctor reader route through here, so the resolution can
|
|
22
|
+
* only be wrong in one place, and a fix lands everywhere at once. That
|
|
23
|
+
* writer/reader agreement is the load-bearing property: rows went missing
|
|
24
|
+
* precisely because the two resolved differently.
|
|
25
|
+
*
|
|
26
|
+
* ## Known residual, stated rather than hidden
|
|
27
|
+
*
|
|
28
|
+
* `resolveConfigPath` still does not walk up. Run from a subdirectory of a
|
|
29
|
+
* project that has no config of its own, it resolves the global `~/.totem/`
|
|
30
|
+
* profile, so the row lands in the global profile's ledger rather than the
|
|
31
|
+
* enclosing project's. That is consistent — telemetry follows the same config
|
|
32
|
+
* the command itself ran under, and the reader follows it too — but it is not
|
|
33
|
+
* the same as project-root discovery. Fixing it properly means changing
|
|
34
|
+
* `resolveConfigPath` semantics for EVERY command, which is a repo-wide change
|
|
35
|
+
* well outside this slice. Scoped out deliberately, not overlooked.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Resolve the ledger directory QBD rows belong in, for a given cwd.
|
|
39
|
+
*
|
|
40
|
+
* Returns `undefined` when no Totem config can be resolved at all — there is no
|
|
41
|
+
* project to instrument, which is a normal state for a general-purpose command
|
|
42
|
+
* like `orient` run outside a repo.
|
|
43
|
+
*/
|
|
44
|
+
export async function resolveQbdLedgerDir(cwd, homeDir) {
|
|
45
|
+
return (await resolveQbdLedgerDirDetailed(cwd, homeDir)).dir;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* As `resolveQbdLedgerDir`, but distinguishes the two reasons resolution can
|
|
49
|
+
* fail so the caller can say which happened.
|
|
50
|
+
*
|
|
51
|
+
* `CONFIG_MISSING` is the honest-absent case — no project here, nothing to
|
|
52
|
+
* instrument, an entirely normal state for a command like `orient`. Any other
|
|
53
|
+
* failure means a config exists but could not be read, which is a degradation
|
|
54
|
+
* worth naming rather than folding into "absent".
|
|
55
|
+
*/
|
|
56
|
+
export async function resolveQbdLedgerDirDetailed(cwd, homeDir) {
|
|
57
|
+
try {
|
|
58
|
+
// Lazy, like every sibling command module: a top-level import here is on the
|
|
59
|
+
// CLI's cold-start path for every invocation, including ones that never
|
|
60
|
+
// touch this seam.
|
|
61
|
+
const path = await import('node:path');
|
|
62
|
+
const { isGlobalConfigPath, loadConfig, resolveConfigPath } = await import('../utils.js');
|
|
63
|
+
// `homeDir` is threaded through so tests can point the global-profile lookup
|
|
64
|
+
// at a temp home. Without it, a test running in a directory with no config
|
|
65
|
+
// resolves the DEVELOPER'S REAL `~/.totem/` profile and writes telemetry
|
|
66
|
+
// into their live ledger — which is exactly what happened: this suite wrote
|
|
67
|
+
// real derive rows into the maintainer's global ledger on every run.
|
|
68
|
+
const configPath = resolveConfigPath(cwd, homeDir);
|
|
69
|
+
const config = await loadConfig(configPath);
|
|
70
|
+
const global = isGlobalConfigPath(configPath, homeDir);
|
|
71
|
+
// configRoot, NOT cwd — see the header. Mirrors the sibling ledger writes.
|
|
72
|
+
return { dir: path.join(path.dirname(configPath), config.totemDir), global };
|
|
73
|
+
// totem-context: intentional cleanup — a sensor must not fail the command it instruments (Tenet 13); the reason is returned to the caller and surfaced, never discarded.
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
// totem-context: intentional cleanup — a sensor must not fail the command it instruments (Tenet 13); the reason is returned to the caller and surfaced, never discarded.
|
|
77
|
+
const code = typeof err === 'object' && err !== null && 'code' in err
|
|
78
|
+
? err.code
|
|
79
|
+
: undefined;
|
|
80
|
+
if (code === 'CONFIG_MISSING') {
|
|
81
|
+
return { reason: 'no Totem config found — not a project, nothing to instrument' };
|
|
82
|
+
}
|
|
83
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
84
|
+
return { reason: `Totem config could not be loaded (${msg})` };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Record a derive-class action from a CLI command.
|
|
89
|
+
*
|
|
90
|
+
* Never throws, never fails the instrumented command. Returns a note whenever
|
|
91
|
+
* nothing was recorded, so the caller can surface it — a sensor that quietly
|
|
92
|
+
* declines to measure is indistinguishable from one measuring zero, which is
|
|
93
|
+
* the ADR-115 § 2 defect class.
|
|
94
|
+
*/
|
|
95
|
+
/**
|
|
96
|
+
* Landing in the global profile is legitimate but must never be silent: the
|
|
97
|
+
* row goes somewhere other than the project the user is looking at, and a
|
|
98
|
+
* reader comparing `doctor --compliance` in the project against these rows
|
|
99
|
+
* would otherwise see an unexplained gap.
|
|
100
|
+
*/
|
|
101
|
+
function globalNote(totemDir) {
|
|
102
|
+
return `query-before-derive: recorded to the global profile ledger at ${totemDir} — no project config found from this cwd`;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The one resolve-then-record body both public seams share.
|
|
106
|
+
*
|
|
107
|
+
* The two used to carry six duplicated statements and three byte-identical note
|
|
108
|
+
* strings. Those strings are load-bearing — the doctor render and the tests
|
|
109
|
+
* match on them — so a reworded note had to be changed in two places or the
|
|
110
|
+
* surfaces silently drifted apart. Single-sourced here.
|
|
111
|
+
*
|
|
112
|
+
* `sense` is the only real difference: which core writer runs.
|
|
113
|
+
*/
|
|
114
|
+
async function recordThrough(cwd, homeDir, sense) {
|
|
115
|
+
const { dir: totemDir, reason, global } = await resolveQbdLedgerDirDetailed(cwd, homeDir);
|
|
116
|
+
if (totemDir === undefined) {
|
|
117
|
+
return {
|
|
118
|
+
recorded: false,
|
|
119
|
+
note: `query-before-derive: ${reason ?? 'unresolved'} — not recording`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const result = sense(totemDir);
|
|
123
|
+
if (result.skipped === true) {
|
|
124
|
+
return {
|
|
125
|
+
recorded: false,
|
|
126
|
+
note: `query-before-derive: no ledger at ${totemDir} — not recording`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return { recorded: result.written, ...(global === true && { note: globalNote(totemDir) }) };
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Record a derive-class action from a CLI command.
|
|
133
|
+
*
|
|
134
|
+
* Never throws, never fails the instrumented command. Returns a note whenever
|
|
135
|
+
* nothing was recorded, so the caller can surface it — a sensor that quietly
|
|
136
|
+
* declines to measure is indistinguishable from one measuring zero, which is
|
|
137
|
+
* the ADR-115 § 2 defect class.
|
|
138
|
+
*/
|
|
139
|
+
export async function recordQbdDerive(cwd, surface, onWarn, homeDir) {
|
|
140
|
+
const { senseDeriveAction } = await import('@mmnto/totem');
|
|
141
|
+
return recordThrough(cwd, homeDir, (totemDir) => senseDeriveAction({ totemDir, source: 'lint', surface }, onWarn));
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Record a corpus query from a CLI command. Same contract as `recordQbdDerive`.
|
|
145
|
+
*/
|
|
146
|
+
export async function recordQbdQuery(cwd, onWarn, homeDir) {
|
|
147
|
+
const { senseCorpusQuery } = await import('@mmnto/totem');
|
|
148
|
+
return recordThrough(cwd, homeDir, (totemDir) => senseCorpusQuery({ totemDir, source: 'lint', surface: 'totem_search' }, onWarn));
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=qbd-seam.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qbd-seam.js","sourceRoot":"","sources":["../../src/commands/qbd-seam.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seam-resolution tests for the query-before-derive instrumentation
|
|
3
|
+
* (mmnto-ai/totem#2510).
|
|
4
|
+
*
|
|
5
|
+
* ## Test isolation is load-bearing here, not hygiene
|
|
6
|
+
*
|
|
7
|
+
* Every test passes an explicit temp `homeDir`. `resolveConfigPath` falls back
|
|
8
|
+
* to the global `~/.totem/` profile when the cwd has no config, so a test that
|
|
9
|
+
* omits it resolves the DEVELOPER'S REAL profile — and on a machine whose
|
|
10
|
+
* global config sets `totemDir: '.'`, the writer then appends real derive rows
|
|
11
|
+
* to their live `~/.totem/ledger/events.ndjson`. An earlier version of this
|
|
12
|
+
* file did exactly that on every suite run. No test here may be *able* to reach
|
|
13
|
+
* the real profile.
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=qbd-seam.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qbd-seam.test.d.ts","sourceRoot":"","sources":["../../src/commands/qbd-seam.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seam-resolution tests for the query-before-derive instrumentation
|
|
3
|
+
* (mmnto-ai/totem#2510).
|
|
4
|
+
*
|
|
5
|
+
* ## Test isolation is load-bearing here, not hygiene
|
|
6
|
+
*
|
|
7
|
+
* Every test passes an explicit temp `homeDir`. `resolveConfigPath` falls back
|
|
8
|
+
* to the global `~/.totem/` profile when the cwd has no config, so a test that
|
|
9
|
+
* omits it resolves the DEVELOPER'S REAL profile — and on a machine whose
|
|
10
|
+
* global config sets `totemDir: '.'`, the writer then appends real derive rows
|
|
11
|
+
* to their live `~/.totem/ledger/events.ndjson`. An earlier version of this
|
|
12
|
+
* file did exactly that on every suite run. No test here may be *able* to reach
|
|
13
|
+
* the real profile.
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from 'node:fs';
|
|
16
|
+
import * as os from 'node:os';
|
|
17
|
+
import * as path from 'node:path';
|
|
18
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
19
|
+
import { cleanTmpDir } from '../test-utils.js';
|
|
20
|
+
import { recordQbdDerive, recordQbdQuery, resolveQbdLedgerDirDetailed } from './qbd-seam.js';
|
|
21
|
+
/** A minimal VALID config — `targets` requires at least one entry. */
|
|
22
|
+
const TOTEM_YAML = [
|
|
23
|
+
'targets:',
|
|
24
|
+
' - glob: "src/**/*.ts"',
|
|
25
|
+
' type: code',
|
|
26
|
+
' strategy: file',
|
|
27
|
+
'',
|
|
28
|
+
].join('\n');
|
|
29
|
+
let projectRoot;
|
|
30
|
+
/** A temp home with NO global profile — the "no config anywhere" case. */
|
|
31
|
+
let emptyHome;
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
projectRoot = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'totem-qbd-seam-')));
|
|
34
|
+
fs.writeFileSync(path.join(projectRoot, 'totem.yaml'), TOTEM_YAML, 'utf-8');
|
|
35
|
+
fs.mkdirSync(path.join(projectRoot, '.totem'), { recursive: true });
|
|
36
|
+
emptyHome = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'totem-qbd-home-')));
|
|
37
|
+
});
|
|
38
|
+
afterEach(() => {
|
|
39
|
+
cleanTmpDir(projectRoot);
|
|
40
|
+
cleanTmpDir(emptyHome);
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* Build a temp home that DOES carry a global profile.
|
|
44
|
+
*
|
|
45
|
+
* `totemDir: '.'` mirrors the real-world shape (it is what this machine's
|
|
46
|
+
* `~/.totem/totem.config.ts` sets), so the profile's ledger lives at
|
|
47
|
+
* `<home>/.totem/ledger/` — the layout the silent-landing finding was about.
|
|
48
|
+
*/
|
|
49
|
+
function homeWithGlobalProfile() {
|
|
50
|
+
const home = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'totem-qbd-ghome-')));
|
|
51
|
+
const globalDir = path.join(home, '.totem');
|
|
52
|
+
fs.mkdirSync(globalDir, { recursive: true });
|
|
53
|
+
fs.writeFileSync(path.join(globalDir, 'totem.yaml'), `totemDir: "."\n${TOTEM_YAML}`, 'utf-8');
|
|
54
|
+
return home;
|
|
55
|
+
}
|
|
56
|
+
/** Where a `homeWithGlobalProfile` home keeps its ledger. */
|
|
57
|
+
function globalTotemDir(home) {
|
|
58
|
+
return path.join(home, '.totem');
|
|
59
|
+
}
|
|
60
|
+
function ledgerRows(totemDir) {
|
|
61
|
+
const file = path.join(totemDir, 'ledger', 'events.ndjson');
|
|
62
|
+
if (!fs.existsSync(file))
|
|
63
|
+
return [];
|
|
64
|
+
return fs
|
|
65
|
+
.readFileSync(file, 'utf-8')
|
|
66
|
+
.split('\n')
|
|
67
|
+
.filter((l) => l.trim().length > 0)
|
|
68
|
+
.map((l) => JSON.parse(l));
|
|
69
|
+
}
|
|
70
|
+
describe('resolveQbdLedgerDirDetailed', () => {
|
|
71
|
+
it('resolves from the config root', async () => {
|
|
72
|
+
const detailed = await resolveQbdLedgerDirDetailed(projectRoot, emptyHome);
|
|
73
|
+
expect(detailed.reason ?? 'resolved').toBe('resolved');
|
|
74
|
+
expect(detailed.dir).toBe(path.join(projectRoot, '.totem'));
|
|
75
|
+
expect(detailed.global).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
it('resolves a cwd that is NOT the config root to the CONFIG ROOT ledger', async () => {
|
|
78
|
+
// The discriminating case. From a subdirectory with a global profile in
|
|
79
|
+
// play, the old `path.join(cwd, config.totemDir)` would answer
|
|
80
|
+
// `<subdir>/.totem`; the correct answer is the resolved config's own root.
|
|
81
|
+
// At the project root the two agree, which is why a root-only assertion
|
|
82
|
+
// proves nothing about the bug it is supposed to pin.
|
|
83
|
+
const home = homeWithGlobalProfile();
|
|
84
|
+
try {
|
|
85
|
+
const subdir = path.join(projectRoot, 'packages', 'thing');
|
|
86
|
+
fs.mkdirSync(subdir, { recursive: true });
|
|
87
|
+
const detailed = await resolveQbdLedgerDirDetailed(subdir, home);
|
|
88
|
+
// What the old cwd-joined logic would have answered, computed from the
|
|
89
|
+
// SAME `totemDir` this fixture's profile sets (`.`) — so it is `subdir`
|
|
90
|
+
// itself, not `subdir/.totem`. Hard-coding `.totem` here made the
|
|
91
|
+
// assertion pass under both implementations, i.e. pinned nothing.
|
|
92
|
+
const oldBuggyAnswer = path.join(subdir, '.');
|
|
93
|
+
expect(detailed.dir).toBeDefined();
|
|
94
|
+
expect(detailed.dir).not.toBe(oldBuggyAnswer);
|
|
95
|
+
expect(detailed.dir).toBe(globalTotemDir(home));
|
|
96
|
+
expect(detailed.global).toBe(true);
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
cleanTmpDir(home);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
it('gives two different cwds under one config root the SAME ledger dir', async () => {
|
|
103
|
+
const home = homeWithGlobalProfile();
|
|
104
|
+
try {
|
|
105
|
+
const a = path.join(projectRoot, 'packages', 'alpha');
|
|
106
|
+
const b = path.join(projectRoot, 'docs', 'deep', 'nested');
|
|
107
|
+
fs.mkdirSync(a, { recursive: true });
|
|
108
|
+
fs.mkdirSync(b, { recursive: true });
|
|
109
|
+
const fromA = await resolveQbdLedgerDirDetailed(a, home);
|
|
110
|
+
const fromB = await resolveQbdLedgerDirDetailed(b, home);
|
|
111
|
+
// Resolution is a function of the resolved config root, so two cwds that
|
|
112
|
+
// resolve the same config cannot disagree about where rows land. Under
|
|
113
|
+
// the old cwd-joined logic these two answers differed.
|
|
114
|
+
expect(fromA.dir).toBe(fromB.dir);
|
|
115
|
+
expect(fromA.dir).not.toBe(path.join(a, '.totem'));
|
|
116
|
+
expect(fromB.dir).not.toBe(path.join(b, '.totem'));
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
cleanTmpDir(home);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
it('reports CONFIG_MISSING when neither cwd nor home carries a config', async () => {
|
|
123
|
+
const orphan = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'totem-qbd-orphan-')));
|
|
124
|
+
try {
|
|
125
|
+
const detailed = await resolveQbdLedgerDirDetailed(orphan, emptyHome);
|
|
126
|
+
expect(detailed.dir).toBeUndefined();
|
|
127
|
+
expect(detailed.reason).toContain('no Totem config found');
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
cleanTmpDir(orphan);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe('recordQbdDerive', () => {
|
|
135
|
+
it('records into the project ledger when run from the project root', async () => {
|
|
136
|
+
const report = await recordQbdDerive(projectRoot, 'review', () => { }, emptyHome);
|
|
137
|
+
expect(report.recorded).toBe(true);
|
|
138
|
+
expect(report.note).toBeUndefined();
|
|
139
|
+
const rows = ledgerRows(path.join(projectRoot, '.totem'));
|
|
140
|
+
expect(rows).toHaveLength(1);
|
|
141
|
+
expect(rows[0].type).toBe('derive_action');
|
|
142
|
+
expect(rows[0].activity_name).toBe('review');
|
|
143
|
+
});
|
|
144
|
+
it('never creates a stray ledger under a subdirectory', async () => {
|
|
145
|
+
const subdir = path.join(projectRoot, 'packages', 'thing');
|
|
146
|
+
fs.mkdirSync(subdir, { recursive: true });
|
|
147
|
+
const report = await recordQbdDerive(subdir, 'spec', () => { }, emptyHome);
|
|
148
|
+
expect(fs.existsSync(path.join(subdir, '.totem'))).toBe(false);
|
|
149
|
+
if (!report.recorded)
|
|
150
|
+
expect(report.note).toBeDefined();
|
|
151
|
+
});
|
|
152
|
+
it('ANNOUNCES a landing in the global profile instead of doing it silently', async () => {
|
|
153
|
+
// Legitimate, but the row goes somewhere other than the project the user is
|
|
154
|
+
// looking at — so it must say so. This was the silent half of the finding.
|
|
155
|
+
const home = homeWithGlobalProfile();
|
|
156
|
+
const orphan = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'totem-qbd-orphan-')));
|
|
157
|
+
try {
|
|
158
|
+
const report = await recordQbdDerive(orphan, 'orient', () => { }, home);
|
|
159
|
+
expect(report.recorded).toBe(true);
|
|
160
|
+
expect(report.note).toBeDefined();
|
|
161
|
+
expect(report.note).toContain('global profile ledger');
|
|
162
|
+
// And it landed in the global profile's ledger, not the orphan cwd.
|
|
163
|
+
expect(ledgerRows(globalTotemDir(home))).toHaveLength(1);
|
|
164
|
+
expect(fs.existsSync(path.join(orphan, '.totem'))).toBe(false);
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
cleanTmpDir(orphan);
|
|
168
|
+
cleanTmpDir(home);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
it('never no-ops silently when there is no project at all', async () => {
|
|
172
|
+
const orphan = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'totem-qbd-orphan-')));
|
|
173
|
+
try {
|
|
174
|
+
const report = await recordQbdDerive(orphan, 'orient', () => { }, emptyHome);
|
|
175
|
+
expect(report.recorded).toBe(false);
|
|
176
|
+
expect(report.note).toContain('query-before-derive');
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
cleanTmpDir(orphan);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
describe('recordQbdQuery', () => {
|
|
184
|
+
it('writes a corpus_query row carrying a correlation ID into the project ledger', async () => {
|
|
185
|
+
const report = await recordQbdQuery(projectRoot, () => { }, emptyHome);
|
|
186
|
+
expect(report.recorded).toBe(true);
|
|
187
|
+
const rows = ledgerRows(path.join(projectRoot, '.totem'));
|
|
188
|
+
expect(rows).toHaveLength(1);
|
|
189
|
+
expect(rows[0].type).toBe('corpus_query');
|
|
190
|
+
expect(rows[0].activity_name).toBe('totem_search');
|
|
191
|
+
expect(typeof rows[0].qbd_correlation_id).toBe('string');
|
|
192
|
+
});
|
|
193
|
+
it('shares the derive seam’s not-recording contract', async () => {
|
|
194
|
+
// Both seams route through one internal body, so the note strings cannot
|
|
195
|
+
// drift apart — this pins that they really are the same contract.
|
|
196
|
+
const orphan = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'totem-qbd-orphan-')));
|
|
197
|
+
try {
|
|
198
|
+
const queryReport = await recordQbdQuery(orphan, () => { }, emptyHome);
|
|
199
|
+
const deriveReport = await recordQbdDerive(orphan, 'orient', () => { }, emptyHome);
|
|
200
|
+
expect(queryReport.recorded).toBe(false);
|
|
201
|
+
expect(queryReport.note).toBe(deriveReport.note);
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
cleanTmpDir(orphan);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
describe('review seam placement', () => {
|
|
209
|
+
/**
|
|
210
|
+
* Source pin, and an honest account of why it is one.
|
|
211
|
+
*
|
|
212
|
+
* `handleVerdictResult` is module-private and `shieldCommand` needs the
|
|
213
|
+
* orchestrator, the Lance index, git, and the exemption store before it
|
|
214
|
+
* reaches a verdict, so driving the structural branch executably is not
|
|
215
|
+
* feasible at unit scope. The previous version of this test was worse than
|
|
216
|
+
* useless: it indexed the IMPORT of `recordQbdDerive` rather than the call,
|
|
217
|
+
* never read the enclosing control flow, and would have passed after a
|
|
218
|
+
* comment edit.
|
|
219
|
+
*
|
|
220
|
+
* This one anchors to the CALL EXPRESSION inside the enclosing function body.
|
|
221
|
+
* Mutations it catches: moving the record call out of `handleVerdictResult`
|
|
222
|
+
* (structural and standard would both stop recording); deleting the fan's own
|
|
223
|
+
* call (the fan path would stop recording); the structural branch no longer
|
|
224
|
+
* routing through the shared handler before it returns.
|
|
225
|
+
*
|
|
226
|
+
* Mutations it does NOT catch, stated so the pin is not read as stronger than
|
|
227
|
+
* it is: reordering within the handler; a call that is present but
|
|
228
|
+
* unreachable; and — because these are substring matches, not parsed
|
|
229
|
+
* statements — a *comment* mentioning `recordQbdDerive(` would satisfy them
|
|
230
|
+
* just as well as the real call. Accepted, because the alternative at unit
|
|
231
|
+
* scope is no coverage at all, and building an AST harness for one call site
|
|
232
|
+
* is machinery this slice does not need.
|
|
233
|
+
*/
|
|
234
|
+
const source = fs.readFileSync(path.join(__dirname, 'shield.ts'), 'utf-8');
|
|
235
|
+
/** Slice out one top-level function body by declaration name. */
|
|
236
|
+
function functionBody(name) {
|
|
237
|
+
const start = source.indexOf(`async function ${name}(`);
|
|
238
|
+
expect(start, `${name} should exist`).toBeGreaterThan(-1);
|
|
239
|
+
const rest = source.slice(start + 1);
|
|
240
|
+
const end = rest.search(/\n(?:export )?(?:async )?function /);
|
|
241
|
+
return end === -1 ? rest : rest.slice(0, end);
|
|
242
|
+
}
|
|
243
|
+
it('records the derive INSIDE the shared verdict handler', () => {
|
|
244
|
+
// Structural and standard both route through this function, so a call here
|
|
245
|
+
// fires exactly once per review and only after a verdict exists.
|
|
246
|
+
const body = functionBody('handleVerdictResult');
|
|
247
|
+
expect(body).toContain('recordQbdDerive(');
|
|
248
|
+
});
|
|
249
|
+
it('records only AFTER a verdict has parsed — never for --raw or unparsable', () => {
|
|
250
|
+
// The recording used to be the handler's first statement, which put it
|
|
251
|
+
// ahead of BOTH `if (options.raw) return` and the unparsable-verdict throw:
|
|
252
|
+
// a raw context dump recorded a derive (and could consume a query's
|
|
253
|
+
// grounding), and so did a run whose verdict never parsed.
|
|
254
|
+
//
|
|
255
|
+
// The invariant is positional, so pin it positionally: the record call must
|
|
256
|
+
// sit after the raw exit AND after the point where a verdict is parsed.
|
|
257
|
+
const body = functionBody('handleVerdictResult');
|
|
258
|
+
const rawExitIdx = body.indexOf('if (options.raw) return;');
|
|
259
|
+
const laneDeriveIdx = body.indexOf('deriveLaneOutcome(');
|
|
260
|
+
const structuralBranchIdx = body.indexOf('if (outcome.structuredVerdict)');
|
|
261
|
+
const v1BranchIdx = body.indexOf('const verdict = parseVerdict(content);');
|
|
262
|
+
const firstRecordIdx = body.indexOf('await recordReviewDerive()');
|
|
263
|
+
expect(rawExitIdx).toBeGreaterThan(-1);
|
|
264
|
+
expect(laneDeriveIdx).toBeGreaterThan(-1);
|
|
265
|
+
expect(firstRecordIdx).toBeGreaterThan(-1);
|
|
266
|
+
// After the raw exit: `--raw` returns before any record can fire.
|
|
267
|
+
expect(firstRecordIdx).toBeGreaterThan(rawExitIdx);
|
|
268
|
+
// After the verdict is derived: nothing records before parsing is attempted.
|
|
269
|
+
expect(firstRecordIdx).toBeGreaterThan(laneDeriveIdx);
|
|
270
|
+
// And the call sites are the two PARSED-verdict branches, not the body.
|
|
271
|
+
expect(firstRecordIdx).toBeGreaterThan(structuralBranchIdx);
|
|
272
|
+
expect(body.indexOf('await recordReviewDerive()', v1BranchIdx)).toBeGreaterThan(v1BranchIdx);
|
|
273
|
+
});
|
|
274
|
+
it('records on a FAIL verdict too — a failing review is a completed derive', () => {
|
|
275
|
+
// Excluding FAIL would shrink the denominator, which is the falsifier-1
|
|
276
|
+
// failure mode. The record sits at the TOP of the structured branch, ahead
|
|
277
|
+
// of the pass/fail split and ahead of the SHIELD_FAILED throw.
|
|
278
|
+
const body = functionBody('handleVerdictResult');
|
|
279
|
+
const recordIdx = body.indexOf('await recordReviewDerive()');
|
|
280
|
+
const failThrowIdx = body.indexOf("'SHIELD_FAILED'");
|
|
281
|
+
expect(failThrowIdx).toBeGreaterThan(-1);
|
|
282
|
+
expect(recordIdx).toBeLessThan(failThrowIdx);
|
|
283
|
+
});
|
|
284
|
+
it('routes the structural branch through that shared handler before returning', () => {
|
|
285
|
+
const body = functionBody('shieldCommand');
|
|
286
|
+
const structuralIdx = body.indexOf("options.mode === 'structural'");
|
|
287
|
+
expect(structuralIdx).toBeGreaterThan(-1);
|
|
288
|
+
const afterStructural = body.slice(structuralIdx);
|
|
289
|
+
const handlerIdx = afterStructural.indexOf('handleVerdictResult(');
|
|
290
|
+
const returnIdx = afterStructural.indexOf('\n return;');
|
|
291
|
+
expect(handlerIdx).toBeGreaterThan(-1);
|
|
292
|
+
expect(returnIdx).toBeGreaterThan(-1);
|
|
293
|
+
expect(handlerIdx).toBeLessThan(returnIdx);
|
|
294
|
+
});
|
|
295
|
+
it('does NOT record the fan derive at the runReviewFan call site', () => {
|
|
296
|
+
// The call site is unreachable for the two exit-policy paths: a
|
|
297
|
+
// zero-completed-lane round and a `--fail-on` failure both PERSIST an honest
|
|
298
|
+
// verdict and only then throw, so a record placed after the call skipped
|
|
299
|
+
// exactly those reviews — completed derives escaping the denominator, with
|
|
300
|
+
// the query correlation left consumable by a later derive.
|
|
301
|
+
const body = functionBody('shieldCommand');
|
|
302
|
+
const fanIdx = body.indexOf('runReviewFan(');
|
|
303
|
+
expect(fanIdx).toBeGreaterThan(-1);
|
|
304
|
+
// Between the fan call and the branch's `return`, nothing records.
|
|
305
|
+
const afterFan = body.slice(fanIdx);
|
|
306
|
+
const returnIdx = afterFan.indexOf('\n return;');
|
|
307
|
+
expect(returnIdx).toBeGreaterThan(-1);
|
|
308
|
+
expect(afterFan.slice(0, returnIdx)).not.toContain('await recordQbdDerive(');
|
|
309
|
+
});
|
|
310
|
+
it('writes the fan derive to the SAME totemDir the artifact was saved into', () => {
|
|
311
|
+
// Not re-resolved from cwd: a cwd with no local config falls back to the
|
|
312
|
+
// user's global `~/.totem/` profile, which appended real rows to the
|
|
313
|
+
// maintainer's live ledger during this package's tests. The artifact's own
|
|
314
|
+
// directory is both authoritative and incapable of wandering.
|
|
315
|
+
expect(fanSource).toContain('senseDeriveAction({ totemDir: ctx.totemDirAbs');
|
|
316
|
+
});
|
|
317
|
+
const fanSource = fs.readFileSync(path.join(__dirname, 'review-fan.ts'), 'utf-8');
|
|
318
|
+
it('records the fan derive the instant the verdict artifact is PERSISTED', () => {
|
|
319
|
+
// Persisted verdict ⇔ recorded derive. Ordering is the invariant, so it is
|
|
320
|
+
// pinned by ordering: the record must sit after the save and before both
|
|
321
|
+
// exit-policy throws.
|
|
322
|
+
const saveIdx = fanSource.indexOf('saveVerdictArtifact(ctx.totemDirAbs, verdict)');
|
|
323
|
+
const recordIdx = fanSource.indexOf('senseDeriveAction({ totemDir: ctx.totemDirAbs');
|
|
324
|
+
const zeroLaneThrowIdx = fanSource.indexOf('hasNoCompletedLane(verdict.lanes)');
|
|
325
|
+
const failOnIdx = fanSource.indexOf('const failOn = ctx.options.failOn;');
|
|
326
|
+
expect(saveIdx).toBeGreaterThan(-1);
|
|
327
|
+
expect(recordIdx).toBeGreaterThan(-1);
|
|
328
|
+
expect(zeroLaneThrowIdx).toBeGreaterThan(-1);
|
|
329
|
+
expect(failOnIdx).toBeGreaterThan(-1);
|
|
330
|
+
// After persistence: a fan that throws BEFORE writing an artifact records
|
|
331
|
+
// nothing, which keeps the other half of the invariant true.
|
|
332
|
+
expect(recordIdx).toBeGreaterThan(saveIdx);
|
|
333
|
+
// Before both exit-policy throws: a persisted-then-policy-throw round is a
|
|
334
|
+
// completed derive and still records.
|
|
335
|
+
expect(recordIdx).toBeLessThan(zeroLaneThrowIdx);
|
|
336
|
+
expect(recordIdx).toBeLessThan(failOnIdx);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
//# sourceMappingURL=qbd-seam.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qbd-seam.test.js","sourceRoot":"","sources":["../../src/commands/qbd-seam.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-fan.d.ts","sourceRoot":"","sources":["../../src/commands/review-fan.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"review-fan.d.ts","sourceRoot":"","sources":["../../src/commands/review-fan.ts"],"names":[],"mappings":"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"}
|
|
@@ -984,6 +984,32 @@ export async function runReviewFan(ctx) {
|
|
|
984
984
|
// The saved hash IS the content address (dedup-safe: an identical round returns
|
|
985
985
|
// the existing address).
|
|
986
986
|
const verdictHash = saveVerdictArtifact(ctx.totemDirAbs, verdict).hash;
|
|
987
|
+
// Query-before-derive instrumentation (mmnto-ai/totem#2510): the fan's derive
|
|
988
|
+
// is recorded HERE — the instant the verdict artifact is on disk — and not at
|
|
989
|
+
// the `runReviewFan` call site in `shield.ts`.
|
|
990
|
+
//
|
|
991
|
+
// The call site is unreachable for the two exit-policy paths below: a
|
|
992
|
+
// zero-completed-lane round and a `--fail-on` failure both PERSIST an honest
|
|
993
|
+
// verdict (including `settled=false` states, which `totem review --covariate`
|
|
994
|
+
// reads back) and only then throw. Recording after the call therefore skipped
|
|
995
|
+
// exactly those reviews — a completed derive escaping the denominator, and
|
|
996
|
+
// worse, leaving the query's correlation still consumable by a later derive.
|
|
997
|
+
//
|
|
998
|
+
// Placement keeps the other half true by construction: a fan that throws
|
|
999
|
+
// BEFORE reaching this line — a lane-assembly or invocation failure, with no
|
|
1000
|
+
// artifact written — records nothing. Persisted verdict ⇔ recorded derive.
|
|
1001
|
+
//
|
|
1002
|
+
// Writes to `ctx.totemDirAbs` — the very directory the artifact above was
|
|
1003
|
+
// saved into — rather than re-resolving from `ctx.cwd` through the seam
|
|
1004
|
+
// helper. Two reasons, one correctness and one safety: the derive row belongs
|
|
1005
|
+
// in the same ledger as the verdict it accompanies, and re-resolving from a
|
|
1006
|
+
// cwd with no local config would fall back to the user's global `~/.totem/`
|
|
1007
|
+
// profile. Routing through the helper here did exactly that, appending real
|
|
1008
|
+
// rows to the maintainer's live ledger during this package's tests.
|
|
1009
|
+
{
|
|
1010
|
+
const { senseDeriveAction } = await import('@mmnto/totem');
|
|
1011
|
+
senseDeriveAction({ totemDir: ctx.totemDirAbs, source: 'lint', surface: 'review' }, (msg) => log.warn(DISPLAY_TAG, msg));
|
|
1012
|
+
}
|
|
987
1013
|
// ── ZERO completed verdict lanes (Gate G3, mmnto-ai/totem#2452): the honest verdict
|
|
988
1014
|
// is now WRITTEN — hard-error ──
|
|
989
1015
|
// Keyed on `hasNoCompletedLane` (⇔ `verdict.completedLaneCount === 0`, superRefine-bound):
|