Skip to content

Latest commit

 

History

History
265 lines (214 loc) · 11.2 KB

File metadata and controls

265 lines (214 loc) · 11.2 KB

Configuration

codehelion scan reads an optional codehelion.toml from the scan root. codehelion config init writes a fully commented template with every key at its built-in default, and codehelion config show prints the effective configuration after files and defaults are resolved.

codehelion config init      # write codehelion.toml
codehelion config show      # what this run would use, and where it came from

Where the file is read from

codehelion.toml is read only from the scan root itself and is never inherited from a parent directory: a scan says which settings governed it and where they came from, and a file nobody named that sits above the tree being read is not that. --config <file> names one explicitly, wherever it lives.

Two settings are deliberately flags rather than configuration keys, because the file is discovered inside the tree being scanned: --untrusted, whose whole point is that its subject does not choose it, and --allow-execution, which would otherwise be granted by the code it is a permission over.

What to scan

# include = []                      # path globs to include; empty means every supported source file
# exclude = []                      # path globs to exclude from the include set
# min-clone-tokens = 20             # smallest clone reported, in tokens
# entropy-ratio-floor = 0.60        # below this normalized entropy, a group is degenerate repetition
# literal-normalization = "full"    # "preserve", "category" or "full"
# database = ".codehelion/audit.db" # local-database location
# jobs = 4                          # frontend read-and-lex workers; omit for automatic

jobs sets frontend read-and-lex worker threads only; clone grouping and report rendering remain serial. Omitted, the worker count follows host parallelism. The value in the template is an example, not the default.

Languages, and the one ambiguous extension

[languages]
# rust = true
# c = true
# cpp = true
# headers = "detect"                # grammar for a bare ".h": "detect", "c", "cpp"

.h is the one extension C and C++ share, and the grammar it is read with decides what the analysis can see inside it: a C++ header read as C recovers into shapes that declare nothing, which both hides its real duplication and invents duplication between class bodies.

detect counts the files whose extension is not in doubt and follows the majority. Where a tree has none — a header-only library — it reads the headers themselves for something only C++ spells, and one of them saying so settles the run. The choice is part of the run's build variant, so results read one way are never compared with results read the other.

Priority

[priority]                          # whole numbers, read as shares
# maintenance-risk = 2
# refactoring-ease = 1

Only the composition is settable. What a duplication costs to keep and what it costs to remove are questions about the code, and a setting that changed the answers would make two projects' reports incomparable. Every finding carries all three measures whatever these are set to; setting both to zero orders the report on clone confidence alone.

Suppression

The full set of policies is documented in Suppression. The keys:

[suppression]
# paths = []
# vendored-paths = [...]            # hidden by default; [] reads them like any other tree
# symbols = []                      # globs over the name of the enclosing unit
# clone-ids = []                    # stable clone-group ids (hex; a prefix needs at least 8 characters)
# generated-markers = ["@generated", "do not edit", "automatically generated", "auto-generated", "autogenerated"]
# test-paths = [...]
# test-code = "rank-down"
# split-pairs = "rank-down"
# width-family = "hide"

[suppression.boilerplate]
# trivial-body = "rank-down"
# forwarding = "hide"
# macro-repetition = "rank-down"
# guarded-dispatch = "hide"
# configured-answer = "hide"
# composed-answer = "hide"
# built-answer = "hide"

Setting a list key replaces its defaults rather than adding to them, which is why generated-markers names the built-in banners alongside a project's own.

Semantic rules

[semantic]
# disabled = ["sequence-pipeline-v1"]

Restricted Semantic rules are all enabled by default. Listing a stable rule id here disables it for this project without broadening the detector for everyone else.

Helper locations

[helpers]
# rust = "/opt/codehelion/codehelion-backend-rust"
# clang = "/opt/codehelion/codehelion-backend-clang"

Useful for hermetic CI or an installation outside PATH. These are read only from a configuration named with --config: this file is discovered inside the tree being scanned, and a repository must not get to choose which program a scan of it starts. In a file found at the scan root the section is ignored, with a note saying so; pass --helper rust=<path> or name the file with --config to pin a helper.

Resource ceilings

Every ceiling that fires is accounted for in the report.

[limits]
# max-file-bytes = 2097152          # larger files are skipped and counted
# parse-timeout-ms = 10000          # deterministic parse-work budget, not wall-clock time
# helper-timeout-ms = 300000        # Semantic helper response deadline
# posting-cap = 64                  # longest posting list that still enters pairing
# pair-budget = 1000000             # candidate pairs per pairing pass
# near-miss-delta = 0.05            # diagnostic band below the Type-3 gate
# near-miss-cap = 1000              # retained near misses per report
# sibling-candidate-budget = 50000
# sibling-per-group-cap = 8
# sibling-total-cap = 1000
# signature-sibling-candidate-budget = 50000
# signature-sibling-per-group-cap = 8
# signature-sibling-total-cap = 1000
# signature-sibling-max-units-per-signature = 8
# verification-budget = 1000000     # pairs sent to precise verification
# max-alignment-cells = 4000000     # dynamic-programming cells per alignment
# max-component = 1024              # largest set of related units compared as one piece

parse-timeout-ms is a deterministic work budget measured in compatibility milliseconds (256 input bytes per millisecond), not a wall-clock deadline: the same tree hits it in the same place on a fast machine and a slow one.

posting-cap and pair-budget override both modes at once. Left out, each mode keeps the default its own measurements picked — the modes pair different things, and their candidate counts differ by an order of magnitude on the same tree. Set them to bound a scan that is taking longer than you will wait; the report then states how many candidates the ceiling left unexamined.

signature-sibling-max-units-per-signature is a rarity threshold rather than a resource ceiling. A signature shared by much of a tree proposes work without proposing duplication, so it stops being evidence — see Limitations.

What a report says about the run before it

[report]
# churn-top = 100

How many of each run's highest-ranked groups are compared when saying what became of the work worth looking at. A total counts duplication rather than progress: closing a handful of groups out of thousands leaves it almost where it was, so the comparison is made over the top of each run.

Seams

A seam is a set of paths that implement the same semantics in more than one place. The ledger is written by hand and is the source of truth for codehelion seam and codehelion guard; nothing discovers or edits it. See Seam tracking.

[[seam]]
id = "frontend-c-cpp"
members = ["crates/codehelion-frontend-c/**", "crates/codehelion-frontend-cpp/**"]
note = "same semantics implemented twice across the two frontends"

members are globs over repository-relative paths, and a seam needs at least two of them. note is free text that nothing reads. Repeat the [[seam]] block for each seam.

The settings are a separate section, because TOML cannot spell one name as both an array of tables and a table.

[seam-tracking]
# breach-window = 20                # commits after an asymmetric change in which a fix counts as a breach
# history-limit = 2000              # newest commits read
# max-commit-size = 30              # commits touching more files than this are left out of coupling
# min-coupling = 0.60               # --suggest floor
# min-support = 3                   # --suggest floor
# suggest-depth = 2                 # leading path components --suggest counts co-change over

max-commit-size applies to the coupling figures alone, not to breach detection: a sweeping rename hands support to every pair it touched, but a large commit that broke a seam still broke it. history-limit is a ceiling on how much history is read rather than a guarantee of how much there is; --until <rev> fixes the other end of the range, which is what makes two generations' numbers comparable.

codehelion seam records what it measured into the local database described below, which is what a later report reads to set two generations beside each other. Which invocations record and which do not is on the seam-tracking page.

The local database

Each scan creates its persistent local audit database at .codehelion/audit.db by default, placed under the Git repository holding the scan root so that scanning a subdirectory reuses the repository's database rather than starting a new one; a scan root outside any repository holds its own. --db <path> overrides the location.

Add .codehelion/ to the repository's .gitignore. This database is not an expendable build cache: it is where the run history the reports and the churn summary are derived from lives.

Completed scans are stored there, and text, JSON and SARIF reports are exports from those snapshots. An unchanged tree reuses its compatible completed run; --no-reuse records a fresh one. What reuse saves is the recording half of a run, and -v prints the two halves separately, so how much it costs is measurable rather than guessed at.

codehelion cache status        # location, size, and what is in it
codehelion cache prune --force # apply the retention limits and compact
codehelion cache clear --force # permanently delete the local audit database

prune keeps the newest 20 standalone artifact analyses and the newest 20 comparisons of each kind unless --keep-artifacts and --keep-comparisons say otherwise. Both prune and clear delete retained history, so both require the explicit confirmation flag.

A database written under a different schema is never migrated. At the default path a run leaves that database exactly where it is, records into audit-v<schema>.db beside it, and says which file it used; a database named with --db is refused instead, since writing somewhere else would ignore the path that was asked for. codehelion doctor lists every audit database in the directory, which of them this build can open, and which one a run would take.

Nothing is lost that a fresh scan does not recreate. The audit database holds derived state, so a database an earlier build wrote costs the tree the runs it could have been compared against and nothing beyond that. Removing it is a decision left to the reader, since the file is as large as the one in use and only the reader knows whether an older build still opens it.