@tekyzinc/gsd-t 3.10.10 → 3.10.11
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 +14 -0
- package/commands/gsd-t-unattended.md +6 -0
- package/docs/unattended-config.md +138 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GSD-T are documented here. Updated with each release.
|
|
4
4
|
|
|
5
|
+
## [3.10.11] - 2026-04-15
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `docs/unattended-config.md` — full schema and recipe reference for `.gsd-t/.unattended/config.json`. The supervisor has always loaded this file (M36 safety rails), but there was no user-facing doc explaining the schema, precedence, or common overrides.
|
|
9
|
+
- `commands/gsd-t-unattended.md` Step 1c cross-references the new config doc and calls out the solo-project recipe (`{"protectedBranches": []}` to disable the main/master guard).
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Flaky test: `scripts/gsd-t-context-meter.e2e.test.js` `HARD_TIMEOUT_MS` bumped 6000 → 12000ms. The hook child process runs fine in 30ms in isolation but was timing out under full-suite parallelism load on some machines. No behavioral change — just a more forgiving outer cap.
|
|
13
|
+
- `commands/gsd-t-unattended.md` gained Step 1e: pre-flight software check that hard-fails the launch if `node`, `claude`, or `git` are missing, and prints soft warnings for missing platform helpers (`caffeinate` on darwin; `systemd-inhibit`/`notify-send` on linux; BurntToast advisory on win32). Replaces the previous "crash mid-run when a helper is missing" behavior with fail-fast + actionable install instructions.
|
|
14
|
+
- `docs/unattended-windows-caveats.md` added §0 "Required Software" matrix listing hard-required and soft-recommended tools per platform.
|
|
15
|
+
|
|
16
|
+
### Notes
|
|
17
|
+
- No API or contract changes. `.gsd-t/.unattended/config.json` loader and precedence (CLI > env > config > defaults) were already built into M36 safety rails — this release only surfaces them in documentation.
|
|
18
|
+
|
|
5
19
|
## [3.10.10] - 2026-04-15
|
|
6
20
|
|
|
7
21
|
### Major version bump: 2.x → 3.x
|
|
@@ -77,6 +77,12 @@ Parse `$ARGUMENTS` for:
|
|
|
77
77
|
- `--max-iterations=N` — iteration cap (default: `200`)
|
|
78
78
|
- `--dry-run` — preflight only; print what would be spawned, do NOT spawn
|
|
79
79
|
|
|
80
|
+
**Persistent overrides**: create `.gsd-t/.unattended/config.json` to change
|
|
81
|
+
defaults per-project (caps, protected branches, dirty-tree whitelist). CLI
|
|
82
|
+
flags always win over the config file. See `docs/unattended-config.md` for
|
|
83
|
+
the full schema and common recipes (e.g. `{"protectedBranches": []}` for
|
|
84
|
+
solo projects that commit directly to main).
|
|
85
|
+
|
|
80
86
|
Run via Bash to read the current milestone from progress.md:
|
|
81
87
|
|
|
82
88
|
```bash
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Unattended Supervisor — Configuration File
|
|
2
|
+
|
|
3
|
+
**File**: `.gsd-t/.unattended/config.json` (optional, per-project)
|
|
4
|
+
**Contract reference**: `.gsd-t/contracts/unattended-supervisor-contract.md` §13
|
|
5
|
+
**Loader**: `bin/gsd-t-unattended-safety.js` → `loadConfig(projectDir)`
|
|
6
|
+
**Consumer**: `bin/gsd-t-unattended.js` (supervisor entrypoint)
|
|
7
|
+
|
|
8
|
+
The unattended supervisor reads an optional JSON config file at
|
|
9
|
+
`.gsd-t/.unattended/config.json`. If present, its fields override the
|
|
10
|
+
hardcoded defaults. If absent, the supervisor runs with the defaults below.
|
|
11
|
+
Malformed JSON fails the launch with exit code 2 (preflight-failure) — the
|
|
12
|
+
supervisor never silently falls back on a broken config.
|
|
13
|
+
|
|
14
|
+
## Precedence
|
|
15
|
+
|
|
16
|
+
From highest to lowest:
|
|
17
|
+
|
|
18
|
+
1. **CLI flags** passed to `/user:gsd-t-unattended` (e.g. `--hours=48`)
|
|
19
|
+
2. **Environment variables** (`GSD_T_HOURS`, `GSD_T_MAX_ITERATIONS`, etc.)
|
|
20
|
+
3. **`.gsd-t/.unattended/config.json`** fields
|
|
21
|
+
4. **Hardcoded defaults** in `bin/gsd-t-unattended-safety.js` → `DEFAULTS`
|
|
22
|
+
|
|
23
|
+
A CLI flag always wins. An env var beats the config file. The config file
|
|
24
|
+
beats the built-in defaults. Missing fields fall through to the next level
|
|
25
|
+
individually — a config with only `protectedBranches` still uses the default
|
|
26
|
+
`hours`, `maxIterations`, etc.
|
|
27
|
+
|
|
28
|
+
## Schema
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"hours": 24,
|
|
33
|
+
"maxIterations": 200,
|
|
34
|
+
"protectedBranches": ["main", "master", "develop", "trunk", "release/*", "hotfix/*"],
|
|
35
|
+
"dirtyTreeWhitelist": [
|
|
36
|
+
".gsd-t/heartbeat-*.jsonl",
|
|
37
|
+
".gsd-t/.context-meter-state.json",
|
|
38
|
+
".gsd-t/events/*.jsonl",
|
|
39
|
+
".gsd-t/token-metrics.jsonl",
|
|
40
|
+
".gsd-t/token-log.md",
|
|
41
|
+
".gsd-t/.unattended/*",
|
|
42
|
+
".gsd-t/.handoff/*",
|
|
43
|
+
".claude/settings.local.json",
|
|
44
|
+
".claude/settings.local.json.bak*"
|
|
45
|
+
],
|
|
46
|
+
"gutterNoProgressIters": 5,
|
|
47
|
+
"workerTimeoutMs": 3600000
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Field reference
|
|
52
|
+
|
|
53
|
+
| Field | Type | Default | Purpose |
|
|
54
|
+
|---|---|---|---|
|
|
55
|
+
| `hours` | number | `24` | Wall-clock cap in hours. Supervisor exits with code 6 (gutter) once `wallClockElapsedMs >= hours * 3600 * 1000`. |
|
|
56
|
+
| `maxIterations` | integer | `200` | Iteration cap. Supervisor exits with code 6 once `iter >= maxIterations`. |
|
|
57
|
+
| `protectedBranches` | string[] | `["main","master","develop","trunk","release/*","hotfix/*"]` | Branches where the pre-launch guard refuses to spawn. Glob patterns supported (`*`, `**`, `?`). Empty array = no branch protection. |
|
|
58
|
+
| `dirtyTreeWhitelist` | string[] | (see defaults) | Files that can be dirty without triggering the clean-worktree refusal. Glob patterns supported. Non-whitelisted dirty files cause exit code 8. |
|
|
59
|
+
| `gutterNoProgressIters` | integer | `5` | Lookback window for the no-progress gutter detector. Larger = less sensitive. |
|
|
60
|
+
| `workerTimeoutMs` | integer | `3600000` (1h) | Hard wall-clock timeout for a single `claude -p` worker iteration. Exceeding this causes worker SIGTERM + exit code 3. |
|
|
61
|
+
|
|
62
|
+
## Common Overrides
|
|
63
|
+
|
|
64
|
+
### Solo project — commit directly to main
|
|
65
|
+
|
|
66
|
+
For projects where you're the only contributor and main is your working
|
|
67
|
+
branch, disable the protected-branch guard:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"protectedBranches": []
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The safety rail still runs, but with an empty list nothing matches, so the
|
|
76
|
+
guard always allows. The Destructive Action Guard, blocker sentinels, caps,
|
|
77
|
+
and Red Team are all still active — you're only opting out of one specific
|
|
78
|
+
check.
|
|
79
|
+
|
|
80
|
+
### Long overnight runs
|
|
81
|
+
|
|
82
|
+
Raise the caps for multi-day unattended milestones:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"hours": 72,
|
|
87
|
+
"maxIterations": 600
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Extra-noisy project
|
|
92
|
+
|
|
93
|
+
If your project writes logs or caches outside the default whitelist and you
|
|
94
|
+
don't want to commit or stash them before each run:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"dirtyTreeWhitelist": [
|
|
99
|
+
".gsd-t/heartbeat-*.jsonl",
|
|
100
|
+
".gsd-t/.context-meter-state.json",
|
|
101
|
+
".gsd-t/events/*.jsonl",
|
|
102
|
+
".gsd-t/token-metrics.jsonl",
|
|
103
|
+
".gsd-t/token-log.md",
|
|
104
|
+
".gsd-t/.unattended/*",
|
|
105
|
+
".gsd-t/.handoff/*",
|
|
106
|
+
".claude/settings.local.json",
|
|
107
|
+
"logs/**",
|
|
108
|
+
"tmp/**",
|
|
109
|
+
"*.local.cache"
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Whitelist is a replacement, not an append. If you override it, restate the
|
|
115
|
+
defaults you want to keep.
|
|
116
|
+
|
|
117
|
+
## Validation
|
|
118
|
+
|
|
119
|
+
The loader in `bin/gsd-t-unattended-safety.js` merges field-by-field. Only
|
|
120
|
+
the fields you set are overridden — everything else keeps its default. If
|
|
121
|
+
the file exists but isn't valid JSON, the launcher aborts with:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
[gsd-t-unattended] preflight-failure: safety-rails: malformed JSON in
|
|
125
|
+
.gsd-t/.unattended/config.json: <parse error>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
and exits with code 2. The PID file, state file, and run log are never
|
|
129
|
+
written on a preflight failure.
|
|
130
|
+
|
|
131
|
+
## Git
|
|
132
|
+
|
|
133
|
+
`.gsd-t/.unattended/` is in the dirty-tree whitelist, so you can either:
|
|
134
|
+
- **Commit the config** — makes it part of the project's canonical setup
|
|
135
|
+
- **Gitignore the config** — treat it as a per-developer preference
|
|
136
|
+
|
|
137
|
+
Both work. There's no preferred choice — it depends on whether your team
|
|
138
|
+
wants a uniform cap across machines or lets each developer tune their own.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.11",
|
|
4
4
|
"description": "GSD-T: Contract-Driven Development for Claude Code — 61 slash commands with unattended supervisor relay, headless CI/CD mode, graph-powered code analysis, real-time agent dashboard, execution intelligence, task telemetry, doc-ripple enforcement, backlog management, impact analysis, test sync, milestone archival, and PRD generation",
|
|
5
5
|
"author": "Tekyz, Inc.",
|
|
6
6
|
"license": "MIT",
|