@ihelpee/prumo-plugin-go-gin 0.8.3 → 0.9.0
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.
- package/README.md +46 -39
- package/dist/rules.d.ts.map +1 -1
- package/dist/rules.js +2 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,17 +9,17 @@
|
|
|
9
9
|
|
|
10
10
|
> Official **Go/Gin** architectural invariant plugin for [Prumo](https://www.npmjs.com/package/@ihelpee/prumo) — the deterministic gatekeeper and business guardrails for AI-assisted engineering.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
In Go, the three failure modes AI commits most often are structural: **a mutation route without auth** (Gin spreads middleware across three layers — inline, `Group.Use`, `Engine.Use` — and the group layer is where the false-negative lives), **a swallowed error** (`_ = err`, `x, _ := f()` — the language's native silent failure) and **binding without validation** (`ShouldBindJSON` on a struct without `binding:"..."` tags). This plugin polices all three with pure static AST analysis — **no app boot, no `go build` of the target, no network**.
|
|
13
13
|
|
|
14
|
-
Go
|
|
14
|
+
Go is also the only language in the Prumo ecosystem where the oracle law ("whoever generates does not specify correctness") can be enforced by **the compiler itself**: implementation under `internal/**` and the oracle in a separate module (`oracle/go.mod`) turn importing the implementation into a build error, not a lint finding. The plugin recommends this topology as the gold standard and tolerates the single-module one (covered by the static rule).
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Installation
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
19
|
pnpm add -D @ihelpee/prumo-plugin-go-gin @ihelpee/prumo
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Configure
|
|
22
|
+
Configure it in `prumo.config.ts` (the real key is `invariants:`, not `plugins:`):
|
|
23
23
|
|
|
24
24
|
```ts
|
|
25
25
|
import { defineConfig } from '@ihelpee/prumo';
|
|
@@ -39,66 +39,73 @@ export default defineConfig({
|
|
|
39
39
|
});
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
Or in `.prumo/invariants/rules.ts` (where the waivers live):
|
|
43
43
|
|
|
44
44
|
```ts
|
|
45
45
|
import { goGinPreset } from '@ihelpee/prumo-plugin-go-gin';
|
|
46
46
|
export default goGinPreset;
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
##
|
|
49
|
+
## Invariants
|
|
50
50
|
|
|
51
|
-
| id | sev. |
|
|
51
|
+
| id | sev. | the footgun | the honest boundary (what it does NOT catch) |
|
|
52
52
|
|---|---|---|---|
|
|
53
|
-
| `mutation-routes-guarded` | error |
|
|
54
|
-
| `error-handling-enforced` | error |
|
|
55
|
-
| `error-handling-unchecked` | warn |
|
|
56
|
-
| `payload-validation-bound` | error | `ShouldBindJSON`/`Bind`
|
|
57
|
-
| `payload-validation-query` | warn |
|
|
58
|
-
| `oracle-no-src` | error |
|
|
59
|
-
| `oracle-whitebox-test` | error | `_test.go`
|
|
60
|
-
| `src-no-oracle` | error |
|
|
61
|
-
| `oracle-module-couples-app` | error | `oracle/go.mod`
|
|
62
|
-
| `no-cross-feature-import` | warn | `internal/<A>/`
|
|
63
|
-
| `monetary-is-integer` | warn |
|
|
64
|
-
| `go-toolchain-missing` | warn | `go`
|
|
65
|
-
| `go-parse-error` | error |
|
|
66
|
-
|
|
67
|
-
##
|
|
68
|
-
|
|
69
|
-
- **
|
|
70
|
-
- **
|
|
71
|
-
- **
|
|
72
|
-
- **Timeout** (default 20s)
|
|
73
|
-
- `go`
|
|
74
|
-
|
|
75
|
-
##
|
|
53
|
+
| `mutation-routes-guarded` | error | a mutation route (`POST`/`PUT`/`PATCH`/`DELETE`) without auth in **any** layer — inline, `Group.Use`, `Engine.Use`, with **transitive** inheritance from sub-groups | `Recovery`/`Logger`/`CORS` don't count as auth; an explicit `NoAuth()` marks an intentionally public route; read routes are never targeted |
|
|
54
|
+
| `error-handling-enforced` | error | an error deliberately discarded: `_ = err`, `x, _ := f()` | `if err := f(); err != nil` is not a finding |
|
|
55
|
+
| `error-handling-unchecked` | warn | a call returning `error` used as a bare statement (`db.Save(o)`) | heuristic without type info: only functions in `knownErrReturning` or seen with `err` in the same file; hence `warn`, never blocks without `--fail-on-warn` |
|
|
56
|
+
| `payload-validation-bound` | error | `ShouldBindJSON`/`Bind` on a struct with a data field lacking a `binding:"..."` tag | a type not resolvable syntactically **is not reported** (never guesses); `binding:"-"` is ignored |
|
|
57
|
+
| `payload-validation-query` | warn | query/uri binding without a tag | query validation is frequently optional — `warn` |
|
|
58
|
+
| `oracle-no-src` | error | an oracle test importing an internal application package (resolved against the `module` in `go.mod`) | alias, dot and blank imports are all edge cases — bypass via alias is blocked |
|
|
59
|
+
| `oracle-whitebox-test` | error | a `_test.go` inside `internal/**` declaring `package foo` — accesses unexported symbols: a white-box mirror by construction | `package foo_test` is black-box and does not violate |
|
|
60
|
+
| `src-no-oracle` | error | production importing the oracle directory (a fixture leaking into production) | — |
|
|
61
|
+
| `oracle-module-couples-app` | error | `oracle/go.mod` with a `require`/`replace` of the application module: the compiler boundary was disabled on purpose | the single-module topology has no `oracle/go.mod` and is covered by `oracle-no-src` |
|
|
62
|
+
| `no-cross-feature-import` | warn | `internal/<A>/` importing `internal/<B>/` | Go layouts vary — `warn` in the MVP |
|
|
63
|
+
| `monetary-is-integer` | warn | a monetary field as `float32`/`float64` | `int64` with a `Cents` suffix is clean |
|
|
64
|
+
| `go-toolchain-missing` | warn | `go` absent on the host: Go invariants are **not evaluated** | never silent; `--fail-on-warn` promotes it to a block |
|
|
65
|
+
| `go-parse-error` | error | a `.go` file that fails to parse becomes invisible to the rules | fixing/excluding the file resolves it |
|
|
66
|
+
|
|
67
|
+
## How it works (and why it's safe)
|
|
68
|
+
|
|
69
|
+
- **Go stdlib-only extractor** (`go-extractor/`, module `ihelpee.dev/prumo-go-extractor`): `go/parser` + `go/ast` serializing the AST into **canonical JSON v1** on stdout. Zero external dependency — any `require` in the extractor's `go.mod` is a build failure.
|
|
70
|
+
- **The extractor is a parser, not an implementer of the law.** The "is this a violation?" decision lives 100% in the Node core (`rules.ts`). Two implementers of the same law drift — self-refutation for a tool that hunts drift.
|
|
71
|
+
- **It never runs the code under analysis**: only `parser.ParseFile`. The extractor's `go run` executes from inside the isolated module with `GOTOOLCHAIN=local` and `GOPROXY=off` — the target's dependency graph is never touched, and the absence of network is mechanical, not accidental.
|
|
72
|
+
- **Timeout** (default 20s) on the subprocess; a pathological parse won't hang the gate.
|
|
73
|
+
- `go` absent → a named `warn` finding, never a silent skip.
|
|
74
|
+
|
|
75
|
+
## Options
|
|
76
76
|
|
|
77
77
|
```ts
|
|
78
78
|
goGinPlugin({
|
|
79
79
|
authSymbols: ['Auth', 'RequireAuth', 'JWTAuth'], // R3.5
|
|
80
80
|
publicSymbols: ['NoAuth'], // R3.6
|
|
81
81
|
knownErrReturning: ['Save', 'Exec', 'Do'], // R3.8
|
|
82
|
-
excludePatterns: ['**/gen/**'], // R1.7 (vendor/
|
|
82
|
+
excludePatterns: ['**/gen/**'], // R1.7 (vendor/ and generated are already default)
|
|
83
83
|
srcDirs: ['internal', 'pkg', 'cmd'], // R2.5/R2.7
|
|
84
84
|
oracleDirs: ['oracle', 'tests/oracle'], // R2.x
|
|
85
85
|
timeoutMs: 20_000, // R1.5
|
|
86
86
|
})
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
##
|
|
89
|
+
## The Go oracle gold standard
|
|
90
90
|
|
|
91
91
|
```
|
|
92
92
|
orders/ # go.mod: module github.com/acme/orders
|
|
93
|
-
internal/orders/handler.go #
|
|
93
|
+
internal/orders/handler.go # implementation — importable only within this module
|
|
94
94
|
cmd/server/main.go
|
|
95
|
-
oracle/ #
|
|
96
|
-
go.mod #
|
|
97
|
-
orders_blackbox_test.go # HTTP black-box;
|
|
95
|
+
oracle/ # SEPARATE module: its own go.mod
|
|
96
|
+
go.mod # WITHOUT require/replace of the application module
|
|
97
|
+
orders_blackbox_test.go # HTTP black-box; the CONTRACT's expectation
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
In this topology the mirror test **does not compile** — the law is physical, not opinionated. Prumo becomes an intent verifier (`oracle-module-couples-app`).
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
---
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
## License & Brand
|
|
105
|
+
|
|
106
|
+
Copyright © 2026 **IHELPEE TECNOLOGIA LTDA** (<https://ihelpee.com>). All rights reserved.
|
|
107
|
+
Created and authored by [Alex Gotardi](https://github.com/alexgotardi).
|
|
108
|
+
|
|
109
|
+
Licensed under the [Apache License, Version 2.0](https://github.com/ihelpee/prumo/blob/main/LICENSE) (the "License"); you may not use this file except in compliance with the License. A copy is available at <http://www.apache.org/licenses/LICENSE-2.0>.
|
|
110
|
+
|
|
111
|
+
The **"Prumo"** name and logo are trademarks of IHELPEE TECNOLOGIA LTDA and are **not** licensed under the Apache 2.0 license.
|
package/dist/rules.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,YAAY,EACZ,KAAK,OAAO,EAGb,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAOL,KAAK,YAAY,EAIlB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,YAAY,EACZ,KAAK,OAAO,EAGb,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAOL,KAAK,YAAY,EAIlB,MAAM,UAAU,CAAC;AA8ElB;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAcnE;AASD,iFAAiF;AACjF,wBAAgB,YAAY,IAAI,OAAO,CAWtC;AAyFD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAkCtE;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,GAAE,YAAiB,GAAG,OAAO,CAyBvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CA+BvE;AAoBD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAqChD;AAED,oGAAoG;AACpG,wBAAgB,sBAAsB,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAoCvE;AA6BD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CA2B5D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAyBnE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CA2B5D;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAgChD;AAwBD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CA6BrE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAuB3C;AAUD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,YAAiB,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAyBpF;AAED,qFAAqF;AACrF,eAAO,MAAM,WAAW,EAAE,OAAO,EAAwB,CAAC;AAE1D,eAAe,WAAW,CAAC"}
|
package/dist/rules.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { rule, definePlugin, } from '@ihelpee/prumo/invariants';
|
|
2
2
|
import { startsWithAny } from '@ihelpee/prumo/core';
|
|
3
3
|
import { runGoExtractor, DEFAULT_AUTH_SYMBOLS, DEFAULT_PUBLIC_SYMBOLS, DEFAULT_KNOWN_ERR_RETURNING, DEFAULT_ORACLE_DIRS, } from './ast.js';
|
|
4
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
4
5
|
/**
|
|
5
6
|
* Invariantes Go/Gin (spec `docs/especificacao-prumo-go-gin.md` §2 e §3).
|
|
6
7
|
*
|
|
@@ -690,7 +691,7 @@ function isUnderAny(p, prefixes) {
|
|
|
690
691
|
export function goGinPlugin(opts = {}) {
|
|
691
692
|
return definePlugin({
|
|
692
693
|
name: 'go-gin',
|
|
693
|
-
version:
|
|
694
|
+
version: pkg.version,
|
|
694
695
|
description: 'Go/Gin invariants: mutation route guards (inline/Group.Use/Engine.Use transitivo), error-handling enforcement, payload binding validation, oracle isolation nativa de Go (internal/, white-box, módulo separado).',
|
|
695
696
|
extractors: {
|
|
696
697
|
go: async (ctx) => ({ result: await runGoExtractor(ctx.root, opts) }),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ihelpee/prumo-plugin-go-gin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Go/Gin plugin for Prumo: mutation route guards (inline/Group.Use/Engine.Use), error-handling enforcement, payload binding validation, and Go-native oracle isolation.",
|
|
6
6
|
"author": "Alex Gotardi <alexgotardi@gmail.com>",
|
|
@@ -33,6 +33,6 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@ihelpee/prumo": "0.
|
|
36
|
+
"@ihelpee/prumo": "0.9.0"
|
|
37
37
|
}
|
|
38
38
|
}
|