mirror of
https://github.com/chrisbanes/skills.git
synced 2026-09-19 08:37:48 +08:00
Add Android benchmark comparison skill (#69)
This commit is contained in:
@@ -68,12 +68,17 @@ for its lane-specific fallback and blocking behavior.
|
||||
|
||||
- Working on Compose state or effects? Start with [`compose-state-and-effects`](skills/compose-state-and-effects/SKILL.md).
|
||||
- Investigating recomposition, stability, or jank? Start with [`compose-performance`](skills/compose-performance/SKILL.md).
|
||||
- Comparing Android benchmark configurations or a measured Android default? Start with [`android-benchmark-comparison`](skills/android-benchmark-comparison/SKILL.md).
|
||||
- Reviewing Flow or coroutine architecture? Start with [`kotlin-concurrency-and-flow`](skills/kotlin-concurrency-and-flow/SKILL.md).
|
||||
|
||||
### Routing
|
||||
|
||||
- [`using-chrisbanes-skills`](skills/using-chrisbanes-skills/SKILL.md) — route Kotlin and Jetpack Compose work to the focused skills.
|
||||
|
||||
### Benchmarking
|
||||
|
||||
- [`android-benchmark-comparison`](skills/android-benchmark-comparison/SKILL.md) — compare physical Android benchmark configurations with verified coverage, controlled conditions, trace-backed diagnosis of unstable rankings, and bounded conclusions.
|
||||
|
||||
### Jetpack Compose
|
||||
|
||||
#### State and side effects
|
||||
@@ -197,6 +202,7 @@ for Astra and 5.6 coverage and its current evidence limits.
|
||||
| [`kotlin-api-design`](skills/kotlin-api-design/SKILL.md) | 66.7% | 100.0% | 100.0% |
|
||||
| [`kotlin-concurrency-and-flow`](skills/kotlin-concurrency-and-flow/SKILL.md) | 33.3% | 100.0% | 100.0% |
|
||||
| [`kotlin-control-flow`](skills/kotlin-control-flow/SKILL.md) | 27.8% | 100.0% | 100.0% |
|
||||
| [`android-benchmark-comparison`](skills/android-benchmark-comparison/SKILL.md) | — | — | — |
|
||||
| [`grounded-writing`](skills/grounded-writing/SKILL.md) | — | 100.0% | 100.0% |
|
||||
| [`implement-with-subagents`](skills/implement-with-subagents/SKILL.md) | — | — | 100.0% |
|
||||
| [`release-kotlin-library`](skills/release-kotlin-library/SKILL.md) | — | — | — |
|
||||
@@ -227,6 +233,7 @@ The source runs, selection rules, and detailed scorecards are in the
|
||||
| [`kotlin-api-design`](skills/kotlin-api-design/SKILL.md) | 57.4k → 145.8k (+154%) | 3 → 7 (+133%) | 1 → 1 (+0%) | 30.0s → 53.0s (+77%) |
|
||||
| [`kotlin-concurrency-and-flow`](skills/kotlin-concurrency-and-flow/SKILL.md) | 72.7k → 119.2k (+64%) | 4 → 5 (+25%) | 1 → 1 (+0%) | 46.0s → 64.2s (+40%) |
|
||||
| [`kotlin-control-flow`](skills/kotlin-control-flow/SKILL.md) | 71.8k → 109.6k (+53%) | 4 → 5 (+25%) | 1 → 1 (+0%) | 39.1s → 53.7s (+37%) |
|
||||
| [`android-benchmark-comparison`](skills/android-benchmark-comparison/SKILL.md) | — | — | — | — |
|
||||
| [`grounded-writing`](skills/grounded-writing/SKILL.md) | 41.3k → 65.4k (+59%) | 2 → 3 (+50%) | 1 → 1 (+0%) | 16.2s → 26.9s (+66%) |
|
||||
| [`release-kotlin-library`](skills/release-kotlin-library/SKILL.md) | — | — | — | — |
|
||||
|
||||
|
||||
+13
-6
@@ -4,10 +4,10 @@ This directory contains a reproducible, advisory evaluator with a shared core
|
||||
and suite-specific catalogs, fixtures, coverage rules, and safety policies. It
|
||||
tests concrete scenarios modelled on real-world coding work, with expected
|
||||
outcomes, allowed-write boundaries, and no-change controls. The committed suites
|
||||
cover six Compose skills, four Kotlin/Gradle skills, and six workflow/writing
|
||||
skills: `grounded-writing`, `implement-with-subagents`, `release-kotlin-library`,
|
||||
`run-github-project`, `shepherd`, and `to-plan`. It is designed to answer three
|
||||
separate questions:
|
||||
cover six Compose skills, four Kotlin/Gradle skills, and seven workflow/writing
|
||||
skills: `android-benchmark-comparison`, `grounded-writing`,
|
||||
`implement-with-subagents`, `release-kotlin-library`, `run-github-project`,
|
||||
`shepherd`, and `to-plan`. It is designed to answer three separate questions:
|
||||
|
||||
1. Does a skill improve the correctness and restraint of the resulting work?
|
||||
2. Does automatic activation report the expected implicitly invokable public skill entrypoints?
|
||||
@@ -59,6 +59,7 @@ suite-wide aggregate.
|
||||
| `kotlin-api-design` | 66.7% | 100.0% | 100.0% |
|
||||
| `kotlin-concurrency-and-flow` | 33.3% | 100.0% | 100.0% |
|
||||
| `kotlin-control-flow` | 27.8% | 100.0% | 100.0% |
|
||||
| `android-benchmark-comparison` | — | — | — |
|
||||
| `grounded-writing` | — | 100.0% | 100.0% |
|
||||
| `implement-with-subagents` | — | — | 100.0% |
|
||||
| `release-kotlin-library` | — | — | — |
|
||||
@@ -89,6 +90,7 @@ The source runs, selection rules, and detailed scorecards are in the
|
||||
| `kotlin-api-design` | 57.4k → 145.8k (+154%) | 3 → 7 (+133%) | 1 → 1 (+0%) | 30.0s → 53.0s (+77%) |
|
||||
| `kotlin-concurrency-and-flow` | 72.7k → 119.2k (+64%) | 4 → 5 (+25%) | 1 → 1 (+0%) | 46.0s → 64.2s (+40%) |
|
||||
| `kotlin-control-flow` | 71.8k → 109.6k (+53%) | 4 → 5 (+25%) | 1 → 1 (+0%) | 39.1s → 53.7s (+37%) |
|
||||
| `android-benchmark-comparison` | — | — | — | — |
|
||||
| `grounded-writing` | 41.3k → 65.4k (+59%) | 2 → 3 (+50%) | 1 → 1 (+0%) | 16.2s → 26.9s (+66%) |
|
||||
| `release-kotlin-library` | — | — | — | — |
|
||||
|
||||
@@ -113,8 +115,8 @@ Each eligible `case × arm` condition runs three times by default. A case that
|
||||
targets no implicitly invokable skill is excluded from the automatic arm before
|
||||
execution. The 38-case Compose suite schedules 342 subject calls and 342
|
||||
blinded judge calls. The 22-case Kotlin/Gradle suite schedules 198 subject calls
|
||||
and 198 blinded judge calls. The 18-case workflows/writing suite schedules 126
|
||||
subject calls and 126 blinded judge calls.
|
||||
and 198 blinded judge calls. The 21-case workflows/writing suite schedules 153
|
||||
subject calls and 153 blinded judge calls.
|
||||
|
||||
All subject and judge processes use `--ignore-user-config`, explicit
|
||||
`skills.config` entries, network-disabled sandboxes, disabled hosted web search,
|
||||
@@ -142,6 +144,11 @@ required `expected_skills`; precision accepts any reported skill in the case's
|
||||
permit a genuinely relevant secondary skill without requiring every successful
|
||||
subject to consult it.
|
||||
|
||||
A no-skill automatic control sets `automatic_no_skill_control: true`. It still
|
||||
runs in the automatic arm, while requiring and permitting no public skill, so
|
||||
unnecessary activation remains visible without becoming a routing false
|
||||
negative.
|
||||
|
||||
### Corpus
|
||||
|
||||
The Compose benchmark remains 38 scored cases and comprises:
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"id": "android-benchmark-comparison-direct",
|
||||
"title": "Document a controlled quality comparison",
|
||||
"family": "benchmarking",
|
||||
"target_skills": ["android-benchmark-comparison"],
|
||||
"expected_skills": ["android-benchmark-comparison"],
|
||||
"task_mode": "edit",
|
||||
"kind": "direct",
|
||||
"fixture": "text",
|
||||
"allowed_write_paths": ["comparison.md"],
|
||||
"validators": [{"argv": ["python3", "@validators/text_case.py", "android-benchmark-comparison-direct"], "timeout_seconds": 30}],
|
||||
"rubric": [
|
||||
{"id": "experiment-evidence", "text": "The comparison records build/configuration identity, completed case and iteration coverage, raw evidence, and conditions."},
|
||||
{"id": "bounded-decision", "text": "The conclusion reports variability and traces, avoids claiming a CPU metric measures GPU shader time, and does not assign the combined controls' effect to affinity alone."}
|
||||
],
|
||||
"provenance": {"kind": "synthetic"}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"files": ["comparison.md"],
|
||||
"must_match": ["(?i)build", "(?i)raw", "(?i)trace", "(?i)variab", "(?i)completed", "(?i)controlled"],
|
||||
"must_not_match": ["(?i)CPU frame (?:duration|time) (?:measures|is) GPU shader"]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Quality comparison
|
||||
|
||||
Build: `abc123`; device: example handset. Quality 0 and 0.25 reversed CPU
|
||||
rankings on the first rerun. An ascending and descending rerun used controlled
|
||||
brightness and verified CPU placement in the trace interval. The combined
|
||||
controls made results more consistent, but cannot isolate affinity's effect.
|
||||
|
||||
Raw results and traces are attached to the run record. Finish this comparison
|
||||
without inventing values.
|
||||
@@ -0,0 +1,3 @@
|
||||
Create `comparison.md` from the supplied benchmark evidence. Recommend a default
|
||||
only to the extent supported by the evidence. Preserve uncertainty and do not
|
||||
invent a causal explanation.
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"id": "android-benchmark-comparison-negative",
|
||||
"title": "Do not turn a code-style request into a benchmark experiment",
|
||||
"family": "benchmarking",
|
||||
"target_skills": ["android-benchmark-comparison"],
|
||||
"expected_skills": ["android-benchmark-comparison"],
|
||||
"automatic_no_skill_control": true,
|
||||
"task_mode": "edit",
|
||||
"kind": "negative",
|
||||
"fixture": "text",
|
||||
"allowed_write_paths": [],
|
||||
"validators": [{"argv": ["python3", "@validators/text_case.py", "android-benchmark-comparison-negative"], "timeout_seconds": 30}],
|
||||
"rubric": [
|
||||
{"id": "restraint", "text": "The response recognizes that a formatting-only request supplies no competing configurations or benchmark decision."},
|
||||
{"id": "no-benchmarking", "text": "The response does not run, design, or demand a performance experiment for the formatting-only request."}
|
||||
],
|
||||
"provenance": {"kind": "synthetic"}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"files": ["draft.md"],
|
||||
"must_contain": ["duplicate parse"]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
Inspect whether `draft.md` already follows an 80-column style. Change it only
|
||||
if it does not; preserve its words and meaning, and do not run commands.
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"id": "android-benchmark-comparison-novel",
|
||||
"title": "Review a reversed benchmark ranking",
|
||||
"family": "benchmarking",
|
||||
"target_skills": ["android-benchmark-comparison"],
|
||||
"expected_skills": ["android-benchmark-comparison"],
|
||||
"task_mode": "review",
|
||||
"kind": "novel",
|
||||
"fixture": "text",
|
||||
"allowed_write_paths": [],
|
||||
"validators": [{"argv": ["python3", "@validators/text_case.py", "android-benchmark-comparison-novel"], "timeout_seconds": 30}],
|
||||
"rubric": [
|
||||
{"id": "reversal-investigation", "text": "The review asks to verify case/iteration coverage, balance or reverse run order, and inspect trace intervals before selecting a default."},
|
||||
{"id": "affinity-boundary", "text": "The review distinguishes fixed performance mode from verified CPU placement and requires restoration after any affinity experiment."}
|
||||
],
|
||||
"provenance": {"kind": "synthetic"}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"files": ["draft.md"],
|
||||
"must_contain": ["duplicate parse"]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
Review the next safe action only; do not edit files. A quality 0 run was faster
|
||||
than quality 0.25 yesterday, but slower today. Both reports say "fixed
|
||||
performance mode" and contain rounded p95 values, but neither names all cases
|
||||
or iterations. An affinity command was tried, and no trace verifies placement.
|
||||
The team wants to pick the convenient faster default now.
|
||||
@@ -54,6 +54,7 @@ class EvalCase:
|
||||
forbidden_command_patterns: tuple[str, ...] = ()
|
||||
allowed_skills: tuple[str, ...] = ()
|
||||
calibration: bool = False
|
||||
automatic_no_skill_control: bool = False
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -150,6 +151,10 @@ def load_case(manifest_path: Path, repo_root: Path) -> EvalCase:
|
||||
if kind == "routing" and not expected_skills:
|
||||
raise CaseValidationError("routing cases require at least one expected skill")
|
||||
|
||||
automatic_no_skill_control = data.get("automatic_no_skill_control", False)
|
||||
if not isinstance(automatic_no_skill_control, bool):
|
||||
raise CaseValidationError("automatic_no_skill_control must be a boolean")
|
||||
|
||||
fixture = _require_string(data, "fixture")
|
||||
if not _safe_relative(fixture):
|
||||
raise CaseValidationError("fixture must be a safe relative path")
|
||||
@@ -266,6 +271,7 @@ def load_case(manifest_path: Path, repo_root: Path) -> EvalCase:
|
||||
required_command_patterns=command_patterns["required_command_patterns"],
|
||||
forbidden_command_patterns=command_patterns["forbidden_command_patterns"],
|
||||
allowed_skills=allowed_skills,
|
||||
automatic_no_skill_control=automatic_no_skill_control,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ def _routing_expectations(
|
||||
) -> tuple[tuple[str, ...], tuple[str, ...]]:
|
||||
if arm != "automatic":
|
||||
return case.expected_skills, case.allowed_skills or case.expected_skills
|
||||
if case.automatic_no_skill_control:
|
||||
return (), ()
|
||||
automatic_skills = set(automatically_invokable_public_skills(repo_root))
|
||||
return (
|
||||
tuple(skill for skill in case.expected_skills if skill in automatic_skills),
|
||||
@@ -71,7 +73,9 @@ def _routing_expectations(
|
||||
|
||||
|
||||
def _automatic_eligible(case: EvalCase, repo_root: Path) -> bool:
|
||||
return bool(_routing_expectations(case, "automatic", repo_root)[0])
|
||||
return case.automatic_no_skill_control or bool(
|
||||
_routing_expectations(case, "automatic", repo_root)[0]
|
||||
)
|
||||
|
||||
|
||||
def evaluation_conditions(
|
||||
|
||||
@@ -11,6 +11,7 @@ PUBLIC_SKILLS = (
|
||||
"compose-performance",
|
||||
"compose-state-and-effects",
|
||||
"compose-ui-testing-patterns",
|
||||
"android-benchmark-comparison",
|
||||
"gradle-run",
|
||||
"grounded-writing",
|
||||
"implement-with-subagents",
|
||||
@@ -66,6 +67,7 @@ KOTLIN_GRADLE_SKILLS = (
|
||||
"kotlin-control-flow",
|
||||
)
|
||||
WORKFLOWS_WRITING_SKILLS = (
|
||||
"android-benchmark-comparison",
|
||||
"grounded-writing",
|
||||
"implement-with-subagents",
|
||||
"release-kotlin-library",
|
||||
@@ -98,7 +100,7 @@ SUITES = {
|
||||
id="workflows-writing",
|
||||
title="Workflows and writing",
|
||||
skills=WORKFLOWS_WRITING_SKILLS,
|
||||
benchmark_cases=18,
|
||||
benchmark_cases=21,
|
||||
routing_cases=0,
|
||||
calibration_cases=12,
|
||||
require_skill_triads=True,
|
||||
|
||||
@@ -60,8 +60,24 @@ class CaseContractTest(unittest.TestCase):
|
||||
self.assertEqual(("compose-state-and-effects",), case.expected_skills)
|
||||
self.assertEqual(("compose-state-and-effects",), case.allowed_skills)
|
||||
self.assertFalse(case.calibration)
|
||||
self.assertFalse(case.automatic_no_skill_control)
|
||||
self.assertEqual("Fix the subject.\n", case.prompt)
|
||||
|
||||
def test_allows_a_no_skill_automatic_control(self):
|
||||
case_dir = self.write_case(valid_manifest(automatic_no_skill_control=True))
|
||||
|
||||
case = load_case(case_dir / "case.json", self.root)
|
||||
|
||||
self.assertTrue(case.automatic_no_skill_control)
|
||||
|
||||
def test_requires_automatic_no_skill_control_to_be_boolean(self):
|
||||
case_dir = self.write_case(valid_manifest(automatic_no_skill_control="yes"))
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
CaseValidationError, "automatic_no_skill_control must be a boolean"
|
||||
):
|
||||
load_case(case_dir / "case.json", self.root)
|
||||
|
||||
def test_allowed_skills_must_include_every_expected_skill(self):
|
||||
case_dir = self.write_case(
|
||||
valid_manifest(
|
||||
|
||||
@@ -75,11 +75,11 @@ class EvaluationCliTest(unittest.TestCase):
|
||||
|
||||
plan = json.loads(output)
|
||||
self.assertEqual(0, status)
|
||||
self.assertEqual(18, plan["case_count"])
|
||||
self.assertEqual(42, plan["condition_count"])
|
||||
self.assertEqual(126, plan["subject_calls"])
|
||||
self.assertEqual(126, plan["judge_calls"])
|
||||
self.assertEqual(252, plan["total_calls"])
|
||||
self.assertEqual(21, plan["case_count"])
|
||||
self.assertEqual(51, plan["condition_count"])
|
||||
self.assertEqual(153, plan["subject_calls"])
|
||||
self.assertEqual(153, plan["judge_calls"])
|
||||
self.assertEqual(306, plan["total_calls"])
|
||||
|
||||
def test_filters_case_skill_and_arm_before_counting_calls(self):
|
||||
status, output = self.invoke(
|
||||
|
||||
@@ -125,10 +125,10 @@ class CodexRunnerTest(unittest.TestCase):
|
||||
self.assertIn("SKILL.md", rendered)
|
||||
self.assertEqual(1, " ".join(none).count("path = "))
|
||||
self.assertEqual(2, " ".join(forced).count("path = "))
|
||||
self.assertEqual(14, " ".join(automatic).count("path = "))
|
||||
self.assertEqual(15, " ".join(automatic).count("path = "))
|
||||
self.assertEqual(0, " ".join(none).count("enabled = true"))
|
||||
self.assertEqual(1, " ".join(forced).count("enabled = true"))
|
||||
self.assertEqual(13, " ".join(automatic).count("enabled = true"))
|
||||
self.assertEqual(14, " ".join(automatic).count("enabled = true"))
|
||||
self.assertIn("$compose-state-and-effects", forced[-1])
|
||||
self.assertNotIn("$compose-state-and-effects", automatic[-1])
|
||||
self.assertIn("If you run Gradle, use `--offline --no-scan`.", automatic[-1])
|
||||
|
||||
@@ -31,11 +31,11 @@ class WorkflowsWritingMatrixTest(unittest.TestCase):
|
||||
|
||||
benchmark = [case for case in report.cases if not case.calibration]
|
||||
calibration = [case for case in report.cases if case.calibration]
|
||||
self.assertEqual(18, len(benchmark))
|
||||
self.assertEqual(21, len(benchmark))
|
||||
self.assertEqual(12, len(calibration))
|
||||
self.assertIn("grounded-writing", PUBLIC_SKILLS)
|
||||
self.assertNotIn("implement", PUBLIC_SKILLS)
|
||||
self.assertEqual(18, len(filter_cases(report.cases, case_ids=None, skills=None)))
|
||||
self.assertEqual(21, len(filter_cases(report.cases, case_ids=None, skills=None)))
|
||||
self.assertFalse(any(case.kind == "routing" for case in report.cases))
|
||||
self.assertEqual(
|
||||
{
|
||||
@@ -206,6 +206,9 @@ class WorkflowsWritingMatrixTest(unittest.TestCase):
|
||||
"grounded-writing-direct",
|
||||
"grounded-writing-novel",
|
||||
"grounded-writing-negative",
|
||||
"android-benchmark-comparison-direct",
|
||||
"android-benchmark-comparison-novel",
|
||||
"android-benchmark-comparison-negative",
|
||||
"release-kotlin-library-direct",
|
||||
"release-kotlin-library-novel",
|
||||
"release-kotlin-library-negative",
|
||||
@@ -255,6 +258,25 @@ class WorkflowsWritingMatrixTest(unittest.TestCase):
|
||||
self.assertEqual(["grounded-writing"], records[2]["expected_skills"])
|
||||
self.assertFalse(records[3]["automatic_eligible"])
|
||||
|
||||
def test_no_skill_automatic_control_runs_without_routing_to_its_target(self):
|
||||
report = validate_corpus(REPO_ROOT, suite="workflows-writing")
|
||||
case = next(
|
||||
case
|
||||
for case in report.cases
|
||||
if case.id == "android-benchmark-comparison-negative"
|
||||
)
|
||||
|
||||
self.assertTrue(case.automatic_no_skill_control)
|
||||
self.assertIn(
|
||||
(case, "automatic"), evaluation_conditions(REPO_ROOT, (case,), ("automatic",))
|
||||
)
|
||||
records = [{"case_id": case.id, "arm": "automatic"}]
|
||||
reconcile_automatic_eligibility(REPO_ROOT, report.cases, records)
|
||||
|
||||
self.assertTrue(records[0]["automatic_eligible"])
|
||||
self.assertEqual([], records[0]["expected_skills"])
|
||||
self.assertEqual([], records[0]["allowed_skills"])
|
||||
|
||||
def test_behavioral_expectations_do_not_assert_fixture_prose(self):
|
||||
expectations = json.loads(
|
||||
(
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
name: android-benchmark-comparison
|
||||
description: Use when comparing physical Android benchmark configurations, investigating inconsistent rankings, or selecting an Android default from measured results. Do not use for code-level Compose performance diagnosis without a configuration comparison.
|
||||
---
|
||||
|
||||
# Android benchmark comparison
|
||||
|
||||
## Core principle
|
||||
|
||||
Treat a physical Android configuration comparison as a reproducible experiment:
|
||||
verify comparable workloads and device conditions before interpreting a ranking
|
||||
or choosing a default.
|
||||
|
||||
## Procedure
|
||||
|
||||
1. State the decision, configurations, workloads, metric definitions, and
|
||||
repetitions. Preserve exact build identity, configuration, raw results, and
|
||||
traces; then verify every intended case and iteration ran. Distinguish
|
||||
missing, failed, and excluded runs; do not compare only the fastest
|
||||
survivors.
|
||||
2. Control and record relevant device conditions, including device model and
|
||||
state, thermal and power mode, display brightness, background load, and
|
||||
network or input conditions. Keep device-specific commands and CPU masks in
|
||||
the project's runbook.
|
||||
3. Balance or reverse run order and repeat the comparison. Report the spread
|
||||
and whether the ordering holds; do not discard slow iterations after seeing
|
||||
the result.
|
||||
4. When rankings reverse or variability is material, investigate before making
|
||||
the decision. Use traces to check the measured interval and plausible
|
||||
causes such as CPU placement, contention, or thermal state. A fixed-
|
||||
performance setting does not prove CPU placement. If affinity is used,
|
||||
discover the device topology, verify placement during the measured trace
|
||||
interval, label the outcome a controlled comparison, and restore device
|
||||
settings afterwards.
|
||||
5. Calculate summaries from unrounded observations, then round only for
|
||||
presentation. Name the aggregation explicitly: the mean of per-run
|
||||
percentiles is not a percentile of pooled observations. Choose an
|
||||
aggregation that answers the stated decision; do not prescribe one statistic
|
||||
universally.
|
||||
6. Separate controlled-experiment evidence from normal user performance. If
|
||||
several conditions changed together, report the comparison as more
|
||||
controlled but do not attribute its whole difference to one control. Use
|
||||
CPU frame-duration evidence to inform a visual quality/performance decision,
|
||||
without claiming it measures GPU shader time.
|
||||
7. Finish with the raw-evidence location, completed-case counts, variability,
|
||||
trace findings, controls and restoration status, plus the bounded decision
|
||||
or remaining uncertainty.
|
||||
|
||||
## Boundaries
|
||||
|
||||
- A single stable benchmark run can support a narrow observation, but not a
|
||||
robust configuration ranking.
|
||||
- Do not turn a device-specific CPU mask, brightness value, iteration count, or
|
||||
summary statistic into a permanent default.
|
||||
- When traces or repeat coverage cannot resolve a reversal, keep the default
|
||||
unchanged or make a provisional decision with that limitation explicit.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: using-chrisbanes-skills
|
||||
description: Use when debugging, benchmarking, or profiling leads into Kotlin or Jetpack Compose source before the cause is known, or when one task spans multiple Kotlin or Compose concerns, especially plain Kotlin Flow or navigation delivery plus sealed branching.
|
||||
description: Use when routing Kotlin or Jetpack Compose work, or physical Android benchmark evidence that needs a configuration decision, especially when several Kotlin or Compose concerns overlap.
|
||||
---
|
||||
|
||||
# Using chrisbanes skills
|
||||
@@ -13,7 +13,9 @@ only when its independent behavior changes the same work.
|
||||
|
||||
## Routing procedure
|
||||
|
||||
1. Read the task and the Kotlin source that makes the concern concrete.
|
||||
1. Read the task. For Kotlin or Compose work, inspect the source that makes the
|
||||
concern concrete. For an Android benchmark comparison, inspect the supplied
|
||||
reports, configurations, and traces instead.
|
||||
2. If one focused skill clearly matches, load it directly and stop routing.
|
||||
3. Before loading a Compose skill, point to a concrete Compose API or composable
|
||||
in the inspected source, or to an explicit request to create or design
|
||||
@@ -40,6 +42,7 @@ only when its independent behavior changes the same work.
|
||||
| Kotlin classification, `when`, guards, exhaustiveness, smart casts, or null branches | [`kotlin-control-flow`](../kotlin-control-flow/SKILL.md) |
|
||||
| Kotlin function ownership, domain types, expect/actual, or platform seams | [`kotlin-api-design`](../kotlin-api-design/SKILL.md) |
|
||||
| Planned Gradle execution or a Gradle-centered warning/failure workflow | [`gradle-run`](../gradle-run/SKILL.md) |
|
||||
| Comparing physical Android benchmark configurations, reversed rankings, or an Android default | [`android-benchmark-comparison`](../android-benchmark-comparison/SKILL.md) |
|
||||
| Kotlin library release preparation, publication, or readiness | [`release-kotlin-library`](../release-kotlin-library/SKILL.md) |
|
||||
| One ready GitHub issue or in-chat task needs repository-aware planning | [`to-plan`](../to-plan/SKILL.md) |
|
||||
| Polling PRs/MRs, review comments, CI failures, or routine follow-up | [`shepherd`](../shepherd/SKILL.md) |
|
||||
|
||||
Reference in New Issue
Block a user