@ngockhoale/ukit 3.4.39 → 3.4.40

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 CHANGED
@@ -9,6 +9,13 @@ All notable changes to UKit are documented here.
9
9
  - New `/ukit:ci-check` command + `ci-check.mjs` helper (core pack): prechecks, fail-closed budget guard, local preflight, at most one dispatch per invocation, write-ahead run-id state, `status` (never dispatches), `--ref`, `--dry-run`, per-OS report. Never pushes, merges or publishes.
10
10
  - Default-branch bootstrap stub documented in `docs/design/CI-CROSS-PLATFORM-MATRIX.md` (requires separate approval).
11
11
 
12
+ ## 3.4.40 - 2026-10-12
13
+
14
+ **Completion Gate: a read-only request no longer owes `impact-evidence` it can never produce.**
15
+ - Root cause: a `READ_ONLY` contract (analysis of Markdown/logs/prompt text, read-only production inspection) carried `impact-evidence`, satisfied only by a source-read receipt. Answers drawn from docs, logs or text already in the prompt yield none, so Stop demanded further tool activity and looped into the loop breaker.
16
+ - Fix: for `READ_ONLY` with no named target files and no attempted write, `impact-evidence` is not applicable. A named target still needs its read; any attempted write (unauthorized side effect) keeps the obligation; mutation orders keep write/verification/operation proof.
17
+ - Regressions: `tests/hooks/completionGateRequestScope.test.js` (cross-request scope after an edit request, read-only inspection, missing contract, unauthorized write). Test allowlist gains the runtime-only `docs/AI_HANDOFF/RUN.md` cursor reference.
18
+
12
19
  ## 3.4.39 - 2026-10-12
13
20
 
14
21
  **Completion Gate: unrelated compound commands no longer erase authoritative git evidence; seals honour operation freshness.**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngockhoale/ukit",
3
- "version": "3.4.39",
3
+ "version": "3.4.40",
4
4
  "description": "Install/update an index-first AI workspace for Claude Code, OpenAI Codex and omp (Oh My Pi).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -3413,6 +3413,16 @@ function evaluateCompletionContract({ state = {}, ledger = {}, cwd, phase = null
3413
3413
  const operationalTask = operationStatus !== null;
3414
3414
  const missingEvidence = evidence.filter((item) => !evidenceSatisfied(item, effectiveLedger, state, { cwd }));
3415
3415
  if (operationalTask && !operationStatus.complete && !missingEvidence.includes('operation-verification')) missingEvidence.push('operation-verification');
3416
+ // A READ_ONLY request's deliverable is the reply: it may be answered from Markdown, logs or
3417
+ // text already in the prompt, none of which yields a source-read receipt, so impact-evidence
3418
+ // is NOT_APPLICABLE to it when no target files were named (request-scoped — never inherited from an earlier edit request in
3419
+ // the same session). Any attempted write keeps the obligation: an unauthorized side effect
3420
+ // of a read-only request is never treated as irrelevant.
3421
+ if (routeSummary.executionContract?.taskKind === 'READ_ONLY' && effectiveLedger.writeAttempted !== true
3422
+ && !(Array.isArray(routeSummary.expectedSourceFiles) && routeSummary.expectedSourceFiles.length > 0)) {
3423
+ const at = missingEvidence.indexOf('impact-evidence');
3424
+ if (at !== -1) missingEvidence.splice(at, 1);
3425
+ }
3416
3426
  const releaseMissing = releasePublicationMissing(state, effectiveLedger, cwd);
3417
3427
  if (releaseMissing) missingEvidence.push(releaseMissing);
3418
3428
  // TASK-009 (BL-011): the bug-fix floor. On a `playbookId: bug-fix` route a