You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: guard check_resource and check_backup_age when ctx is uninitialized
When ctx is installed as a global plugin, its hooks fire in every
project Claude opens — including non-ctx projects. Two relay hooks
were missing the state.Initialized() guard and nagged users with
"Load Xx CPU count" and backup-age warnings in projects that don't
use ctx at all.
Add the guard, matching the pattern already present in 18 other
hooks. Safety hooks (block_dangerous_command, block_non_path_ctx)
intentionally run regardless of ctx state.
Also records this session's decisions and learnings, and updates
TASKS.md line 30 to reflect partial progress (boundary side effect
resolved in e24941d; remaining hooks need per-hook audit).
Spec: specs/hook-guard-uninitialized.md
Signed-off-by: Jose Alekhinne <jose@parlakisik.com>
| 2026-04-06 | Use hook relay for session provenance instead of JSONL parsing or env vars |
@@ -120,6 +122,29 @@ For significant decisions:
120
122
121
123
-->
122
124
125
+
## [2026-04-13-153617] Walk boundary uses git as a hint, not a requirement
126
+
127
+
**Status**: Accepted
128
+
129
+
**Context**: ctx init failed when a non-ctx-initialized repo lived inside a
130
+
ctx-initialized parent workspace. walkForContextDir walked up and found the
131
+
parent's .context, then the boundary check rejected it. We considered
132
+
project-marker heuristics (go.mod, package.json) and making git mandatory.
133
+
134
+
**Decision**: Walk boundary uses git as a hint, not a requirement
135
+
136
+
**Rationale**: Project markers are unreliable (e.g. package.json for customer
137
+
shipments, Haskell projects have no common marker). Making git mandatory breaks
138
+
ctx's 'git recommended but not required' stance. Git-as-hint resolves the bug
139
+
without new dependencies: walk finds candidate, validate against git root,
140
+
discard if outside; fall back to CWD when no git is found.
141
+
142
+
**Consequence**: walkForContextDir now consults findGitRoot to anchor ancestor
143
+
.context candidates. Monorepos, submodules, and nested workspaces resolve
144
+
correctly. No-git projects still work via CWD fallback.
145
+
146
+
---
147
+
123
148
## [2026-04-11-200000] Journal stays local; LEARNINGS.md is the shareable layer
124
149
125
150
**Status**: Accepted
@@ -296,27 +321,37 @@ the implementation task.
296
321
297
322
**Status**: Accepted
298
323
299
-
**Context**: Had a proposed ctx-architecture-extend for extension point mapping, making four skills
324
+
**Context**: Had a proposed ctx-architecture-extend for extension point mapping,
325
+
making four skills
300
326
301
327
**Decision**: Architecture skill pipeline is a triad not a quartet
302
328
303
-
**Rationale**: Extension points already covered per-module in DETAILED_DESIGN and by registration site discovery in enrich. Fourth skill fragments pipeline without distinct value
329
+
**Rationale**: Extension points already covered per-module in DETAILED_DESIGN
330
+
and by registration site discovery in enrich. Fourth skill fragments pipeline
331
+
without distinct value
304
332
305
-
**Consequence**: Pipeline is map enrich hunt. Three skills three questions: how does it work, how well does it connect, where will it break
333
+
**Consequence**: Pipeline is map enrich hunt. Three skills three questions: how
334
+
does it work, how well does it connect, where will it break
306
335
307
336
---
308
337
309
338
## [2026-04-08-013731] Remove #done tag convention, simplify task archival
310
339
311
340
**Status**: Accepted
312
341
313
-
**Context**: Tasks had #done:YYYY-MM-DD timestamps that agents added inconsistently and nobody read. compact --archive filtered by age using these timestamps.
342
+
**Context**: Tasks had #done:YYYY-MM-DD timestamps that agents added
343
+
inconsistently and nobody read. compact --archive filtered by age using these
344
+
timestamps.
314
345
315
346
**Decision**: Remove #done tag convention, simplify task archival
316
347
317
-
**Rationale**: [x] checkbox is semantically sufficient. git blame provides the completion timestamp. Removing #done eliminates redundant ceremony and simplifies compact --archive to archive all completed tasks regardless of age.
348
+
**Rationale**: [x] checkbox is semantically sufficient. git blame provides the
349
+
completion timestamp. Removing #done eliminates redundant ceremony and
350
+
simplifies compact --archive to archive all completed tasks regardless of age.
318
351
319
-
**Consequence**: compact --archive no longer filters by archive_after_days for tasks. The .ctxrc field is inert but retained for backwards compatibility. Historical #done tags in archives are preserved.
352
+
**Consequence**: compact --archive no longer filters by archive_after_days for
353
+
tasks. The .ctxrc field is inert but retained for backwards compatibility.
~/.gnupg/gpg-agent.conf; gpgconf --kill gpg-agent. Once the passphrase is saved
129
+
in Keychain, signing works from any context.
130
+
131
+
**Application**: If agents or CI need to sign commits, configure pinentry-mac
132
+
(macOS) or pinentry-gtk/pinentry-qt (Linux) with the OS keychain, not
133
+
pinentry-curses. This is a one-time setup per machine.
134
+
135
+
---
136
+
137
+
## [2026-04-13-153618] Load average measures a queue, not CPU utilization
138
+
139
+
**Context**: The 'Load Xx CPU count' resource alert fired at 1.74x while htop
140
+
showed per-core utilization well under 50% and idle cores. Load average counts
141
+
runnable + uninterruptible-sleep processes, smoothed over 1/5/15 minutes.
142
+
143
+
**Lesson**: Load average and CPU% measure different things. High load with low
144
+
CPU% typically means many short-lived processes or I/O-bound work (e.g., go test
145
+
spawning hundreds of parallel test binaries). The 1-minute average is too
146
+
reactive for dev machines that periodically run test suites — 5-minute smooths
147
+
transient spikes without hiding sustained pressure.
148
+
149
+
**Application**: For alerting thresholds based on system load, prefer 5-minute
150
+
over 1-minute averages. 1-minute is useful for interactive debugging; 5-minute
151
+
is better for automated alerts that should not fire on normal build/test
152
+
activity.
153
+
154
+
---
155
+
156
+
## [2026-04-13-153618] rc.ContextDir() is the single source of truth — fix the resolver, not callers
157
+
158
+
**Context**: When ctx init failed with a boundary error, my first instinct was
159
+
to have init bypass rc.ContextDir() and use filepath.Join(cwd, dir.Context)
160
+
directly. Volkan shut that down: rc.ContextDir() encodes invariants (team
161
+
shares, symlinks, network mounts, .ctxrc overrides) that individual commands
162
+
cannot reason about.
163
+
164
+
**Lesson**: Resolution chains with multiple fallbacks are contracts. If one
165
+
command bypasses the chain, it silently diverges from every other command's
166
+
notion of 'the context directory.' When a resolver produces a wrong answer for a
167
+
specific case, fix the resolver — don't let callers opt out.
168
+
169
+
**Application**: Any time you see rc.ContextDir(), rc.RC(), or similar central
170
+
resolvers producing a bad result, the fix belongs in the resolver itself (or in
171
+
its input data like .ctxrc). Caller-side bypasses create drift.
172
+
173
+
---
174
+
115
175
## [2026-04-09-001323] Pad index shifting is a real UX bug in batch operations
116
176
117
-
**Context**: ctx pad rm 10; rm 11; rm 12 deleted wrong entries because indices shifted after each deletion
177
+
**Context**: ctx pad rm 10; rm 11; rm 12 deleted wrong entries because indices
178
+
shifted after each deletion
118
179
119
-
**Lesson**: Any ID-based system where users chain operations needs stable IDs. Look-then-act is safe for single ops; look-then-batch-act breaks with shifting indices
180
+
**Lesson**: Any ID-based system where users chain operations needs stable IDs.
181
+
Look-then-act is safe for single ops; look-then-batch-act breaks with shifting
182
+
indices
120
183
121
-
**Application**: Both pad and remind now use stable IDs with batch delete and range support. Apply same pattern to any future numbered-list subsystem
184
+
**Application**: Both pad and remind now use stable IDs with batch delete and
185
+
range support. Apply same pattern to any future numbered-list subsystem
122
186
123
187
---
124
188
125
189
## [2026-04-08-074612] fmt.Fprintf to strings.Builder silently discards errors
126
190
127
-
**Context**: golangci-lint errcheck allows fmt.Fprintf to strings.Builder because Write never fails, but project convention says zero silent discard
191
+
**Context**: golangci-lint errcheck allows fmt.Fprintf to strings.Builder
192
+
because Write never fails, but project convention says zero silent discard
128
193
129
-
**Lesson**: Linter coverage gaps exist where language guarantees mask conventions. AST tests fill the gap
194
+
**Lesson**: Linter coverage gaps exist where language guarantees mask
195
+
conventions. AST tests fill the gap
130
196
131
-
**Application**: Created TestNoUncheckedFmtWrite to enforce fmt.Fprintf error handling. Use if _, err := fmt.Fprintf(...) with log.Warn on the error path
197
+
**Application**: Created TestNoUncheckedFmtWrite to enforce fmt.Fprintf error
198
+
handling. Use if _, err := fmt.Fprintf(...) with log.Warn on the error path
132
199
133
200
---
134
201
135
202
## [2026-04-08-074604] AST audit tests must cover unexported functions too
136
203
137
-
**Context**: TestDocCommentStructure only checked exported functions, so agent-written helpers in format.go had no godoc enforcement
204
+
**Context**: TestDocCommentStructure only checked exported functions, so
205
+
agent-written helpers in format.go had no godoc enforcement
138
206
139
-
**Lesson**: Convention enforcement tests must default to scanning all documented functions. Use explicit opt-outs (test files) not opt-ins (exported only)
207
+
**Lesson**: Convention enforcement tests must default to scanning all documented
208
+
functions. Use explicit opt-outs (test files) not opt-ins (exported only)
140
209
141
-
**Application**: When adding AST audit tests, scan all functions. We fixed TestDocCommentStructure to drop the IsExported gate and fixed 84 violations
210
+
**Application**: When adding AST audit tests, scan all functions. We fixed
211
+
TestDocCommentStructure to drop the IsExported gate and fixed 84 violations
0 commit comments