@miller-tech/uap 1.65.2 → 1.65.3
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
|
Binary file
|
|
@@ -35,6 +35,59 @@ SHIP_PATTERNS = (
|
|
|
35
35
|
re.compile(r"\b(pr[-_ ]?ready|sign[-_ ]?off|ready[-_ ]for[-_ ]review)\b", re.I),
|
|
36
36
|
)
|
|
37
37
|
|
|
38
|
+
# Risk-scope: a parallel expert review is required only for *substantive* diffs.
|
|
39
|
+
# A diff that touches ONLY low-risk surfaces (frontend/styles, docs, config,
|
|
40
|
+
# tests, assets) ships freely — trivial/frontend PRs aren't gated. High-risk
|
|
41
|
+
# paths (infra/IaC, CI/CD, schemas/contracts, DB migrations, the policy engine)
|
|
42
|
+
# always require review, even with a low-risk extension.
|
|
43
|
+
LOW_RISK_EXT = {
|
|
44
|
+
".css", ".scss", ".sass", ".less", ".html", ".astro", ".vue", ".svelte",
|
|
45
|
+
".tsx", ".jsx", ".md", ".mdx", ".txt", ".csv", ".svg", ".png", ".jpg",
|
|
46
|
+
".jpeg", ".gif", ".webp", ".avif", ".ico", ".woff", ".woff2", ".ttf", ".eot",
|
|
47
|
+
".json", ".yaml", ".yml", ".toml", ".lock", ".lockb",
|
|
48
|
+
}
|
|
49
|
+
LOW_RISK_DIR_RE = re.compile(
|
|
50
|
+
r"(^|/)(docs|public|assets|static|stories|__tests__|tests?|e2e|fixtures)/", re.I
|
|
51
|
+
)
|
|
52
|
+
HIGH_RISK_PATH_RE = re.compile(
|
|
53
|
+
r"(^|/)(infra|terraform|helm|helm_charts|k8s|kubernetes)/"
|
|
54
|
+
r"|\.tf$|\.tfvars$|\.tf\.json$"
|
|
55
|
+
r"|(^|/)\.github/workflows/"
|
|
56
|
+
r"|(^|/)migrations?/|\.sql$"
|
|
57
|
+
r"|(^|/)schemas/|^src/types/|\.proto$"
|
|
58
|
+
r"|(^|/)[Dd]ockerfile|docker-compose"
|
|
59
|
+
r"|^src/policies/",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _changed_files(root: Path) -> list[str] | None:
|
|
64
|
+
"""Files changed vs the upstream base, or None if no base is resolvable
|
|
65
|
+
(detached / no upstream — the caller then falls back to requiring review)."""
|
|
66
|
+
for base in ("origin/master", "origin/main", "master", "main"):
|
|
67
|
+
rc, out, _ = run(["git", "diff", "--name-only", f"{base}...HEAD"], cwd=root, timeout=10)
|
|
68
|
+
if rc == 0:
|
|
69
|
+
return [ln.strip() for ln in out.splitlines() if ln.strip()]
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _is_low_risk(f: str) -> bool:
|
|
74
|
+
if HIGH_RISK_PATH_RE.search(f):
|
|
75
|
+
return False
|
|
76
|
+
if LOW_RISK_DIR_RE.search(f):
|
|
77
|
+
return True
|
|
78
|
+
return Path(f).suffix.lower() in LOW_RISK_EXT
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _active_waiver(root: Path) -> bool:
|
|
82
|
+
"""A committable, env-free bypass: an active waiver file. Works in harnesses
|
|
83
|
+
that strip env vars (where UAP_NO_REVIEW=1 cannot be set)."""
|
|
84
|
+
wdir = root / "policies" / "waivers"
|
|
85
|
+
if wdir.exists():
|
|
86
|
+
for w in wdir.glob("*expert-review*.md"):
|
|
87
|
+
if w.is_file():
|
|
88
|
+
return True
|
|
89
|
+
return (root / ".uap" / "reviews" / "WAIVER").exists()
|
|
90
|
+
|
|
38
91
|
|
|
39
92
|
def current_branch(root: Path) -> str | None:
|
|
40
93
|
# symbolic-ref resolves the branch name even on an unborn branch (no commits
|
|
@@ -85,6 +138,23 @@ def main() -> None:
|
|
|
85
138
|
emit(True, "branch not resolvable (detached/non-git) — fail-open")
|
|
86
139
|
slug = slug_for(branch)
|
|
87
140
|
|
|
141
|
+
# Env-free bypass: an active waiver file (works where UAP_NO_REVIEW=1 can't).
|
|
142
|
+
if _active_waiver(root):
|
|
143
|
+
emit(True, "expert-review waived (policies/waivers/*expert-review*.md or .uap/reviews/WAIVER)")
|
|
144
|
+
|
|
145
|
+
# Risk-scope: if the diff vs upstream touches ONLY low-risk surfaces
|
|
146
|
+
# (frontend/styles, docs, config, tests, assets) — no infra/IaC, CI, schemas,
|
|
147
|
+
# migrations, or policy code — the change ships without a parallel review.
|
|
148
|
+
# When the base diff is not resolvable (None) we do NOT skip: we can't prove
|
|
149
|
+
# the change is low-risk, so the review requirement below still applies.
|
|
150
|
+
changed = _changed_files(root)
|
|
151
|
+
if changed and all(_is_low_risk(f) for f in changed):
|
|
152
|
+
emit(
|
|
153
|
+
True,
|
|
154
|
+
f"low-risk diff ({len(changed)} file(s): frontend/docs/config/tests only) "
|
|
155
|
+
"— parallel expert review not required",
|
|
156
|
+
)
|
|
157
|
+
|
|
88
158
|
review = root / ".uap" / "reviews" / f"{slug}.json"
|
|
89
159
|
if not review.exists():
|
|
90
160
|
emit(
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
## Rule
|
|
9
9
|
|
|
10
|
-
A parallel expert review MUST precede shipping a
|
|
10
|
+
A parallel expert review MUST precede shipping a **substantive** change. When no
|
|
11
11
|
review artifact exists for the current branch (or the artifact is stale relative
|
|
12
12
|
to `HEAD`), the enforcer blocks the ship actions:
|
|
13
13
|
|
|
@@ -15,6 +15,23 @@ to `HEAD`), the enforcer blocks the ship actions:
|
|
|
15
15
|
- `gh pr create`
|
|
16
16
|
- merge / pr-ready / signoff / ready-for-review operations
|
|
17
17
|
|
|
18
|
+
### Risk scope (low-risk diffs ship freely)
|
|
19
|
+
|
|
20
|
+
The review is required only when the diff vs upstream touches a **substantive**
|
|
21
|
+
surface. A change that touches ONLY low-risk surfaces — frontend/styles
|
|
22
|
+
(`.css/.scss/.tsx/.jsx/.vue/.svelte/.html`), docs (`.md`), config
|
|
23
|
+
(`.json/.yaml/.toml`), tests, and assets — ships without a parallel review, so
|
|
24
|
+
frontend-only / docs-only PRs are never blocked.
|
|
25
|
+
|
|
26
|
+
High-risk paths ALWAYS require review even with a low-risk extension:
|
|
27
|
+
infra/IaC (`infra/`, `terraform/`, `helm/`, `k8s/`, `*.tf`), CI/CD
|
|
28
|
+
(`.github/workflows/`), schemas/contracts (`schemas/`, `src/types/`, `*.proto`),
|
|
29
|
+
DB migrations (`migrations/`, `*.sql`), container build (`Dockerfile`,
|
|
30
|
+
`docker-compose`), and the policy engine (`src/policies/`).
|
|
31
|
+
|
|
32
|
+
When the upstream base diff is not resolvable (detached HEAD / no upstream), the
|
|
33
|
+
enforcer does NOT assume low-risk — the review requirement still applies.
|
|
34
|
+
|
|
18
35
|
Review artifact: `.uap/reviews/<branch-slug>.json`, written by the
|
|
19
36
|
`parallel-expert-review` skill on consolidation. The slug is an **injective
|
|
20
37
|
percent-encoding** of the branch name (`%`→`%25`, `/`→`%2F`) so distinct refs
|
|
@@ -51,7 +68,14 @@ with `/` → `-`). Missing artifact → block; present but `head` mismatch → b
|
|
|
51
68
|
(stale); present and current → allow.
|
|
52
69
|
|
|
53
70
|
Fail-open: if the branch/HEAD cannot be resolved (detached HEAD, non-git tree),
|
|
54
|
-
the operation is allowed.
|
|
71
|
+
the operation is allowed.
|
|
72
|
+
|
|
73
|
+
Bypasses (two, so a constrained harness always has one available):
|
|
74
|
+
|
|
75
|
+
- `UAP_NO_REVIEW=1` — environment override (one-off meta-work).
|
|
76
|
+
- **File waiver** — a committable file, which works in harnesses that strip env
|
|
77
|
+
vars: any `policies/waivers/*expert-review*.md`, or a `.uap/reviews/WAIVER`
|
|
78
|
+
marker. Use this when the env override can't be set.
|
|
55
79
|
|
|
56
80
|
```rules
|
|
57
81
|
- title: "A parallel expert review must precede ship"
|