Control Adoption & Backport Scan¶
Maturity: assess — worth exploring; promising but not yet proven across enough contexts.
When to use: Deliberately invoke in Agent mode against an in-scope consumer repository to produce a point-in-time read on which of the library's deterministic controls the repo already has, and — just as importantly — what the repo does better or newer that should be pulled back into the library. Re-run periodically (e.g. per quarter, or when a repo lands significant tooling changes) to keep provenance and effort estimates honest.
The agent needs read access only to the target repo; it must not modify that repo. It writes results into the library / portfolio repo that owns the matrix (paths confirmed in the scope gate).
Where results are stored (the data model)¶
This scan is a portfolio rollup — one machine-friendly data file holds the current control state for all scanned repos, so it can feed measurement frameworks and show the net diff between runs. Three artefacts, each with a distinct job:
| File | Job | Format |
|---|---|---|
control-matrix.yml |
State — current status of each control per repo, with since (last-changed) dates and provenance |
YAML (primary machine artefact) |
reviews/YYYY-MM.yml |
Run log — when each repo was scanned + the per-run changes net diff |
YAML |
scans/<repo-id>/ongoing-control-adoption-review.md |
Narrative — the human-readable evidence write-up (optional) | Markdown |
Default layout (engagement libraries often use this; confirm in the scope gate — do not invent a second schema):
docs/management/compliance/
control-matrix.yml
repos.yml # optional registry of in-scope clones
reviews/YYYY-MM.yml
scans/<repo-id>/ongoing-control-adoption-review.md
Starter shapes live in this skill's ../assets/. Copy them into
the portfolio repo on first use if the files do not exist yet.
Net diff: on each run, read the repo's prior block in control-matrix.yml,
set the observed status per control, and compare. A control whose status changed
gets a new since: date and is recorded as {control, from, to} in the run-log
changes. Unchanged controls keep their old since. First run for a repo →
changes: baseline. A drift-free re-run → changes: [].
The scan runs in two directions for every control:
| Direction | Question | Outcome |
|---|---|---|
| Adoption (library → repo) | Has this repo taken up a library asset/pattern? | Evidence the library is landing; a proof point |
| Backport (repo → library) | Does this repo have a refinement or net-new implementation the library lacks? | A candidate to transplant/generalise into the library |
What this scan covers¶
The canonical control list is in control-catalogue.md. Always read that file first so the scan stays in sync if scope changes.
Library-pattern adoption signals to check alongside: see the catalogue section of the same file.
Scope gate — confirm before running (mandatory)¶
Do not assume scope. Before scanning, confirm the following. If a point is unambiguous from the request or workspace, state the assumption and proceed; otherwise ask and wait.
- Target repo + archetype. Which repository, and what component type is it —
Python/API service, front-end app, data pipeline, or platform/IaC? The
archetype decides which controls are in scope vs N/A (e.g. data-platform
naming standards are often N/A for a React app; RUM is N/A for a pure data
pipeline). If a
repos.yml(or equivalent registry) recordslocal_cloneand archetype, default to that and say so. - Comparison baseline. Scan against the full catalogue in control-catalogue.md unless the user names a narrower set.
- Results location. Which portfolio/library path holds
control-matrix.ymlandreviews/? Default suggestion:docs/management/compliance/in the repo that owns the engagement library. Do not write into the target consumer repo.
Prompt¶
Produce a Control Adoption & Backport Scan for this repository. Work entirely from the local clone, read-only — do not modify the target repo.
First, settle scope (see Scope gate). Confirm the target repo, its archetype, the control set, and the results path. State the archetype in one line, then proceed.
1. Fingerprint the repo¶
Identify the toolchain and layout: package manager, language(s), test runner, CI system, default branch, and any monorepo/service structure. Note the exact evidence files you will cite (config paths, pipeline YAML, hook config).
2. Evidence table — one row per control¶
For each control in scope, search the repo (see Where to look below) and record:
- Status: ✅ present · 🟡 partial · ⬜ absent · — N/A for this archetype
- Evidence: the concrete file(s) + what they show (cite paths; quote the tool/flag, e.g.
pytest --cov-fail-under=90, not "has tests")- Direction: Adoption (cites a library asset/pattern), Backport (a refinement or net-new impl the library lacks — say what to extract), or Parity (matches library)
Be specific and evidence-led. "Present" requires a cited file, not an inference.
3. Backport candidates (repo → library)¶
Pull out, as a ranked list, anything this repo does that the library should absorb: a smarter gate, a reusable template, a tested helper, a novel stage. For each, name the source file, the library target (which skill or HoEN need it feeds), and a one-line extraction note.
4. Adoption evidence (library → repo)¶
List where this repo already runs a library asset/pattern (see catalogue signals). If none, say so plainly — an independent implementation is a backport source, not an adoption case.
5. Provenance & effort implication¶
For each control, state the library sourcing verdict:
- Port — a scanned consumer repo already proves a workable exemplar
- Transplant — a reusable asset already exists in the engineering library
- Net-new — not yet evidenced anywhere in the portfolio
Say whether this repo changes the current library effort estimate or merely confirms it. Flag any control that is confirmed absent across the swept repos (that keeps a step net-new).
6. Update the data model (required) + narrative (optional)¶
a.
control-matrix.yml(state — always). Underrepos.<repo-id>, setarchetype,default_branch,last_run(today),last_git_ref(short SHA), and each control's{status, direction, evidence}. For any control whose status changed vs the stored value, setsince:to today; otherwise leavesinceunchanged. Recomputecounts. Recordbackport_candidatesandadoption_signals. If the repo is new, add its block and remove it frompending_reposwhen that list exists. Refreshcontrol_provenanceif the cross-repo picture shifted (e.g. a control that was net-new is now proven somewhere →port). Bump top-levelupdated.b.
reviews/YYYY-MM.yml(run log — always). Add an entry per repo scanned withrepo_id,scan_id: control-adoption,status,git_ref,reviewed_at,counts, andchanges— the net diff (baselineon first run,[]if drift-free, else a list of{control, from, to}). Create the month file if absent.c.
scans/<repo-id>/ongoing-control-adoption-review.md(narrative — optional). If a human write-up is wanted, prepend a## Run: <YYYY-MM-DD>section (evergreen frontmatter withscan_id: control-adoption; bumplast_reviewed). Lead with the At a glance block: archetype, present/partial/absent/na counts, # backport candidates, # adoption signals, and what changed since last run.Report back the net diff (or
baseline), the updated counts, and any new backport candidates — do not silently rewrite effort plans or estimate JSON; flag effort implications instead.
Where to look (search hints)¶
| Control | Files / signals to grep |
|---|---|
| Local dev | .pre-commit-config.yaml, pyproject.toml/uv.lock, package.json scripts, README run steps |
| Version control | .husky/, commitlint.config.*, .pre-commit-config.yaml (commit-msg), detect-secrets/gitleaks |
| Quality engineering | pytest/--cov-fail-under, jest+coverage, coverage gates in CI, hook config |
| Static analysis | ruff, flake8, pylint, mypy, tsc --noEmit, ESLint config |
| Standards compliance | Naming/layout rules, compliance-scan artefacts (data-platform archetypes only when applicable) |
| Deployment | .github/workflows/**, azure-pipelines.yml, ci_cd/pipelines/**, deploy templates, environment/approval gates |
| Security controls | bandit, pip-audit, detect-secrets, gitleaks, Dependabot/Mend/Snyk, dependency scans |
| Logging & monitoring | opentelemetry, azure-monitor-opentelemetry, telemetry.py, structured logging, App Insights / equivalent exporters |
| Infrastructure as Code | *.tf, main.tf, bicep, pulumi, terraform pipeline stages |
Tips for reviewers¶
- Scope by archetype first. Marking a control ⬜ when it is genuinely N/A for the archetype distorts the read. Use — for N/A and say why.
- Cite the file, not the vibe. Every ✅ needs a path and the actual tool/flag. This is what makes the provenance verdict (Port vs Net-new) defensible.
- Two directions, always. A repo with strong independent controls is a rich backport source even with zero library adoption — that is a finding, not a blank.
- Confirmed-absent is a result. A control missing across every swept repo (e.g. secret pre-push, IaC) is what keeps a library step net-new and higher-effort. Record it.
- Feed the plan, don't silently rewrite it. Report provenance/effort implications; apply them to effort estimates only when the user asks.
- Keep the control list synced. The catalogue owns the control set — if scope changes there, update control-catalogue.md rather than drifting in this prompt.