adamant-style
Skill4 starsChanged 3 months agoApache-2.0View on GitHub
Adamant code style rules enforced by `admt style` (wraps `redo style`). Use when writing or reviewing Ada, YAML, or Python in any Adamant project, fixing style warnings, or aligning generated code with project conventions.
In this repository27 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- adamant-assembly-devSkill
- adamant-build-systemSkill
- adamant-code-reviewSkill
- adamant-component-devSkill
- adamant-cosmos-integrationSkill
- adamant-cosmos-suite-resultsSkill
- adamant-cosmos-testingSkill
- adamant-cosmos-tool-creationSkill
- adamant-debuggingSkill
- adamant-formal-verificationSkill
- adamant-framework-componentsSkill
- adamant-framework-internalsSkill
- adamant-generator-devSkill
- adamant-project-setupSkill
- adamant-regression-suiteSkill
- adamant-skill-campaignSkill
- adamant-skill-creationSkill
- adamant-skill-selectorSkill
- adamant-subassembliesSkill
- adamant-testingSkill
- adamant-toolsSkill
- adamant-type-systemSkill
- high-assurance-designSkill
- knowledge-acquisitionSkill
- task-planningSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
27 rules. About 0 are common, 8 are distinctive, and 19 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
19
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 48
NOT enforced: c (comment formatting), m/M (max line length), s (separate specs).
- Very specific: line 86
Always use
or else: instead of or for boolean expressions (-gnatyB) - Very specific: line 87
Always use
and then: instead of and for boolean expressions - Very specific: line 97
thenon its own line: when condition spans multiple lines (-gnatyi) - Very specific: line 150
Avoid when others on enumeration case statements for the same reason: it re-opens the silent-absorption hole that case exists to close.
- Very specific: line 184
No redundant
use: if already visible through base class (-gnatwr) - Distinctive: line 201
Prefer a constant to a function that returns a constant expression, and a nested expression function to a body-level one.
- Very specific: line 202
Prefer the narrowest type: a range or modular type sized to the value, an enumeration over an integer code, and the packed .T when the …
- Very specific: line 244
Based literals: Use 16#...# for hex
- Very specific: line 246
Box default
<>: Use in aggregates when default initialization is appropriate. - Distinctive: line 251
When a procedure or function signature is too long to fit on a single line, format it with:
- Very specific: line 282
Only mark an object aliased when you actually take 'Access of it.
- Distinctive: line 309
Use traditional function body for anything complex or multi-line.
- Distinctive: line 313
Use sparingly, primarily for shortening deeply qualified names:
- Distinctive: line 345
If access types are necessary, document the justification.
- Very specific: line 349
Document start marker required: Every .yaml file must begin with ---
- Very specific: line 368
with:is ONLY for preamble code visibility: Do not put connector types or framework types here. - Very specific: line 394
Must have # noqa: F401 to suppress unused import warning
- Distinctive: line 395
Must have exactly one trailing newline
- Very specific: line 488
Unused
CountfromDispatch_All: Use Natural_Assert.Eq (T.Dispatch_All, N) directly, or suppress with pragma Warnings (Off, "variable … - Very specific: line 496
use Command_Execution_Status;: If removed, return Success. - Very specific: line 498
Rule: Before removing ANY with, grep the body for types/operators/procedures from that package
- Very specific: line 506
Record aggregate with
[]: Only arrays use [] - Very specific: line 509
Assigned-but-never-read variables: Use pragma Warnings (Off, Var).
- Distinctive: line 511
Wrong indentation: Must be exactly 3 spaces per level
- Very specific: line 512
Statements on
then/elseline: Must be on separate line (-gnatyS) - Distinctive: line 544
ALL style warnings are fixable.
≈ “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
Adamant Style Guide
admt style enforces Ada compiler warnings, YAML lint, Python flake8, and codespell. All code must pass.
Running Style Checks
admt style # Current directory (redo style)
admt style --all # Recursive (redo style_all)
```ada
Style logs written to `build/style/style.log` per directory.
## Ada Style Flags (Actual)
The enforced flags are `-gnaty3aABbdDefhiklL12nOprStux`:
| Flag | Rule |
|------|------|
| `3` | Indentation of 3 spaces |
| `a` | Attribute casing must match RM |
| `A` | Multi-dimensional `'Length` must specify index |
| `B` | Short-circuit operators required for booleans |
| `b` | No trailing blanks |
| `d` | No DOS line endings (CR+LF) |
| `D` | Identifiers in mixed case |
| `e` | Labels required on `end` statements |
| `f` | No form feeds or vertical tabs |
| `h` | No horizontal tabs |
| `i` | If-then layout (multi-line `then` placement) |
| `k` | Keywords must be lower case |
| `l` | Layout per Ada RM |
| `L12` | Max nesting level of 12 |
| `n` | Standard casing must match RM |
| `O` | `overriding` keyword required |
| `p` | Pragma casing |
| `r` | Reference casing must match declaration |
| `S` | No statements on same line as `then`/`else` |
| `t` | Token spacing (space before parens, around operators) |
| `u` | No unnecessary blank lines |
| `x` | No unnecessary parentheses |
NOT enforced: `c` (comment formatting), `m`/`M` (max line length), `s` (separate specs).
## Ada Whitespace Rules
- **3-space indentation** (`-gnaty3`): Not 2, not 4
- **No trailing whitespace** on any line (`-gnatyb`)
- **No multiple blank lines** in sequence (`-gnatyu`)
- **No tabs** (`-gnatyh`): Spaces only
- **No DOS line endings** (`-gnatyd`): Unix LF only
- **No form feeds or vertical tabs** (`-gnatyf`)
- **Space required before `(`** in type conversions and function calls (`-gnatyt`)
```ada
-- WRONG: Unsigned_32(Value)
-- RIGHT: Unsigned_32 (Value)- Space around binary operators:
A + B,2 ** 16, notA+B,2**16 - No space after
(or before):Foo (X, Y)notFoo ( X, Y ) - No unnecessary parentheses (
-gnatyx):return X;notreturn (X); - Use Ada 2022
@syntax for self-referencing assignments:-- CORRECT: Self.Counter := @ + 1; Self.Buffer_Index := @ + Data'Length; -- WRONG: Self.Counter := Self.Counter + 1;
Ada Naming and Casing
- Identifiers in mixed case (
-gnatyD):My_VariablenotMY_VARIABLEormyvariable - Match declaration casing exactly (
-gnatyr): If declaredHeartbeat_OK, neverHeartbeat_Ok - Keywords lower case (
-gnatyk):begin,end,if, neverBEGIN,If - Attribute casing (
-gnatya):'Length,'Range,'First(RM standard) - Standard casing (
-gnatyn):Integer,Boolean,Naturalper RM - Pragma casing (
-gnatyp):pragma Unreferenced, notpragma UNREFERENCED
Short-Circuit Operators (CRITICAL)
- Always use
or elseinstead oforfor boolean expressions (-gnatyB) - Always use
and theninstead ofandfor boolean expressions - Bitwise
or/andon integer types are fine (they're not boolean)-- WRONG: if A > 0 or B > 0 then -- RIGHT: if A > 0 or else B > 0 then -- OK: Mask := Mask or 16#FF#; (bitwise, not boolean)
Control Flow Layout
thenon its own line when condition spans multiple lines (-gnatyi)-- WRONG: if Self.Enabled and then Self.Count > Threshold then -- RIGHT: if Self.Enabled and then Self.Count > Threshold then- No statements on same line as
then/else(-gnatyS)-- WRONG: if X then return; end if; -- RIGHT: if X then return; end if; - Labels on
endstatements (-gnatye):end My_Proc;not bareend;for named blocks - Max nesting depth 12 (
-gnatyL12): Refactor deeply nested code null;required in empty blocks: Cannot leave only a comment in an if/else/loop body
Case Statements Over If/Elsif Chains
Prefer case over an if/elsif chain when dispatching on an enumeration (or any
discrete value with static alternatives). A case statement is compiler-checked for totality:
when a literal is added later, every unhandled case fails to compile, where an if/elsif
chain falls silently into its else. This matters doubly for Adamant enumeration types
(Package.Enum_Name.E) because models grow literals over time, and it is the pattern agents
most often get wrong -- an elsif chain of equality tests against enum literals should be a
case.
-- WRONG: silently absorbs a future literal into the else arm.
if Status = Success then
...
elsif Status = Stale then
...
else
...
end if;
-- RIGHT: adding a literal to the status enum breaks this statement until handled.
case Status is
when Success =>
...
when Stale =>
...
when Not_Available | Error =>
...
end case;Avoid when others on enumeration case statements for the same reason: it re-opens the
silent-absorption hole that case exists to close. Enumerate the literals (grouping
alternatives with | where they share an arm) unless the type is genuinely open-ended at
this site.
An if/elsif chain is correct where case is not legal. Case choices must be static
(Ada RM 5.4), so matching a value against non-static comparands -- configured limits,
stored identifiers, record components -- has no case form and the chain is the right tool.
In that shape, have the classifier return an enumeration decision and let every caller
case over it, so compiler-checked totality resumes at the dispatch site (and, for a proved
logic package, contract equivalences can carry the disjointness the compiler cannot see).
Array Aggregates (Ada 2022)
- Use
[]not()for array aggregates (-gnatwj) - Record aggregates MUST use
()-- only arrays use[]Buffer := [others => 0]; -- RIGHT (array) Buffer := (others => 0); -- WRONG (obsolescent) Rec := (Field_A => 1, Field_B => 2); -- RIGHT (record) Arr := [others => (others => <>)]; -- RIGHT: outer [] (array), inner () (record)
Multi-Dimensional Array 'Length (-gnatyA)
-- WRONG: Buffer'Length
-- RIGHT: Buffer'Length (1) -- must specify dimension index
```ada
## With-Clauses and Visibility
- **Only `with` packages you actually reference** (`-gnatwu`)
- **No redundant `with`** in body if spec already has it (`-gnatwr`)
- **No redundant `use`** if already visible through base class (`-gnatwr`)
- Move `with` to body if only the body references it
- **`overriding` keyword required** on overriding declarations (`-gnatyO`)
### `use Interfaces` Redundancy Rule
Components with commands, init params, or data dependencies get `with Interfaces; use Interfaces;` in their generated base class. Adding it again in the implementation spec triggers `-gnatwr`. Simple tick-only components do NOT get it automatically and need it explicitly.
## Scope Everything To The Smallest Unit Possible
Let the compiler work for you. Declare each entity in the smallest region that needs it, so a misuse is a compile error instead of a review comment.
- A helper subprogram with a single caller is declared inside that caller, before its `begin`, not at package level.
- A helper with several callers is declared immediately above the first subprogram that uses it, not collected at the top of the body.
- Types, constants, and variables used by one subprogram live in that subprogram's declarative part. Put state in the component `Instance` record only when it must persist between calls.
- `use Package;` and `use type` go inside the one subprogram that needs them. Move them to body level only when several subprograms need them, and never to hide where calls into a package come from. Qualify the call instead.
- Component helpers shared by several handlers are primitives declared in the private part of the implementation spec and called through `Self`.
- Prefer a constant to a function that returns a constant expression, and a nested expression function to a body-level one.
- Prefer the narrowest type: a range or modular type sized to the value, an enumeration over an integer code, and the packed `.T` when the caller already holds one, so the generated validation does the checking.
```ada
procedure Update_Commanded (Self : in out Instance; Command_Ms : in Unsigned_16; Threshold_Ms : in Unsigned_16) is
-- Only Update_Commanded needs this, so it lives here and reads Threshold_Ms directly:
function Is_Actuation (Previous_Ms : in Unsigned_16) return Boolean is
(Command_Ms > 0 and then Previous_Ms < Threshold_Ms);
begin
if Is_Actuation (Self.Previous_Ms) then
Self.Actuations := @ + 1;
end if;
Self.Previous_Ms := Command_Ms;
end Update_Commanded;Variables and Constants
- No unused variables (
-gnatwu): Usepragma Unreferenced (Var);if needed - No useless assignments (
-gnatwm): Don't assign if value is never read - Assigned-but-never-read:
pragma Unreferenceddoes NOT suppress this. Usepragma Warnings (Off, Var);or rename toIgnore_* - Declare constants when possible (
-gnatwk): If never modified, useconstant
Pragma Assert (no string messages)
Never include a string message argument in pragma Assert. The message is compiled into the FSW image as a string literal in .rodata regardless of whether the assertion ever fires, bloating image size for no runtime benefit. Document the rationale with a comment above the assertion instead.
-- WRONG: bloats image with the message string
pragma Assert (Table_Size > Header_Size, "Table_Size must exceed header size");
-- RIGHT: keep image lean, document the why with a comment
-- Table_Size must exceed the parameter table header size.
pragma Assert (Table_Size > Header_Size);This applies to every pragma Assert in hand-written component implementations and shared helpers. redo templates does not emit string-arg asserts, so any string-arg assert you see is hand-added and should be rewritten. Same rule for pragma Assert_And_Cut and any other Adamant-used assert pragma that accepts an optional message.
Subprogram and Aggregate Style
is nullfor empty connector drop handlers:overriding procedure X_Send_Dropped (...) is null;- Named association in aggregates when >1 field:
(Value => 42)not(42) - Underscore grouping for large literals:
16#FFFF_FFFF#not16#FFFFFFFF# - Based literals: Use
16#...#for hex - Qualified aggregates:
Packed_U16.T'(Value => N)when type is ambiguous - Box default
<>: Use in aggregates when default initialization is appropriate. Prefer explicit values for critical fields:(Status => Success, Count => 0)over(Status => Success, Count => <>). - Deliberately reordered call arguments: when a call passes actuals in an unusual order on purpose (e.g. a lemma that swaps two operands), use named association in the call --
F (A => X, B => Z, C => Y)-- not positional actuals. GNAT's-gnatw.pwarns "actuals for this call may be in wrong order" on exactly this shape; naming the arguments expresses the intent and clears the warning withoutpragma Warnings (Off, ...), which would suppress the check everywhere else it is useful. Name the deliberate thing rather than silence the warning.
Multi-Line Subprogram Signatures
When a procedure or function signature is too long to fit on a single line, format it with:
- Open
(on the same line as the subprogram name - Each parameter on its own line, indented 3 spaces relative to the subprogram declaration
- Close
)on its own line, aligned with the start of the subprogram declaration return .../is/;follow immediately after)on the same line
-- CORRECT:
function Get_Ptr_And_Header_From_Region (
Region : in Memory_Region.T;
Table_Header : out Parameter_Table_Header.T
) return Byte_Array_Pointer.Instance is
...
begin
...
end Get_Ptr_And_Header_From_Region;
-- WRONG: open paren on its own line, params over-indented, `return` floats:
function Get_Ptr_And_Header_From_Region
(Region : in Memory_Region.T;
Table_Header : out Parameter_Table_Header.T)
return Byte_Array_Pointer.Instance
is
...Single-line signatures stay on one line; this rule applies only when the signature wraps.
aliased Only For 'Access
Only mark an object aliased when you actually take 'Access of it. 'Address
does not require aliased. Adding it for an 'Address-only object is noise
and falsely signals that an access type is involved.
-- 'Address does NOT need aliased:
X : Some_Type;
A : System.Address := X'Address; -- fine, X is not aliased
-- 'Access DOES need aliased:
Y : aliased Some_Type;
P : Some_Type_Access := Y'Access; -- aliased required hereAdvanced Ada Constructs
use type vs use all type vs use Package
use type Package.Type_Name;makes operators visible for that specific type. Preferred for arithmetic (+,-,<, etc.).use all type Package.Type_Name;also makes primitive subprograms visible. Avoid unless needed -- broader scope risks name conflicts.use Package;makes all public names visible including enum literals. Use when you need enum values directly (e.g.,use Command_Enums.Command_Response_Status;to writeSuccessinstead ofCommand_Response_Status.Success).- Both
use typeanduse Packagebelong inside the subprogram that needs them. Place them at package body level only when several subprograms in the body need them (see Scope Everything To The Smallest Unit Possible).
Expression Functions
- Allowed for simple single-expression results:
function Is_Valid (X : T) return Boolean is (X.Field > 0); - Use traditional function body for anything complex or multi-line.
- Same spacing rules apply (space before
(, operators, etc.).
Renaming Declarations
- Use sparingly, primarily for shortening deeply qualified names:
T : Component.Sensor.Implementation.Tester.Instance_Access renames Self.Tester; - Standard declaration formatting. Document the reason when not obvious.
Generic Instantiations
- Standard declaration formatting with space before
(:package My_Assert is new Basic_Assertions.Generic_Assert (My_Type);
Multi-Line String Concatenation
- Align continuation strings, space around
&:Message := "First part of string " & "second part continues " & "on multiple lines";
SPARK Contracts and Aspects
- Format aspects with consistent indentation:
function Increment (X : Natural) return Natural with Pre => X < Natural'Last, Post => Increment'Result = X + 1; - SPARK pragmas follow standard pragma casing (
-gnatyp):pragma Annotate (GNATprove, ...),pragma SPARK_Mode. - See adamant-build-system (SPARK prove section) for prove configuration.
Access Types (Ravenscar Warning)
- Ravenscar profile restricts dynamic allocation and task types. Prefer generic formal subprograms over access-to-subprogram types when possible.
- If access types are necessary, document the justification.
YAML Rules
- Document start marker required: Every
.yamlfile must begin with--- - No trailing whitespace
- Consistent indentation: 2 spaces for YAML (Adamant convention)
- No tabs: Spaces only
- Quoted string defaults: Enum defaults and string values:
default: "Sensor_Id.Sensor_Id_Type.Temperature_1" with:only for preamble/field types: Include a package inwith:only if preamble code or field types reference it
Type YAML Preamble Style
preamble: |
type Stale_Count_Type is mod 2**4;
type Bit_Type is mod 2**1;
```ada
YAML is linted by yamllint with a project-specific config. Jinja2 templates are resolved before linting.
### Component YAML `with:`
**`with:` is ONLY for preamble code visibility.** Do not put connector types or framework types here.
```yaml
# WRONG:
with:
- Tick
- Command
# RIGHT -- only if preamble references it:
with:
- Interfaces
preamble: |
use Interfaces;
subtype My_Range is Unsigned_8 range 0 .. 100;
```ada
**Assembly YAML `with:` is different** -- assemblies legitimately need packages for discriminants and init params.
## Python (flake8)
Ignored flake8 rules: E121, E123, E126, E226, E24, E704, W503, W504, E402, E501.
```python
from environments import test # noqa: F401
```ada
- Must have `# noqa: F401` to suppress unused import warning
- Must have exactly one trailing newline
- E501 (line length) is NOT enforced
## Codespell
Codespell runs on all files in the directory (excluding build dirs). It checks for common misspellings. The project has an ignore list at `$ADAMANT_DIR/redo/codespell/ignore_list.txt`. If codespell flags a legitimate word, add it to the ignore list or restructure the text.
## Framework Template Artifacts (Cannot Fix)
These warnings come from generated template/type files and are expected:
- `unit "Component.X.Implementation.Tester" is not referenced in spec`
- `with clause might be moved to body` (on test spec)
- `unnecessary with of ancestor` (on test spec)
- `unit "Interfaces" is not referenced` in generated type specs
These are produced by `admt templates` and would be overwritten if modified.
## Implementation Spec Patterns
```ada
-- Component with commands/init/data deps: Interfaces visible via base class
-- Do NOT add: with Interfaces; use Interfaces; (redundant)
with Tick;
with Command;
package Component.Limit_Checker.Implementation is
type Instance is new Limit_Checker.Base_Instance with private;
private
type Instance is new Limit_Checker.Base_Instance with record
Current_Value : Unsigned_16 := 0;
end record;
overriding procedure Tick_T_Recv_Sync (Self : in out Instance; Arg : in Tick.T);
overriding procedure Event_T_Send_Dropped (Self : in out Instance; Arg : in Event.T) is null;
end Component.Limit_Checker.Implementation;
```ada
## Implementation Body Patterns
```ada
package body Component.Sensor_Reader.Implementation is
use type Interfaces.Unsigned_32;
overriding procedure Tick_T_Recv_Sync (Self : in out Instance; Arg : in Tick.T) is
pragma Unreferenced (Arg);
The_Time : constant Sys_Time.T := Self.Sys_Time_T_Get;
begin
Self.Data_Product_T_Send_If_Connected (
Self.Data_Products.Reading_Count (The_Time, (Value => Self.Reading_Count)));
end Tick_T_Recv_Sync;
end Component.Sensor_Reader.Implementation;
```ada
Key patterns:
- `pragma Unreferenced (Arg);` when tick argument unused
- `use type` for operator visibility without full `use`
- `Self.*_Send_If_Connected` for optional connectors
- Qualified aggregates: `Packed_U16.T'(Value => N)` when type ambiguous
## AI/Sub-Agent Output Warnings
Code generated by AI agents or copy-pasted from AI output frequently has these style violations:
1. **Trailing whitespace** -- AI outputs often pad lines with spaces. Bulk fix: `sed -i 's/[[:space:]]*$//' file.adb`
2. **Multiple consecutive blank lines** -- AI likes visual separation. Ada style (`-gnatyu`) forbids it.
3. **Wrong indentation** -- AI defaults to 2 or 4 spaces. Adamant requires exactly 3 (`-gnaty3`).
4. **`(others => 0)` instead of `[others => 0]`** -- AI trained on pre-Ada-2022 syntax.
5. **Boolean `or`/`and` instead of `or else`/`and then`** -- AI doesn't know Adamant's `-gnatyB` rule.
6. **Missing space before `(`** in type conversions -- `Unsigned_32(X)` instead of `Unsigned_32 (X)`.
7. **Wrong keyword casing** -- `BEGIN`, `PROCEDURE`, `NULL` instead of `begin`, `procedure`, `null` (`-gnatyk`).
8. **Statements on same line as `then`/`else`** -- `if X then return; end if;` instead of separate lines (`-gnatyS`).
9. **Unnecessary parentheses in returns** -- `return (X);` instead of `return X;` (`-gnatyx`).
10. **Missing `overriding` keyword** -- AI often omits `overriding` on procedure declarations (`-gnatyO`).
11. **`[]` for record aggregates** -- AI confuses array `[]` with record `()`. Records ALWAYS use `()`.
12. **String messages in `pragma Assert`** -- AI commonly emits `pragma Assert (Cond, "explanation")`. The string bloats image size; strip it and move the explanation to a comment above the assertion.
13. **`aliased` for `'Address`-only objects** -- AI adds `aliased` when only `'Address` is taken. `aliased` is only required for `'Access`; drop it otherwise.
**Always run `admt style` on every file touched by AI or sub-agents before committing.** A bulk trailing-whitespace fix across all test files is often necessary after sub-agent work:
```bash
find src/components -name "*.adb" -path "*/test/*" -exec sed -i 's/[[:space:]]*$//' {} +
find src/components -name "*.ads" -path "*/test/*" -exec sed -i 's/[[:space:]]*$//' {} +
```ada
## Common Patterns by Frequency
### Most Common (fix first)
1. **Unused `with` in test bodies** (40+): Left over from templates or copy-paste
2. **Redundant `use Interfaces`** (20+): Already visible through generated base class
3. **Unused `with` in component bodies** (15+): Redundant with already in spec
4. **`(others => ...)` array syntax** (64): Needs `[others => ...]` (Ada 2022)
5. **Unused `with` in component specs** (10+): Declared but not referenced
### Frequent
6. **Unused `Count` from `Dispatch_All`**: Use `Natural_Assert.Eq (T.Dispatch_All, N)` directly, or suppress with `pragma Warnings (Off, "variable ""Count"" is assigned but never read");` before the package body. Ada forbids bare function calls (`T.Dispatch_All;` illegal).
7. **Missing space before `(`** in type conversions
8. **`or` / `and` instead of `or else` / `and then`**
9. **`then` not on its own line** in multi-line conditions
10. **Redundant conversions**: `Natural (I)` where `I` is already Natural
### Dangerous Removals (verify before removing)
- **`with X; use X;` where `use` provides operator visibility**: Removing `with Command_Types;` breaks `=` and `<`
- **`use Command_Execution_Status;`**: If removed, `return Success;` becomes ambiguous
- **`AUnit.Assertions`**: GNAT reports "no entities referenced" even when `Assert` is called via `use`. Only remove if ALL assertions use qualified names
- **Rule**: Before removing ANY `with`, grep the body for types/operators/procedures from that package
### Occasional
11. **Bad casing** (not matching declaration)
12. **Type mismatches in assertions**: Wrong `Packed_U16_Assert` vs `Packed_U32_Assert`
13. **Multiple blank lines** in sequence
14. **Duplicate with-clauses** (same package withed twice)
15. **`use Command_Execution_Status.E;`** in test bodies -- has no effect
16. **Record aggregate with `[]`**: Only arrays use `[]`
17. **`Short_Float` vs `IEEE_Float_32`**: `Packed_F32.T.Value` is `Short_Float`
18. **Missing space around `**` operator**: `2**16` -> `2 ** 16`
19. **Assigned-but-never-read variables**: Use `pragma Warnings (Off, Var);`
20. **Unnecessary parentheses**: `return (X);` -> `return X;` (`-gnatyx`)
21. **Wrong indentation**: Must be exactly 3 spaces per level
22. **Statements on `then`/`else` line**: Must be on separate line (`-gnatyS`)
## Quick Decision Table
| Situation | Action |
|---|---|
| Unused variable | `pragma Unreferenced (Var);` |
| Assigned-but-never-read | `pragma Warnings (Off, Var);` or rename `Ignore_*` |
| Unused `with` in body (spec has it) | Remove from body |
| Unused `with` in spec (only body uses it) | Move to body |
| `with X; use X;` seems unused but operators used | Keep it -- grep first |
| `(others => 0)` on array | Change to `[others => 0]` |
| `(others => <>)` on record | Keep `()` -- records use parens |
| Boolean `or`/`and` | Change to `or else`/`and then` |
| Multi-line if | Put `then` on its own line |
| Empty block body | Add `null;` |
| Function result unused | `Ignore := Func (...); pragma Unreferenced (Ignore);` |
| `pragma Assert (X, "msg")` | Drop the message; move it to a comment above the assert |
| `aliased` on `'Address`-only object | Drop `aliased`; it's only needed for `'Access` |
| Redundant `use Interfaces` | Remove if base class provides it |
| Unnecessary parens | `return X;` not `return (X);` |
| Wrong indentation | Use 3 spaces per level |
| Statement on then/else line | Move to next line |
| `Buffer'Length` on 2D array | Use `Buffer'Length (1)` |
## Style Checklist
```bash
admt style
cat build/style/style.logALL style warnings are fixable. Common test spec warnings and fixes:
unit "Component.X.Implementation.Tester" is not referenced in spec-- move thewithto the bodywith clause might be moved to body-- move thewithto the bodyunnecessary with of ancestor-- child packages auto-see parents, remove thewith- Redundant
with/use Interfacesin YAMLpreamble:-- generated base already adds it when component has commands/init
Related Skills
- Component dev: adamant-component-dev
- Testing: adamant-testing
- Build system: adamant-build-system
References
- references/style-patterns.md: Detailed examples for every pattern with before/after code
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.

