sourcecode 5.9.29__py3-none-any.whl → 5.9.31__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 +1 -1
- sourcecode/_build_commit.py +3 -3
- sourcecode/_docs/DEFECT-LEDGER.md +70 -0
- sourcecode/_docs/USER_GUIDE.md +1 -1
- sourcecode/cli.py +172 -18
- sourcecode/detach.py +21 -1
- sourcecode/non_coverage.py +14 -3
- sourcecode/release_info.py +1 -1
- sourcecode/repository_ir.py +148 -62
- {sourcecode-5.9.29.dist-info → sourcecode-5.9.31.dist-info}/METADATA +3 -3
- {sourcecode-5.9.29.dist-info → sourcecode-5.9.31.dist-info}/RECORD +15 -15
- {sourcecode-5.9.29.dist-info → sourcecode-5.9.31.dist-info}/WHEEL +0 -0
- {sourcecode-5.9.29.dist-info → sourcecode-5.9.31.dist-info}/entry_points.txt +0 -0
- {sourcecode-5.9.29.dist-info → sourcecode-5.9.31.dist-info}/licenses/LICENSE +0 -0
- {sourcecode-5.9.29.dist-info → sourcecode-5.9.31.dist-info}/licenses/NOTICE +0 -0
sourcecode/__init__.py
CHANGED
sourcecode/_build_commit.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""Generated at build time by hatch_build.py. Do not edit (AUD-592-D04)."""
|
|
2
2
|
|
|
3
|
-
BUILD_COMMIT = '
|
|
4
|
-
CLOSURE_PROVENANCE = {'AUD-611-B05': {'commit': '', 'status': 'uncited'}, 'AUD-611-B06': {'commit': '', 'status': 'uncited'}, 'AUD-611-B07': {'commit': '', 'status': 'uncited'}, 'AUD-611-B08': {'commit': '', 'status': 'uncited'}, 'AUD-611-B09': {'commit': '', 'status': 'uncited'}, 'AUD-611-B10': {'commit': '', 'status': 'uncited'}, 'AUD-611-B11': {'commit': '', 'status': 'uncited'}, 'AUD-612-07': {'commit': '', 'status': 'uncited'}, 'AUD-612-09': {'commit': '', 'status': 'uncited'}, 'AUD-612-14': {'commit': '', 'status': 'uncited'}, 'AUD-612-B03': {'commit': '', 'status': 'uncited'}, 'AUD-612-B07': {'commit': '', 'status': 'uncited'}, 'AUD-612-B13': {'commit': '', 'status': 'uncited'}, 'AUD-612-E': {'commit': '', 'status': 'uncited'}, 'AUD-612-G': {'commit': '', 'status': 'uncited'}, 'AUD-612-I': {'commit': '', 'status': 'uncited'}, 'AUD-612-K': {'commit': '', 'status': 'uncited'}, 'AUD-612-M': {'commit': '', 'status': 'uncited'}, 'AUD-612-R': {'commit': '', 'status': 'uncited'}, 'AUD-613-ROOT': {'commit': '', 'status': 'uncited'}, 'AUD-614-07': {'commit': '', 'status': 'uncited'}, 'AUD-614-E': {'commit': '', 'status': 'uncited'}, 'AUD-614-F': {'commit': '', 'status': 'uncited'}, 'AUD-614-G': {'commit': '', 'status': 'uncited'}, 'AUD-614-I': {'commit': '', 'status': 'uncited'}, 'AUD-614-INTENT-TIE': {'commit': '', 'status': 'uncited'}, 'AUD-614-JUNIT4': {'commit': '', 'status': 'uncited'}, 'AUD-614-RISK-L0': {'commit': '', 'status': 'uncited'}, 'AUD-614-SELFTEST-TIMEOUT': {'commit': '', 'status': 'uncited'}, 'AUD-615-07': {'commit': '', 'status': 'uncited'}, 'AUD-615-COLD-COMPACT': {'commit': '', 'status': 'uncited'}, 'AUD-615-DRIFT': {'commit': '', 'status': 'uncited'}, 'AUD-615-E': {'commit': '', 'status': 'uncited'}, 'AUD-615-F': {'commit': '', 'status': 'uncited'}, 'AUD-615-INTENT-TIE': {'commit': '', 'status': 'uncited'}, 'AUD-615-JUNIT4': {'commit': '', 'status': 'uncited'}, 'AUD-615-RISK-L0': {'commit': '', 'status': 'uncited'}, 'AUD-615-SELFTEST-TIMEOUT': {'commit': '', 'status': 'uncited'}, 'AUD-616-E-PROV': {'commit': '', 'status': 'uncited'}, 'AUD-616-F, -RISK-L0, -SELFTEST-TIMEOUT, -INTENT-TIE, -DRIFT, -COLD-COMPACT, -E, -07': {'commit': '', 'status': 'uncited'}, 'AUD-616-INTENT-TIE-COV': {'commit': '', 'status': 'uncited'}, 'AUD-616-JUNIT4-SELF': {'commit': '', 'status': 'uncited'}, 'AUD-616-KOTLIN': {'commit': '', 'status': 'uncited'}, 'AUD-616-O': {'commit': '', 'status': 'uncited'}, 'AUD-616-P': {'commit': '', 'status': 'uncited'}, 'Suite hygiene': {'commit': '', 'status': 'uncited'}, 'Window': {'commit': '', 'status': 'uncited'}, '`ALT-25`': {'commit': '', 'status': 'uncited'}, '`ASK-FIELD-01`': {'commit': '829f9fa', 'status': 'present'}, '`ASK-FIELD-02`': {'commit': '6a659fa', 'status': 'present'}, '`ASK-FIELD-03`': {'commit': '55b0d51', 'status': 'present'}, '`AUD-588-F05`': {'commit': '470e4a4', 'status': 'present'}, '`AUD-590-B01` / `B-01`, `F-01`': {'commit': '', 'status': 'uncited'}, '`AUD-590-B02` / `B-02`, `F-02`': {'commit': '', 'status': 'uncited'}, '`AUD-590-B03` / `B-03`, `F-03`': {'commit': '', 'status': 'uncited'}, '`AUD-590-B04` / `B-04`, `F-04`': {'commit': '', 'status': 'uncited'}, '`AUD-590-R01` / `R-01`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A01` / `A-1`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A02` / `A-2`, `A-4`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A03` / `A-3`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A05` / `A-5`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A06` / `A-6`, `A-7`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A08` / `A-8`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A09` / `A-9`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A10` / `A-10`': {'commit': '', 'status': 'uncited'}, '`AUD-592-A02` / `A-1` second half, `§12.5`': {'commit': '63f3d61', 'status': 'present'}, '`AUD-592-B01` / `B-8`': {'commit': '8329614', 'status': 'present'}, '`AUD-592-D01` / `D-1`': {'commit': '0f8e03f', 'status': 'present'}, '`AUD-592-D02` / `D-2`': {'commit': '1d3db4d', 'status': 'present'}, '`AUD-592-D03` / `D-3`': {'commit': 'f28fe40', 'status': 'present'}, '`AUD-592-R01` / `A-1`': {'commit': '216025f', 'status': 'present'}, '`AUD-592-R02` / `N-4`, reopens `AUD-513-N04`': {'commit': 'ec3050d', 'status': 'present'}, '`AUD-593-N01` / `N-01`': {'commit': 'dd6a706', 'status': 'present'}, '`AUD-593-N02` / `N-02`': {'commit': 'f539787', 'status': 'present'}, '`AUD-593-N03` / `N-03`': {'commit': '1dd0b1c', 'status': 'present'}, '`AUD-593-N05` / `N-05`': {'commit': 'aa89388', 'status': 'present'}, '`AUD-593-N06` / `N-06`': {'commit': 'aa584a6', 'status': 'present'}, '`AUD-594-N04` / `D-5`, disclosure half of `B-3`': {'commit': 'a0060b7', 'status': 'present'}, '`AUD-594-X01` / `A-1`, residual of `AUD-593-N03`': {'commit': 'dd222b9', 'status': 'present'}, '`AUD-594-X02` / `A-1` second half': {'commit': '1193937', 'status': 'present'}, '`AUD-594-X03` / `X-03`, residual of `AUD-593-N01`': {'commit': 'e89e8f0', 'status': 'present'}, '`AUD-594-X04`': {'commit': '05b8cc9', 'status': 'present'}, '`AUD-595-A02` / `N-5`, advisory half of `AUD-588-B11`': {'commit': '3e15227', 'status': 'present'}, '`AUD-595-A03` / `B-6` exit-code half': {'commit': 'ab7285f', 'status': 'present'}, '`AUD-595-A05`': {'commit': 'e0b3d10', 'status': 'present'}, '`AUD-595-A07`, narrow half of `AUD-592-A02`': {'commit': 'cc15177', 'status': 'present'}, '`AUD-595-B01` / §B': {'commit': 'b77a1ad', 'status': 'present'}, '`AUD-595-Q01`': {'commit': '91a6566', 'status': 'present'}, '`AUD-596-A01` / `ASK-DET-001`': {'commit': 'fa508b4', 'status': 'present'}, '`AUD-596-A02` / `ASK-SELF-001`': {'commit': '4dfadc8', 'status': 'present'}, '`AUD-596-A03` / `ASK-C1-001`': {'commit': 'bffa3a6', 'status': 'present'}, '`AUD-596-A04` / `ASK-UX-003` + `ASK-UX-004`': {'commit': 'f0aac3c', 'status': 'present'}, '`AUD-596-B01` / `B-01`, harder witness for `BUG-6`': {'commit': '567d09d', 'status': 'present'}, '`AUD-596-B02` / `B-02`, class residual of `R2`': {'commit': '', 'status': 'uncited'}, '`AUD-596-B03` / `B-03`': {'commit': 'a8cb814', 'status': 'present'}, '`AUD-596-B06` / `B-06`': {'commit': '8107927', 'status': 'present'}, '`AUD-596-B07` / `B-07`, class residual of `AUD-592-R02`': {'commit': 'e060485', 'status': 'present'}, '`AUD-596-B09` / `B-09`': {'commit': '5b8146c', 'status': 'present'}, '`AUD-596-B10` / `B-10`': {'commit': '5cb994d', 'status': 'present'}, '`AUD-596-B16` / `B-16`': {'commit': '1507f69', 'status': 'present'}, '`AUD-596-D01` / `B-13` + `B-14`': {'commit': '0b1bdf0', 'status': 'present'}, '`AUD-596-D02` / `B-08`, residual of `AUD-594-N04`': {'commit': 'e7f73c3', 'status': 'present'}, '`AUD-596-D03` / `ASK-AGT-001`': {'commit': '8c46967', 'status': 'present'}, '`AUD-596-D04` / `B-18`': {'commit': '040f027', 'status': 'present'}, '`AUD-596-D05` / `B-19`': {'commit': 'fd2bf68', 'status': 'present'}, '`AUD-596-D06` / `B-20`': {'commit': '784cd83', 'status': 'present'}, '`AUD-596-D07` / `B-17`, half refuted': {'commit': 'c3ff822', 'status': 'present'}, '`AUD-596-D08` / `B-22`, class residual of `AUD-591-A06`': {'commit': 'b396c6a', 'status': 'present'}, '`AUD-596-D09` / `B-23`, surviving half of `B26`': {'commit': 'fd3d63f', 'status': 'present'}, '`AUD-596-D10` / `B-29`': {'commit': '', 'status': 'uncited'}, '`AUD-596-D11` / `ASK-UX-005`': {'commit': 'f4b4f77', 'status': 'present'}, '`AUD-596-D12` — six hints that send the reader back to the error': {'commit': '498df44', 'status': 'present'}, '`AUD-596-D13` / `B-28`': {'commit': '1014c72', 'status': 'present'}, '`AUD-596-D14` / `B-15`, narrow half of `B20`': {'commit': '10f2827', 'status': 'present'}, '`AUD-596-R01` / `B-05`': {'commit': '', 'status': 'uncited'}, '`AUD-596-X01` / `ASK-GATE-001`, gating half of `B24`': {'commit': 'e59c655', 'status': 'present'}, '`AUD-596-X02` / `ASK-UX-001` + `ASK-UX-002` + `B-21`': {'commit': 'f6ebf50', 'status': 'present'}, '`AUD-597-A01` / `ASK-UX-001` + `N-01`': {'commit': 'f8cf061', 'status': 'present'}, '`AUD-597-A02` / `ASK-UX-008` + `ASK-DOC-002`': {'commit': '9d47a4c', 'status': 'present'}, '`AUD-597-A03` / `ASK-DET-001`': {'commit': '4c7622a', 'status': 'present'}, '`AUD-597-A04` / `ASK-LEDGER-001`': {'commit': '46fb870', 'status': 'present'}, '`AUD-597-D01` / `B-04`': {'commit': '1094e6a', 'status': 'present'}, '`AUD-597-D02` / `ASK-DOC-001`': {'commit': 'ecb1bb7', 'status': 'present'}, '`AUD-597-D03` / `N-06`': {'commit': '9784333', 'status': 'present'}, '`AUD-597-D04` / `N-05`': {'commit': 'e51c087', 'status': 'present'}, '`AUD-597-D05` / `N-04`, fourth appearance of `C4-27`': {'commit': '9cccc15', 'status': 'present'}, '`AUD-597-D06` / `ASK-CLI-001`': {'commit': '178aa6d', 'status': 'present'}, '`AUD-597-D07` / `N-03`': {'commit': '9245e35', 'status': 'present'}, '`AUD-597-R01` / `ASK-PERF-001`': {'commit': '6910054', 'status': 'present'}, '`AUD-597-R02` / `ASK-ENC-001`': {'commit': 'ce6dac1', 'status': 'present'}, '`AUD-597-R03` / `ASK-UX-002`': {'commit': 'c57e50b', 'status': 'present'}, '`AUD-597-X01` / `ASK-BUILD-001` + `ASK-META-001` / `B-12`': {'commit': '354338b', 'status': 'present'}, '`AUD-598-B01` / `ASK-META-001`': {'commit': 'b2f7c65', 'status': 'present'}, '`AUD-598-B02` / `ASK-UX-002`': {'commit': '56a4bf7', 'status': 'present'}, '`AUD-598-B03` / `B-11`': {'commit': 'c63cb24', 'status': 'present'}, '`AUD-598-B04` / `N-02`': {'commit': '187937f', 'status': 'present'}, '`AUD-598-R01` / `ASK-PERF-002`': {'commit': '', 'status': 'uncited'}, '`AUD-598-X01` / `N-01` + `B-13` + `B-14` + `B-29` + `N-06`': {'commit': '6f2f5a4', 'status': 'present'}, '`AUD-600-B01` / `P-01`': {'commit': '366ffed', 'status': 'present'}, '`AUD-600-B02` / `P-02` + `ASK-PACK-002`': {'commit': '2a814c3', 'status': 'present'}, '`AUD-600-B03` / `ASK-PACK-001`': {'commit': '452f2a0', 'status': 'present'}, '`AUD-600-D01`': {'commit': '1224e1b', 'status': 'present'}, '`AUD-600-D02`': {'commit': 'eab8172', 'status': 'present'}, '`AUD-600-R01` / `R-01`': {'commit': '88add64', 'status': 'present'}, '`AUD-601-B01` / `N-02`, 5th round': {'commit': '', 'status': 'uncited'}, '`AUD-601-B02` / `ASK-PACK-004`': {'commit': '', 'status': 'uncited'}, '`AUD-601-D01` / `N-01`, `ASK-UX-001`, 5th round': {'commit': '', 'status': 'uncited'}, '`AUD-601-D02` / `B-13`, `B-14`, 5th round': {'commit': '', 'status': 'uncited'}, '`AUD-601-M01` / `B-26`, `B-27` retracted': {'commit': '', 'status': 'uncited'}, '`AUD-601-R01` / `R-02`': {'commit': '', 'status': 'uncited'}, '`AUD-619-WATCH`': {'commit': '', 'status': 'uncited'}, '`AUD-620-COMMAND-SURFACE`': {'commit': '', 'status': 'uncited'}, '`AUD-620-REVIEW-PR`': {'commit': '', 'status': 'uncited'}, '`AUD-621-REVIEW-PR`': {'commit': '', 'status': 'uncited'}, '`B-3`': {'commit': '773268d', 'status': 'present'}, '`B-6`': {'commit': '17c6e06', 'status': 'present'}, '`B-8`': {'commit': '8329614', 'status': 'present'}, '`BUG-13`': {'commit': '', 'status': 'uncited'}, '`BUG-15`': {'commit': '', 'status': 'uncited'}, '`BUG-16`': {'commit': '', 'status': 'uncited'}, '`BUG-21`': {'commit': '', 'status': 'uncited'}, '`BUG-3` / `443b345`': {'commit': '', 'status': 'uncited'}, '`BUG-4a` / `AUD-588-B11` residual': {'commit': '24b4185', 'status': 'present'}, '`BUG-4b` / `AUD-588-B11` residual': {'commit': '0376350', 'status': 'present'}, '`E-39`, class residual of `AUD-593-N06`': {'commit': '25fc11f', 'status': 'present'}, '`N-5`': {'commit': 'c68083f', 'status': 'present'}, '`N-7`': {'commit': '082e9de', 'status': 'present'}, '`NEW-02` / `BUG-05`': {'commit': '', 'status': 'uncited'}, '`R-1`': {'commit': '424fb1c', 'status': 'present'}, '`R-2`': {'commit': '5158b92', 'status': 'present'}, '`R-3`': {'commit': '88aec04', 'status': 'present'}, '`R-4`': {'commit': '04fd04f', 'status': 'present'}, '`REG-01`': {'commit': '', 'status': 'uncited'}, '`REG-04`': {'commit': '', 'status': 'uncited'}, '`retrieve security-surface --target`': {'commit': '', 'status': 'uncited'}}
|
|
5
|
-
CLOSURE_COVERAGE = {'closed_rows':
|
|
3
|
+
BUILD_COMMIT = '1cca45c9b950c882c44b7a21aaad5e230cdddab7'
|
|
4
|
+
CLOSURE_PROVENANCE = {'AUD-611-B05': {'commit': '', 'status': 'uncited'}, 'AUD-611-B06': {'commit': '', 'status': 'uncited'}, 'AUD-611-B07': {'commit': '', 'status': 'uncited'}, 'AUD-611-B08': {'commit': '', 'status': 'uncited'}, 'AUD-611-B09': {'commit': '', 'status': 'uncited'}, 'AUD-611-B10': {'commit': '', 'status': 'uncited'}, 'AUD-611-B11': {'commit': '', 'status': 'uncited'}, 'AUD-612-07': {'commit': '', 'status': 'uncited'}, 'AUD-612-09': {'commit': '', 'status': 'uncited'}, 'AUD-612-14': {'commit': '', 'status': 'uncited'}, 'AUD-612-B03': {'commit': '', 'status': 'uncited'}, 'AUD-612-B07': {'commit': '', 'status': 'uncited'}, 'AUD-612-B13': {'commit': '', 'status': 'uncited'}, 'AUD-612-E': {'commit': '', 'status': 'uncited'}, 'AUD-612-G': {'commit': '', 'status': 'uncited'}, 'AUD-612-I': {'commit': '', 'status': 'uncited'}, 'AUD-612-K': {'commit': '', 'status': 'uncited'}, 'AUD-612-M': {'commit': '', 'status': 'uncited'}, 'AUD-612-R': {'commit': '', 'status': 'uncited'}, 'AUD-613-ROOT': {'commit': '', 'status': 'uncited'}, 'AUD-614-07': {'commit': '', 'status': 'uncited'}, 'AUD-614-E': {'commit': '', 'status': 'uncited'}, 'AUD-614-F': {'commit': '', 'status': 'uncited'}, 'AUD-614-G': {'commit': '', 'status': 'uncited'}, 'AUD-614-I': {'commit': '', 'status': 'uncited'}, 'AUD-614-INTENT-TIE': {'commit': '', 'status': 'uncited'}, 'AUD-614-JUNIT4': {'commit': '', 'status': 'uncited'}, 'AUD-614-RISK-L0': {'commit': '', 'status': 'uncited'}, 'AUD-614-SELFTEST-TIMEOUT': {'commit': '', 'status': 'uncited'}, 'AUD-615-07': {'commit': '', 'status': 'uncited'}, 'AUD-615-COLD-COMPACT': {'commit': '', 'status': 'uncited'}, 'AUD-615-DRIFT': {'commit': '', 'status': 'uncited'}, 'AUD-615-E': {'commit': '', 'status': 'uncited'}, 'AUD-615-F': {'commit': '', 'status': 'uncited'}, 'AUD-615-INTENT-TIE': {'commit': '', 'status': 'uncited'}, 'AUD-615-JUNIT4': {'commit': '', 'status': 'uncited'}, 'AUD-615-RISK-L0': {'commit': '', 'status': 'uncited'}, 'AUD-615-SELFTEST-TIMEOUT': {'commit': '', 'status': 'uncited'}, 'AUD-616-E-PROV': {'commit': '', 'status': 'uncited'}, 'AUD-616-F, -RISK-L0, -SELFTEST-TIMEOUT, -INTENT-TIE, -DRIFT, -COLD-COMPACT, -E, -07': {'commit': '', 'status': 'uncited'}, 'AUD-616-INTENT-TIE-COV': {'commit': '', 'status': 'uncited'}, 'AUD-616-JUNIT4-SELF': {'commit': '', 'status': 'uncited'}, 'AUD-616-KOTLIN': {'commit': '', 'status': 'uncited'}, 'AUD-616-O': {'commit': '', 'status': 'uncited'}, 'AUD-616-P': {'commit': '', 'status': 'uncited'}, 'Suite hygiene': {'commit': '', 'status': 'uncited'}, 'Window': {'commit': '', 'status': 'uncited'}, '`ALT-08` (arithmetic half)': {'commit': '', 'status': 'uncited'}, '`ALT-25`': {'commit': '', 'status': 'uncited'}, '`ASK-FIELD-01`': {'commit': '829f9fa', 'status': 'present'}, '`ASK-FIELD-02`': {'commit': '6a659fa', 'status': 'present'}, '`ASK-FIELD-03`': {'commit': '55b0d51', 'status': 'present'}, '`AUD-588-F05`': {'commit': '470e4a4', 'status': 'present'}, '`AUD-590-B01` / `B-01`, `F-01`': {'commit': '', 'status': 'uncited'}, '`AUD-590-B02` / `B-02`, `F-02`': {'commit': '', 'status': 'uncited'}, '`AUD-590-B03` / `B-03`, `F-03`': {'commit': '', 'status': 'uncited'}, '`AUD-590-B04` / `B-04`, `F-04`': {'commit': '', 'status': 'uncited'}, '`AUD-590-R01` / `R-01`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A01` / `A-1`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A02` / `A-2`, `A-4`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A03` / `A-3`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A05` / `A-5`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A06` / `A-6`, `A-7`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A08` / `A-8`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A09` / `A-9`': {'commit': '', 'status': 'uncited'}, '`AUD-591-A10` / `A-10`': {'commit': '', 'status': 'uncited'}, '`AUD-592-A02` / `A-1` second half, `§12.5`': {'commit': '63f3d61', 'status': 'present'}, '`AUD-592-B01` / `B-8`': {'commit': '8329614', 'status': 'present'}, '`AUD-592-D01` / `D-1`': {'commit': '0f8e03f', 'status': 'present'}, '`AUD-592-D02` / `D-2`': {'commit': '1d3db4d', 'status': 'present'}, '`AUD-592-D03` / `D-3`': {'commit': 'f28fe40', 'status': 'present'}, '`AUD-592-R01` / `A-1`': {'commit': '216025f', 'status': 'present'}, '`AUD-592-R02` / `N-4`, reopens `AUD-513-N04`': {'commit': 'ec3050d', 'status': 'present'}, '`AUD-593-N01` / `N-01`': {'commit': 'dd6a706', 'status': 'present'}, '`AUD-593-N02` / `N-02`': {'commit': 'f539787', 'status': 'present'}, '`AUD-593-N03` / `N-03`': {'commit': '1dd0b1c', 'status': 'present'}, '`AUD-593-N05` / `N-05`': {'commit': 'aa89388', 'status': 'present'}, '`AUD-593-N06` / `N-06`': {'commit': 'aa584a6', 'status': 'present'}, '`AUD-594-N04` / `D-5`, disclosure half of `B-3`': {'commit': 'a0060b7', 'status': 'present'}, '`AUD-594-X01` / `A-1`, residual of `AUD-593-N03`': {'commit': 'dd222b9', 'status': 'present'}, '`AUD-594-X02` / `A-1` second half': {'commit': '1193937', 'status': 'present'}, '`AUD-594-X03` / `X-03`, residual of `AUD-593-N01`': {'commit': 'e89e8f0', 'status': 'present'}, '`AUD-594-X04`': {'commit': '05b8cc9', 'status': 'present'}, '`AUD-595-A02` / `N-5`, advisory half of `AUD-588-B11`': {'commit': '3e15227', 'status': 'present'}, '`AUD-595-A03` / `B-6` exit-code half': {'commit': 'ab7285f', 'status': 'present'}, '`AUD-595-A05`': {'commit': 'e0b3d10', 'status': 'present'}, '`AUD-595-A07`, narrow half of `AUD-592-A02`': {'commit': 'cc15177', 'status': 'present'}, '`AUD-595-B01` / §B': {'commit': 'b77a1ad', 'status': 'present'}, '`AUD-595-Q01`': {'commit': '91a6566', 'status': 'present'}, '`AUD-596-A01` / `ASK-DET-001`': {'commit': 'fa508b4', 'status': 'present'}, '`AUD-596-A02` / `ASK-SELF-001`': {'commit': '4dfadc8', 'status': 'present'}, '`AUD-596-A03` / `ASK-C1-001`': {'commit': 'bffa3a6', 'status': 'present'}, '`AUD-596-A04` / `ASK-UX-003` + `ASK-UX-004`': {'commit': 'f0aac3c', 'status': 'present'}, '`AUD-596-B01` / `B-01`, harder witness for `BUG-6`': {'commit': '567d09d', 'status': 'present'}, '`AUD-596-B02` / `B-02`, class residual of `R2`': {'commit': '', 'status': 'uncited'}, '`AUD-596-B03` / `B-03`': {'commit': 'a8cb814', 'status': 'present'}, '`AUD-596-B06` / `B-06`': {'commit': '8107927', 'status': 'present'}, '`AUD-596-B07` / `B-07`, class residual of `AUD-592-R02`': {'commit': 'e060485', 'status': 'present'}, '`AUD-596-B09` / `B-09`': {'commit': '5b8146c', 'status': 'present'}, '`AUD-596-B10` / `B-10`': {'commit': '5cb994d', 'status': 'present'}, '`AUD-596-B16` / `B-16`': {'commit': '1507f69', 'status': 'present'}, '`AUD-596-D01` / `B-13` + `B-14`': {'commit': '0b1bdf0', 'status': 'present'}, '`AUD-596-D02` / `B-08`, residual of `AUD-594-N04`': {'commit': 'e7f73c3', 'status': 'present'}, '`AUD-596-D03` / `ASK-AGT-001`': {'commit': '8c46967', 'status': 'present'}, '`AUD-596-D04` / `B-18`': {'commit': '040f027', 'status': 'present'}, '`AUD-596-D05` / `B-19`': {'commit': 'fd2bf68', 'status': 'present'}, '`AUD-596-D06` / `B-20`': {'commit': '784cd83', 'status': 'present'}, '`AUD-596-D07` / `B-17`, half refuted': {'commit': 'c3ff822', 'status': 'present'}, '`AUD-596-D08` / `B-22`, class residual of `AUD-591-A06`': {'commit': 'b396c6a', 'status': 'present'}, '`AUD-596-D09` / `B-23`, surviving half of `B26`': {'commit': 'fd3d63f', 'status': 'present'}, '`AUD-596-D10` / `B-29`': {'commit': '', 'status': 'uncited'}, '`AUD-596-D11` / `ASK-UX-005`': {'commit': 'f4b4f77', 'status': 'present'}, '`AUD-596-D12` — six hints that send the reader back to the error': {'commit': '498df44', 'status': 'present'}, '`AUD-596-D13` / `B-28`': {'commit': '1014c72', 'status': 'present'}, '`AUD-596-D14` / `B-15`, narrow half of `B20`': {'commit': '10f2827', 'status': 'present'}, '`AUD-596-R01` / `B-05`': {'commit': '', 'status': 'uncited'}, '`AUD-596-X01` / `ASK-GATE-001`, gating half of `B24`': {'commit': 'e59c655', 'status': 'present'}, '`AUD-596-X02` / `ASK-UX-001` + `ASK-UX-002` + `B-21`': {'commit': 'f6ebf50', 'status': 'present'}, '`AUD-597-A01` / `ASK-UX-001` + `N-01`': {'commit': 'f8cf061', 'status': 'present'}, '`AUD-597-A02` / `ASK-UX-008` + `ASK-DOC-002`': {'commit': '9d47a4c', 'status': 'present'}, '`AUD-597-A03` / `ASK-DET-001`': {'commit': '4c7622a', 'status': 'present'}, '`AUD-597-A04` / `ASK-LEDGER-001`': {'commit': '46fb870', 'status': 'present'}, '`AUD-597-D01` / `B-04`': {'commit': '1094e6a', 'status': 'present'}, '`AUD-597-D02` / `ASK-DOC-001`': {'commit': 'ecb1bb7', 'status': 'present'}, '`AUD-597-D03` / `N-06`': {'commit': '9784333', 'status': 'present'}, '`AUD-597-D04` / `N-05`': {'commit': 'e51c087', 'status': 'present'}, '`AUD-597-D05` / `N-04`, fourth appearance of `C4-27`': {'commit': '9cccc15', 'status': 'present'}, '`AUD-597-D06` / `ASK-CLI-001`': {'commit': '178aa6d', 'status': 'present'}, '`AUD-597-D07` / `N-03`': {'commit': '9245e35', 'status': 'present'}, '`AUD-597-R01` / `ASK-PERF-001`': {'commit': '6910054', 'status': 'present'}, '`AUD-597-R02` / `ASK-ENC-001`': {'commit': 'ce6dac1', 'status': 'present'}, '`AUD-597-R03` / `ASK-UX-002`': {'commit': 'c57e50b', 'status': 'present'}, '`AUD-597-X01` / `ASK-BUILD-001` + `ASK-META-001` / `B-12`': {'commit': '354338b', 'status': 'present'}, '`AUD-598-B01` / `ASK-META-001`': {'commit': 'b2f7c65', 'status': 'present'}, '`AUD-598-B02` / `ASK-UX-002`': {'commit': '56a4bf7', 'status': 'present'}, '`AUD-598-B03` / `B-11`': {'commit': 'c63cb24', 'status': 'present'}, '`AUD-598-B04` / `N-02`': {'commit': '187937f', 'status': 'present'}, '`AUD-598-R01` / `ASK-PERF-002`': {'commit': '', 'status': 'uncited'}, '`AUD-598-X01` / `N-01` + `B-13` + `B-14` + `B-29` + `N-06`': {'commit': '6f2f5a4', 'status': 'present'}, '`AUD-600-B01` / `P-01`': {'commit': '366ffed', 'status': 'present'}, '`AUD-600-B02` / `P-02` + `ASK-PACK-002`': {'commit': '2a814c3', 'status': 'present'}, '`AUD-600-B03` / `ASK-PACK-001`': {'commit': '452f2a0', 'status': 'present'}, '`AUD-600-D01`': {'commit': '1224e1b', 'status': 'present'}, '`AUD-600-D02`': {'commit': 'eab8172', 'status': 'present'}, '`AUD-600-R01` / `R-01`': {'commit': '88add64', 'status': 'present'}, '`AUD-601-B01` / `N-02`, 5th round': {'commit': '', 'status': 'uncited'}, '`AUD-601-B02` / `ASK-PACK-004`': {'commit': '', 'status': 'uncited'}, '`AUD-601-D01` / `N-01`, `ASK-UX-001`, 5th round': {'commit': '', 'status': 'uncited'}, '`AUD-601-D02` / `B-13`, `B-14`, 5th round': {'commit': '', 'status': 'uncited'}, '`AUD-601-M01` / `B-26`, `B-27` retracted': {'commit': '', 'status': 'uncited'}, '`AUD-601-R01` / `R-02`': {'commit': '', 'status': 'uncited'}, '`AUD-619-WATCH`': {'commit': '', 'status': 'uncited'}, '`AUD-620-COMMAND-SURFACE`': {'commit': '', 'status': 'uncited'}, '`AUD-620-REVIEW-PR`': {'commit': '', 'status': 'uncited'}, '`AUD-621-REVIEW-PR`': {'commit': '', 'status': 'uncited'}, '`B-3`': {'commit': '773268d', 'status': 'present'}, '`B-6`': {'commit': '17c6e06', 'status': 'present'}, '`B-8`': {'commit': '8329614', 'status': 'present'}, '`BUG-03` (statement half)': {'commit': '', 'status': 'uncited'}, '`BUG-09`': {'commit': '', 'status': 'uncited'}, '`BUG-10` (Vert.x residual)': {'commit': '', 'status': 'uncited'}, '`BUG-13`': {'commit': '', 'status': 'uncited'}, '`BUG-13`, `BUG-15`, `BUG-17`, `BUG-21`, `BUG-08`, `BUG-10`/`BUG-23`': {'commit': '', 'status': 'uncited'}, '`BUG-14`': {'commit': '', 'status': 'uncited'}, '`BUG-15`': {'commit': '', 'status': 'uncited'}, '`BUG-16`': {'commit': '', 'status': 'uncited'}, '`BUG-20`': {'commit': '', 'status': 'uncited'}, '`BUG-21`': {'commit': '', 'status': 'uncited'}, '`BUG-3` / `443b345`': {'commit': '', 'status': 'uncited'}, '`BUG-4a` / `AUD-588-B11` residual': {'commit': '24b4185', 'status': 'present'}, '`BUG-4b` / `AUD-588-B11` residual': {'commit': '0376350', 'status': 'present'}, '`E-39`, class residual of `AUD-593-N06`': {'commit': '25fc11f', 'status': 'present'}, '`N-5`': {'commit': 'c68083f', 'status': 'present'}, '`N-7`': {'commit': '082e9de', 'status': 'present'}, '`NEW-01` (regime row)': {'commit': '', 'status': 'uncited'}, '`NEW-02` / `BUG-05`': {'commit': '', 'status': 'uncited'}, '`R-01-INFLIGHT` (stage capture)': {'commit': '', 'status': 'uncited'}, '`R-1`': {'commit': '424fb1c', 'status': 'present'}, '`R-2`': {'commit': '5158b92', 'status': 'present'}, '`R-3`': {'commit': '88aec04', 'status': 'present'}, '`R-4`': {'commit': '04fd04f', 'status': 'present'}, '`REG-01`': {'commit': '', 'status': 'uncited'}, '`REG-04`': {'commit': '', 'status': 'uncited'}, '`SEC-010` cost': {'commit': '', 'status': 'uncited'}, '`retrieve security-surface --target`': {'commit': '', 'status': 'uncited'}}
|
|
5
|
+
CLOSURE_COVERAGE = {'closed_rows': 185, 'present': 91, 'absent': 0, 'unresolved': 0, 'uncited': 94, 'unknown': 0}
|
|
@@ -14,6 +14,76 @@ Status values: `open` · `in-progress` · `closed <version>` · `by-design` (wit
|
|
|
14
14
|
The facts these rows are keyed to are published: `ask schema facts-v1` prints the registry
|
|
15
15
|
(authority, definition, consumers, parity test) that the release battery enforces.
|
|
16
16
|
|
|
17
|
+
## Current Synchronization — Release `5.9.30`, nine rows worked on the 5.9.29 queue (2026-09-02)
|
|
18
|
+
|
|
19
|
+
**A full pass over the open queue from the two 5.9.29 audits, one commit per
|
|
20
|
+
row, batteries run against every change.** Nine rows closed or materially
|
|
21
|
+
narrowed; two — `R-02` and the `pack assessment` default — investigated and
|
|
22
|
+
left open with the reasoning recorded, rather than guessed at.
|
|
23
|
+
|
|
24
|
+
| ID | Severity | Status | Evidence and required closure |
|
|
25
|
+
|---|---:|---|---|
|
|
26
|
+
| `R-01-INFLIGHT` (stage capture) | High | **closed** | `Progress.work()`'s sink was built only when the visible heartbeat was *enabled* — false off a TTY, in CI, under `NO_COLOR`, and piped through `timeout`, the field's configuration in all seven sessions. `_work_sink`/`_rule_pass_progress` now build the sink whenever a `Progress`/deadline object exists at all: `Progress.work()` is cheap regardless of whether it prints (a lock, a tuple compare, `_beat()`'s own internal `enabled` check), so an unwatched run's hang now records its stage exactly as a watched one does. Two invariant tests that pinned the old contract are updated to the corrected one; two new tests assert the unwatched case directly. |
|
|
27
|
+
| `R-02` (the process does not exit) | High | **one confirmed instance fixed, not proven to be the field's exact mechanism** | Auditing every background thread and process pool in this codebase found one genuine defect of this shape: the root `ask` command's async cache write started a `daemon=True` thread — specifically so an unfinished write could not hold up exit — and then registered `atexit.register(_cache_write_thread.join, 30.0)`, re-joining it anyway. Removed. `verify` itself does not go through this code path, so this is not asserted to be the auditor's exact mechanism; it is a real, independently confirmed instance of the same failure class, fixed on the same principle the codebase already states elsewhere (`parse_cache._delete_behind`): a daemon thread's unfinished work costs the next run a cache miss, not the caller a wait after their answer already arrived. |
|
|
28
|
+
| `BUG-14` | High | **closed** | Same class as `BUG-13`, the pattern named by request: `plan TARGET [PATH]` read a lone positional as the change target, leaving `path` at its default `.` — over a workspace of nested repositories, that drove a full IR build with no validation. The same nested-repository guard now refuses before any build starts, naming the count, with `--allow-nested`, and the hint explicitly names the grammar confusion (`plan` reads a lone argument as the target, not the repository). |
|
|
29
|
+
| `BUG-01` | Critical maximum | **widened, closed for `endpoints`** | `build_repo_ir` already detected a file whose extracted symbols are not trustworthy and published it as `parse_failures`; `extract_java_endpoints` parses the same sources through its own independent loop and never ran that check. The exact field shape (`total: 1`, one file silently missing) had no honesty pattern to catch it — `zero_result_reason` only fires when the whole answer is empty. `_parse_health_row` is now the one authority both extractors call (`build_repo_ir`'s own behaviour verified byte-identical against its existing battery); `endpoints` publishes `parse_failures`/`parse_failures_basis` whenever non-empty, at any total. |
|
|
30
|
+
| `NEW-01` (regime row) | High | **closed** | 103/103 across four consecutive external rounds was never going to be closed by a fifth measurement — the ask was the product's own guarantee. `tests/test_new01_silent_empty_success_regime.py` runs the real CLI dispatch (not the guard functions mocked in isolation, which a separate existing file already covers) across the whole `REQUIRED_ANSWER_COMMANDS` population against a real fixture repository, and fails if any of them ever reports success with nothing behind it — verified non-vacuous before committing (5 of 6 commands exit 0 with 10-27 KB real payloads on the fixture; `verify` exits its own documented 2 for no contracts declared). |
|
|
31
|
+
| `BUG-03` (statement half) | High | **closed** | The merge-half fix (previous round) already made every audit-family surface correctly classify a majority non-Spring stack as `fit: "partial"` — verified end to end on struts (1,488 Java files, 5 beans) across `spring-audit`, `risk`, `posture` and `audit-report` (inherits it via the other two). What the audit's "mismo stack_fit.statement sin proporción" still named: the statement said only "marginal" in prose, with the raw counts published beside it but not divided for the reader. It now states the density directly — "5 of 1488 Java files carry a Spring bean (0.34%)" — and a `spring_density_pct` field carries the same number for a machine reader, published only on the partial branch. |
|
|
32
|
+
| `BUG-20` | Low | **closed** | The `--detach` envelope's `output` field carried whatever string the operator typed, with nothing saying which directory it was relative to — unusable from outside that invocation's shell. `_resolved_output_path` joins a relative path against the invocation's own root with `.absolute()`, not `.resolve()`: it states where the path points without canonicalising symlinks nobody asked to have normalised away, which is also what keeps the existing detach battery's exact-path assertions passing on macOS (`/var/...` vs `/private/var/...`). |
|
|
33
|
+
| `BUG-09` | Medium | **closed** | AUD-597-D06 unified three repository-flag spellings across the catalogue, but its mechanism only ever moved an alias into an empty *positional* slot. `compare`'s repository is the declared option `--path`, not a positional, so `compare A B --repo <r>` was never recognised — four rounds hit this exact repro. `_normalise_repository_option_flag` covers the second shape: where a command declares its repository as an option named `path`/`repo`/`dir`, any other alias is rewritten to the declared one, in place, with the same duplicate-spelling guard the positional case already has. |
|
|
34
|
+
| `BUG-10` (Vert.x residual) | Medium | **closed for Vert.x; Ktor stays out of scope** | The one repository of eleven left with only the generic disclaimer: Vert.x's Router is a fluent call chain (`router.get("/x").handler(...)`) with no `@` anywhere, structurally invisible to the annotation-shaped evidence rule. A second, equally vendor-neutral rule now catches it — an HTTP-verb method called with one path-like literal, chained into a handler-attachment call — guarded against firing on unrelated code (`Map.get("/key")` with no handler chain, a bare `.route().handler()` with no path). Ktor's routing DSL lives in `.kt` files, which this extractor never reads; extending file discovery to a second language is a different, larger change than this row. |
|
|
35
|
+
| `pack assessment` default | — | **investigated, left unchanged, reasoning recorded** | Reproduced on spring-petclinic: the unbounded default is 68.5K estimated tokens (over the 50K ceiling), `--compact` brings it to 35KB (well under). `--compact` genuinely bounds it — this was AUD-600-B02's own fix, verified still holding. The unbounded default measuring 2.29M tokens on a larger repository (that round's own number) makes clear the full report is a deliberately unbounded, opt-in answer, not an oversight: flipping the default would need a `--compact/--no-compact` toggle pair (today only `--compact` is declared) and would change behaviour for every existing caller who relies on the current default producing the full report on a repository small enough not to hit the ceiling. Left as a product-default question rather than changed unilaterally. |
|
|
36
|
+
|
|
37
|
+
Suite: run in full after the batch, same population as the last recorded
|
|
38
|
+
green run — see the commit history for the exact count. One vacuous
|
|
39
|
+
assertion introduced earlier in the session by this same battery (`or True`
|
|
40
|
+
in a stage-capture test) was caught by the suite's own mutation-testing
|
|
41
|
+
battery and fixed in the same pass, not left for an eighth round to find.
|
|
42
|
+
|
|
43
|
+
## Current Synchronization — Two audits of `5.9.29`: the audit family answers, and the marker's own gap (2026-09-02)
|
|
44
|
+
|
|
45
|
+
**Both lineages report the release positively and neither found a regression.**
|
|
46
|
+
The multi-repository round scores **8.5/10** (8.4 for 5.9.28, from 8.1) and
|
|
47
|
+
calls 5.9.29 a consolidation: nothing closed, nothing regressed, and the
|
|
48
|
+
coverage sweep byte-identical to the previous session across eleven
|
|
49
|
+
repositories — the 5.9.26–5.9.28 corrections hold under repetition rather than
|
|
50
|
+
being one-build accidents. The native-Windows round scores **7.8/10**, its
|
|
51
|
+
largest jump in seven, and reports the sentence six sessions could not
|
|
52
|
+
produce: **all six audit-family commands answered.** `spring-audit` 3/4,
|
|
53
|
+
`verify` 2/2, `risk` 1/1 and `audit-report` 1/1 (both firsts in six sessions),
|
|
54
|
+
`migrate-check`/`migrate-apply` 1/1 each, `remediate` 1/1 at 74,8 s after two
|
|
55
|
+
rounds of hanging. Full evidence:
|
|
56
|
+
[`AUDIT-2026-09-02-ALTERNATIVE-5.9.29.md`](AUDIT-2026-09-02-ALTERNATIVE-5.9.29.md)
|
|
57
|
+
and [`AUDIT-2026-09-02-EXTERNAL-5.9.29.md`](AUDIT-2026-09-02-EXTERNAL-5.9.29.md).
|
|
58
|
+
|
|
59
|
+
**The `SEC-010` work is confirmed from the field, with their numbers:** three
|
|
60
|
+
successive runs, one `content_id` (`4a0429c7784da360`), 385 findings each, and
|
|
61
|
+
the family's own clock falling 42,8 → 25,4 → 20,0 s as the cache warmed. The
|
|
62
|
+
command went 73,9 → 46,9 → 35,9 s. `selftest` rose from 1/12 to 6/12 passing
|
|
63
|
+
rows on the same deadline.
|
|
64
|
+
|
|
65
|
+
**And the in-flight marker did its job on the first try — including against
|
|
66
|
+
us.** It captured a hang, and what it captured contradicts part of what this
|
|
67
|
+
ledger assumed. See `R-01` below.
|
|
68
|
+
|
|
69
|
+
| ID | Severity | Status | Evidence and required closure |
|
|
70
|
+
|---|---:|---|---|
|
|
71
|
+
| `R-01` (phase attribution) | Critical maximum | **open, sharpest evidence in seven rounds** | The marker on the one hung run: `started_at` 1788411595,53 and `phase_entered_at` 1788411734,89 — **139,36 s spent before the run reached "applying all rules"**, about 70 % of the time it lived, with the stderr heartbeat agreeing (two warnings naming `auditing 3342 Java files`, then the rules phase for 41,4 s). The successful runs of the same session covered that whole stretch in ~72,7 s. The auditor's inference that the new `seeds()` pre-index moved the cost earlier is **refutable in source**: `_http_input_query_sinks` is called from `SEC-010`'s `analyze`, inside the `security_rules` phase — after the point their marker recorded. What sits in those 139 s is the CIR build, the XML security-configuration scan and the start of the semantic model, all published under one heartbeat label. Required work, adopted from their three requests: split that phase into visible sub-stages, publish the pre-index as its own timing entry, and repeat the bisection measuring that phase separately from the rules phase rather than only the total. |
|
|
72
|
+
| `R-01-INFLIGHT` (stage capture) | High | **open, defect in what 5.9.29 shipped, found by their evidence** | Their capture reads `last_stage: null` for the ~60 s the run spent in the rules phase, and null through the 139 s before it — in a phase whose stages the heartbeat does name. The cause is ours: stage capture rides on `Progress.work`, and the sink that calls it is built only when the heartbeat is **enabled**, which it is not off a TTY, in CI, under `NO_COLOR`, or piped through `timeout` — the field's configuration in all seven sessions. The marker's most useful field is therefore blank in exactly the environment it was built for. Closure: record the stage regardless of whether anything is watching. |
|
|
73
|
+
| `R-02` (the process does not exit) | High | **open, new failure class** | `timeout -k 5 200 ask verify .` returned `rc=124` with **5 333 bytes of a complete, valid answer** — `verdict: pass`, `contract_count: 14`, `content_id: ca00e3a40668e5bf`, `answer_bounds.complete: true`. Six sessions of hangs produced 0 bytes; this one finished the work and did not leave. Distinct from `ALT-01`/`ALT-03` and to be tracked apart: the analysis is not the problem here, the exit is. Candidates, one of them this product's own recent addition: a non-daemon thread outliving the answer — the parse worker pool, the heartbeat thread, or the concurrency lease. Closure: prove nothing this codebase starts can delay interpreter shutdown after the answer is written. |
|
|
74
|
+
| `SEC-010` cost | Medium | **closed 5.9.29, confirmed in the field** | Three runs, identical `content_id`, 42,8 → 25,4 → 20,0 s with the cache warming. The warm-path benefit the product promised and no session had observed. |
|
|
75
|
+
| `ALT-08` (arithmetic half) | Low | **closed, field verification received** | `ask prepare-context review-pr` — the correct command this time — gives `final_size_bytes: 93 462`, matching `len(json.dumps(payload without _meta))` byte for byte. |
|
|
76
|
+
| `ALT-01` / `ALT-03` | Critical maximum | **open, materially narrowed** | 3/4 and six families answering is the best measurement of seven rounds and is not the 25–30 repetitions per command this ledger requires. `R-01` above leaves open that the bottleneck was moved rather than removed, and this ledger does not close a row on a hypothesis it has just been given evidence against. |
|
|
77
|
+
| `NEW-01` (regime row) | High | **open, and the request is not for more measurement** | 103/103 across four consecutive versions in the multi-repository lineage. What is asked for is the product's own guarantee: the explanation of what fixed it, published in this ledger, plus an automated regime assertion, so closure stops depending on a recurring external audit. |
|
|
78
|
+
| `BUG-14` | High | **open, fourth round, fix pattern already exists here** | `ask plan <repo>` still hangs to an external kill at 45 s with an empty stderr, because a repository path is accepted where the signature reads `TARGET [PATH]`. Same class as `BUG-13`, which 5.9.28 closed by validating before starting, counting what it found and offering `--allow-nested`. The auditor asks for that pattern, by name, on this row. |
|
|
79
|
+
| `BUG-01` | Critical maximum | **open, and the honesty pattern needs widening** | A file with a parse error still disappears with no signal (`total: 1`, only `/ok`). `zero_result_reason` fires only at `total: 0`, so the disclosure that closed `BUG-10` does not reach this shape. Required: name files excluded by a parse failure at **any** total, not only when the answer is empty. |
|
|
80
|
+
| `BUG-10` (routing DSL residual) | Medium | **partially closed, residual named** | `unmodeled_routing_evidence` verified across 11 repositories (198 files of Micronaut annotations, 52 of Servlets, 6 of `@Route`/`@WebSocket`) and `null` where a repository has endpoints. A fluent router DSL carries no annotation and no path literal, so it yields neither evidence nor a declared gap — one repository of eleven is left with the generic disclaimer alone. |
|
|
81
|
+
| `REG-03` | Medium | **the auditor retracts their own claim** | The warm-path delta went −22,4 % → −9,2 % → **+24,0 %** on the same pair of consecutive invocations while absolute cold time fell 69,1 → 21,9 s. Their conclusion: system load at the moment of measurement dominates this metric, not ASK's cache state, and their 5.9.27 report of *the first real warm-cache gain ever observed* is withdrawn to "possible, not confirmed". Recorded here because a retraction by the party who made the claim is evidence, and because this product must not quote that figure as a benchmark either. |
|
|
82
|
+
| `REG-02` | Critical | **open, fourth consecutive round** | `--agent` fails by default on large repositories (1 623 MB and 2 572 MB observed, same range as three prior rounds, no trend either way). |
|
|
83
|
+
| `BUG-16` | Medium | **disclosure closed, size open** | The eviction contracts shipped in 5.9.29 are confirmed present through `cache status`. What the auditor still records is the size: 2,4 GB total, 1,8 GB of it the context cache. The contract this product publishes for that store is entry count and age, not bytes — which is honest and is also why the store can be this large. Whether it should have a byte budget is the open half. |
|
|
84
|
+
| `BUG-13`, `BUG-15`, `BUG-17`, `BUG-21`, `BUG-08`, `BUG-10`/`BUG-23` | — | **closed, stable under repetition** | Re-verified across four to five consecutive versions with no sign of relapse, and byte-identical coverage figures between the last two sessions. |
|
|
85
|
+
| `BUG-09`, `BUG-11`, `BUG-20`, `BUG-02`, `BUG-12`, `BUG-03` | — | **open, unchanged** | Flag vocabulary, `pack assessment` returning `OUTPUT_TOO_LARGE` by default (now with granular progress where it used to fail silently), an unresolved POSIX path under `--detach`, and the three rows that need the field's own large repository. |
|
|
86
|
+
|
|
17
87
|
## Current Synchronization — Release `5.9.29`, hardening pass and a green suite (2026-09-02)
|
|
18
88
|
|
|
19
89
|
**The suite is green — 13 748 tests, 0 failures — for the first time in
|
sourcecode/_docs/USER_GUIDE.md
CHANGED
sourcecode/cli.py
CHANGED
|
@@ -1206,6 +1206,71 @@ def _leaf_for_args(args: "list[str]") -> "tuple[Any, int]":
|
|
|
1206
1206
|
return None, 0
|
|
1207
1207
|
|
|
1208
1208
|
|
|
1209
|
+
def _normalise_repository_option_flag(
|
|
1210
|
+
args: "list[str]", *, leaf: Any, consumed: int, declared: "set[str]"
|
|
1211
|
+
) -> "Optional[list[str]]":
|
|
1212
|
+
"""BUG-09: the other shape AUD-597-D06 named and did not yet cover.
|
|
1213
|
+
|
|
1214
|
+
That row's own docstring lists three conventions — a positional (most of
|
|
1215
|
+
the catalogue), `--path` (`compare`), `--repo` (the ref forms of `delta`
|
|
1216
|
+
and `contract-diff`) — and the mechanism below it only ever reconciles
|
|
1217
|
+
the *first* against the other two: it moves an alias into an empty
|
|
1218
|
+
*positional* slot. `compare`'s repository is not positional, it is the
|
|
1219
|
+
option `--path` itself, so `compare A B --repo <r>` was never a spelling
|
|
1220
|
+
the rewrite recognised — `--repo` was simply not one of `compare`'s
|
|
1221
|
+
declared options, and Click refused it as such, four audit rounds
|
|
1222
|
+
running.
|
|
1223
|
+
|
|
1224
|
+
Where the command's repository lives in a declared OPTION named
|
|
1225
|
+
`path`/`repo`/`dir` (Click infers the option's `param.name` from the
|
|
1226
|
+
Python parameter the same way it does for a positional), any *other*
|
|
1227
|
+
alias spelling typed by the caller is rewritten in place to the one this
|
|
1228
|
+
command declares — in place, because unlike the positional case there is
|
|
1229
|
+
no slot to move the value into, only a flag token to rename beside the
|
|
1230
|
+
value that already follows it.
|
|
1231
|
+
"""
|
|
1232
|
+
option_slot = next(
|
|
1233
|
+
(
|
|
1234
|
+
param for param in (getattr(leaf, "params", None) or ())
|
|
1235
|
+
if not is_argument(param)
|
|
1236
|
+
and str(getattr(param, "name", "")) in _REPOSITORY_ARGUMENT_NAMES
|
|
1237
|
+
),
|
|
1238
|
+
None,
|
|
1239
|
+
)
|
|
1240
|
+
if option_slot is None:
|
|
1241
|
+
return None
|
|
1242
|
+
canonical = next(
|
|
1243
|
+
(a for a in _REPOSITORY_OPTION_ALIASES if a in declared), None
|
|
1244
|
+
)
|
|
1245
|
+
if canonical is None:
|
|
1246
|
+
return None
|
|
1247
|
+
other_aliases = [
|
|
1248
|
+
a for a in _REPOSITORY_OPTION_ALIASES if a != canonical and a not in declared
|
|
1249
|
+
]
|
|
1250
|
+
if not other_aliases:
|
|
1251
|
+
return None
|
|
1252
|
+
|
|
1253
|
+
rest = args[consumed:]
|
|
1254
|
+
if any(token.partition("=")[0] == canonical for token in rest):
|
|
1255
|
+
# The command's own spelling is already there — a second one is a
|
|
1256
|
+
# duplicate to refuse, not a spelling to accept, matching the
|
|
1257
|
+
# positional guard's own "every slot already named" rule.
|
|
1258
|
+
return None
|
|
1259
|
+
|
|
1260
|
+
rewritten = False
|
|
1261
|
+
out: "list[str]" = []
|
|
1262
|
+
for token in rest:
|
|
1263
|
+
name, sep, inline = token.partition("=")
|
|
1264
|
+
if not rewritten and name in other_aliases:
|
|
1265
|
+
out.append(canonical + (sep + inline if sep else ""))
|
|
1266
|
+
rewritten = True
|
|
1267
|
+
continue
|
|
1268
|
+
out.append(token)
|
|
1269
|
+
if not rewritten:
|
|
1270
|
+
return None
|
|
1271
|
+
return args[:consumed] + out
|
|
1272
|
+
|
|
1273
|
+
|
|
1209
1274
|
def _normalise_repository_option(args: "list[str]") -> "list[str]":
|
|
1210
1275
|
"""`--path <repo>` on a command that takes the repository positionally.
|
|
1211
1276
|
|
|
@@ -1236,7 +1301,12 @@ def _normalise_repository_option(args: "list[str]") -> "list[str]":
|
|
|
1236
1301
|
str(getattr(param, "name", "")) in _REPOSITORY_ARGUMENT_NAMES
|
|
1237
1302
|
for param in slots
|
|
1238
1303
|
):
|
|
1239
|
-
|
|
1304
|
+
# Not a positional-repository command — try the declared-option shape
|
|
1305
|
+
# (`compare --path`) before giving up on this command entirely.
|
|
1306
|
+
_flag_rewrite = _normalise_repository_option_flag(
|
|
1307
|
+
args, leaf=leaf, consumed=consumed, declared=declared
|
|
1308
|
+
)
|
|
1309
|
+
return args if _flag_rewrite is None else _flag_rewrite
|
|
1240
1310
|
|
|
1241
1311
|
aliases = [a for a in _REPOSITORY_OPTION_ALIASES if a not in declared]
|
|
1242
1312
|
if not aliases:
|
|
@@ -2937,10 +3007,22 @@ def _work_sink(prog: Any) -> Any:
|
|
|
2937
3007
|
waiting for — `phase=auditing 3342 Java files elapsed=6.8m` for 6,8 minutes,
|
|
2938
3008
|
with no denominator and no rate. The counts can only come from the loop doing
|
|
2939
3009
|
the work, so the analysis is given a sink rather than the spinner being given
|
|
2940
|
-
a guess. `None` when
|
|
2941
|
-
|
|
3010
|
+
a guess. `None` only when there is no `Progress` object at all (no command
|
|
3011
|
+
context to attribute counts to).
|
|
3012
|
+
|
|
3013
|
+
R-01-INFLIGHT (5.9.29 re-audit). This used to also return `None` when the
|
|
3014
|
+
heartbeat was disabled — off a TTY, in CI, under `NO_COLOR`, piped through
|
|
3015
|
+
`timeout` — which is the field's configuration in every one of seven
|
|
3016
|
+
sessions. That made `Progress.work()` unreachable on exactly the runs the
|
|
3017
|
+
in-flight marker exists to diagnose, so a captured hang read
|
|
3018
|
+
`last_stage: null` even mid-phase, in a phase whose sub-stages
|
|
3019
|
+
(`parsing`, `linking`, `assembling the IR`, `scanning XML security
|
|
3020
|
+
configuration`) the heartbeat already names. `prog.work()` is cheap by
|
|
3021
|
+
construction — a lock, a tuple compare, and `_beat()`'s own `enabled` check
|
|
3022
|
+
— so calling it unconditionally costs nothing extra on a watched run and
|
|
3023
|
+
gives an unwatched one the same forensic stage capture.
|
|
2942
3024
|
"""
|
|
2943
|
-
if prog is None
|
|
3025
|
+
if prog is None:
|
|
2944
3026
|
return None
|
|
2945
3027
|
|
|
2946
3028
|
def sink(done: int, total: int, stage: str) -> None:
|
|
@@ -2982,26 +3064,35 @@ def _rule_pass_progress(
|
|
|
2982
3064
|
"""
|
|
2983
3065
|
from sourcecode.rule_pass import RulePassProgress
|
|
2984
3066
|
|
|
2985
|
-
|
|
2986
|
-
|
|
3067
|
+
# R-01-INFLIGHT (5.9.29 re-audit). `sink`/`detail_sink` used to be built
|
|
3068
|
+
# only when a heartbeat was actively watching, so a family's stage detail
|
|
3069
|
+
# (`SEC-010: parsing callees 129/772 files`) never reached `prog.work()`
|
|
3070
|
+
# on an unwatched run — exactly the field's configuration. `prog.work()`
|
|
3071
|
+
# is cheap regardless of whether it prints, so the sinks are built
|
|
3072
|
+
# whenever a `Progress` object exists at all; `stop_when` already forced
|
|
3073
|
+
# this object into existence for the deadline's sake, and now the same
|
|
3074
|
+
# object also gives an unwatched run's hang its forensic stage.
|
|
3075
|
+
if prog is None and stop_when is None:
|
|
2987
3076
|
return None
|
|
2988
3077
|
|
|
2989
3078
|
def sink(done: int, total: int, rule_id: str) -> None:
|
|
2990
|
-
prog
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
3079
|
+
if prog is not None:
|
|
3080
|
+
prog.work(
|
|
3081
|
+
done, total,
|
|
3082
|
+
stage=f"{stage} ({rule_id})",
|
|
3083
|
+
unit=unit,
|
|
3084
|
+
estimate=False,
|
|
3085
|
+
)
|
|
2996
3086
|
|
|
2997
3087
|
def detail_sink(done: int, total: int, label: str, detail_unit: str) -> None:
|
|
2998
3088
|
# C3-79: inside a family the units *are* comparable to each other — files
|
|
2999
3089
|
# are files — so the ETA is allowed here, unlike the family counter above.
|
|
3000
|
-
prog
|
|
3090
|
+
if prog is not None:
|
|
3091
|
+
prog.work(done, total, stage=f"{stage} ({label})", unit=detail_unit)
|
|
3001
3092
|
|
|
3002
3093
|
return RulePassProgress(
|
|
3003
|
-
sink=sink if
|
|
3004
|
-
detail_sink=detail_sink if
|
|
3094
|
+
sink=sink if prog is not None else None,
|
|
3095
|
+
detail_sink=detail_sink if prog is not None else None,
|
|
3005
3096
|
stop_when=stop_when,
|
|
3006
3097
|
)
|
|
3007
3098
|
|
|
@@ -4806,10 +4897,19 @@ def _get_command_with_preprocessing(typer_instance: Any) -> Any:
|
|
|
4806
4897
|
started = time.monotonic()
|
|
4807
4898
|
command = _telemetry_command(args)
|
|
4808
4899
|
success = True
|
|
4900
|
+
error_kind = None
|
|
4809
4901
|
try:
|
|
4810
4902
|
return _orig_cmd_main(args=args, **kwargs)
|
|
4811
|
-
except
|
|
4903
|
+
except SystemExit as exc:
|
|
4904
|
+
# Click uses SystemExit(0) even after successful CLI/MCP calls.
|
|
4905
|
+
# Preserve its exit while recording the outcome, not the exception.
|
|
4906
|
+
success = exc.code is None or exc.code == 0
|
|
4907
|
+
if not success:
|
|
4908
|
+
error_kind = type(exc).__name__
|
|
4909
|
+
raise
|
|
4910
|
+
except BaseException as exc:
|
|
4812
4911
|
success = False
|
|
4912
|
+
error_kind = type(exc).__name__
|
|
4813
4913
|
raise
|
|
4814
4914
|
finally:
|
|
4815
4915
|
try:
|
|
@@ -4821,6 +4921,7 @@ def _get_command_with_preprocessing(typer_instance: Any) -> Any:
|
|
|
4821
4921
|
flags=_telemetry_flags(args),
|
|
4822
4922
|
duration_s=time.monotonic() - started,
|
|
4823
4923
|
success=success,
|
|
4924
|
+
error_kind=error_kind,
|
|
4824
4925
|
)
|
|
4825
4926
|
except Exception:
|
|
4826
4927
|
pass
|
|
@@ -7618,10 +7719,27 @@ def main(
|
|
|
7618
7719
|
if os.environ.get("SOURCECODE_CACHE_SYNC") in ("1", "true", "yes"):
|
|
7619
7720
|
_write_cache_async()
|
|
7620
7721
|
else:
|
|
7621
|
-
|
|
7722
|
+
# R-02 (5.9.29 re-audit): this used to register
|
|
7723
|
+
# `atexit.register(_cache_write_thread.join, 30.0)` — a
|
|
7724
|
+
# blocking join on a thread the two lines above deliberately
|
|
7725
|
+
# made `daemon=True` so it would NOT hold up exit. The field
|
|
7726
|
+
# measured a `verify` invocation that wrote a complete, valid
|
|
7727
|
+
# answer to stdout and was still killed by an external
|
|
7728
|
+
# 200-second timeout: the work was done, the process would
|
|
7729
|
+
# not leave. A daemon thread that gets re-joined at atexit is
|
|
7730
|
+
# not asynchronous, it is synchronous with extra steps, on
|
|
7731
|
+
# exactly the machine where a slow disk or a contended cache
|
|
7732
|
+
# directory (the customer's own R-01 environment) makes that
|
|
7733
|
+
# 30-second bound real rather than theoretical. The comment
|
|
7734
|
+
# above already states the intent — "low-latency asynchronous
|
|
7735
|
+
# path for ordinary analysis" — this now matches it: if the
|
|
7736
|
+
# write has not landed by the time the interpreter tears
|
|
7737
|
+
# down, it is lost, same as any other daemon thread's
|
|
7738
|
+
# unfinished work, and the next run pays a cache miss instead
|
|
7739
|
+
# of the caller paying an unexplained wait after their answer
|
|
7740
|
+
# already arrived.
|
|
7622
7741
|
_cache_write_thread = _threading.Thread(target=_write_cache_async, daemon=True)
|
|
7623
7742
|
_cache_write_thread.start()
|
|
7624
|
-
_atexit.register(_cache_write_thread.join, 30.0)
|
|
7625
7743
|
|
|
7626
7744
|
# Update RIS with aggregated snapshot data (non-fatal side-effect).
|
|
7627
7745
|
# Update RIS whenever git is available, even when L1/L2 cache is skipped
|
|
@@ -10987,6 +11105,11 @@ def plan_cmd(
|
|
|
10987
11105
|
None, "--output", "-o",
|
|
10988
11106
|
help="Write output to a file instead of stdout.",
|
|
10989
11107
|
),
|
|
11108
|
+
allow_nested: bool = typer.Option(
|
|
11109
|
+
False, "--allow-nested",
|
|
11110
|
+
help="Run anyway when the implicit `.` covers nested Git repositories "
|
|
11111
|
+
"(BUG-14, same class as BUG-13). The default refuses.",
|
|
11112
|
+
),
|
|
10990
11113
|
format: str = _format_option(help="Output format: json (default) or yaml."),
|
|
10991
11114
|
copy: bool = _copy_option(),
|
|
10992
11115
|
progress_mode: Optional[str] = _progress_option(),
|
|
@@ -11015,6 +11138,37 @@ def plan_cmd(
|
|
|
11015
11138
|
|
|
11016
11139
|
target_dir = _admit_path(path, usage="ask plan <target> <path>")
|
|
11017
11140
|
|
|
11141
|
+
# BUG-14, same class as BUG-13. `plan TARGET [PATH]` took a single
|
|
11142
|
+
# positional argument in the field (`ask plan spring-petclinic`) and
|
|
11143
|
+
# Click's grammar consumed it as `target`, silently leaving `path` at its
|
|
11144
|
+
# default `.` — over a workspace of 31 nested Git repositories, that
|
|
11145
|
+
# implicit `.` drove a full IR build over the whole workspace with no
|
|
11146
|
+
# validation, and the field cut it at 45s with an empty stderr, nothing
|
|
11147
|
+
# this product's own guard for `selftest` would have allowed. The same
|
|
11148
|
+
# guard applies here: an implicit `.` that covers nested repositories is
|
|
11149
|
+
# refused before any expensive work starts, with the same escape hatch.
|
|
11150
|
+
if str(path) == ".":
|
|
11151
|
+
from sourcecode.selftest import nested_repository_count
|
|
11152
|
+
|
|
11153
|
+
_nested = nested_repository_count(target_dir)
|
|
11154
|
+
if _nested and not allow_nested:
|
|
11155
|
+
_emit_error_json(
|
|
11156
|
+
INVALID_USAGE_CODE,
|
|
11157
|
+
f"plan refuses an unscoped run: the implicit `.` covers "
|
|
11158
|
+
f"{_nested} nested Git repository(s), so the change plan "
|
|
11159
|
+
f"would build its IR over a workspace rather than a "
|
|
11160
|
+
f"repository.",
|
|
11161
|
+
hint=(
|
|
11162
|
+
"Pass the repository explicitly (`ask plan <target> "
|
|
11163
|
+
"<path/to/repo>`), or `--allow-nested` to run over the "
|
|
11164
|
+
"workspace on purpose. If `<target>` was meant to name "
|
|
11165
|
+
"the repository, `plan` reads it as the change target — "
|
|
11166
|
+
"the repository is the second, optional argument."
|
|
11167
|
+
),
|
|
11168
|
+
nested_repositories=_nested,
|
|
11169
|
+
)
|
|
11170
|
+
raise typer.Exit(code=2)
|
|
11171
|
+
|
|
11018
11172
|
from sourcecode.context_graph import ContextGraph
|
|
11019
11173
|
from sourcecode.change_plan import build_change_plan
|
|
11020
11174
|
from sourcecode.repository_ir import find_java_files
|
sourcecode/detach.py
CHANGED
|
@@ -152,6 +152,26 @@ def output_path_of(args: "list[str]") -> Optional[str]:
|
|
|
152
152
|
return None
|
|
153
153
|
|
|
154
154
|
|
|
155
|
+
def _resolved_output_path(args: "list[str]", *, root: Path) -> Optional[str]:
|
|
156
|
+
"""`output_path_of`, made absolute against the invocation's own directory.
|
|
157
|
+
|
|
158
|
+
BUG-20: a relative `--output` (the common case, typed from wherever the
|
|
159
|
+
operator happened to be) came back in the envelope exactly as given —
|
|
160
|
+
"output.json", never "which directory". A caller reading the envelope
|
|
161
|
+
back from outside that shell (a monitoring script, a different working
|
|
162
|
+
directory, a log shipped elsewhere) had a string it could not use.
|
|
163
|
+
`.absolute()`, not `.resolve()`: this states where the path points
|
|
164
|
+
without also canonicalising symlinks the caller never asked to have
|
|
165
|
+
normalised away — the two shapes a detached run needs are "usable from
|
|
166
|
+
anywhere" and "still the path that was typed," not "the same inode's
|
|
167
|
+
other name."
|
|
168
|
+
"""
|
|
169
|
+
raw = output_path_of(args)
|
|
170
|
+
if raw is None:
|
|
171
|
+
return None
|
|
172
|
+
return str((root / Path(raw)).absolute())
|
|
173
|
+
|
|
174
|
+
|
|
155
175
|
def run_detached(args: "list[str]", *, root: Path) -> dict:
|
|
156
176
|
"""Start `args` (already free of the flag) detached; return the envelope."""
|
|
157
177
|
stamp = f"{int(time.time())}-{os.getpid()}"
|
|
@@ -168,7 +188,7 @@ def run_detached(args: "list[str]", *, root: Path) -> dict:
|
|
|
168
188
|
"pid": pid,
|
|
169
189
|
"broke_away_from_parent_job": broke_away,
|
|
170
190
|
"log": str(log_path),
|
|
171
|
-
"output":
|
|
191
|
+
"output": _resolved_output_path(args, root=root),
|
|
172
192
|
"how_to_read": (
|
|
173
193
|
"The analysis runs in a process that does not belong to this shell. "
|
|
174
194
|
"Its answer appears at `output` when it finishes; a `.partial` file "
|
sourcecode/non_coverage.py
CHANGED
|
@@ -558,15 +558,26 @@ def stack_fit(
|
|
|
558
558
|
beans = int(footprint.get("spring_beans") or 0)
|
|
559
559
|
java_files = int(footprint.get("java_files") or 0)
|
|
560
560
|
if spring_detected and java_files and beans / java_files < 0.1:
|
|
561
|
+
# BUG-03 (5.9.29, statement half): the machine-readable ratio was
|
|
562
|
+
# already published in `spring_footprint`, but the sentence a reader
|
|
563
|
+
# actually reads said only "marginal" — an auditor who read the prose
|
|
564
|
+
# and not the two raw integers beside it could not tell 9,9 % from
|
|
565
|
+
# 0,03 % apart, both of which take this branch. The density is now
|
|
566
|
+
# stated in the sentence itself, not left for the reader to divide.
|
|
567
|
+
_density_pct = round(100 * beans / java_files, 2)
|
|
561
568
|
return {
|
|
562
569
|
"schema_version": STACK_FIT_SCHEMA,
|
|
563
570
|
"spring_detected": True,
|
|
564
571
|
"fit": "partial",
|
|
565
572
|
"spring_footprint": {"spring_beans": beans, "java_files": java_files},
|
|
573
|
+
"spring_density_pct": _density_pct,
|
|
566
574
|
"statement": (
|
|
567
|
-
"Spring is present but marginal in this scope
|
|
568
|
-
"
|
|
569
|
-
"
|
|
575
|
+
f"Spring is present but marginal in this scope — {beans} of "
|
|
576
|
+
f"{java_files} Java files carry a Spring bean ({_density_pct:g} %), "
|
|
577
|
+
"under the 10 % floor this axis treats as coverage — so "
|
|
578
|
+
"Spring-shaped axes model only the detected Spring population. Do "
|
|
579
|
+
"not read their absence of findings as coverage of the remaining "
|
|
580
|
+
"repository."
|
|
570
581
|
),
|
|
571
582
|
"how_to_read": "Use Spring results for the detected Spring population only.",
|
|
572
583
|
}
|
sourcecode/release_info.py
CHANGED
|
@@ -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-09-
|
|
30
|
+
RELEASE_DATE = "2026-09-12"
|
|
31
31
|
|
|
32
32
|
#: Releases per day, measured over the latest 30 CHANGELOG releases (the same
|
|
33
33
|
#: computation the test re-runs). The nine-day interval before 5.9.0 lowers
|
sourcecode/repository_ir.py
CHANGED
|
@@ -2642,6 +2642,61 @@ def _mask_java(text: str) -> str:
|
|
|
2642
2642
|
return ''.join(out)
|
|
2643
2643
|
|
|
2644
2644
|
|
|
2645
|
+
|
|
2646
|
+
def _parse_health_row(
|
|
2647
|
+
rel_path: str, source: str, symbols: "list[Any]"
|
|
2648
|
+
) -> "Optional[dict]":
|
|
2649
|
+
"""One verdict on whether *rel_path*'s extracted symbols are trustworthy.
|
|
2650
|
+
|
|
2651
|
+
BUG-01. Shared by every extractor that reads Java source into symbols —
|
|
2652
|
+
`build_repo_ir` and `extract_java_endpoints` chief among them — so a file
|
|
2653
|
+
with a syntax error cannot be named as a parse failure on one surface and
|
|
2654
|
+
vanish silently on another. Returns a `parse_failures`-shaped row, or
|
|
2655
|
+
`None` for a clean file.
|
|
2656
|
+
|
|
2657
|
+
Two shapes, in order:
|
|
2658
|
+
|
|
2659
|
+
1. A type declaration (`class`/`interface`/`enum`/`record`) that yielded
|
|
2660
|
+
zero symbols at all — `type_declaration_produced_no_symbols`.
|
|
2661
|
+
2. A file that DID yield symbols, but whose brace or paren count is
|
|
2662
|
+
unbalanced once literals and comments are masked out — meaning the
|
|
2663
|
+
extractor's regex-based recovery stopped somewhere the reader cannot
|
|
2664
|
+
see. Brace balance alone misses a missing `;` or a missing `)` on a
|
|
2665
|
+
method signature (both still extract a clean class+method pair with
|
|
2666
|
+
balanced braces); the paren check catches that second shape without a
|
|
2667
|
+
real Java grammar, because a parameter or argument list that never
|
|
2668
|
+
closes is invalid Java regardless of what the braces do.
|
|
2669
|
+
"""
|
|
2670
|
+
if not symbols and _TYPE_DECL_KEYWORD_RE.search(source):
|
|
2671
|
+
from sourcecode.reconciliation import declares_java_type
|
|
2672
|
+
|
|
2673
|
+
if declares_java_type(_mask_java(source)):
|
|
2674
|
+
return {
|
|
2675
|
+
"path": rel_path,
|
|
2676
|
+
"status": "failed",
|
|
2677
|
+
"reason": "type_declaration_produced_no_symbols",
|
|
2678
|
+
}
|
|
2679
|
+
return None
|
|
2680
|
+
if symbols and (
|
|
2681
|
+
source.count("{") != source.count("}")
|
|
2682
|
+
or source.count("(") != source.count(")")
|
|
2683
|
+
):
|
|
2684
|
+
_masked_src = _mask_java(source)
|
|
2685
|
+
if _masked_src.count("{") != _masked_src.count("}"):
|
|
2686
|
+
return {
|
|
2687
|
+
"path": rel_path,
|
|
2688
|
+
"status": "recovered",
|
|
2689
|
+
"reason": "unbalanced_braces",
|
|
2690
|
+
}
|
|
2691
|
+
if _masked_src.count("(") != _masked_src.count(")"):
|
|
2692
|
+
return {
|
|
2693
|
+
"path": rel_path,
|
|
2694
|
+
"status": "recovered",
|
|
2695
|
+
"reason": "unbalanced_parens",
|
|
2696
|
+
}
|
|
2697
|
+
return None
|
|
2698
|
+
|
|
2699
|
+
|
|
2645
2700
|
def _located_body(raw_lines: list[str], start_idx: int) -> tuple[str, list[tuple[int, int]]]:
|
|
2646
2701
|
"""Like `_method_body`, but returns (masked_body, line_map) where `line_map[k]`
|
|
2647
2702
|
= (source_line_1based, col_offset) is the absolute coordinate of column 0 of the
|
|
@@ -6816,50 +6871,19 @@ def build_repo_ir(
|
|
|
6816
6871
|
elif _previous != _value:
|
|
6817
6872
|
del _repo_constants[_name]
|
|
6818
6873
|
_ambiguous_constants.add(_name)
|
|
6819
|
-
#
|
|
6820
|
-
#
|
|
6821
|
-
#
|
|
6822
|
-
#
|
|
6823
|
-
#
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6874
|
+
# BUG-01 (5.9.29 widening): the check below used to live only here,
|
|
6875
|
+
# so a file whose symbols were untrustworthy vanished with a signal
|
|
6876
|
+
# from `spring-audit`/`risk` but with none at all from `endpoints`,
|
|
6877
|
+
# which parses this same source through its own independent loop.
|
|
6878
|
+
# `_parse_health_row` is the one authority both call, so the same
|
|
6879
|
+
# file gets the same verdict on every surface that reads it.
|
|
6880
|
+
_health_row = _parse_health_row(rel_path, source, symbols)
|
|
6881
|
+
if _health_row is not None:
|
|
6882
|
+
if _health_row["reason"] == "type_declaration_produced_no_symbols":
|
|
6827
6883
|
_unparsed_type_files.append(rel_path)
|
|
6828
|
-
|
|
6829
|
-
"path": rel_path,
|
|
6830
|
-
"status": "failed",
|
|
6831
|
-
"reason": "type_declaration_produced_no_symbols",
|
|
6832
|
-
})
|
|
6833
|
-
# E-10: a brace that never closes is not a style question — it means the
|
|
6834
|
-
# symbols recovered from this file stop somewhere the reader cannot see.
|
|
6835
|
-
#
|
|
6836
|
-
# BUG-01 (5.9.25 audit): brace balance alone missed most real syntax
|
|
6837
|
-
# errors — `int x = 5` with a missing `;`, or `void broken( {` with a
|
|
6838
|
-
# missing `)`, both extract a clean class+method symbol pair with
|
|
6839
|
-
# balanced braces, so the file vanished with no disclosure at all. An
|
|
6840
|
-
# unbalanced *paren* count, masked the same way, catches the second
|
|
6841
|
-
# shape cheaply without a real Java grammar: a method or call whose
|
|
6842
|
-
# parameter/argument list never closes is invalid Java regardless of
|
|
6843
|
-
# what its braces do.
|
|
6844
|
-
elif symbols and (
|
|
6845
|
-
source.count("{") != source.count("}")
|
|
6846
|
-
or source.count("(") != source.count(")")
|
|
6847
|
-
):
|
|
6848
|
-
_masked_src = _mask_java(source)
|
|
6849
|
-
if _masked_src.count("{") != _masked_src.count("}"):
|
|
6850
|
-
_unbalanced_files.append(rel_path)
|
|
6851
|
-
_parse_failures.setdefault(rel_path, {
|
|
6852
|
-
"path": rel_path,
|
|
6853
|
-
"status": "recovered",
|
|
6854
|
-
"reason": "unbalanced_braces",
|
|
6855
|
-
})
|
|
6856
|
-
elif _masked_src.count("(") != _masked_src.count(")"):
|
|
6884
|
+
else:
|
|
6857
6885
|
_unbalanced_files.append(rel_path)
|
|
6858
|
-
|
|
6859
|
-
"path": rel_path,
|
|
6860
|
-
"status": "recovered",
|
|
6861
|
-
"reason": "unbalanced_parens",
|
|
6862
|
-
})
|
|
6886
|
+
_parse_failures.setdefault(rel_path, _health_row)
|
|
6863
6887
|
_per_file.append((rel_path, package, raw_imports, symbols))
|
|
6864
6888
|
if "@" in source:
|
|
6865
6889
|
_parsed_refs = _extract_annotation_type_refs(source, package)
|
|
@@ -8315,6 +8339,20 @@ def extract_java_endpoints(
|
|
|
8315
8339
|
_ROUTE_LITERAL_ANN_RE = _re.compile(
|
|
8316
8340
|
r"@(\w+)\s*\(\s*(?:(?:value|path)\s*=\s*)?\"(/[^\"]*)\"",
|
|
8317
8341
|
)
|
|
8342
|
+
# BUG-10 (residual, 5.9.29): Vert.x's Router is a fluent call chain, not an
|
|
8343
|
+
# annotation — `router.get("/subscriptions").handler(ctx -> …)` — so no
|
|
8344
|
+
# `@`-prefixed evidence rule can ever see it, and it was the one framework
|
|
8345
|
+
# of eleven surveyed that fell through to the bare disclaimer with no file
|
|
8346
|
+
# named. The shape is as vendor-neutral as the annotation rule above: an
|
|
8347
|
+
# HTTP-verb method called with exactly one path-like string literal,
|
|
8348
|
+
# immediately chained into a call this repository's own routers all use to
|
|
8349
|
+
# attach a handler. `route(...)` is included for `Router#route`, which
|
|
8350
|
+
# Vert.x also dispatches on a path before choosing a verb.
|
|
8351
|
+
_ROUTE_LITERAL_CHAIN_RE = _re.compile(
|
|
8352
|
+
r"\.(get|post|put|delete|patch|head|options|route)\s*\(\s*"
|
|
8353
|
+
r"\"(/[^\"]*)\"\s*\)\s*\.\s*"
|
|
8354
|
+
r"(?:handler|blockingHandler|coroutineHandler|produces|consumes)\b"
|
|
8355
|
+
)
|
|
8318
8356
|
#: The annotations this model already reads. Evidence from one of these is
|
|
8319
8357
|
#: covered surface, not a gap — the list is an exclusion, never the rule.
|
|
8320
8358
|
_MODELED_ROUTE_ANNS = frozenset({
|
|
@@ -8322,6 +8360,14 @@ def extract_java_endpoints(
|
|
|
8322
8360
|
"DeleteMapping", "PatchMapping", "Path", "FeignClient", "RequestLine",
|
|
8323
8361
|
})
|
|
8324
8362
|
_unmodeled_routing: "dict[str, list[tuple[str, str]]]" = {}
|
|
8363
|
+
# BUG-01 (5.9.29 widening): this extractor parses every source itself,
|
|
8364
|
+
# independently of `build_repo_ir`, so the same syntax-error shape that
|
|
8365
|
+
# `_parse_health_row` catches there was invisible here — a file could
|
|
8366
|
+
# vanish from `endpoints` with `total: 1` and no signal at all, because
|
|
8367
|
+
# the health check that would have named it only ran on the other
|
|
8368
|
+
# surface. One dict, filled from the same authority, published as
|
|
8369
|
+
# `parse_failures` alongside the routes it could not fully trust.
|
|
8370
|
+
_endpoint_parse_failures: "dict[str, dict]" = {}
|
|
8325
8371
|
|
|
8326
8372
|
# BUG #3 (JobRunr field test): imperative router-DSL routes. Lightweight HTTP
|
|
8327
8373
|
# frameworks that deliberately avoid Spring/JAX-RS (JobRunr's own dashboard
|
|
@@ -8389,12 +8435,13 @@ def extract_java_endpoints(
|
|
|
8389
8435
|
# against the endpoints this run produced once the surface is built —
|
|
8390
8436
|
# a file that shows a path literal and contributes no endpoint is the
|
|
8391
8437
|
# gap this row is about.
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
):
|
|
8438
|
+
_stripped_source = _strip_java_comments(source)
|
|
8439
|
+
for _ann, _literal in _ROUTE_LITERAL_ANN_RE.findall(_stripped_source):
|
|
8395
8440
|
if _ann in _MODELED_ROUTE_ANNS:
|
|
8396
8441
|
continue
|
|
8397
|
-
_unmodeled_routing.setdefault(rel, []).append((_ann, _literal))
|
|
8442
|
+
_unmodeled_routing.setdefault(rel, []).append((f"@{_ann}", _literal))
|
|
8443
|
+
for _verb, _literal in _ROUTE_LITERAL_CHAIN_RE.findall(_stripped_source):
|
|
8444
|
+
_unmodeled_routing.setdefault(rel, []).append((f".{_verb}(…)", _literal))
|
|
8398
8445
|
# C3-6: this extractor parsed every file itself while `build_repo_ir`
|
|
8399
8446
|
# read the content-addressed parse cache for the same bytes, so a run
|
|
8400
8447
|
# that does both — the root `--compact` view builds the summary here and
|
|
@@ -8416,6 +8463,9 @@ def extract_java_endpoints(
|
|
|
8416
8463
|
_pkey, _pkg, _imports, symbols,
|
|
8417
8464
|
_fstats.get("excluded_statements", 0),
|
|
8418
8465
|
)
|
|
8466
|
+
_health_row = _parse_health_row(rel, source, symbols)
|
|
8467
|
+
if _health_row is not None:
|
|
8468
|
+
_endpoint_parse_failures.setdefault(rel, _health_row)
|
|
8419
8469
|
# Cross-file constants for annotation-path folding (see _collect_repo_constants).
|
|
8420
8470
|
for _cname, _cval in _collect_file_constants(source).items():
|
|
8421
8471
|
if _cname in _const_ambiguous:
|
|
@@ -9190,6 +9240,30 @@ def extract_java_endpoints(
|
|
|
9190
9240
|
)
|
|
9191
9241
|
except Exception:
|
|
9192
9242
|
pass
|
|
9243
|
+
# BUG-01 (5.9.29 widening): the same authority `build_repo_ir` uses to
|
|
9244
|
+
# name a file whose extracted symbols are not trustworthy — a type
|
|
9245
|
+
# declaration that yielded none, or a brace/paren count that stays
|
|
9246
|
+
# unbalanced after masking comments and literals — publishes here too.
|
|
9247
|
+
# Before this, such a file simply produced no endpoint and nothing said
|
|
9248
|
+
# why: `total: 1, only /ok` for a repository that also has `Bad.java`
|
|
9249
|
+
# read as "this repository exposes one endpoint," not "one file could
|
|
9250
|
+
# not be trusted." Published whenever non-empty, at any total — the
|
|
9251
|
+
# honesty pattern is not only for the zero case.
|
|
9252
|
+
if _endpoint_parse_failures:
|
|
9253
|
+
result["parse_failures"] = [
|
|
9254
|
+
_endpoint_parse_failures[path] for path in sorted(_endpoint_parse_failures)
|
|
9255
|
+
]
|
|
9256
|
+
result["parse_failures_basis"] = (
|
|
9257
|
+
"Files whose extracted symbols are not fully trustworthy: a type "
|
|
9258
|
+
"declaration that yielded zero symbols, or a brace/paren count "
|
|
9259
|
+
"that stays unbalanced once comments and string literals are "
|
|
9260
|
+
"masked out. `status: \"failed\"` means nothing from the file "
|
|
9261
|
+
"reached this answer; `status: \"recovered\"` means some symbols "
|
|
9262
|
+
"did, but the file's structure past the imbalance is unverified. "
|
|
9263
|
+
"The same check `spring-audit`/`risk` publish under this name — "
|
|
9264
|
+
"one authority for whether a file's symbols can be trusted."
|
|
9265
|
+
)
|
|
9266
|
+
|
|
9193
9267
|
# BUG-10: reconcile the route-shaped evidence against what this run
|
|
9194
9268
|
# actually modelled. A file that showed a path literal and produced an
|
|
9195
9269
|
# endpoint is covered; one that produced none is a routing style this model
|
|
@@ -9207,22 +9281,31 @@ def extract_java_endpoints(
|
|
|
9207
9281
|
if _unmodeled_files:
|
|
9208
9282
|
_EVIDENCE_CAP = 10
|
|
9209
9283
|
_examples = [
|
|
9210
|
-
{"file": rel, "
|
|
9284
|
+
{"file": rel, "marker": marker, "path_literal": literal}
|
|
9211
9285
|
for rel in sorted(_unmodeled_files)
|
|
9212
|
-
for
|
|
9286
|
+
for marker, literal in _unmodeled_files[rel][:1]
|
|
9213
9287
|
]
|
|
9214
|
-
|
|
9288
|
+
_markers = sorted({marker for hits in _unmodeled_files.values() for marker, _ in hits})
|
|
9215
9289
|
result["unmodeled_routing_evidence"] = {
|
|
9216
9290
|
"files": len(_unmodeled_files),
|
|
9217
|
-
|
|
9291
|
+
# BUG-10 (residual): the field kept the field name `annotations`,
|
|
9292
|
+
# so it stays, even though the population it names has widened
|
|
9293
|
+
# past annotations — `.get(…)` is a fluent call-chain marker, not
|
|
9294
|
+
# one. `markers` is the same list under a name that admits both.
|
|
9295
|
+
"annotations": _markers,
|
|
9296
|
+
"markers": _markers,
|
|
9218
9297
|
"examples": _examples[:_EVIDENCE_CAP],
|
|
9219
9298
|
"basis": (
|
|
9220
|
-
"Files
|
|
9221
|
-
"
|
|
9222
|
-
"
|
|
9223
|
-
"
|
|
9224
|
-
"
|
|
9225
|
-
"
|
|
9299
|
+
"Files with route-shaped evidence that produced no entry in "
|
|
9300
|
+
"this endpoint population: either a declarative annotation "
|
|
9301
|
+
"whose argument is a path-like string literal (`@Route(\"/x\")`),"
|
|
9302
|
+
" or an HTTP-verb call chained straight into a handler "
|
|
9303
|
+
"attachment (`.get(\"/x\").handler(…)`, Vert.x's Router). The "
|
|
9304
|
+
"rule names no framework: a path literal is what a declarative "
|
|
9305
|
+
"route looks like, chained into a handler call is what a "
|
|
9306
|
+
"fluent router looks like, in every framework that uses either "
|
|
9307
|
+
"shape. This is evidence of routing this model does not read — "
|
|
9308
|
+
"not a route list, and never added to `total`."
|
|
9226
9309
|
),
|
|
9227
9310
|
**_cap_effect(
|
|
9228
9311
|
"unmodeled_routing_examples",
|
|
@@ -9312,15 +9395,18 @@ def extract_java_endpoints(
|
|
|
9312
9395
|
elif _unmodeled_files:
|
|
9313
9396
|
# BUG-10: this branch used to say "no recognized routing construct
|
|
9314
9397
|
# was found" over a repository whose files carry route-shaped
|
|
9315
|
-
#
|
|
9316
|
-
# sentence has to state it.
|
|
9317
|
-
|
|
9318
|
-
|
|
9398
|
+
# evidence this model does not read. The measurement exists; the
|
|
9399
|
+
# sentence has to state it. Widened (5.9.29) past annotations to
|
|
9400
|
+
# the fluent call-chain marker (`.get(…)`, Vert.x's Router), which
|
|
9401
|
+
# was the one framework of eleven surveyed left with no evidence
|
|
9402
|
+
# at all — only the disclaimer below now applies to it.
|
|
9403
|
+
_markers_seen = ", ".join(
|
|
9404
|
+
sorted({marker for hits in _unmodeled_files.values() for marker, _ in hits})[:6]
|
|
9319
9405
|
)
|
|
9320
9406
|
result["zero_result_reason"] = (
|
|
9321
9407
|
f"0 endpoints recognized. Searched: {_searched}. "
|
|
9322
|
-
f"{len(_unmodeled_files)} file(s) declare
|
|
9323
|
-
f"this model does not read ({
|
|
9408
|
+
f"{len(_unmodeled_files)} file(s) declare route-shaped evidence "
|
|
9409
|
+
f"this model does not read ({_markers_seen}) — see "
|
|
9324
9410
|
f"`unmodeled_routing_evidence`. Do NOT read this as 'no public API': "
|
|
9325
9411
|
f"the routing style, not the surface, is what is missing here."
|
|
9326
9412
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 5.9.
|
|
3
|
+
Version: 5.9.31
|
|
4
4
|
Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/HarounDominique/sourcecode
|
|
6
6
|
Project-URL: Repository, https://github.com/HarounDominique/sourcecode
|
|
@@ -59,7 +59,7 @@ Description-Content-Type: text/markdown
|
|
|
59
59
|
> question. All analysis is local and deterministic; see [Privacy](#configuration--privacy)
|
|
60
60
|
> before inspecting a repository whose telemetry policy you need to control.
|
|
61
61
|
|
|
62
|
-

|
|
63
63
|

|
|
64
64
|
|
|
65
65
|
Copyright (c) 2026 Dominique Haroun. All rights reserved. ASK Engine 5.7.0 and
|
|
@@ -290,7 +290,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
|
|
|
290
290
|
# pip / pipx
|
|
291
291
|
pipx install sourcecode # or: pip install sourcecode
|
|
292
292
|
|
|
293
|
-
ask version # ask 5.9.
|
|
293
|
+
ask version # ask 5.9.31 — and, on a build that has aged,
|
|
294
294
|
# how many releases have probably shipped since
|
|
295
295
|
```
|
|
296
296
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
sourcecode/__init__.py,sha256=
|
|
1
|
+
sourcecode/__init__.py,sha256=aE6bZn3549jPrAPXdSSzOOUcSbTElZNwvDgnf8PkQRw,309
|
|
2
2
|
sourcecode/__main__.py,sha256=qDFVkobwsdZrX0B3stiRqsUNivVpybKO-egzAwCW4xw,165
|
|
3
|
-
sourcecode/_build_commit.py,sha256=
|
|
3
|
+
sourcecode/_build_commit.py,sha256=soR9bluaRLiRQOZKiKG6JgH8eSuPbG1Am0XOse7hd9s,12816
|
|
4
4
|
sourcecode/access_drift.py,sha256=uYD8ipiEAaTnkz0IhG6ujU_KI3LghdY-6ycurs-BZnc,9355
|
|
5
5
|
sourcecode/adaptive_scanner.py,sha256=yJBKjNpkY6bpueYJ2YnRezen3sYZDecEt7WaaNWdqug,9466
|
|
6
6
|
sourcecode/analysis_budget.py,sha256=ZuNEboPF8A6GK-_V7WNt92ezgriga7_Rbr-vvSN4UEE,4183
|
|
@@ -35,7 +35,7 @@ sourcecode/change_plan.py,sha256=drAoDsqFplutCLc6Y0xue7sYkTls0SpYh7aOXvttv3I,129
|
|
|
35
35
|
sourcecode/ci_output.py,sha256=X4NRokWWMRF9Ex8OQrEO2g04GzJ00GDP5zYIoqI9YCc,4625
|
|
36
36
|
sourcecode/cir_graphs.py,sha256=RytqSv1WF8kdlfXj2fPQz16LY4akS2kyThbdWL8beCQ,14835
|
|
37
37
|
sourcecode/classifier.py,sha256=ft1RGPIChvO84q2QMrEH93x1J15AXNWMh26lnxvoRao,26476
|
|
38
|
-
sourcecode/cli.py,sha256=
|
|
38
|
+
sourcecode/cli.py,sha256=XII7rmrcJA-eN-sMlfLCKP7fUNl83iEXQfP_-Okdyy8,988561
|
|
39
39
|
sourcecode/click_runtime.py,sha256=K2cUdzFhbd6uEUpucWptXE89_z-ZNZGsqgd-34usUXk,1890
|
|
40
40
|
sourcecode/client_calls.py,sha256=YOPnfRZzRyqmdHvXSVeiunW8cuiuCuWXacNIQRgKMCw,22640
|
|
41
41
|
sourcecode/code_notes_analyzer.py,sha256=EJemNCNc9Dn-1RZYu-aNbK0ELzmsyC4s6FdHi3XyNEI,9392
|
|
@@ -63,7 +63,7 @@ sourcecode/defect_identity.py,sha256=XS2VFDImg9NLaRImybKTeyk-CoDSsXmchldg0dwvM7c
|
|
|
63
63
|
sourcecode/degradation.py,sha256=XmmCjuwSPBi5QX_Ww-0mGYk6Ks1dmVq9T5z3LNPeo7A,19035
|
|
64
64
|
sourcecode/dependency_analyzer.py,sha256=YJ0EECXGrpUWr9CTjQTtSZQfoBWcNQ5ksofZOC6Fv7Q,65835
|
|
65
65
|
sourcecode/deployment_prefix.py,sha256=kPHPT6ZLg6CnMqCp9QwhbNNjDyS0sXAfKlPtSHUMggs,12180
|
|
66
|
-
sourcecode/detach.py,sha256=
|
|
66
|
+
sourcecode/detach.py,sha256=lmymkamQQm_YGl86J9aACgEd5FFfrFEr9Pmws86JECw,9242
|
|
67
67
|
sourcecode/doc_analyzer.py,sha256=05bjTUbDbmnbajD_cgRnACzS8T7xxBKVX4CjkJlhZg8,24411
|
|
68
68
|
sourcecode/dynamic_argument_surface.py,sha256=u6zJoY-zChYVw1-SrgiyAq-rUwqMZ5ZqBwLfbPJ_8ng,2960
|
|
69
69
|
sourcecode/empty_answer_diagnostics.py,sha256=VMgR6aGL_1YREuA7KizlIK1pglDDOxn-QsDYIxfVuYE,7294
|
|
@@ -108,7 +108,7 @@ sourcecode/metrics_analyzer.py,sha256=gLoRWKygF18jLgwsqmGXSWopw-f5iO1VbM7Jjdif6a
|
|
|
108
108
|
sourcecode/migrate_check.py,sha256=jpxjQVruHkxGFIfTD4pnNZmBXKrJcZ6Q5nBtgkfRNmE,172846
|
|
109
109
|
sourcecode/migration_apply.py,sha256=36E9IUq7RbpGVt6RZ8PlSZKgDoEMHorZrXw6UVWPnpw,8692
|
|
110
110
|
sourcecode/migration_blast.py,sha256=OPryWkM6-PbvcG3eJFdcWUnlpXBje41nu2BkrZnE2hg,9359
|
|
111
|
-
sourcecode/non_coverage.py,sha256=
|
|
111
|
+
sourcecode/non_coverage.py,sha256=jUXEyIcGldORR5Pi5qlK3f9L_yBu3aMZIx6qJZjrSGA,32264
|
|
112
112
|
sourcecode/openapi_surface.py,sha256=BTt0K-woZbkbWTN77IkqeBm_Okag9owR0848fmot8sk,16207
|
|
113
113
|
sourcecode/openrewrite_recipe.py,sha256=0pS-61falE6rSfkos2MPnmoDamvoeTT-8Kmj7smj_DI,12987
|
|
114
114
|
sourcecode/output_bounds.py,sha256=BvaRQY5nuytgfNUJHyO7JDLOHuSy0vdjqasISxmxLxI,15516
|
|
@@ -143,7 +143,7 @@ sourcecode/redactor.py,sha256=SB4hwIvg8h-hvcqKcDWaZvA-aSyn-at-BIRwa0tUv5E,3227
|
|
|
143
143
|
sourcecode/reference_facts.py,sha256=mx7H-Ax5y8sKAQHrnJCXlgjkUzqZtQTByv9Zy2lxKQQ,15500
|
|
144
144
|
sourcecode/regress.py,sha256=6rlFP2rsIzVKAA0spJ66To528GyBtnRI2Zg9vAGq8kQ,13264
|
|
145
145
|
sourcecode/regulatory_pack.py,sha256=xVWd8hYg6MjGfkFP8UWcYeLmNMxEk8k2uSbTcnGMbhg,3421
|
|
146
|
-
sourcecode/release_info.py,sha256=
|
|
146
|
+
sourcecode/release_info.py,sha256=u-opkkqIN4jnbtXmQVPV35Ga9zvbORXP2w2MHNUbbDg,5918
|
|
147
147
|
sourcecode/relevance_scorer.py,sha256=0AgEt4KrV73nioMqBgjhGjtY7L2C7L7cSyKtj3IKcrw,9408
|
|
148
148
|
sourcecode/remediation_diff.py,sha256=fGYqPmQF7bO54L8ivztX5PgmW4fVu54gNcG6OEQ192U,9730
|
|
149
149
|
sourcecode/remediation_flow.py,sha256=OFlrNCD2dKw1WlX5cHqVl1yrQZHi2TjCThH8Q3X1PwI,10294
|
|
@@ -151,7 +151,7 @@ sourcecode/remediation_report.py,sha256=3B7sFR-guQn6vxAxTRcm7k82mRNPsyj4e9ON_X3F
|
|
|
151
151
|
sourcecode/remedies.py,sha256=V2_cD4pLq8bKRkzF-3RGFoiu1xWYZS384WDVp1MrlZw,10225
|
|
152
152
|
sourcecode/rename_refactor.py,sha256=oASZIf7TxcOBy3RQ0FuOe-4HlNW_JOu9RW9JqCxGNBE,17225
|
|
153
153
|
sourcecode/repo_classifier.py,sha256=FG1vaWKdWXsWdl-S8hjVMiTqcwgaRXkDyvK4rPcOGtQ,22681
|
|
154
|
-
sourcecode/repository_ir.py,sha256=
|
|
154
|
+
sourcecode/repository_ir.py,sha256=PHpxMG4EKwo7wwW_eMd1OJi8Ys1PMISS38cOmDU_AV0,542323
|
|
155
155
|
sourcecode/resource_budget.py,sha256=WbJqw4pT70Da_KJP2ibZfNTPR6aiEFD2ziF1fSdWLNM,12656
|
|
156
156
|
sourcecode/ris.py,sha256=HsLVHZfseEHNqMyxrj8SvrzUK7jE_85lsWjHtsEw9ik,29196
|
|
157
157
|
sourcecode/risk.py,sha256=jzSq_TaT-EXrhM0V5sOXQHE_XRGvupRfz8mAM0_VpF4,107641
|
|
@@ -278,13 +278,13 @@ sourcecode/telemetry/consent.py,sha256=-Wb8BFGXEexOs8M0Eja7F-T6ZtLNPeRoZnHcHvlP7
|
|
|
278
278
|
sourcecode/telemetry/events.py,sha256=l3Z2SQUO4_C2D2ItXOOdVNimAmHedUHnUxqYFTxnsAE,2900
|
|
279
279
|
sourcecode/telemetry/filters.py,sha256=-lqT2oorECuqEIdeHb--7AZ6BCaUx0bya720a-Z5x6w,7335
|
|
280
280
|
sourcecode/telemetry/transport.py,sha256=4gGHsq0WeY9VywEZXA3vUxykfiYnw9uuqfjAAec7F8o,1681
|
|
281
|
-
sourcecode/_docs/DEFECT-LEDGER.md,sha256=
|
|
281
|
+
sourcecode/_docs/DEFECT-LEDGER.md,sha256=o2CY-nisHJOuYpn2qnUv2jVjEtSdnkiC-ilnu0kiFss,1233466
|
|
282
282
|
sourcecode/_docs/LICENSE,sha256=23-fk61oSWGVmkWyka-FIM0rhAPM2hcYHnsaridL8Uo,1859
|
|
283
283
|
sourcecode/_docs/NOTICE,sha256=Br-AA8Y3iJo1WXa5uP8QBpzqI5nDu3iGLbFyvDt3BOs,321
|
|
284
|
-
sourcecode/_docs/USER_GUIDE.md,sha256=
|
|
285
|
-
sourcecode-5.9.
|
|
286
|
-
sourcecode-5.9.
|
|
287
|
-
sourcecode-5.9.
|
|
288
|
-
sourcecode-5.9.
|
|
289
|
-
sourcecode-5.9.
|
|
290
|
-
sourcecode-5.9.
|
|
284
|
+
sourcecode/_docs/USER_GUIDE.md,sha256=ta7lNm3q9ME6CyXZx4ttLh3sB2POEa2FeP5IE0GZoqY,108622
|
|
285
|
+
sourcecode-5.9.31.dist-info/METADATA,sha256=TLlOxRRCLsXdoOy04SIYFjpNDl0I-xl_GimBpyKnk7A,67653
|
|
286
|
+
sourcecode-5.9.31.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
287
|
+
sourcecode-5.9.31.dist-info/entry_points.txt,sha256=-JEAdChrK5We51kZcb7OaDcyil-dHBjBPL-NhuO-QY8,89
|
|
288
|
+
sourcecode-5.9.31.dist-info/licenses/LICENSE,sha256=23-fk61oSWGVmkWyka-FIM0rhAPM2hcYHnsaridL8Uo,1859
|
|
289
|
+
sourcecode-5.9.31.dist-info/licenses/NOTICE,sha256=Br-AA8Y3iJo1WXa5uP8QBpzqI5nDu3iGLbFyvDt3BOs,321
|
|
290
|
+
sourcecode-5.9.31.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|