instar 1.3.1031 → 1.3.1032
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -212,12 +212,32 @@ function isInRegistry(filepath, registryContent) {
|
|
|
212
212
|
|
|
213
213
|
function hasMatchingCanary(stagedFiles, filepath) {
|
|
214
214
|
// A matching canary is any file in the same adapter's canary/ directory,
|
|
215
|
-
// or a file named *Canary*.ts
|
|
215
|
+
// or a file named *Canary*.ts ADJACENT to the source file.
|
|
216
|
+
//
|
|
217
|
+
// "Adjacent" used to be unimplemented: the second clause tested
|
|
218
|
+
// `/canary/i.test(path.basename(f))` against every staged file without ever
|
|
219
|
+
// referencing `filepath`. That made it a property of the COMMIT, not a
|
|
220
|
+
// relationship — stage one canary-named file anywhere and every other file in
|
|
221
|
+
// the change was credited with having a canary. src/ carries 11 such files, so
|
|
222
|
+
// any broad commit touching one satisfied the canary half of Rule 3 wholesale.
|
|
223
|
+
//
|
|
224
|
+
// It failed in the QUIET direction (weakening the gate rather than blocking
|
|
225
|
+
// wrongly), which is why nothing ever complained about it.
|
|
226
|
+
// TWO canary/ locations, because sources sit at two depths. A source one
|
|
227
|
+
// level below the adapter root (adapters/X/observability/foo.ts) has its
|
|
228
|
+
// canary at adapters/X/canary/; a source AT the adapter root
|
|
229
|
+
// (adapters/X/foo.ts) has it at adapters/X/canary/ too — but that is
|
|
230
|
+
// `<dir>/canary`, not `<parent>/canary`. The original computed only the
|
|
231
|
+
// parent form, so the directory clause silently missed the second layout and
|
|
232
|
+
// the global fallback above was covering for it. Removing the fallback
|
|
233
|
+
// without fixing this would have turned a too-weak check into a wrong one.
|
|
216
234
|
const dir = path.dirname(filepath);
|
|
217
235
|
const adapterRoot = dir.split('/').slice(0, -1).join('/');
|
|
218
|
-
const
|
|
236
|
+
const canaryDirs = [path.join(dir, 'canary'), path.join(adapterRoot, 'canary')];
|
|
219
237
|
return stagedFiles.some(
|
|
220
|
-
(f) =>
|
|
238
|
+
(f) =>
|
|
239
|
+
canaryDirs.some((cd) => f.startsWith(cd + '/')) ||
|
|
240
|
+
(path.dirname(f) === dir && /canary/i.test(path.basename(f))),
|
|
221
241
|
);
|
|
222
242
|
}
|
|
223
243
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-07-28T13:
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-07-28T13:11:52.917Z",
|
|
5
|
+
"instarVersion": "1.3.1032",
|
|
6
6
|
"entryCount": 202,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The Rule 3 gate's canary check credited a file if **any** staged file had a canary-ish basename — it
|
|
9
|
+
never referenced the file under test, so it was a property of the commit rather than a relationship.
|
|
10
|
+
`src/` holds 11 canary-named files, so any broad commit touching one satisfied the canary half of Rule 3
|
|
11
|
+
for everything else in the change. It failed in the permissive direction, which is why it went unnoticed.
|
|
12
|
+
|
|
13
|
+
Underneath it, the canary-directory probe computed `<parent-of-dir>/canary` only, missing a source that
|
|
14
|
+
sits directly in an adapter root. The permissive fallback was masking that — so removing the fallback
|
|
15
|
+
alone would have turned a too-weak check into a wrong one.
|
|
16
|
+
|
|
17
|
+
Both fixed: the fallback now requires the canary to be in the file's own directory, and the probe covers
|
|
18
|
+
both layouts.
|
|
19
|
+
|
|
20
|
+
## What to Tell Your User
|
|
21
|
+
|
|
22
|
+
Nothing — a contributor-facing pre-commit script.
|
|
23
|
+
|
|
24
|
+
## Summary of New Capabilities
|
|
25
|
+
|
|
26
|
+
None. The gate is stricter: it stops granting canary credit that was never earned. A file carrying a
|
|
27
|
+
Rule 3.1 rationale is unaffected.
|
|
28
|
+
|
|
29
|
+
## Evidence
|
|
30
|
+
|
|
31
|
+
- Red → green: the new unrelated-canary test fails without the change (1 failed / 26 passed), passes with
|
|
32
|
+
it (27/27).
|
|
33
|
+
- The **second** bug was found because an existing test failed when I tightened the first. I assumed the
|
|
34
|
+
test was wrong; it was describing a real directory layout the probe could not see.
|
|
35
|
+
- Held deliberately until #1701 landed — tightening this earlier would have surfaced main's latent Rule 3
|
|
36
|
+
violations on every merge. Verified `mergeHeadIfMerging` is on `main` before proceeding.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# ELI16 — one file with the right name let a whole commit off the hook
|
|
2
|
+
|
|
3
|
+
Rule 3 says code that reads outside state must ship with either a written justification or a "canary" —
|
|
4
|
+
a small file that proves the reading still works. The check looked for a canary next to your file.
|
|
5
|
+
|
|
6
|
+
Except it didn't check "next to". It asked: *is any file in this commit called something-canary?* If
|
|
7
|
+
yes, **every** file in the commit was treated as having one. There are eleven canary-named files in the
|
|
8
|
+
source tree, so any broad change touching one of them satisfied that half of the rule for everything
|
|
9
|
+
else it contained.
|
|
10
|
+
|
|
11
|
+
It failed silently in the permissive direction — it let things through rather than blocking them — so
|
|
12
|
+
nobody ever hit it and complained.
|
|
13
|
+
|
|
14
|
+
**A second bug was hiding underneath.** The check *did* have a proper "look in the canary folder next to
|
|
15
|
+
this file" rule, but it looked one directory too high. It worked for files nested inside an adapter and
|
|
16
|
+
missed files sitting directly in one. The sloppy catch-all was quietly covering for it — so removing
|
|
17
|
+
the catch-all on its own would have turned a too-weak check into a plainly wrong one.
|
|
18
|
+
|
|
19
|
+
I only found that because an existing test failed when I tightened the first rule. I had assumed the
|
|
20
|
+
test was wrong. It wasn't; it was describing a real folder layout the check couldn't see.
|
|
21
|
+
|
|
22
|
+
**Both are fixed:** the catch-all now requires the canary to actually be beside the file, and the folder
|
|
23
|
+
rule checks both layouts.
|
|
24
|
+
|
|
25
|
+
The check is now stricter than it was yesterday. That's the point — it was passing things it should
|
|
26
|
+
have refused.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Side-effects review — Rule 3 canary adjacency
|
|
2
|
+
|
|
3
|
+
**Change:** `hasMatchingCanary` in `scripts/check-rule3-coverage.cjs` — the basename fallback is scoped
|
|
4
|
+
to the file's own directory, and the canary-directory probe now covers both layouts. One new test.
|
|
5
|
+
|
|
6
|
+
## Direction of effect
|
|
7
|
+
|
|
8
|
+
**Stricter**, so the risk to weigh is a false REFUSAL blocking legitimate work.
|
|
9
|
+
|
|
10
|
+
| situation | before | after |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| canary in `<dir>/canary/` | **missed** (only `<parent>/canary` was computed) | matched |
|
|
13
|
+
| canary in `<parent>/canary/` | matched | matched |
|
|
14
|
+
| canary-named file **beside** the source | matched | matched |
|
|
15
|
+
| canary-named file **anywhere else in the commit** | matched ❌ | **not matched** — the fix |
|
|
16
|
+
| no canary, but a rationale comment | passes | passes (unchanged) |
|
|
17
|
+
|
|
18
|
+
Rule 3 is satisfied by `inRegistry && (rationale || canary)` **or** `rationale && canary`, so a file
|
|
19
|
+
with a rationale is unaffected either way. This only removes credit that was never earned.
|
|
20
|
+
|
|
21
|
+
## The interaction that made this worth care
|
|
22
|
+
|
|
23
|
+
Removing the global fallback alone would have **broken** the check: the directory probe computed
|
|
24
|
+
`<parent-of-dir>/canary`, which misses a source sitting directly in an adapter root. The fallback was
|
|
25
|
+
masking it. An existing test caught this immediately — I had assumed the test was wrong, and it was
|
|
26
|
+
describing a real layout.
|
|
27
|
+
|
|
28
|
+
## Sequencing — why now and not earlier
|
|
29
|
+
|
|
30
|
+
Filed as ACT-1472 and deliberately held: making this stricter **before** #1701 (judge the author's
|
|
31
|
+
contribution, not the merge index) would have surfaced all of main's latent Rule 3 violations on every
|
|
32
|
+
merge. #1701 is now on `main` (verified: `mergeHeadIfMerging` present), so a merge evaluates only the
|
|
33
|
+
committer's own files and this cannot cascade.
|
|
34
|
+
|
|
35
|
+
## Blast radius
|
|
36
|
+
|
|
37
|
+
Pre-commit script only — not in `src/`, not shipped, not executed at runtime. `git revert` restores
|
|
38
|
+
both the permissive fallback and the layout blind spot.
|
|
39
|
+
|
|
40
|
+
## Verification
|
|
41
|
+
|
|
42
|
+
- Red → green: the new unrelated-canary test fails without the change (1 failed / 26 passed) and passes
|
|
43
|
+
with it (27/27).
|
|
44
|
+
- The pre-existing "canary staged alongside" test passes, which is what demonstrates the layout fix —
|
|
45
|
+
it was the failure that revealed the second bug.
|