devworkspace 0.3.1 → 0.3.3
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/CHANGELOG.md +31 -1
- package/README.md +3 -1
- package/dist/agents/claude/content.js +27 -4
- package/dist/agents/claude/content.js.map +1 -1
- package/dist/cli/args.d.ts +45 -0
- package/dist/cli/args.js +13 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/help.js +67 -8
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/render.d.ts +10 -0
- package/dist/cli/render.js +197 -1
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/run.js +100 -6
- package/dist/cli/run.js.map +1 -1
- package/dist/config/schemas.d.ts +6 -0
- package/dist/config/schemas.js +6 -0
- package/dist/config/schemas.js.map +1 -1
- package/dist/core/version.d.ts +7 -0
- package/dist/core/version.js +13 -0
- package/dist/core/version.js.map +1 -1
- package/dist/core/workspace.d.ts +1 -0
- package/dist/core/workspace.js +1 -0
- package/dist/core/workspace.js.map +1 -1
- package/dist/discovery/commands.d.ts +1 -0
- package/dist/discovery/commands.js +3 -1
- package/dist/discovery/commands.js.map +1 -1
- package/dist/features/schema.d.ts +3 -0
- package/dist/features/schema.js +79 -0
- package/dist/features/schema.js.map +1 -0
- package/dist/features/types.d.ts +77 -0
- package/dist/features/types.js +2 -0
- package/dist/features/types.js.map +1 -0
- package/dist/features/validate.d.ts +14 -0
- package/dist/features/validate.js +124 -0
- package/dist/features/validate.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/services/doctor.js +34 -0
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/drift.d.ts +21 -0
- package/dist/services/drift.js +89 -0
- package/dist/services/drift.js.map +1 -0
- package/dist/services/features.d.ts +22 -0
- package/dist/services/features.js +105 -0
- package/dist/services/features.js.map +1 -0
- package/dist/services/graph.d.ts +97 -0
- package/dist/services/graph.js +342 -0
- package/dist/services/graph.js.map +1 -0
- package/dist/services/refresh.js +15 -0
- package/dist/services/refresh.js.map +1 -1
- package/dist/services/setup.d.ts +56 -0
- package/dist/services/setup.js +116 -0
- package/dist/services/setup.js.map +1 -0
- package/dist/services/status.d.ts +6 -0
- package/dist/services/status.js +16 -0
- package/dist/services/status.js.map +1 -1
- package/dist/services/taskContext.d.ts +28 -5
- package/dist/services/taskContext.js +221 -4
- package/dist/services/taskContext.js.map +1 -1
- package/dist/services/verify.d.ts +11 -0
- package/dist/services/verify.js +64 -2
- package/dist/services/verify.js.map +1 -1
- package/docs/architecture-report/01-executive-summary.md +168 -0
- package/docs/architecture-report/02-system-architecture.md +356 -0
- package/docs/architecture-report/03-tools-and-technologies.md +112 -0
- package/docs/architecture-report/04-execution-flows.md +257 -0
- package/docs/architecture-report/05-codebase-map.md +150 -0
- package/docs/architecture-report/06-command-reference.md +446 -0
- package/docs/architecture-report/07-data-flow-and-integrations.md +268 -0
- package/docs/architecture-report/08-build-test-deployment.md +185 -0
- package/docs/architecture-report/09-security-and-reliability.md +165 -0
- package/docs/architecture-report/10-feature-status.md +110 -0
- package/docs/architecture-report/11-glossary.md +97 -0
- package/docs/architecture-report/README.md +103 -0
- package/docs/architecture-report/diagrams.md +446 -0
- package/docs/getting-started.md +38 -1
- package/package.json +1 -1
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# Chapter 7: Data Flow & Subsystem Integrations
|
|
2
|
+
|
|
3
|
+
> **Comprehensive architectural analysis of how data enters, transforms, persists, and exports across DevWorkspace, detailing file schemas, atomic guarantees, and external agent boundaries.**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. End-to-End Data Lifecycle
|
|
8
|
+
|
|
9
|
+
DevWorkspace functions as a structured data pipeline that turns messy repository files, terminal commands, and AI interactions into durable, verifiable project state:
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart TD
|
|
13
|
+
subgraph Ingestion["1. Ingestion & Discovery"]
|
|
14
|
+
Manifests["Manifests & Configs\n(package.json, tsconfig.json, Cargo.toml)"]
|
|
15
|
+
GitMeta["Git Metadata\n(HEAD, branch, commit SHA, dirty state)"]
|
|
16
|
+
CLIInputs["CLI Arguments & Flags\n(parsed via node:util parseArgs)"]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
subgraph Processing["2. Transformation & Validation"]
|
|
20
|
+
Scanner["Scanner & Detector\n(bounded depth, ignores node_modules)"]
|
|
21
|
+
Schemas["Schema Validation\n(Zod-like custom TS type guards)"]
|
|
22
|
+
AuthRank["Authority Engine\n(User Rank 4 > File Rank 3 > AI Rank 2)"]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
subgraph AtomicStore["3. Persistence & Concurrency"]
|
|
26
|
+
TempWrite["Exclusive Temp Write\n(.tmp.<pid>.<random> with sync)"]
|
|
27
|
+
Rename["Atomic Rename with Retry\n(Windows EBUSY/EPERM backoff)"]
|
|
28
|
+
LockFile[".devworkspace/local/workspace.lock\n(PID + timestamp advisory lock)"]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
subgraph StorageLayout["4. Storage Layout (.devworkspace/)"]
|
|
32
|
+
ProjJson["project.json"]
|
|
33
|
+
FactsJson["context/facts.json & testing-contract.json"]
|
|
34
|
+
TasksDir["tasks/active/*.json & tasks/completed/*.json"]
|
|
35
|
+
ADRDir["decisions/0001-*.md"]
|
|
36
|
+
SessDir["sessions/*.json"]
|
|
37
|
+
AnalysisDir["analysis/discovery.json & onboarding-prompt.md"]
|
|
38
|
+
LocalDir["local/ (git-ignored: testenv.json, locks)"]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
subgraph Egress["5. Egress & Consumption"]
|
|
42
|
+
HumanOut["Terminal Styled Text / ANSI"]
|
|
43
|
+
JSONOut["Deterministic JSON (--json)"]
|
|
44
|
+
AgentRules["Managed Blocks in Instruction Files\n(CLAUDE.md, AGENTS.md, .cursorrules)"]
|
|
45
|
+
ExportBundle["Portable Knowledge Bundle\n(devworkspace-export-<date>.json)"]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
Manifests --> Scanner
|
|
49
|
+
GitMeta --> Scanner
|
|
50
|
+
CLIInputs --> Schemas
|
|
51
|
+
Scanner --> Schemas
|
|
52
|
+
Schemas --> AuthRank
|
|
53
|
+
AuthRank --> LockFile
|
|
54
|
+
LockFile --> TempWrite
|
|
55
|
+
TempWrite --> Rename
|
|
56
|
+
Rename --> StorageLayout
|
|
57
|
+
StorageLayout --> HumanOut
|
|
58
|
+
StorageLayout --> JSONOut
|
|
59
|
+
StorageLayout --> AgentRules
|
|
60
|
+
StorageLayout --> ExportBundle
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 2. The `.devworkspace/` Directory Schema
|
|
66
|
+
|
|
67
|
+
All workspace state lives in a dedicated `.devworkspace/` directory located at the project root. This separation keeps the user's source code pristine while ensuring AI context is version-controlled and team-portable.
|
|
68
|
+
|
|
69
|
+
### 2.1. Complete Directory Layout
|
|
70
|
+
```text
|
|
71
|
+
.devworkspace/
|
|
72
|
+
├── .gitignore # Ignores local/ and migration backups
|
|
73
|
+
├── project.json # Core repository identifier and schema version
|
|
74
|
+
├── analysis/ # Generated by "devworkspace analyze"
|
|
75
|
+
│ ├── discovery.json # Raw machine-readable detection output
|
|
76
|
+
│ └── onboarding-prompt.md # Optimized initialization prompt for Claude Code
|
|
77
|
+
├── context/ # Project knowledge and execution contracts
|
|
78
|
+
│ ├── facts.json # Key-value facts with evidence and confidence
|
|
79
|
+
│ ├── testing-contract.json # Discovered test, lint, and build commands
|
|
80
|
+
│ ├── commands.json # Discovered development and operational scripts
|
|
81
|
+
│ └── *.md # Optional domain-specific architectural markdown
|
|
82
|
+
├── tasks/ # Task management subsystem
|
|
83
|
+
│ ├── active/
|
|
84
|
+
│ │ └── T-20261102-a1b2.json # Currently active engineering tasks
|
|
85
|
+
│ └── completed/
|
|
86
|
+
│ └── T-20261101-9f8e.json # Completed tasks with verification records
|
|
87
|
+
├── decisions/ # Architecture Decision Records (ADRs)
|
|
88
|
+
│ ├── 0001-use-postgresql.md
|
|
89
|
+
│ └── 0002-async-event-bus.md
|
|
90
|
+
├── sessions/ # Engineering session summaries (token-efficient)
|
|
91
|
+
│ └── S-20261102-143022.json
|
|
92
|
+
└── local/ # MACHINE-LOCAL ONLY (Never committed to Git)
|
|
93
|
+
├── testenv.json # Declared local test environments
|
|
94
|
+
└── workspace.lock # Concurrency lock file (pid, timestamp)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
### 2.2. Core JSON File Schemas
|
|
100
|
+
|
|
101
|
+
#### 1. `project.json`
|
|
102
|
+
Contains workspace identity and version tracking:
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"schemaVersion": 1,
|
|
106
|
+
"id": "c1f7b2e4-9843-4e8c-8712-42173160a221",
|
|
107
|
+
"name": "devworkspace",
|
|
108
|
+
"root": "d:/projects/codeing_stuff/devworkspace",
|
|
109
|
+
"createdAt": "2026-11-02T04:30:00.000Z",
|
|
110
|
+
"updatedAt": "2026-11-02T04:35:12.000Z"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### 2. `context/facts.json`
|
|
115
|
+
Structured facts tagged with authority rank, source files, and status:
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"schemaVersion": 1,
|
|
119
|
+
"facts": [
|
|
120
|
+
{
|
|
121
|
+
"key": "stack.runtime",
|
|
122
|
+
"value": "Node.js v20+ with ES Modules",
|
|
123
|
+
"source": "package.json",
|
|
124
|
+
"sourceType": "file",
|
|
125
|
+
"sources": ["package.json"],
|
|
126
|
+
"confidence": "HIGH",
|
|
127
|
+
"status": "VERIFIED",
|
|
128
|
+
"authority": 3,
|
|
129
|
+
"updatedAt": "2026-11-02T04:31:00.000Z"
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### 3. `tasks/active/T-*.json`
|
|
136
|
+
Lifecycle tracking and completion gate evidence:
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"schemaVersion": 1,
|
|
140
|
+
"id": "T-20261102-ab12",
|
|
141
|
+
"title": "Add PostgreSQL connection pool health check",
|
|
142
|
+
"type": "FEATURE",
|
|
143
|
+
"status": "IN_PROGRESS",
|
|
144
|
+
"request": "Add database healthcheck endpoint and verify pool recovers after timeout",
|
|
145
|
+
"classification": {
|
|
146
|
+
"confidence": "high",
|
|
147
|
+
"readOnly": false,
|
|
148
|
+
"packages": ["backend"]
|
|
149
|
+
},
|
|
150
|
+
"plan": [
|
|
151
|
+
"Write integration test simulating pool starvation",
|
|
152
|
+
"Implement healthcheck query in pool manager",
|
|
153
|
+
"Run verification suite"
|
|
154
|
+
],
|
|
155
|
+
"verification": [
|
|
156
|
+
{
|
|
157
|
+
"check": "typecheck",
|
|
158
|
+
"status": "PASSED",
|
|
159
|
+
"evidence": [{ "kind": "executed", "at": "2026-11-02T04:33:00.000Z", "exitCode": 0 }]
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"check": "integration",
|
|
163
|
+
"status": "PENDING"
|
|
164
|
+
}
|
|
165
|
+
],
|
|
166
|
+
"testRunCounts": {
|
|
167
|
+
"baseline": { "passed": 142, "failed": 0 },
|
|
168
|
+
"after": { "passed": 145, "failed": 0 }
|
|
169
|
+
},
|
|
170
|
+
"attestations": {
|
|
171
|
+
"userWorkIntact": true,
|
|
172
|
+
"knowledgeReviewed": false,
|
|
173
|
+
"finalStateInspected": false
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 3. Atomic Persistence & Concurrency Guarantees
|
|
181
|
+
|
|
182
|
+
DevWorkspace is engineered to never leave corrupt, truncated, or half-written JSON files on disk, even during unexpected system power loss, process termination, or concurrent multi-agent executions.
|
|
183
|
+
|
|
184
|
+
### 3.1. Atomic Temporary Write & Rename Pattern
|
|
185
|
+
Implemented in [`src/utils/fs.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/utils/fs.ts):
|
|
186
|
+
|
|
187
|
+
1. **Unique Staging File**: Rather than modifying the target file in place, DevWorkspace creates a staging file in the same directory using the format:
|
|
188
|
+
```text
|
|
189
|
+
<targetFile>.<pid>.<hexRandom4Bytes>.tmp
|
|
190
|
+
```
|
|
191
|
+
2. **Exclusive File Creation (`wx` mode)**: Opened with OS flag `wx` to ensure no race conditions with other processes trying to use the same temporary filename.
|
|
192
|
+
3. **Forced Flush (`fsync`)**: Calls `await fh.sync()` before closing the file handle, forcing OS kernel buffers to commit data directly to physical storage.
|
|
193
|
+
4. **Pre-Commit Validation**: If writing JSON, DevWorkspace executes a `JSON.parse()` pass on the written text before replacing the real file. If invalid, the write aborts and the staging file is unlinked.
|
|
194
|
+
5. **Atomic Rename with Windows Backoff**: Calls `fs.rename()`. On POSIX systems, `rename` is atomic. On Windows, file indexers, antivirus scanners, or IDE file watchers can hold momentary locks; DevWorkspace implements an exponential backoff retry loop (up to 20 attempts) catching `EPERM`, `EBUSY`, and `EACCES`.
|
|
195
|
+
|
|
196
|
+
### 3.2. Advisory Workspace Locking
|
|
197
|
+
Implemented in [`src/utils/lock.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/utils/lock.ts):
|
|
198
|
+
|
|
199
|
+
- **Mechanism**: Every mutating command executes inside `withLock(workspaceDir, fn)`. It acquires an exclusive lock file at `.devworkspace/local/workspace.lock`.
|
|
200
|
+
- **Payload**: The lock contains `{ pid: process.pid, at: Date.now() }`.
|
|
201
|
+
- **Dead Process Detection**: If a lock exists, DevWorkspace verifies if `pid` is still alive via `process.kill(pid, 0)`. If the process has died or the lock is older than 60 seconds, it is safely broken.
|
|
202
|
+
- **Signal Trapping**: Node process traps `SIGINT` and `SIGTERM` to synchronously unlink the lock file via [`src/utils/cleanup.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/utils/cleanup.ts).
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 4. Multi-Agent Data Boundaries
|
|
207
|
+
|
|
208
|
+
DevWorkspace integrates with AI coding agents (Claude Code, Cursor, Codex, Copilot, Antigravity) while maintaining strict architectural boundaries.
|
|
209
|
+
|
|
210
|
+
```mermaid
|
|
211
|
+
sequenceDiagram
|
|
212
|
+
autonumber
|
|
213
|
+
participant Agent as AI Coding Agent
|
|
214
|
+
participant File as CLAUDE.md / AGENTS.md / .cursorrules
|
|
215
|
+
participant DW as DevWorkspace CLI
|
|
216
|
+
participant State as .devworkspace/ State
|
|
217
|
+
|
|
218
|
+
Note over DW,File: Non-Destructive Ingestion
|
|
219
|
+
DW->>File: Reads existing agent file
|
|
220
|
+
DW->>DW: Locates <!-- DEVWORKSPACE:START --> marker
|
|
221
|
+
DW->>File: Injects/Updates managed instruction block
|
|
222
|
+
Note over File: Preserves 100% of existing user rules
|
|
223
|
+
|
|
224
|
+
Note over Agent,DW: Progressive Context Loop
|
|
225
|
+
Agent->>DW: devworkspace context --for "Fix checkout tax error"
|
|
226
|
+
DW->>State: Queries facts, contract, and active tasks
|
|
227
|
+
DW->>DW: Classifies request & filters relevant packages
|
|
228
|
+
DW-->>Agent: Returns high-signal context (omits irrelevant facts)
|
|
229
|
+
|
|
230
|
+
Note over Agent,DW: Verified Completion Loop
|
|
231
|
+
Agent->>DW: devworkspace task status T-01 COMPLETED
|
|
232
|
+
DW->>State: evaluateGate() checks contract, tests, attestations
|
|
233
|
+
alt Gate Fails
|
|
234
|
+
DW-->>Agent: Exit 1 + Warning: "Required check 'typecheck' has not passed"
|
|
235
|
+
else Gate Passes
|
|
236
|
+
DW->>State: Moves task from tasks/active/ to tasks/completed/
|
|
237
|
+
DW-->>Agent: Exit 0: Task COMPLETED
|
|
238
|
+
end
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### 4.1. Non-Destructive Instruction Block Injection
|
|
242
|
+
Implemented in [`src/agents/shared.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/agents/shared.ts):
|
|
243
|
+
- DevWorkspace injects instructions into agent root files (`CLAUDE.md`, `AGENTS.md`, `.cursorrules`, `.github/copilot-instructions.md`) using strict HTML boundary markers:
|
|
244
|
+
```markdown
|
|
245
|
+
<!-- DEVWORKSPACE:START -->
|
|
246
|
+
<!-- Managed by devworkspace. Do not edit this block manually. -->
|
|
247
|
+
... concise instructions, testing contracts, and commands ...
|
|
248
|
+
<!-- DEVWORKSPACE:END -->
|
|
249
|
+
```
|
|
250
|
+
- Any text written by developers outside this block is strictly preserved.
|
|
251
|
+
- When `devworkspace reset --include-agent-files` is run, only the managed block is stripped; user comments and custom rules remain intact.
|
|
252
|
+
|
|
253
|
+
### 4.2. Progressive Context Delivery
|
|
254
|
+
Instead of overloading LLM context windows with thousands of lines of documentation, `devworkspace context --for "<request>"` performs dynamic filtering:
|
|
255
|
+
1. Matches `<request>` keywords against known monorepo packages, stack technologies, and testing contract commands.
|
|
256
|
+
2. Injects mandatory architectural invariants (e.g. "Do not mutate production DBs").
|
|
257
|
+
3. Omits irrelevant microservice configs and secondary test suites.
|
|
258
|
+
4. Returns token-efficient, high-density facts tagged with their origin.
|
|
259
|
+
|
|
260
|
+
### 4.3. External Developer Tool Integrations
|
|
261
|
+
|
|
262
|
+
| Integration | Primary Purpose | Execution Model | Data Exchanged |
|
|
263
|
+
|---|---|---|---|
|
|
264
|
+
| **Graphify** | Visual codebase dependency graphs & clustering | Managed external CLI (`graphify .` via Claude Code) | Generates `graphify-out/` and architecture visualizations |
|
|
265
|
+
| **Agent Skills** | Extends coding agents with specialized command sets | Local skill scripts (`.agent-skills/` or user path) | Skill manifests and invocation protocols |
|
|
266
|
+
| **Ponytail** | Terminal-based background process monitor | Standalone CLI on PATH (`ponytail`) | Process statuses, ports, log output |
|
|
267
|
+
| **OmniRoute** | Observed network router / proxy | Passive detection (observed on PATH only) | None (zero execution, read-only observation) |
|
|
268
|
+
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Chapter 8: Build, Test & Deployment Architecture
|
|
2
|
+
|
|
3
|
+
> **Complete technical breakdown of the TypeScript build pipeline, Vitest test suites, coverage gates, release verification scripts, and GitHub Actions CI/CD workflows.**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Diagram 6: Build, Test & Deployment Pipeline
|
|
8
|
+
|
|
9
|
+
The following diagram illustrates the complete validation pipeline that code traverses—from developer source TypeScript to published npm registry artifact:
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart TD
|
|
13
|
+
subgraph Developer["Local Development"]
|
|
14
|
+
Source["TypeScript Source (src/)"]
|
|
15
|
+
Tests["Test Suites (tests/unit, integration, e2e)"]
|
|
16
|
+
Clean["scripts/clean.mjs\n(Purges dist/)"]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
subgraph BuildPipeline["Compilation & Packaging"]
|
|
20
|
+
TSC["TypeScript Compiler (tsc -p tsconfig.build.json)\nES2022, NodeNext, Declarations (.d.ts), Maps (.js.map)"]
|
|
21
|
+
Pack["npm pack --ignore-scripts\n(Generates devworkspace-<version>.tgz)"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subgraph TestGates["Quality & Verification Gates"]
|
|
25
|
+
Typecheck["npm run typecheck\n(Strict TS validation)"]
|
|
26
|
+
ESLint["npm run lint\n(ESLint flat config)"]
|
|
27
|
+
Vitest["npm run coverage\n(778 tests across Unit, Integration, E2E)"]
|
|
28
|
+
Audit["npm run audit:security\n(Production dependency audit)"]
|
|
29
|
+
ReleaseCheck["scripts/release-check.mjs\n(Hygiene, Semver, Docs, Tags, Clean Git)"]
|
|
30
|
+
Smoke["scripts/smoke.mjs\n(Tarball inspection & isolated CLI run)"]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
subgraph CICD["GitHub Actions Automation"]
|
|
34
|
+
CIWorkflow[".github/workflows/ci.yml\n(Ubuntu, Windows, macOS on Node 20 & 22)"]
|
|
35
|
+
ReleaseWorkflow[".github/workflows/release.yml\n(Manual dispatch, OIDC Trusted Publishing)"]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
subgraph Registry["Distribution"]
|
|
39
|
+
NPMRegistry["npm Registry (Public)\nhttps://www.npmjs.com/package/devworkspace"]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
Source --> Clean
|
|
43
|
+
Clean --> TSC
|
|
44
|
+
TSC --> Pack
|
|
45
|
+
Source --> Typecheck
|
|
46
|
+
Source --> ESLint
|
|
47
|
+
Tests --> Vitest
|
|
48
|
+
Pack --> Smoke
|
|
49
|
+
Typecheck & ESLint & Vitest & Audit & Smoke --> ReleaseCheck
|
|
50
|
+
|
|
51
|
+
ReleaseCheck --> CIWorkflow
|
|
52
|
+
CIWorkflow --> ReleaseWorkflow
|
|
53
|
+
ReleaseWorkflow -->|"npm publish --access public (OIDC Token)"| NPMRegistry
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 2. TypeScript Compilation Architecture
|
|
59
|
+
|
|
60
|
+
DevWorkspace uses modern, native Node.js ES Modules (ESM) with TypeScript strict mode enabled throughout.
|
|
61
|
+
|
|
62
|
+
### 2.1. Dual Configuration Model
|
|
63
|
+
The repository maintains two TypeScript configuration files:
|
|
64
|
+
|
|
65
|
+
1. **`tsconfig.json`**: Root configuration for local development, IDE language servers, and test running. Includes `tests/` and `scripts/`.
|
|
66
|
+
2. **`tsconfig.build.json`**: Production compilation configuration used strictly for generating the distribution payload. Excludes `tests/`, `scripts/`, and mocks to ensure zero non-production code leaks into `dist/`.
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"extends": "./tsconfig.json",
|
|
71
|
+
"compilerOptions": {
|
|
72
|
+
"noEmit": false,
|
|
73
|
+
"declaration": true,
|
|
74
|
+
"declarationMap": true,
|
|
75
|
+
"sourceMap": true,
|
|
76
|
+
"outDir": "./dist"
|
|
77
|
+
},
|
|
78
|
+
"include": ["src/**/*"],
|
|
79
|
+
"exclude": ["tests/**/*", "scripts/**/*", "**/*.test.ts"]
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 2.2. Key Compiler Settings
|
|
84
|
+
- **`target: "ES2022"`**: Targets modern ECMAScript features (native private fields, `Object.hasOwn`, top-level await).
|
|
85
|
+
- **`module: "NodeNext"` & `moduleResolution: "NodeNext"`**: Strictly enforces modern Node.js module resolution, requiring explicit `.js` extensions in all TypeScript import paths.
|
|
86
|
+
- **`strict: true`**: Enforces strict null checks, no implicit any, and strict function types.
|
|
87
|
+
- **`declaration: true`**: Emits complete TypeScript type declarations (`.d.ts`), enabling consumers to import DevWorkspace programmatically with full autocomplete and type safety.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 3. Testing Strategy & Framework (Vitest)
|
|
92
|
+
|
|
93
|
+
DevWorkspace uses **Vitest** as its unified test runner across all testing tiers.
|
|
94
|
+
|
|
95
|
+
### 3.1. Test Suites Structure
|
|
96
|
+
The test suite consists of **31 test files** comprising **778 passing tests**, categorized into three distinct layers:
|
|
97
|
+
|
|
98
|
+
| Tier | Directory | Test Files | Focus & Scope |
|
|
99
|
+
|---|---|:---:|---|
|
|
100
|
+
| **Unit** | `tests/unit/` | 19 | Pure unit tests targeting isolated modules (argument parser, schema validators, path sanitization, redact engine, authority rankings). Runs in milliseconds without disk I/O. |
|
|
101
|
+
| **Integration** | `tests/integration/` | 8 | Subsystem coordination tests. Tests atomic filesystem writes, locks, discovery scanning, task state transitions, and integration adapters using temporary directories. |
|
|
102
|
+
| **End-to-End** | `tests/e2e/` | 4 | Full CLI end-to-end execution. Spawns real CLI commands via child processes against temporary mock repositories, verifying stdout, stderr, and exit codes. |
|
|
103
|
+
|
|
104
|
+
### 3.2. Coverage Enforcement
|
|
105
|
+
Test coverage is enforced via `@vitest/coverage-v8`. The build pipeline executes `npm run coverage`, which mandates strict statement, branch, function, and line coverage minimums across all modules in `src/`.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 4. Release Verification & Quality Gates
|
|
110
|
+
|
|
111
|
+
Publishing a release of DevWorkspace requires passing a multi-layer verification gate executed by `scripts/release-check.mjs`.
|
|
112
|
+
|
|
113
|
+
### 4.1. `release-check.mjs` Gate Checks
|
|
114
|
+
The script executes 11 sequential validation gates and aborts with exit code `1` upon the first failure:
|
|
115
|
+
|
|
116
|
+
1. **Git State Verification**: Asserts that `git status --porcelain` is 100% clean (no uncommitted modifications).
|
|
117
|
+
2. **Tag Alignment**: Verifies that the current `HEAD` commit is tagged with `v${version}` matching `package.json`.
|
|
118
|
+
3. **Semver Compliance**: Asserts that `package.json` version conforms strictly to Semantic Versioning (`X.Y.Z`).
|
|
119
|
+
4. **Changelog Integrity**: Confirms that `CHANGELOG.md` contains a dedicated entry header for the release version (`## [X.Y.Z] - YYYY-MM-DD`).
|
|
120
|
+
5. **License Ownership**: Asserts `package.json` license is valid (e.g. `MIT`) and `LICENSE` exists.
|
|
121
|
+
6. **URL Sanity**: Ensures `repository`, `bugs`, and `homepage` URLs in `package.json` do not contain placeholder strings (e.g. `OWNER`).
|
|
122
|
+
7. **Documentation Presence**: Verifies existence of all 10 core documentation files in `docs/` (`getting-started.md`, `architecture.md`, `security.md`, etc.).
|
|
123
|
+
8. **Production Hygiene Scan**: Recursively scans all `.ts` files in `src/` to ensure no active `TODO`, `FIXME`, `XXX`, `HACK`, or unapproved `stub`/`placeholder` markers exist.
|
|
124
|
+
9. **Static Checks**: Executes `npm run typecheck` and `npm run lint`.
|
|
125
|
+
10. **Test Coverage**: Executes `npm run coverage` to ensure all 778 tests pass with coverage thresholds met.
|
|
126
|
+
11. **Production Dependency Audit**: Executes `npm run audit:security` to confirm zero vulnerabilities exist in production dependencies.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
### 4.2. `smoke.mjs`: Fresh-Install Verification
|
|
131
|
+
|
|
132
|
+
Before any package is released, `scripts/smoke.mjs` conducts a black-box verification of the published package:
|
|
133
|
+
|
|
134
|
+
```mermaid
|
|
135
|
+
sequenceDiagram
|
|
136
|
+
autonumber
|
|
137
|
+
participant Runner as Smoke Runner (scripts/smoke.mjs)
|
|
138
|
+
participant NPM as npm pack
|
|
139
|
+
participant FS as Temporary Filesystem
|
|
140
|
+
participant CLI as Published CLI (node dist/cli/main.js)
|
|
141
|
+
|
|
142
|
+
Runner->>NPM: npm pack --ignore-scripts
|
|
143
|
+
NPM-->>Runner: Creates devworkspace-0.3.1.tgz
|
|
144
|
+
Runner->>FS: Reads tarball contents (tar -tzf)
|
|
145
|
+
Note over Runner,FS: Verifies LICENSE, README.md, dist/<br/>Rejects any tests/, src/, or scripts/ leaks
|
|
146
|
+
Runner->>FS: Creates fresh temp project folder
|
|
147
|
+
Runner->>FS: Extracts tarball into temp project
|
|
148
|
+
Runner->>CLI: Executes "devworkspace --version"
|
|
149
|
+
CLI-->>Runner: Returns "0.3.1" (Exit 0)
|
|
150
|
+
Runner->>CLI: Executes "devworkspace init --dry-run"
|
|
151
|
+
CLI-->>Runner: Returns initialization plan (Exit 0)
|
|
152
|
+
Runner->>FS: Purges temporary directory
|
|
153
|
+
Note over Runner: Smoke test PASSED
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
- **Tarball Content Whitelist**: Ensures only `package.json`, `README.md`, `LICENSE`, `CHANGELOG.md`, and compiled `dist/` files are present in the package. Source `.ts` files, test fixtures, scripts, and temporary files are strictly prevented from publishing.
|
|
157
|
+
- **Real Execution**: Verifies that the packaged CLI entrypoint starts up without missing dependencies or broken import paths.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 5. CI/CD & Deployment Workflows
|
|
162
|
+
|
|
163
|
+
DevWorkspace uses GitHub Actions for continuous integration and automated releases.
|
|
164
|
+
|
|
165
|
+
### 5.1. Continuous Integration (`.github/workflows/ci.yml`)
|
|
166
|
+
- **Triggers**: Every push to `main` and all Pull Requests.
|
|
167
|
+
- **Cross-Platform Matrix**: Runs across **Ubuntu Latest**, **Windows Latest**, and **macOS Latest** on Node.js **20** and **22**.
|
|
168
|
+
- **Steps**:
|
|
169
|
+
- `npm ci`
|
|
170
|
+
- `npm run typecheck`
|
|
171
|
+
- `npm run lint`
|
|
172
|
+
- `npm run build`
|
|
173
|
+
- `npm run test:unit`
|
|
174
|
+
- `npm run test:integration`
|
|
175
|
+
- `npm run test:e2e`
|
|
176
|
+
- `npm run smoke`
|
|
177
|
+
- **Coverage & Security Job**: Runs on Ubuntu to verify coverage thresholds and execute `npm audit`.
|
|
178
|
+
|
|
179
|
+
### 5.2. Automated Release Workflow (`.github/workflows/release.yml`)
|
|
180
|
+
DevWorkspace publishes packages using modern **GitHub Actions OIDC Trusted Publishing**:
|
|
181
|
+
- **Manual Trigger (`workflow_dispatch`)**: Publishing requires an explicit maintainer trigger with a confirmation input matching the exact version string from `package.json`.
|
|
182
|
+
- **Dry-Run Mode**: Defaults to `dry_run: true` so maintainers can preview all release checks and tarball contents in CI before pushing to the public registry.
|
|
183
|
+
- **OIDC Token Permission (`id-token: write`)**: Generates short-lived, cryptographic OIDC tokens exchanged with npm. No permanent `NPM_TOKEN` secret is stored in repository settings.
|
|
184
|
+
- **Environment Protection (`environment: publish`)**: Allows repository administrators to attach required reviewers and deployment rules to the `publish` environment.
|
|
185
|
+
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Chapter 9: Security, Privacy & System Reliability
|
|
2
|
+
|
|
3
|
+
> **Exhaustive analysis of DevWorkspace's defense-in-depth security model: credential redaction, symlink escape containment, destructive command blocking, and crash-resilient concurrency.**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Security Architecture & Threat Model
|
|
8
|
+
|
|
9
|
+
DevWorkspace operates on a **zero-trust local model**. It assumes that:
|
|
10
|
+
1. Repositories may contain third-party open-source code or LLM-generated code that could introduce malicious symlinks, path traversals, or dangerous shell commands.
|
|
11
|
+
2. Coding agents might attempt to read secrets (`.env`, private keys) or run destructive database migrations without human awareness.
|
|
12
|
+
3. Multiple terminal sessions or agents could execute commands simultaneously, threatening workspace state corruption.
|
|
13
|
+
|
|
14
|
+
To neutralize these threats, DevWorkspace enforces six non-bypassable layers of defense:
|
|
15
|
+
|
|
16
|
+
```mermaid
|
|
17
|
+
flowchart TD
|
|
18
|
+
subgraph InputDefense["Layer 1: Input & Filesystem Containment"]
|
|
19
|
+
NoSymlinks["Symlink Escape Guard\n(assertNoSymlinkEscape, realpath check)"]
|
|
20
|
+
PathBound["Path Boundary Assertion\n(isInside root check)"]
|
|
21
|
+
SensitiveBlock["Sensitive File Blocklist\n(.env, *.pem, id_rsa, .npmrc never read)"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subgraph MemoryDefense["Layer 2: Resource & Memory Bounding"]
|
|
25
|
+
BoundedRead["Bounded File Streaming\n(maxBytes 512KB limit, MAX_JSON_BYTES 5MB)"]
|
|
26
|
+
NoInteractiveHangs["Zero Interactive Stdin\n(never hangs waiting for user prompt)"]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
subgraph DataSanitization["Layer 3: Privacy & Secrets Redaction"]
|
|
30
|
+
RedactEngine["Multi-Pattern Redaction\n(AWS keys, Slack/GitHub tokens, JWTs, private keys)"]
|
|
31
|
+
SafeLogging["Deterministic Redacted Output\n(logs, error traces, and export bundles)"]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
subgraph CommandSafetyEngine["Layer 4: Command Safety & Execution Sandbox"]
|
|
35
|
+
DestructiveFilter["Destructive Keyword Filter\n(blocks drop, truncate, flushall, migrate, rm -rf)"]
|
|
36
|
+
TestEnvGuard["Test Environment Enforcer\n(blocks DB-touching tests unless declared in testenv)"]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
subgraph ConcurrencyResilience["Layer 5: Concurrency & Atomic State"]
|
|
40
|
+
AdvisoryLock["Workspace Advisory Lock\n(PID + timeout check, stale lock recovery)"]
|
|
41
|
+
AtomicFlush["Atomic File Writes\n(.tmp with fsync flush + Windows rename retry backoff)"]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
subgraph ProcessSafety["Layer 6: Signal Trapping & Cleanup"]
|
|
45
|
+
SignalHandler["Process Signal Trapping\n(SIGINT / SIGTERM synchronously unlinks locks & temp files)"]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
InputDefense --> MemoryDefense
|
|
49
|
+
MemoryDefense --> DataSanitization
|
|
50
|
+
DataSanitization --> CommandSafetyEngine
|
|
51
|
+
CommandSafetyEngine --> ConcurrencyResilience
|
|
52
|
+
ConcurrencyResilience --> ProcessSafety
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 2. Secrets Redaction & Privacy Engine
|
|
58
|
+
|
|
59
|
+
Implemented in [`src/security/redact.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/security/redact.ts):
|
|
60
|
+
|
|
61
|
+
### 2.1. Monitored Credential Patterns
|
|
62
|
+
DevWorkspace maintains an active regex registry matching industry credential signatures:
|
|
63
|
+
|
|
64
|
+
| Credential Type | Regex Pattern / Signature | Redacted Token Output |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| **Private Keys** | `-----BEGIN (RSA\|EC\|DSA\|OPENSSH\|PGP)? PRIVATE KEY-----` | `[REDACTED:private-key]` |
|
|
67
|
+
| **AWS Access Keys** | `\b(?:AKIA\|ASIA)[0-9A-Z]{16}\b` | `[REDACTED:aws-access-key]` |
|
|
68
|
+
| **GitHub Tokens** | `\b(?:ghp\|gho\|ghu\|ghs\|ghr)_[A-Za-z0-9]{30,}\b` | `[REDACTED:github-token]` |
|
|
69
|
+
| **Slack Tokens** | `\bxox[abprs]-[A-Za-z0-9-]{10,}\b` | `[REDACTED:slack-token]` |
|
|
70
|
+
| **API Keys** | `\bsk-[A-Za-z0-9_-]{20,}\b` | `[REDACTED:api-key]` |
|
|
71
|
+
| **Google API Keys** | `\bAIza[0-9A-Za-z_-]{34,36}\b` | `[REDACTED:google-api-key]` |
|
|
72
|
+
| **npm Tokens** | `\bnpm_[A-Za-z0-9]{36}\b` | `[REDACTED:npm-token]` |
|
|
73
|
+
| **JSON Web Tokens (JWT)**| `\beyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b` | `[REDACTED:jwt]` |
|
|
74
|
+
| **URL Credentials** | `\b[a-z][a-z0-9+.-]*:\/\/[^\s/:@]+:[^\s/@]{3,}@` | `[REDACTED:url-credentials]` |
|
|
75
|
+
| **Generic Secrets** | `(?:password\|secret\|passwd\|auth_key)[\"']?\s*[:=]\s*...` | `[REDACTED:generic-secret]` |
|
|
76
|
+
|
|
77
|
+
### 2.2. Universal Application
|
|
78
|
+
Redaction is applied deterministically across:
|
|
79
|
+
- All CLI stdout and stderr formatting passes ([`src/cli/render.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/cli/render.ts)).
|
|
80
|
+
- Loggers and error messages (`formatError` in [`src/errors/index.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/errors/index.ts)).
|
|
81
|
+
- Stored knowledge facts and session handoffs.
|
|
82
|
+
- Exported JSON bundles (`devworkspace export`).
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 3. Path Traversal & Symlink Escape Defenses
|
|
87
|
+
|
|
88
|
+
Implemented in [`src/security/files.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/security/files.ts) and [`src/utils/paths.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/utils/paths.ts):
|
|
89
|
+
|
|
90
|
+
### 3.1. Sensitive File Quarantine
|
|
91
|
+
DevWorkspace enforces a strict file blocklist. When scanning repository text, the CLI **refuses to open**:
|
|
92
|
+
- Any `.env` file (e.g. `.env`, `.env.local`, `.env.production`), **except** non-sensitive template files (`.env.example`, `.env.sample`).
|
|
93
|
+
- Certificates and private keys (`*.pem`, `*.key`, `*.p12`, `id_rsa`, `id_ed25519`).
|
|
94
|
+
- Cloud credentials and state (`service-account*.json`, `credentials`, `terraform.tfstate`, `*.tfvars`).
|
|
95
|
+
- Package manager auth files (`.npmrc`, `.pypirc`, `.netrc`, `.git-credentials`).
|
|
96
|
+
|
|
97
|
+
> **Architectural Invariant**: DevWorkspace records only that a credential file *exists* for stack detection; it never reads the contents.
|
|
98
|
+
|
|
99
|
+
### 3.2. Bounded Traversal & Memory Limits
|
|
100
|
+
To prevent denial-of-service via memory exhaustion:
|
|
101
|
+
- Text file reads are capped by `safeReadText(root, rel, maxBytes = 524288)` (512 KB).
|
|
102
|
+
- JSON configuration files are capped by `MAX_JSON_BYTES = 5 * 1024 * 1024` (5 MB). Files exceeding these bounds are rejected.
|
|
103
|
+
|
|
104
|
+
### 3.3. Symlink Escape Prevention
|
|
105
|
+
- `isInside(absRoot, full)` verifies the resolved absolute path starts within the workspace root.
|
|
106
|
+
- `st.isSymbolicLink()` check returns `null` immediately on symlinks during scanning.
|
|
107
|
+
- `assertNoSymlinkEscape(root, full)` resolves physical `realpath` and asserts that symlinks do not escape outside the project directory.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 4. Destructive Command Guards & Safe Execution
|
|
112
|
+
|
|
113
|
+
Implemented in [`src/verification/safety.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/verification/safety.ts):
|
|
114
|
+
|
|
115
|
+
When an AI agent or developer executes `devworkspace task run <id> <check>`, the command safety engine inspects the package manifest and command string before spawning a child process:
|
|
116
|
+
|
|
117
|
+
```mermaid
|
|
118
|
+
flowchart TD
|
|
119
|
+
RunCmd["devworkspace task run <id> <check>"] --> InspectCmd["Inspect Command String & Manifest"]
|
|
120
|
+
|
|
121
|
+
InspectCmd --> CheckDestructive{"Contains Destructive Keywords?\n(drop, truncate, flushall, migrate, seed, rm -rf)"}
|
|
122
|
+
CheckDestructive -- Yes --> Block["BLOCKED: Exit Code 2\nRefuses to auto-execute hazardous script"]
|
|
123
|
+
|
|
124
|
+
CheckDestructive -- No --> CheckService{"Uses External Services?\n(pg, prisma, redis, mongoose, bullmq)"}
|
|
125
|
+
CheckService -- No --> ExecuteSafe["SAFE: Execute Subprocess\n(typecheck, lint, unit tests)"]
|
|
126
|
+
|
|
127
|
+
CheckService -- Yes --> CheckDeclared{"Declared in testenv.json?\n(devworkspace testenv declare --yes)"}
|
|
128
|
+
CheckDeclared -- No --> RequireEnv["NEEDS TEST ENVIRONMENT: Exit Code 2\nRequires explicit local isolation declaration"]
|
|
129
|
+
CheckDeclared -- Yes --> ExecuteSafe
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 4.1. Hazardous Keyword Filtering
|
|
133
|
+
Any script containing `drop`, `truncate`, `flushall`, `flushdb`, `reset`, `seed`, `migrate`, `db:push`, `--force`, or `rm -rf` is classified as `BLOCKED`. DevWorkspace refuses to auto-execute it under any circumstance.
|
|
134
|
+
|
|
135
|
+
### 4.2. Database & Service Quarantine (`testenv`)
|
|
136
|
+
If a package manifest lists database drivers (`pg`, `mysql2`, `mongodb`, `ioredis`, `prisma`, `typeorm`, `sequelize`, `drizzle-orm`, `bullmq`), integration and e2e checks are marked `needs-test-environment`.
|
|
137
|
+
They can only run if the engineer explicitly ran:
|
|
138
|
+
```bash
|
|
139
|
+
devworkspace testenv declare --package <pkg> --check integration --target "disposable docker stack" --yes
|
|
140
|
+
```
|
|
141
|
+
This declaration is stored strictly in `.devworkspace/local/testenv.json` and is never committed to Git.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 5. System Reliability, Locking & Signal Trapping
|
|
146
|
+
|
|
147
|
+
### 5.1. Concurrency Control (`withLock`)
|
|
148
|
+
- Mutating commands acquire an exclusive lock file at `.devworkspace/local/workspace.lock`.
|
|
149
|
+
- Prevents split-brain state when multiple coding agents run parallel tasks in the same project.
|
|
150
|
+
- Implements stale lock recovery: if the process holding the lock dies (`pidAlive()` check fails) or the lock exceeds 60 seconds, it is automatically broken.
|
|
151
|
+
|
|
152
|
+
### 5.2. Atomic File Commits
|
|
153
|
+
All updates to `.devworkspace/` utilize the atomic write pattern:
|
|
154
|
+
1. Data written to unique staging file (`.tmp.<pid>.<hex>`).
|
|
155
|
+
2. Data flushed to disk via `fsync()`.
|
|
156
|
+
3. Validated via `JSON.parse()`.
|
|
157
|
+
4. Atomically renamed into place with exponential backoff on Windows (`EPERM`/`EBUSY` handling).
|
|
158
|
+
|
|
159
|
+
### 5.3. Signal Traps & Cleanup Handlers
|
|
160
|
+
[`src/utils/cleanup.ts`](file:///d:/projects/codeing_stuff/devworkspace/src/utils/cleanup.ts) registers lifecycle hooks on `process.on('SIGINT')` and `process.on('SIGTERM')`:
|
|
161
|
+
- Unlinks temporary staging files immediately.
|
|
162
|
+
- Releases `.devworkspace/local/workspace.lock`.
|
|
163
|
+
- Terminates spawned child test processes cleanly, returning exit code `130`.
|
|
164
|
+
- Ensures zero dangling lock files or half-written temporary files remain on the developer's machine.
|
|
165
|
+
|