uzomuzo-oss copilot-learned-coding.instructions.md

Copilot instructions for future-architect/uzomuzo-oss, covering coding standards — learned from copilot reviews and pending copilot patterns.

Instructions file for GitHub Copilot

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add instructions/future-architect/uzomuzo-oss/copilot-learned-coding
Clone the repo
git clone --depth 1 https://github.com/future-architect/uzomuzo-oss

Made for: GitHub Copilot.

Per session 14,962 This file is loaded in full into every session.
When invoked 14,962 The same file — it is already loaded in full.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.14962 $0.14962
Opus 5 $0.07481 $0.07481
Sonnet 5 $0.02992 $0.02992
Haiku 4.5 $0.01496 $0.01496

Measured yesterday against content hash 4fd5de06d346, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

uzomuzo-oss copilot-learned-coding.instructions.md scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured yesterday.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

.github/instructions/copilot-learned-coding.instructions.md · 305 lines

How it starts

The opening of the file, as written. The whole thing — 305 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Coding Standards — Learned from Copilot Reviews

Rules extracted from recurring Copilot review patterns on coding-standards topics (naming, defensive coding, API consistency, CI workflows, output formatting, etc.).

  • Diff Content Filtering: When writing tools that analyze git diff output, always strip diff metadata lines (+++, ---, diff --git, @@) before pattern-matching on ^+ lines. Diff headers can trigger false positives.
  • Comment-Code Consistency: When changing implementation behavior (e.g., switching from three-dot to two-dot diff), update all comments and documentation that reference the old behavior in the same commit. Also verify that function/struct comments accurately describe the actual heuristic or mechanism — do not mention capabilities (e.g., detecting "true:") that the code does not implement. Comments that overstate behavior create false confidence in coverage.
  • Documentation Command Accuracy: When adding or updating shell commands in documentation (README, CONTRIBUTING, etc.), verify they work by checking the actual project structure. Use go build -o <binary> . (package target) instead of go build -o <binary> main.go (single file) for multi-file packages. Ensure version references match go.mod and CI configuration.
  • Markdown Link Validity: When adding or editing Markdown files under .github/ (templates, workflows, docs), use absolute paths from the repo root (e.g., /docs/development.md) for links to repo files, since relative paths resolve from the file's directory. Always verify that linked files actually exist before committing.
  • Nullable Field Documentation: When documenting a pointer or optional field, enumerate all conditions under which it can be nil/empty — not just the primary case. For example, a ForkSource field should note it is empty when IsFork is false and when the parent is private/inaccessible. Similarly, ensure the comment names the correct upstream API field (e.g., parent vs source) that the implementation actually uses.
  • Defensive Coding — Validate Early, Fail Clearly: When a constructor or factory function receives a required dependency (e.g., a service, client, or parser), validate it is non-nil and return a descriptive error rather than allowing a nil-pointer panic later. Similarly, when CLI flags are mutually exclusive, reject the invalid combination at the validation layer with a clear message instead of silently preferring one. When a data field is a collection (slice/array), emit all items in serialized output rather than silently taking only the first. When sniffing file formats, validate field values (not just key presence) — e.g., check bomFormat == "CycloneDX", not just that bomFormat exists.
  • File Type Detection — Use Exact Basename, Not Suffix: When detecting file types by name (e.g., go.mod), use filepath.Base(path) == "go.mod" instead of strings.HasSuffix(path, ".mod"). Suffix matching can misclassify unrelated files (e.g., deps.mod) and route them to the wrong parser. Similarly, when matching path segments (e.g., .github/workflows/), require a leading path separator (/.github/workflows/) to avoid false positives from paths where the segment is embedded (e.g., /tmp/not.github/workflows/).
  • Use Spec-Compliant Parsers for Standardized Formats: When parsing standardized file formats (CSV, RECORD, TSV), use the language's spec-compliant parser (e.g., encoding/csv) instead of naive strings.Split or similar. Naive splitting misparses quoted or escaped fields, producing silent data corruption.
  • Reject Flags That Silently Have No Effect: When a CLI flag only applies to a specific input mode (e.g., --sample for PURL list files), explicitly reject it with a clear error when the input is a different mode (e.g., go.mod or SBOM). Do not silently ignore the flag — users assume their flags take effect.
  • Deduplicate Inputs Before Batch API Calls: When accepting user-provided input lists (PURLs, URLs) that feed into batch API calls, deduplicate them while preserving first-seen order before processing. Duplicates cause redundant external calls, skew logging/counts, and waste resources.
  • Normalize User-Provided Enum Values: When accepting string values for format selectors, mode switches, or other enums from CLI flags, normalize with strings.TrimSpace(strings.ToLower(...)) before validation. Case-sensitive matching rejects common inputs like --format JSON or --format "json ".
  • Normalize Config Values Once Before Guard and Use: When a config-sourced value is validated (e.g., strings.TrimSpace(v) != "") and then used, assign the normalized result to a variable and use that variable for both the guard and subsequent operations (SetBaseURL, logging). Checking TrimSpace(v) in the guard but passing the original v to the consumer silently passes whitespace-padded values, producing invalid URLs or config entries.
  • Doc Comments Must Match Type-Level Constraints: When writing doc comments, ensure stated conditions are possible for the parameter types — do not document "nil" for non-pointer types (e.g., string, int), do not claim a knob controls APIs it does not actually affect, and do not name only a subset of the languages/contexts that use a shared constant. When test names or comment examples reference specific inputs, they must match the actual values under test. Comments that describe impossible states or overstate scope create false confidence and mislead future maintainers.
  • Match net/url Function to Semantic Context: When manipulating URL components, select the net/url function that matches the component's semantics — u.Hostname() (not u.Host) when only the hostname is needed (avoids including the port), url.PathUnescape/url.PathEscape (not url.QueryUnescape/url.QueryEscape) for URL path segments (avoids +-as-space misinterpretation). Mismatched functions silently corrupt values containing reserved characters like :, +, or @.
  • Enforce Access Constraints on All CI Trigger Paths: When a CI workflow guards against cross-repository or fork PRs on the pull_request trigger (e.g., head.repo.full_name == github.repository), enforce the same constraint in code paths reachable by other triggers (schedule, workflow_dispatch) that bypass the trigger-level guard. Unguarded paths can fire privileged operations (e.g., GraphQL mutations with a PAT) on fork PRs, causing auth failures or unintended side effects. Similarly, use generous page sizes (e.g., first:100 instead of first:20) in paginated API verification queries to avoid false negatives that trigger unnecessary retries.
  • Interface Contract Documentation Must Match Signature Semantics: When documenting an interface method, the doc comment must accurately reflect the method's full signature — including error returns, nil semantics, and parameter constraints. If the signature returns (T, error), do not document it as "returns nil/empty on failure" — state that errors may be returned and describe the caller's expected handling (e.g., non-fatal/graceful degradation). Mismatched contract documentation misleads implementers and callers.
  • GitHub Actions || Treats Empty as Falsy: When a workflow input documents "empty = X behavior", do not use ${{ inputs.foo || 'default' }} — the || operator treats empty string as falsy and applies the default, preventing users from intentionally selecting the empty option. Instead, pass the raw input via an env var and apply defaults conditionally (e.g., only for scheduled triggers).
  • Guard Downstream Jobs Against Missing Outputs: When a CI job produces outputs that downstream jobs depend on (exit codes, flags), gate downstream jobs on needs.<job>.outputs.<key> != '' to prevent execution when the upstream job fails before setting outputs. Otherwise, empty values may be misinterpreted (e.g., empty exit code "" compared with != "0" evaluates to true, creating misleading reports).
  • Use Quoted Heredocs for Literal Text in CI Workflows: When constructing multi-line literal text bodies in CI workflow scripts (e.g., comment bodies, PR descriptions), use quoted heredoc delimiters (<<'DELIM') to prevent accidental parameter expansion and command substitution. Inject dynamic values (markers, timestamps) via append after the heredoc rather than embedding them inside an expansion-enabled body.
  • CI Job Gating — Key on Outputs, Not Job Result: When a CI job intentionally exits non-zero for a primary use case (e.g., policy violations), downstream jobs must not gate on needs.<job>.result == 'success'. Use explicit output variables (exit codes, flags) to control downstream behavior, so jobs run in the scenarios they are designed for.
  • Remove Dead Configuration Inputs: When a configuration surface (CLI flag, workflow input, env var) is no longer honored by the implementation (e.g., hardcoded internally), remove it entirely rather than leaving a misleading interface. A visible input that silently does nothing is worse than no input at all.
  • CI Permissions Documentation — Verify Inheritance: When documenting GitHub Actions job permissions, verify each job's actual permissions: block in the workflow file. Jobs without an explicit permissions: key inherit the workflow-level permissions — do not describe them as having "no permissions" or "no extra permissions". State what each job actually has, including inherited defaults.
  • Attribute Control Claims to the Correct Mechanism: When a comment asserts that a specific configuration, permission, or flag is "required for" or "controls" a behavior, verify the claim against the actual code path. Do not attribute behavior to a nearby-but-uninvolved mechanism (e.g., claiming permissions: block is "required for" gh commands when a PAT env var provides the effective auth; claiming a config field controls retries for an API where a different mechanism governs the retry decision). Misattributed control claims cause maintainers to debug or tune the wrong component.
  • Lazy I/O During Format Detection: When probing a file's format, prefer path-based checks first, then read only a small prefix for content-based heuristics. Read the full file only after confirming the format to avoid wasted I/O on non-matching files (e.g., reading an entire docker-compose.yml just to check if it's a GitHub Actions workflow).
  • Deterministic Output from Non-Deterministic Sources: When building ordered output from non-deterministic sources (Go map iteration, goroutine-collected results, API directory listings), sort the data before further processing. This applies to rendered text, BFS seed queues, and any "first-seen wins" algorithm where input order determines provenance.
  • Post-Filter Fuzzy Search Results: When using search APIs that perform fuzzy or word-level matching (e.g., GitHub issue search), add a post-filter to verify exact matches before acting on results. Fuzzy matches can cause false-positive deduplication or incorrect state transitions.
  • Rerun Analyzers with Combined Input Sets on Retry: When retrying a subset of inputs through an analyzer that tracks collisions or shared matches, rerun with the combined input set (original + retry) to preserve attribution consistency. Subset reruns can misattribute shared matches to the wrong source.
  • Guard Resource Bounds in HTTP Client Retry Logic: When implementing retry/backoff logic for HTTP clients: (1) guard time.Duration arithmetic against integer overflow — use strconv.ParseInt and reject values exceeding math.MaxInt64/time.Second rather than clamping to an arbitrary policy constant; (2) cap response body reads with io.LimitReader in retry paths (429/5xx) to prevent unbounded memory and log growth across retry attempts; (3) use time.NewTimer + Stop/drain instead of time.After in select with ctx.Done() to prevent timer accumulation during long cancellable waits.
  • Consolidate Detection Heuristics — Single Source of Truth: When a detection heuristic (file type sniffing, format detection, path matching) is used in multiple locations, centralize it in the responsible package and have callers delegate. Duplicating the heuristic across layers (e.g., cmd/ and infrastructure/) risks drift when one copy is updated but the other is not.
  • Use Correct GitHub API Media Types: When calling GitHub REST APIs, use the documented Accept header for the desired response format. For raw file content use application/vnd.github.raw (not application/vnd.github.raw+json). Incorrect media types may cause silent content-negotiation failures or unexpected response formats. Refer to GitHub's REST API media type documentation before adding a new endpoint call.
  • Narrow Typed Error Matching to Specific Conditions: When checking typed errors (e.g., IsResourceNotFoundError), verify the error's message or context matches the expected source — not just the error type. A single error type can be returned by multiple code paths with different semantics (e.g., "repo not found" vs "no package managers"), and a broad type check can trigger incorrect fallback behavior for unrelated error origins.
  • ADR and Documentation Must Describe Actual Behavior: When writing ADRs or design documents alongside implementation, verify that documented output formats, UI behavior, and feature descriptions match what the code actually produces. Do not document aspirational behavior (e.g., "source is embedded in per-entry headers") when the implementation has known limitations (e.g., only the summary table shows source). Document the current state accurately and note planned improvements separately.
  • Consistent Conditional Columns Across Output Formats: When a column or field is conditionally shown in one output format (e.g., table omits RELATION when all entries are Unknown), apply the same conditional logic to all other formats (CSV, JSON). Unconditionally including a column in one format while conditionally hiding it in another creates inconsistent API surfaces and confuses downstream consumers.
  • Nil vs Empty Map Semantics for Sentinel-Checked Maps: When a function returns a map that callers check for nil as a sentinel (e.g., "no data available" vs "data resolved but empty"), return nil when the resolved set is empty rather than an empty non-nil map. An empty non-nil map can cause callers to misinterpret "no results found" as "all items excluded", leading to incorrect classification or silent data loss.
  • Normalize Repo-Scoped Paths with path.Clean: When accepting user- or YAML-supplied paths that are scoped within a repository (e.g., local action ./ references), normalize with path.Clean (not filepath.Clean) and reject results that equal "." or start with "..". Also reject backslashes. This prevents traversal beyond the repository root via the Contents API without blocking valid intra-repo .. segments (e.g., ./foo/../barbar).
  • Preserve Original Input Through Heuristic Fallback Chains: In chained heuristic pipelines where each step transforms an intermediate result, fallback on empty must return the original input — not the intermediate value from a prior step. Returning an intermediate value violates the documented contract and can produce silently incorrect results when later steps depend on the untransformed original.
  • Accurate Error Map Keys: When recording errors in a map[string]error keyed by file path, use the actual resolved path — not a hardcoded filename. If a fetch tries action.yml then falls back to action.yaml, the error key must reflect which file was attempted, or use the parent path without a filename assumption.
  • Exported API Must Not Leak Unexported Types: When an exported function or method returns (or accepts) an unexported type, it creates an API that other packages cannot use. Either export the type, unexport the function if all callers are package-internal, or use an exported interface/struct. Similarly, when a JSON struct tag uses omitempty on a boolean or always-present slice field, the serialized output becomes ambiguous (absent vs false/empty) for downstream consumers — omit omitempty for fields whose zero value is semantically meaningful.
  • Handle All Valid Input Forms in Format Parsers: When parsing a structured format (ZIP entries, RECORD files, manifests), handle all valid representations defined by the spec — not just the common case. For example, Python wheel RECORD files contain both package directories (pkg/__init__.py) and root-level modules (six.py); skipping root-level entries silently drops valid import names for single-module packages.
  • Explicit Fallback for Unknown Enum Values: When mapping external values (API responses, YAML fields) to internal enums or display strings, map unrecognized values to an explicit fallback (e.g., "unknown(X)") rather than silently defaulting to a valid enum member. Silent defaults hide data quality issues and make debugging harder.
  • Enforce HTTP Client Hardening on All Code Paths: When constructing an HTTP client with security hardening (redirect policies, SSRF guards, timeout caps), ensure the hardening applies uniformly — including on test-injected clients and across all status-code branches. Specifically: (1) when a constructor accepts an injected *http.Client, set missing security callbacks (e.g., CheckRedirect) to the hardened default rather than relying on callers to attach them manually; (2) classify retryable HTTP statuses (408 Request Timeout, 429 Too Many Requests) as transient alongside 5xx — do not negative-cache them as authoritative failures; (3) verify redirect-counting logic against net/http's via slice semantics where len(via) counts prior requests, so len(via) > maxRedirects allows exactly N hops while len(via) >= maxRedirects allows only N-1.
  • Machine-Readable Columns Must Contain Single Values: When adding columns to machine-readable output (CSV, JSON), each column must contain exactly one data type — do not combine a label and a number in a single field (e.g., "HIGH (7.5)"). Split compound values into separate columns (e.g., max_advisory_severity + max_cvss3_score). Mixed-format cells break downstream parsing and sorting.
  • Use Domain Constants for Domain-Defined String Values: When display or mapping logic switches on string values that are defined as domain constants (e.g., LicenseSource*), reference the constants — not duplicated raw strings. Duplicating values causes silent drift when constants are renamed or new values are added.
  • Branch Output Display on Each Field's Own Availability: When rendering output fields (CLI text, CSV, JSON), branch display logic on each field's own availability — do not couple display of one field to the presence of an unrelated field. Ensure all output formats use the same data-source fallback chain as domain logic. Use host-agnostic labels (e.g., Repository: not GitHub:) unless the host is confirmed, and render all populated data fields rather than silently dropping them.
  • Use utf8.RuneCountInString for Terminal Display Widths: When computing string widths for terminal display (box drawing, alignment), use utf8.RuneCountInString — not len — to avoid incorrect sizing with multi-byte characters (box-drawing glyphs, emoji). Clamp computed padding to zero when content already exceeds the budget rather than forcing a minimum that widens output beyond the declared width.
  • Filter and Normalize IDs Before Batch API Calls: When building batch API requests from collected IDs, filter empty/whitespace values and deduplicate before processing to prevent invalid HTTP requests and cache pollution. Use select on ctx.Done() alongside channel operations in batch goroutines to avoid blocking after context cancellation.
  • Respect Context Lifecycle in Concurrent and Delegated I/O: (1) When a function issues I/O (HTTP, database, external API) on behalf of a caller that provides a context.Context, thread that context through every intermediate function in the call chain — never substitute context.Background() at an internal callsite. context.Background() ignores the caller's cancellation and deadline signals, causing orphaned requests that persist after cancellation or exceed timeout budgets. (2) When dispatching goroutines under bounded concurrency, acquire the semaphore before launching the goroutine (not inside it) and select on ctx.Done() alongside the semaphore send to stop dispatch on cancellation — this avoids spawning parked goroutines that outlive the context.
  • Guard Nil Structs Consistently Across Output Formats: When a struct field may be nil (e.g., ReleaseInfo), apply the nil guard in every output renderer that accesses it (text, CSV, JSON). If one renderer has the guard and another does not, the unguarded path will panic on nil input.
  • Gate Fallback Logic on Error, Not Result Nilness: When deciding whether to trigger fallback or retry logic, check the error value — not whether the result is nil. A nil result with nil error is a valid success case (e.g., zero matches found), and treating it as a failure triggers unnecessary retries or incorrect fallback paths.
  • Use Dedicated Predicates and Full Renderers for Sentinel/Composed Values: When a domain type uses sentinel values (e.g., NOASSERTION), use dedicated predicate methods (e.g., IsUsableSPDX()) in all guard checks — not ad-hoc field comparisons that miss sentinel states. Canonicalize sentinels before rendering compound expressions (parser leaf fields may preserve non-canonical casing). When a type has a renderer composing sub-components (e.g., ExprLicense.String() includes Identifier + OrLater + WITH exception), use the renderer — not a single field — for the full representation. When recording provenance in multi-branch resolution functions, set evidence fields to the input that actually produced the match, not a prior failed branch's input.
  • Minimize Allocations in Hot Paths: In batch-processing or frequently-called functions, avoid unnecessary O(n) allocations when only a subset of data is needed. Cache results of expensive parsing calls when the same value is checked multiple times in a loop iteration, and iterate to a known cutoff point rather than materializing the full collection (e.g., iterate runes up to a count rather than converting the entire string to []rune).
  • Use Structured Parsers for Structured Identifier Properties: When checking properties of structured identifiers (PURLs, URIs, import paths), use the appropriate parser rather than naive string operations (strings.Contains, strings.Split). For example, strings.Contains(purl, "@") misclassifies npm scoped packages like pkg:npm/@scope/name as versioned because @ appears in the namespace. Use packageurl.FromString(p).Version != "" or an equivalent parser-based check.
  • Use u.Hostname() for Port-Safe Host Comparison: When comparing URL hostnames, use u.Hostname() instead of u.Host. The Host field includes the port component (e.g., github.com:443), so direct string comparison against a bare hostname fails silently, misclassifying URLs and triggering unnecessary fallback processing. Similarly, when parsing multi-entry go-import/go-source meta tags, select the entry whose import prefix most specifically matches the requested path per the Go module spec — blindly taking the first match can resolve to the wrong repository on monorepo vanity pages.
  • Use Case-Insensitive Comparison for URL Components: When comparing URL components (scheme, host), use case-insensitive comparison per RFC 3986 — schemes (HTTP://) and hosts (GitHub.COM) are case-insensitive. Normalize with strings.ToLower or strings.EqualFold before prefix checks or host matching to avoid double-prefixing or missed matches.
  • Structured Logging Conventions: When adding slog calls: use DEBUG level for routine per-item telemetry (reserve INFO for exceptional events); use snake_case for event names (not spaces) for consistency and filterability; choose field key names that accurately describe the data across all call sites (e.g., "ref" not "purl" when the function handles both PURLs and URLs).
  • Match Validation Format Strings to Production Format Strings: When a validation or check function mirrors a production function's output (e.g., marker validation vs. marker replacement), use the exact same format strings and delimiters. Mismatched formats allow invalid input to pass validation silently.
  • CI Steps Must Stage All Script Outputs: When a CI step checks for changes and stages files after running a script, include all files the script can produce — not just the commonly changed subset. If the script's output file list is defined in a config (e.g., commands.json), derive the staging paths from that config or use a broad git diff --quiet check. Silently dropping outputs leads to dirty workspaces or missed commits.
  • CI Workflow Steps Must Use Dynamic Refs: When a CI workflow step references a branch name (e.g., --base main in gh pr create), use the workflow's actual ref context (e.g., ${{ github.ref_name }}) instead of hardcoding a branch name. Hardcoded refs produce unexpected behavior when the workflow is triggered from a non-default branch.
  • Output Column Header Must Match Rendered Data: When rendering tabular or structured output, verify that each column header/label corresponds to the actual data field being printed — not a related but different field (e.g., printing Name under a "PURL" header). Review header-to-value correspondence in the same pass as adding columns.
  • Unique Map Keys for Multi-Value Sentinels: When using sentinel keys in a map to track special-case entries (e.g., blank imports, dot imports), ensure each entry gets a unique key (e.g., sentinel prefix + distinguishing suffix like the import path). Shared sentinel keys cause later entries to silently overwrite earlier ones, losing data.
  • Use Framework-Provided Parsed Arguments for Subprocess Delegation: When delegating to a subprocess from a CLI framework handler, use the framework's parsed argument accessors (e.g., cmd.Args().Slice()) instead of the process-global os.Args. Global args may not match the framework's routing and break when the CLI is invoked programmatically.
  • Classify from Raw Values Before Rounding: When deriving a category or label from a computed numeric value (e.g., score → difficulty bucket), apply the classification logic to the raw value before any rounding. Rounding first can push boundary values into the wrong bucket.
  • Match Write Guard Quantifiers to Write Semantics: When a conditional guard protects a field write, the guard's effective quantifier (any/all/only) must match the write's semantic claim. An "any item has X" flag (e.g., hasNoAssertion) guarding a branch that writes Expression="NOASSERTION" claiming "only X inputs present" will silently misrepresent mixed inputs. Similarly, when a replacement guard checks for presence of any high-quality entry, verify the replacement is a net improvement — "has any SPDX" does not guarantee "strictly higher quality" when non-standard entries are also present.
  • Validate Generated Strings Against Target-Language Syntax: When programmatically generating identifiers, import paths, or package names for a target language, validate each candidate against that language's syntax rules before emitting it. Validation must cover the full identifier grammar — not just invalid characters but also positional rules (e.g., Java identifiers cannot start with a digit) and compound structures (e.g., dot-separated package names must validate each segment independently). For example, Maven artifactIds often contain hyphens (commons-lang3) and groupIds can too (commons-io), which are invalid in Java package names — emitting them verbatim produces candidates that can never match real imports. Similarly, error hints and suggestions must use terminology appropriate to the detected language/ecosystem, not hardcode references to a single ecosystem (e.g., go.mod) when the tool supports multiple languages.
  • Collect All Matches in Collector Functions — No Early Return: When a function iterates over children/items to collect all matching results (e.g., AST bindings, search hits), append each match to a slice and return the slice after the loop. Do not return on the first match — early return drops remaining items. This applies whenever the caller needs all matches, not just the first.
  • Continue AST Ancestor Walks Past Non-Matching Nodes: When walking AST ancestors to find a guarding condition (e.g., if TYPE_CHECKING: blocks), continue past intermediate nodes of the same type that don't match the target condition. Returning early on the first type match (e.g., the first if_statement) misses the actual guard when the import is nested inside inner conditionals.
  • Normalize Map Keys Consistently Across Insert and Lookup: When building a map[string]T with normalized keys (e.g., strings.ToLower at insertion), apply the same normalization at every lookup site. A mismatch causes silent lookup failures for inputs with non-canonical casing (e.g., mixed-case Python module names like OpenSSL). Audit all functions that query the map, not just the one you're currently editing.
  • Sanitize Dynamic Content in GitHub Actions Workflow Commands: When embedding dynamic content (shell variables, step outputs) into GitHub Actions workflow commands (::warning::, ::error::, ::set-output::), sanitize multi-line content and :: sequences first — they break command parsing and can inject accidental workflow commands. Emit a short single-line summary and log the full payload separately.
  • Populate Sentinel Error Fields on Graceful Skip Paths: When short-circuiting a function that returns a result struct whose Error field is inspected downstream as a sentinel (e.g., batch assembly "mark not found" logic), populate the Error field even on graceful skip paths. A zero-value struct with nil Error breaks sentinel checks and silently omits the entry from result maps.
  • Use Ecosystem-Neutral Language in Multi-Language Error Messages: When a CLI tool supports multiple ecosystems, error hints and suggestions must not reference language-specific files (e.g., go.mod) unless the current context is confirmed to be that language. Generic messages like "dependency manifest not found" are safer than ecosystem-specific ones.
  • Extract Shared Helpers for Near-Duplicate Code Paths: When two functions follow the same sequence (e.g., parse input → call external API → interpret result → populate output) differing only in how one parameter is obtained, extract the shared sequence into a single helper parameterized on that value. Near-duplicate paths drift silently when logging, error handling, or evidence formatting is updated in one copy but not the other.
  • Narrow Candidate Heuristics and Map Assertions to Specific Items: When generating candidate values (import paths, match keys) from heuristics, validate each candidate against its target domain to avoid false-positive attribution from overly broad matching. Similarly, when asserting on map[K]V results, check the specific key under test (paths := m[key]; len(paths) == 0) — not the whole map (len(m) == 0), which only confirms any key has data without verifying the key you care about.
  • Narrow Heuristic Candidate Sets to Avoid False Attribution: When building candidate lists for matching (e.g., import-path heuristics, file-type detection), prefer precise patterns over broad substring matching. An overly broad heuristic (e.g., taking only the last segment after a delimiter) can collide with unrelated entries and cause false attribution (e.g., marking an unrelated dependency as "used"). Add validation or specificity constraints to each candidate before insertion.
  • Verify Tree-Sitter Query Patterns Do Not Overlap: When adding new tree-sitter (or similar AST) query patterns to a multi-pattern query, verify that the new pattern does not match nodes already captured by an existing pattern via parent-child nesting. For example, a standalone member_expression pattern already matches the inner pkg.Foo node inside new pkg.Foo(), so adding a new_expression wrapping member_expression pattern would double-count the same call site. Test with representative code that exercises both the new and existing patterns.
  • Constrain Tree-Sitter Queries with Predicates for Framework-Specific Patterns: When adding tree-sitter query patterns that target framework-specific AST shapes (e.g., Angular decorators, Vue component registrations), use #eq? or #match? predicates to constrain matches to the intended decorator names, function names, and property keys. Unconstrained structural patterns (e.g., "any decorator with an array argument") match far more broadly than intended and introduce false-positive call sites from unrelated code that happens to share the same AST shape. Always verify that FilterPredicates is called in the match loop so predicates are actually applied, and use dedicated capture names for predicate-only captures (e.g., @decorator, @metaKey) that are excluded from counting logic.

Read the full file on GitHub · 305 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. yesterday First seen · 305 lines · 14,962 tokens per session scan A 4fd5de06d346

Subscribe to this mod's changes

uzomuzo-oss copilot-learned-coding.instructions.md is an instructions file published in the GitHub repository future-architect/uzomuzo-oss (32 stars, last pushed yesterday), licensed Apache-2.0. It adds 14,962 tokens to every session, about $0.0748 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-01.