candor-ts 0.26.0 → 0.28.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/surface.mjs CHANGED
@@ -213,7 +213,10 @@ export function bestFind(inferred, direct, calls, isTest = () => false) {
213
213
 
214
214
  // Emit the surface note to STDERR. `loc` is a Map<qual, "file:line"> for the source callout; `log` is
215
215
  // the sink (defaults to console.error). Mirrors surface.rs::emit exactly.
216
- export function emitSurface(inferred, direct, calls, loc, isTest = () => false, log = console.error) {
216
+ // `cause` (optional) lets the CALLER name why the graph is unresolved, because only the caller knows.
217
+ // See the qualification below: naming a cause the run can RULE OUT is the false-disclosure class this
218
+ // project treats as worse than saying nothing.
219
+ export function emitSurface(inferred, direct, calls, loc, isTest = () => false, log = console.error, cause = null) {
217
220
  const res = bestFind(inferred, direct, calls, isTest);
218
221
  // A real SURPRISING reach is a genuine finding — show it (below), even amid Unknowns.
219
222
  if (res !== null && res.winner !== null) { /* fall through to the surprising-reach message */ }
@@ -227,10 +230,20 @@ export function emitSurface(inferred, direct, calls, loc, isTest = () => false,
227
230
  const total = [...inferred.values()].filter((s) => s.size > 0).length; // EFFECTFUL fns (pure units excluded)
228
231
  const unknown = [...inferred.values()].filter((s) => s.has("Unknown")).length;
229
232
  if (total > 0 && unknown * 3 >= total) { // ≥ ~1/3 of effectful functions Unknown → meaningfully unresolved
233
+ // NAME THE CAUSE THAT APPLIES, not the usual one. This sentence used to end "a missing tsconfig.json
234
+ // or unresolvable imports are the usual cause" UNCONDITIONALLY — including on runs that had just
235
+ // found and used a tsconfig, and had already printed the real cause two lines above (the packages
236
+ // the classifier does not cover). Measured on a real Angular app: candor-ts reported 32 of 32
237
+ // functions Unknown and blamed a missing tsconfig while `tsconfig.json` sat in the project root and
238
+ // had been read. A disclosure that names a cause the run can rule out sends the operator to fix
239
+ // something that is not broken, and this family already treats that as worse than a missing one
240
+ // (`net-partner` was once reported "ignoring unknown config key" WHILE BEING HONOURED).
241
+ const why = cause
242
+ ?? "unresolvable imports are the usual cause";
230
243
  log(
231
244
  `candor: no surprising reaches — but ${unknown} of ${total} function(s) are Unknown `
232
245
  + `(unresolved calls; their transitive effects are NOT analyzed). Run \`candor blindspots\`; `
233
- + `a missing tsconfig.json or unresolvable imports are the usual cause.`,
246
+ + `${why}.`,
234
247
  );
235
248
  return;
236
249
  }