instar 1.3.258 → 1.3.259
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
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ELI16-on-every-PR gate (team standard, 2026-06-05).
|
|
4
|
+
*
|
|
5
|
+
* Every PR's DESCRIPTION must carry a plain-English ELI16 overview — because the
|
|
6
|
+
* PR description is what a reviewer reads and approves when they open the link.
|
|
7
|
+
* The ELI16 *file* (docs/specs/<slug>.eli16.md) remains the durable companion;
|
|
8
|
+
* this gate enforces that the OVERVIEW is also in the PR BODY so it is front and
|
|
9
|
+
* centre at review time. (Justin, 2026-06-05: "when I click on the link, that's
|
|
10
|
+
* what I'm going to see and read and approve.")
|
|
11
|
+
*
|
|
12
|
+
* Pure check — `checkPrDescriptionEli16({ body, title, authorType })` — plus a
|
|
13
|
+
* CLI wrapper that reads PR_BODY / PR_TITLE / PR_AUTHOR_TYPE from env (set by the
|
|
14
|
+
* workflow) and exits 0 when an ELI16 overview is present (or the PR is exempt),
|
|
15
|
+
* 1 with actionable guidance when it is missing.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** Minimum plain-English content under the ELI16 heading — a real overview, not a one-liner. */
|
|
19
|
+
export const MIN_ELI16_DESCRIPTION_CHARS = 200;
|
|
20
|
+
|
|
21
|
+
/** A markdown heading (any level) whose text contains "ELI16" / "ELI-16" / "ELI 16". */
|
|
22
|
+
const ELI16_HEADING = /^[ \t]*#{1,6}[ \t]+.*ELI[ \t-]?16/im;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {{ body?: string|null, title?: string|null, authorType?: string|null }} pr
|
|
26
|
+
* @returns {{ ok: boolean, exempt?: string, reason?: string, chars?: number, min?: number }}
|
|
27
|
+
*/
|
|
28
|
+
export function checkPrDescriptionEli16(pr) {
|
|
29
|
+
const title = String(pr?.title ?? '');
|
|
30
|
+
// Exempt the genuinely-automated PRs: bot authors + the release-cut commit.
|
|
31
|
+
if (String(pr?.authorType ?? '') === 'Bot') return { ok: true, exempt: 'bot-author' };
|
|
32
|
+
if (/^chore:\s*release\b/i.test(title)) return { ok: true, exempt: 'release-cut' };
|
|
33
|
+
|
|
34
|
+
const body = String(pr?.body ?? '');
|
|
35
|
+
const m = ELI16_HEADING.exec(body);
|
|
36
|
+
if (!m) return { ok: false, reason: 'no-eli16-heading' };
|
|
37
|
+
|
|
38
|
+
// Content under the ELI16 heading, up to the next heading.
|
|
39
|
+
const after = body.slice(m.index + m[0].length);
|
|
40
|
+
const section = after.split(/\n[ \t]*#{1,6}[ \t]/)[0];
|
|
41
|
+
const content = section.replace(/<!--[\s\S]*?-->/g, '').trim();
|
|
42
|
+
if (content.length < MIN_ELI16_DESCRIPTION_CHARS) {
|
|
43
|
+
return { ok: false, reason: 'eli16-too-short', chars: content.length, min: MIN_ELI16_DESCRIPTION_CHARS };
|
|
44
|
+
}
|
|
45
|
+
return { ok: true };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ── CLI (used by .github/workflows/eli16-pr-gate.yml) ─────────────────
|
|
49
|
+
const invokedDirectly =
|
|
50
|
+
process.argv[1] && import.meta.url === new URL(`file://${process.argv[1]}`).href;
|
|
51
|
+
if (invokedDirectly) {
|
|
52
|
+
const res = checkPrDescriptionEli16({
|
|
53
|
+
body: process.env.PR_BODY,
|
|
54
|
+
title: process.env.PR_TITLE,
|
|
55
|
+
authorType: process.env.PR_AUTHOR_TYPE,
|
|
56
|
+
});
|
|
57
|
+
if (res.ok) {
|
|
58
|
+
console.log(
|
|
59
|
+
res.exempt
|
|
60
|
+
? `ELI16 gate: exempt (${res.exempt}).`
|
|
61
|
+
: 'ELI16 gate: OK — the PR description includes an ELI16 overview.',
|
|
62
|
+
);
|
|
63
|
+
process.exit(0);
|
|
64
|
+
}
|
|
65
|
+
const detail =
|
|
66
|
+
res.reason === 'eli16-too-short'
|
|
67
|
+
? ` (found an ELI16 heading but only ${res.chars} chars of content; need >= ${res.min}).`
|
|
68
|
+
: '.';
|
|
69
|
+
console.error(
|
|
70
|
+
`ELI16 gate FAILED: this PR's description has no plain-English ELI16 overview${detail}\n\n` +
|
|
71
|
+
`Team standard (2026-06-05): every PR description must include an "## ELI16 — <one line>" section ` +
|
|
72
|
+
`that explains the change for a non-expert — because the PR description is what the reviewer reads ` +
|
|
73
|
+
`and approves when they open the link. Add it to the PR body (copy from your ` +
|
|
74
|
+
`docs/specs/<slug>.eli16.md companion). Edit the PR description and this check will re-run.`,
|
|
75
|
+
);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-06-05T00:
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-06-05T00:47:15.893Z",
|
|
5
|
+
"instarVersion": "1.3.259",
|
|
6
6
|
"entryCount": 198,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
Added a CI gate (`.github/workflows/eli16-pr-gate.yml` + the pure check
|
|
9
|
+
`scripts/eli16-pr-description-check.mjs`) that requires every PR's DESCRIPTION to carry a
|
|
10
|
+
plain-English ELI16 overview, and FAILS the PR when it is missing. Per Justin's standard
|
|
11
|
+
(2026-06-05): the PR description is what a reviewer reads and approves on the link, and the PRs "had
|
|
12
|
+
different formats." The ELI16 *file* (docs/specs/<slug>.eli16.md) is unchanged and still enforced at
|
|
13
|
+
commit time; this closes the PR-body half. Re-runs on `edited` (self-clears on a description fix);
|
|
14
|
+
exempts bot authors + the automated release-cut PR.
|
|
15
|
+
|
|
16
|
+
## What to Tell Your User
|
|
17
|
+
|
|
18
|
+
None — internal change (no user-facing surface).
|
|
19
|
+
|
|
20
|
+
## Summary of New Capabilities
|
|
21
|
+
|
|
22
|
+
None — internal change (no user-facing surface).
|
|
23
|
+
|
|
24
|
+
## Evidence
|
|
25
|
+
|
|
26
|
+
- The decision is a PURE function (`checkPrDescriptionEli16`) with 10 unit tests covering both
|
|
27
|
+
sides (has-overview → pass; missing / too-short / next-heading-boundary / comment-stripped → fail)
|
|
28
|
+
and every exemption (bot, release-cut, title-mentions-release non-exemption, null inputs).
|
|
29
|
+
- `node --check scripts/eli16-pr-description-check.mjs` clean. New additive workflow — cannot affect
|
|
30
|
+
existing checks/builds/releases; a failing PR is visible + self-clears on a description edit.
|
|
31
|
+
- This PR's own description carries an ELI16 overview (dogfoods the gate). scripts + workflow + test
|
|
32
|
+
only, no `src/` (internal-only lane).
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Side-Effects Review — ELI16-on-every-PR gate (PR description)
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `eli16-pr-description-gate`
|
|
4
|
+
**Date:** `2026-06-05`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** `required (a new gate that blocks EVERY PR)`
|
|
7
|
+
|
|
8
|
+
## Summary
|
|
9
|
+
|
|
10
|
+
Justin's standard (2026-06-05): every PR's DESCRIPTION must carry a plain-English ELI16 overview,
|
|
11
|
+
because the description is what a reviewer reads and approves when they open the PR link — and the
|
|
12
|
+
current PRs "have different formats." This adds a CI gate (`.github/workflows/eli16-pr-gate.yml`)
|
|
13
|
+
that runs a pure check (`scripts/eli16-pr-description-check.mjs`) on every PR body and FAILS the PR
|
|
14
|
+
when no ELI16 overview is present. The ELI16 *file* (`docs/specs/<slug>.eli16.md`) is unchanged and
|
|
15
|
+
still enforced at commit time by the instar-dev gate; this is the missing PR-body half.
|
|
16
|
+
|
|
17
|
+
## Decision-point inventory
|
|
18
|
+
|
|
19
|
+
One decision: does the PR body contain an ELI16 overview? PASS when (a) the author is a Bot, or
|
|
20
|
+
(b) the title is a `chore: release` cut, or (c) the body has a heading whose text contains
|
|
21
|
+
`ELI16`/`ELI-16`/`ELI 16` followed by >= 200 chars of (comment-stripped) content. Otherwise FAIL.
|
|
22
|
+
|
|
23
|
+
## 1. Over-block (what it blocks)
|
|
24
|
+
|
|
25
|
+
A human/agent PR whose description lacks a real ELI16 overview is blocked — that's the point. The
|
|
26
|
+
check re-runs on `edited`, so adding the overview to the description clears it WITHOUT a new push.
|
|
27
|
+
The failure message is actionable (tells you exactly what to add + that the file is a good source).
|
|
28
|
+
|
|
29
|
+
## 2. Under-block (what it lets through)
|
|
30
|
+
|
|
31
|
+
Bot PRs and the automated `chore: release` PR (which has no human reviewer reading an ELI16). A PR
|
|
32
|
+
that has a real ELI16 heading + >= 200 chars passes. The check measures content only up to the next
|
|
33
|
+
heading, so a one-line ELI16 followed by a long "What Changed" does NOT slip through (tested).
|
|
34
|
+
|
|
35
|
+
## 3. Blast radius — CRITICAL
|
|
36
|
+
|
|
37
|
+
This gate blocks EVERY non-exempt PR, so a false-fail would block the whole fleet's PRs. Mitigations:
|
|
38
|
+
the decision is a PURE function with 10 unit tests covering both sides AND every exemption (bot,
|
|
39
|
+
release-cut, the "title mentions release" non-exemption, null/empty inputs, the next-heading
|
|
40
|
+
boundary, comment-stripping). The gate is a NEW, additive workflow — it cannot affect existing
|
|
41
|
+
checks, builds, or releases; a failing PR is VISIBLE and self-clears on a description edit (not a
|
|
42
|
+
silent jam like the manifest/publish class). No `src/` runtime change.
|
|
43
|
+
|
|
44
|
+
## 4. Reversibility
|
|
45
|
+
|
|
46
|
+
Fully reversible: delete the workflow + script + test. No state, no migration. Verified: the check
|
|
47
|
+
script parses (`node --check`); 10/10 unit tests pass. This PR's own description carries an ELI16
|
|
48
|
+
overview (dogfoods the gate).
|