Skip to content

Detect nested .ok projects and make deinit ancestor resolution explicit #684

Description

@kinpoe-ray

Summary

OpenKnowledge can end up with nested projects when a child project is initialized first and an ancestor is initialized later. ok init detects an existing .ok only by walking upward from the requested directory; initializing an ancestor does not detect descendant .ok projects inside its content scope.

This creates ambiguous project resolution and makes ok deinit <path> potentially surprising because it may resolve upward and remove an ancestor project rather than the directory the user believes they selected.

Environment

  • OpenKnowledge CLI: 0.29.1
  • macOS
  • OK Desktop

Reproduction / observed layout

The machine ended up with this structure:

/Users/example/.ok                         # ancestor OK project
/Users/example/Project/
└── kpr-oppo-knowledge-base/
    └── .ok                                # independent child OK project

The ancestor project's content.dir pointed into Project (the Desktop UI opened/displayed the child knowledge content), while kpr-oppo-knowledge-base also retained a complete independent OK setup (.ok, .okignore, MCP configs, project skills, and .git/ok).

This can happen with the following ordering:

  1. Initialize Project/kpr-oppo-knowledge-base as an OK project.
  2. Later initialize /Users/example as another OK project and set its content.dir to Project or a descendant.
  3. The ancestor initialization succeeds because it does not scan the selected content scope for descendant .ok directories.

Surprising deinit behavior

Running:

ok deinit /Users/example/Project --dry-run --json

reported:

[ok] Using OpenKnowledge project at /Users/example

and planned removal of /Users/example/.ok plus its project-level MCP entries and skills. The requested path and resolved project root were different. With --yes, the ancestor project was removed while the nested child project remained.

The resolver behavior is internally consistent (nearest ancestor .ok), but it is easy for a user to misunderstand—especially when OK Desktop displays an opened folder/content directory rather than clearly distinguishing the project root and content.dir.

Risks

  • The same Markdown tree may be watched/indexed by both ancestor and child projects.
  • Project identity differs depending on the current working directory.
  • Desktop project name/opened folder, project root, and content directory can appear to be the same concept when they are not.
  • deinit <path> can remove configuration above the requested path without an explicit mismatch confirmation.

Suggested safeguards

  1. During ok init, scan the proposed content.dir for descendant .ok directories and warn or refuse unless explicitly overridden.

  2. Reject or warn when changing content.dir to a tree containing another OK project.

  3. Make parent watchers automatically exclude nested OK project roots.

  4. Before deinit, always show both:

    Requested path: /Users/example/Project
    Resolved project root: /Users/example
    
  5. When those paths differ, require an explicit confirmation or a flag such as --project-root /Users/example; consider not allowing --yes alone to bypass this mismatch protection.

  6. In OK Desktop, display the project root and content directory separately.

Expected behavior

OpenKnowledge should either prevent nested project configurations or handle them as an explicit, well-defined feature. Destructive project operations should make ancestor resolution unmistakable before applying changes.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions