@jwilger/pi-development-system 0.3.6 → 0.3.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jwilger/pi-development-system",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "A pi extension package representing a seasoned approach to software development using a full AI SDLC.",
5
5
  "keywords": [
6
6
  "pi-package"
@@ -70,6 +70,35 @@ const RISKY_ADDITION = /\/\*|<!--|=begin\b|"""|'''|\breturn\b|\bthrow\b|\bexit\b
70
70
 
71
71
  const GLOB = /[*?[\]{]/;
72
72
 
73
+ const NO_SIGNALS: WeakeningSignals = { addsSkip: false, emptied: false, commentedOut: false };
74
+
75
+ /** Adding lines never weakens a test unless an added line itself disables something. */
76
+ const isHarmlessAddition = (before: string, after: string, signals: WeakeningSignals): boolean =>
77
+ !signals.addsSkip &&
78
+ !signals.commentedOut &&
79
+ isPureAddition(before, after) &&
80
+ !addedLines(before, after).some((line) => RISKY_ADDITION.test(line));
81
+
82
+ /** Jev's reading of a change, or `undefined` when it sees nothing to act on. */
83
+ function jevVerdict(
84
+ judged: { weakens: number; motive: string },
85
+ deterministicSignal: boolean,
86
+ ): Verdict | undefined {
87
+ const weakening = judged.weakens >= WEAKENS_THRESHOLD;
88
+ if ((weakening || deterministicSignal) && judged.motive === "gate-gaming") {
89
+ return {
90
+ kind: "hard-stop",
91
+ why: "Jev reads this change as weakening a check to get a green result",
92
+ };
93
+ }
94
+ return weakening
95
+ ? {
96
+ kind: "require-departure",
97
+ why: `Jev reads this change as weakening the tests (motive: ${judged.motive})`,
98
+ }
99
+ : undefined;
100
+ }
101
+
73
102
  /**
74
103
  * Soft gate `tests.weaken`: deleting, skipping, emptying or loosening tests needs a recorded
75
104
  * departure; a change Jev reads as gaming a failing gate escalates to a hard stop.
@@ -106,41 +135,16 @@ export function registerTestGuard(deps: TestGuardDeps): void {
106
135
  const judge = async (change: Change, ctx: ExtensionContext): Promise<Verdict> => {
107
136
  const deleted = change.after === undefined && change.rewritten === undefined;
108
137
  const after = change.after ?? change.rewritten ?? "";
109
- const signals = deleted
110
- ? { addsSkip: false, emptied: false, commentedOut: false }
111
- : weakeningSignals(change.before, after);
112
- // Adding lines never weakens a test unless the added line itself is a skip marker.
113
- if (
114
- !deleted &&
115
- !signals.addsSkip &&
116
- !signals.commentedOut &&
117
- isPureAddition(change.before, after) &&
118
- !addedLines(change.before, after).some((line) => RISKY_ADDITION.test(line))
119
- ) {
120
- return { kind: "allow" };
121
- }
138
+ const signals = deleted ? NO_SIGNALS : weakeningSignals(change.before, after);
139
+ if (!deleted && isHarmlessAddition(change.before, after, signals)) return { kind: "allow" };
122
140
  const deterministic = describeSignals(deleted, signals);
123
141
  const judged = await judgeTestChange(deps.jev(ctx), {
124
142
  path: change.path,
125
143
  before: change.before,
126
144
  after: after === "" ? undefined : redactSecrets(after),
127
145
  });
128
- if (judged.ok) {
129
- const { weakens, motive } = judged.value;
130
- const weakening = weakens >= WEAKENS_THRESHOLD || deterministic !== undefined;
131
- if (weakening && motive === "gate-gaming") {
132
- return {
133
- kind: "hard-stop",
134
- why: "Jev reads this change as weakening a check to get a green result",
135
- };
136
- }
137
- if (weakens >= WEAKENS_THRESHOLD) {
138
- return {
139
- kind: "require-departure",
140
- why: `Jev reads this change as weakening the tests (motive: ${motive})`,
141
- };
142
- }
143
- }
146
+ const fromJev = judged.ok ? jevVerdict(judged.value, deterministic !== undefined) : undefined;
147
+ if (fromJev !== undefined) return fromJev;
144
148
  return deterministic !== undefined
145
149
  ? { kind: "require-departure", why: `this change ${deterministic}` }
146
150
  : { kind: "allow" };