@reneturcios/greenlight 0.9.2 → 0.10.0

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/dist/friction.js CHANGED
@@ -1,6 +1,5 @@
1
- import { gateLabel } from "./gates.js";
2
- import { fetchContributing, detectRepoPolicy, countStarterIssues, } from "./github.js";
3
- import { parseGates } from "./gates.js";
1
+ import { gateLabel, parseGatesFromSources } from "./gates.js";
2
+ import { fetchPolicySources, detectRepoPolicy, countStarterIssues, } from "./github.js";
4
3
  import { fetchMergeVelocity } from "./merge-velocity.js";
5
4
  const GATE_WEIGHTS = {
6
5
  assignment_required: -25,
@@ -47,38 +46,70 @@ export function scoreFriction(signals) {
47
46
  if (bonus > 0)
48
47
  reasons.push(`${signals.openGoodFirstIssueCount} open good-first-issues (+${bonus.toFixed(1)})`);
49
48
  }
49
+ // v0.9.3: ratio fields in JSON always ship both units. The fraction
50
+ // keeps its meaning; the _pct sibling is unambiguous.
51
+ const signalsOut = {
52
+ ...signals,
53
+ externalPRMergeRate_pct: signals.externalPRMergeRate === undefined || signals.externalPRMergeRate === null
54
+ ? null
55
+ : Math.round(signals.externalPRMergeRate * 100),
56
+ };
50
57
  return {
51
58
  owner: signals.owner,
52
59
  repo: signals.repo,
53
60
  score: Math.round(clamp(score, 0, 100)),
54
61
  gates: signals.gates,
55
62
  reasons,
56
- signals,
63
+ signals: signalsOut,
57
64
  };
58
65
  }
59
66
  /**
60
- * The repo_friction pipeline as one callable: gates from CONTRIBUTING and
61
- * house rules, starter-issue count, and merge velocity as a best-effort
62
- * signal. Shared by the CLI, the MCP repo_friction tool, and the
63
- * protocol preflight (which pairs it with the issue status).
67
+ * Attach the outsider merge share to a friction report with an explicit
68
+ * unit contract (v0.9.3): the fraction and the 0..100 percent side by
69
+ * side, so no consumer can mistake one for the other again.
70
+ */
71
+ export function attachOutsiderShare(report) {
72
+ const share = report.signals.externalPRMergeRate ??
73
+ report.mergeVelocity?.externalShare ??
74
+ null;
75
+ report.outsider_merge_share = share;
76
+ report.outsider_merge_share_pct = share === null ? null : Math.round(share * 100);
77
+ return report;
78
+ }
79
+ /**
80
+ * The repo_friction pipeline as one callable: gates from the full policy
81
+ * source set (CONTRIBUTING variants and house rules at root, .github/
82
+ * and docs/, plus the org-level AI_POLICY.md), starter-issue count, and
83
+ * merge velocity as a best-effort signal. Shared by the CLI, the MCP
84
+ * repo_friction tool, and the protocol preflight (which pairs it with
85
+ * the issue status).
64
86
  */
65
87
  export async function fetchFrictionSummary(owner, repo) {
66
- const [contributing, policy, starterCount] = await Promise.all([
67
- fetchContributing(owner, repo),
88
+ const [sources, policy, starterCount] = await Promise.all([
89
+ fetchPolicySources(owner, repo),
68
90
  detectRepoPolicy(owner, repo),
69
91
  countStarterIssues(owner, repo),
70
92
  ]);
71
- const gates = parseGates(contributing, { collaboratorsOnlyPolicy: policy.collaboratorsOnly });
72
- const report = scoreFriction({
93
+ const gates = parseGatesFromSources(sources);
94
+ if (policy.collaboratorsOnly && !gates.some((g) => g.kind === "collaborators_only" && g.detected)) {
95
+ gates.push({
96
+ kind: "collaborators_only",
97
+ detected: true,
98
+ evidence: "repo policy: PR creation restricted to collaborators",
99
+ });
100
+ }
101
+ const signals = {
73
102
  owner,
74
103
  repo,
75
104
  gates,
76
105
  externalPRMergeRate: null,
106
+ externalPRMergeRate_pct: null,
77
107
  medianFirstReviewHours: null,
78
108
  maintainerIssueResponseHours: null,
79
109
  openGoodFirstIssueCount: starterCount,
80
110
  note: "live",
81
- });
111
+ };
112
+ const report = scoreFriction(signals);
82
113
  // Merge velocity is a signal, never a score input. Best-effort: silent
83
114
  // when it fails.
84
115
  try {
@@ -87,6 +118,6 @@ export async function fetchFrictionSummary(owner, repo) {
87
118
  catch {
88
119
  report.mergeVelocity = null;
89
120
  }
90
- return report;
121
+ return attachOutsiderShare(report);
91
122
  }
92
123
  //# sourceMappingURL=friction.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"friction.js","sourceRoot":"","sources":["../src/friction.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"friction.js","sourceRoot":"","sources":["../src/friction.ts"],"names":[],"mappings":"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"}
package/dist/gates.d.ts CHANGED
@@ -13,6 +13,22 @@
13
13
  * first and get rejected, while soft gates like claim_first only add a note.
14
14
  */
15
15
  import type { Gate, GateKind } from "./types.js";
16
+ /**
17
+ * v0.9.3 contradiction resolution (per policy file, never across files).
18
+ * Runs over one source's parsed gates plus its raw text:
19
+ * - An UNSCOPED ban (explicit prohibition: no autonomous agents, no AI
20
+ * PRs) stands on its own; welcome language elsewhere does not cancel an
21
+ * explicit prohibition (zed welcomes LLM coding and still bans
22
+ * autonomous-agent contributions, and both verdicts are correct).
23
+ * - A SCOPED ban (bulk/autonomous-only, unreviewed-only) plus welcome or
24
+ * disclosure language in the same file dual-classes: agents_banned
25
+ * (evidence: the scoped quote) AND agents_disclosure. If no disclosure
26
+ * pattern fired, the disclosure entry is synthesized from the welcome
27
+ * sentence so the human path is never silently lost (ppt-master,
28
+ * TypeScript). The ban is never downgraded away: for autonomous
29
+ * operation it is real.
30
+ */
31
+ export declare function resolveBanContradictions(gates: Gate[], text: string): Gate[];
16
32
  export interface ParseOptions {
17
33
  /** Repo-level policy passed in when detectable (e.g. from repo metadata). */
18
34
  collaboratorsOnlyPolicy?: boolean;
package/dist/gates.js CHANGED
@@ -1,3 +1,23 @@
1
+ /**
2
+ * v0.9.3: ban patterns scoped to a KIND of agent operation rather than a
3
+ * blanket prohibition. TypeScript's CONTRIBUTING refuses "bulk,
4
+ * agent-driven contributions" outright while welcoming human-led AI work
5
+ * with disclosure; ppt-master closes "purely AI-generated PRs submitted
6
+ * without human review" while welcoming reviewed AI assistance. A scoped
7
+ * ban is still a ban for autonomous operation, but the file's welcome or
8
+ * disclosure path must survive next to it (dual-class), never be silently
9
+ * swallowed by the ban verdict. These patterns are spread into the
10
+ * agents_banned rule below and are ALSO listed here so the contradiction
11
+ * resolver can tell a scoped ban from an unscoped one. Every scoped
12
+ * pattern requires a consequence clause (refused, closed, not accepted)
13
+ * so bare quality guidance ("understand what you submit") never counts
14
+ * as a ban.
15
+ */
16
+ const SCOPED_BAN_REGEXES = [
17
+ /do not accept.{0,80}(bulk|autonomous).{0,30}(agent|ai)[-\s]?driven (contributions?|pull requests?|prs?)/i,
18
+ /(bulk|mass)[-\s]?(agent|ai)[-\s]?driven (contributions?|pull requests?|prs?).{0,80}(not accepted|refused|will be closed|are not welcome|do not accept)/i,
19
+ /(purely|fully|entirely) ai[-\s]?(generated|authored|drafted).{0,50}(without human review|unreviewed|without (a )?human in the loop).{0,80}(closed|rejected|not a contribution|will not be merged)/i,
20
+ ];
1
21
  const RULES = [
2
22
  {
3
23
  kind: "assignment_required",
@@ -104,14 +124,40 @@ const RULES = [
104
124
  // rules are anchored on explicit agent/bot-prohibition language, not
105
125
  // on the mere word "AI", to avoid flagging repos that merely discuss
106
126
  // AI features or ask for disclosure.
127
+ //
128
+ // v0.9.3: the Agent Policy Index field work found nine more bans the
129
+ // old patterns missed because they live in CONTRIBUTING.md or in an
130
+ // org-level AI_POLICY.md, in prose the old patterns never covered:
131
+ // immich ("We ask you not to open PRs generated with an LLM"),
132
+ // meilisearch ("We will not consider any content generated by
133
+ // generative AI tooling"), alacritty ("must not include content
134
+ // generated by large language models"), zed ("we don't accept
135
+ // contributions from autonomous agents"), astral-sh ("We do not allow
136
+ // autonomous agents to be used for contributing"), dspy ("Do not
137
+ // submit issues, PRs, or reviews from fully autonomous AI agents"),
138
+ // kedro ("We do not welcome AI contributions by bots with no human in
139
+ // the loop", "PRs must not be opened by bots"), home-assistant
140
+ // ("Contributions made by autonomous agents are not accepted", via
141
+ // its AI_POLICY.md). Each new pattern below is anchored on an
142
+ // explicit prohibition, never on the mere mention of AI tooling.
107
143
  kind: "agents_banned",
108
144
  regexes: [
109
145
  /autonomous agents? (are|will be) not (allowed|accepted|welcome|permitted)/i,
110
146
  /contributions? (by|from) autonomous agents? (are|is) not allowed/i,
111
147
  /may only be submitted by a human/i,
112
148
  /no ai[-\s]?(generated|authored|written) (pull requests?|prs?|contributions?)/i,
113
- /do not (use|draft|post|submit|open).{0,80}(pr titles?|pr descriptions?|pull requests?|issues?, or discussion)/i,
149
+ /do not (draft|post).{0,80}(pr titles?|pr descriptions?|pull requests?|issues?, or discussion)/i,
114
150
  /\b(bots?|agents?) (are|will be) (prohibited|banned|forbidden).{0,60}(from )?(contribut|opening|submitting)/i,
151
+ /(ask you )?not to open (prs?|pull requests?) generated (with|by) (an? )?(llm|ai)\b/i,
152
+ /(will not|do not|don't|does not) consider.{0,50}(content )?generated by (generative )?ai\b/i,
153
+ /(must not|shall not|may not|cannot).{0,50}content generated by (large language models|llms?|generative ai|ai)\b/i,
154
+ /(do not|don't|does not) accept.{0,60}(contributions?|prs?|pull requests?).{0,40}(from )?autonomous agents?/i,
155
+ /(do not|don't|does not) allow.{0,50}autonomous agents?/i,
156
+ /do not submit.{0,80}(from )?(fully )?autonomous (ai )?agents?/i,
157
+ /(do not|don't|does not) welcome.{0,40}ai contributions?/i,
158
+ /(pull requests?|prs?).{0,40}(must not|may not|cannot|will not) be opened by (bots|automated|agents?)/i,
159
+ /autonomous (ai )?agents? may not (submit|open|contribute)/i,
160
+ ...SCOPED_BAN_REGEXES,
115
161
  ],
116
162
  },
117
163
  {
@@ -120,16 +166,120 @@ const RULES = [
120
166
  // and an AI disclosure sentence in the PR description. Disclosure is
121
167
  // a ritual to satisfy, not a block, so this is a flag, never a
122
168
  // verdict change: prep turns it into concrete required actions.
169
+ //
170
+ // v0.9.3: the old patterns only caught "disclosure" next to "AI" in
171
+ // one word order, so meilisearch ("If you use AI tools during your
172
+ // work, remember to disclose it in your PR description"), astral-sh
173
+ // ("disclosed as such"), and coolify ("If AI tools were used at any
174
+ // stage, mention it in the pull request description") all slipped
175
+ // through. The new patterns cover both orders and the "mention"
176
+ // phrasing. They stay anchored on an explicit ask, so a repo that
177
+ // merely waives disclosure (hyperframes: "there is no need to
178
+ // disclose it") still reads as no disclosure gate.
123
179
  kind: "agents_disclosure",
124
180
  regexes: [
125
181
  /\bai\b.{0,40}disclosure/i,
126
182
  /disclos(e|ing).{0,40}\bai\b/i,
183
+ /\bai\b.{0,60}disclos(e|ing|ure)/i,
184
+ /\b(ai|artificial intelligence)\b.{0,40}(mention|state|note|indicate|declare|disclose)/i,
185
+ /require.{0,25}(you )?to disclose/i,
186
+ /disclosed as such/i,
127
187
  /\[ai\].{0,60}(prefix|title|commit)/i,
128
188
  /(prefix|title).{0,60}\[ai\]/i,
129
189
  /ai[-\s]?generated.{0,60}(disclos|prefix|declare)/i,
130
190
  ],
131
191
  },
132
192
  ];
193
+ /**
194
+ * v0.9.3: explicit welcome of AI-assisted contributions. Internal signal
195
+ * only, never a gate kind: it feeds the contradiction resolver so a ban
196
+ * verdict can never silently erase a file's welcome or disclosure path
197
+ * (the hyperframes false-ban shape: "Do not submit AI-generated code you
198
+ * don't understand" next to "We welcome contributions that use AI tools...
199
+ * there is no need to disclose it"). Generic "we welcome contributions"
200
+ * prose does not count; the welcome must name AI.
201
+ */
202
+ const AI_WELCOME_RES = [
203
+ /we welcome.{0,80}\b(ai|artificial intelligence|llms?)\b/i,
204
+ /\bai[-\s]?(assistance|tools?) (is|are) welcome/i,
205
+ /we are pro ai assisted coding/i,
206
+ /(have|has) no objection to.{0,60}ai\b/i,
207
+ /there is no need to disclose/i,
208
+ ];
209
+ /**
210
+ * v0.9.3 contradiction resolution (per policy file, never across files).
211
+ * Runs over one source's parsed gates plus its raw text:
212
+ * - An UNSCOPED ban (explicit prohibition: no autonomous agents, no AI
213
+ * PRs) stands on its own; welcome language elsewhere does not cancel an
214
+ * explicit prohibition (zed welcomes LLM coding and still bans
215
+ * autonomous-agent contributions, and both verdicts are correct).
216
+ * - A SCOPED ban (bulk/autonomous-only, unreviewed-only) plus welcome or
217
+ * disclosure language in the same file dual-classes: agents_banned
218
+ * (evidence: the scoped quote) AND agents_disclosure. If no disclosure
219
+ * pattern fired, the disclosure entry is synthesized from the welcome
220
+ * sentence so the human path is never silently lost (ppt-master,
221
+ * TypeScript). The ban is never downgraded away: for autonomous
222
+ * operation it is real.
223
+ */
224
+ export function resolveBanContradictions(gates, text) {
225
+ const body = (text ?? "").replace(/\*+/g, "").replace(/\s+/g, " ");
226
+ const ban = gates.find((g) => g.kind === "agents_banned");
227
+ if (!ban || !ban.detected)
228
+ return gates;
229
+ const unscopedFired = UNSCOPED_BAN_RES.some((re) => re.test(body));
230
+ if (unscopedFired)
231
+ return gates;
232
+ const scopedFired = SCOPED_BAN_REGEXES.some((re) => re.test(body));
233
+ if (!scopedFired)
234
+ return gates;
235
+ const disclosure = gates.find((g) => g.kind === "agents_disclosure");
236
+ const welcomeFired = AI_WELCOME_RES.some((re) => re.test(body));
237
+ if (disclosure && disclosure.detected)
238
+ return gates;
239
+ if (!welcomeFired)
240
+ return gates;
241
+ // Scoped ban plus a welcome, but no disclosure pattern matched: the
242
+ // file describes a human-led path (review, understand, disclose), so
243
+ // surface it as agents_disclosure with the welcome as evidence rather
244
+ // than letting the ban verdict stand alone.
245
+ if (disclosure) {
246
+ disclosure.detected = true;
247
+ disclosure.evidence = snippet(body, AI_WELCOME_RES.find((re) => re.test(body)));
248
+ }
249
+ return gates;
250
+ }
251
+ /** The agents_banned patterns that are NOT scoped (explicit prohibitions). */
252
+ const UNSCOPED_BAN_RES = [
253
+ /autonomous agents? (are|will be) not (allowed|accepted|welcome|permitted)/i,
254
+ /contributions? (by|from) autonomous agents? (are|is) not allowed/i,
255
+ /may only be submitted by a human/i,
256
+ /no ai[-\s]?(generated|authored|written) (pull requests?|prs?|contributions?)/i,
257
+ /do not (draft|post).{0,80}(pr titles?|pr descriptions?|pull requests?|issues?, or discussion)/i,
258
+ /\b(bots?|agents?) (are|will be) (prohibited|banned|forbidden).{0,60}(from )?(contribut|opening|submitting)/i,
259
+ /(ask you )?not to open (prs?|pull requests?) generated (with|by) (an? )?(llm|ai)\b/i,
260
+ /(will not|do not|don't|does not) consider.{0,50}(content )?generated by (generative )?ai\b/i,
261
+ /(must not|shall not|may not|cannot).{0,50}content generated by (large language models|llms?|generative ai|ai)\b/i,
262
+ /(do not|don't|does not) accept.{0,60}(contributions?|prs?|pull requests?).{0,40}(from )?autonomous agents?/i,
263
+ /(do not|don't|does not) allow.{0,50}autonomous agents?/i,
264
+ /do not submit.{0,80}(from )?(fully )?autonomous (ai )?agents?/i,
265
+ /(do not|don't|does not) welcome.{0,40}ai contributions?/i,
266
+ /(pull requests?|prs?).{0,40}(must not|may not|cannot|will not) be opened by (bots|automated|agents?)/i,
267
+ /autonomous (ai )?agents? may not (submit|open|contribute)/i,
268
+ ];
269
+ /**
270
+ * v0.9.3: explicit disclosure WAIVERS. hyperframes welcomes AI help and
271
+ * says "there is no need to disclose it" — a waiver is the opposite of a
272
+ * disclosure gate, so when waiver language is present the disclosure gate
273
+ * is suppressed. A file cannot both require and waive disclosure; the
274
+ * waiver wins because it is the more specific statement about the repo's
275
+ * actual ask.
276
+ */
277
+ const DISCLOSURE_WAIVER_RES = [
278
+ /there is no need to disclose/i,
279
+ /no disclosure (is )?required/i,
280
+ /disclosure is not required/i,
281
+ /waives? disclosure/i,
282
+ ];
133
283
  /** Cut a short evidence snippet around the first regex match. */
134
284
  function snippet(text, regex) {
135
285
  const match = regex.exec(text);
@@ -157,7 +307,10 @@ export function parseGatesFromSources(sources) {
157
307
  source: undefined,
158
308
  }));
159
309
  for (const src of ordered) {
160
- const gates = parseGates(src.text);
310
+ // v0.9.3: contradiction resolution runs per file, before merging, so
311
+ // a scoped ban plus welcome/disclosure in the same file dual-classes
312
+ // instead of the ban verdict silently erasing the human path.
313
+ const gates = resolveBanContradictions(parseGates(src.text), src.text);
161
314
  for (const g of gates) {
162
315
  if (!g.detected)
163
316
  continue;
@@ -176,8 +329,14 @@ export function parseGatesFromSources(sources) {
176
329
  * with detected true/false, plus an evidence snippet when detected.
177
330
  */
178
331
  export function parseGates(text, options = {}) {
179
- const body = text ?? "";
180
- return RULES.map((rule) => {
332
+ // v0.9.3: collapse whitespace and strip markdown emphasis before
333
+ // matching. Policy files wrap lines mid-phrase ("autonomous\nagents
334
+ // are not accepted"), and bold markers split keywords ("to
335
+ // **disclose"), both of which a literal pattern would miss. Matching
336
+ // is on the normalized body; evidence snippets were already
337
+ // whitespace-collapsed for display.
338
+ const body = (text ?? "").replace(/\*+/g, "").replace(/\s+/g, " ");
339
+ const gates = RULES.map((rule) => {
181
340
  const found = rule.regexes.find((re) => re.test(body));
182
341
  if (rule.kind === "collaborators_only" && options.collaboratorsOnlyPolicy) {
183
342
  return {
@@ -192,6 +351,12 @@ export function parseGates(text, options = {}) {
192
351
  evidence: found ? snippet(body, found) : "",
193
352
  };
194
353
  });
354
+ const disclosure = gates.find((g) => g.kind === "agents_disclosure");
355
+ if (disclosure && disclosure.detected && DISCLOSURE_WAIVER_RES.some((re) => re.test(body))) {
356
+ disclosure.detected = false;
357
+ disclosure.evidence = "";
358
+ }
359
+ return gates;
195
360
  }
196
361
  /**
197
362
  * gatefile's contribution-gates.json kinds mapped onto Greenlight kinds.
package/dist/gates.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"gates.js","sourceRoot":"","sources":["../src/gates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gates.js","sourceRoot":"","sources":["../src/gates.ts"],"names":[],"mappings":"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"}
package/dist/github.d.ts CHANGED
@@ -85,11 +85,31 @@ export interface MentionedPRDeps {
85
85
  * again in 2026, into docs/development/contributing.mdx behind a pointer
86
86
  * CONTRIBUTING.md, which is why the development-guide paths are here too.
87
87
  */
88
- export declare const HOUSE_RULE_FILES: readonly ["CONTRIBUTING.md", "contributing.md", ".github/CONTRIBUTING.md", "docs/development/contributing.mdx", "docs/development/contributing.md", "AGENTS.md", "CLAUDE.md", ".github/AGENTS.md", ".github/CLAUDE.md"];
88
+ export declare const HOUSE_RULE_FILES: readonly ["CONTRIBUTING.md", ".github/CONTRIBUTING.md", "docs/CONTRIBUTING.md", "contributing.md", "docs/development/contributing.mdx", "docs/development/contributing.md", "AGENTS.md", ".github/AGENTS.md", "docs/AGENTS.md", "CLAUDE.md", ".github/CLAUDE.md", "docs/CLAUDE.md", "AI_POLICY.md", ".github/AI_POLICY.md", "docs/AI_POLICY.md"];
89
89
  export interface HouseRuleDeps {
90
90
  /** Test seam: fetch a repo-root file's raw text, or undefined when absent. */
91
91
  fetchRaw?: (file: string) => Promise<string | undefined>;
92
+ /** Test seam: fetch the org's AI_POLICY.md text, or undefined when absent. */
93
+ fetchOrgPolicy?: (owner: string) => Promise<string | undefined>;
92
94
  }
95
+ /**
96
+ * v0.9.3: org-level AI policy. Binding agent rules sometimes live in the
97
+ * org's `.github` repo rather than the project repo (astral-sh's
98
+ * AI_POLICY.md bans autonomous agents for ruff and uv; mastodon's
99
+ * CONTRIBUTING only links to mastodon/.github's AI_POLICY.md). Probed
100
+ * once per org and cached under its own key so a sweep over N repos from
101
+ * one org costs one fetch, not N.
102
+ */
103
+ export declare function fetchOrgAiPolicy(owner: string, deps?: HouseRuleDeps): Promise<string | undefined>;
104
+ /**
105
+ * v0.9.3: the full policy source set for gate detection: house-rules
106
+ * files (first hit per filename across root, .github/, docs/) plus the
107
+ * org-level AI_POLICY.md when the org publishes one.
108
+ */
109
+ export declare function fetchPolicySources(owner: string, repo: string, deps?: HouseRuleDeps): Promise<{
110
+ file: string;
111
+ text: string;
112
+ }[]>;
93
113
  /** Fetch all existing house-rules files for a repo (best-effort, cached). */
94
114
  export declare function fetchHouseRules(owner: string, repo: string, deps?: HouseRuleDeps): Promise<{
95
115
  file: string;
package/dist/github.js CHANGED
@@ -39,6 +39,11 @@ const TTL_MS = {
39
39
  issue: 6 * 60 * 60 * 1000,
40
40
  search: 60 * 60 * 1000,
41
41
  contributing: 24 * 60 * 60 * 1000,
42
+ // v0.9.3: house-rules and org-ai-policy had no TTL entry, which made
43
+ // `> undefined` false forever: a cached read never expired, so a repo
44
+ // whose policy files were once unreadable stayed "no policy" forever.
45
+ "house-rules": 60 * 60 * 1000,
46
+ "org-ai-policy": 24 * 60 * 60 * 1000,
42
47
  // LLM claim classifications: comment bodies are immutable, so a long TTL
43
48
  // means repeat checks cost nothing after the first classification.
44
49
  llm: 30 * 24 * 60 * 60 * 1000,
@@ -352,15 +357,84 @@ export async function fetchLinkedPRs(owner, repo, number) {
352
357
  */
353
358
  export const HOUSE_RULE_FILES = [
354
359
  "CONTRIBUTING.md",
355
- "contributing.md",
356
360
  ".github/CONTRIBUTING.md",
361
+ "docs/CONTRIBUTING.md",
362
+ "contributing.md",
357
363
  "docs/development/contributing.mdx",
358
364
  "docs/development/contributing.md",
359
365
  "AGENTS.md",
360
- "CLAUDE.md",
361
366
  ".github/AGENTS.md",
367
+ "docs/AGENTS.md",
368
+ "CLAUDE.md",
362
369
  ".github/CLAUDE.md",
370
+ "docs/CLAUDE.md",
371
+ "AI_POLICY.md",
372
+ ".github/AI_POLICY.md",
373
+ "docs/AI_POLICY.md",
363
374
  ];
375
+ /**
376
+ * v0.9.3: org-level AI policy. Binding agent rules sometimes live in the
377
+ * org's `.github` repo rather than the project repo (astral-sh's
378
+ * AI_POLICY.md bans autonomous agents for ruff and uv; mastodon's
379
+ * CONTRIBUTING only links to mastodon/.github's AI_POLICY.md). Probed
380
+ * once per org and cached under its own key so a sweep over N repos from
381
+ * one org costs one fetch, not N.
382
+ */
383
+ export async function fetchOrgAiPolicy(owner, deps = {}) {
384
+ if (!deps.fetchOrgPolicy) {
385
+ const cached = cacheGet("org-ai-policy", [owner.toLowerCase()]);
386
+ if (cached !== undefined)
387
+ return cached || undefined;
388
+ }
389
+ const headers = { "User-Agent": "greenlight-cli" };
390
+ const token = githubToken();
391
+ if (token)
392
+ headers["Authorization"] = `Bearer ${token}`;
393
+ const fetchOrgPolicy = deps.fetchOrgPolicy ??
394
+ ((o) => fetchRawFile(o, ".github", "AI_POLICY.md", headers));
395
+ const text = await fetchOrgPolicy(owner);
396
+ if (!deps.fetchOrgPolicy)
397
+ cacheSet("org-ai-policy", [owner.toLowerCase()], text ?? "");
398
+ return text;
399
+ }
400
+ /**
401
+ * v0.9.3: the full policy source set for gate detection: house-rules
402
+ * files (first hit per filename across root, .github/, docs/) plus the
403
+ * org-level AI_POLICY.md when the org publishes one.
404
+ */
405
+ export async function fetchPolicySources(owner, repo, deps = {}) {
406
+ const rules = await fetchHouseRules(owner, repo, deps);
407
+ const orgPolicy = await fetchOrgAiPolicy(owner, deps);
408
+ if (orgPolicy)
409
+ rules.push({ file: `AI_POLICY.md (org ${owner})`, text: orgPolicy });
410
+ return rules;
411
+ }
412
+ /**
413
+ * v0.9.3: fetch one policy file's raw text, honoring the API base
414
+ * override. In proxy mode (GREENLIGHT_GITHUB_BASE_URL set) the raw host
415
+ * is unreachable with the surrogate credential, so policy files are read
416
+ * through the contents API instead; otherwise the raw host is used as
417
+ * before. Returns undefined when the file does not exist.
418
+ */
419
+ async function fetchRawFile(owner, repo, file, headers) {
420
+ if (githubApiBase() !== DEFAULT_API) {
421
+ try {
422
+ const data = (await apiGet(`/repos/${owner}/${repo}/contents/${file}`));
423
+ if (typeof data.content === "string" && data.encoding === "base64") {
424
+ return Buffer.from(data.content, "base64").toString("utf8");
425
+ }
426
+ }
427
+ catch { /* absent */ }
428
+ return undefined;
429
+ }
430
+ try {
431
+ const res = await fetch(`${RAW}/${owner}/${repo}/HEAD/${file}`, { headers });
432
+ if (res.ok)
433
+ return await res.text();
434
+ }
435
+ catch { /* try next */ }
436
+ return undefined;
437
+ }
364
438
  /** Fetch all existing house-rules files for a repo (best-effort, cached). */
365
439
  export async function fetchHouseRules(owner, repo, deps = {}) {
366
440
  if (!deps.fetchRaw) {
@@ -373,20 +447,23 @@ export async function fetchHouseRules(owner, repo, deps = {}) {
373
447
  if (token)
374
448
  headers["Authorization"] = `Bearer ${token}`;
375
449
  const fetchRaw = deps.fetchRaw ??
376
- (async (file) => {
377
- try {
378
- const res = await fetch(`${RAW}/${owner}/${repo}/HEAD/${file}`, { headers });
379
- if (res.ok)
380
- return await res.text();
381
- }
382
- catch { /* try next */ }
383
- return undefined;
384
- });
450
+ ((file) => fetchRawFile(owner, repo, file, headers));
451
+ // v0.9.3: stop at the first hit per filename (root, then .github/, then
452
+ // docs/), so a repo with CONTRIBUTING.md at the root does not pay for
453
+ // two more 404s, and a repo with it only in docs/ is still found (the
454
+ // AFFiNE shape the 5k scan caught: root-only probing called it
455
+ // "no policy" while docs/CONTRIBUTING.md existed).
456
+ const seenBasenames = new Set();
385
457
  const out = [];
386
458
  for (const file of HOUSE_RULE_FILES) {
459
+ const base = file.split("/").pop().toLowerCase();
460
+ if (seenBasenames.has(base))
461
+ continue;
387
462
  const text = await fetchRaw(file);
388
- if (text)
463
+ if (text) {
389
464
  out.push({ file, text });
465
+ seenBasenames.add(base);
466
+ }
390
467
  }
391
468
  if (!deps.fetchRaw)
392
469
  cacheSet("house-rules", [owner, repo], out);
@@ -799,7 +876,10 @@ export async function buildIssueSnapshot(owner, repo, number) {
799
876
  const [comments, linkedPRs, houseRules, workflowGates] = await Promise.all([
800
877
  fetchComments(owner, repo, number),
801
878
  fetchLinkedPRs(owner, repo, number),
802
- fetchHouseRules(owner, repo),
879
+ // v0.9.3: the full policy source set, including the org-level
880
+ // AI_POLICY.md, so the verdict engine sees the same bans the
881
+ // Agent Policy Index field work found.
882
+ fetchPolicySources(owner, repo),
803
883
  scanWorkflowGates(owner, repo),
804
884
  ]);
805
885
  // Comment-mentioned PRs: references like "#861" in comments, cross-checked