Skip to content

fix(KEN-3935): anchor new worktree link exclusions to the root - #4976

Merged
vanillagreen-fleet-lanes[bot] merged 7 commits into
mainfrom
ken-3935
Oct 14, 2026
Merged

vanillagreen-fleet-lanes[bot] merged 7 commits into
mainfrom
ken-3935

Conversation

@vanillagreen-fleet-lanes

@vanillagreen-fleet-lanes vanillagreen-fleet-lanes Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Write new worktree exclusion entries and negations at the repository root. New files under a tracked nested directory with the same name remain visible and stage with git add -A.
  • Preserve existing rules and file permissions. Retain exclusion read and write failures through each setup and repair caller.
  • Create an absent exclusion file directly under the caller's permission mask. The existing-file replacement path keeps its permission-preserving copy and checked replacement.
  • Legacy bare-line migration is outside this pull request. Existing bare rules remain unchanged; KEN-4001 tracks their migration.

Done when

  • Root anchoring and nested file staging: the exclusion writer and exclusion suite.
  • Help: the fix-links help section states /<path> and !/<path>/.
  • Matching tracked renders and the worktree changelog fragment ship with the source changes. The path safety suite's existing exclusion expectations use the anchored output.

Test plan

  • Cut boundary suite: 13 assertions passed. Fresh anchored rules leave nested new files visible and staged. Existing bare rules and negations remain intact, including missing-source creation.
  • First-write cut: 12 assertions passed. Mask 027 produces mode 640. Both retained-call controls fail their rows, including a write that leaves no exclusion file.
  • Test fixture correction: 5 selected assertions passed after removing POSIX startup. Bash 3.2 rejects the script's existing process substitutions in POSIX mode; the supported startup keeps the permission-mask and missing-output checks.
  • Retained setup and repair outcome matrix: 266 assertions passed. Read and write faults retain their command failures.
  • The preserved-rule control fails when legacy cleanup is restored. Earlier retained-call controls detect discarded writer failures and the second-write error check.
  • Path safety suite: 21 assertions passed.
  • Preflight, document limits, and commit guards passed.
  • Linux and macOS worktree suites passed before the base update. The feature diff is unchanged after a clean update onto the merged KEN-3992 fix. Configured validation accepted CI mode. Required CI passed on the new published head. The permitted macOS overseer retry passed. Merge-group validation is pending.

Created issues

  • KEN-4001: migrate old bare exclusions across all setup paths. This follow-up carries the verified missing-source migration failure removed from this pull request's scope.

Merge decision

Prepared head: 44d87570abeb18fa40b1dd9c6e30cab9f9b4f545.

Attempt: --expected-head 44d87570abeb18fa40b1dd9c6e30cab9f9b4f545, exit 75, merge-route: queue cause=queue-occupied. The feature review is retained because its files are byte-identical after the base update. Copilot approved this head in review 5509185778. Required CI and current-head approval passed again after the merge-group failure tracked in KEN-4024. The overseer authorized a retry on this unchanged head. The latest exact-head merge attempt returned exit 75 and queued this pull request again. Merge-group validation is pending.

Closes KEN-3935

@linear-code

linear-code Bot commented Oct 13, 2026

Copy link
Copy Markdown

KEN-3935

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Exclusion-write failures are discarded, allowing setup or repair to report success without applying the migration.

1 open finding
What changed in this PR

Anchors worktree exclusions at the repository root and migrates legacy patterns.

Changes:

  • Writes anchored exclusions while preserving file modes.
  • Adds migration, nested-path, and mutation-control tests.
  • Updates help, render, and changelog files.
File Description
skills/​worktree/​scripts/​lib/​links.sh Implements anchored exclusions and migration.
skills/​worktree/​scripts/​lib/​help.sh Documents exclusion behavior.
skills/​worktree/​tests/​worktree_exclude_tracked_paths.sh Expands exclusion tests and controls.
skills/​worktree/​tests/​worktree_path_safety.sh Updates expected anchored patterns.
.agents/​skills/​worktree/​scripts/​lib/​links.sh Updates the tracked script render.
.agents/​skills/​worktree/​scripts/​lib/​help.sh Updates the tracked help render.
changelog.d/​worktree/​fixed/​root-excludes.md Records the user-visible fix.

🧠 Review effort: Balanced


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread skills/worktree/scripts/lib/links.sh Outdated
@vanillagreen-fleet-lanes
vanillagreen-fleet-lanes Bot marked this pull request as draft October 13, 2026 14:07
@vanillagreen-fleet-lanes

Copy link
Copy Markdown
Contributor Author

Design contract: each exclusion caller retains the writer result.

written means the root-anchored entry and required negation are present, exact legacy lines are removed, and existing permissions and other patterns are retained. unchanged means that result was already present, or the path is empty. A replacement failure returns 1 and emits worktree-exclude-write-failed. A read failure returns 1 and emits worktree-exclude-read-failed. A missing exclusion file is a valid first-write case. A failed Git-directory lookup is a read failure. An empty successful filter result is not a read failure.

The table states the result of the exclusion operation. Other operations in the same caller must also succeed before the caller returns 0.

Direct caller in links.sh Routes that invoke it Written Unchanged Replacement failed Read failed
copy_ignore_file_into_worktree Untracked .gitignore child through link_untracked_child and link_untracked_children; create, fix-links, or tracked-directory repair 0; no local message 0; no local message 1; writer error; parent records the unresolved child 1; writer error; parent records the unresolved child
symlink_into_worktree Configured root symlink through setup; tracked-directory repair; missing or safe materialized link through repair_materialized_path; untracked child link through the same repair path 0; no local message 0; no local message 1; writer error retained by setup or repair 1; writer error retained by setup or repair
setup_worktree_links: WORKTREE_MKDIRS Create, fix-links, and setup after a completed rewrite 0; no local message 0; no local message 1; writer error; stop setup 1; writer error; stop setup
setup_worktree_links: WORKTREE_COPIES Create, fix-links, and setup after a completed rewrite 0; no local message 0; no local message 1; writer error; stop setup before the configured copy 1; writer error; stop setup before the configured copy
setup_worktree_links: WORKTREE_RELATIVE_SYMLINKS Create, fix-links, and setup after a completed rewrite 0; no local message 0; no local message 1; writer error; stop setup 1; writer error; stop setup
Command or repair route Written or unchanged Replacement or read failure
create, including setup through setup_app_worktree 0; normal created-worktree result 1; writer error; no successful created-worktree result
create --reuse, rewrite completion, and app setup carriers 0; their normal terminal result 1; writer error retained through the existing setup return
fix-links 0; worktree-links-restored 1; writer error plus worktree-links-unrestored; no restored result
repair-links: tracked directory 0; normal child repair result 1; writer error; child-links-unresolved when a child fails
repair-links: missing or safe materialized runtime link 0; worktree-links-repaired when the link changes 1; writer error; no repaired result for the failed path
repair-links: already healthy runtime link 0; quiet; the writer is not invoked The writer is not invoked on this path
Post-rebase setup in push 0; continue the guarded push 1; writer error; stop before the push

The final production round checks the writer's reads and writes and all direct caller returns against this table. Tests use the real commands and isolate the replacement and read failures. They retain the calls when removing the checked returns for a must-fail control. If the migration still fails after this round, the authorized scope cut keeps anchored new entries and removes the legacy migration. A proposal will record the migration symptom and how a user reaches it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Legacy exclusions remain unmigrated for missing sources and already-healthy repaired symlinks.

1 open finding

🧠 Review effort: Balanced

Comment thread skills/worktree/scripts/lib/links.sh Outdated
@vanillagreen-fleet-lanes

Copy link
Copy Markdown
Contributor Author

Dispositions at 0a313f1

review:5506118711 - Tracked: KEN-4001. The missing-source create migration failure is verified and moves to the follow-up issue. Legacy migration is being removed from this pull request. Missing-source fix-links reports failure. The healthy repair path does not invoke the writer under the posted design.

Copilot AI previously approved these changes Oct 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approved

The anchored rules, error propagation, compatibility scope, documentation, and regression coverage are consistent with the stated fix.

0 open findings

🧠 Review effort: Balanced

Copilot AI previously approved these changes Oct 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approved

The implementation, tracked renders, documentation, and regression coverage consistently address the root-anchoring defect.

0 open findings

🧠 Review effort: Balanced

@vanillagreen-fleet-lanes vanillagreen-fleet-lanes Bot changed the title fix(KEN-3935): worktree: the info/exclude line for a WORKTREE_SYMLINKS entry is unanchored and hides nested directories of the same name fix(KEN-3935): anchor new worktree link exclusions to the root Oct 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approved

The implementation, documentation, renders, and regression controls consistently cover the intended root-anchoring behavior.

0 open findings

🧠 Review effort: Balanced

@vanillagreen-fleet-lanes
vanillagreen-fleet-lanes Bot added this pull request to the merge queue Oct 13, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 13, 2026
@vanillagreen-fleet-lanes
vanillagreen-fleet-lanes Bot added this pull request to the merge queue Oct 13, 2026
Merged via the queue into main with commit b122ac5 Oct 14, 2026
145 of 147 checks passed
@vanillagreen-fleet-lanes
vanillagreen-fleet-lanes Bot deleted the ken-3935 branch October 14, 2026 03:10
@vanillagreen-fleet-lanes

Copy link
Copy Markdown
Contributor Author

Completed issue

  • KEN-3935: new worktree exclusion rules ignore the root link. New files under a tracked nested directory of the same name remain visible and stage with git add -A.
  • PR #4976 merged at 2026-10-14T03:10:31Z as b122ac556eab774a78cb09e38cf7da8b69094337.
  • Done-when 1: the writer emits /NAME and !/NAME/. The exclusion tests prove that the root link stays ignored and the nested new file stages.
  • Done-when 2: fix-links --help states the anchored forms.

Created issue

  • KEN-4001: worktree: a bare exclusion line an earlier version wrote migrates to the anchored form on every setup path. Project: Skills & Agents Library. Existing bare rules remain unchanged in this merge.

Validation

  • Local checks passed: 13 cut-boundary assertions, 12 first-write assertions, 5 selected fixture assertions, 266 setup and repair outcome assertions, and 21 path-safety assertions.
  • Failure controls detect discarded writer failures, a missed second write failure, and removal of the legacy-rule preservation boundary.
  • The final error-handling, test, and external reviews passed. The feature files stayed byte-identical after the base update.
  • Linux and macOS worktree CI passed. Required CI passed on head 44d87570abeb18fa40b1dd9c6e30cab9f9b4f545. Copilot approved that head in review 5509185778.
  • The permitted macOS overseer retry passed. The overseer tracked the later merge-group wall-time failure in KEN-4024 and authorized the unchanged-head queue retry. The PR then merged.

Review changes

  • Review: preserve existing exclusion-file permissions in d567424ce89d3566075cb4f8b42b5537fbaa0872.
  • Copilot: retain writer read and write failures through setup and repair callers in f17193794db5a113f640f18c8b1e1bf4be3a2313.
  • Test review: cover the second content-write failure in 3abe511fb38525103de970d6449764383a99fd77.
  • Scope cut: preserve legacy bare rules and move migration to KEN-4001 in 7997bda3e52973e523f88d6596559862797b3b16.
  • CI scope cut: create an absent exclusion file under the caller's permission mask in 865f17855652c9a08093c187971fdf08bba29ea7.
  • Test review: remove the unsupported POSIX startup from the Bash 3.2 fixture in 44d87570abeb18fa40b1dd9c6e30cab9f9b4f545.

Recorded review cycles: 2. No post-merge box remains.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant