rubric
strands_teams.rubric ¶
Single scoring rubric shared by the narrative-scoring tool and quality hook.
NarrativeRubric is the one place the scoring dimensions, their threshold tables, and the revision threshold (default 3.5) live. Both the score_narrative-equivalent coordinator tool (AC-2-6) and the quality hook (AC-3-3) call :meth:NarrativeRubric.score, deduping the two pre-split formulas that drifted apart (the pre-split team-tools module used discrete threshold tables; hooks.py:509-539 used continuous min(5, count/divisor) divisors). This module keeps the threshold-table intent as the single canonical scoring; the continuous variant is subsumed (same dimensions, same 3.5 threshold) per explore.yaml hidden coupling #5.
Dimensions are data-driven: each :class:RubricDimension names a measure (a regex pattern or a counter callable), an ascending (min_count, score) threshold table, and a suggestion template. The domain regexes (file:line, mermaid, file-path) ship here as importable defaults so a use case just references :data:DEFAULT_NARRATIVE_RUBRIC rather than hardcoding them — but a use case may build its own NarrativeRubric with different dimensions.
FILE_LINE_PATTERN module-attribute ¶
Matches file.ext:123 style file:line references (specificity).
HEADING_PATTERN module-attribute ¶
Matches level-⅔ markdown headings (structure). Needs re.MULTILINE.
MERMAID_PATTERN module-attribute ¶
Matches a mermaid code fence (diagrams). Case-insensitive.
FILE_PATH_PATTERN module-attribute ¶
Matches slash-separated file paths (cross-references). Counted as unique.
DEFAULT_REVISION_THRESHOLD module-attribute ¶
Average below which an artifact needs a revision/enrichment pass.
DEFAULT_NARRATIVE_RUBRIC module-attribute ¶
DEFAULT_NARRATIVE_RUBRIC = NarrativeRubric(
dimensions=(
RubricDimension(
name="specificity",
pattern=FILE_LINE_PATTERN,
thresholds=(
(0, 1.0),
(5, 2.0),
(10, 3.0),
(20, 4.0),
(30, 5.0),
),
suggestion="Add more file:line references (currently {count}).",
),
RubricDimension(
name="structure",
pattern=HEADING_PATTERN,
flags=re.MULTILINE,
thresholds=(
(0, 1.0),
(3, 2.0),
(5, 3.0),
(8, 4.0),
(11, 5.0),
),
suggestion="Add more section headings for structure (currently {count}).",
),
RubricDimension(
name="diagrams",
pattern=MERMAID_PATTERN,
flags=re.IGNORECASE,
thresholds=((0, 1.0), (1, 3.0), (2, 5.0)),
suggestion="Add at least one mermaid diagram for call flow or architecture.",
weak_score=1.0,
),
RubricDimension(
name="depth",
counter=count_lines,
thresholds=(
(0, 1.0),
(20, 2.0),
(50, 3.0),
(100, 4.0),
(200, 5.0),
),
suggestion="Expand content depth (currently {count} lines).",
),
RubricDimension(
name="cross_references",
pattern=FILE_PATH_PATTERN,
unique=True,
thresholds=(
(0, 1.0),
(3, 2.0),
(8, 3.0),
(15, 4.0),
(25, 5.0),
),
suggestion="Cross-reference more files/modules (currently {count} unique paths).",
),
)
)
The default five-dimension narrative rubric (revision threshold 3.5).
RubricDimension dataclass ¶
RubricDimension(
name,
thresholds,
suggestion,
pattern=None,
flags=0,
unique=False,
counter=None,
weak_score=2.0,
)
One scored dimension of a narrative artifact.
A dimension measures a count from the text (via a regex pattern or a counter callable), then maps that count to a 0-5 score using an ascending (min_count, score) threshold table: the score is the highest table entry whose min_count does not exceed the measured count.
Attributes:
| Name | Type | Description |
|---|---|---|
name | str | Dimension key (e.g., |
thresholds | tuple[tuple[int, float], ...] | Ascending |
suggestion | str | Improvement hint; may contain a |
pattern | str | None | Regex whose match count is the measure. Ignored if |
flags | int | Regex flags applied to |
unique | bool | If True, count distinct matches rather than all matches. |
counter | Callable[[str], int] | None | Callable measuring the count directly (overrides |
weak_score | float | Emit |
measure ¶
Return the raw count this dimension measures from text.
Source code in packages/strands-teams/src/strands_teams/rubric.py
score_count ¶
Map a measured count to its 0-5 score via the threshold table.
Source code in packages/strands-teams/src/strands_teams/rubric.py
ScoreReport dataclass ¶
Result of scoring a text against a :class:NarrativeRubric.
NarrativeRubric dataclass ¶
The single rubric object: dimensions + revision threshold.
Attributes:
| Name | Type | Description |
|---|---|---|
dimensions | tuple[RubricDimension, ...] | Ordered scoring dimensions. |
revision_threshold | float | Average (and per-artifact) score below which the artifact needs a revision pass (default |
score ¶
Score text across every dimension.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text | str | The narrative artifact content to score. | required |
Returns:
| Name | Type | Description |
|---|---|---|
A | ScoreReport | class: |
ScoreReport | average, the | |
ScoreReport | threshold), and improvement suggestions for weak dimensions. |