delivery-friction-analyzer 0.10.0 → 0.12.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.
@@ -1,6 +1,6 @@
1
1
  # Friction Report Contract
2
2
 
3
- Milestone 3 introduced `friction-report.v1`, a deterministic report generated from a `friction-metrics.v1` repository metrics summary. Milestones 4 and 5 add Markdown and methodology profile suggestions without adding report JSON fields. The report layer does not fetch GitHub data, mutate repositories, rank individuals, or depend on services beyond the data collection path that produced the metrics summary.
3
+ Milestone 3 introduced `friction-report.v1`, a deterministic report generated from a `friction-metrics.v1` repository metrics summary. Milestone 4 added configured workflow context. Milestone 5 adds sanitized contributor-source metadata for configured `.all-contributorsrc` coverage without raw contributor file contents or individual rankings. The report layer does not fetch GitHub data, mutate repositories, rank individuals, or depend on services beyond the data collection path that produced the metrics summary.
4
4
 
5
5
  ## Outputs
6
6
 
@@ -28,6 +28,7 @@ The command reads local `friction-metrics.v1` JSON and writes deterministic `fri
28
28
  - `targetRepository`: analyzed repository identity; live analysis sample size is encoded as `targetRepository.analysisPullRequestLimit` from collection metadata.
29
29
  - `analysisFilter`: optional metadata for explicit filters applied before metrics computation, including excluded PR classes and before/after PR counts.
30
30
  - `configuredWorkflow`: optional user-configured workflow context from the repository profile. It is not observed GitHub evidence and does not change scoring, ranking, CSV exports, or PR class matching.
31
+ - `contributorSource`: optional sanitized contributor-source metadata from the repository profile and collection path. It records source type, path, coverage status, parsed hint count, and guardrail note. It does not include raw contributor file contents or contributor rankings.
31
32
  - `summary`: repository totals and top bottleneck identifiers.
32
33
  - `coverage`: PR-open diff, workflow-run, and review-thread coverage counts plus caveats.
33
34
  - `commentSources`: total and source-grouped review comments for Copilot, human, bot, scanner, author replies, and unknown sources.
@@ -57,6 +58,7 @@ The Markdown renderer presents the same report data for human review:
57
58
  - a compact recommendation-category snapshot before detailed bottlenecks, with the full category reference retained later in the report;
58
59
  - a short "How To Read This Report" guide that distinguishes observed evidence, interpretation, recommendations, and caveats;
59
60
  - a configured workflow context section only when repository profile workflow fields are present, labeled as user-configured profile context rather than observed GitHub evidence;
61
+ - a contributor source context section only when a contributor source is configured, labeled as metadata that may improve comment-source classification coverage without changing scores, authorship conclusions, reviewer attribution, CSV export shape, person-level CSV output, or individual ranking guardrails;
60
62
  - workflow data caveats when configured workflow context clarifies unavailable PR-open diff or workflow-run evidence;
61
63
  - evidence-quality and coverage tables before detailed recommendations;
62
64
  - key findings that highlight top bottlenecks, strongest displayed signal, outlier caveats, PR class caveats, and coverage caveats;
@@ -75,7 +77,7 @@ The Markdown renderer presents the same report data for human review:
75
77
  - a reference to the detailed `methodology.md` artifact generated by full live analysis;
76
78
  - guardrails, follow-up, and artifact-sensitivity guidance.
77
79
 
78
- Markdown output should not include individual contributor or reviewer rankings.
80
+ Markdown output should not include raw contributor file contents or individual contributor/reviewer rankings.
79
81
  Status labels are Markdown presentation helpers, not `friction-report.v1` fields. They should preserve the underlying source labels and counts rather than replacing auditable evidence.
80
82
  Profile suggestions are also presentation helpers, not `friction-report.v1` fields. They are derived from existing PR class and file-surface evidence, appear at most once per suggestion category, and do not change scores, rankings, CSV exports, filtering, or PR class matching. Because the report JSON does not carry repository-profile rule inventory, all analyzed PRs using fallback `unknown` PR class evidence is the renderer's small-sample proxy for no configured PR class rule producing usable classification evidence.
81
83
 
@@ -114,6 +116,7 @@ Full live analysis writes `methodology.md` as a hybrid artifact: stable explanat
114
116
  - target repository and report/metric versions;
115
117
  - profile path when available;
116
118
  - configured workflow context when supplied by the repository profile, labeled as user-configured context rather than observed GitHub evidence;
119
+ - contributor-source context when configured, including source type, path, coverage status, and parsed hint count, without raw contributor contents or rankings;
117
120
  - profile suggestions when PR class, file/path, or workflow-context profile evidence crosses deterministic fallback thresholds, or an explicit no-threshold note when none were triggered;
118
121
  - requested and collected PR counts;
119
122
  - collection coverage status and API-family diagnostics;
@@ -139,6 +142,8 @@ Minimum CSV column groups:
139
142
 
140
143
  Empty CSV cells mean unavailable or not applicable. Numeric zero should be used only for observed or computed zero counts. Count columns that depend on optional GitHub coverage should keep source or coverage labels nearby so spreadsheet readers can tell unavailable evidence apart from observed zeroes. CSVs must not include raw comment bodies, raw workflow logs, tokens, secret-bearing environment details, or individual contributor/reviewer rankings.
141
144
 
145
+ Contributor-source coverage appears in `collection-coverage.csv` as the `contributor_source` API family when configured. CSVs may include aggregate comment-source counts influenced by contributor hints, but they must not include raw `.all-contributorsrc` contents, contributor names, contributor login lists, or person rankings.
146
+
142
147
  ## Optional Downstream Narrative Drafting
143
148
 
144
149
  The existing `friction-report.json` artifact plus the curated CSV exports are sufficient context for an optional local workflow where a separate model drafts a narrative summary. M2 does not justify a new `report-context.json`, CLI flag, fixture output, or artifact write path.
@@ -9,6 +9,7 @@ Milestone 1 defines the first normalized fixture shape. It is intentionally limi
9
9
  - `TargetRepository`: owner/name/default branch/visibility/window for the repository being analyzed.
10
10
  - `AnalysisFilter`: optional metadata for downstream analysis filters applied after collection and normalization. When present, it records excluded PR classes, the original collected PR count, and the filtered PR count.
11
11
  - `RepositoryLanguageDistribution`: byte counts from `GET /repos/{owner}/{repo}/languages`, stored as context only.
12
+ - `ContributorSource`: optional sanitized metadata from a configured structured contributor source. It records source type, path, coverage status, diagnostics, and parsed hint count. It must not preserve raw contributor file contents or contributor login lists.
12
13
  - `PullRequest`: source IDs, author login when known, URL, state, PR class evidence, lifecycle timestamps, final diff shape, PR-open diff source confidence, optional PR-open additions/deletions/changed-file counts when direct or reconstructed data is available, files, reviews, review decision summary, review threads, comments, checks, and workflow-run coverage.
13
14
  - `PrClassSummary`: profile-driven PR class, classification source, and winning rule ID. Unmatched PRs use `class: "unknown"`, `classificationSource: "fallback_rule"`, and `ruleId: null`.
14
15
  - `Commit`: commit OID, authored timestamp, committed timestamp when present, and message headline.
@@ -24,6 +25,8 @@ Milestone 1 defines the first normalized fixture shape. It is intentionally limi
24
25
 
25
26
  Normalized data must preserve whether a value came from a public API, GraphQL thread query, repository profile rule, fallback rule, internal UI partial, or unavailable coverage. Later metric and report stages should use those source labels before making confidence claims.
26
27
 
28
+ Configured contributor hints may classify otherwise-unknown comment authors into existing comment-source groups during the analysis run, but parsed login lists are transient and must not be persisted in generated artifacts. Hints must not change PR authorship, reviewer attribution, scoring formulas, or person-level report/CSV rows.
29
+
27
30
  ## Analysis Filters
28
31
 
29
32
  `source-bundle.json` remains the full collected sample. When a local analysis excludes one or more PR classes, `normalized.json` contains the filtered PR set and an `analysisFilter` object:
@@ -6,6 +6,7 @@ The MVP runs locally with the user's GitHub credentials. Reports must expose una
6
6
  | --- | --- | --- | --- | --- | --- |
7
7
  | REST repository metadata | unauthenticated or token | public read | `repo` or fine-grained metadata read | repository visibility, default branch confirmation | mark repository metadata partial |
8
8
  | REST languages | unauthenticated or token | public read | `repo` or fine-grained contents/metadata read | language byte distribution context | omit language context; do not infer file role from language |
9
+ | REST repository contents for configured contributor source | token recommended | public contents read | `repo` or fine-grained contents read | optional `.all-contributorsrc` contributor hints for comment-source classification metadata | mark contributor-source coverage unavailable, malformed, partial, or unsupported; do not infer identities from other sources |
9
10
  | Pull request metadata | `gh` token / GraphQL-backed PR fields | public read | `repo` or pull request read | lifecycle, final diff shape, files, commits, reviews | mark PR inventory partial |
10
11
  | REST review comments | token recommended | public read | `repo` or pull request read | individual review comments and comment paths | source breakdown based only on reviews if unavailable |
11
12
  | GraphQL review threads | token | public read | `repo` or pull request read | thread count, resolved state, outdated state | thread metrics unavailable; comment count can remain REST-only |
@@ -18,8 +19,10 @@ The MVP runs locally with the user's GitHub credentials. Reports must expose una
18
19
  The analyzer should record:
19
20
 
20
21
  - API family attempted.
21
- - Coverage status: `available`, `partial`, `unavailable`, or `rate_limited`.
22
+ - Coverage status: `available`, `partial`, `unavailable`, `malformed`, `unsupported`, or `rate_limited`.
22
23
  - Required scope or permission when known.
23
24
  - Impact on downstream metrics.
24
25
 
25
26
  Missing coverage must flow into report metadata. For example, unavailable GraphQL review threads should disable thread-resolution metrics while preserving REST review-comment counts.
27
+
28
+ Contributor-source coverage is optional. Missing, inaccessible, malformed, or unsupported contributor files should not fail analysis and should not cause the analyzer to infer private identity data from names, emails, commits, or external services.
@@ -4,6 +4,8 @@ Repository profiles map paths to file categories, file roles, and functional sur
4
4
 
5
5
  Schema: `schemas/repository-profile.schema.json`.
6
6
 
7
+ Repository profiles own repository semantics. Keep file rules, PR class rules, workflow context, branch or release strategy, and contributor-source declarations here. Optional [run presets](run-presets.md) only store reusable run settings such as the target repository, profile path, sample size, output directory, dry-run mode, CSV preference, JSON completion preference, validation-target mode, and requested PR class exclusions. Explicit CLI flags override preset values.
8
+
7
9
  ## Categories
8
10
 
9
11
  - `code`
@@ -160,3 +162,27 @@ Example:
160
162
  Use stable identifiers exactly as shown above. Display labels such as "squash merges" or "release PRs" belong in CLI prompts or documentation, not in profile data.
161
163
 
162
164
  When interactive setup writes profile changes, it preserves deterministic two-space JSON formatting in place. If an existing profile uses other formatting, setup writes a generated profile copy and prints that generated path in completion output instead of rewriting the original file.
165
+
166
+ ## Contributor Source
167
+
168
+ `contributors` is optional user-configured context for structured contributor hints. The first supported source is `.all-contributorsrc` as `all_contributors` JSON. When omitted, analysis runs normally without contributor hints.
169
+
170
+ Supported fields:
171
+
172
+ - `sourceType`: optional, defaults to `all_contributors` when `contributors` is present.
173
+ - `path`: optional trimmed, slash-delimited repository-relative path, defaults to `.all-contributorsrc`.
174
+
175
+ Example:
176
+
177
+ ```json
178
+ {
179
+ "contributors": {
180
+ "sourceType": "all_contributors",
181
+ "path": ".all-contributorsrc"
182
+ }
183
+ }
184
+ ```
185
+
186
+ Markdown contributor files such as `CONTRIBUTORS.md` are not supported contributor sources in this milestone. The analyzer records them as unsupported/unparsed coverage when encountered and does not parse Markdown into identities.
187
+
188
+ Contributor hints may improve repository-level comment-source classification coverage, such as classifying a configured contributor login as an existing human-reviewer source. They do not change scoring formulas, PR authorship conclusions, reviewer attribution, PR class matching, CSV export shape, or individual rankings. Generated artifacts expose only contributor-source metadata such as type, path, status, diagnostics, and parsed hint count; they do not include raw contributor file contents, contributor login lists, or contributor rankings.
@@ -0,0 +1,91 @@
1
+ # Run Presets
2
+
3
+ Run presets are optional local JSON files for reusing CLI run settings. They are intended for rerunning the same analysis without re-answering interactive prompts.
4
+
5
+ Repository meaning stays in repository profiles. Put file rules, PR class rules, workflow context, branch or release strategy, and contributor-source declarations in a repository profile. A run preset may only point at a profile and store run inputs or preferences such as the target repository, sample size, output directory, dry-run mode, CSV preference, JSON completion preference, validation-target mode, and requested PR class exclusions.
6
+
7
+ ## Save A Preset
8
+
9
+ Interactive setup asks whether to save a local run preset near the end of the prompt flow. If you answer yes, you choose the preset path explicitly. The CLI does not invent a global or cloud-synced preset location.
10
+
11
+ Saving a preset may overwrite an existing regular file at that path, but the path must not be a directory, symbolic link, or other special file.
12
+
13
+ You can also save a preset from flags:
14
+
15
+ ```sh
16
+ npm run analyze:github -- \
17
+ --repo example/example-repo \
18
+ --limit 30 \
19
+ --profile profiles/example-repo.json \
20
+ --out reports/example-repo \
21
+ --save-preset .delivery-friction-analyzer/example-repo.run-preset.json
22
+ ```
23
+
24
+ When a preset is written, the completion output includes:
25
+
26
+ ```text
27
+ Run preset saved: .delivery-friction-analyzer/example-repo.run-preset.json.
28
+ ```
29
+
30
+ With `--json`, the same path is emitted as `savedRunPresetPath` in the machine-readable completion receipt.
31
+
32
+ ## Rerun From A Preset
33
+
34
+ Use `--preset <path>` to load saved settings without prompts:
35
+
36
+ ```sh
37
+ npm run analyze:github -- --preset .delivery-friction-analyzer/example-repo.run-preset.json
38
+ ```
39
+
40
+ Explicit CLI flags override preset values. This makes one-off reruns predictable:
41
+
42
+ ```sh
43
+ npm run analyze:github -- \
44
+ --preset .delivery-friction-analyzer/example-repo.run-preset.json \
45
+ --limit 10 \
46
+ --no-csv
47
+ ```
48
+
49
+ In that command, the preset still supplies values such as `--repo`, `--profile`, and `--out`, while `--limit 10` and `--no-csv` win over the saved sample size and CSV preference.
50
+
51
+ Boolean preset values can be overridden in either direction:
52
+
53
+ - `--dry-run` or `--no-dry-run`
54
+ - `--validation-target` or `--no-validation-target`
55
+ - `--csv` or `--no-csv`
56
+ - `--json` or `--no-json`
57
+
58
+ If both forms are provided in one command, the later flag wins. For example, `--preset local.json --dry-run --no-dry-run` runs a full analysis, while `--preset local.json --no-csv --csv` writes CSV evidence files.
59
+
60
+ ## Format
61
+
62
+ Preset files use `analyze-github-run-preset.v1`:
63
+
64
+ ```json
65
+ {
66
+ "schemaVersion": "analyze-github-run-preset.v1",
67
+ "run": {
68
+ "repository": "example/example-repo",
69
+ "limit": 30,
70
+ "profilePath": "profiles/example-repo.json",
71
+ "outDir": "reports/example-repo",
72
+ "dryRun": false,
73
+ "isValidationTarget": false,
74
+ "csv": true,
75
+ "json": false,
76
+ "excludedPrClasses": []
77
+ }
78
+ }
79
+ ```
80
+
81
+ The CLI only reads and writes the allowlisted `run` keys shown above. Presets must not contain GitHub tokens, secrets, raw source bundles, normalized data, metrics, reports, methodology text, CSV contents, contributor file contents, or repository profile rules.
82
+
83
+ ## Cleanup
84
+
85
+ Preset files are local user-owned files. Delete a preset when it no longer matches how you want to run the analyzer:
86
+
87
+ ```sh
88
+ rm .delivery-friction-analyzer/example-repo.run-preset.json
89
+ ```
90
+
91
+ Deleting a preset does not delete generated reports or repository profiles. If a preset points at a generated profile, review and clean up that profile separately.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "delivery-friction-analyzer",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Local GitHub pull request analytics for delivery friction reports.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/release-log.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ### 2026-06-20 — Reusable Run Presets
6
+
7
+ - What changed: GitHub analysis can now load local run settings from `--preset` and save reusable settings with `--save-preset` or the interactive setup flow, with explicit CLI flags taking precedence.
8
+ - Why it matters: Maintainers can rerun an interactive setup non-interactively without moving repository semantics out of repository profiles.
9
+ - Who is affected: Maintainers using `--interactive` or repeated local analysis commands.
10
+ - Action needed: Optional; save a local preset for repeated runs and delete stale preset files when they no longer match the desired analysis settings.
11
+ - PR: #48
12
+
13
+ ### 2026-06-20 — Contributor Source Configuration
14
+
15
+ - What changed: Repository profiles can now configure `.all-contributorsrc` as a structured contributor source, and analysis records contributor-source coverage while using sanitized hints only for aggregate comment-source classification.
16
+ - Why it matters: Maintainers can improve comment-source coverage without parsing Markdown contributor files, changing scores, or emitting raw contributor contents or person rankings in reports or CSVs.
17
+ - Who is affected: Maintainers authoring repository profiles or reviewing generated reports, methodology, and coverage artifacts.
18
+ - Action needed: Optional; add `contributors.sourceType: "all_contributors"` and a repository-relative `contributors.path` when a target repository has a trusted `.all-contributorsrc`.
19
+ - PR: #47
20
+
5
21
  ### 2026-06-20 — Workflow Data Caveats
6
22
 
7
23
  - What changed: Markdown friction reports and methodology now explain PR-open diff and workflow-run coverage limits with configured workflow context when it is available, and suggest adding workflow context when omitted context would clarify unavailable evidence.
@@ -36,6 +36,32 @@
36
36
  }
37
37
  }
38
38
  },
39
+ "contributorSource": {
40
+ "type": "object",
41
+ "additionalProperties": false,
42
+ "required": ["sourceType", "path", "coverage", "hintCount"],
43
+ "properties": {
44
+ "sourceType": { "enum": ["all_contributors"] },
45
+ "path": { "type": "string" },
46
+ "coverage": {
47
+ "type": "object",
48
+ "additionalProperties": false,
49
+ "required": ["family", "source", "status", "attempts", "diagnostics", "downstreamImpact"],
50
+ "properties": {
51
+ "family": { "const": "contributor_source" },
52
+ "source": { "type": "string" },
53
+ "status": { "enum": ["available", "partial", "unavailable", "malformed", "unsupported", "rate_limited"] },
54
+ "attempts": { "type": "integer", "minimum": 1 },
55
+ "diagnostics": {
56
+ "type": "array",
57
+ "items": { "type": "string" }
58
+ },
59
+ "downstreamImpact": { "type": ["string", "null"] }
60
+ }
61
+ },
62
+ "hintCount": { "type": "integer", "minimum": 0 }
63
+ }
64
+ },
39
65
  "pullRequests": {
40
66
  "type": "array",
41
67
  "items": {
@@ -103,6 +103,29 @@
103
103
  }
104
104
  },
105
105
  "minProperties": 1
106
+ },
107
+ "contributors": {
108
+ "type": "object",
109
+ "additionalProperties": false,
110
+ "properties": {
111
+ "sourceType": {
112
+ "enum": ["all_contributors"]
113
+ },
114
+ "path": {
115
+ "type": "string",
116
+ "minLength": 1,
117
+ "pattern": "\\S",
118
+ "not": {
119
+ "anyOf": [
120
+ { "pattern": "^/" },
121
+ { "pattern": "^\\s|\\s$" },
122
+ { "pattern": "\\\\" },
123
+ { "pattern": "(^|/)\\.\\.(/|$)" }
124
+ ]
125
+ }
126
+ }
127
+ },
128
+ "minProperties": 1
106
129
  }
107
130
  }
108
131
  }