sourcecode 5.1.0__py3-none-any.whl → 5.3.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.
- sourcecode/__init__.py +1 -1
- sourcecode/architectural_delta.py +57 -0
- sourcecode/cache_model.py +93 -29
- sourcecode/cli.py +367 -37
- sourcecode/consumer_join.py +357 -0
- sourcecode/contract_diff.py +27 -0
- sourcecode/environment_resolution.py +200 -12
- sourcecode/execution_plan.py +41 -2
- sourcecode/format_contract.py +1 -0
- sourcecode/non_coverage.py +12 -8
- sourcecode/perf.py +116 -5
- sourcecode/remedies.py +51 -1
- sourcecode/risk.py +92 -2
- sourcecode/spring_findings.py +39 -0
- sourcecode/spring_impact.py +10 -0
- sourcecode/sql_taint.py +362 -0
- sourcecode/timeline.py +459 -0
- sourcecode/verify_edit.py +70 -24
- sourcecode/verify_rules.py +9 -0
- sourcecode/waivers.py +384 -0
- {sourcecode-5.1.0.dist-info → sourcecode-5.3.0.dist-info}/METADATA +52 -14
- {sourcecode-5.1.0.dist-info → sourcecode-5.3.0.dist-info}/RECORD +25 -21
- {sourcecode-5.1.0.dist-info → sourcecode-5.3.0.dist-info}/WHEEL +0 -0
- {sourcecode-5.1.0.dist-info → sourcecode-5.3.0.dist-info}/entry_points.txt +0 -0
- {sourcecode-5.1.0.dist-info → sourcecode-5.3.0.dist-info}/licenses/LICENSE +0 -0
sourcecode/__init__.py
CHANGED
|
@@ -235,6 +235,63 @@ def diff_metrics(base: ArchMetrics, head: ArchMetrics) -> dict:
|
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
|
|
238
|
+
#: The one sentence both identical-state payloads are derived from (C3-107).
|
|
239
|
+
#: It is an argument, not an assumption, and it rests on a property this product
|
|
240
|
+
#: publishes and asserts every release: the analysis is a pure function of the
|
|
241
|
+
#: tree state, byte-identical across eleven field rounds and two major jumps.
|
|
242
|
+
IDENTICAL_STATE_BASIS = (
|
|
243
|
+
"The two states are one tree, and the analysis is a deterministic function of "
|
|
244
|
+
"the tree state, so every delta is zero without reading the tree. What is "
|
|
245
|
+
"*not* claimed is anything about the tree itself: the per-side totals were "
|
|
246
|
+
"not measured and are `null`, never 0 — pass two different states, or run "
|
|
247
|
+
"`ask <repo>` on one of them, to measure the repository rather than the diff."
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def identical_state_delta() -> dict:
|
|
252
|
+
"""The `architectural-delta-v1` payload for two states that are one state.
|
|
253
|
+
|
|
254
|
+
C3-107 closed the second build; the eleventh round measured what was left —
|
|
255
|
+
`delta` 24,6 s and `contract-diff` 59,9 s to conclude that a tree does not
|
|
256
|
+
differ from itself, from a purged cache. Building one side to diff it against
|
|
257
|
+
itself is a measurement of the *repository*, and this command's answer is the
|
|
258
|
+
*difference*: with one tree state the difference is empty by construction.
|
|
259
|
+
|
|
260
|
+
So the deltas are published as the zeroes they provably are, and every figure
|
|
261
|
+
that would require an analysis is `null` with the reason attached — the rule
|
|
262
|
+
this product applies everywhere else (an axis that was not measured is
|
|
263
|
+
`unknown`, never `0`).
|
|
264
|
+
"""
|
|
265
|
+
empty_counts = {"base": None, "head": None, "delta": 0}
|
|
266
|
+
return {
|
|
267
|
+
"schema": ARCH_DELTA_SCHEMA,
|
|
268
|
+
"base_cir_hash": None,
|
|
269
|
+
"head_cir_hash": None,
|
|
270
|
+
"totals": {
|
|
271
|
+
"files": dict(empty_counts),
|
|
272
|
+
"symbols": dict(empty_counts),
|
|
273
|
+
"endpoints": dict(empty_counts),
|
|
274
|
+
"dependency_edges": dict(empty_counts),
|
|
275
|
+
"import_cycles": dict(empty_counts),
|
|
276
|
+
},
|
|
277
|
+
"endpoint_surface": {
|
|
278
|
+
"added_count": 0, "removed_count": 0, "added": [], "removed": [],
|
|
279
|
+
},
|
|
280
|
+
"fan_in_shifts": {"changed_count": 0, "shifts": []},
|
|
281
|
+
"import_cycle_shifts": {
|
|
282
|
+
"added_count": 0, "removed_count": 0, "added": [], "removed": [],
|
|
283
|
+
},
|
|
284
|
+
"blast_radius_shifts": {
|
|
285
|
+
"scope": "fan_in_shift_symbols", "changed_count": 0, "shifts": [],
|
|
286
|
+
},
|
|
287
|
+
"analysis": {"performed": False, "basis": IDENTICAL_STATE_BASIS},
|
|
288
|
+
"provenance": (
|
|
289
|
+
"architectural_delta (D1), identical states: no repository was read. "
|
|
290
|
+
+ IDENTICAL_STATE_BASIS
|
|
291
|
+
),
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
|
|
238
295
|
def _transitive_reach(fqn: str, reverse_graph: dict, node_cap: int) -> int:
|
|
239
296
|
"""Size of the transitive reverse-dependency set of `fqn` (its blast radius).
|
|
240
297
|
|
sourcecode/cache_model.py
CHANGED
|
@@ -141,10 +141,11 @@ REFERENCE_JAVA_FILES = 2000
|
|
|
141
141
|
REFERENCE_MEASURED_VERSION = "3.2.2"
|
|
142
142
|
|
|
143
143
|
#: The other end of the measured range, and the reason this module publishes a
|
|
144
|
-
#: *class* rather than a projected duration (C4-19). Field evaluation #
|
|
145
|
-
#: Windows 11 / PowerShell 5.1 / pipx / Python 3.10
|
|
146
|
-
#: 3 342-file repository ran **
|
|
147
|
-
#: 2 000-file reference, for a repository 1,7× the size
|
|
144
|
+
#: *class* rather than a projected duration (C4-19). Field evaluation #26, on
|
|
145
|
+
#: Windows 11 / PowerShell 5.1 / pipx / Python 3.10, every cache purged first:
|
|
146
|
+
#: `spring-audit` on a 3 342-file repository ran **31,0 s** — the same command
|
|
147
|
+
#: takes 8.8 s on the 2 000-file reference, for a repository 1,7× the size, and it
|
|
148
|
+
#: ran 8,4 s on the same subject two releases earlier.
|
|
148
149
|
#:
|
|
149
150
|
#: **The refusal to project stands, and this evaluation strengthened it** (C3-97).
|
|
150
151
|
#: For eight releases the pair of anchors said *cost does not track file count*;
|
|
@@ -159,9 +160,11 @@ REFERENCE_MEASURED_VERSION = "3.2.2"
|
|
|
159
160
|
#: each was measured on**, and how to run it.
|
|
160
161
|
#:
|
|
161
162
|
#: History of the anchor, kept because it is the measurement C3-76 exists for:
|
|
162
|
-
#: 408 s (#13) → 2 351 s (#16, C3-72) → 8,4 s (#22, C3-97)
|
|
163
|
-
#: quoted as an operational anchor for four releases after
|
|
164
|
-
#: it, and told operators to detach commands that finish in
|
|
163
|
+
#: 408 s (#13) → 2 351 s (#16, C3-72) → 8,4 s (#22, C3-97) → 31,0 s (#26, C3-110).
|
|
164
|
+
#: The middle figure was quoted as an operational anchor for four releases after
|
|
165
|
+
#: the build that produced it, and told operators to detach commands that finish in
|
|
166
|
+
#: seconds; the last one moved 3,7× in two releases with byte-identical payloads,
|
|
167
|
+
#: which is the movement the release gate exists to catch and did not.
|
|
165
168
|
#:
|
|
166
169
|
#: ⚠ `FIELD_ANCHOR`, `FIELD_ANCHOR_SECONDS` and `FIELD_ANCHOR_MEASURED_VERSION`
|
|
167
170
|
#: are **derived from the `spring-audit` row**, below `COMMANDS`. They used to be
|
|
@@ -242,12 +245,12 @@ COMMANDS: tuple[CommandCache, ...] = (
|
|
|
242
245
|
"71,7 s again for `--agent` on the state it had just analysed (C3-103).",
|
|
243
246
|
"--compact 13.3 s cold → 0.3 s warm (cold re-measured on 3.7.0: was 19.3 s, C3-6); "
|
|
244
247
|
"--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,
|
|
245
|
-
field_seconds=
|
|
248
|
+
field_seconds=166.7, field_cache_state="cold", field_measured_version="5.1.0"),
|
|
246
249
|
CommandCache("posture", ("cir", "parse"), "shared", False,
|
|
247
250
|
"Resolves the conditional bean graph on every run, over the shared CIR a warm "
|
|
248
251
|
"builds — the parse it used to repeat for itself. `--diff` compares two profile "
|
|
249
252
|
"sets over that one IR, so the second side costs the resolution only.",
|
|
250
|
-
"10.1 s → 1.6 s", analysis_class="repo-wide", cold_seconds=10.1, warm_seconds=1.6, field_seconds=8.
|
|
253
|
+
"10.1 s → 1.6 s", analysis_class="repo-wide", cold_seconds=10.1, warm_seconds=1.6, field_seconds=8.3, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
251
254
|
CommandCache("risk", ("cir", "parse"), "shared", False,
|
|
252
255
|
"Composes what the audit, impact-chain and the posture already answer, so it "
|
|
253
256
|
"pays each of their costs once over the shared CIR a warm builds — one parse "
|
|
@@ -255,7 +258,7 @@ COMMANDS: tuple[CommandCache, ...] = (
|
|
|
255
258
|
"within the run.",
|
|
256
259
|
"not measured on the battery yet — the composition is bounded by the "
|
|
257
260
|
"`spring-audit` + `impact-chain` costs listed here, not by new analysis",
|
|
258
|
-
analysis_class="deep", field_seconds=
|
|
261
|
+
analysis_class="deep", field_seconds=77.2, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
259
262
|
CommandCache("enrich", ("cir", "parse"), "shared", False,
|
|
260
263
|
"Runs the same composition as `risk` over the repository, then joins a SARIF "
|
|
261
264
|
"log to it. Reading the log is negligible; everything a warm helps with is the "
|
|
@@ -280,30 +283,31 @@ COMMANDS: tuple[CommandCache, ...] = (
|
|
|
280
283
|
"builds. Cost scales with the number of declared types, not with the "
|
|
281
284
|
"size of the label.",
|
|
282
285
|
"not measured on the battery yet — one `impact-chain` traversal per "
|
|
283
|
-
"declared seed type over a CIR the warm already paid for", analysis_class="repo-wide"
|
|
286
|
+
"declared seed type over a CIR the warm already paid for", analysis_class="repo-wide",
|
|
287
|
+
field_seconds=28.9, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
284
288
|
CommandCache("endpoints", ("ris", "parse"), "shared", False,
|
|
285
289
|
"Recomputes the endpoint surface on every run, over a parse a warm has already "
|
|
286
290
|
"paid for. Until 3.7.0 the extractor parsed every file itself instead of reading "
|
|
287
291
|
"the shared parse cache, and a warm measurably bought it nothing (C3-6).",
|
|
288
|
-
"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=
|
|
292
|
+
"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.6, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
289
293
|
CommandCache("spring-audit", ("ris", "parse"), "shared", False,
|
|
290
294
|
"Recomputes every run, but over a parse a warm has already paid for.",
|
|
291
|
-
"8.8 s → 3.7 s", analysis_class="repo-wide", cold_seconds=8.8, warm_seconds=3.7, field_seconds=
|
|
295
|
+
"8.8 s → 3.7 s", analysis_class="repo-wide", cold_seconds=8.8, warm_seconds=3.7, field_seconds=31.0, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
292
296
|
CommandCache("migrate-check", ("cir",), "none", False,
|
|
293
297
|
"Computes its own inventory and shares nothing a warm builds. Only `--blast-radius` "
|
|
294
298
|
"reuses the shared CIR.",
|
|
295
|
-
"4.8 s → 4.8 s", analysis_class="repo-wide", cold_seconds=4.8, warm_seconds=4.8, field_seconds=
|
|
299
|
+
"4.8 s → 4.8 s", analysis_class="repo-wide", cold_seconds=4.8, warm_seconds=4.8, field_seconds=11.3, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
296
300
|
CommandCache("impact-chain", ("cir", "parse"), "shared", False,
|
|
297
301
|
"The CIR is the expensive half — this is where a warm pays most.",
|
|
298
302
|
"9.9 s → 1.7 s", analysis_class="core", cold_seconds=9.9, warm_seconds=1.7,
|
|
299
|
-
field_seconds=
|
|
303
|
+
field_seconds=16.1, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
300
304
|
CommandCache("impact", ("parse",), "shared", False, "", "4.9 s → 2.8 s", analysis_class="core", cold_seconds=4.9, warm_seconds=2.8,
|
|
301
305
|
field_seconds=7.7, field_measured_version="4.18.0"),
|
|
302
306
|
CommandCache("pr-impact", ("parse",), "shared", False,
|
|
303
307
|
"Diff-dependent: the answer itself is never stored. What it costs follows the "
|
|
304
308
|
"diff, not the repository: 12,5 s on an ordinary one and 11,8 s on a diff of "
|
|
305
309
|
"security configuration, measured at field scale.", analysis_class="core",
|
|
306
|
-
field_seconds=
|
|
310
|
+
field_seconds=25.7, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
307
311
|
CommandCache("verify", (), "none", False, "Runs the contracts against a fresh reading.", analysis_class="core"),
|
|
308
312
|
CommandCache("verify-edit", ("parse",), "shared", True,
|
|
309
313
|
"Built for the edit loop: the parse cache is what keeps an unchanged file out of the "
|
|
@@ -311,15 +315,17 @@ COMMANDS: tuple[CommandCache, ...] = (
|
|
|
311
315
|
"yet: eval #23 measured 76,6 s on a tree with no edits, because the HEAD side is "
|
|
312
316
|
"still built in a throwaway worktree instead of reusing the shared CIR (C3-102).",
|
|
313
317
|
"14.6 s → 9.6 s → 5.6 s on repeat", analysis_class="repo-wide", cold_seconds=14.6, warm_seconds=9.6,
|
|
314
|
-
field_seconds=
|
|
318
|
+
field_seconds=119.5, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
315
319
|
CommandCache("review-pr", ("cir",), "none", False,
|
|
316
320
|
"Diff-dependent, and it reuses the CIR only if one exists. On a small diff, loading "
|
|
317
321
|
"the warmed CIR costs more than the work it saves.",
|
|
318
322
|
"1.1 s → 2.3 s (slower)", analysis_class="core", cold_seconds=1.1, warm_seconds=2.3),
|
|
319
323
|
CommandCache("plan", ("parse",), "shared", False, "", "9.3 s → 3.8 s", analysis_class="core", cold_seconds=9.3, warm_seconds=3.8),
|
|
320
324
|
CommandCache("compare", ("parse",), "shared", False, "", analysis_class="core"),
|
|
321
|
-
CommandCache("delta", (), "none", False, "Analyses two states — two checkouts, or two refs materialised into temporary trees; neither is the tree the cache describes.", analysis_class="repo-wide"
|
|
322
|
-
|
|
325
|
+
CommandCache("delta", (), "none", False, "Analyses two states — two checkouts, or two refs materialised into temporary trees; neither is the tree the cache describes.", analysis_class="repo-wide",
|
|
326
|
+
field_seconds=24.6, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
327
|
+
CommandCache("contract-diff", (), "none", False, "Analyses two states (checkouts or refs); neither is the tree the cache describes.", analysis_class="repo-wide",
|
|
328
|
+
field_seconds=59.9, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
323
329
|
CommandCache("fix-bug", ("task",), "none", True,
|
|
324
330
|
"Shorthand for `prepare-context fix-bug`; caches its own answer, which a warm never runs.", analysis_class="core"),
|
|
325
331
|
CommandCache("rename-class", (), "none", False, "", analysis_class="core"),
|
|
@@ -341,26 +347,28 @@ COMMANDS: tuple[CommandCache, ...] = (
|
|
|
341
347
|
"no answer hit", analysis_class="repo-wide", cold_seconds=6.5, warm_seconds=0.3),
|
|
342
348
|
CommandCache("explain", ("cir",), "shared", False, "Serves from the shared CIR a warm builds.",
|
|
343
349
|
"9.8 s → 1.6 s", analysis_class="core", cold_seconds=9.8, warm_seconds=1.6,
|
|
344
|
-
field_seconds=
|
|
350
|
+
field_seconds=6.3, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
345
351
|
CommandCache("export", ("parse",), "shared", False, "", "8.8 s → 3.7 s", analysis_class="repo-wide", cold_seconds=8.8, warm_seconds=3.7),
|
|
346
352
|
CommandCache("repo-ir", ("parse",), "shared", False,
|
|
347
353
|
"Carried as *did not finish* from 4.10.4 until eval #23 ran it at field size in "
|
|
348
354
|
"9,8 s — a run that did not finish once is not a command that cannot finish "
|
|
349
355
|
"(C3-100, and the same correction `modernize` needed).",
|
|
350
356
|
"5.1 s → 2.9 s", analysis_class="repo-wide", cold_seconds=5.1, warm_seconds=2.9,
|
|
351
|
-
field_seconds=
|
|
357
|
+
field_seconds=19.2, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
352
358
|
CommandCache("validation", ("parse",), "shared", False, "", "11.6 s → 6.4 s", analysis_class="repo-wide", cold_seconds=11.6, warm_seconds=6.4,
|
|
353
|
-
field_seconds=
|
|
359
|
+
field_seconds=39.5, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
354
360
|
CommandCache("modernize", ("parse",), "shared", False,
|
|
355
361
|
"Blocked in the session that recorded C3-53 and measured since: a run that did "
|
|
356
362
|
"not finish once is not a command that cannot finish.",
|
|
357
363
|
"5.2 s → 3.0 s", analysis_class="repo-wide", cold_seconds=5.2, warm_seconds=3.0,
|
|
358
|
-
field_seconds=
|
|
364
|
+
field_seconds=17.1, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
359
365
|
CommandCache("chunk-file", (), "none", False, "Reads one file; nothing to cache.", analysis_class="core"),
|
|
360
366
|
CommandCache("cold-start", ("ris",), "answer", True,
|
|
361
367
|
"Reads the RIS a warm rebuilds — that is all it does. Without one it answers "
|
|
362
368
|
"`no_ris` instead of a snapshot.",
|
|
363
|
-
"0.2 s either way", analysis_class="core", cold_seconds=0.2, warm_seconds=0.2
|
|
369
|
+
"0.2 s either way", analysis_class="core", cold_seconds=0.2, warm_seconds=0.2,
|
|
370
|
+
field_seconds=0.4, field_cache_state="mixed", field_measured_version="5.1.0"),
|
|
371
|
+
CommandCache("timeline", (), "none", False, "Each sample is a fresh materialisation of a different commit, so nothing is shared between samples: two commits are two trees, and a cache keyed on a tree state can only ever serve one of them. The per-sample cost is measured and published in the payload.", analysis_class="ir"),
|
|
364
372
|
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"),
|
|
365
373
|
CommandCache("baseline", ("parse",), "shared", False,
|
|
366
374
|
"`capture`/`diff`/`trend` over architectural metrics. The field figure is `capture`, "
|
|
@@ -405,13 +413,15 @@ def _row(command: str) -> "CommandCache":
|
|
|
405
413
|
|
|
406
414
|
#: The headline anchor, read off the table rather than written twice (C3-100).
|
|
407
415
|
#: `spring-audit` is the command the whole series measured — 408 s (#13), 2 351 s
|
|
408
|
-
#: (#16), 8,4 s (#22) — so it is the row the front page quotes, and
|
|
409
|
-
#: means reading it, not copying it.
|
|
416
|
+
#: (#16), 8,4 s (#22), 31,0 s (#26) — so it is the row the front page quotes, and
|
|
417
|
+
#: quoting it means reading it, not copying it. The figure moving *up* between two
|
|
418
|
+
#: rounds with byte-identical payloads is the reason C3-110 exists: nothing in this
|
|
419
|
+
#: repository measured the direction, and the anchor is the only place it shows.
|
|
410
420
|
_FIELD_ANCHOR_ROW = _row("spring-audit")
|
|
411
421
|
FIELD_ANCHOR_SECONDS = _FIELD_ANCHOR_ROW.field_seconds
|
|
412
422
|
FIELD_ANCHOR_MEASURED_VERSION = _FIELD_ANCHOR_ROW.field_measured_version
|
|
413
423
|
FIELD_ANCHOR = (
|
|
414
|
-
f"field evaluation #
|
|
424
|
+
f"field evaluation #26: spring-audit on {_thousands(FIELD_ANCHOR_JAVA_FILES)} "
|
|
415
425
|
f"Java files took {FIELD_ANCHOR_SECONDS:g} s (Windows, pipx, "
|
|
416
426
|
f"{_FIELD_ANCHOR_ROW.field_cache_state} cache) against "
|
|
417
427
|
f"{_FIELD_ANCHOR_ROW.cold_seconds:g} s on the "
|
|
@@ -532,6 +542,37 @@ def field_anchor_note(row: "Optional[CommandCache]") -> "Optional[str]":
|
|
|
532
542
|
return f"on {measured_on}"
|
|
533
543
|
|
|
534
544
|
|
|
545
|
+
def field_anchor_currency_clause(row: "Optional[CommandCache]") -> "Optional[str]":
|
|
546
|
+
"""The same fact as :func:`field_anchor_note`, said where it is *acted on* (C3-110).
|
|
547
|
+
|
|
548
|
+
C3-109 made every field figure carry its build, and the eleventh round confirms
|
|
549
|
+
the label is read and believed — and then reports the gap it does not close:
|
|
550
|
+
`spring-audit` publishes *"8,4 s … (4.18.0)"* while the same command measures
|
|
551
|
+
31,0 s on the build the reader is running. `(on 4.18.0)` is the right label for
|
|
552
|
+
a **row in a table**, where the reader is comparing figures; it is not enough
|
|
553
|
+
on a line that tells somebody how to run something, because there the figure is
|
|
554
|
+
being used as advice about the build in hand.
|
|
555
|
+
|
|
556
|
+
So the same fact gets a longer form for the surfaces that advise: the build,
|
|
557
|
+
and the admission that nothing has re-measured it here. That admission is the
|
|
558
|
+
registry this product applies everywhere else (`counts_are_floor`,
|
|
559
|
+
`unchanged_for`, `confidence_basis`) and the one place it had not applied to
|
|
560
|
+
itself.
|
|
561
|
+
|
|
562
|
+
``None`` when the figure was taken on the running build — there is nothing to
|
|
563
|
+
admit — or when there is no figure at all.
|
|
564
|
+
"""
|
|
565
|
+
if row is None or (row.field_seconds is None and not row.field_blocked):
|
|
566
|
+
return None
|
|
567
|
+
from sourcecode import __version__
|
|
568
|
+
|
|
569
|
+
measured_on = row.field_measured_version
|
|
570
|
+
if measured_on == __version__:
|
|
571
|
+
return None
|
|
572
|
+
where = f"measured on {measured_on}" if measured_on else "build not recorded"
|
|
573
|
+
return f"{where}; this build has not been re-measured at that scale"
|
|
574
|
+
|
|
575
|
+
|
|
535
576
|
def cost_sentence() -> str:
|
|
536
577
|
"""The one paragraph the front page says about cost, derived here (CL-21).
|
|
537
578
|
|
|
@@ -544,15 +585,38 @@ def cost_sentence() -> str:
|
|
|
544
585
|
with. It is generated from the anchors instead, so refreshing them refreshes
|
|
545
586
|
the prose.
|
|
546
587
|
"""
|
|
588
|
+
from sourcecode import __version__
|
|
589
|
+
|
|
547
590
|
audit = next((r for r in COMMANDS if r.command == "spring-audit"), None)
|
|
548
591
|
seconds = FIELD_ANCHOR_SECONDS if audit is None or audit.field_seconds is None else audit.field_seconds
|
|
592
|
+
# C3-110: the figure is history the moment it is published, and this sentence
|
|
593
|
+
# is the surface a reader budgets against. The field measured 31,0 s where this
|
|
594
|
+
# line said 8,4 s, and the line was not wrong — it named 4.18.0 — it just left
|
|
595
|
+
# the reader to notice that 4.18.0 is not the build they are running. Said
|
|
596
|
+
# outright, and paired with the one figure this project *can* refresh: the gate
|
|
597
|
+
# measurement of the build in hand, when there is one.
|
|
598
|
+
stale = (
|
|
599
|
+
""
|
|
600
|
+
if FIELD_ANCHOR_MEASURED_VERSION == __version__
|
|
601
|
+
else f", and {__version__} has not been re-measured at that scale"
|
|
602
|
+
)
|
|
603
|
+
gate = ""
|
|
604
|
+
_gate_cell = gate_anchor("spring-audit")
|
|
605
|
+
_gate_state = gate_currency()
|
|
606
|
+
if _gate_cell and _gate_state.get("current"):
|
|
607
|
+
gate = (
|
|
608
|
+
f" On this build the release gate measured the same command at "
|
|
609
|
+
f"{_gate_cell['seconds']:g} s on a "
|
|
610
|
+
f"{_thousands(int(_gate_cell['java_files']))}-file repository "
|
|
611
|
+
f"({_gate_cell['cache_state']} cache, {_gate_cell['host_class']})."
|
|
612
|
+
)
|
|
549
613
|
return (
|
|
550
614
|
f"Cost tracks the command class and the build, not the file count: "
|
|
551
615
|
f"per-symbol queries are the fast path, inventory commands scale with "
|
|
552
616
|
f"files, and a repository-wide audit measured {seconds:g} s on a "
|
|
553
617
|
f"{_thousands(FIELD_ANCHOR_JAVA_FILES)}-file repository "
|
|
554
|
-
f"({FIELD_ANCHOR_MEASURED_VERSION}). `ask cache model` prints
|
|
555
|
-
f"and the build behind it for every command; "
|
|
618
|
+
f"({FIELD_ANCHOR_MEASURED_VERSION}{stale}).{gate} `ask cache model` prints "
|
|
619
|
+
f"the figure and the build behind it for every command; "
|
|
556
620
|
f"ASK_MAX_ANALYSIS_SECONDS/ASK_PROGRESS bound and narrate a run where CI "
|
|
557
621
|
f"wants an explicit budget."
|
|
558
622
|
)
|