@haposoft/cafekit 0.16.0-rc.1 → 0.16.0-rc.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haposoft/cafekit",
3
- "version": "0.16.0-rc.1",
3
+ "version": "0.16.0-rc.2",
4
4
  "description": "Native spec-driven workflows for Claude Code, Codex CLI, and OpenCode. Bundles CafeKit skills, runtime hooks, agents, and installer scaffolding.",
5
5
  "author": "Haposoft <nghialt@haposoft.com>",
6
6
  "license": "MIT",
@@ -44,12 +44,17 @@ Before reading any specific logic, you MUST run a Dependency Scope Check (Blast
44
44
 
45
45
  | # | Pillar | Example Issues |
46
46
  |---|--------|----------------|
47
- | 1 | **Security** | XSS, SQL injection, hardcoded secrets, missing auth checks |
47
+ | 1 | **Security** | XSS, SQL injection, hardcoded secrets, missing auth checks, over-broad log redaction corrupting safe identifiers/public URLs, quote/delimiter-unsafe authorization redaction, non-idempotent redaction, filesystem write escaping via traversal/symlink/sibling-prefix, non-canonical return path, non-atomic write or leaked temp file |
48
48
  | 2 | **Logic Correctness** | Race conditions, null references, off-by-one, unawait-ed async |
49
49
  | 3 | **Architecture** | Cross-module coupling, layer separation violations, circular dependencies |
50
50
  | 4 | **Principles (YAGNI/KISS/DRY)** | Code duplication, over-engineering, features outside scope |
51
51
  | 5 | **Convention & Style** | Non-standard naming, missing type annotations, formatting issues |
52
52
 
53
+ ### Critical-only invariants (enforce only when the diff touches these surfaces)
54
+
55
+ - **Logging redaction:** exact token-boundary matching (safe suffixes `_file`/`_path`/`_hint`/`_label` and `tokenizer` must not be redacted), public URLs unchanged unless they carry a credential, `Bearer`/`Basic` redaction preserves surrounding quotes and trailing `,`/`;`/whitespace outside the value, never drops the closing quote, and `redact(redact(x)) === redact(x)`.
56
+ - **Filesystem write boundary:** existing real directory root, reject empty/whitespace-only/URI/absolute/traversal/sibling-prefix before mutation, dual containment (lexical `path.resolve` **and** `realpath` of deepest existing parent), never follow or overwrite final symlink, never create parents outside root, atomic same-directory temp + `rename` with cleanup, return canonical `realpath` on success.
57
+
53
58
  ## Review Process
54
59
 
55
60
  Assume the code may be AI-generated. Do not trust polished structure, confident comments, or happy-path tests — verify behavior from evidence.
@@ -144,6 +149,8 @@ When called from `develop` Step 4 (Quality Gate Auto-Fix):
144
149
  - Cross-service behavior "proven" only by process-local memory, fake adapters, or other non-shared placeholders
145
150
  - Files or features from later tasks delivered early without explicit scope-escape justification
146
151
  - Task marked complete while required commands/evidence are still FAIL / UNVERIFIED
152
+ - Logging redaction that over-redacts safe identifiers/public URLs, drops closing quotes, consumes `,`/`;` delimiters, or is not idempotent when the diff touches redaction/sanitization
153
+ - Filesystem write that returns a lexical path instead of canonical `realpath`, skips `realpath` parent containment, follows or overwrites a final symlink, creates or mutates anything outside the root on rejection, or leaks a temp file / misses atomic same-directory `rename`
147
154
 
148
155
  ## Operating Guidelines
149
156
 
@@ -257,6 +257,58 @@ const dbPassword = process.env.DB_PASSWORD;
257
257
  if (!dbPassword) throw new Error('DB_PASSWORD not set');
258
258
  ```
259
259
 
260
+ ## Critical Security Invariants (apply only when the task touches these surfaces)
261
+
262
+ These invariants are lane-aware: enforce them for Critical tasks that touch the
263
+ named surface; for Direct/Standard tasks that happen to touch it, apply the same
264
+ checks with proportional evidence (targeted unit test + diff self-check for Direct,
265
+ bounded suite for Standard). Do not impose a fixed heavy ceremony on every task.
266
+
267
+ ### Logging & Secret Redaction
268
+
269
+ - Match secret names by exact token boundaries, not broad substrings. Never redact
270
+ by substring inside safe identifiers — e.g. names ending in `_file`, `_path`,
271
+ `_hint`, `_label` or containing `tokenizer` must stay intact. Preserve the
272
+ field/key name, replace only the value with `[REDACTED]` (use `[REDACTED-PEM]`
273
+ for PEM blocks, keeping the surrounding structure).
274
+ - Leave public URLs and credential-free strings untouched. URL redaction applies
275
+ only when a credential is present in the URL (e.g. `user:pass@host`).
276
+ - Authorization redaction is quote-aware and delimiter-safe: match schemes
277
+ `Bearer`/`Basic` case-insensitively, redact only the credential that follows,
278
+ preserve surrounding quotes and trailing delimiters (`,`, `;`, whitespace) outside
279
+ the redacted value, and never drop the closing quote.
280
+ - Idempotence: `redact(redact(x)) === redact(x)`. The markers `[REDACTED]` /
281
+ `[REDACTED-PEM]` are stable and not re-wrapped or corrupted.
282
+ - Verification guidance: cover true-positive credential cases, false-positive
283
+ safe-identifier and public-URL cases, quoted `Bearer`/`Basic` with trailing
284
+ delimiters, multi-line/PEM cases when relevant, and an idempotence round-trip.
285
+ Assert that no secret appears in error messages or completion reports and that
286
+ safe values are byte-identical after redaction.
287
+
288
+ ### Filesystem Write Boundary
289
+
290
+ - Require an existing real directory as root. Reject before any mutation when
291
+ `targetPath` is empty or whitespace-only, contains a URI scheme, is absolute,
292
+ escapes via `..` segments, or escapes via sibling-prefix (`root` vs
293
+ `root-evil`).
294
+ - Containment needs two checks: lexical containment of the resolved path
295
+ (`path.resolve(root, target)` inside root) **and** `realpath` containment of
296
+ the deepest existing parent directory. This blocks symlink-pointing-outside
297
+ and traversal that lexical check alone would miss. Never follow or overwrite a
298
+ symlink at the final target; never create parent directories outside root.
299
+ - Perform atomic same-directory write: create a temporary file in the target
300
+ directory, write fully, then `rename` into place. Remove the temp file on any
301
+ error. Rejections must happen before creating or modifying anything outside root.
302
+ - Return the canonical `realpath` of the target on success (e.g. macOS
303
+ `/var` → `/private/var` alias must resolve). Keep the public API otherwise
304
+ unchanged.
305
+ - Verification guidance: nested success, traversal / absolute / URI / sibling-prefix
306
+ rejection, parent-symlink rejection, final-symlink rejection (do not follow or
307
+ overwrite), no-outside-mutation assertion (filesystem outside root unchanged on
308
+ failure), atomic temp cleanup, and canonical return-path equality. Critical runs
309
+ the full project suite; Direct/Standard use proportional lane evidence (targeted
310
+ unit test + diff self-check for Direct, bounded suite for Standard).
311
+
260
312
  ## API Security Checklist
261
313
 
262
314
  - [ ] Use HTTPS/TLS 1.3 only
@@ -45,6 +45,26 @@ Stage A applies same spec compliance review checklist for every tier: scope, req
45
45
  - Scope fidelity is mandatory: missing scoped behavior, extra unapproved behavior, or task output that exists only as orphaned/unreachable code is a review failure even when build/tests pass.
46
46
  - Runtime-facing artifacts must be reachable from the real entrypoint/caller named by the task or the task-aware scout report.
47
47
 
48
+ ### Critical security verification (apply only when the task touches these surfaces)
49
+
50
+ No fixed ceremony for every task — apply the checklist below only when the
51
+ touched files, risk signals, or task description include logging/redaction or
52
+ filesystem write boundaries. Direct uses targeted unit test + diff self-check,
53
+ Standard a bounded suite, Critical strict evidence (inspector/test-runner/
54
+ code-auditor per lane policy).
55
+
56
+ - **Logging / secret redaction:** assert broad matchers did not corrupt safe
57
+ identifiers or public URLs; quoted `Bearer`/`Basic` redaction keeps surrounding
58
+ quotes and leaves trailing `,`/`;`/whitespace outside the replacement; redaction
59
+ is idempotent (`redact(redact(x)) === redact(x)`); no secret appears in test
60
+ failures or the verification receipt.
61
+ - **Filesystem write boundary:** assert lexical `path.resolve` **and** `realpath` of
62
+ the deepest existing parent both stay inside the canonical root; parent-symlink
63
+ and final-symlink targets are rejected without following/overwriting; no file
64
+ outside root is created or mutated on rejection; write goes via same-directory
65
+ temp file + atomic `rename` with cleanup on error; success returns canonical
66
+ `realpath` (platform aliases resolved).
67
+
48
68
  ## Flash Gate (`--flash`)
49
69
 
50
70
  Use this only when `/hapo:develop ... --flash` is present.