guardlink 1.0.0 → 1.1.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +14 -0
  3. package/dist/agents/config.d.ts +2 -0
  4. package/dist/agents/config.d.ts.map +1 -1
  5. package/dist/agents/config.js +1 -1
  6. package/dist/agents/config.js.map +1 -1
  7. package/dist/agents/prompts.d.ts +2 -2
  8. package/dist/agents/prompts.d.ts.map +1 -1
  9. package/dist/agents/prompts.js +223 -31
  10. package/dist/agents/prompts.js.map +1 -1
  11. package/dist/analyzer/sarif.js +1 -1
  12. package/dist/cli/index.js +2 -56
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/dashboard/data.d.ts.map +1 -1
  15. package/dist/dashboard/data.js +19 -12
  16. package/dist/dashboard/data.js.map +1 -1
  17. package/dist/dashboard/diagrams.d.ts.map +1 -1
  18. package/dist/dashboard/diagrams.js +310 -37
  19. package/dist/dashboard/diagrams.js.map +1 -1
  20. package/dist/dashboard/generate.d.ts.map +1 -1
  21. package/dist/dashboard/generate.js +21 -5
  22. package/dist/dashboard/generate.js.map +1 -1
  23. package/dist/init/picker.d.ts.map +1 -1
  24. package/dist/init/picker.js +2 -2
  25. package/dist/init/picker.js.map +1 -1
  26. package/dist/init/templates.js +1 -1
  27. package/dist/mcp/server.d.ts.map +1 -1
  28. package/dist/mcp/server.js +8 -26
  29. package/dist/mcp/server.js.map +1 -1
  30. package/dist/parser/index.d.ts +1 -0
  31. package/dist/parser/index.d.ts.map +1 -1
  32. package/dist/parser/index.js +1 -0
  33. package/dist/parser/index.js.map +1 -1
  34. package/dist/parser/parse-line.js +3 -3
  35. package/dist/parser/parse-line.js.map +1 -1
  36. package/dist/parser/parse-project.js +1 -1
  37. package/dist/parser/validate.d.ts +19 -0
  38. package/dist/parser/validate.d.ts.map +1 -0
  39. package/dist/parser/validate.js +105 -0
  40. package/dist/parser/validate.js.map +1 -0
  41. package/dist/tui/commands.d.ts +1 -6
  42. package/dist/tui/commands.d.ts.map +1 -1
  43. package/dist/tui/commands.js +96 -221
  44. package/dist/tui/commands.js.map +1 -1
  45. package/dist/tui/config.d.ts +2 -0
  46. package/dist/tui/config.d.ts.map +1 -1
  47. package/dist/tui/config.js.map +1 -1
  48. package/dist/tui/index.d.ts.map +1 -1
  49. package/dist/tui/index.js +20 -24
  50. package/dist/tui/index.js.map +1 -1
  51. package/dist/tui/input.d.ts +2 -2
  52. package/dist/tui/input.js +2 -2
  53. package/dist/types/index.d.ts +1 -1
  54. package/dist/types/index.d.ts.map +1 -1
  55. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,34 @@ All notable changes to GuardLink CLI will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.0] — 2026-02-21
9
+
10
+ ### Added
11
+
12
+ - **Validation**: Shared `findDanglingRefs` and `findUnmitigatedExposures` with consistent `#id`/bare-name normalization across CLI, TUI, and MCP
13
+ - **Validation**: Expanded dangling ref checks to cover `@flows`, `@boundary`, `@audit`, `@owns`, `@handles`, `@assumes` annotations
14
+ - **Diagrams**: Threat graph now renders `@transfers`, `@validates`, trust boundaries, data classifications, ownership, and CWE references
15
+ - **Diagrams**: Heuristic icons for assets (👤 user, 🖥️ service, 🗄️ database) and flow mechanisms (🔐 TLS, 🌐 HTTP, 📨 queue)
16
+ - **Prompts**: Flow-first threat modeling methodology with architecture mapping, trust boundary identification, and coupled annotation style guide
17
+ - **Prompts**: Agent context now includes existing data flows and unmitigated exposures for smarter annotation
18
+ - **Model**: Two-step `/model` configuration — CLI Agents (Claude Code, Codex, Gemini) or API providers
19
+ - **Tests**: Dashboard diagram generation tests (label sanitization, severity resolution, transfers, validations)
20
+ - **Tests**: Parser regression tests (`@flows` via + description, `@shield` vs `@shield:begin` disambiguation)
21
+ - **Tests**: Validation unit tests (dangling refs, unmitigated exposure matching with ref normalization)
22
+ - **README**: Manual installation instructions (build from source + npm link)
23
+
24
+ ### Fixed
25
+
26
+ - **Parser**: `@flows` regex no longer swallows description when `via` mechanism is present
27
+ - **Parser**: `@shield` no longer incorrectly matches `@shield:begin` and `@shield:end`
28
+ - **Validation**: `#id` and bare-name refs now compare correctly (e.g., `#sqli` matches `sqli` in mitigations)
29
+
30
+ ### Removed
31
+
32
+ - **TUI**: `/scan` command — redundant with `/status` coverage display; AI-driven annotation replaces manual symbol discovery
33
+ - **TUI**: `/exposures` and `/show` commands — exposure data remains accessible via `/validate`, MCP `guardlink_status`, and `guardlink://unmitigated` resource
34
+ - **Dependencies**: Removed accidental `build` package (unused)
35
+
8
36
  ## [1.0.0] — 2026-02-21
9
37
 
10
38
  Initial public release of GuardLink.
package/README.md CHANGED
@@ -35,6 +35,20 @@ npm install -g guardlink
35
35
 
36
36
  Requires Node.js 18+.
37
37
 
38
+ ### Manual Installation
39
+
40
+ To install from source:
41
+
42
+ ```bash
43
+ # 1. Build the project
44
+ npm run build
45
+
46
+ # 2. Link globally
47
+ npm link
48
+ ```
49
+
50
+ To uninstall: `npm unlink -g guardlink`
51
+
38
52
  ## Quick Start
39
53
 
40
54
  ```bash
@@ -15,6 +15,8 @@ interface SavedConfig {
15
15
  provider?: LLMProvider;
16
16
  model?: string;
17
17
  apiKey?: string;
18
+ aiMode?: 'cli-agent' | 'api';
19
+ cliAgent?: string;
18
20
  }
19
21
  /**
20
22
  * Resolve LLM configuration using the unified priority chain.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/agents/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhE,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAgDD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D,SAAS,GAAG,IAAI,CAmDlB;AAiCD,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAEtE;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAEvD;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAGlE;AAED,yBAAyB;AACzB,wBAAgB,gBAAgB,IAAI,WAAW,GAAG,IAAI,CAErD;AAID,uDAAuD;AACvD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG3C;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,MAAM,CAcR"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/agents/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhE,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAgDD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D,SAAS,GAAG,IAAI,CAmDlB;AAiCD,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAEtE;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAEvD;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAGlE;AAED,yBAAyB;AACzB,wBAAgB,gBAAgB,IAAI,WAAW,GAAG,IAAI,CAErD;AAID,uDAAuD;AACvD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG3C;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,MAAM,CAcR"}
@@ -176,7 +176,7 @@ export function describeConfigSource(root, flags) {
176
176
  if (process.env.DEEPSEEK_API_KEY)
177
177
  return 'DEEPSEEK_API_KEY env var';
178
178
  const pc = readJsonFile(projectConfigPath(root));
179
- if (pc && Object.keys(pc).length > 0 && pc.provider)
179
+ if (pc && Object.keys(pc).length > 0 && (pc.provider || pc.aiMode))
180
180
  return `.guardlink/${CONFIG_FILE}`;
181
181
  const lc = readJsonFile(legacyConfigPath(root));
182
182
  if (lc && Object.keys(lc).length > 0 && lc.provider)
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/agents/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/agents/config.ts"],"names":[],"mappings":"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"}
@@ -7,8 +7,8 @@ import type { ThreatModel } from '../types/index.js';
7
7
  /**
8
8
  * Build a prompt for annotation agents.
9
9
  *
10
- * Includes the GuardLink reference doc (truncated), current model summary,
11
- * user instructions, and precise GAL syntax rules with common pitfalls.
10
+ * Includes the GuardLink reference doc, current model summary with flows and exposures,
11
+ * flow-first threat modeling methodology, and precise GAL syntax rules.
12
12
  */
13
13
  export declare function buildAnnotatePrompt(userPrompt: string, root: string, model: ThreatModel | null): string;
14
14
  //# sourceMappingURL=prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/agents/prompts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,GAAG,IAAI,GACxB,MAAM,CAyGR"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/agents/prompts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,GAAG,IAAI,GACxB,MAAM,CA6SR"}
@@ -8,8 +8,8 @@ import { resolve } from 'node:path';
8
8
  /**
9
9
  * Build a prompt for annotation agents.
10
10
  *
11
- * Includes the GuardLink reference doc (truncated), current model summary,
12
- * user instructions, and precise GAL syntax rules with common pitfalls.
11
+ * Includes the GuardLink reference doc, current model summary with flows and exposures,
12
+ * flow-first threat modeling methodology, and precise GAL syntax rules.
13
13
  */
14
14
  export function buildAnnotatePrompt(userPrompt, root, model) {
15
15
  // Read the reference doc if available
@@ -18,8 +18,17 @@ export function buildAnnotatePrompt(userPrompt, root, model) {
18
18
  if (existsSync(refPath)) {
19
19
  refDoc = readFileSync(refPath, 'utf-8');
20
20
  }
21
- let modelSummary = 'No threat model parsed yet. Run `guardlink parse` after annotating.';
21
+ // Fall back to docs/GUARDLINK_REFERENCE.md
22
+ if (!refDoc) {
23
+ const docsRefPath = resolve(root, 'docs', 'GUARDLINK_REFERENCE.md');
24
+ if (existsSync(docsRefPath)) {
25
+ refDoc = readFileSync(docsRefPath, 'utf-8');
26
+ }
27
+ }
28
+ let modelSummary = 'No threat model parsed yet. This may be a fresh project — define assets, threats, and controls first.';
22
29
  let existingIds = '';
30
+ let existingFlows = '';
31
+ let existingExposures = '';
23
32
  if (model) {
24
33
  const parts = [
25
34
  `${model.annotations_parsed} annotations`,
@@ -28,6 +37,8 @@ export function buildAnnotatePrompt(userPrompt, root, model) {
28
37
  `${model.threats.length} threats`,
29
38
  `${model.controls.length} controls`,
30
39
  `${model.mitigations.length} mitigations`,
40
+ `${model.flows.length} flows`,
41
+ `${model.boundaries.length} boundaries`,
31
42
  ];
32
43
  modelSummary = `Current model: ${parts.join(', ')}.`;
33
44
  // Include existing IDs so the agent doesn't create duplicates or dangling refs
@@ -36,45 +47,208 @@ export function buildAnnotatePrompt(userPrompt, root, model) {
36
47
  const controlIds = model.controls.filter(c => c.id).map(c => `#${c.id}`);
37
48
  if (threatIds.length + assetIds.length + controlIds.length > 0) {
38
49
  const sections = [];
39
- if (threatIds.length)
40
- sections.push(`Threats: ${threatIds.join(', ')}`);
41
50
  if (assetIds.length)
42
51
  sections.push(`Assets: ${assetIds.join(', ')}`);
52
+ if (threatIds.length)
53
+ sections.push(`Threats: ${threatIds.join(', ')}`);
43
54
  if (controlIds.length)
44
55
  sections.push(`Controls: ${controlIds.join(', ')}`);
45
- existingIds = `\n\nExisting defined IDs (use these in @exposes, @mitigates, etc.):\n${sections.join('\n')}`;
56
+ existingIds = `\n\nExisting defined IDs (REUSE these do NOT redefine):\n${sections.join('\n')}`;
57
+ }
58
+ // Include existing flows so agent understands the current flow graph
59
+ if (model.flows.length > 0) {
60
+ const flowLines = model.flows.slice(0, 30).map(f => ` ${f.source} -> ${f.target}${f.mechanism ? ` via ${f.mechanism}` : ''} (${f.location.file}:${f.location.line})`);
61
+ existingFlows = `\n\nExisting data flows (extend these, don't duplicate):\n${flowLines.join('\n')}`;
62
+ if (model.flows.length > 30)
63
+ existingFlows += `\n ... and ${model.flows.length - 30} more`;
64
+ }
65
+ // Include unmitigated exposures so agent knows what still needs attention
66
+ const unmitigatedExposures = model.exposures.filter(e => {
67
+ return !model.mitigations.some(m => m.asset === e.asset && m.threat === e.threat)
68
+ && !model.acceptances.some(a => a.asset === e.asset && a.threat === e.threat);
69
+ });
70
+ if (unmitigatedExposures.length > 0) {
71
+ const expLines = unmitigatedExposures.slice(0, 20).map(e => ` ${e.asset} exposed to ${e.threat} [${e.severity || 'unrated'}] (${e.location.file}:${e.location.line})`);
72
+ existingExposures = `\n\nOpen exposures (unmitigated — add @mitigates or @accepts for these):\n${expLines.join('\n')}`;
73
+ if (unmitigatedExposures.length > 20)
74
+ existingExposures += `\n ... and ${unmitigatedExposures.length - 20} more`;
46
75
  }
47
76
  }
48
- return `You are annotating a codebase with GuardLink security annotations.
77
+ return `You are an expert security engineer performing threat modeling as code.
78
+ Your job is to read this codebase deeply, understand how code flows between components, and annotate it with GuardLink (GAL) security annotations that accurately represent the security posture.
79
+
80
+ This is NOT a vulnerability scanner. You are building a living threat model embedded in the code itself.
81
+ Annotations capture what COULD go wrong, what controls exist, and how data moves — not just confirmed bugs.
49
82
 
50
- ${refDoc ? '## GuardLink Reference\n\n' + refDoc.slice(0, 4000) + '\n\n' : ''}## Current State
51
- ${modelSummary}${existingIds}
83
+ ${refDoc ? '## GuardLink Annotation Language Reference\n\n' + refDoc.slice(0, 4000) + '\n\n' : ''}## Current State
84
+ ${modelSummary}${existingIds}${existingFlows}${existingExposures}
52
85
 
53
- ## Task
86
+ ## Your Task
54
87
  ${userPrompt}
55
88
 
56
- ## PRECISE Annotation Syntax (follow EXACTLY)
89
+ ## HOW TO THINK Flow-First Threat Modeling
90
+
91
+ Before writing ANY annotation, you MUST understand the code deeply:
92
+
93
+ ### Step 1: Map the Architecture
94
+ Read ALL source files related to the area you're annotating. Trace:
95
+ - Entry points (HTTP handlers, CLI commands, message consumers, event listeners)
96
+ - Data paths (how user input flows through functions, classes, middleware, to storage or output)
97
+ - Exit points (database writes, API calls, file I/O, rendered templates, responses)
98
+ - Class hierarchies, inherited methods, shared utilities, middleware chains
99
+ - Configuration and environment variable usage
100
+
101
+ ### Step 2: Identify Trust Boundaries
102
+ Look for where trust changes:
103
+ - External user → application code (HTTP boundary)
104
+ - Application → database (data layer boundary)
105
+ - Service → service (network boundary)
106
+ - Frontend → backend (client/server boundary)
107
+ - Application → third-party API (vendor boundary)
108
+ - Internal code → spawned process (process boundary)
109
+
110
+ ### Step 3: Identify What Could Go Wrong
111
+ At each boundary crossing and data transformation, ask:
112
+ - What if this input is malicious? (@exposes)
113
+ - What validation/sanitization exists? (@mitigates)
114
+ - What sensitive data passes through here? (@handles)
115
+ - Is there an assumption that could be violated? (@assumes)
116
+ - Has the team accepted this risk intentionally? (@accepts)
117
+ - Is this risk handled by someone else? (@transfers)
118
+
119
+ ### Step 4: Write Coupled Annotation Blocks
120
+ NEVER write a single annotation in isolation. Every annotated location should tell a complete story.
121
+
122
+ ## ANNOTATION STYLE GUIDE — Write Like a Developer
123
+
124
+ ### Always Couple Annotations Together
125
+ A file's doc-block should paint the full security picture of that module. Group annotations logically:
126
+
127
+ \`\`\`
128
+ // @shield:begin -- "Example annotation block for reference, excluded from parsing"
129
+ //
130
+ // GOOD — Complete story at a single code location:
131
+ // @exposes #auth-api to #sqli [P1] cwe:CWE-89 -- "User-supplied email passed to findUser() query builder"
132
+ // @mitigates #auth-api against #sqli using #input-validation -- "Zod schema validates email format before query"
133
+ // @flows User_Input -> #auth-api via POST./login -- "Login form submits credentials"
134
+ // @flows #auth-api -> #user-db via TypeORM.findOne -- "Authenticated user lookup"
135
+ // @handles pii on #auth-api -- "Processes email, password, session tokens"
136
+ // @comment -- "Password comparison uses bcrypt.compare with timing-safe equality"
137
+ //
138
+ // BAD — Isolated annotation with no context:
139
+ // @exposes #auth-api to #sqli -- "SQL injection possible"
140
+ //
141
+ // @shield:end
142
+ \`\`\`
143
+
144
+ ### Description Style — Reference Actual Code
145
+ Descriptions must reference the real code: function names, variable names, libraries, mechanisms.
146
+
147
+ \`\`\`
148
+ // @shield:begin -- "Description examples, excluded from parsing"
149
+ //
150
+ // GOOD: -- "req.body.token passed to jwt.verify() without audience check"
151
+ // GOOD: -- "bcrypt rounds set to 12 via BCRYPT_COST env var"
152
+ // GOOD: -- "Rate limiter uses express-rate-limit at 100req/15min on /api/*"
153
+ //
154
+ // BAD: -- "Input not validated" (too vague — WHICH input? WHERE?)
155
+ // BAD: -- "Uses encryption" (WHAT encryption? On WHAT data?)
156
+ // BAD: -- "Security vulnerability exists" (meaningless — be specific)
157
+ //
158
+ // @shield:end
159
+ \`\`\`
160
+
161
+ ### @flows — Stitch the Complete Data Path
162
+ @flows is the backbone of the threat model. Trace data movement accurately:
163
+
164
+ \`\`\`
165
+ // @shield:begin -- "Flow examples, excluded from parsing"
166
+ //
167
+ // Trace a request through the full stack:
168
+ // @flows User_Browser -> #api-gateway via HTTPS -- "Client sends auth request"
169
+ // @flows #api-gateway -> #auth-service via internal.gRPC -- "Gateway forwards to auth microservice"
170
+ // @flows #auth-service -> #user-db via pg.query -- "Looks up user record by email"
171
+ // @flows #auth-service -> #session-store via redis.set -- "Stores session token with TTL"
172
+ // @flows #auth-service -> User_Browser via Set-Cookie -- "Returns session cookie to client"
173
+ //
174
+ // @shield:end
175
+ \`\`\`
176
+
177
+ ### @boundary — Mark Every Trust Zone Crossing
178
+ Place @boundary annotations where trust level changes between two components:
179
+
180
+ \`\`\`
181
+ // @shield:begin -- "Boundary examples, excluded from parsing"
182
+ //
183
+ // @boundary between #api-gateway and External_Internet (#public-boundary) -- "TLS termination, rate limiting at edge"
184
+ // @boundary between #backend and #database (#data-boundary) -- "Application to persistence layer, connection pooling via pgBouncer"
185
+ // @boundary between #app and #payment-provider (#vendor-boundary) -- "PCI-DSS scope boundary, tokenized card data only"
186
+ //
187
+ // @shield:end
188
+ \`\`\`
57
189
 
58
- Definitions go in .guardlink/definitions.js (or .py/.rs). Source files use only relationship verbs.
190
+ ### Where to Place Annotations
191
+ Annotations go in the file's top doc-block comment OR directly above the security-relevant code:
59
192
 
60
- ### Definitions
61
193
  \`\`\`
62
- // @shield:begin -- "Example annotations for agent prompt, excluded from parsing"
63
- // @asset Server.Auth (#auth) -- "Authentication service"
64
- // @threat SQL_Injection (#sqli) [P0] cwe:CWE-89 -- "Unsanitized input in SQL"
65
- // @control Prepared_Statements (#prepared-stmts) -- "Parameterized queries"
194
+ // @shield:begin -- "Placement examples, excluded from parsing"
195
+ //
196
+ // FILE-LEVEL (top doc-block) for module-wide security properties:
197
+ // Place @exposes, @mitigates, @flows, @handles, @boundary that describe the module as a whole
198
+ //
199
+ // INLINE (above specific functions/methods) — for function-specific concerns:
200
+ // Place @exposes, @mitigates above the exact function where the risk or control lives
201
+ // Place @comment above tricky security-relevant code to explain intent
202
+ //
66
203
  // @shield:end
67
204
  \`\`\`
68
205
 
69
- ### Relationships (use in source files)
206
+ ### Severity Be Honest, Not Alarmist
207
+ Annotations capture what COULD go wrong, calibrated to realistic risk:
208
+ - **[P0] / [critical]**: Directly exploitable by external attacker, severe impact (RCE, auth bypass, data breach)
209
+ - **[P1] / [high]**: Exploitable with some conditions, significant impact (privilege escalation, data leak)
210
+ - **[P2] / [medium]**: Requires specific conditions or insider access (SSRF, info disclosure)
211
+ - **[P3] / [low]**: Minor impact or very difficult to exploit (timing side-channels, verbose errors)
212
+
213
+ Don't rate everything P0. A SQL injection in an admin-only internal tool is different from one in a public API.
214
+
215
+ ### @comment — Always Add Context
216
+ Every annotation block should include at least one @comment explaining non-obvious security decisions, assumptions, or context that helps future developers (and AI tools) understand the "why".
217
+
218
+ ### @shield — DO NOT USE Unless Explicitly Asked
219
+ @shield and @shield:begin/@shield:end block AI coding assistants from reading the annotated code.
220
+ This means any shielded code becomes invisible to AI tools — they cannot analyze, refactor, or annotate it.
221
+ Do NOT add @shield annotations unless the user has EXPLICITLY requested it (e.g., "shield the crypto module").
222
+ Adding @shield on your own initiative would actively harm the threat model by creating blind spots where AI cannot help.
223
+
224
+ ## PRECISE GAL Syntax
225
+
226
+ Definitions go in .guardlink/definitions.{ts,js,py,rs}. Source files use only relationship verbs.
227
+
228
+ ### Definitions (in .guardlink/definitions file)
70
229
  \`\`\`
71
- // @shield:begin -- "Example annotations for agent prompt, excluded from parsing"
230
+ // @shield:begin -- "Definition syntax examples, excluded from parsing"
231
+ // @asset Server.Auth (#auth) -- "Authentication service handling login and session management"
232
+ // @threat SQL_Injection (#sqli) [P0] cwe:CWE-89 -- "Unsanitized input reaches SQL query builder"
233
+ // @control Prepared_Statements (#prepared-stmts) -- "Parameterized queries via ORM or driver placeholders"
234
+ // @shield:end
235
+ \`\`\`
236
+
237
+ ### Relationships (in source files)
238
+ \`\`\`
239
+ // @shield:begin -- "Relationship syntax examples, excluded from parsing"
72
240
  // @exposes #auth to #sqli [P0] cwe:CWE-89 owasp:A03:2021 -- "User input concatenated into query"
73
- // @mitigates #auth against #sqli using #prepared-stmts -- "Uses parameterized queries"
241
+ // @mitigates #auth against #sqli using #prepared-stmts -- "Uses parameterized queries via sqlx"
242
+ // @accepts #timing-attack on #auth -- "Acceptable given bcrypt constant-time comparison"
243
+ // @transfers #ddos from #api to #cdn -- "Cloudflare handles L7 DDoS mitigation"
74
244
  // @flows req.body.username -> db.query via string-concat -- "User input flows to SQL"
75
- // @boundary between #frontend and #api (#trust-boundary) -- "Public/private boundary"
76
- // @handles pii on #auth -- "Processes user credentials"
77
- // @comment -- "TODO: add rate limiting to prevent brute force"
245
+ // @boundary between #frontend and #api (#web-boundary) -- "TLS-terminated public/private boundary"
246
+ // @handles pii on #auth -- "Processes email, password, session tokens"
247
+ // @validates #prepared-stmts for #auth -- "Integration test sqlInjectionTest.ts confirms parameterized queries block SQLi payloads"
248
+ // @audit #auth -- "Session token rotation logic needs cryptographic review"
249
+ // @assumes #auth -- "Upstream API gateway has already validated TLS and rate-limited requests"
250
+ // @owns security-team for #auth -- "Security team reviews all auth PRs"
251
+ // @comment -- "Password hashing uses bcrypt with cost factor 12, migration from SHA256 completed in v2.1"
78
252
  // @shield:end
79
253
  \`\`\`
80
254
 
@@ -84,13 +258,13 @@ Definitions go in .guardlink/definitions.js (or .py/.rs). Source files use only
84
258
  WRONG: \`@boundary api -- "desc"\` (only one argument — will NOT parse)
85
259
  RIGHT: \`@boundary between #api and #client (#api-boundary) -- "Trust boundary"\`
86
260
 
87
- 2. **@flows is ONE source ONE target per line**: \`@flows <source> -> <target> via <mechanism>\`.
261
+ 2. **@flows is ONE source -> ONE target per line**: \`@flows <source> -> <target> via <mechanism>\`.
88
262
  WRONG: \`@flows A -> B, C -> D -- "desc"\` (commas not supported)
89
263
  RIGHT: \`@flows A -> B via mechanism -- "desc"\` (one per line, repeat for multiple)
90
264
 
91
265
  3. **@exposes / @mitigates require DEFINED #id refs**: Every \`#id\` you reference must exist as a definition.
92
266
  Before using \`@exposes #app to #sqli\`, ensure \`@threat SQL_Injection (#sqli)\` exists in definitions.
93
- Add new definitions to .guardlink/definitions.js FIRST, then reference them in source files.
267
+ Add new definitions to the .guardlink/definitions file FIRST, then reference them in source files.
94
268
 
95
269
  4. **Severity in square brackets**: \`[P0]\` \`[P1]\` \`[P2]\` \`[P3]\` or \`[critical]\` \`[high]\` \`[medium]\` \`[low]\`.
96
270
  Goes AFTER the threat ref in @exposes: \`@exposes #app to #sqli [P0] cwe:CWE-89\`
@@ -108,13 +282,31 @@ Definitions go in .guardlink/definitions.js (or .py/.rs). Source files use only
108
282
 
109
283
  8. **External refs are space-separated after severity**: \`cwe:CWE-89 owasp:A03:2021 capec:CAPEC-66\`
110
284
 
285
+ 9. **@comment always needs -- and quotes**: \`@comment -- "your note here"\`.
286
+ A bare \`@comment\` without description is valid but useless. Always include context.
287
+
288
+ 10. **One annotation per comment line.** Do NOT put two @verbs on the same line.
289
+
111
290
  ## Workflow
112
- 1. Read existing definitions in .guardlink/definitions.js — reuse existing IDs
113
- 2. Add any NEW threat/control definitions FIRST
114
- 3. Then add relationship annotations (@exposes, @mitigates, @flows, etc.) in source files
115
- 4. Use the project's comment style (// for JS/TS, # for Python, etc.)
116
- 5. Run guardlink_validate (MCP) or \`guardlink validate\` to check for errors
117
- 6. Fix any validation errors before finishing
291
+
292
+ 1. **Read first, annotate second.** Read ALL related source files before writing any annotation.
293
+ Trace the full call chain: entry point middleware handler → service → repository → database.
294
+ Understand class hierarchies, shared utilities, and configuration.
295
+
296
+ 2. **Read existing definitions** in the .guardlink/definitions file — reuse existing IDs, never duplicate.
297
+
298
+ 3. **Add NEW definitions FIRST** if you need new assets, threats, or controls.
299
+ Group related definitions together with section comments.
300
+
301
+ 4. **Annotate in coupled blocks.** For each security-relevant location, write the complete story:
302
+ @exposes + @mitigates (or @accepts) + @flows + @comment at minimum.
303
+ Think: "what's the risk, what's the defense, how does data flow here, and what should the next developer know?"
304
+
305
+ 5. **Use the project's comment style** (// for JS/TS/Go/Rust, # for Python/Ruby/Shell, etc.)
306
+
307
+ 6. **Run validation** via guardlink_validate (MCP) or \`guardlink validate\` to check for errors.
308
+
309
+ 7. **Fix any validation errors** before finishing — especially dangling refs and malformed syntax.
118
310
  `;
119
311
  }
120
312
  //# sourceMappingURL=prompts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/agents/prompts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/agents/prompts.ts"],"names":[],"mappings":"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"}
@@ -120,7 +120,7 @@ export function generateSarif(model, diagnostics = [], danglingRefs = [], option
120
120
  tool: {
121
121
  driver: {
122
122
  name: 'GuardLink',
123
- version: '1.0.0',
123
+ version: '1.1.0',
124
124
  informationUri: 'https://guardlink.bugb.io',
125
125
  rules: RULES,
126
126
  },
package/dist/cli/index.js CHANGED
@@ -24,7 +24,7 @@
24
24
  import { Command } from 'commander';
25
25
  import { resolve, basename } from 'node:path';
26
26
  import { readFileSync, existsSync } from 'node:fs';
27
- import { parseProject } from '../parser/index.js';
27
+ import { parseProject, findDanglingRefs, findUnmitigatedExposures } from '../parser/index.js';
28
28
  import { initProject, detectProject, promptAgentSelection } from '../init/index.js';
29
29
  import { generateReport, generateMermaid } from '../report/index.js';
30
30
  import { diffModels, formatDiff, formatDiffMarkdown, parseAtRef } from '../diff/index.js';
@@ -80,7 +80,7 @@ function detectProjectName(root, explicit) {
80
80
  program
81
81
  .name('guardlink')
82
82
  .description('GuardLink — Security annotations for code. Threat modeling that lives in your codebase.')
83
- .version('1.0.0')
83
+ .version('1.1.0')
84
84
  .addHelpText('before', gradient(['#00ff41', '#00d4ff'])(ASCII_LOGO));
85
85
  // ─── init ────────────────────────────────────────────────────────────
86
86
  program
@@ -764,58 +764,4 @@ function printStatus(model) {
764
764
  console.log(`Comments: ${model.comments.length}`);
765
765
  console.log(`Shields: ${model.shields.length}`);
766
766
  }
767
- function findDanglingRefs(model) {
768
- const diagnostics = [];
769
- // Collect all defined IDs
770
- const definedIds = new Set();
771
- for (const a of model.assets)
772
- if (a.id)
773
- definedIds.add(a.id);
774
- for (const t of model.threats)
775
- if (t.id)
776
- definedIds.add(t.id);
777
- for (const c of model.controls)
778
- if (c.id)
779
- definedIds.add(c.id);
780
- for (const b of model.boundaries)
781
- if (b.id)
782
- definedIds.add(b.id);
783
- // Check all references
784
- const checkRef = (ref, loc) => {
785
- if (ref.startsWith('#')) {
786
- const id = ref.slice(1);
787
- if (!definedIds.has(id)) {
788
- diagnostics.push({
789
- level: 'warning',
790
- message: `Dangling reference: #${id} is never defined`,
791
- file: loc.file,
792
- line: loc.line,
793
- });
794
- }
795
- }
796
- };
797
- for (const m of model.mitigations) {
798
- checkRef(m.threat, m.location);
799
- if (m.control)
800
- checkRef(m.control, m.location);
801
- }
802
- for (const e of model.exposures)
803
- checkRef(e.threat, e.location);
804
- for (const a of model.acceptances)
805
- checkRef(a.threat, a.location);
806
- for (const t of model.transfers)
807
- checkRef(t.threat, t.location);
808
- for (const v of model.validations)
809
- checkRef(v.control, v.location);
810
- return diagnostics;
811
- }
812
- function findUnmitigatedExposures(model) {
813
- // Build set of (asset, threat) pairs that are mitigated or accepted
814
- const mitigated = new Set();
815
- for (const m of model.mitigations)
816
- mitigated.add(`${m.asset}::${m.threat}`);
817
- for (const a of model.acceptances)
818
- mitigated.add(`${a.asset}::${a.threat}`);
819
- return model.exposures.filter(e => !mitigated.has(`${e.asset}::${e.threat}`));
820
- }
821
767
  //# sourceMappingURL=index.js.map