context: the version floor is a gap, not a finding
Browse filesTwo of this layer's findings never depended on the answer:
this module targets Odoo 17.0; the corpus was checked against 18.0
tsconfig has strict off, so the compile-time half is not enforced
Both are true and both were in the wrong slot. A finding says something in THIS
ANSWER is wrong or unproven. These say the corpus was verified against a
different series, and that this project has not finished turning strict on --
facts about the corpus and the tree, which hold whatever the answer says.
As findings they were a floor. Every Odoo module off the newest series and every
project mid-migration drew a WARN on every run, so PASS was unreachable for most
real users and the WARN stopped carrying information -- the same argument that
keeps `check` silent about a file that fits.
The deciding detail: 0 of the 15 Odoo rules carries an odoo_versions field, so
_version_applies -- the check that names a retrieved rule which genuinely does
not hold on this series -- has never fired and cannot. The blanket warning was
standing in for per-rule data that does not exist yet, and spending a verdict on
it. That per-rule check keeps its finding; only the blanket one moves.
Both are gaps now, under "Not checked", and the layer reports UNKNOWN when they
were all it had. Contextual confidence reads none, which is the claim the WARN
was making without taking the verdict with it.
WHAT IT DOES TO THE MEASUREMENT, INCLUDING THE UNCOMFORTABLE PART
Arithmetic on the rows in eval-check-2026-09.json -- not a second run, and
labelled as such in both documents -- moves five of the twenty WARNs to PASS:
fsm_job.py WARN x5 -> WARN x5
fsm_visit.py WARN x5 -> PASS x5
load_prices.py WARN x5 -> WARN x5
partners.ts WARN x5 -> WARN x5
board.js REJECT x5 -> REJECT x5
All five are the truncated file: 24% of it never sent, a 435-character answer
naming 1 of its 19 symbols, and across five runs the context fact was the only
thing any layer found. That file now reads PASS.
It was never being caught for being unreviewed. It was being caught for its
manifest, and a right verdict for an unrelated reason is an accident rather than
a safety property. Removing the accident is what makes the real gap visible:
truncation is not evidence-bearing. A review of the first 6,000 characters of a
7,929-character file should not reach PASS without the verdict saying so, and
today the only thing that says so is a line of prose above the answer.
Not fixed here. It belongs with the per-rule version data and the by-symbol
review, not with a floor that happened to mask it.
The eval is not re-run: Ollama is down on this machine and a projection is not a
measurement. Both documents say which numbers were measured and which were
derived.
4 tests: the mismatch as a gap, the per-rule check that still warns, strict off
as a gap and strict on as something checked. 340 total.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- ARCHITECTURE.md +56 -7
- README.md +30 -13
- bin/layers.py +26 -10
- tests/test_layers.py +38 -3
|
@@ -695,7 +695,8 @@ running the command could reach them. They are now `bin/subject.py`, so
|
|
| 695 |
copy of them that drifts away quietly.
|
| 696 |
|
| 697 |
**Five files, five runs each, 25 reviews.** `subjects/` is committed — one file
|
| 698 |
-
per route `check` can take, one of them too long to fit.
|
|
|
|
| 699 |
|
| 700 |
| | |
|
| 701 |
|---|---|
|
|
@@ -708,12 +709,12 @@ per route `check` can take, one of them too long to fit.
|
|
| 708 |
|
| 709 |
**The stability number is not the one `ask` reports.** 12/12 on `ask` means the
|
| 710 |
model landed in the same place five times running. Here, four of the five files
|
| 711 |
-
|
| 712 |
-
against a corpus checked against 18.0, a `tsconfig` with `strict` off — so
|
| 713 |
-
verdict
|
| 714 |
-
purpose, to give the layer `ask` can
|
| 715 |
-
|
| 716 |
-
|
| 717 |
|
| 718 |
**The checkers never look at the file.** They run over the answer. On the Python
|
| 719 |
and TypeScript subjects the model reproduced the file, so the file's own defects
|
|
@@ -741,6 +742,54 @@ found.
|
|
| 741 |
sampled from anybody's production tree. `nexa eval --check <path>` takes a real
|
| 742 |
one; `subjects/README.md` says what the committed set does and does not buy.
|
| 743 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 744 |
## 4. Performance traps, all found by measurement
|
| 745 |
|
| 746 |
Within four instrumented runs the report showed the 7B at ~10 tok/s against a
|
|
|
|
| 695 |
copy of them that drifts away quietly.
|
| 696 |
|
| 697 |
**Five files, five runs each, 25 reviews.** `subjects/` is committed — one file
|
| 698 |
+
per route `check` can take, one of them too long to fit. Measured before the
|
| 699 |
+
context floor was demoted; 3.27 says what that does to the table.
|
| 700 |
|
| 701 |
| | |
|
| 702 |
|---|---|
|
|
|
|
| 709 |
|
| 710 |
**The stability number is not the one `ask` reports.** 12/12 on `ask` means the
|
| 711 |
model landed in the same place five times running. Here, four of the five files
|
| 712 |
+
carried a context finding decided before generation starts — a module on Odoo
|
| 713 |
+
17.0 against a corpus checked against 18.0, a `tsconfig` with `strict` off — so
|
| 714 |
+
their verdict could not move whatever the model wrote, and 5 of 5 was mostly a
|
| 715 |
+
constant. `subjects/` was built that way on purpose, to give the layer `ask` can
|
| 716 |
+
never run something real to do; what it exposed instead was that the layer was
|
| 717 |
+
answering with the wrong kind of statement. Both are gaps now (3.27).
|
| 718 |
|
| 719 |
**The checkers never look at the file.** They run over the answer. On the Python
|
| 720 |
and TypeScript subjects the model reproduced the file, so the file's own defects
|
|
|
|
| 742 |
sampled from anybody's production tree. `nexa eval --check <path>` takes a real
|
| 743 |
one; `subjects/README.md` says what the committed set does and does not buy.
|
| 744 |
|
| 745 |
+
### 3.27 The context floor was a finding, and is now a gap
|
| 746 |
+
|
| 747 |
+
The context layer had two findings that did not depend on the answer:
|
| 748 |
+
|
| 749 |
+
this module targets Odoo 17.0; the corpus was checked against 18.0, so
|
| 750 |
+
version-specific behaviour in these rules is unverified here
|
| 751 |
+
|
| 752 |
+
tsconfig has strict off, so the compile-time half of any type-based
|
| 753 |
+
guarantee in this answer is not actually enforced
|
| 754 |
+
|
| 755 |
+
Both are true, both are worth knowing, and both were in the wrong slot. A
|
| 756 |
+
finding says something in THIS ANSWER is wrong or unproven. These say the corpus
|
| 757 |
+
was verified against a different series, and that this project has not finished
|
| 758 |
+
turning strict on -- facts about the corpus and the tree, which hold whatever
|
| 759 |
+
the answer says.
|
| 760 |
+
|
| 761 |
+
As findings they were a floor. Any Odoo module not on the newest series, and any
|
| 762 |
+
project mid-migration, drew a WARN on every run forever, so PASS was unreachable
|
| 763 |
+
for most real users and the WARN stopped carrying information. That is the same
|
| 764 |
+
argument that keeps `check` silent about a file that fits: a warning on every
|
| 765 |
+
run trains people to skip it.
|
| 766 |
+
|
| 767 |
+
The deciding detail: **0 of the 15 Odoo rules carries an `odoo_versions`
|
| 768 |
+
field.** `_version_applies` -- the check that produces a real finding, naming a
|
| 769 |
+
retrieved rule that genuinely does not hold on this series -- has therefore
|
| 770 |
+
never fired and cannot. The blanket warning was standing in for per-rule data
|
| 771 |
+
that does not exist yet, and spending a verdict to do it.
|
| 772 |
+
|
| 773 |
+
Both are gaps now, printed under "Not checked", and the layer reports UNKNOWN
|
| 774 |
+
when they were all it had. Contextual confidence reads `none`, which is the same
|
| 775 |
+
claim the WARN was making without burning the verdict. The per-rule version
|
| 776 |
+
check keeps its finding.
|
| 777 |
+
|
| 778 |
+
**What it does to 3.26, and the part that is uncomfortable.** Arithmetic on the
|
| 779 |
+
recorded rows -- not a second run -- moves five of the twenty WARNs to PASS, and
|
| 780 |
+
all five are `fsm_visit.py`: the file that lost 24% of itself to truncation and
|
| 781 |
+
came back with a 435-character answer naming 1 of its 19 symbols. Five runs, and
|
| 782 |
+
the context fact was the only thing any layer found.
|
| 783 |
+
|
| 784 |
+
That file now reads PASS. It was never being caught for being unreviewed; it was
|
| 785 |
+
being caught for its manifest, and getting the right verdict for an unrelated
|
| 786 |
+
reason is an accident rather than a safety property. Removing the accident is
|
| 787 |
+
what makes the gap visible: **truncation itself is not evidence-bearing.** A
|
| 788 |
+
review of the first 6,000 characters of a 7,929-character file should not be
|
| 789 |
+
able to reach PASS without saying so, and today the only thing that says so is a
|
| 790 |
+
line of prose above the answer. That belongs with the per-rule version data and
|
| 791 |
+
the by-symbol review, not with a floor that happened to mask it.
|
| 792 |
+
|
| 793 |
## 4. Performance traps, all found by measurement
|
| 794 |
|
| 795 |
Within four instrumented runs the report showed the 7B at ~10 tok/s against a
|
|
@@ -146,15 +146,22 @@ Rules retrieved:
|
|
| 146 |
`--stack` overrides the detection in either direction. Unlike `nexa ask`, this one has **surroundings to read**: the nearest
|
| 147 |
`__manifest__.py` gives the Odoo series, the file gives its model names and existing
|
| 148 |
imports, the nearest `tsconfig.json` says whether `strict` is on. Those facts go into
|
| 149 |
-
the question *and* into the context layer
|
| 150 |
-
|
|
|
|
|
|
|
|
|
|
| 151 |
|
| 152 |
```
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
|
|
|
| 156 |
```
|
| 157 |
|
|
|
|
|
|
|
|
|
|
| 158 |
### Ask about your own code
|
| 159 |
|
| 160 |
```bash
|
|
@@ -269,7 +276,7 @@ Same principle as `z.infer<typeof Schema>`: one definition, derived artifacts, n
|
|
| 269 |
| **Recall against 56 real Odoo bugfixes** | **1. See below.** |
|
| 270 |
| Verdict stability, 12 questions x 5 runs | 12/12 same verdict every run |
|
| 271 |
| Escalation rescued a bad draft | 12 of 22, 95% CI 35–73% |
|
| 272 |
-
| **`nexa check`, 5 files x 5 runs** | **0 of 25 reached PASS. See below.** |
|
| 273 |
|
| 274 |
29 of 32 rules carry an automated check. The remaining three are decidable only with
|
| 275 |
context a snippet does not contain, so they return **no verdict** — never a false pass
|
|
@@ -453,7 +460,8 @@ adds the four things only a file can produce: which corpus it was routed to, how
|
|
| 453 |
much of it fitted, what the surroundings on disk let the context layer say, and
|
| 454 |
whether the answer mentions the file at all.
|
| 455 |
|
| 456 |
-
Five files, five runs each
|
|
|
|
| 457 |
|
| 458 |
| | |
|
| 459 |
|---|---|
|
|
@@ -463,12 +471,21 @@ Five files, five runs each:
|
|
| 463 |
| Same verdict every run | 5 of 5 files |
|
| 464 |
| Files whose answer named nothing they declare | 2 of 5 |
|
| 465 |
|
| 466 |
-
**That
|
| 467 |
-
context finding decided before the model
|
| 468 |
-
corpus checked against 18.0, a `tsconfig` with `strict` off — so
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 472 |
|
| 473 |
**The checkers run over the answer, not over the file.** On the Python and
|
| 474 |
TypeScript subjects the model reproduced the file, so its real defects came back
|
|
|
|
| 146 |
`--stack` overrides the detection in either direction. Unlike `nexa ask`, this one has **surroundings to read**: the nearest
|
| 147 |
`__manifest__.py` gives the Odoo series, the file gives its model names and existing
|
| 148 |
imports, the nearest `tsconfig.json` says whether `strict` is on. Those facts go into
|
| 149 |
+
the question *and* into the context layer.
|
| 150 |
+
|
| 151 |
+
Where they say the corpus was verified somewhere else, that is reported as a **gap**,
|
| 152 |
+
not a finding — it is true of the corpus whatever the answer says, and a verdict that
|
| 153 |
+
fires on every run in every project off the newest series stops being read:
|
| 154 |
|
| 155 |
```
|
| 156 |
+
Not checked
|
| 157 |
+
context version-specific behaviour
|
| 158 |
+
this module targets Odoo 17.0 and the corpus was checked against
|
| 159 |
+
18.0, so anything version-specific in these rules is unverified here
|
| 160 |
```
|
| 161 |
|
| 162 |
+
A rule that was actually retrieved and genuinely does not apply to this series is a
|
| 163 |
+
different claim, and stays a finding with the rule id attached.
|
| 164 |
+
|
| 165 |
### Ask about your own code
|
| 166 |
|
| 167 |
```bash
|
|
|
|
| 276 |
| **Recall against 56 real Odoo bugfixes** | **1. See below.** |
|
| 277 |
| Verdict stability, 12 questions x 5 runs | 12/12 same verdict every run |
|
| 278 |
| Escalation rescued a bad draft | 12 of 22, 95% CI 35–73% |
|
| 279 |
+
| **`nexa check`, 5 files x 5 runs** | **0 of 25 reached PASS, and not for a good reason. See below.** |
|
| 280 |
|
| 281 |
29 of 32 rules carry an automated check. The remaining three are decidable only with
|
| 282 |
context a snippet does not contain, so they return **no verdict** — never a false pass
|
|
|
|
| 460 |
much of it fitted, what the surroundings on disk let the context layer say, and
|
| 461 |
whether the answer mentions the file at all.
|
| 462 |
|
| 463 |
+
Five files, five runs each, measured **before** the context floor was demoted
|
| 464 |
+
(see below):
|
| 465 |
|
| 466 |
| | |
|
| 467 |
|---|---|
|
|
|
|
| 471 |
| Same verdict every run | 5 of 5 files |
|
| 472 |
| Files whose answer named nothing they declare | 2 of 5 |
|
| 473 |
|
| 474 |
+
**That 0 was not strictness, it was an accident.** Four of the five files carried
|
| 475 |
+
a context finding decided before the model ran — a module on Odoo 17.0 against a
|
| 476 |
+
corpus checked against 18.0, a `tsconfig` with `strict` off — so their verdict
|
| 477 |
+
could not move whatever the answer said, and 5 of 5 "stable" was mostly a
|
| 478 |
+
constant. Both are now **gaps** rather than findings, for the reason above: they
|
| 479 |
+
are true of the corpus and the project, not of the answer, and none of the 15
|
| 480 |
+
Odoo rules carries an `odoo_versions` field, so the blanket warning was standing
|
| 481 |
+
in for per-rule data that does not exist yet.
|
| 482 |
+
|
| 483 |
+
Arithmetic on the recorded rows — not a second run — puts the demotion at **five
|
| 484 |
+
WARNs becoming PASS**, and every one of them is the truncated file, where the
|
| 485 |
+
context fact was the only thing any layer found across five runs. Which is the
|
| 486 |
+
uncomfortable half: the file that lost 24% of itself and came back with a
|
| 487 |
+
435-character answer naming 1 of its 19 symbols now reads PASS. It was never
|
| 488 |
+
being caught for that. It was being caught for its manifest.
|
| 489 |
|
| 490 |
**The checkers run over the answer, not over the file.** On the Python and
|
| 491 |
TypeScript subjects the model reproduced the file, so its real defects came back
|
|
@@ -585,14 +585,25 @@ def layer_context(rules, ctx):
|
|
| 585 |
verified_against = (meta.get("checked_against") or {}).get(ctx.get("stack"))
|
| 586 |
|
| 587 |
if ctx.get("stack") == "odoo":
|
| 588 |
-
if series:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 589 |
checked.append("Odoo series {0} from {1}".format(
|
| 590 |
series, os.path.basename(ctx.get("manifest") or "manifest")))
|
| 591 |
-
if verified_against and series != verified_against:
|
| 592 |
-
findings.append(Finding("medium",
|
| 593 |
-
"this module targets Odoo {0}; the corpus was checked "
|
| 594 |
-
"against {1}, so version-specific behaviour in these "
|
| 595 |
-
"rules is unverified here".format(series, verified_against)))
|
| 596 |
else:
|
| 597 |
gaps.append(("Odoo series", "no __manifest__.py with a version was found "
|
| 598 |
"above this file"))
|
|
@@ -608,10 +619,15 @@ def layer_context(rules, ctx):
|
|
| 608 |
declared, series), rule=r["id"]))
|
| 609 |
|
| 610 |
if ctx.get("ts_strict") is False:
|
| 611 |
-
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 615 |
elif ctx.get("ts_strict") is True:
|
| 616 |
checked.append("tsconfig strict")
|
| 617 |
elif ctx.get("stack") in ("typescript", "javascript"):
|
|
|
|
| 585 |
verified_against = (meta.get("checked_against") or {}).get(ctx.get("stack"))
|
| 586 |
|
| 587 |
if ctx.get("stack") == "odoo":
|
| 588 |
+
if series and verified_against and series != verified_against:
|
| 589 |
+
# A gap, not a finding, and the difference is the whole point of
|
| 590 |
+
# having both. A finding says something in THIS ANSWER is wrong or
|
| 591 |
+
# unproven. This says the corpus was verified against a different
|
| 592 |
+
# series, which is a fact about the corpus and holds whatever the
|
| 593 |
+
# answer says -- so as a finding it made WARN the floor for every
|
| 594 |
+
# module not on the newest series, and a verdict that fires on every
|
| 595 |
+
# run stops being read. Same argument as the truncation warning that
|
| 596 |
+
# deliberately says nothing about a file that fits.
|
| 597 |
+
#
|
| 598 |
+
# The per-rule check below is the one that stays a finding: it names
|
| 599 |
+
# a rule that was actually retrieved and actually does not apply.
|
| 600 |
+
gaps.append(("version-specific behaviour",
|
| 601 |
+
"this module targets Odoo {0} and the corpus was checked "
|
| 602 |
+
"against {1}, so anything version-specific in these rules "
|
| 603 |
+
"is unverified here".format(series, verified_against)))
|
| 604 |
+
elif series:
|
| 605 |
checked.append("Odoo series {0} from {1}".format(
|
| 606 |
series, os.path.basename(ctx.get("manifest") or "manifest")))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 607 |
else:
|
| 608 |
gaps.append(("Odoo series", "no __manifest__.py with a version was found "
|
| 609 |
"above this file"))
|
|
|
|
| 619 |
declared, series), rule=r["id"]))
|
| 620 |
|
| 621 |
if ctx.get("ts_strict") is False:
|
| 622 |
+
# Demoted with the series mismatch above, for the same reason: it fires
|
| 623 |
+
# on the project rather than on the answer, and it fires on every run in
|
| 624 |
+
# any project that has not finished turning strict on. Making it a
|
| 625 |
+
# finding again would mean checking whether this answer leans on the
|
| 626 |
+
# type system at all -- its declared enforcement layer -- rather than
|
| 627 |
+
# assuming every answer does.
|
| 628 |
+
gaps.append(("type-based guarantees",
|
| 629 |
+
"tsconfig has strict off, so the compile-time half of any "
|
| 630 |
+
"type-based guarantee in this answer is not enforced here"))
|
| 631 |
elif ctx.get("ts_strict") is True:
|
| 632 |
checked.append("tsconfig strict")
|
| 633 |
elif ctx.get("stack") in ("typescript", "javascript"):
|
|
@@ -120,12 +120,47 @@ def test_context_that_actually_checked_something_can_pass(odoo_rules):
|
|
| 120 |
assert result.verdict in (layers.PASS, layers.WARN)
|
| 121 |
|
| 122 |
|
| 123 |
-
def
|
| 124 |
-
"""The corpus was checked against 18.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
result = layers.layer_context(odoo_rules, _ctx(odoo_series="15.0",
|
| 126 |
manifest="__manifest__.py"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
assert result.verdict == layers.WARN
|
| 128 |
-
assert any(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
|
| 130 |
|
| 131 |
# ------------------------------------------------------------ semantic gating
|
|
|
|
| 120 |
assert result.verdict in (layers.PASS, layers.WARN)
|
| 121 |
|
| 122 |
|
| 123 |
+
def test_context_mismatched_series_is_a_gap_and_not_a_finding(odoo_rules):
|
| 124 |
+
"""The corpus was checked against 18.0 and a 15.0 module deserves to be told
|
| 125 |
+
-- under 'Not checked', which is where things that are true of the corpus
|
| 126 |
+
rather than of the answer belong.
|
| 127 |
+
|
| 128 |
+
It was a finding, and as a finding it was the floor: no module off the
|
| 129 |
+
newest series could reach PASS however good the answer was, on any run. A
|
| 130 |
+
verdict that fires every time stops being read, and none of the 15 Odoo
|
| 131 |
+
rules carries an odoo_versions field, so the blanket warning was standing in
|
| 132 |
+
for per-rule data that does not exist yet.
|
| 133 |
+
"""
|
| 134 |
result = layers.layer_context(odoo_rules, _ctx(odoo_series="15.0",
|
| 135 |
manifest="__manifest__.py"))
|
| 136 |
+
assert result.findings == []
|
| 137 |
+
assert result.verdict == layers.UNKNOWN, "nothing was established, and it says so"
|
| 138 |
+
assert any("15.0" in why and "18.0" in why for _, why in result.not_checked)
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def test_context_still_warns_about_a_rule_that_does_not_apply(odoo_rules):
|
| 142 |
+
"""The half that survived the demotion, and the half that earns a finding:
|
| 143 |
+
this one names a rule that was retrieved and genuinely does not hold here."""
|
| 144 |
+
versioned = [dict(odoo_rules[0], odoo_versions="17.0-18.0")]
|
| 145 |
+
result = layers.layer_context(versioned, _ctx(odoo_series="15.0",
|
| 146 |
+
manifest="__manifest__.py"))
|
| 147 |
assert result.verdict == layers.WARN
|
| 148 |
+
assert any(f.rule == odoo_rules[0]["id"] for f in result.findings)
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
def test_strict_off_is_a_gap_too():
|
| 152 |
+
"""Same shape as the series mismatch: true of the project, not of the
|
| 153 |
+
answer, and true on every run until somebody finishes the migration."""
|
| 154 |
+
result = layers.layer_context([], _ctx(stack="typescript", ts_strict=False))
|
| 155 |
+
assert result.findings == []
|
| 156 |
+
assert result.verdict == layers.UNKNOWN
|
| 157 |
+
assert any("strict off" in why for _, why in result.not_checked)
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
def test_strict_on_is_something_this_layer_checked():
|
| 161 |
+
result = layers.layer_context([], _ctx(stack="typescript", ts_strict=True))
|
| 162 |
+
assert result.verdict == layers.PASS
|
| 163 |
+
assert "tsconfig strict" in result.checked
|
| 164 |
|
| 165 |
|
| 166 |
# ------------------------------------------------------------ semantic gating
|