@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.
- package/.agents/skills/deft/SKILL.md +6 -0
- package/.agents/skills/deft-directive-article-review/SKILL.md +11 -0
- package/.agents/skills/deft-directive-build/SKILL.md +10 -0
- package/.agents/skills/deft-directive-cost/SKILL.md +12 -0
- package/.agents/skills/deft-directive-debug/SKILL.md +13 -0
- package/.agents/skills/deft-directive-gh-arch/SKILL.md +11 -0
- package/.agents/skills/deft-directive-gh-slice/SKILL.md +10 -0
- package/.agents/skills/deft-directive-glossary/SKILL.md +10 -0
- package/.agents/skills/deft-directive-interview/SKILL.md +9 -0
- package/.agents/skills/deft-directive-pre-pr/SKILL.md +9 -0
- package/.agents/skills/deft-directive-refinement/SKILL.md +10 -0
- package/.agents/skills/deft-directive-release/SKILL.md +12 -0
- package/.agents/skills/deft-directive-review-cycle/SKILL.md +10 -0
- package/.agents/skills/deft-directive-setup/SKILL.md +10 -0
- package/.agents/skills/deft-directive-swarm/SKILL.md +10 -0
- package/.agents/skills/deft-directive-sync/SKILL.md +9 -0
- package/.agents/skills/deft-directive-triage/SKILL.md +9 -0
- package/.agents/skills/deft-directive-write-skill/SKILL.md +9 -0
- package/LICENSE.md +22 -0
- package/QUICK-START.md +167 -0
- package/UPGRADING.md +517 -0
- package/coding/build-output.md +28 -0
- package/coding/coding.md +235 -0
- package/coding/debugging.md +110 -0
- package/coding/holzmann.md +96 -0
- package/coding/hygiene.md +127 -0
- package/coding/security.md +158 -0
- package/coding/testing.md +162 -0
- package/coding/toolchain.md +44 -0
- package/commands.md +300 -0
- package/context/context.md +57 -0
- package/context/deterministic-split.md +67 -0
- package/context/examples.md +26 -0
- package/context/fractal-summaries.md +69 -0
- package/context/long-horizon.md +46 -0
- package/context/spec-deltas.md +177 -0
- package/context/tool-design.md +34 -0
- package/context/working-memory.md +62 -0
- package/contracts/boundary-maps.md +65 -0
- package/contracts/deterministic-questions.md +59 -0
- package/contracts/hierarchy.md +77 -0
- package/conventions/content-manifest.json +399 -0
- package/conventions/machine-generated-banner.md +130 -0
- package/conventions/references.md +120 -0
- package/conventions/rule-ownership.json +382 -0
- package/conventions/task-caching.md +43 -0
- package/conventions/vbrief-filenames.md +70 -0
- package/deployments/README.md +37 -0
- package/deployments/agentuity/README.md +138 -0
- package/deployments/agentuity/via-cli.md +380 -0
- package/deployments/agentuity/via-cloud.md +425 -0
- package/deployments/agentuity/via-github-actions.md +664 -0
- package/deployments/agentuity/via-gravity-network.md +606 -0
- package/deployments/agentuity/via-vpc.md +607 -0
- package/deployments/aws/README.md +38 -0
- package/deployments/aws/via-app-runner.md +612 -0
- package/deployments/aws/via-ecs-fargate.md +561 -0
- package/deployments/aws/via-elastic-beanstalk.md +628 -0
- package/deployments/aws/via-lambda.md +649 -0
- package/deployments/azure/README.md +37 -0
- package/deployments/azure/via-aks.md +390 -0
- package/deployments/azure/via-app-service.md +564 -0
- package/deployments/azure/via-container-apps.md +599 -0
- package/deployments/azure/via-functions.md +552 -0
- package/deployments/cloud-gov/README.md +63 -0
- package/deployments/cloud-gov/agents/compliance-docs.md +154 -0
- package/deployments/cloud-gov/agents.md +39 -0
- package/deployments/cloud-gov/cicd.md +64 -0
- package/deployments/cloud-gov/deployment.md +150 -0
- package/deployments/cloud-gov/logging.md +43 -0
- package/deployments/cloud-gov/manifest.md +121 -0
- package/deployments/cloud-gov/overview.md +58 -0
- package/deployments/cloud-gov/security.md +46 -0
- package/deployments/cloud-gov/services.md +72 -0
- package/deployments/cloud-gov/upstream/README.md +18 -0
- package/deployments/cloudflare/README.md +33 -0
- package/deployments/cloudflare/via-dashboard.md +83 -0
- package/deployments/cloudflare/via-git.md +90 -0
- package/deployments/cloudflare/via-github-actions.md +185 -0
- package/deployments/cloudflare/via-terraform.md +157 -0
- package/deployments/cloudflare/via-wrangler.md +165 -0
- package/deployments/fly-io/README.md +37 -0
- package/deployments/fly-io/via-dockerfile.md +648 -0
- package/deployments/fly-io/via-flyctl.md +653 -0
- package/deployments/fly-io/via-github-actions.md +695 -0
- package/deployments/fly-io/via-multi-region.md +598 -0
- package/deployments/google/README.md +34 -0
- package/deployments/google/via-app-engine.md +42 -0
- package/deployments/google/via-cloud-functions.md +23 -0
- package/deployments/google/via-cloud-run.md +330 -0
- package/deployments/google/via-gke.md +23 -0
- package/deployments/netlify/README.md +99 -0
- package/deployments/netlify/via-cli.md +17 -0
- package/deployments/netlify/via-functions.md +19 -0
- package/deployments/netlify/via-git.md +25 -0
- package/deployments/vercel/README.md +90 -0
- package/deployments/vercel/via-api.md +16 -0
- package/deployments/vercel/via-cli.md +17 -0
- package/deployments/vercel/via-git.md +24 -0
- package/docs/BROWNFIELD.md +179 -0
- package/docs/getting-started.md +137 -0
- package/docs/good-agents-md.md +137 -0
- package/events/README.md +89 -0
- package/events/event-record.schema.json +26 -0
- package/events/registry.json +166 -0
- package/events/registry.schema.json +71 -0
- package/glossary.md +145 -0
- package/incidents/README.md +81 -0
- package/incidents/_template.md +38 -0
- package/interfaces/cli.md +104 -0
- package/interfaces/rest.md +212 -0
- package/interfaces/tui.md +242 -0
- package/interfaces/web.md +123 -0
- package/languages/6502-DASM.md +132 -0
- package/languages/c.md +235 -0
- package/languages/commands.md +23 -0
- package/languages/cpp.md +132 -0
- package/languages/csharp.md +259 -0
- package/languages/dart.md +183 -0
- package/languages/delphi.md +218 -0
- package/languages/elixir.md +208 -0
- package/languages/go.md +78 -0
- package/languages/java.md +278 -0
- package/languages/javascript.md +163 -0
- package/languages/julia.md +175 -0
- package/languages/kotlin.md +193 -0
- package/languages/markdown.md +168 -0
- package/languages/mermaid.md +146 -0
- package/languages/officejs.md +392 -0
- package/languages/python.md +209 -0
- package/languages/r.md +163 -0
- package/languages/rust.md +216 -0
- package/languages/sql.md +216 -0
- package/languages/swift.md +153 -0
- package/languages/typescript.md +132 -0
- package/languages/vba.md +279 -0
- package/languages/vhdl.md +180 -0
- package/languages/visual-basic.md +151 -0
- package/languages/zig.md +196 -0
- package/meta/SOUL.md +27 -0
- package/meta/code-field.md +44 -0
- package/meta/morals.md +40 -0
- package/meta/philosophy.md +39 -0
- package/meta/project.md +49 -0
- package/meta/ralph.md +223 -0
- package/meta/security.md +80 -0
- package/meta/versioning.md +326 -0
- package/package.json +22 -0
- package/packs/lessons/lessons-pack-0.1.json +553 -0
- package/packs/patterns/patterns-pack-0.1.json +57 -0
- package/packs/rules/rules-pack-0.1.json +4767 -0
- package/packs/skills/skills-pack-0.1.json +262 -0
- package/packs/strategies/strategies-pack-0.1.json +167 -0
- package/packs/swarm-spec/swarm-spec-pack-0.1.json +17 -0
- package/patterns/executor-layer-credentials.md +227 -0
- package/patterns/llm-app.md +156 -0
- package/patterns/multi-agent.md +278 -0
- package/patterns/prompt-assembly-layer-ordering.md +154 -0
- package/patterns/role-as-overlay.md +179 -0
- package/platforms/2600.md +137 -0
- package/platforms/unity.md +329 -0
- package/references/composer-skill-porting.md +152 -0
- package/references/cost-models.md +163 -0
- package/references/ip-risk.md +246 -0
- package/references/plain-english-ux.md +275 -0
- package/resilience/context-pruning.md +67 -0
- package/resilience/continue-here.md +62 -0
- package/scm/changelog.md +276 -0
- package/scm/git.md +139 -0
- package/scm/github.md +265 -0
- package/secrets/.gitkeep +0 -0
- package/skills/deft-build/SKILL.md +20 -0
- package/skills/deft-directive-article-review/SKILL.md +156 -0
- package/skills/deft-directive-build/SKILL.md +302 -0
- package/skills/deft-directive-cost/SKILL.md +201 -0
- package/skills/deft-directive-debug/SKILL.md +140 -0
- package/skills/deft-directive-decompose/SKILL.md +96 -0
- package/skills/deft-directive-gh-arch/SKILL.md +160 -0
- package/skills/deft-directive-gh-slice/SKILL.md +199 -0
- package/skills/deft-directive-glossary/SKILL.md +118 -0
- package/skills/deft-directive-interview/SKILL.md +528 -0
- package/skills/deft-directive-pre-pr/SKILL.md +131 -0
- package/skills/deft-directive-probe/SKILL.md +127 -0
- package/skills/deft-directive-refinement/SKILL.md +403 -0
- package/skills/deft-directive-release/SKILL.md +266 -0
- package/skills/deft-directive-review-cycle/SKILL.md +401 -0
- package/skills/deft-directive-setup/SKILL.md +717 -0
- package/skills/deft-directive-swarm/SKILL.md +989 -0
- package/skills/deft-directive-sync/SKILL.md +288 -0
- package/skills/deft-directive-triage/SKILL.md +137 -0
- package/skills/deft-directive-write-skill/SKILL.md +169 -0
- package/skills/deft-interview/SKILL.md +16 -0
- package/skills/deft-pre-pr/SKILL.md +16 -0
- package/skills/deft-review-cycle/SKILL.md +16 -0
- package/skills/deft-roadmap-refresh/SKILL.md +16 -0
- package/skills/deft-setup/SKILL.md +20 -0
- package/skills/deft-swarm/SKILL.md +16 -0
- package/skills/deft-sync/SKILL.md +16 -0
- package/strategies/README.md +83 -0
- package/strategies/artifact-guards.md +85 -0
- package/strategies/bdd.md +115 -0
- package/strategies/brownfield.md +7 -0
- package/strategies/discuss.md +129 -0
- package/strategies/emit-hints.md +69 -0
- package/strategies/enterprise.md +193 -0
- package/strategies/interview.md +551 -0
- package/strategies/map.md +179 -0
- package/strategies/probe.md +151 -0
- package/strategies/rapid.md +155 -0
- package/strategies/research.md +155 -0
- package/strategies/roadmap.md +9 -0
- package/strategies/speckit.md +437 -0
- package/strategies/v0-20-contract.md +134 -0
- package/strategies/yolo.md +169 -0
- package/swarm/swarm.md +300 -0
- package/templates/COST-ESTIMATE.md +114 -0
- package/templates/PULL_REQUEST_TEMPLATE.md +35 -0
- package/templates/agent-prompt-preamble.md +409 -0
- package/templates/agents-entry.md +211 -0
- package/templates/agents-entry.placeholders.md +75 -0
- package/templates/embed.go +20 -0
- package/templates/embed_test.go +36 -0
- package/templates/make-spec-example.md +9 -0
- package/templates/make-spec.md +246 -0
- package/templates/project.md.template +52 -0
- package/templates/specification.md +1 -0
- package/templates/swarm-greptile-poller-prompt.md +556 -0
- package/templates/user.md.template +31 -0
- package/tools/RWLDL.md +80 -0
- package/tools/greptile.md +141 -0
- package/tools/installer.md +23 -0
- package/tools/taskfile-migration.md +32 -0
- package/tools/taskfile.md +185 -0
- package/tools/telemetry.md +285 -0
- package/vbrief/schemas/cache-meta.schema.json +137 -0
- package/vbrief/schemas/candidates.schema.json +130 -0
- package/vbrief/schemas/codebase-map.schema.json +213 -0
- package/vbrief/schemas/lessons-pack.schema.json +134 -0
- package/vbrief/schemas/patterns-pack.schema.json +84 -0
- package/vbrief/schemas/rules-pack.schema.json +105 -0
- package/vbrief/schemas/skills-pack.schema.json +94 -0
- package/vbrief/schemas/slices.schema.json +87 -0
- package/vbrief/schemas/strategies-pack.schema.json +89 -0
- package/vbrief/schemas/swarm-spec-pack.schema.json +84 -0
- package/vbrief/schemas/vbrief-core.schema.json +1022 -0
- package/vbrief/vbrief.md +684 -0
- package/verification/integration.md +76 -0
- package/verification/plan-checking.md +85 -0
- package/verification/uat.md +60 -0
- 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
|
package/languages/vba.md
ADDED
|
@@ -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
|