@h2loop/safe-c-coding-plugin 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,12 +2,15 @@
2
2
  mode: subagent
3
3
  displayName: Safe-C Reviewer
4
4
  description: >-
5
- Reviews C / C++ (.c, .h, .cpp, .hpp) against the safe-c-coding (MISRA C:2012-aligned)
6
- guidelines and reports findings by severity. Given a file, diff, or code range, it scans
7
- for undefined behaviour, dynamic allocation, unchecked returns, implicit conversions,
8
- missing switch defaults, recursion, and other hazardous constructs, and reports each as
9
- "severity file:line what's wrong -> safe fix". Use it to audit hand-written or
10
- generated C/C++ before it lands, especially for embedded / safety-critical targets.
5
+ ALWAYS invoke this subagent once you have written, generated, or modified any C or C++
6
+ code (.c, .h, .cpp, .hpp), or whenever you want to review existing C/C++ code do not
7
+ skip this for one-line changes or code that looks routine. Reviews the code against the
8
+ safe-c-coding (MISRA C:2012-aligned) guidelines. Given a file, diff, or code range, it
9
+ scans for undefined behaviour, dynamic allocation, unchecked returns, implicit
10
+ conversions, missing switch defaults, recursion, and other hazardous constructs, and
11
+ reports each as "severity — file:line — what's wrong -> safe fix". Use it to audit
12
+ hand-written or generated C/C++ before it lands, especially for embedded / safety-critical
13
+ targets.
11
14
  permission:
12
15
  # deny-all FIRST, then allow specifics: PermissionNext resolves with findLast
13
16
  # (last matching rule wins), so "*": deny MUST precede the allows or it overrides them.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@h2loop/safe-c-coding-plugin",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Safe-C coding plugin for Hydron — MISRA C:2012-aligned defensive C/C++ guidelines as an always-on skill plus a safe-c-reviewer subagent",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -21,10 +21,14 @@
21
21
  ],
22
22
  "files": [
23
23
  ".hydron-plugin",
24
+ "plugins",
24
25
  "skills",
25
26
  "agents",
26
27
  "README.md"
27
28
  ],
29
+ "dependencies": {
30
+ "@kilocode/plugin": "*"
31
+ },
28
32
  "repository": {
29
33
  "type": "git",
30
34
  "url": "git+https://github.com/h2loop/safe-c-misra-skill-plugin.git"
@@ -0,0 +1,12 @@
1
+ import type { Plugin } from "@kilocode/plugin"
2
+
3
+ export const SafeCCodingPlugin: Plugin = async () => ({
4
+ "experimental.chat.system.transform": async (_input, output) => {
5
+ output.system.push(
6
+ "Before writing, generating, modifying, or reviewing any C or C++ code " +
7
+ "(.c, .h, .cpp, .hpp), invoke the safe-c-coding skill. After writing or " +
8
+ "modifying C/C++ code, invoke the safe-c-reviewer subagent. Do this even " +
9
+ "for a one-line change or code that looks routine.",
10
+ )
11
+ },
12
+ })
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: safe-c-coding
3
- description: Use when writing, generating, modifying, or reviewing C or C++ code (.c, .h, .cpp, .hpp), especially for embedded, automotive, medical, aerospace, or other safety-critical or resource-constrained targets where reliability, determinism, and freedom from undefined behaviour matter.
3
+ description: ALWAYS invoke this skill before writing, generating, modifying, or reviewing any C or C++ code (.c, .h, .cpp, .hpp) — no exception for one-line changes, snippets, or code that looks routine. Applies especially to embedded, automotive, medical, aerospace, or other safety-critical or resource-constrained targets where reliability, determinism, and freedom from undefined behaviour matter, but the mandatory-invocation rule applies to all C/C++ work.
4
4
  ---
5
5
 
6
6
  # Safe C Coding
@@ -22,8 +22,8 @@ Short list, verified on every function you write or edit. Everything else lives
22
22
  3. **No dynamic memory, recursion, VLAs, `exit`/`abort`/`longjmp`, or unbounded string functions** — use the substitutes in guidelines.md.
23
23
  4. **No implicit narrowing and no signed/unsigned mixing** — every conversion explicit.
24
24
  5. **Braces on every body, a `default` on every `switch`, every return value used or `(void)`-discarded.**
25
- 6. **Every identifier you reference is one you have actually read in a declaration.** Before writing a macro, struct or union member, type, enum constant, global, or function name that this file does not itself define, find its declaration in the headers and context you were given, and copy the spelling from there. Names that feel like they *must* exist a size or count macro accompanying a table, a member named after the quantity it holds, an obvious-looking helper very often do not, and a plausible invented name is a compile error, not a style blemish. Note in particular that a length may be exposed as a variable rather than a macro, and that a member's name usually describes its slot, not its physical meaning. If you cannot find a declaration for something you need, say so rather than guessing at it.
26
- 7. **Every guard you add must be able to fail.** Before testing a value against zero, NULL, or a range limit, establish what the value actually is. If it is fixed at compile time a macro expanding to a literal expression, an enum constant, a `sizeof`, a `const` object with a visible initialiser, the address of a declared object or array — then the test has one permanent answer, and an always-true or always-false controlling expression is a required-rule violation (dead code), not extra safety. Guard the things that genuinely vary at run time: parameters, values read from globals or hardware, results of computation. If the worry is that a *configured constant* could be set wrongly, check it at compile time with `#if` or a static-assertion idiom, which costs nothing at run time and cannot be dead code. This does **not** loosen items 1 and 2: an index or pointer that arrives as a parameter, or is read from a global, a struct, or a device, is precisely the varying kind, and still needs its real `if` guard. The two rules point the same way — put guards where a value can actually surprise you, and nowhere else.
25
+ 6. **Every identifier you reference is one you have actually read in a declaration.** A plausible invented name a size/count macro that feels like it must accompany a table, a member named after the quantity it holds rather than its declared name is a compile error, not a style blemish. Full rule: see guidelines.md § General.
26
+ 7. **Every guard you add must be able to fail.** A guard whose tested value is fixed at compile time (a macro, enum constant, `sizeof`, `const` with a visible initialiser, a declared object's address) has one permanent answer that's an always-true/-false controlling expression, a dead-code violation, not extra safety; check it with `#if`/a static assertion instead. This does **not** loosen items 1 and 2: a value that arrives as a parameter or is read from a global, struct, or device is precisely the varying kind and still needs its real `if` guard. Full rule: see guidelines.md § Control flow.
27
27
 
28
28
  Where one of these clashes with the surrounding house style, follow the guideline in the code you write and note the divergence in one line.
29
29
 
@@ -72,7 +72,7 @@ Walk the lines you wrote — not the whole file — and answer each question exp
72
72
  6. **Every branch construct**: braced bodies, a `default` in every `switch`, a terminating `else` where the chain must be exhaustive.
73
73
  7. **Anything on the banned-facility list** (dynamic memory, recursion, VLAs, `exit`/`abort`/`longjmp`, unbounded string functions): replaced by its substitute, or deviated from with a written justification.
74
74
 
75
- State the result of the audit in one or two lines before you finish, so the check is visible rather than assumed.
75
+ State the result of the audit before you finish: for every Critical or Standard finding raised by the reviewer subagent or by your own re-read — name the finding and the specific edit that resolved it. "Audit passed" or "no issues found" with no re-read behind it is not an audit; a finding with no matching fix next to it is not an audit either.
76
76
 
77
77
  ## Preferred patterns
78
78