chaos-code-risk-scan
Skill127 starsChanged 31 days agoApache-2.0View on GitHub
Scan a source code repository for resilience risks that a Harness chaos experiment can prove (outbound calls without timeouts, retries without backoff, missing graceful shutdown, health checks that mask dependency state, unbounded queues and pools, local state), map each one to a generic SourceCode risk rule, and report them to Harness as a CodeRepository risk scan. Use when the user asks to scan a repo or service code for resilience or chaos risks, or wants code findings they can verify with chaos experiments. Do not use for manifest or pipeline risk scans (those run in Harness), to create or run chaos experiments (use chaos-experiment), or for security or code quality review. Trigger phrases: scan this repo for resilience risks, chaos code scan, find chaos-provable risks, code risk scan, resilience review of this service.
In this repository76 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- .cursor/rules/harness.mdcCursor rule
- manage-rolesSkill
- manage-usersSkill
- create-agentSkill
- create-agent-templateSkill
- dbops-changesetSkill
- choose-metricSkill
- cleanup-feature-flagsSkill
- create-experimentSkill
- create-feature-flagSkill
- create-metricSkill
- discover-feature-flagsSkill
- explain-flagSkill
- feature-flag-onboardingSkill
- fme-pipelineSkill
- instrument-feature-flagSkill
- instrument-metricSkill
- manage-experimentsSkill
- manage-flag-lifecycleSkill
- manage-segmentsSkill
- review-experiment-resultsSkill
- update-flag-targetingSkill
- create-connectorSkill
- create-environmentSkill
- create-infrastructureSkill
- create-secretSkill
- create-serviceSkill
- ai-operationsSkill
- analyze-costsSkill
- audit-reportSkill
- chaos-dr-testSkill
- chaos-experimentSkill
- create-policySkill
- deployment-readinessSkill
- dora-metricsSkill
- gitops-statusSkill
- incident-responseSkill
- manage-idpSkill
- manage-slosSkill
- optimize-pipelineSkill
- pr-analysisSkill
- scorecard-reviewSkill
- security-reportSkill
- sei-analyticsSkill
- template-usageSkill
- create-pipelineSkill
- create-pipeline-v1Skill
- create-templateSkill
- create-triggerSkill
- debug-pipelineSkill
- manage-freeze-windowsSkill
- migrate-pipelineSkill
- run-pipelineSkill
- create-sbomSkill
- enforce-sbomSkill
- manage-artifactsSkill
- manage-cdeSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
34 rules. About 0 are common, 12 are distinctive, and 22 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈12
Distinctive · estimate
This author's own choices. Worth a look.
22
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 45
If a write is blocked because no confirmation prompt could be shown, retry that same call once with confirm: true.
- Distinctive: line 51
NEVER claim a tool call succeeded without an explicit success response from the tool.
- Distinctive: line 52
NEVER fabricate, assume, or pre-empt tool results.
- Very specific: line 53
NEVER submit a finding that validate_evidence.py dropped, and never edit a snippet to make it pass.
- Very specific: line 64
Use the org and project already configured for Harness MCP.
- Very specific: line 67
Run git status --porcelain.
- Distinctive: line 73
Look up the previous scan of this repository and this branch before reading any source.
- Very specific: line 88
If that previous commit is not an ancestor of HEAD (a rebase, or a commit git cannot resolve), a diff is not possible.
- Very specific: line 92
Read the origin URL, the current branch, and HEAD:
- Very specific: line 105
Keep the baseline scan identity.
- Very specific: line 108
Run inventory. Pass --since <commitSHA> only for a same-branch baseline with a different commit.
- Very specific: line 115
Read repo.scanMode before opening any file.
- Very specific: line 125
Before opening any source file, compare counts with the facts kept.
- Distinctive: line 173
If a mitigation exists, add a disposition (below).
- Very specific: line 174
Do not clear a fact because the call looks minor (a Slack notifier, a reporter, a library helper): a call that can hang is a risk wherever …
- Very specific: line 182
Write one finding per (rule, module) for every module that has an uncleared fact.
- Very specific: line 186
Write $TMP/dispositions.json for every cleared fact:
- Very specific: line 204
Regression check against the baseline: When Phase 2 found a baseline scan that still exists, fetch its findings …
- Distinctive: line 213
If a confirmed risk has no matching rule, follow rule-authoring.md.
- Very specific: line 216
No rule exists, and the failure mode is in failure-modes.md: harness_create that catalog rule with confirm: true.
- Very specific: line 220
After any create, re-fetch rules into $TMP/rules.json.
- Very specific: line 225
Write $TMP/draft.json as {"findings": [...]} using the shape in evidence-contract.md:
- Distinctive: line 231
Do not send severity or category.
- Very specific: line 240
Read dropped. Fix a finding only if the reason is a mistake you made (wrong line range, missing fault name) and the code really shows the …
- Distinctive: line 264
Do not ask which service to use, and do not link a runtime discovered service.
- Very specific: line 287
Do not send branch. If a create fails because the identity is too long, shorten the slug from the end and say so.
- Distinctive: line 300
Create every missing custom service in one batch, then every missing chaos service in one batch.
- Distinctive: line 303
If a create fails, leave that module's findings out of the submit and record the error.
- Very specific: line 321
When scanMode is diff and validation kept no findings, still create the scan and submit {"findings": []}.
- Very specific: line 328
If the response lists per-finding errors, report them.
- Distinctive: line 349
Do not list agents, services, or probes, and do not call update:
- Distinctive: line 418
Follow this order. The Harness submit is a few seconds.
- Very specific: line 424
Start inventory at --max-per-kind 80.
- Distinctive: line 429
Create the missing custom services in one batch, then the chaos services in one batch.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Chaos Code Risk Scan
Find resilience risks in a repository that a chaos experiment can turn into a
pass/fail result, and send them to Harness as a CodeRepository risk scan.
Harness then scores them, adds them to the scan report and, for modules linked
to a chaos service, recommends experiments.
The work is split so evidence cannot be invented: scripts extract facts and verify snippets; you only map verified facts to rules and write the explanation; the server re-validates everything.
One prompt runs the whole flow. Do not ask the user to choose an org, project, module,
service, rule, or to approve a create or a submit. The only stops are a missing
origin remote, or a tool error that a single retry does not clear. Report those
at the end; do not pause the scan to ask how to proceed.
Pass confirm: true on every harness_create and on the attach update below.
If a write is blocked because no confirmation prompt could be shown, retry that
same call once with confirm: true. Do not attach a runtime discovered service
during the scan. After the summary, offer that attachment in one sentence and
stop. Ask for the discovered service and probes only after the user asks to attach.
MANDATORY — Tool Result Verification:
- NEVER claim a tool call succeeded without an explicit success response from the tool.
- NEVER fabricate, assume, or pre-empt tool results. If a call did not return a confirmed result, say so and retry.
- NEVER submit a finding that
validate_evidence.pydropped, and never edit a snippet to make it pass. - A confirmation card is not a reason to stop. Retry with
confirm: true, then continue.
Instructions
SKILL_DIR below is the directory containing this file. Run scripts with
python3 "$SKILL_DIR/scripts/<script>.py" and keep their JSON output in a
temporary directory, not in the user's repository.
Phase 1: Scope and preflight
- Use the org and project already configured for Harness MCP. State them:
Working in org=..., project=.... Do not ask. - Repository root: the path the user named, otherwise the workspace root that is a git repo.
- Run
git status --porcelain. Evidence is validated againstHEAD. If the tree is dirty, continue and say in the summary that uncommitted files were ignored. - The repository needs an
originremote; risks are keyed to it. Stop if it has none.
Phase 2: Last scan of this branch, then inventory
Look up the previous scan of this repository and this branch before reading any source. Branch and commit live on the scan. One code-repository custom service covers every branch of a module; reuse it whether this is a first scan, a diff, or a skip. Do not create another service because the branch changed.
Decide from the newest scan whose source.codeRepository.repoURL matches this
origin (host/org/repo, no scheme) and whose branch is the current branch.
A scan of any other branch is not a baseline.
| Previous scan of this branch | What to do |
| None | Full inventory. Create a new scan of the whole tree. |
Same commitSHA as HEAD | Skip. Do not inventory, fetch rules, create services, or create a scan. Say which branch and commit were already scanned, then stop. |
Different commitSHA | Diff only. Pass that commit as --since and scan files changed between it and HEAD. Create a new scan that records this commit. |
If that previous commit is not an ancestor of HEAD (a rebase, or a commit git
cannot resolve), a diff is not possible. Inventory falls back to a full scan
and you still create the new scan. Say that in the summary.
- Read the origin URL, the current branch, and
HEAD:
git -C "$REPO" remote get-url origin
git -C "$REPO" rev-parse --abbrev-ref HEAD
git -C "$REPO" rev-parse HEADharness_list(resource_type="chaos_risk_scan", filters={scan_type: "CodeRepository", sort_field: "lastUpdated", sort_ascending: false}). Take the newest scan for thisrepoURLand thisbranch. If a list item has nosource,harness_getthat scan. A scan with an empty branch matches only when no same-branch scan exists. A scan that is listed but returns 404 onharness_getwas deleted: treat it as no baseline, and say so in the summary. Keep the baseline scan identity; Phase 4 uses it for the regression check. Compare itscommitSHAtoHEADand follow the table above. Stop here when they are equal.- Run inventory. Pass
--since <commitSHA>only for a same-branch baseline with a different commit. Start at--max-per-kind 80so a large module is not scanned twice.
python3 "$SKILL_DIR/scripts/inventory.py" --repo "$REPO" --out "$TMP/inventory.json" --max-per-kind 80 [--since COMMIT]- Read
repo.scanModebefore opening any file. The same-commit case already stopped in step 2; these are the two modes that continue:
diff— facts cover only files changed sincerepo.baseCommit. Map and submit only those. Open only files cited by facts. Create the scan.full— this branch has no previous scan, or its commit cannot bound a diff. Scan the tree as usual and create the scan.unchanged—HEADis the commit already scanned. This is the same skip as step 2. Do not fetch rules, create services, or create a scan. Stop.
- Before opening any source file, compare
countswith the facts kept. If any module and kind has a higher count than the facts kept for it, re-run inventory once with--max-per-kindset to that largest count. Do this before Phase 3.
The output lists modules and facts (kind, file, startLine, snippet, attrs).
Facts are candidates, not findings. Test, example, vendor, generated, tooling and
frontend-only code is already excluded. Unchanged files are left as they were on
the previous scan; this run does not re-judge them.
Phase 3: Fetch rules
harness_list(resource_type="chaos_risk_rule", filters={data_source: "SourceCode"}, compact=false), all pages.
Save the bodies as {"data": [...]} in $TMP/rules.json. Call
harness_get(resource_type="chaos_risk_rule", resource_id=<identity>) only for
a rule whose spec.faults is missing. Read
failure-modes.md for the failure modes, faults and probe signals.
Phase 4: Map facts to rules
The inventory is deterministic, so the verdicts must be too: two scans of the same commit must report the same risks. Every actionable fact ends in exactly one state: reported in a finding, or cleared by a cited mitigation. There is no third state such as "skipped", "low impact" or "not verified".
Actionable facts, per scripts/coverage.py:
| Fact | Actionable when |
outbound_client | timeout is none or unknown |
retry_construct | backoff is none or constant, or attempt_cap is not bounded |
health_endpoint, serving_entrypoint, local_state | always (open the file and decide) |
Work module by module, not in the order you find interesting. Group the
actionable facts by file. Read each cited file once, in one batch, and decide
every fact in that file from that read. Open another file only when the
mitigation lives there, such as a shared client factory or the main of a
one-shot job. On a diff scan, do not open a file the inventory did not cite.
For every actionable fact, look for a mitigation:
- A shared client factory or
client.Timeoutset after construction, a context deadline at the call site, a mesh timeout in repo config. - A resilience library with exponential backoff and jitter wrapping the call.
Shutdown/Stopcalled after SIGTERM; readiness that returns non-2xx when the dependency is down; state kept in an external store.- The code is startup-only, a CLI or a one-shot job (cite the entry point line).
- A
harness-chaos-ignorecomment.
If a mitigation exists, add a disposition (below). If none does, it is a finding.
Do not clear a fact because the call looks minor (a Slack notifier, a reporter, a
library helper): a call that can hang is a risk wherever it sits. Do not clear a
fact you have not opened. attrs.timeout: unknown needs a look at the call site;
if you still cannot tell, report it with the uncertainty in evidence, not drop it.
A retry with backoff does not bound a single attempt. A client with no Timeout is
still a timeout finding even when its retries use backoff.
Write one finding per (rule, module) for every module that has an uncleared fact. Put
up to 5 call sites in codeLocations and the total in callSiteCount. Count call
sites from the inventory (grep-verifiable), not by estimate. Cap: 8 findings per module.
Write $TMP/dispositions.json for every cleared fact:
{"dispositions": [
{"module": "subscriber", "file": "subscriber/pkg/common/restCall.go", "startLine": 61,
"kind": "outbound_client", "reason": "shared_factory_timeout",
"mitigation": {"file": "subscriber/pkg/common/restCall.go", "line": 70},
"note": "client.Timeout is set to 40s right after construction"}
]}reason is one of shared_factory_timeout, context_deadline, mesh_timeout,
resilience_library, bounded_backoff, graceful_shutdown_present,
health_check_correct, external_store, not_serving_path, suppressed,
pattern_absent (the match is not the risk, such as an import used only to parse;
cite the real usage).
mitigation must point at a real file and line at HEAD.
Regression check against the baseline. When Phase 2 found a baseline scan that
still exists, fetch its findings (harness_execute(resource_type="chaos_risk_scan",
action="report", resource_id=<baseline>)). For each prior (rule, module), either this
scan reports it again or you confirm at HEAD that the cited code changed or was
fixed. Say which in the summary. A prior finding that vanished with unchanged code
means you under-reported: go back and report it.
Phase 5: Create missing catalog rules
If a confirmed risk has no matching rule, follow rule-authoring.md.
- An existing rule covers the failure mode: use it. Do not update it.
- No rule exists, and the failure mode is in failure-modes.md:
harness_createthat catalog rule withconfirm: true. Do not show a confirmation message and do not wait. - Anything else: drop the finding and list it in the summary.
After any create, re-fetch rules into $TMP/rules.json. The confirmation message in
rule-authoring.md applies only when the user asked to add or edit a rule on its own.
Phase 6: Draft findings
Write $TMP/draft.json as {"findings": [...]} using the shape in
evidence-contract.md:
codeLocations[].snippetis copied verbatim from the inventory or the file atHEAD.resilienceTestingRecnames at least one fault from the rule'sspec.faultsand the probe signal.moduleis the inventory module path (.for the root).- Do not send severity or category; they come from the rule.
Phase 7: Validate
python3 "$SKILL_DIR/scripts/validate_evidence.py" --repo "$REPO" \
--rules "$TMP/rules.json" --findings "$TMP/draft.json" --out "$TMP/valid.json"Read dropped. Fix a finding only if the reason is a mistake you made (wrong line
range, missing fault name) and the code really shows the risk; otherwise leave it dropped.
Code marked harness-chaos-ignore: <rule> <reason> is suppressed on purpose; respect it.
Then run the coverage gate. It must exit 0 before you onboard or submit anything:
python3 "$SKILL_DIR/scripts/coverage.py" --repo "$REPO" --inventory "$TMP/inventory.json" \
--findings "$TMP/valid.json" --dispositions "$TMP/dispositions.json" --out "$TMP/coverage.json"Exit 1 means some actionable fact is neither reported nor cleared, or a disposition
cites an unacceptable reason or a missing mitigation line. Read uncovered and
badDispositions in coverage.json, open each file, then add a finding or a real
disposition and rerun. Do not edit a disposition to make it pass without a mitigation
you have read. If a finding was dropped by the validator, its facts become uncovered
again; fix the finding or clear the facts with a genuine mitigation.
Omit --dispositions when nothing was cleared. In diff mode the inventory only
holds changed files, so the gate checks only those.
Phase 8: Onboard each module that has a finding
Findings are stored only when a CodeRepository chaos service matches the repo URL and module. For each module that still has a valid finding, reuse or create that pair. Do not ask which service to use, and do not link a runtime discovered service.
Match the inventory repoURL and the module path. One custom service and one
chaos service cover every branch of that module. A different branch is a new
scan of the same service, not a new service. Do not put the branch in the
name, the identity, or the create body, and do not update an existing service
to store the current branch.
Compare repository URLs after normalizing both sides: lowercase, drop the scheme
(https://, http://, ssh://, git://), userinfo, a trailing slash, and a
.git suffix, then turn : into /. github.com/acme/payments matches
https://github.com/acme/payments.git. An empty module and "." are the same
module. Ignore any branch already stored on a custom service.
harness_list(resource_type="custom_service", filters={type: "CodeRepository"}). Reuse the service whose normalizedrepoURLand module match, even when its branch differs fromHEADor its identity contains a branch name. When more than one matches, reuse the one whose identity is the{repo}-{module}slug; otherwise reuse the oldest. Do not create another. Create only when none match:harness_create(resource_type="custom_service", confirm=true)withtype=CodeRepository,repo_urlset to the origin URL,moduleset to the inventory path,tags=["code-scan"],name{repo} {module}, andidentitya slug of{repo}-{module}(.becomesroot). Keep the returnedid. Do not sendbranch. If a create fails because the identity is too long, shorten the slug from the end and say so. A duplicate identity means this service already exists: look it up and reuse it.harness_list(resource_type="chaos_service"). Reuse the service whoseexternalServiceIdis the custom service id from step 1, on every branch. Otherwiseharness_create(resource_type="chaos_service", confirm=true)with the same identity and name,agent_id=custom-discovery-agent,external_service_idset to the custom service id (not the slug),tags=["code-scan"], andprobes=[]. Omitenvironment_id,infrastructure_id,infrastructure_type, andlinked_discovered_service.- Remember
MODULE=<chaos service identity>for--link.
Create every missing custom service in one batch, then every missing chaos service in one batch.
If a create fails, leave that module's findings out of the submit and record the error. Continue with the other modules. A duplicate identity means the service already exists: look it up and reuse it.
Phase 9: Create the scan and submit
python3 "$SKILL_DIR/scripts/build_payload.py" scan --inventory "$TMP/inventory.json" \
[--link services/api=payments-api ...] --out "$TMP/scan.json"
python3 "$SKILL_DIR/scripts/build_payload.py" findings --findings "$TMP/valid.json" --out "$TMP/findings.json"Pass every remembered module as --link MODULE=CHAOS_SERVICE_IDENTITY. Omit a module
that has no chaos service; its findings are not stored.
scan.json stores both source.codeRepository.branch and commitSHA. Confirm
both are present before creating the scan. Omit branch only when HEAD is detached.
When scanMode is diff and validation kept no findings, still create the scan
and submit {"findings": []}. That records this commit as the next baseline so
the same diff is not read again. Do not do this for unchanged.
harness_create(resource_type="chaos_risk_scan", confirm=true, body=<scan.json>).harness_execute(resource_type="chaos_risk_scan", action="submit_findings", resource_id=<identity>, body=<findings.json>). The first successful submission completes the scan; submit once. Do not wait for a review.- If the response lists per-finding
errors, report them. If the call fails with "not accepting findings", the scan was already completed; create a new scan.
Phase 10: Summarise
Report the scan identity, branch, commit, scan mode (full, diff from
<baseCommit>, or unchanged), saved and failed counts, the findings table, any custom
services and chaos services created or reused, any catalog rules created, modules
left out because onboarding failed, and dropped findings with the reason. Add the
coverage line from coverage.py (actionable, covered, cleared) with each cleared
fact's reason and mitigation, and the baseline regression result (re-reported, fixed
in code, or none because no baseline existed). Then
explain how to verify each risk:
- A code-repository risk whose chaos service has a mapped discovered service gets an experiment recommendation for that workload and the rule's faults.
- A risk becomes Confirmed when an experiment runs against the linked service with a
probe whose rule details reference the rule identity, and the probe fails. Hand off to
chaos-experimentto build that experiment. - The scan report is available via
harness_execute(resource_type="chaos_risk_scan", action="report").
End with this offer, naming each code-repository chaos service from this run. Do not list agents, services, or probes, and do not call update:
You can attach the code-repository chaos service
<identity>to a discovered service so Harness can recommend experiments for these risks. Say if you want to do that.
Attach a discovered service (only when the user asks)
This is a separate turn. Wait until the user asks to attach. Then ask, and do not update until they have answered:
- Which code-repository chaos service, when this run produced more than one.
- Which workload. List
discovered_agent(skipcustom-discovery-agent), ask them to pick an agent, then listdiscovered_servicefor that agent and itsenvironmentIdentifierwithcompact: false. The environment is required; an empty environment looks the agent up as missing. Offer only records whoseidentityisnamespace:kind:nameand whose kind isDeployment,DaemonSet, orStatefulSet(for examplehce:Deployment:frontend). Show that identity, not just the name. A Kubernetes Service such ashce:Service:nginxcannot be an experiment target. When the user names a service ("nginx"), link the workload of that name (hce:Deployment:nginx, then StatefulSet, then DaemonSet). If the name match is only a Service, readspec.kubernetes.workloadson that record and link the discovered service whose identity is that workload'snamespace:kind:name. If no such workload exists, say so and do not link the Service. Keep the agent's identity, its environment, and the workload record'sid. - Which probes to associate. Ask whether to add any. If they do, list
chaos_probeand have them fill each required input. If they do not, keep the probes already on the service.
Then harness_get the chaos service and harness_update it with confirm: true.
The update replaces the record, so resend name, description, tags,
external_service_id, and agent_id (custom-discovery-agent) from the get.
agent_id stays custom-discovery-agent. Also send the discovered service's
infrastructure the same way a chaos service is created for that service: for a
Kubernetes discovery agent, environment_id is the agent's environmentIdentifier,
infrastructure_id is the agent's identity (bare, not environment-prefixed), and
infrastructure_type is KubernetesV2. Send probes as the full set (the
existing ones, plus any they just chose). Send
"environment_id": "<agent environment>",
"infrastructure_id": "<agent identity>",
"infrastructure_type": "KubernetesV2",
"linked_discovered_service": { "agent_id": "<agent identity>", "environment_id": "<agent environment>", "external_id": "<discovered service id>" }external_id is the workload record's id, not its name and not the Kubernetes
Service of the same name. After the update, harness_get the chaos service and
check linkedDiscoveredService.identity. It must be namespace:Deployment:name,
namespace:DaemonSet:name, or namespace:StatefulSet:name. If the kind is
Service, the wrong record was linked; find the workload and update again.
Report the chaos service identity, the workload identity, and the infrastructure
that were linked.
Examples
- "Scan this repo for resilience risks we can test with chaos" — inventory, onboard, submit. No questions.
- "Scan this feature branch" — full inventory when this branch has no previous scan. Reuse the custom service and chaos service for each module. Findings for module
apionfeature/retry-budgetland on the samepayments-apiservice asmain. - "Scan again, nothing new committed" — the newest scan of this branch already has this
commitSHA. Stop. Do not create a scan. - "Scan again after new commits on the same branch" — reuse those services and pass
--sincethe previous scan'scommitSHA. Only changed files are read. - "Run a chaos code scan and link
services/apito thepayments-apiservice" — Phase 9 uses that link and still onboards any other module that has findings. - "Why was my finding dropped?" — read
droppedinvalid.jsonand explain the reason. - "Add a rule for retries without backoff" — rule authoring only, and this one waits for confirmation.
- "Create a chaos experiment for these risks" — hand off to
chaos-experiment. - "Attach this code-repository service to a discovered service" — the attach section only. Ask for a Deployment, DaemonSet, or StatefulSet and for probes, then update.
Performance Notes
Follow this order. The Harness submit is a few seconds; the time is spent reading source.
- Same branch, same commit: stop. Do not inventory or create a scan.
- Same branch, different commit: pass
--sincethat scan'scommitSHA. Inventory reads only changed files. A branch with no previous scan is a full inventory. Either way, reuse the custom service and chaos service for each module. - Start inventory at
--max-per-kind 80. The script default is 40. Ifcountsshows a kind was truncated, re-run once with a higher cap before reading source. - One read per cited file, in a single batch. Decide every fact in that file from
that read. On a
diffscan, do not open a file the inventory did not cite. - List rules with
compact: false.harness_geta rule only whenspec.faultsis absent. - Create the missing custom services in one batch, then the chaos services in one batch. Submit findings once.
validate_evidence.py reads each file once at the commit via git show. A scan that
misses a risk the previous scan of that branch found erodes trust as much as a false
positive. Precision comes from verifying each fact and citing the mitigation, not from
dropping facts you did not check. coverage.py enforces this. At most 8 findings per
module and 100 per scan; the validator enforces both.
Troubleshooting
| Issue | Fix |
coverage.py exits 1 with uncovered facts | Open each fact's file. Report it, or add a disposition that cites a real mitigation line. "Low impact" and "not verified" are not allowed |
| Custom service exists for the same repo URL and module on another branch | Reuse that custom service and its chaos service. Do not create one for this branch. Branch and commit are stored on the scan |
coverage.py reports a bad disposition | The reason must be from the allowed list and mitigation must be an existing file and line at HEAD |
Baseline scan listed but harness_get returns 404 | It was deleted. Run a full scan and note that no baseline existed |
not a git work tree | Point --repo at the repository root |
| Baseline commit is not an ancestor of HEAD | Inventory falls back to a full scan. This happens after a rebase or on a branch with no previous scan |
the repository has no origin remote | Add an origin remote; risks are keyed by repo URL |
snippet does not match the file | Copy the snippet from the file at HEAD; check the line range covers it |
names none of the rule faults | Mention one of the rule's spec.faults in resilienceTestingRec |
rule ... is not in the fetched rule list | Re-fetch rules after creating one in Phase 5 |
| Rule create fails on identity | Identity must match ^code-[a-z0-9-]{3,60}$ and name a failure mode |
| Rule create fails on limit | A project allows 30 custom SourceCode rules; update an overlapping rule instead |
submit_findings returns 409 | The scan is no longer accepting findings; create a new scan |
chaosServiceIdentity not found | List chaos_service and use an existing identity, or leave the module unlinked |
| Mapped service gets no experiment recommendation | The link is a Kubernetes Service (namespace:Service:name). Re-attach the Deployment, DaemonSet, or StatefulSet whose identity is namespace:kind:name |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

