sourcecode 4.18.0__py3-none-any.whl → 5.0.0__py3-none-any.whl

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.

Potentially problematic release.


This version of sourcecode might be problematic. Click here for more details.

sourcecode/__init__.py CHANGED
@@ -4,4 +4,4 @@ ASK Engine is the product. ``ask`` is the canonical CLI command; ``sourcecode``
4
4
  the legacy compatibility alias and the Python/PyPI package name. See
5
5
  docs/PRODUCT_IDENTITY.md (normative)."""
6
6
 
7
- __version__ = "4.18.0"
7
+ __version__ = "5.0.0"
sourcecode/cache_model.py CHANGED
@@ -74,11 +74,11 @@ class CommandCache:
74
74
  cold_seconds: "Optional[float]" = None
75
75
  warm_seconds: "Optional[float]" = None
76
76
  #: The other measured point: this command on the field repository
77
- #: (3 342 Java files, Windows 11 / PowerShell 5.1 / pipx, cold), from field
78
- #: evaluations #13, #14 and #16. Seconds where a run finished; `field_blocked`
79
- #: where it did not — the harness promoted the process and the session died,
80
- #: which is a measurement of a different kind and is never written as a
81
- #: duration. Rows with neither were not attempted there.
77
+ #: (3 342 Java files, Windows 11 / PowerShell 5.1 / pipx, warm), from the
78
+ #: field evaluations. Seconds where a run finished; `field_blocked` where it
79
+ #: did not — the harness promoted the process and the session died, which is a
80
+ #: measurement of a different kind and is never written as a duration. Rows
81
+ #: with neither were not attempted there.
82
82
  #:
83
83
  #: C3-72: where two evaluations of the same command at this size disagree, the
84
84
  #: figure here is the **most recent** one, because it describes the build a
@@ -88,6 +88,17 @@ class CommandCache:
88
88
  #: measurement C3-76 exists for.
89
89
  field_seconds: "Optional[float]" = None
90
90
  field_blocked: bool = False
91
+ #: **C3-97.** The build the field figure was taken on. An anchor without one is
92
+ #: a measurement that can outlive its build and keep deciding: 4.18.0 deleted
93
+ #: two catastrophic-backtracking patterns (C3-95, C3-96) and every figure taken
94
+ #: before it describes a cost that no longer exists — `spring-audit` at 2 351 s
95
+ #: where the same command on the same commit of the same repository now takes
96
+ #: 8,4 s. Anchors older than the running build are still published, because a
97
+ #: measurement is worth more than silence; what changes is that they are
98
+ #: **labelled** with the build they belong to, so a reader can see the figure is
99
+ #: not this one's. `field_anchor_note()` renders that label and
100
+ #: `execution_plan` appends it to the `here:` line.
101
+ field_measured_version: "Optional[str]" = None
91
102
 
92
103
 
93
104
  #: Where every `measured` figure comes from.
@@ -109,26 +120,38 @@ REFERENCE_JAVA_FILES = 2000
109
120
  REFERENCE_MEASURED_VERSION = "3.2.2"
110
121
 
111
122
  #: The other end of the measured range, and the reason this module publishes a
112
- #: *class* rather than a projected duration (C4-19). Field evaluation #16, on
123
+ #: *class* rather than a projected duration (C4-19). Field evaluation #22, on
113
124
  #: Windows 11 / PowerShell 5.1 / pipx / Python 3.10: `spring-audit` on a
114
- #: 3 342-file repository ran **2 351 s** — 267× the 8.8 s the same command takes
115
- #: on the 2 000-file reference, for a repository 1,7× the size. Cost does not
116
- #: scale with file count in any way this product has measured, so a projected
117
- #: "~15 s on your repository" would be a confident falsehood of exactly the kind
118
- #: the ledger exists to prevent. What can be said honestly is the class, the two
119
- #: measured anchors, and how to run it.
125
+ #: 3 342-file repository ran **8,4 s** — the same command takes 8.8 s on the
126
+ #: 2 000-file reference, for a repository 1,7× the size.
120
127
  #:
121
- #: C3-72 replaced evaluation #13's 408 s with #16's 2 351 s here: the same command
122
- #: on the same repository at the same commit, measured three releases later
123
- #: (2 557 s in 4.10.6, 2 398 s in 4.10.7, 2 351 s in 4.11.0). The older figure was
124
- #: the one a budget message quoted as "~600s" for three releases while the
125
- #: measurement stood four times higher.
128
+ #: **The refusal to project stands, and this evaluation strengthened it** (C3-97).
129
+ #: For eight releases the pair of anchors said *cost does not track file count*;
130
+ #: what the series actually shows is that **cost tracks the build**. The identical
131
+ #: command on the identical commit of the identical repository measured 2 557 s
132
+ #: (4.10.6), 2 398 s (4.10.7), 2 351 s (4.11.0), 2 377 s (4.12.0), 1 371 s
133
+ #: (4.16.0) and 8,4 s (4.18.0) — a 280× move produced by deleting two
134
+ #: catastrophic-backtracking patterns (C3-95, C3-96), with every payload
135
+ #: byte-identical throughout. A projection would therefore have to predict our own
136
+ #: next release, which is the confident falsehood the ledger exists to prevent.
137
+ #: What can be said honestly is the class, the two measured anchors, **the build
138
+ #: each was measured on**, and how to run it.
139
+ #:
140
+ #: History of this constant, kept because it is the measurement C3-76 exists for:
141
+ #: 408 s (#13) → 2 351 s (#16, C3-72) → 8,4 s (#22, C3-97). The middle figure was
142
+ #: quoted as an operational anchor for four releases after the build that produced
143
+ #: it, and told operators to detach commands that finish in seconds.
126
144
  FIELD_ANCHOR = (
127
- "field evaluation #16: spring-audit on 3 342 Java files took 2 351 s "
145
+ "field evaluation #22: spring-audit on 3 342 Java files took 8.4 s "
128
146
  "(Windows, pipx, warm cache) against 8.8 s on the 2 000-file reference"
129
147
  )
130
148
  FIELD_ANCHOR_JAVA_FILES = 3342
131
- FIELD_ANCHOR_SECONDS = 2351.4
149
+ FIELD_ANCHOR_SECONDS = 8.4
150
+
151
+ #: The build the field anchors above were taken on. Rows carrying a different
152
+ #: `field_measured_version` are published with that build's name attached rather
153
+ #: than as figures for this one (C3-97).
154
+ FIELD_ANCHOR_MEASURED_VERSION = "4.18.0"
132
155
 
133
156
 
134
157
  #: Every layer keys on `cache.worktree_signature` — the exact tree state (C1-9).
@@ -196,12 +219,12 @@ COMMANDS: tuple[CommandCache, ...] = (
196
219
  "`--env-map`, `--depth N` and `--exclude` change the *analysis*, so they miss the "
197
220
  "warmed core and rescan — this is the 171 s the field measured after a 103 s warm.",
198
221
  "--compact 13.3 s cold → 0.3 s warm (cold re-measured on 3.7.0: was 19.3 s, C3-6); "
199
- "--agent --full --env-map --depth 20 34.7 s → 33.9 s (no gain)", analysis_class="repo-wide", cold_seconds=13.3, warm_seconds=0.3, field_seconds=115.0),
222
+ "--agent --full --env-map --depth 20 34.7 s → 33.9 s (no gain)", analysis_class="repo-wide", cold_seconds=13.3, warm_seconds=0.3, field_seconds=115.0, field_measured_version="4.10.4"),
200
223
  CommandCache("posture", ("cir", "parse"), "shared", False,
201
224
  "Resolves the conditional bean graph on every run, over the shared CIR a warm "
202
225
  "builds — the parse it used to repeat for itself. `--diff` compares two profile "
203
226
  "sets over that one IR, so the second side costs the resolution only.",
204
- "10.1 s → 1.6 s", analysis_class="repo-wide", cold_seconds=10.1, warm_seconds=1.6, field_seconds=38.0),
227
+ "10.1 s → 1.6 s", analysis_class="repo-wide", cold_seconds=10.1, warm_seconds=1.6, field_seconds=8.0, field_measured_version="4.18.0"),
205
228
  CommandCache("risk", ("cir", "parse"), "shared", False,
206
229
  "Composes what the audit, impact-chain and the posture already answer, so it "
207
230
  "pays each of their costs once over the shared CIR a warm builds — one parse "
@@ -209,7 +232,7 @@ COMMANDS: tuple[CommandCache, ...] = (
209
232
  "within the run.",
210
233
  "not measured on the battery yet — the composition is bounded by the "
211
234
  "`spring-audit` + `impact-chain` costs listed here, not by new analysis",
212
- analysis_class="deep", field_seconds=3232.2),
235
+ analysis_class="deep", field_seconds=73.3, field_measured_version="4.18.0"),
213
236
  CommandCache("enrich", ("cir", "parse"), "shared", False,
214
237
  "Runs the same composition as `risk` over the repository, then joins a SARIF "
215
238
  "log to it. Reading the log is negligible; everything a warm helps with is the "
@@ -239,25 +262,31 @@ COMMANDS: tuple[CommandCache, ...] = (
239
262
  "Recomputes the endpoint surface on every run, over a parse a warm has already "
240
263
  "paid for. Until 3.7.0 the extractor parsed every file itself instead of reading "
241
264
  "the shared parse cache, and a warm measurably bought it nothing (C3-6).",
242
- "3.3 s → 1.4 s (re-measured on 3.7.0; was 2.8 s → 2.9 s)", analysis_class="repo-wide", cold_seconds=3.3, warm_seconds=1.4, field_seconds=5.0),
265
+ "3.3 s → 1.4 s (re-measured on 3.7.0; was 2.8 s → 2.9 s)", analysis_class="repo-wide", cold_seconds=3.3, warm_seconds=1.4, field_seconds=3.8, field_measured_version="4.18.0"),
243
266
  CommandCache("spring-audit", ("ris", "parse"), "shared", False,
244
267
  "Recomputes every run, but over a parse a warm has already paid for.",
245
- "8.8 s → 3.7 s", analysis_class="repo-wide", cold_seconds=8.8, warm_seconds=3.7, field_seconds=2351.4),
268
+ "8.8 s → 3.7 s", analysis_class="repo-wide", cold_seconds=8.8, warm_seconds=3.7, field_seconds=8.4, field_measured_version="4.18.0"),
246
269
  CommandCache("migrate-check", ("cir",), "none", False,
247
270
  "Computes its own inventory and shares nothing a warm builds. Only `--blast-radius` "
248
271
  "reuses the shared CIR.",
249
- "4.8 s → 4.8 s", analysis_class="repo-wide", cold_seconds=4.8, warm_seconds=4.8, field_seconds=26.7),
272
+ "4.8 s → 4.8 s", analysis_class="repo-wide", cold_seconds=4.8, warm_seconds=4.8, field_seconds=10.2, field_measured_version="4.18.0"),
250
273
  CommandCache("impact-chain", ("cir", "parse"), "shared", False,
251
274
  "The CIR is the expensive half — this is where a warm pays most.",
252
- "9.9 s → 1.7 s", analysis_class="core", cold_seconds=9.9, warm_seconds=1.7),
253
- CommandCache("impact", ("parse",), "shared", False, "", "4.9 s → 2.8 s", analysis_class="core", cold_seconds=4.9, warm_seconds=2.8),
275
+ "9.9 s → 1.7 s", analysis_class="core", cold_seconds=9.9, warm_seconds=1.7,
276
+ field_seconds=5.5, field_measured_version="4.18.0"),
277
+ CommandCache("impact", ("parse",), "shared", False, "", "4.9 s → 2.8 s", analysis_class="core", cold_seconds=4.9, warm_seconds=2.8,
278
+ field_seconds=7.7, field_measured_version="4.18.0"),
254
279
  CommandCache("pr-impact", ("parse",), "shared", False,
255
- "Diff-dependent: the answer itself is never stored.", analysis_class="core"),
280
+ "Diff-dependent: the answer itself is never stored. What it costs follows the "
281
+ "diff, not the repository: 12,5 s on an ordinary one and 11,8 s on a diff of "
282
+ "security configuration, measured at field scale.", analysis_class="core",
283
+ field_seconds=12.5, field_measured_version="4.18.0"),
256
284
  CommandCache("verify", (), "none", False, "Runs the contracts against a fresh reading.", analysis_class="core"),
257
285
  CommandCache("verify-edit", ("parse",), "shared", True,
258
286
  "Built for the edit loop: the parse cache is what keeps an unchanged file out of the "
259
287
  "next run. Its own second run is faster again.",
260
- "14.6 s → 9.6 s → 5.6 s on repeat", analysis_class="repo-wide", cold_seconds=14.6, warm_seconds=9.6, field_blocked=True),
288
+ "14.6 s → 9.6 s → 5.6 s on repeat", analysis_class="repo-wide", cold_seconds=14.6, warm_seconds=9.6,
289
+ field_blocked=True, field_measured_version="4.10.4"),
261
290
  CommandCache("review-pr", ("cir",), "none", False,
262
291
  "Diff-dependent, and it reuses the CIR only if one exists. On a small diff, loading "
263
292
  "the warmed CIR costs more than the work it saves.",
@@ -286,11 +315,18 @@ COMMANDS: tuple[CommandCache, ...] = (
286
315
  "WITHOUT a warm, a second identical run: 10.2 s → 9.4 s (5 486 files) — "
287
316
  "no answer hit", analysis_class="repo-wide", cold_seconds=6.5, warm_seconds=0.3),
288
317
  CommandCache("explain", ("cir",), "shared", False, "Serves from the shared CIR a warm builds.",
289
- "9.8 s → 1.6 s", analysis_class="core", cold_seconds=9.8, warm_seconds=1.6),
318
+ "9.8 s → 1.6 s", analysis_class="core", cold_seconds=9.8, warm_seconds=1.6,
319
+ field_seconds=4.4, field_measured_version="4.18.0"),
290
320
  CommandCache("export", ("parse",), "shared", False, "", "8.8 s → 3.7 s", analysis_class="repo-wide", cold_seconds=8.8, warm_seconds=3.7),
291
- CommandCache("repo-ir", ("parse",), "shared", False, "", "5.1 s → 2.9 s", analysis_class="repo-wide", cold_seconds=5.1, warm_seconds=2.9, field_blocked=True),
292
- CommandCache("validation", ("parse",), "shared", False, "", "11.6 s → 6.4 s", analysis_class="repo-wide", cold_seconds=11.6, warm_seconds=6.4),
293
- CommandCache("modernize", ("parse",), "shared", False, "", "5.2 s → 3.0 s", analysis_class="repo-wide", cold_seconds=5.2, warm_seconds=3.0, field_blocked=True),
321
+ CommandCache("repo-ir", ("parse",), "shared", False, "", "5.1 s → 2.9 s", analysis_class="repo-wide", cold_seconds=5.1, warm_seconds=2.9,
322
+ field_blocked=True, field_measured_version="4.10.4"),
323
+ CommandCache("validation", ("parse",), "shared", False, "", "11.6 s → 6.4 s", analysis_class="repo-wide", cold_seconds=11.6, warm_seconds=6.4,
324
+ field_seconds=17.4, field_measured_version="4.18.0"),
325
+ CommandCache("modernize", ("parse",), "shared", False,
326
+ "Blocked in the session that recorded C3-53 and measured since: a run that did "
327
+ "not finish once is not a command that cannot finish.",
328
+ "5.2 s → 3.0 s", analysis_class="repo-wide", cold_seconds=5.2, warm_seconds=3.0,
329
+ field_seconds=9.1, field_measured_version="4.18.0"),
294
330
  CommandCache("chunk-file", (), "none", False, "Reads one file; nothing to cache.", analysis_class="core"),
295
331
  CommandCache("cold-start", ("ris",), "answer", True,
296
332
  "Reads the RIS a warm rebuilds — that is all it does. Without one it answers "
@@ -298,7 +334,7 @@ COMMANDS: tuple[CommandCache, ...] = (
298
334
  "0.2 s either way", analysis_class="core", cold_seconds=0.2, warm_seconds=0.2),
299
335
  CommandCache("trend", (), "none", False, "Reads stored baseline artifacts from disk; analyses no source, so no cache layer applies. Same command as `baseline trend`.", analysis_class="none"),
300
336
  CommandCache("baseline", ("parse",), "shared", False, "`capture`/`diff`/`trend` over architectural metrics.",
301
- "capture 8.7 s → 3.6 s", analysis_class="repo-wide", cold_seconds=8.7, warm_seconds=3.6, field_seconds=11.0),
337
+ "capture 8.7 s → 3.6 s", analysis_class="repo-wide", cold_seconds=8.7, warm_seconds=3.6, field_seconds=11.0, field_measured_version="4.10.4"),
302
338
  CommandCache("retrieve", ("cir", "parse"), "shared", False,
303
339
  "Every query builds or reuses the shared CIR a warm builds.", analysis_class="core"),
304
340
  CommandCache("archetype", ("parse",), "shared", False, "", "9.3 s → 5.6 s", analysis_class="repo-wide", cold_seconds=9.3, warm_seconds=5.6),
@@ -363,12 +399,102 @@ class Conditioning:
363
399
  return (
364
400
  f"This repository ({self.scope}) is larger than the repository the "
365
401
  f"figures below were measured on ({REFERENCE_JAVA_FILES} Java files), "
366
- f"and cost has not been observed to scale with file count: "
402
+ f"and what cost tracks here is the build rather than the file count: "
367
403
  f"{FIELD_ANCHOR}. Read each figure as the reference's, not as yours; "
368
404
  f"the `here:` lines say how each command can be run on this one."
369
405
  )
370
406
 
371
407
 
408
+ def field_anchor_note(row: "Optional[CommandCache]") -> "Optional[str]":
409
+ """The build a row's field figure belongs to, when it is not this one (C3-97).
410
+
411
+ ``None`` when there is nothing to qualify — no field figure, or one measured on
412
+ the running build. Otherwise a short parenthetical naming the build, because a
413
+ figure carrying another release's name is a measurement and a figure carrying
414
+ none is a claim about this one.
415
+
416
+ The figure is never suppressed. A measurement from four releases ago still
417
+ beats silence for a reader deciding how to run a command; what it must not do
418
+ is arrive undated, which is how `spring-audit`'s 2 351 s went on recommending
419
+ a nightly job for a command that had come to take 8,4 s.
420
+ """
421
+ if row is None or (row.field_seconds is None and not row.field_blocked):
422
+ return None
423
+ from sourcecode import __version__
424
+
425
+ measured_on = row.field_measured_version
426
+ if measured_on is None:
427
+ return "build not recorded"
428
+ if measured_on == __version__:
429
+ return None
430
+ # Short on purpose: this rides along every `here:` line and every row of
431
+ # `cache model`, and the build is the whole fact. The sentence that explains
432
+ # what an older build means is `field_currency()['statement']`, printed once.
433
+ return f"on {measured_on}"
434
+
435
+
436
+ def cost_sentence() -> str:
437
+ """The one paragraph the front page says about cost, derived here (CL-21).
438
+
439
+ `--help` and the README used to carry their own hand-written version of it —
440
+ *"repo-wide/deep compositions can take minutes … use deep jobs nightly"* —
441
+ which stayed true for as long as the anchors behind it did and then went on
442
+ being printed for two more releases, recommending a nightly job for commands
443
+ that had come to finish in seconds. A sentence maintained beside the table it
444
+ describes is the second copy of a fact, which is the rule this module opens
445
+ with. It is generated from the anchors instead, so refreshing them refreshes
446
+ the prose.
447
+ """
448
+ audit = next((r for r in COMMANDS if r.command == "spring-audit"), None)
449
+ seconds = FIELD_ANCHOR_SECONDS if audit is None or audit.field_seconds is None else audit.field_seconds
450
+ return (
451
+ f"Cost tracks the command class and the build, not the file count: "
452
+ f"per-symbol queries are the fast path, inventory commands scale with "
453
+ f"files, and a repository-wide audit measured {seconds:g} s on a "
454
+ f"{_thousands(FIELD_ANCHOR_JAVA_FILES)}-file repository "
455
+ f"({FIELD_ANCHOR_MEASURED_VERSION}). `ask cache model` prints the figure "
456
+ f"and the build behind it for every command; "
457
+ f"ASK_MAX_ANALYSIS_SECONDS/ASK_PROGRESS bound and narrate a run where CI "
458
+ f"wants an explicit budget."
459
+ )
460
+
461
+
462
+ def _thousands(n: int) -> str:
463
+ return f"{n:,}".replace(",", " ")
464
+
465
+
466
+ def field_currency() -> dict:
467
+ """The same statement as `reference_currency`, for the field anchors (C3-97).
468
+
469
+ Published so a consumer can see which side of the pair is current without
470
+ parsing prose, and so the gap is visible the day it opens rather than the day
471
+ an evaluation points at it.
472
+ """
473
+ from sourcecode import __version__
474
+
475
+ current = __version__
476
+ stale = sorted(
477
+ row.command
478
+ for row in COMMANDS
479
+ if (row.field_seconds is not None or row.field_blocked)
480
+ and row.field_measured_version not in (None, current)
481
+ )
482
+ return {
483
+ "anchor": FIELD_ANCHOR,
484
+ "measured_on_version": FIELD_ANCHOR_MEASURED_VERSION,
485
+ "running_version": current,
486
+ "current": FIELD_ANCHOR_MEASURED_VERSION == current,
487
+ "rows_measured_on_an_earlier_build": stale,
488
+ "statement": (
489
+ f"The field anchors were taken on {FIELD_ANCHOR_MEASURED_VERSION}; you "
490
+ f"are running {current}. Each row states the build its field figure "
491
+ f"belongs to, and no figure is projected onto this one."
492
+ if FIELD_ANCHOR_MEASURED_VERSION != current
493
+ else f"The field anchors were taken on {current}, the build you are running."
494
+ ),
495
+ }
496
+
497
+
372
498
  def reference_currency() -> dict:
373
499
  """How old the reference figures are, in releases the reader can name (F-AP).
374
500
 
@@ -429,9 +555,10 @@ def as_dict(here: "Optional[Conditioning]" = None) -> dict:
429
555
  # table nine releases old cannot read as this build's measurement.
430
556
  "reference_currency": reference_currency(),
431
557
  # Published beside the reference so no consumer reads the figures as a
432
- # law: the same command has been measured 46× slower on a repository 1.7×
433
- # the size, on a different platform (C4-19).
558
+ # law: the same command on the same commit of the same repository has
559
+ # measured 2 351 s and 8,4 s on two of our own builds (C4-19, C3-97).
434
560
  "field_anchor": FIELD_ANCHOR,
561
+ "field_currency": field_currency(),
435
562
  "commands": [
436
563
  {
437
564
  "command": cmd.command,
@@ -453,6 +580,20 @@ def as_dict(here: "Optional[Conditioning]" = None) -> dict:
453
580
  if cmd.cold_seconds is None
454
581
  else {"cold": cmd.cold_seconds, "warm": cmd.warm_seconds}
455
582
  ),
583
+ # C3-97: the field figure and the build it belongs to travel
584
+ # together, or not at all. A consumer that reads the seconds
585
+ # without the build is the defect this key exists to prevent.
586
+ "field_measurement": (
587
+ None
588
+ if cmd.field_seconds is None and not cmd.field_blocked
589
+ else {
590
+ "seconds": cmd.field_seconds,
591
+ "did_not_finish": cmd.field_blocked,
592
+ "java_files": FIELD_ANCHOR_JAVA_FILES,
593
+ "measured_on_version": cmd.field_measured_version,
594
+ "note": field_anchor_note(cmd),
595
+ }
596
+ ),
456
597
  }
457
598
  for cmd in COMMANDS
458
599
  ],
@@ -478,6 +619,13 @@ def render_markdown() -> str:
478
619
  f"performance gate (`docs/perf/REGRESSION-GATE.md`) is what re-measures them."
479
620
  )
480
621
  out.append("")
622
+ out.append(
623
+ f"The second anchor is the field one, and it carries its own build for the "
624
+ f"same reason (C3-97): {FIELD_ANCHOR}. Where a command was measured on an "
625
+ f"earlier release than the one you are running, `ask cache model` says so "
626
+ f"on that row rather than presenting the figure as this build's."
627
+ )
628
+ out.append("")
481
629
  out.append("| Command | A warm gives it | Measured (nothing cached → after a warm) | Repeat run cached | Layers | Notes |")
482
630
  out.append("|---|---|---|---|---|---|")
483
631
  for cmd in COMMANDS:
@@ -556,12 +704,26 @@ def render_text(here: "Optional[Conditioning]" = None) -> str:
556
704
  lines.append("What a warm gives each command")
557
705
  lines.append(f" Timings: {REFERENCE_REPOSITORY}, each command measured in isolation.")
558
706
  lines.append(f" {reference_currency()['statement']}")
707
+ lines.append(f" {field_currency()['statement']}")
559
708
  width = max(len(c.command) for c in COMMANDS)
560
709
  for cmd in COMMANDS:
561
710
  repeat = "repeat cached" if cmd.repeat else "recomputes"
562
711
  lines.append(f" {cmd.command.ljust(width)} {_WARM_LABEL[cmd.warm]:<16} ({repeat})")
563
712
  if cmd.measured:
564
713
  lines.append(f" {' ' * width} measured: {cmd.measured}")
714
+ if cmd.field_seconds is not None or cmd.field_blocked:
715
+ # C3-97: never the seconds without the build they were taken on.
716
+ note = field_anchor_note(cmd)
717
+ shown = (
718
+ "did not finish in an interactive session"
719
+ if cmd.field_seconds is None
720
+ else f"{cmd.field_seconds:g} s"
721
+ )
722
+ suffix = f" ({note})" if note else ""
723
+ lines.append(
724
+ f" {' ' * width} field: {shown} at "
725
+ f"{_thousands(FIELD_ANCHOR_JAVA_FILES)} Java files{suffix}"
726
+ )
565
727
  if cmd.note:
566
728
  lines.append(f" {' ' * width} {cmd.note}")
567
729
  if here is not None and cmd.command in here.per_command:
sourcecode/cli.py CHANGED
@@ -467,6 +467,25 @@ def _help_scope() -> "Optional[Any]":
467
467
  return None
468
468
 
469
469
 
470
+ def _cost_sentence() -> str:
471
+ """What the front page says about cost, from the module that measured it.
472
+
473
+ CL-21: this paragraph used to be written here, went stale with the anchors it
474
+ paraphrased, and kept telling operators to schedule a nightly job for commands
475
+ that finish in seconds. It is `cache_model`'s sentence now, so it cannot drift
476
+ from the table `ask cache model` prints.
477
+ """
478
+ try:
479
+ from sourcecode.cache_model import cost_sentence
480
+
481
+ return cost_sentence()
482
+ except Exception:
483
+ return (
484
+ "Cost tracks the command class and the build: `ask cache model` prints "
485
+ "what each command measured, and on which build."
486
+ )
487
+
488
+
470
489
  def _build_help_text(scope: "Optional[Any]" = None) -> str:
471
490
  """Build --help text dynamically based on current license state."""
472
491
  try:
@@ -485,10 +504,7 @@ def _build_help_text(scope: "Optional[Any]" = None) -> str:
485
504
  Deterministic Java/Spring semantics and reusable structural context for AI coding agents.
486
505
 
487
506
  Cache warms on first scan; later calls reuse pre-built context instead of rescanning.
488
- Performance depends on command class and repo size: per-symbol queries are the fast path,
489
- inventory commands scale with files, and repo-wide/deep compositions can take
490
- minutes on multi-thousand-endpoint repositories. Use deep jobs nightly or with
491
- ASK_MAX_ANALYSIS_SECONDS/ASK_PROGRESS when CI needs an explicit budget.
507
+ {_cost_sentence()}
492
508
 
493
509
  {_start_here_block(scope)}
494
510
 
sourcecode/detach.py CHANGED
@@ -1,8 +1,12 @@
1
1
  """detach.py — run a repository-wide analysis so it outlives the shell that started it.
2
2
 
3
- C3-53, three reproductions on the field repository: `spring-audit` runs 408 s of
4
- analysis, the agent harness promotes the foreground process to background at
5
- ~600 s, and the session dies. **Backgrounding it did not help, and neither did
3
+ C3-53, three reproductions on the field repository: `spring-audit` ran 408 s of
4
+ analysis **on the build measured then** (4.7.0-class; the same command on the same
5
+ repository measures 8,4 s on 4.18.0 — C3-97), the agent harness promoted the
6
+ foreground process to background at ~600 s, and the session died. The cost that
7
+ provoked this module has since collapsed; what the module answers — *a run that
8
+ must outlive the shell that started it* — has not, because a nightly composition
9
+ or a `risk` on a large tree still crosses that boundary. **Backgrounding it did not help, and neither did
6
10
  `Start-Process -NoNewWindow -PassThru`** — all six detached processes died at
7
11
  the same second the session did.
8
12
 
@@ -14,13 +14,15 @@ answer lives: `ask --help` orders its front page from it, and `remedies` checks
14
14
  every command it suggests against it.
15
15
 
16
16
  **What this module will not do is invent a number.** The natural design is to
17
- project seconds by scaling the reference measurement with the file count, and it
18
- would be wrong in the direction that costs a session: `spring-audit` takes 8.8 s
19
- on the 2 000-file reference and the field measured **408 s** on 3 342 files —
20
- 46× for 1.7× the size. Cost is dominated by what the repository contains and by
21
- the platform, neither of which a file count predicts. So what is published is a
22
- *class* and the measured anchors behind it, never a projected duration for the
23
- repository in hand.
17
+ project seconds by scaling the reference measurement with the file count, and the
18
+ series refutes it from both ends: `spring-audit` takes 8.8 s on the 2 000-file
19
+ reference, and on one 3 342-file repository at one commit the field measured
20
+ 408 s (#13), 2 351 s (#16) and **8,4 s** (#22) — three builds of ours, one of them
21
+ 280× apart from another, with byte-identical payloads. Cost is dominated by what
22
+ the repository contains, by the platform, and above all by the build; a file count
23
+ predicts none of the three. So what is published is a *class*, the measured
24
+ anchors behind it and **the release each was taken on** (C3-97), never a projected
25
+ duration for the repository in hand.
24
26
  """
25
27
 
26
28
  from __future__ import annotations
@@ -36,6 +38,7 @@ from sourcecode.cache_model import (
36
38
  FIELD_ANCHOR_JAVA_FILES,
37
39
  REFERENCE_JAVA_FILES,
38
40
  REFERENCE_REPOSITORY,
41
+ field_anchor_note,
39
42
  )
40
43
 
41
44
  #: How a command can be run on the scope in hand.
@@ -45,11 +48,13 @@ DETACH = "detach" # `--output` + `--detach`, or a nightly job
45
48
  UNKNOWN = "unknown" # not measured on this axis; never guessed
46
49
 
47
50
  #: Above this many Java files a repository-wide pass is in the regime the field
48
- #: measured in minutes rather than seconds. The number is the midpoint of the two
49
- #: anchors this product has actually measured (2 000 files → 8.8 s, 3 342 files →
50
- #: 408 s), not a preference: below the reference we have a measurement, above the
51
- #: field anchor we have a measurement, and the boundary between them is the
52
- #: honest place to change the advice.
51
+ #: measures in, rather than the one the reference was taken in. The number is the
52
+ #: midpoint of the two sizes this product has actually measured (2 000 files and
53
+ #: 3 342 files), not a preference: below the reference we have a measurement,
54
+ #: above the field anchor we have a measurement, and the boundary between them is
55
+ #: the honest place to change the advice. What changes there is which anchor a
56
+ #: verdict rests on — not an assumption that the larger one is slow, which is the
57
+ #: half C3-97 had to correct.
53
58
  LARGE_SCOPE_JAVA_FILES = (REFERENCE_JAVA_FILES + FIELD_ANCHOR_JAVA_FILES) // 2
54
59
 
55
60
  #: Stop walking after this many directory entries. A front page must not pay for
@@ -253,12 +258,17 @@ def _reference(row) -> Optional[str]:
253
258
  parts.append(
254
259
  f"{row.cold_seconds:g} s cold{warm} at {REFERENCE_JAVA_FILES} files"
255
260
  )
261
+ note = field_anchor_note(row)
262
+ dated = f", {note}" if note else ""
256
263
  if row.field_seconds is not None:
257
- parts.append(f"{row.field_seconds:g} s at {_files(FIELD_ANCHOR_JAVA_FILES)} files (field)")
264
+ parts.append(
265
+ f"{row.field_seconds:g} s at {_files(FIELD_ANCHOR_JAVA_FILES)} files "
266
+ f"(field{dated})"
267
+ )
258
268
  elif row.field_blocked:
259
269
  parts.append(
260
270
  f"did not finish in an interactive session at "
261
- f"{_files(FIELD_ANCHOR_JAVA_FILES)} files (field)"
271
+ f"{_files(FIELD_ANCHOR_JAVA_FILES)} files (field{dated})"
262
272
  )
263
273
  return " · ".join(parts) or None
264
274
 
@@ -310,16 +320,22 @@ def verdict(command: str, scope: Scope) -> Verdict:
310
320
  cls, reference,
311
321
  )
312
322
  if row is not None and row.field_seconds is not None:
323
+ # C3-97: the figure decides, and the build it was taken on travels with
324
+ # it. An anchor from an earlier release still outranks the class — it is
325
+ # a measurement at this size and the class is not — but it is never
326
+ # printed as though it described the build in hand.
327
+ note = field_anchor_note(row)
328
+ dated = f" ({note})" if note else ""
313
329
  if row.field_seconds <= FOREGROUND_SECONDS:
314
330
  return Verdict(
315
331
  command, RUNS_NOW,
316
- f"measured at {row.field_seconds:g} s on a repository this size",
332
+ f"measured at {row.field_seconds:g} s on a repository this size{dated}",
317
333
  cls, reference,
318
334
  )
319
335
  return Verdict(
320
336
  command, DETACH,
321
337
  (
322
- f"measured at {row.field_seconds:g} s on a repository this size — "
338
+ f"measured at {row.field_seconds:g} s on a repository this size{dated} — "
323
339
  f"run it with `--output` and `--detach`, or nightly"
324
340
  ),
325
341
  cls, reference,
@@ -328,9 +344,10 @@ def verdict(command: str, scope: Scope) -> Verdict:
328
344
  return Verdict(
329
345
  command, DETACH,
330
346
  (
331
- f"not measured on a repository this size; its class was — a "
332
- f"{cls} pass in this regime ran into minutes ({FIELD_ANCHOR}). "
333
- f"Offered detached rather than assumed cheap"
347
+ f"not measured on a repository this size, and its class is the "
348
+ f"only thing left to go on — a {cls} pass here has ranged from "
349
+ f"seconds to tens of minutes across our own releases "
350
+ f"({FIELD_ANCHOR}). Offered detached rather than assumed cheap"
334
351
  ),
335
352
  cls, reference,
336
353
  )
sourcecode/perf.py CHANGED
@@ -440,8 +440,10 @@ RELEASE_GATE_COMMANDS: tuple[str, ...] = (
440
440
  #: What the gate does **not** cover, and why — published rather than omitted, so
441
441
  #: "the gate is green" is never read as "every command was measured".
442
442
  RELEASE_GATE_EXCLUSIONS: tuple[tuple[str, str], ...] = (
443
- ("risk", "54 minutes on the gate repository (F-AQ); a nightly cannot hold it, "
444
- "and the cost is structural rather than a regression to detect"),
443
+ ("risk", "68 s on the gate repository since C3-96 deleted the catastrophic "
444
+ "backtracking that made it 54 minutes (F-AQ) — no longer excluded for "
445
+ "cost, only until a baseline cell exists for it; the first capture "
446
+ "that includes it makes it gated (C3-99)"),
445
447
  ("impact-chain", "takes a symbol, not a repository — its cost is the audit "
446
448
  "`risk` and `spring-audit` already gate"),
447
449
  ("verify-edit", "measures an edit loop, which needs a working-tree mutation "
sourcecode/phased_run.py CHANGED
@@ -300,14 +300,16 @@ def budget_warning(
300
300
  service from a 3 342-file monolith.
301
301
 
302
302
  What replaces it is what this product actually has: the **measured anchors for
303
- this command** (`cache_model`, both ends of the range) and the **size of the
304
- repository in hand** (`execution_plan.measure_scope`). What deliberately does
305
- *not* replace it is a projection: the cost model's own docstring records that
306
- cost does not scale with file count in any way this product has measured —
307
- 8,8 s at 2 000 files against 2 351 s at 3 342 for the same command — so
308
- "~15 s on your repository" would be a confident falsehood of the exact kind
309
- this ledger exists to prevent. The anchors and the size are the honest claim,
310
- and the class floor is named as a class floor when there is nothing better.
303
+ this command** (`cache_model`, both ends of the range, each carrying the build
304
+ it was taken on) and the **size of the repository in hand**
305
+ (`execution_plan.measure_scope`). What deliberately does *not* replace it is a
306
+ projection, and C3-97 made that case stronger rather than weaker: the same
307
+ command on the same commit of the same 3 342-file repository measured 2 351 s
308
+ on 4.11.0 and 8,4 s on 4.18.0, against 8,8 s at 2 000 files throughout. Cost
309
+ tracks the build at least as much as the tree, so "~15 s on your repository"
310
+ would be a confident falsehood of the exact kind this ledger exists to
311
+ prevent. The anchors and the size are the honest claim, and the class floor is
312
+ named as a class floor when there is nothing better.
311
313
  """
312
314
  lines = [
313
315
  f"[ask] budget: {command} is a {cls} analysis and the configured budget "
@@ -27,7 +27,7 @@ from typing import Any, Optional
27
27
  #: The date `__version__` was released, from that version's CHANGELOG entry.
28
28
  #: `tests/test_release_info.py` fails the build if the two disagree, so this is
29
29
  #: a copy of a fact rather than a second authority for it.
30
- RELEASE_DATE = "2026-08-10"
30
+ RELEASE_DATE = "2026-08-11"
31
31
 
32
32
  #: Releases per day, measured over the 30 releases before this one (the same
33
33
  #: computation the test re-runs against the CHANGELOG). Stable across window
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 4.18.0
3
+ Version: 5.0.0
4
4
  Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
5
5
  License-File: LICENSE
6
6
  Keywords: agents,ai,codebase,context,developer-tools,llm
@@ -42,7 +42,7 @@ Description-Content-Type: text/markdown
42
42
 
43
43
  **Context · Impact · Migration · Architecture · Review — everything from one structural model.**
44
44
 
45
- ![Version](https://img.shields.io/badge/version-4.18.0-blue)
45
+ ![Version](https://img.shields.io/badge/version-5.0.0-blue)
46
46
  ![Python](https://img.shields.io/badge/python-3.9%2B-green)
47
47
 
48
48
  > **ASK Engine** is the product. The CLI command is **`ask`**. The legacy **`sourcecode`**
@@ -54,7 +54,7 @@ Description-Content-Type: text/markdown
54
54
 
55
55
  ## The problem
56
56
 
57
- Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. On small and mid-sized repos that cost is seconds; on large Java/Spring monoliths, repo-wide semantic composition can be minutes. Multiply that by dozens of agent turns per hour, and repo context acquisition becomes a real bottleneck — not just latency, but tokens, compute, and iteration velocity.
57
+ Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. On a large Java/Spring monolith that is thousands of files of parsing per turn, repeated for every question asked about the same unchanged tree. Multiply it by dozens of agent turns per hour, and repo context acquisition becomes a real bottleneck — not just latency, but tokens, compute, and iteration velocity.
58
58
 
59
59
  ASK Engine solves this with a persistent structural cache keyed on file content hashes. After the first scan, later invocations reuse pre-built context whenever their command can consume the warmed layers. The repo doesn't change? The cache doesn't expire.
60
60
 
@@ -69,7 +69,7 @@ ASK Engine solves this with a persistent structural cache keyed on file content
69
69
  | Keycloak | 7,885 Java files | 10.5s | 0.6s | **~17x** |
70
70
  | BroadleafCommerce | 2,985 Java files | 2.7s | 0.3s | **~9x** |
71
71
 
72
- These numbers are cache-layer benchmarks, not a promise for every command. Per-symbol queries and compact context benefit most. Inventory commands scale with file count. Repo-wide/deep compositions such as `risk`, `audit-report` and large `spring-audit` runs can take minutes on multi-thousand-endpoint repositories and belong in a supervised or nightly job unless CI sets an explicit budget.
72
+ These numbers are cache-layer benchmarks, not a promise for every command. Per-symbol queries and compact context benefit most, and inventory commands scale with file count. What a repository-wide analysis costs tracks the build more than the file count: on one 3,342-file monolith, at one commit, `spring-audit` measured 2,351s on 4.11.0 and **8.4s on 4.18.0** with a byte-identical payload — so ASK publishes measured anchors and the release each was taken on, and never projects a duration for your repository. `ask cache model` prints both anchors per command, and `risk` — the one composition still measured in the tens of seconds at that size — is the one to give a budget or a detached run.
73
73
 
74
74
  With the right command class, ASK Engine becomes **constant infrastructure** inside agent loops — call the fast/context surfaces before edits and reserve deep compositions for the points where their evidence is worth the runtime.
75
75
 
@@ -126,7 +126,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
126
126
  # pip / pipx
127
127
  pipx install sourcecode # or: pip install sourcecode
128
128
 
129
- ask version # ask 4.18.0 — and, on a build that has aged,
129
+ ask version # ask 5.0.0 — and, on a build that has aged,
130
130
  # how many releases have probably shipped since
131
131
  ```
132
132
 
@@ -1,4 +1,4 @@
1
- sourcecode/__init__.py,sha256=LpY49oJbepgtrBXuaM-nvqCIK9EhzKSzsI0twe763hk,309
1
+ sourcecode/__init__.py,sha256=Y22bv5DzCS9Djs9Ql4VI3jyeczhm8uAgC4Nl9LjiXm0,308
2
2
  sourcecode/adaptive_scanner.py,sha256=yJBKjNpkY6bpueYJ2YnRezen3sYZDecEt7WaaNWdqug,9466
3
3
  sourcecode/archetype.py,sha256=CZvRLpkHot_D8D3JFQVorr-EHDJyh0BbS7RnSTqBigM,40499
4
4
  sourcecode/architectural_baseline.py,sha256=4GiMVBLJVHvRKSWQGf2ZVurI1-R0qk5pmaevgvGSgVA,26325
@@ -9,7 +9,7 @@ sourcecode/ast_extractor.py,sha256=aXJjZ7XjAdxa99hWNm4SyzPqx4gNWiTbUYjNWGNl-Vc,5
9
9
  sourcecode/audit_report.py,sha256=CLvvlQH2oA6Qj4UADUWhNwSsp1OcyzwXXey5DN_IiWI,8660
10
10
  sourcecode/baseline_autocapture.py,sha256=tmMLexQSeaQRRbqxAd7walvGQqnF0mdpxQmkL40rlhI,15623
11
11
  sourcecode/cache.py,sha256=CK_J8NqyaTNZ57KQT-R4puqI8yYlzG5WL7uLFRbzods,41727
12
- sourcecode/cache_model.py,sha256=JCoC0nBchtv1j6UAgPepyJU_RFafxmch6oCLNO1QPFI,32666
12
+ sourcecode/cache_model.py,sha256=jQcXAIpfBl2rXrf8xitNKXy8M0RSIn4F4hQYV-tKGm8,41285
13
13
  sourcecode/call_surface.py,sha256=fiqYfHooxN1fX9oQoysq1LS3LoZcobhyUNjAGEZKpwk,4148
14
14
  sourcecode/caller_metrics.py,sha256=--sFGDnIog_YGu9xZHMcB91F5xZakfaAKvy15xU54hg,7904
15
15
  sourcecode/caller_reach.py,sha256=RRF49tv4-QswraJ2vsZ89VAMOj7BmYXlAdXr-tLP_CA,9483
@@ -18,7 +18,7 @@ sourcecode/chain_rules.py,sha256=Bi6UHfgd-GxWswmnHRcPz5jdbAuqka3Zkz_P-MTvqhw,127
18
18
  sourcecode/change_plan.py,sha256=aX1mp2XnlDN-8R2BcTiu8HlkDwQ_4fN1ZLckj0VMXHM,9945
19
19
  sourcecode/cir_graphs.py,sha256=9G0HHj1kw2325IDyzo2OpX73BNswEckecf4MZUXB4JM,12078
20
20
  sourcecode/classifier.py,sha256=JBzPwSSrDG-tUHAbcKB678HRbjLpD-ohzbzzO62mgpo,20114
21
- sourcecode/cli.py,sha256=rHwUACJ4ehe-QUUDB95LXuNrroNc_0BniGqOJhsFtTs,604512
21
+ sourcecode/cli.py,sha256=5sTk3jJ1Xh-JlnLiwN9bH0y3puiYejENXfl5iN0efrU,604917
22
22
  sourcecode/client_calls.py,sha256=daRTgbXNUOfkzGXJpVb6A737R_Thhka8vw1_YgxCaLg,13548
23
23
  sourcecode/code_notes_analyzer.py,sha256=EJemNCNc9Dn-1RZYu-aNbK0ELzmsyC4s6FdHi3XyNEI,9392
24
24
  sourcecode/compare.py,sha256=2GdDy0qkDSgmkkpgvoCHitoLj3mt30EeFgJ8PGEXJng,14712
@@ -41,7 +41,7 @@ sourcecode/defect_identity.py,sha256=XS2VFDImg9NLaRImybKTeyk-CoDSsXmchldg0dwvM7c
41
41
  sourcecode/degradation.py,sha256=BtuGUKFgkzI3Z6fwmUdxEUEaLFAcPQ_bHhU2w9ItDxw,18376
42
42
  sourcecode/dependency_analyzer.py,sha256=fQCaWQ7_BNcVgZv8gweJCwJ1CGlXsz8nw_tqN3aHJNE,63952
43
43
  sourcecode/deployment_prefix.py,sha256=g0_4bE_m9svjhnapRpOp8BJkj6Ul94Ij_iVezygMZ0I,11956
44
- sourcecode/detach.py,sha256=zF5qY4DF1JN3CEjbq3eKf0PnSmywQlTcN6aLEAMPdjU,7650
44
+ sourcecode/detach.py,sha256=PvkCcbIuTaDKKt5TGqtQLahmsmCkflui33jLnMEWkvg,8006
45
45
  sourcecode/doc_analyzer.py,sha256=05bjTUbDbmnbajD_cgRnACzS8T7xxBKVX4CjkJlhZg8,24411
46
46
  sourcecode/dynamic_argument_surface.py,sha256=u6zJoY-zChYVw1-SrgiyAq-rUwqMZ5ZqBwLfbPJ_8ng,2960
47
47
  sourcecode/endpoint_literals.py,sha256=Qf4gTZzvNSFDGDuOvF0YRL9NvaYKKj24klhR5LIOaXc,3263
@@ -52,7 +52,7 @@ sourcecode/envelope.py,sha256=fpF_8znvPqGXKZb0UPYcCYjm27yO7Pr-WsdXNE-tEoY,8911
52
52
  sourcecode/environment_resolution.py,sha256=bfhkM0RGSyLwzFvfi-YhHjU1cy2ufA_WIkXBVeHs9y8,22130
53
53
  sourcecode/error_schema.py,sha256=uwosfNaSujtYm11_732Hu92z5ITV040fQDaIyefSvR4,1683
54
54
  sourcecode/evidence_provider.py,sha256=GSSL44JEaouO5AHks2sB3d1YvC9xIKIld1yBYxZpXxo,4277
55
- sourcecode/execution_plan.py,sha256=40OWXopf5q0rKkG2F_b282lsQ3Tkq-zIfWdMURUiLis,17120
55
+ sourcecode/execution_plan.py,sha256=KRI_bFiBbmxOu0aF4bGwgVK9RdH8eB6g9Xhj1fkS2Zk,18120
56
56
  sourcecode/explain.py,sha256=yqxvKiLF0XMMg11PdgqMFrsim5SXuEKM1U2cLvCLspM,29935
57
57
  sourcecode/file_chunker.py,sha256=3vkM3mDQ5eE_yTPvUgjyjpGFBIjkW6_mrBmIbrylnA8,16444
58
58
  sourcecode/file_classifier.py,sha256=pJCeN9KqWpAwKMCgGP4KDsBjuWMeo4zlbj5fv3hk9dA,15587
@@ -82,8 +82,8 @@ sourcecode/parse_cache.py,sha256=fhXnoaOgVWwp_8q0ngJ76UZ09qJ6uxDd0jaX8jdezvo,208
82
82
  sourcecode/partial_contract.py,sha256=x_N_0bF3mpNNjXd7JFB1zr6LSIroo2zN5GCz14GXvXQ,3510
83
83
  sourcecode/path_admission.py,sha256=OGNSoluhVh8YYOBZBnACUrkmH4Tp_yxjGLifkcsxQpo,5838
84
84
  sourcecode/path_filters.py,sha256=LmTYq735orssKTIuxTX1mE1FHAXF7dVEJEse35xE1RA,12371
85
- sourcecode/perf.py,sha256=vZDEj1wS905peXmREdOniZrWCikElOyPTw-E32zVZAQ,25847
86
- sourcecode/phased_run.py,sha256=WiQhsSJyFZcRsqrsiHzQhzgSlRtOuSDe-Bd-g4BypYk,16420
85
+ sourcecode/perf.py,sha256=ZCPxDIg6ww6PXfLwcqNTH99lc1UgkYUZI3MywFgRO90,25991
86
+ sourcecode/phased_run.py,sha256=cFd0Lxfc8XL-XkCVCCzcjd9bZbtgkJkGZAHfmJ6dBJ4,16542
87
87
  sourcecode/pipe_contract.py,sha256=PML0Er5d8uDyec4OrdUXuyqHbGPUYndjeaKUjkFz2u4,8369
88
88
  sourcecode/posture.py,sha256=TGzSwa413NJyVvBgGWyCyaFqJXX-fnctq7vdxVs9z9A,76744
89
89
  sourcecode/pr_comment_renderer.py,sha256=239PmJdf95av_ZW236C7_tvq_ahECeuF9AZxrheJ4OQ,15573
@@ -97,7 +97,7 @@ sourcecode/readonly.py,sha256=dqGiNVvpfi4Ww8VzwUs6E3SdbqcHL1LFHItIK7IjrM0,5830
97
97
  sourcecode/reconciliation.py,sha256=GU-1PTcVr8zcbtC7BASfpHcZndP9AdboXPNQiBc0fzo,34251
98
98
  sourcecode/redactor.py,sha256=SB4hwIvg8h-hvcqKcDWaZvA-aSyn-at-BIRwa0tUv5E,3227
99
99
  sourcecode/reference_facts.py,sha256=Ns495c6eTmq2SrqPkcUrJUJru4_wj_yRWm4YDeJwves,13440
100
- sourcecode/release_info.py,sha256=4Jfym0xPvJpauhXDWLY2An8yIzae5OlAYZeUr24URsc,5378
100
+ sourcecode/release_info.py,sha256=Y3PXhq7U_6Ewu2irpSWvlOzcSHs1cQlemvDXGtC1RnQ,5378
101
101
  sourcecode/relevance_scorer.py,sha256=0AgEt4KrV73nioMqBgjhGjtY7L2C7L7cSyKtj3IKcrw,9408
102
102
  sourcecode/remedies.py,sha256=9eAuP9ndw78YvuUtOi2VvoeNnVCMh1q0uxfnPIkvx7c,7838
103
103
  sourcecode/rename_refactor.py,sha256=h6dNFlB9aZ_3q6heeHBkgXQeXaT03nvPSsYH6P8qxFg,12965
@@ -205,8 +205,8 @@ sourcecode/telemetry/consent.py,sha256=pQdl-QeLl6Gcibn0eWHSKZrm-HYSsjpVqOnjrgFp8
205
205
  sourcecode/telemetry/events.py,sha256=4_yeO58U-Cwc1Qb27VB0_EjhmroY0k91n3_VGxeALB8,2776
206
206
  sourcecode/telemetry/filters.py,sha256=RzxauTz8HliO4BllQnXEXc7zTeqdCZi5MgqGEDuW7OQ,6570
207
207
  sourcecode/telemetry/transport.py,sha256=4gGHsq0WeY9VywEZXA3vUxykfiYnw9uuqfjAAec7F8o,1681
208
- sourcecode-4.18.0.dist-info/METADATA,sha256=dlV7aqM2IWphltK1Fy-6IwjH4D_y3UGIymO26VBZTEU,42089
209
- sourcecode-4.18.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
210
- sourcecode-4.18.0.dist-info/entry_points.txt,sha256=-JEAdChrK5We51kZcb7OaDcyil-dHBjBPL-NhuO-QY8,89
211
- sourcecode-4.18.0.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
212
- sourcecode-4.18.0.dist-info/RECORD,,
208
+ sourcecode-5.0.0.dist-info/METADATA,sha256=mW6-jtrJZ6KxEAqRhncgpItWR93mFkL5sHDq0NjTd1Y,42410
209
+ sourcecode-5.0.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
210
+ sourcecode-5.0.0.dist-info/entry_points.txt,sha256=-JEAdChrK5We51kZcb7OaDcyil-dHBjBPL-NhuO-QY8,89
211
+ sourcecode-5.0.0.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
212
+ sourcecode-5.0.0.dist-info/RECORD,,