From f76901bcfb73d2d742b1cdbd9920791a7f500c2d Mon Sep 17 00:00:00 2001 From: Daniel Rosales <111561081+dnlrsls@users.noreply.github.com> Date: Sat, 10 Oct 2026 15:07:40 -0500 Subject: [PATCH] docs(odd): track pinned safety correction chain --- odd/tasks/path-fence-1659-1660.md | 64 +++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 odd/tasks/path-fence-1659-1660.md diff --git a/odd/tasks/path-fence-1659-1660.md b/odd/tasks/path-fence-1659-1660.md new file mode 100644 index 000000000..6212618e8 --- /dev/null +++ b/odd/tasks/path-fence-1659-1660.md @@ -0,0 +1,64 @@ +# Complete path-consent safety follow-ups +Branch: `fix/path-fence-1659-1660`; base: PR #1610 at `162c9bda89242a73f5ed55d7383a8d96ad19660d`. +Delivery: `feature-branch-chain`, selected by user; tracker draft/no-merge on pinned #1610 dependency, focused child PRs <=400 diff lines; Node test runner. + +## Specs +S1. User workflow: "que sigue acá? hacer el analisis y luego validar los problemas y hacer la implementacion ,verify, rdd y PR?"; authorization: "hagamos eso". +S2. Approval: "Aprobemos los issues, somos maintainers". Both issues must retain the verified `status:approved` label. +S3. Base decision: "¿Confirmás que seguimos sobre el head del PR #1610 y preparamos un PR complementario?" → "sip". +S4. #1659 expected: "a target that writes outside the session worktree through a symlink requires per-target consent". Validate the existing dangling-symlink regression; do not duplicate upstream correction. +S5. #1660 expected: "malformed boundary inputs are dropped at read and never widen the boundary (fail closed); confirmation-failure semantics are uniform across the two confirmation flows; path-key coverage is guarded against schema drift." + +S6. Investigation authorization: "sip, investiguemos los fallos". Diagnose full-suite causes before resuming delivery; no unrelated implementation is implied. +S7. Fixture correction authorization: "¿autorizás corregir la portabilidad y el aislamiento de esos fixtures en una unidad separada del arreglo de seguridad?" → "sip, hagamos eso". Keep fixture fixes separate from the security correction. +S8. Launcher reproduction: "spawnSync ... fake-pi.mjs EFTYPE". Correct the disposable fake runtime's Windows execution without changing production launcher behavior. +S9. Permission and Git fixtures: "chmod 000" remains readable on Windows; registry bootstrap expected `[]` but found an enclosing Git root. Preserve the unreadable-input rejection check and isolate the no-repository fixture. +S10. SIGINT investigation authorization: "¿investigamos la interrupción en Windows como alcance separado, sin relajar la exigencia de salida `130`?" → "sip". Investigation remains read-only; no automatic acceptance of a new test strategy. +S11. Windows fixture adaptation authorization: "¿Autorizás esa adaptación?" → "sip". Deliver the event to the actual launcher in a test-only Windows fixture, keep normal exit130/no-Pi/child-termination checks, and keep native signal delivery on POSIX. Windows result is modeled event proof, not console E2E. + +S12. External-temp permission: "¿autorizás usar únicamente la carpeta descartable `C:\Users\Blackie\AppData\Local\Temp\gentle-shell-verify-1659-1660` para repetir sólo ese caso?" → "sip, hagamos eso". Recheck only absent-peer PATH fallback; do not expand external access or rerun the suite. + +## Tasks +- T0 | S6 | delegated read-only investigation: three causes proven, remainder unclassified | dropped: superseded by authorized scoped fixture correction, not claimed fully classified | commit: N/A (investigation only). +- T3 | S7-S9 | two parallel bounded writers with disjoint launcher vs permission/Git edit surfaces | in_progress: independent verification complete including targeted absence/PATH recheck; two separate work-unit commits pending | two work-unit commits pending; permission/Git and targeted launcher checks pass, full launcher remains partial. +- T1 | S1-S5 | inline implementation: shared confirmation flow, no independent disjoint writer units; independent delegated verify (security trigger), then RDD | pending: fixture prerequisite T3 | commit: pending; inherited primary regressions pass. +- T2 | S1-S3 | inline delivery: publish complementary branch/PR and record evidence | pending | commit: pending. + +## Log +L1. Original request: "que sigue acá? hacer el analisis y luego validar los problemas y hacer la implementacion ,verify, rdd y PR?" +L2. Authorization: "hagamos eso". Approval: "Aprobemos los issues, somos maintainers". Base confirmation: "sip" to the exact S3 question. +L3. Current main lacked the reported fence. PR #1610 remains open; its pinned head already contains `c4bdac5684be73ced3e743973bdcf0de24d9b3f9` (dangling links) and `2a77814029102116b8eebdfa75d0fb2f917cde12` (invalid durable roots). Do not reimplement these fixes. Both issues approved with verified MAINTAIN capability and post-readback. +L4. Baseline: `node --experimental-strip-types --test tests/path-consent-fence.test.ts tests/session-worktree-registry.test.ts`: 30 pass, 1 fail. Dangling alias OS-write witness and malformed roots pass. Existing bootstrap fixture at registry test:63 detects enclosing user-home Git repo instead of no repo; this is a known base/environment failure, not candidate RED. No skipped symlink checks. +L5. Dependencies installed with frozen lockfile and scripts disabled; generated local store removed. No dependency/lockfile changes. Installed public Pi tool factories confirm all six currently carry `path`; a schema-key assertion will flag future additions rather than inventing speculative path extraction. +L6. Remaining implementation: optional confirmation capability must deny consistently in shell and path flows; actual confirmation rejections keep denied lifecycle and original exception. Add public hook regression (RED before fix), preserve approved/denied/rejected behavior, and add installed-schema parity assertion. Schema assertion has no meaningful behavior RED because current schemas already match; simulate drift to prove the assertion rejects additions. +L7. Checks planned: targeted confirmation tests; all path-fence tests; full suite and typecheck once after correction; independent verifier with exact known baseline failure. RDD is enabled globally; candidate consent remains separate. No changes to Bash path fencing (parent #1305 slice 3). +L8. RED observed: missing-confirm public hook regression fails with `TypeError: Cannot read properties of undefined (reading 'confirm')` at confirmCommand. Applied optional confirmation call; GREEN pending. +L9. GREEN: targeted confirmation lifecycle tests pass and path-fence suite is 17/17 passing, no skips. Typecheck initially found TS2339 in the synthetic schema clone; corrected its test-only type annotation without changing runtime behavior. Corrected `pnpm typecheck` passes (187 recorded diagnostics, no regressions). Full suite remains in progress; final focused spot check includes the no-cached-grant assertion. Candidate is staged (140 authored diff lines). ASSESS before staging was unassessable due to intended untracked paths, so independent security verification remains required. +L10. Final focused spot check: 3/3 passing (missing capability, existing confirmation lifecycle, installed schema assertion). `pnpm check:runtime-modules` passes: 9 generated modules match; no runtime generation needed. Independent verifier running after focused self-checks; full suite still running. No RDD START or publication yet. +L11. Independent verifier passes candidate scope with no severe blockers: confirmation tests 2/2, path-fence 17/17, malformed-root focused 1/1, all without skips. Outside-path approval/error logic was inspected, not separately re-executed as a full matrix. ASSESS after staging: high (security escalation from native medium); independent verification required. `reviewDue` false (`under_budget`), but user explicitly requested RDD. INSPECT ready; no START, lineage, receipt or consent granted yet. +L12. Full `pnpm test` has detected at least 30 failing tests across unrelated guard, preferences, relay and bootstrap surfaces; complete result still pending. Only the earlier registry bootstrap failure is proven baseline/environment-specific. Do not claim every new suite failure is preexisting or mark the feature done. Pause RDD, commits, push and PR until the user decides whether to authorize investigation of these full-suite failures or proceed with explicitly limited draft delivery. No further verification started. Existing full-suite job remains running to its original completion. +L13. User continuation: "sip, investiguemos los fallos". Resume with read-only failure classification and bounded base/candidate reproductions. Do not rerun the full suite or add unrelated fixes. Original full-suite job still running at 8m15s when investigation began; candidate/base state unchanged. +L14. Root-class mapping completed read-only (CodeGraph unavailable, no index mutation). No final unit summary; runner waits for child close and has no stage timeout, so a specific hang is not proven. Initial count was 181 failure records, not a final failure total. +L15. Bounded launcher reproduction: `Herdr isolated TUI launch explicitly loads the canonical managed bridge` fails identically on candidate and base-production override with `spawnSync ... fake-pi.mjs EFTYPE`, assertion 1 !== 0. Base override uses immutable `git show` source via Node load hook, preserving cwd/import resolution; relevant bin/lib/runtime/tests unchanged from pinned base. +L16. First exact permission regex matched no named test; its file-level exit 0 is NOT successful proof. Corrected selector `an unreadable file` executes the actual history-GC witness and fails: Windows can read chmod-000 input, GC removes it, cleanup chmod throws ENOENT. A disposable in-workspace OS probe confirms `readableAfterChmod000: true`. Relevant history source/test paths are unchanged from pinned base; no source fixes made. +L17. Three causal classes have evidence: Windows fake executable launch (identical base/candidate witness), Windows POSIX-mode assumption (direct OS witness and existing GC failure), and previously proven ancestor-Git fixture interference. Do not attribute every one of the 181 observed records to these classes; remainder and full-suite termination still unresolved. +L18. Stopped original job-7 after observed failures and prolonged unfinished unit stage; no terminal suite result. Provider-contract and runtime-harness stages were not reached. No full-suite retry, source fix, commit or review transaction created. Investigation is partial: three root classes evidenced; remaining failures and specific delay cause unproven. Needs user decision to authorize separate fixture portability/isolation work before security delivery can resume. +L19. User authorizes separate fixture correction: "sip, hagamos eso" to exact S7 question. Two independent units (launcher fake process harness vs permission/Git fixture isolation) have disjoint edit surfaces and each requires substantive helper/test work; Writer parallelism trigger applies. Launch both bounded writers together; no production launcher, history store or registry changes. Do not skip the requested permission scenario on Windows; inject a scoped unreadable-file witness when mode bits cannot enforce it. Forecast combined feature <400 authored diff lines; review budget applies to honest final diff. +L20. Permission/Git writer returns completed: focused unreadable 1/1, registry 16/16, full GC 22/22, no skips. Parent readback validates exact-path EACCES restoration, byte preservation and real nested-parent barrier witness. POSIX real-permission branch not executed on this Windows host. Parent spot check pending. +L21. Launcher writer returns partial: requested launcher witnesses 3/3 and helper 1/1 pass; whole launcher file 116 pass/6 fail/8 existing skips. Scope remains test-only. One bounded correction batch authorized for the same fixture surfaces: bare PATH mock lookup and only demonstrable portable expectations; no persona/CLI/signal contract weakening. `pnpm check:provider-contract` and `pnpm test:harness` now both pass (original stopped unit stage had not reached them). +L22. Parent spot check permission/Git: 38/38 pass, zero skips. Launcher one correction batch fixes 5 of the 6 exposed failures (root-first PATH mock lookup, Windows quoting, observed persona restoration); full launcher now 121 pass/1 fail/8 preexisting skips. SIGINT assertion unchanged: native process reports signal SIGINT, while test requires normal exit 130. No safe fixture-only correction established; do not silently change the interruption contract. +L23. Typecheck of new fixture test found TS2769: JS helper return inferred as array union instead of command/args tuple. Parent applied test-only `[string, string[]]` annotation; corrected typecheck passes (187 recorded diagnostics, no regressions) and helper spot check 1/1 passes. No production files changed by fixture writers. No full-suite rerun, new RDD lineage, commits or publication. +L24. Final state: S7-S9 target fixes applied and target checks observed, but T3 remains partial because required full launcher validation has one unresolved SIGINT failure. No new independent fixture verifier or combined seam/full suite claimed; blocked proof is surfaced once as Needs your decision, not hidden by another sweep. All work-unit commits, source RDD and complementary PR remain pending. Needs user decision whether to investigate actual Windows interruption semantics as a separate authorized scope; no blanket skips or exit-code relaxation. +L25. User SIGINT investigation reply: "sip" to exact S10 question. Official Node v24 process/child-process docs state terminal Ctrl+C emits catchable SIGINT, while `child.kill('SIGINT')` on Windows force-terminates the target. Read-only source check: launcher registers SIGINT and forwards it in spawnAndWait; no production edit. +L26. Disposable Node v24.14.0 probe: native-kill gives code=null, signal=SIGINT, stdout READY only; modeled-event gives code130, signal=null, stdout READY/HANDLED. Both have empty stderr. Confirms mismatched test stimulus, not a launcher production bug or actual console Ctrl+C E2E. Do not equate the generic modeled handler with verified actual launcher cancellation/child cleanup. +L27. Recommendation awaiting implementation consent: Windows-only controlled delivered-event fixture for the actual launcher, preserving normal exit130/no-pi/child-termination assertions and actual OS signals on POSIX. Report Windows transport proof as modeled, not console E2E. No source changes in this investigation; previous failures/skips and RDD/commit/PR blockers remain explicit. +L28. User adaptation reply: "sip" to exact S11 question. Inline route: understood bounded test-only correction, no second disjoint writing unit or context trigger. Existing SIGINT failure is RED evidence. Forecast remains near400 authored lines; inspect actual total before next commit without cosmetic reduction. +L29. Windows adaptation GREEN: interrupt and ordinary child-signal cases 2/2; provisioning PID termination asserted. Final seam across five affected test files: 178 pass/0 fail/8 preexisting skips (186 tests). Final `pnpm typecheck` passes: no regressions; 187 recorded diagnostics. No actual Windows console E2E or POSIX-host execution claimed. +L30. Delivery selection question returned "Cadena con rama tracker — recomendado". Cache `delivery_strategy=auto-chain`, `chain_strategy=feature-branch-chain`; use pinned dependency mirror so child diffs exclude #1610 foundation. Tracker draft/no-merge; fixture and security slices remain separate. Actual authored diff 398 lines before recording closure, so final crosses400; split honestly, no cosmetic shrink. +L31. Independent final verification required by high native assessment and small delegated-writer profile, before work-unit commits/source RDD. Full unrelated unit corpus remains unclassified from stopped initial run; affected-file seam, provider contract and runtime harness are green. +L32. Independent filesystem verification passes S7/S9:38/38, no skips, fresh in-workspace copy and scoped temporary fixtures; scratch removed. Independent launcher verification is partial:122 pass/1 fail/8 unchanged skips. SIGINT real launcher handler passes normal exit130/signal=null/no-Pi/provisioning PID ESRCH; ordinary child self-kill and helper pass. Sole failed absent-peer witness expected Pi0.99.2 but found ancestor installed Pi1.0.0 because scratch-local TMP nested the fixture under linked node_modules. S8 absence/PATH fallback remains unverified independently. No retries or source correction. +L33. Needs user decision: authorize one disposable external temp target `C:/Users/Blackie/AppData/Local/Temp/gentle-shell-verify-1659-1660` for the single blocked-case recheck, or explicitly accept limited-proof draft delivery. No new verification until decision; full corpus remains unclassified, POSIX/console E2E unavailable, commits/RDD/PR still pending. Pin unchanged although fresh PR1610 head is e262890dcb5f69ff6b7289f7baa491ec72a9bc03; pinned tree has no PR template, confirmed correct cwd/root. +L34. User replies "sip, hagamos eso" to exact S12 permission. Continue the same independent launcher verifier for only its one blocked case; no source correction, no full sweep. External directory must be created exclusively, never overwrite existing contents; remove only owned disposable state. +L35. Targeted independent recheck PASS: `node --experimental-strip-types --test --test-timeout=60000 --test-name-pattern='^a genuinely absent adjacent peer falls back to PATH$' tests/gentle-shell-bin.test.ts`; exit0, exactly1 selected/1 pass/0 fail/0 skips, runner stderr empty. Child status0 and stdout/Pi0.99.2 assertion pass; child stderr not asserted. Exclusive external target, scratch and dependency junction removed; no source change. Earlier122/1/8 run remains separate, not rewritten as full-file-green. +L36. Verification blocker resolved. Delivery boundaries: pinned mirror `feat/path-fence-1610-base`, draft tracker `feat/path-fence-safety`, filesystem child `test/path-fence-filesystem-fixtures`, launcher child `test/path-fence-launcher-fixtures`, security child `fix/path-fence-confirmation`. Tracker initially targets mirror (not main) to exclude inherited #1610 diff. Each child <=400 lines; no merge or base reconciliation authorized implicitly. RDD global on; review security work-unit only against preceding boundary, with separate candidate consent. +L37. Fork `danielgap/gentle-pi` permission is READ. Complementary upstream PR requires publishing a new dependency branch pinned exactly to #1610 head, never modifying the contributor branch. Retarget after #1610 merges; do not claim inherited primary fixes as this candidate's diff.