@deftai/directive-content 0.55.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 (250) hide show
  1. package/.agents/skills/deft/SKILL.md +6 -0
  2. package/.agents/skills/deft-directive-article-review/SKILL.md +11 -0
  3. package/.agents/skills/deft-directive-build/SKILL.md +10 -0
  4. package/.agents/skills/deft-directive-cost/SKILL.md +12 -0
  5. package/.agents/skills/deft-directive-debug/SKILL.md +13 -0
  6. package/.agents/skills/deft-directive-gh-arch/SKILL.md +11 -0
  7. package/.agents/skills/deft-directive-gh-slice/SKILL.md +10 -0
  8. package/.agents/skills/deft-directive-glossary/SKILL.md +10 -0
  9. package/.agents/skills/deft-directive-interview/SKILL.md +9 -0
  10. package/.agents/skills/deft-directive-pre-pr/SKILL.md +9 -0
  11. package/.agents/skills/deft-directive-refinement/SKILL.md +10 -0
  12. package/.agents/skills/deft-directive-release/SKILL.md +12 -0
  13. package/.agents/skills/deft-directive-review-cycle/SKILL.md +10 -0
  14. package/.agents/skills/deft-directive-setup/SKILL.md +10 -0
  15. package/.agents/skills/deft-directive-swarm/SKILL.md +10 -0
  16. package/.agents/skills/deft-directive-sync/SKILL.md +9 -0
  17. package/.agents/skills/deft-directive-triage/SKILL.md +9 -0
  18. package/.agents/skills/deft-directive-write-skill/SKILL.md +9 -0
  19. package/LICENSE.md +22 -0
  20. package/QUICK-START.md +167 -0
  21. package/UPGRADING.md +517 -0
  22. package/coding/build-output.md +28 -0
  23. package/coding/coding.md +235 -0
  24. package/coding/debugging.md +110 -0
  25. package/coding/holzmann.md +96 -0
  26. package/coding/hygiene.md +127 -0
  27. package/coding/security.md +158 -0
  28. package/coding/testing.md +162 -0
  29. package/coding/toolchain.md +44 -0
  30. package/commands.md +300 -0
  31. package/context/context.md +57 -0
  32. package/context/deterministic-split.md +67 -0
  33. package/context/examples.md +26 -0
  34. package/context/fractal-summaries.md +69 -0
  35. package/context/long-horizon.md +46 -0
  36. package/context/spec-deltas.md +177 -0
  37. package/context/tool-design.md +34 -0
  38. package/context/working-memory.md +62 -0
  39. package/contracts/boundary-maps.md +65 -0
  40. package/contracts/deterministic-questions.md +59 -0
  41. package/contracts/hierarchy.md +77 -0
  42. package/conventions/content-manifest.json +399 -0
  43. package/conventions/machine-generated-banner.md +130 -0
  44. package/conventions/references.md +120 -0
  45. package/conventions/rule-ownership.json +382 -0
  46. package/conventions/task-caching.md +43 -0
  47. package/conventions/vbrief-filenames.md +70 -0
  48. package/deployments/README.md +37 -0
  49. package/deployments/agentuity/README.md +138 -0
  50. package/deployments/agentuity/via-cli.md +380 -0
  51. package/deployments/agentuity/via-cloud.md +425 -0
  52. package/deployments/agentuity/via-github-actions.md +664 -0
  53. package/deployments/agentuity/via-gravity-network.md +606 -0
  54. package/deployments/agentuity/via-vpc.md +607 -0
  55. package/deployments/aws/README.md +38 -0
  56. package/deployments/aws/via-app-runner.md +612 -0
  57. package/deployments/aws/via-ecs-fargate.md +561 -0
  58. package/deployments/aws/via-elastic-beanstalk.md +628 -0
  59. package/deployments/aws/via-lambda.md +649 -0
  60. package/deployments/azure/README.md +37 -0
  61. package/deployments/azure/via-aks.md +390 -0
  62. package/deployments/azure/via-app-service.md +564 -0
  63. package/deployments/azure/via-container-apps.md +599 -0
  64. package/deployments/azure/via-functions.md +552 -0
  65. package/deployments/cloud-gov/README.md +63 -0
  66. package/deployments/cloud-gov/agents/compliance-docs.md +154 -0
  67. package/deployments/cloud-gov/agents.md +39 -0
  68. package/deployments/cloud-gov/cicd.md +64 -0
  69. package/deployments/cloud-gov/deployment.md +150 -0
  70. package/deployments/cloud-gov/logging.md +43 -0
  71. package/deployments/cloud-gov/manifest.md +121 -0
  72. package/deployments/cloud-gov/overview.md +58 -0
  73. package/deployments/cloud-gov/security.md +46 -0
  74. package/deployments/cloud-gov/services.md +72 -0
  75. package/deployments/cloud-gov/upstream/README.md +18 -0
  76. package/deployments/cloudflare/README.md +33 -0
  77. package/deployments/cloudflare/via-dashboard.md +83 -0
  78. package/deployments/cloudflare/via-git.md +90 -0
  79. package/deployments/cloudflare/via-github-actions.md +185 -0
  80. package/deployments/cloudflare/via-terraform.md +157 -0
  81. package/deployments/cloudflare/via-wrangler.md +165 -0
  82. package/deployments/fly-io/README.md +37 -0
  83. package/deployments/fly-io/via-dockerfile.md +648 -0
  84. package/deployments/fly-io/via-flyctl.md +653 -0
  85. package/deployments/fly-io/via-github-actions.md +695 -0
  86. package/deployments/fly-io/via-multi-region.md +598 -0
  87. package/deployments/google/README.md +34 -0
  88. package/deployments/google/via-app-engine.md +42 -0
  89. package/deployments/google/via-cloud-functions.md +23 -0
  90. package/deployments/google/via-cloud-run.md +330 -0
  91. package/deployments/google/via-gke.md +23 -0
  92. package/deployments/netlify/README.md +99 -0
  93. package/deployments/netlify/via-cli.md +17 -0
  94. package/deployments/netlify/via-functions.md +19 -0
  95. package/deployments/netlify/via-git.md +25 -0
  96. package/deployments/vercel/README.md +90 -0
  97. package/deployments/vercel/via-api.md +16 -0
  98. package/deployments/vercel/via-cli.md +17 -0
  99. package/deployments/vercel/via-git.md +24 -0
  100. package/docs/BROWNFIELD.md +179 -0
  101. package/docs/getting-started.md +137 -0
  102. package/docs/good-agents-md.md +137 -0
  103. package/events/README.md +89 -0
  104. package/events/event-record.schema.json +26 -0
  105. package/events/registry.json +166 -0
  106. package/events/registry.schema.json +71 -0
  107. package/glossary.md +145 -0
  108. package/incidents/README.md +81 -0
  109. package/incidents/_template.md +38 -0
  110. package/interfaces/cli.md +104 -0
  111. package/interfaces/rest.md +212 -0
  112. package/interfaces/tui.md +242 -0
  113. package/interfaces/web.md +123 -0
  114. package/languages/6502-DASM.md +132 -0
  115. package/languages/c.md +235 -0
  116. package/languages/commands.md +23 -0
  117. package/languages/cpp.md +132 -0
  118. package/languages/csharp.md +259 -0
  119. package/languages/dart.md +183 -0
  120. package/languages/delphi.md +218 -0
  121. package/languages/elixir.md +208 -0
  122. package/languages/go.md +78 -0
  123. package/languages/java.md +278 -0
  124. package/languages/javascript.md +163 -0
  125. package/languages/julia.md +175 -0
  126. package/languages/kotlin.md +193 -0
  127. package/languages/markdown.md +168 -0
  128. package/languages/mermaid.md +146 -0
  129. package/languages/officejs.md +392 -0
  130. package/languages/python.md +209 -0
  131. package/languages/r.md +163 -0
  132. package/languages/rust.md +216 -0
  133. package/languages/sql.md +216 -0
  134. package/languages/swift.md +153 -0
  135. package/languages/typescript.md +132 -0
  136. package/languages/vba.md +279 -0
  137. package/languages/vhdl.md +180 -0
  138. package/languages/visual-basic.md +151 -0
  139. package/languages/zig.md +196 -0
  140. package/meta/SOUL.md +27 -0
  141. package/meta/code-field.md +44 -0
  142. package/meta/morals.md +40 -0
  143. package/meta/philosophy.md +39 -0
  144. package/meta/project.md +49 -0
  145. package/meta/ralph.md +223 -0
  146. package/meta/security.md +80 -0
  147. package/meta/versioning.md +326 -0
  148. package/package.json +22 -0
  149. package/packs/lessons/lessons-pack-0.1.json +553 -0
  150. package/packs/patterns/patterns-pack-0.1.json +57 -0
  151. package/packs/rules/rules-pack-0.1.json +4767 -0
  152. package/packs/skills/skills-pack-0.1.json +262 -0
  153. package/packs/strategies/strategies-pack-0.1.json +167 -0
  154. package/packs/swarm-spec/swarm-spec-pack-0.1.json +17 -0
  155. package/patterns/executor-layer-credentials.md +227 -0
  156. package/patterns/llm-app.md +156 -0
  157. package/patterns/multi-agent.md +278 -0
  158. package/patterns/prompt-assembly-layer-ordering.md +154 -0
  159. package/patterns/role-as-overlay.md +179 -0
  160. package/platforms/2600.md +137 -0
  161. package/platforms/unity.md +329 -0
  162. package/references/composer-skill-porting.md +152 -0
  163. package/references/cost-models.md +163 -0
  164. package/references/ip-risk.md +246 -0
  165. package/references/plain-english-ux.md +275 -0
  166. package/resilience/context-pruning.md +67 -0
  167. package/resilience/continue-here.md +62 -0
  168. package/scm/changelog.md +276 -0
  169. package/scm/git.md +139 -0
  170. package/scm/github.md +265 -0
  171. package/secrets/.gitkeep +0 -0
  172. package/skills/deft-build/SKILL.md +20 -0
  173. package/skills/deft-directive-article-review/SKILL.md +156 -0
  174. package/skills/deft-directive-build/SKILL.md +302 -0
  175. package/skills/deft-directive-cost/SKILL.md +201 -0
  176. package/skills/deft-directive-debug/SKILL.md +140 -0
  177. package/skills/deft-directive-decompose/SKILL.md +96 -0
  178. package/skills/deft-directive-gh-arch/SKILL.md +160 -0
  179. package/skills/deft-directive-gh-slice/SKILL.md +199 -0
  180. package/skills/deft-directive-glossary/SKILL.md +118 -0
  181. package/skills/deft-directive-interview/SKILL.md +528 -0
  182. package/skills/deft-directive-pre-pr/SKILL.md +131 -0
  183. package/skills/deft-directive-probe/SKILL.md +127 -0
  184. package/skills/deft-directive-refinement/SKILL.md +403 -0
  185. package/skills/deft-directive-release/SKILL.md +266 -0
  186. package/skills/deft-directive-review-cycle/SKILL.md +401 -0
  187. package/skills/deft-directive-setup/SKILL.md +717 -0
  188. package/skills/deft-directive-swarm/SKILL.md +989 -0
  189. package/skills/deft-directive-sync/SKILL.md +288 -0
  190. package/skills/deft-directive-triage/SKILL.md +137 -0
  191. package/skills/deft-directive-write-skill/SKILL.md +169 -0
  192. package/skills/deft-interview/SKILL.md +16 -0
  193. package/skills/deft-pre-pr/SKILL.md +16 -0
  194. package/skills/deft-review-cycle/SKILL.md +16 -0
  195. package/skills/deft-roadmap-refresh/SKILL.md +16 -0
  196. package/skills/deft-setup/SKILL.md +20 -0
  197. package/skills/deft-swarm/SKILL.md +16 -0
  198. package/skills/deft-sync/SKILL.md +16 -0
  199. package/strategies/README.md +83 -0
  200. package/strategies/artifact-guards.md +85 -0
  201. package/strategies/bdd.md +115 -0
  202. package/strategies/brownfield.md +7 -0
  203. package/strategies/discuss.md +129 -0
  204. package/strategies/emit-hints.md +69 -0
  205. package/strategies/enterprise.md +193 -0
  206. package/strategies/interview.md +551 -0
  207. package/strategies/map.md +179 -0
  208. package/strategies/probe.md +151 -0
  209. package/strategies/rapid.md +155 -0
  210. package/strategies/research.md +155 -0
  211. package/strategies/roadmap.md +9 -0
  212. package/strategies/speckit.md +437 -0
  213. package/strategies/v0-20-contract.md +134 -0
  214. package/strategies/yolo.md +169 -0
  215. package/swarm/swarm.md +300 -0
  216. package/templates/COST-ESTIMATE.md +114 -0
  217. package/templates/PULL_REQUEST_TEMPLATE.md +35 -0
  218. package/templates/agent-prompt-preamble.md +409 -0
  219. package/templates/agents-entry.md +211 -0
  220. package/templates/agents-entry.placeholders.md +75 -0
  221. package/templates/embed.go +20 -0
  222. package/templates/embed_test.go +36 -0
  223. package/templates/make-spec-example.md +9 -0
  224. package/templates/make-spec.md +246 -0
  225. package/templates/project.md.template +52 -0
  226. package/templates/specification.md +1 -0
  227. package/templates/swarm-greptile-poller-prompt.md +556 -0
  228. package/templates/user.md.template +31 -0
  229. package/tools/RWLDL.md +80 -0
  230. package/tools/greptile.md +141 -0
  231. package/tools/installer.md +23 -0
  232. package/tools/taskfile-migration.md +32 -0
  233. package/tools/taskfile.md +185 -0
  234. package/tools/telemetry.md +285 -0
  235. package/vbrief/schemas/cache-meta.schema.json +137 -0
  236. package/vbrief/schemas/candidates.schema.json +130 -0
  237. package/vbrief/schemas/codebase-map.schema.json +213 -0
  238. package/vbrief/schemas/lessons-pack.schema.json +134 -0
  239. package/vbrief/schemas/patterns-pack.schema.json +84 -0
  240. package/vbrief/schemas/rules-pack.schema.json +105 -0
  241. package/vbrief/schemas/skills-pack.schema.json +94 -0
  242. package/vbrief/schemas/slices.schema.json +87 -0
  243. package/vbrief/schemas/strategies-pack.schema.json +89 -0
  244. package/vbrief/schemas/swarm-spec-pack.schema.json +84 -0
  245. package/vbrief/schemas/vbrief-core.schema.json +1022 -0
  246. package/vbrief/vbrief.md +684 -0
  247. package/verification/integration.md +76 -0
  248. package/verification/plan-checking.md +85 -0
  249. package/verification/uat.md +60 -0
  250. package/verification/verification.md +117 -0
@@ -0,0 +1,153 @@
1
+ # Swift Standards
2
+
3
+ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
4
+
5
+ **⚠️ See also**: [main.md](../../main.md) | [PROJECT.md](../../PROJECT.md) | [telemetry.md](../tools/telemetry.md)
6
+
7
+ **Stack**: Swift 5.9+/6.0+, SwiftPM; iOS: SwiftUI/UIKit; CLI: ArgumentParser; Testing: Swift Testing/XCTest
8
+
9
+ ## Standards
10
+
11
+ ### Documentation
12
+ - ! Follow [Swift API Design Guidelines](https://www.swift.org/documentation/api-design-guidelines/)
13
+ - ! Use Swift Markup comments (triple-slash `///`) for all public APIs
14
+ - ~ Document complexity of computed properties that are not O(1)
15
+
16
+ ### Testing
17
+ See [testing.md](../coding/testing.md).
18
+
19
+ - ! Use Swift Testing (`@Test`, `#expect`) for new tests (Swift 6+)
20
+ - ~ Use XCTest for UI tests, performance tests, and legacy codebases
21
+ - Files: `*Tests.swift` or `*_Tests.swift`
22
+
23
+ ### Coverage
24
+ - ! ≥85% coverage
25
+ - ! Count Sources/\*
26
+ - ! Exclude entry points, generated code, previews
27
+
28
+ ### Style
29
+ - ! Use SwiftLint + SwiftFormat
30
+ - ! Column limit: 100 characters
31
+ - ! Follow [Google Swift Style Guide](https://google.github.io/swift/) or [Kodeco Style Guide](https://github.com/kodecocodes/swift-style-guide)
32
+
33
+ ### Types
34
+ - ! Prefer `let` over `var` when value won't change
35
+ - ! Use strong typing (enums, type aliases, protocols)
36
+ - ⊗ Force unwrap (`!`) unless absolutely necessary
37
+ - ~ Use `guard let`/`if let` for optional unwrapping
38
+ - ~ Prefer `Result` or throwing functions for error handling
39
+
40
+ ### Concurrency
41
+ - ! Use Swift Concurrency (`async`/`await`) over GCD for new code
42
+ - ! Use `actor` for shared mutable state
43
+ - ! Use `@MainActor` for UI-related code
44
+ - ~ Use `Sendable` to mark thread-safe types
45
+ - ⊗ Use `@unchecked Sendable` without careful consideration
46
+ - ~ Enable strict concurrency checking (`SWIFT_STRICT_CONCURRENCY=complete`)
47
+
48
+ ### Telemetry
49
+ - See [telemetry.md](../tools/telemetry.md)
50
+ - ~ Structured logging (OSLog, swift-log) for production
51
+ - ~ Sentry.io for error tracking
52
+ - ? OpenTelemetry Swift for distributed tracing
53
+
54
+ ## Commands
55
+
56
+ See [commands.md](./commands.md).
57
+
58
+ ## Patterns
59
+
60
+ ### Testing
61
+ ```swift
62
+ // Swift Testing
63
+ @Test("login succeeds") func loginSuccess() async throws {
64
+ let result = try await AuthService().login(email: "test@a.com", password: "valid")
65
+ #expect(result.isSuccess)
66
+ }
67
+
68
+ @Test("prices", arguments: [(100, 0.1, 90), (200, 0.25, 150)])
69
+ func price(p: Int, d: Double, e: Int) { #expect(calculatePrice(p, discount: d) == e) }
70
+
71
+ // XCTest
72
+ final class UserTests: XCTestCase {
73
+ var sut: UserService!
74
+ override func setUp() { super.setUp(); sut = UserService() }
75
+ override func tearDown() { sut = nil; super.tearDown() }
76
+ func test_fetchUser() async throws {
77
+ let user = try await sut.fetchUser(id: "123")
78
+ XCTAssertEqual(user.name, "Test User")
79
+ }
80
+ }
81
+ ```
82
+
83
+ ### Concurrency & Error Handling
84
+ ```swift
85
+ actor Counter {
86
+ private var value = 0
87
+ func increment() -> Int { value += 1; return value }
88
+ }
89
+
90
+ @MainActor class ViewModel: ObservableObject {
91
+ @Published var data: [Item] = []
92
+ func loadData() async { data = await fetchItems() }
93
+ }
94
+
95
+ func fetchAll() async throws -> (User, [Post]) {
96
+ async let user = fetchUser(); async let posts = fetchPosts()
97
+ return try await (user, posts)
98
+ }
99
+
100
+ func loadConfig() throws -> Config {
101
+ guard let data = FileManager.default.contents(atPath: path) else { throw ConfigError.fileNotFound(path) }
102
+ return try JSONDecoder().decode(Config.self, from: data)
103
+ }
104
+ ```
105
+
106
+ ### Data Models
107
+ ```swift
108
+ struct User: Codable, Sendable, Equatable { let id: UUID; let name: String; let email: String }
109
+ enum LoadingState<T: Sendable>: Sendable { case idle, loading, success(T), failure(Error) }
110
+ ```
111
+
112
+ ## Package.swift
113
+
114
+ Key settings: `swift-tools-version: 5.9`, platforms `.iOS(.v17)/.macOS(.v14)`, enable `StrictConcurrency`.
115
+
116
+ ## Linter/Formatter Config
117
+
118
+ **`.swiftlint.yml`** key settings:
119
+ - Opt-in: `force_unwrapping`, `implicitly_unwrapped_optional`, `explicit_init`, `fatal_error_message`, `modifier_order`, `yoda_condition`
120
+ - Limits: line 120/150, type body 300/500, file 500/1000, function 50/100
121
+ - Excluded: `.build`, `DerivedData`, `Pods`, `Package.swift`
122
+
123
+ **`.swiftformat`** key settings:
124
+ - `--swiftversion 5.9`, `--indent 4`, `--maxwidth 100`
125
+ - `--wrapcollections before-first`, `--wraparguments before-first`
126
+ - Enabled: `isEmpty`, `redundantSelf`, `sortImports`, `trailingCommas`
127
+
128
+ ## Hygiene
129
+
130
+ **Types:**
131
+ - ⊗ Force unwrap `!` without a documented invariant proving non-nil — already in Standards; treat as hygiene blocker in review
132
+ - ⊗ `any Protocol` (existential) where a concrete type or `some Protocol` (opaque) is knowable (SE-0335)
133
+ - ~ Prefer `some` (opaque return type) over `any` when the concrete type is fixed at the call site
134
+
135
+ **Error handling:**
136
+ - ⊗ `try?` that silently discards errors in non-trivial paths — use `do { try } catch` and handle
137
+ - ⊗ `try!` outside tests without a compile-time guarantee of non-throwing
138
+ - ⊗ Empty `catch {}` blocks
139
+
140
+ **Dead code:**
141
+ - ~ Run `periphery scan` (`Periphery`) to detect unused declarations, types, and protocols
142
+ - ~ SwiftLint `unused_declaration` opt-in rule catches file-local dead code
143
+ - ⊗ `// swiftlint:disable unused_declaration` to suppress rather than remove dead code
144
+
145
+ ## Compliance Checklist
146
+
147
+ - ! Follow Swift API Design Guidelines for all public APIs
148
+ - ! Use Swift Markup comments for documentation
149
+ - ! See [testing.md](../coding/testing.md) for testing requirements
150
+ - ! Use SwiftLint and SwiftFormat
151
+ - ! Use Swift Concurrency (`async`/`await`, `actor`) for async code
152
+ - ⊗ Force unwrap optionals without justification
153
+ - ! Run `task check` before commit
@@ -0,0 +1,132 @@
1
+ # TypeScript Standards
2
+
3
+ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
4
+
5
+ **⚠️ See also**: [main.md](../../main.md) | [PROJECT.md](../../PROJECT.md) | [telemetry.md](../tools/telemetry.md)
6
+
7
+ **Stack**: TypeScript 5.0+, Vitest/Jest; Web: React 18+/Next.js; CLI: commander; Build: Vite/tsup
8
+
9
+ ## Standards
10
+
11
+ ### Documentation
12
+ - ! TSDoc comments for all exported APIs
13
+
14
+ ### Testing
15
+ See [testing.md](../coding/testing.md).
16
+
17
+ - ! Use Vitest (or Jest) + coverage
18
+ - Files: `*.spec.ts` or `*.test.ts`
19
+
20
+ ### Coverage
21
+ - ! ≥85% coverage
22
+ - ! Count src/\*
23
+ - ! Exclude entry points, scripts, generated code
24
+
25
+ ### Style
26
+ - ! Use ESLint + Prettier
27
+ - ~ Prefer functional over classes where practical
28
+
29
+ ### Types
30
+ - ! Use strict mode
31
+ - ⊗ Use `any` — including `as any` or `as unknown as T` casts to bypass type checking
32
+ - ~ Prefer `unknown` for inputs from untrusted sources; narrow with type guards before use
33
+ - ⊗ `unknown` as a function return type where the concrete type is knowable
34
+ - ⊗ `@ts-ignore` or `@ts-expect-error` without an inline comment explaining why it is safe
35
+
36
+ ### Telemetry
37
+ - See [telemetry.md](../tools/telemetry.md)
38
+ - ~ Structured logging (pino, winston) for production
39
+ - ~ Sentry.io for error tracking
40
+ - ? OpenTelemetry for distributed tracing
41
+
42
+ ## Commands
43
+
44
+ See [commands.md](./commands.md).
45
+
46
+ ## Patterns
47
+
48
+ **Parameterized Tests**: `test.each([[1,2],[3,4]])('case %s', (a,b) => {...})`
49
+ **Setup/Teardown**: `beforeEach(() => {})`, `afterEach(() => {})`, `beforeAll`, `afterAll`
50
+ **Mocking**: `vi.fn()`, `vi.mock('module')`, `vi.spyOn(obj, 'method')`
51
+ **React Testing**: `@testing-library/react` - `render()`, `screen`, `fireEvent`, `waitFor`
52
+ **Async**: `await` in tests, `waitFor(() => expect(...))` for async UI
53
+
54
+ ## tsconfig.json
55
+
56
+ ```json
57
+ {
58
+ "compilerOptions": {
59
+ "target": "ES2022",
60
+ "module": "ESNext",
61
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
62
+ "moduleResolution": "bundler",
63
+ "strict": true,
64
+ "noUncheckedIndexedAccess": true,
65
+ "noImplicitOverride": true,
66
+ "esModuleInterop": true,
67
+ "skipLibCheck": true,
68
+ "forceConsistentCasingInFileNames": true,
69
+ "resolveJsonModule": true,
70
+ "isolatedModules": true,
71
+ "outDir": "./dist",
72
+ "rootDir": "./src"
73
+ },
74
+ "include": ["src/**/*"],
75
+ "exclude": ["node_modules", "dist", "**/*.spec.ts"]
76
+ }
77
+ ```
78
+
79
+ ## package.json
80
+
81
+ ```json
82
+ {
83
+ "type": "module",
84
+ "scripts": {
85
+ "test": "vitest",
86
+ "test:coverage": "vitest --coverage",
87
+ "typecheck": "tsc --noEmit",
88
+ "lint": "eslint src --ext .ts,.tsx",
89
+ "fmt": "prettier --write 'src/**/*.{ts,tsx}'",
90
+ "build": "tsup src/index.ts --format esm,cjs --dts"
91
+ },
92
+ "devDependencies": {
93
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
94
+ "@typescript-eslint/parser": "^7.0.0",
95
+ "@vitest/coverage-v8": "^1.0.0",
96
+ "eslint": "^8.56.0",
97
+ "prettier": "^3.2.0",
98
+ "tsup": "^8.0.0",
99
+ "typescript": "^5.3.0",
100
+ "vitest": "^1.0.0"
101
+ }
102
+ }
103
+ ```
104
+
105
+ ## vitest.config.ts
106
+
107
+ Key settings: `globals: true`, `environment: "node"` (or `jsdom`), `coverage.provider: "v8"`, `thresholds: { lines: 85, functions: 85, branches: 85, statements: 85 }`, include `src/**/*.ts`, exclude tests.
108
+
109
+ ## .eslintrc.json
110
+
111
+ Key settings: `@typescript-eslint/parser`, extends `recommended` + `recommended-requiring-type-checking`, rules: `no-explicit-any: error`, `no-unused-vars: [error, { argsIgnorePattern: "^_" }]`, `explicit-function-return-type: [warn, { allowExpressions: true }]`.
112
+
113
+ ## Hygiene
114
+
115
+ **Dead code:**
116
+ - ~ Run `knip` to detect unused exports, files, and dependencies
117
+ - ~ Add `knip` as a `task hygiene` target; treat unused exports in library code as errors
118
+
119
+ **Circular dependencies:**
120
+ - ~ Run `madge --circular --exit-code src/` to detect cycles; resolve by extracting shared types to a lower-level module
121
+ - ⊗ Circular imports between modules — use dependency inversion (interfaces/types in a shared module)
122
+
123
+ **Error handling:**
124
+ - ⊗ Empty `catch` blocks or `catch (e) {}` — log or re-throw
125
+ - ⊗ Returning `null`, `undefined`, or a neutral default to mask a thrown error
126
+
127
+ ## Compliance Checklist
128
+
129
+ - ! Include TSDoc comments for all exported APIs
130
+ - ! Use strict TypeScript; ⊗ use `any`
131
+ - ! See [testing.md](../coding/testing.md) for testing requirements
132
+ - ! Run `task check` before commit
@@ -0,0 +1,279 @@
1
+ # VBA Standards
2
+
3
+ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
4
+
5
+ **⚠️ See also**: [main.md](../../main.md) | [PROJECT.md](../../PROJECT.md) | [telemetry.md](../tools/telemetry.md)
6
+
7
+ **Stack**: VBA 7.1 (Excel 2010+), 64-bit compatible; Testing: Rubberduck VBA or hand-rolled assert module; Source control: exported .bas/.cls/.frm files
8
+
9
+ **Note**: VBA is NOT VB.NET. The [visual-basic.md](./visual-basic.md) module covers VB.NET (.NET 8+, xUnit, Roslyn analyzers, `Option Strict On`, async/await). VBA has no `Try...Catch`, no generics, no async, no dependency injection, no package manager. These standards are written for VBA's actual capabilities.
10
+
11
+ ## Standards
12
+
13
+ ### Documentation
14
+ - ! Module-level header comment block on every module: purpose, author, date, dependencies
15
+ - ! Procedure-level comments on all `Public` subs and functions: purpose, parameters, return value, errors raised
16
+ - ~ Inline comments explain **why**, not **what** — VBA is readable enough without narrating every line
17
+ - ⊗ Orphan comments that describe code that was later changed or removed
18
+
19
+ ### Module Organization
20
+ - ! One responsibility per module — do not build "utility grab bag" modules
21
+ - ! Separate concerns: data access modules, business logic modules, formatting modules, UI modules (UserForms)
22
+ - ~ Modules < 300 lines ideal; ! modules < 500 lines maximum
23
+ - ! Prefix module names by responsibility: `mod_` (standard module), `cls_` (class module), `frm_` (UserForm)
24
+ - ~ Group related procedures within a module using comment-block section headers
25
+
26
+ ### Option Statements
27
+ - ! `Option Explicit` at the top of every module — no exceptions
28
+ - ⊗ Rely on implicit variable declarations — this is the single most common source of VBA bugs
29
+ - ? `Option Compare Text` when case-insensitive string comparison is the module's default behavior
30
+ - ⊗ `Option Base 1` — always use 0-based arrays and be explicit about bounds
31
+
32
+ ### Testing
33
+ - ! Every public procedure in a logic module MUST have a corresponding test
34
+ - ~ Use Rubberduck VBA for unit testing when available (provides `@TestModule`, `@TestMethod` annotations)
35
+ - ? When Rubberduck is unavailable, use a hand-rolled assert pattern (see §Patterns — Test Harness)
36
+ - ! Test modules live in a dedicated `tests/` export folder, prefixed `test_`
37
+ - ! Test procedures are named `Test_<ModuleName>_<Scenario>` (e.g., `Test_ModRevenue_GrowthRateZero`)
38
+
39
+ ### Coverage
40
+ - ! ≥ 70% of public procedures in logic modules have corresponding tests
41
+ - ! Exclude: UserForm event handlers, `Auto_Open`/`Workbook_Open` entry points, formatting-only procedures
42
+ - ~ 70% is the floor, not the target — VBA's testing limitations justify a lower bar than other languages but not zero
43
+
44
+ ### Style
45
+ - ! `PascalCase` for procedure names, module names, public variables, constants, enum members
46
+ - ! `camelCase` for local variables and parameters
47
+ - ! `m_camelCase` for module-level private variables
48
+ - ! `ALL_CAPS_SNAKE` for global constants: `Public Const MAX_RETRY_COUNT As Long = 3`
49
+ - ! Use `Long` not `Integer` — `Integer` is 16-bit and causes silent overflow on modern data sizes
50
+ - ! Use `String` not `Variant` when the type is known
51
+ - ⊗ Hungarian notation (`strName`, `intCount`, `rngData`) — it was standard in VBA culture but harms readability; use meaningful names instead
52
+ - ⊗ Single-letter variable names except `i`, `j`, `k` for loop counters
53
+ - ~ One blank line between procedures; two blank lines between section groups
54
+
55
+ ### Naming Conventions
56
+ - ! Procedure names are verb-first: `CalculateRevenue`, `FormatOutputSection`, `LoadPortfolioData`
57
+ - ! Boolean variables/functions prefixed with `Is`, `Has`, `Can`: `IsValid`, `HasHeader`, `CanProceed`
58
+ - ! Constants describe the value's purpose, not its magnitude: `MAX_PROJECTION_YEARS` not `FIVE`
59
+ - ⊗ Abbreviations in names unless universally understood in the domain: `CalcNPV` is fine, `CalcRev` is not — use `CalculateRevenue`
60
+
61
+ ### Type Safety
62
+ - ! Declare all variables with explicit types — `Dim x As Long`, never `Dim x`
63
+ - ! Use `Long` for all integer work (not `Integer`)
64
+ - ! Use `Double` for all floating-point work (not `Single`)
65
+ - ! Use early binding (`Dim dict As Scripting.Dictionary`) when the reference is always available
66
+ - ~ Use late binding (`Dim dict As Object: Set dict = CreateObject(...)`) only for optional dependencies or cross-version compatibility
67
+ - ⊗ `Variant` for variables whose type is known at design time
68
+ - ⊗ Implicit `Variant` from undeclared variables (enforced by `Option Explicit`)
69
+ - ~ Use `Enum` types for related constants: `Public Enum CellRole: crInput = 1: crAssumption = 2: ...`
70
+
71
+ ### Error Handling
72
+ - ! Every `Public Sub` and `Public Function` MUST have an error handler
73
+ - ! Use the `On Error GoTo ErrHandler` pattern with a labeled handler block at the end
74
+ - ! Error handlers MUST either: (a) raise a meaningful error to the caller, (b) log and recover, or (c) clean up and re-raise
75
+ - ⊗ `On Error Resume Next` as a blanket — it silently swallows every error
76
+ - ? `On Error Resume Next` for exactly one statement when checking existence (e.g., testing if a named range exists), followed immediately by `On Error GoTo 0` or `On Error GoTo ErrHandler`
77
+ - ! Always restore error handling after a `Resume Next` block: `On Error GoTo ErrHandler`
78
+ - ! Clean up resources (close files, restore `Application` state) in the handler or a cleanup label before exiting
79
+ - ⊗ `End` statement — it terminates all execution without cleanup. Use `Exit Sub`/`Exit Function`
80
+ - ~ Raise custom errors with `Err.Raise vbObjectError + N, Source, Description` for domain-specific failures
81
+
82
+ ### Application State Management
83
+ - ! Wrap bulk operations in `Application.ScreenUpdating = False` / `True`
84
+ - ! Wrap calculation-intensive operations in `Application.Calculation = xlCalculationManual` / `xlCalculationAutomatic`
85
+ - ! Wrap event-triggering operations in `Application.EnableEvents = False` / `True`
86
+ - ! Restore all `Application` state in error handlers — a crash with `ScreenUpdating = False` leaves Excel frozen
87
+ - ~ Use a guard pattern (see §Patterns — Application State Guard) to guarantee restore on all exit paths
88
+
89
+ ### Range Operations
90
+ - ! Use named ranges or table references (`ListObject`) — never hardcoded cell addresses in production code
91
+ - ⊗ Cell-by-cell read/write loops — read into a `Variant` array, process, write back as a block
92
+ - ! Use `Range.Value2` not `Range.Value` for numeric reads — `Value` applies date/currency coercion
93
+ - ~ Use `Intersect()` to check range overlap before operations
94
+ - ~ Use `Range.Resize()` and `Range.Offset()` for relative navigation instead of address arithmetic
95
+
96
+ ### Workbook / Worksheet References
97
+ - ! Always qualify worksheet references: `ThisWorkbook.Sheets("Data")`, never bare `Sheets("Data")`
98
+ - ! Use `ThisWorkbook` not `ActiveWorkbook` unless explicitly operating on a different workbook
99
+ - ⊗ `ActiveSheet`, `ActiveCell`, `Selection` in logic modules — these are UI-context-dependent and break when called programmatically
100
+ - ? `ActiveSheet` / `Selection` in UI-facing entry points only (ribbon callbacks, button handlers)
101
+
102
+ ### Security
103
+ - ⊗ Hardcode credentials, API keys, or connection strings in source modules
104
+ - ! Store secrets in environment variables, Windows Credential Manager, or a protected `secrets/` config file excluded from VCS
105
+ - ! Parameterize all SQL — never concatenate user input into query strings
106
+ - ⊗ `Shell()` or `CreateObject("WScript.Shell")` with unsanitized input
107
+
108
+ ## Source Control
109
+
110
+ VBA code lives inside `.xlsm` / `.xlam` binary containers. To participate in git workflows, modules must be exported to the filesystem.
111
+
112
+ - ! Export all VBA modules to `src/` as `.bas` (standard modules), `.cls` (class modules), `.frm` (UserForms) after every meaningful change
113
+ - ! Export test modules to `tests/` with the same convention
114
+ - ! The `.xlsm` / `.xlam` file is checked in alongside exports as the "built" artifact
115
+ - ! Taskfile targets: `task vba:export` (workbook → files), `task vba:import` (files → workbook)
116
+ - ~ Use a `_vba_manifest.json` listing all modules, their types, and export paths for round-trip integrity
117
+ - ⊗ Edit `.bas` files by hand and import without verifying — always round-trip through the workbook to catch compile errors
118
+ - ~ Pre-commit hook runs `task vba:export` to ensure exports are current
119
+
120
+ ## Commands
121
+
122
+ ```bash
123
+ task vba:export # Export VBA modules from .xlsm to src/ and tests/
124
+ task vba:import # Import .bas/.cls/.frm files into .xlsm
125
+ task vba:test # Run test suite (Rubberduck or custom harness)
126
+ task vba:compile-check # Open workbook and check for compile errors
127
+ task check # Pre-commit: export + compile-check + test
128
+ ```
129
+
130
+ ## Patterns
131
+
132
+ ### Error Handler
133
+ ```vb
134
+ Public Sub ProcessData(ByVal ws As Worksheet)
135
+ On Error GoTo ErrHandler
136
+
137
+ Dim appState As cls_ApplicationState
138
+ Set appState = GuardApplicationState() ' see Application State Guard
139
+
140
+ Dim data As Variant
141
+ data = ws.Range("DataTable").Value2
142
+
143
+ ' ... business logic ...
144
+
145
+ appState.Restore
146
+ Exit Sub
147
+ ErrHandler:
148
+ If Not appState Is Nothing Then appState.Restore
149
+ Err.Raise Err.Number, "mod_DataProcessor.ProcessData", _
150
+ "Failed to process data on " & ws.Name & ": " & Err.Description
151
+ End Sub
152
+ ```
153
+
154
+ ### Application State Guard
155
+ ```vb
156
+ ' cls_ApplicationState — guarantees restore on all exit paths
157
+ Private m_screenUpdating As Boolean
158
+ Private m_calculation As XlCalculation
159
+ Private m_enableEvents As Boolean
160
+
161
+ Public Sub Capture()
162
+ m_screenUpdating = Application.ScreenUpdating
163
+ m_calculation = Application.Calculation
164
+ m_enableEvents = Application.EnableEvents
165
+ Application.ScreenUpdating = False
166
+ Application.Calculation = xlCalculationManual
167
+ Application.EnableEvents = False
168
+ End Sub
169
+
170
+ Public Sub Restore()
171
+ Application.ScreenUpdating = m_screenUpdating
172
+ Application.Calculation = m_calculation
173
+ Application.EnableEvents = m_enableEvents
174
+ End Sub
175
+ ```
176
+
177
+ ```vb
178
+ ' mod_AppGuard — factory: creates a cls_ApplicationState, captures state, and returns it
179
+ ' Call at the top of any bulk operation; call guard.Restore in the error handler
180
+ Public Function GuardApplicationState() As cls_ApplicationState
181
+ Dim guard As New cls_ApplicationState
182
+ guard.Capture
183
+ Set GuardApplicationState = guard
184
+ End Function
185
+ ```
186
+
187
+ ### Array-Based Range Operations
188
+ ```vb
189
+ ' ! Read/write ranges as arrays — never cell-by-cell
190
+ Public Function SumColumn(ByVal rng As Range) As Double
191
+ Dim data As Variant
192
+ data = rng.Value2
193
+
194
+ ' Wrap scalar (single-cell range) into a 2-D array so the loop is uniform
195
+ If Not IsArray(data) Then
196
+ Dim tmp(1 To 1, 1 To 1) As Variant
197
+ tmp(1, 1) = data
198
+ data = tmp
199
+ End If
200
+
201
+ Dim total As Double
202
+ Dim i As Long
203
+ For i = LBound(data, 1) To UBound(data, 1)
204
+ If IsNumeric(data(i, 1)) Then total = total + data(i, 1)
205
+ Next i
206
+
207
+ SumColumn = total
208
+ End Function
209
+ ```
210
+
211
+ ### Test Harness (No Rubberduck)
212
+ ```vb
213
+ ' mod_TestRunner — minimal assert pattern when Rubberduck is unavailable
214
+ Private m_passed As Long
215
+ Private m_failed As Long
216
+
217
+ Public Sub RunAllTests()
218
+ m_passed = 0: m_failed = 0
219
+ Test_ModRevenue_GrowthRateZero
220
+ Test_ModRevenue_NegativeGrowth
221
+ ' ... add test calls here ...
222
+ Debug.Print "Results: " & m_passed & " passed, " & m_failed & " failed"
223
+ End Sub
224
+
225
+ Private Sub AssertEqual(ByVal actual As Variant, ByVal expected As Variant, ByVal label As String)
226
+ If actual = expected Then
227
+ m_passed = m_passed + 1
228
+ Else
229
+ m_failed = m_failed + 1
230
+ Debug.Print "FAIL: " & label & " — expected " & expected & ", got " & actual
231
+ End If
232
+ End Sub
233
+
234
+ Private Sub Test_ModRevenue_GrowthRateZero()
235
+ Dim result As Double
236
+ result = CalculateRevenue(1000000, 0, 5)
237
+ AssertEqual result, 1000000, "Revenue with zero growth should equal base"
238
+ End Sub
239
+ ```
240
+
241
+ ### Named Range Lookup
242
+ ```vb
243
+ ' ! Always check existence before referencing a named range
244
+ Public Function NamedRangeExists(ByVal wb As Workbook, ByVal rangeName As String) As Boolean
245
+ On Error GoTo ErrHandler
246
+ Dim rng As Range
247
+ On Error Resume Next ' scoped: existence check only
248
+ Set rng = wb.Names(rangeName).RefersToRange
249
+ On Error GoTo ErrHandler ' restore labeled handler
250
+ NamedRangeExists = Not rng Is Nothing
251
+ Exit Function
252
+ ErrHandler:
253
+ NamedRangeExists = False
254
+ End Function
255
+ ```
256
+
257
+ ## Anti-Patterns
258
+
259
+ Items marked ⊗ in Standards above are not repeated here.
260
+
261
+ - ⊗ **God modules**: 800-line `Module1` with every procedure — split by responsibility
262
+ - ⊗ **Bare `Sheets("Name")`**: Always qualify with `ThisWorkbook`
263
+ - ⊗ **`Select` / `Activate` in logic**: `ws.Range("A1").Select` then `Selection.Value = x` — just write `ws.Range("A1").Value2 = x`
264
+ - ⊗ **Cell-by-cell loops**: Read range into array, process, write back
265
+ - ⊗ **`GoTo` for flow control**: Use `If`/`Select Case`/`Do While` — `GoTo` is only for error handlers
266
+ - ⊗ **`Integer` for counts**: Use `Long` — `Integer` overflows at 32,767
267
+ - ⊗ **Unqualified `ActiveSheet`** in library code: Pass worksheet as a parameter
268
+
269
+ ## Compliance Checklist
270
+
271
+ - ! `Option Explicit` in every module
272
+ - ! Error handler in every public procedure
273
+ - ! `Application` state restored on all exit paths
274
+ - ! Named ranges or table references — no hardcoded addresses
275
+ - ! Array-based range I/O — no cell-by-cell loops
276
+ - ! All variables explicitly typed — no bare `Dim x`
277
+ - ! Modules exported to `src/` and `tests/` for git
278
+ - ! See [testing.md](../coding/testing.md) for testing requirements
279
+ - ! Run `task check` before commit