Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
a53d670
fix(test_verification): fallback to checks for latest build status
srbouffard Jul 23, 2026
7c4df79
fix(documentation): support accepted docs structure and workflow vari…
srbouffard Jul 24, 2026
28a1dc7
fix(substrate_compat): parse broader juju/substrate workflow patterns
srbouffard Jul 24, 2026
eb88309
fix(substrate_compat): tighten juju channel and k8s alias detection
srbouffard Jul 24, 2026
8f97f2a
fix(substrate_compat): remove script-text and note-text false positives
srbouffard Jul 24, 2026
2dfa489
fix(substrate_compat): parse matrix.include, inline comments, and blo…
srbouffard Jul 24, 2026
08fe24d
fix(substrate_compat): handle folded scalars and quoted heredoc text
srbouffard Jul 24, 2026
9eb9f4c
fix(substrate_compat): unquote run: scalar values
srbouffard Jul 24, 2026
6bbae3f
fix(substrate_compat): handle hyphenated heredoc delimiters and comme…
srbouffard Jul 24, 2026
bc97797
fix(support_engagement): separate insufficient sample from measured zero
srbouffard Jul 24, 2026
de68af2
fix(security_ssdlc): use deterministic repo-automation registration s…
srbouffard Jul 24, 2026
9fc0b3b
fix(security_ssdlc): tighten registration detection to owner-scoped t…
srbouffard Jul 24, 2026
49cde27
feat(engine): apply measurability-aware applicability for scoring
srbouffard Jul 24, 2026
bf267d9
feat(metrics): calibrate gates and publish post-fix distribution audit
srbouffard Jul 24, 2026
9c264cc
test(engine): validate required metrics are declared outputs
srbouffard Jul 24, 2026
2589105
fix(substrate_compat): skip run: mapping blocks to prevent crash on d…
srbouffard Jul 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions config/dimensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ dimensions:
applies_to:
product_types: ["charm", "snap"]
aggregation: "worst_in_scope"
required_metrics_for_scoring:
- latest_build_passing
outputs:
coverage_pct: {type: number, range: "0–100", label: "Coverage", description: "Percentage of automated test checks passing in the latest Allure summary."}
stability_pct: {type: number, range: "0–100", label: "Stability", description: "Percentage of non-broken, non-failed checks in the latest Allure summary."}
Expand All @@ -29,6 +31,10 @@ dimensions:
applies_to:
product_types: ["charm", "snap"]
aggregation: "worst_in_scope"
required_metrics_for_scoring:
- readme_meets_structure
- contributing_meets_structure
- has_security
outputs:
readme_meets_structure: {type: boolean, label: "README meets structure", description: "README differs from the single-charm template and contains required sections. Uses canonical/platform-engineering-charm-template and canonical/backup-operators to distinguish repo types."}
contributing_meets_structure: {type: boolean, label: "CONTRIBUTING meets structure", description: "CONTRIBUTING differs from template and contains required contribution and governance sections."}
Expand All @@ -49,6 +55,9 @@ dimensions:
applies_to:
product_types: ["charm"]
aggregation: "worst_in_scope"
required_metrics_for_scoring:
- supports_juju_3
- substrate_test_evidence_present
outputs:
supports_juju_3: {type: boolean, label: "Juju 3 support", description: "Workflow or metadata evidence declares Juju 3 support."}
supports_juju_4: {type: boolean, label: "Juju 4 support", description: "Workflow or metadata evidence declares Juju 4 support."}
Expand All @@ -65,6 +74,9 @@ dimensions:
applies_to:
product_types: ["charm", "snap"]
aggregation: "worst_in_scope"
required_metrics_for_scoring:
- branch_protection_required_checks
- renovate_enabled
outputs:
renovate_enabled: {type: boolean, label: "Renovate enabled", description: "Repository is configured for Renovate updates."}
canonical_repo_automation_registered: {type: boolean, label: "Canonical repo automation registered", description: "Repository is onboarded in canonical-repo-automation."}
Expand All @@ -82,6 +94,10 @@ dimensions:
applies_to:
product_types: ["root", "charm", "snap"]
aggregation: "worst_in_scope"
required_metrics_for_scoring:
- avg_triage_days
- avg_pr_review_days
- response_coverage_rate
outputs:
avg_triage_days: {type: number, range: "≥ 0 days", label: "Avg. triage time", description: "Average days from issue creation to first non-author response."}
avg_pr_review_days: {type: number, range: "≥ 0 days", label: "Avg. PR review time", description: "Average days from PR opening to first submitted review."}
Expand Down
8 changes: 8 additions & 0 deletions config/schemas/dimensions.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@
"type": "string",
"enum": ["worst_in_scope"],
"description": "How leaf results are aggregated into the root product medal. worst_in_scope: minimum medal among in-scope leaves."
},
"required_metrics_for_scoring": {
"type": "array",
"description": "Metric keys that must be present and non-null before this dimension is scoreable. If any are missing, the dimension becomes insufficient_data instead of falling back to bronze/unrated semantics.",
"items": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]*$"
}
}
}
},
Expand Down
28 changes: 28 additions & 0 deletions docs/local-scoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,34 @@ are evaluated by `assemble.py`, so `make _assemble` alone picks them up from the

---

## Measurability gates (`required_metrics_for_scoring`)

Each dimension may declare `required_metrics_for_scoring` in `config/dimensions.yaml`.
This is a list of metric keys that must be present and non-null before PQF will score that
dimension.

- If every required metric is present, the normal medal rubric runs.
- If any required metric is missing or `null`, the dimension becomes
`insufficient_data` and its medal is forced to `unrated`.
- Use this for **measurability** checks only — for example, a missing latest test result or
a support sample that was too small to calculate averages.
- Do **not** use it for normal failing values. A measured `false`, `0`, or low percentage
should still be scored by the rubric.

Current examples:

- `test_verification` requires `latest_build_passing`
- `documentation` requires the core documentation presence/structure booleans
- `substrate_compat` requires a declared Juju support signal plus substrate CI evidence
- `security_ssdlc` requires branch protection and dependency-update measurability
- `support_engagement` requires the sampled response metrics that can otherwise be `null`

This means a rubric-only change still needs a full recompute when scorer outputs or nullability
semantics change, because regenerated `computed/*.json` data may now shift products from
`scored` to `insufficient_data`.

---

## Documentation scoring without LLM

`score-no-llm` and `score` currently produce the same documentation outputs. The
Expand Down
Loading
Loading