cleanup
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 20 Nov 2025 04:12:43 +0000 (04:12 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 20 Nov 2025 04:12:43 +0000 (04:12 +0000)
tool/deprecated/skeleton_check [deleted file]
tool/deprecated/skeleton_commands.py [deleted file]
tool/deprecated/skeleton_compare.py [deleted file]
tool/deprecated/skeleton_config.py [deleted file]
tool/deprecated/skeleton_diff_docs.py [deleted file]
tool/deprecated/skeleton_paths.py [deleted file]
tool/skel.tgz [deleted file]

diff --git a/tool/deprecated/skeleton_check b/tool/deprecated/skeleton_check
deleted file mode 100755 (executable)
index 7051acb..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-#!/usr/bin/env python3
-# -*- mode: python; coding: utf-8; python-indent-offset: 2; indent-tabs-mode: nil -*-
-
-"""
-skeleton_check — CLI front-end for skeleton_diff
-"""
-
-import sys
-from pathlib import Path
-from typing import List
-
-from skeleton_commands import (
-  work_environment,
-  work_structure,
-  work_import,
-  work_export,
-  work_suspicious,
-  work_addendum,
-  work_version,
-  work_usage,
-)
-from skeleton_diff_docs import work_help
-
-
-def CLI() -> int:
-  args_list = sys.argv[1:]
-
-  program_name = Path(sys.argv[0]).name or "skeleton_check"
-
-  if not args_list:
-    work_usage(program_name)
-    return 1
-
-  # 1. Global dominating commands: usage, help, version
-  global_dom_commands_set = {
-    "usage",
-    "help",
-    "version",
-  }
-
-  for token in args_list:
-    if token in global_dom_commands_set:
-      if token == "usage":
-        work_usage(program_name)
-      elif token == "help":
-        work_help()
-      elif token == "version":
-        work_version()
-      return 0
-
-  # 2. Commands that never require a project, and those that do
-  commands_no_other_set = {
-    "environment",
-  }
-
-  commands_require_other_set = {
-    "structure",
-    "import",
-    "export",
-    "suspicious",
-    "addendum",
-    "all",
-  }
-
-  all_commands_set = commands_no_other_set | commands_require_other_set
-
-  commands_list: List[str] = []
-  other_root_path: Path | None = None
-  project_needed_flag = False
-  earliest_requires_index: int | None = None
-
-  n_args = len(args_list)
-  last_index = n_args - 1
-
-  for index, token in enumerate(args_list):
-    if token in all_commands_set:
-      # If we already saw a project-requiring command earlier, and this is
-      # the last token, interpret it as the project path instead of a command.
-      if project_needed_flag and index == last_index and earliest_requires_index is not None:
-        other_root_path = Path(token)
-        break
-
-      # Normal command
-      commands_list.append(token)
-      if token in commands_require_other_set and earliest_requires_index is None:
-        earliest_requires_index = index
-        project_needed_flag = True
-
-    else:
-      # Not a known command: may be the project path, but only if a command
-      # that requires a project has already been seen and this is the last arg.
-      if project_needed_flag and index == last_index and earliest_requires_index is not None:
-        other_root_path = Path(token)
-        break
-
-      print(f"ERROR: unknown command '{token}'.", file=sys.stderr)
-      work_usage(program_name)
-      return 1
-
-  # 3. Post-parse checks
-  if project_needed_flag:
-    # We saw at least one command that requires <other_project_path>.
-    if other_root_path is None:
-      # First project-requiring command was also the last argument: no project path left.
-      last_command = commands_list[-1] if commands_list else "<unknown>"
-      print(
-        f"ERROR: missing <other_project_path> after command '{last_command}'.",
-        file=sys.stderr,
-      )
-      work_usage(program_name)
-      return 1
-
-    if not other_root_path.is_dir():
-      print(f"ERROR: {other_root_path} is not a directory.", file=sys.stderr)
-      work_usage(program_name)
-      return 1
-
-  # 4. Expand 'all' into its constituent checks
-  expanded_commands_list: List[str] = []
-  if "all" in commands_list and len(commands_list) > 1:
-    print("ERROR: 'all' cannot be combined with other commands.", file=sys.stderr)
-    work_usage(program_name)
-    return 1
-
-  for command in commands_list:
-    if command == "all":
-      expanded_commands_list.extend([
-        "environment",
-        "structure",
-        "import",
-        "export",
-        "suspicious",
-        "addendum",
-      ])
-    else:
-      expanded_commands_list.append(command)
-
-  commands_list = expanded_commands_list
-
-  # 5. Execute commands
-  other_root: Path | None = other_root_path
-
-  for command in commands_list:
-    print(f"\\n--- Running: {command} ---")
-    if command == "environment":
-      work_environment()
-    elif command == "structure":
-      if other_root is None:
-        print("ERROR: 'structure' requires <other_project_path>.", file=sys.stderr)
-        work_usage(program_name)
-        return 1
-      work_structure(other_root)
-    elif command == "import":
-      if other_root is None:
-        print("ERROR: 'import' requires <other_project_path>.", file=sys.stderr)
-        work_usage(program_name)
-        return 1
-      work_import(other_root)
-    elif command == "export":
-      if other_root is None:
-        print("ERROR: 'export' requires <other_project_path>.", file=sys.stderr)
-        work_usage(program_name)
-        return 1
-      work_export(other_root)
-    elif command == "suspicious":
-      if other_root is None:
-        print("ERROR: 'suspicious' requires <other_project_path>.", file=sys.stderr)
-        work_usage(program_name)
-        return 1
-      work_suspicious(other_root)
-    elif command == "addendum":
-      if other_root is None:
-        print("ERROR: 'addendum' requires <other_project_path>.", file=sys.stderr)
-        work_usage(program_name)
-        return 1
-      work_addendum(other_root)
-    else:
-      # Should be unreachable because we validated commands_list.
-      print(f"Unknown command: {command}")
-      work_usage(program_name)
-      return 1
-
-  return 0
-
-
-if __name__ == "__main__":
-  sys.exit(CLI())
diff --git a/tool/deprecated/skeleton_commands.py b/tool/deprecated/skeleton_commands.py
deleted file mode 100644 (file)
index 32520c0..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-#!/usr/bin/env python3
-"""
-skeleton_commands — user-facing command implementations for skeleton_diff
-"""
-
-import os
-import sys
-from pathlib import Path
-from typing import List
-
-from skeleton_config import HARMONY_ROOT, VERSION
-from skeleton_paths import index_project
-from skeleton_compare import compare_harmony_to_other
-
-
-# ----------------------------------------------------------------------
-# environment
-# ----------------------------------------------------------------------
-def work_environment() -> int:
-  print("=== Environment ===")
-  print(f"REPO_HOME = {HARMONY_ROOT}")
-  for key, value in sorted(os.environ.items()):
-    if key.startswith(("HARMONY_", "REPO_", "PATH")) or "tool" in key.lower():
-      print(f"{key} = {value}")
-  return 0
-
-
-# ----------------------------------------------------------------------
-# structure
-# ----------------------------------------------------------------------
-def work_structure(other_root: Path) -> int:
-  print("=== Structure Comparison ===")
-
-  results = compare_harmony_to_other(other_root)
-
-  # Only consider directories for structural reports
-  skeleton_dir_list = [
-    rel for rel, info in results.skeleton_dict.items()
-    if info.path_type == "dir"
-  ]
-  other_dir_list = [
-    rel for rel, info in results.other_dict.items()
-    if info.path_type == "dir"
-  ]
-
-  skeleton_dir_set = set(skeleton_dir_list)
-  other_dir_set = set(other_dir_list)
-
-  missing_dir_list = sorted(
-    skeleton_dir_set - other_dir_set,
-    key=lambda p: (len(p.parts), str(p)),
-  )
-
-  new_dir_list = sorted(
-    other_dir_set - skeleton_dir_set,
-    key=lambda p: (len(p.parts), str(p)),
-  )
-
-  if missing_dir_list:
-    print("Missing Harmony directories in <other>:")
-    for rel_dir in missing_dir_list:
-      print(f"  [MISSING]   {rel_dir}")
-    print()
-
-  if new_dir_list:
-    print("New directories present only in <other>:")
-    for rel_dir in new_dir_list:
-      print(f"  [NEW]       {rel_dir}")
-    print()
-
-  if not missing_dir_list and not new_dir_list:
-    print("No structural directory differences detected.")
-
-  return 0
-
-
-# ----------------------------------------------------------------------
-# import / export
-# ----------------------------------------------------------------------
-def work_import(other_root: Path) -> int:
-  print("=== Import Commands (newer → Harmony) ===")
-
-  results = compare_harmony_to_other(other_root)
-  newer_list = results.newer_list
-
-  if not newer_list:
-    print("  No newer files in <other> to import.")
-    return 0
-
-  for rel_path in newer_list:
-    src = other_root / rel_path
-    dst = HARMONY_ROOT / rel_path
-    print(f"cp {src} {dst}  # clobbers older Harmony file")
-
-  return 0
-
-
-def work_export(other_root: Path) -> int:
-  print("=== Export Commands (Harmony → <other>) ===")
-
-  results = compare_harmony_to_other(other_root)
-  older_list = results.older_list
-
-  if not older_list:
-    print("  No stale files in <other> to export.")
-    return 0
-
-  for rel_path in older_list:
-    src = HARMONY_ROOT / rel_path
-    dst = other_root / rel_path
-    print(f"cp {src} {dst}  # clobbers stale file in <other>")
-
-  return 0
-
-
-# ----------------------------------------------------------------------
-# suspicious
-# ----------------------------------------------------------------------
-USER_OWNED_TOP = {
-  "developer",
-  "tester",
-  "release",
-}
-TOOL_TOP = {
-  "tool",
-  "tool_shared",
-}
-
-
-def work_suspicious(other_root: Path) -> int:
-  print("=== Suspicious Files (clutter outside expected zones) ===")
-
-  results = compare_harmony_to_other(other_root)
-  skeleton_dict = results.skeleton_dict
-  other_dict = results.other_dict
-
-  suspicious_list: List[Path] = []
-
-  for rel_path, other_info in other_dict.items():
-    if other_info.path_type != "file":
-      continue
-
-    if rel_path == Path("."):
-      continue
-
-    top_component = rel_path.parts[0]
-
-    # Skip user-owned zones
-    if top_component in USER_OWNED_TOP:
-      continue
-
-    # Skip tool zones
-    if top_component in TOOL_TOP:
-      continue
-
-    # If Harmony knows about this file, it is not suspicious.
-    if rel_path in skeleton_dict:
-      continue
-
-    suspicious_list.append(rel_path)
-
-  suspicious_list.sort(key=lambda p: (len(p.parts), str(p)))
-
-  if suspicious_list:
-    for rel_path in suspicious_list:
-      print(f"  [SUSPICIOUS] {rel_path}")
-  else:
-    print("  None found.")
-
-  return 0
-
-
-# ----------------------------------------------------------------------
-# addendum
-# ----------------------------------------------------------------------
-def work_addendum(other_root: Path) -> int:
-  print("=== Addendum: New Tools in <other> ===")
-
-  results = compare_harmony_to_other(other_root)
-  skeleton_dict = results.skeleton_dict
-  other_dict = results.other_dict
-
-  addendum_list: List[Path] = []
-
-  for rel_path, other_info in other_dict.items():
-    if other_info.path_type != "file":
-      continue
-
-    if rel_path == Path("."):
-      continue
-
-    parts = rel_path.parts
-    if not parts:
-      continue
-
-    top_component = parts[0]
-    if top_component not in TOOL_TOP:
-      continue
-
-    if rel_path not in skeleton_dict:
-      addendum_list.append(rel_path)
-
-  addendum_list.sort(key=lambda p: (len(p.parts), str(p)))
-
-  if addendum_list:
-    for rel_path in addendum_list:
-      print(f"  [ADDENDUM] {rel_path}")
-  else:
-    print("  None found.")
-
-  return 0
-
-
-# ----------------------------------------------------------------------
-# version / usage / help (help text lives in skeleton_diff_docs)
-# ----------------------------------------------------------------------
-def work_version() -> int:
-  print(f"skeleton_diff version {VERSION}")
-  return 0
-
-
-def work_usage(program_name: str) -> int:
-  print(f"Usage: {program_name} [<command>]...  [<other_project_path>]")
-  print()
-  print("<other_project_path> is required if any commands are specified that")
-  print("require a project to analyze.")
-  print()
-  print("Commands:")
-  print("  version      Show program version (Major.Minor)")
-  print("  help         Long-form documentation")
-  print("  usage        This short summary")
-  print("  environment  Show key environment variables (including $REPO_HOME)")
-  print("  structure    Compare directory structure")
-  print("  import       Print shell commands for pulling newer skeleton")
-  print("               files into Harmony")
-  print("  export       Print shell commands for pushing Harmony skeleton")
-  print("               files into <other>")
-  print('  suspicious   List "between" files that are not in the skeleton')
-  print("  addendum     List tool files in <other> that do not exist in")
-  print("               the Harmony skeleton (project-local additions)")
-  print("  all          Run the full set of analyses")
-  print()
-  print("Examples:")
-  print(f"  {program_name} usage")
-  print(f"  {program_name} structure import ../subu")
-  print(f"  {program_name} all ../subu")
-  print()
-  print(f"Run '{program_name} help' for detailed explanations.")
-  return 0
diff --git a/tool/deprecated/skeleton_compare.py b/tool/deprecated/skeleton_compare.py
deleted file mode 100644 (file)
index ac76673..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env python3
-"""
-skeleton_compare — comparison logic between Harmony skeleton and <other>
-"""
-
-from dataclasses import dataclass
-from pathlib import Path
-from typing import Dict, List, Set
-
-from skeleton_config import HARMONY_ROOT
-from skeleton_paths import NodeInfo, index_project
-
-
-@dataclass
-class ComparisonResults:
-  skeleton_dict: Dict[Path, NodeInfo]
-  other_dict: Dict[Path, NodeInfo]
-  missing_list: List[Path]
-  addendum_list: List[Path]
-  newer_list: List[Path]
-  older_list: List[Path]
-
-
-def compare_harmony_to_other(other_root: Path) -> ComparisonResults:
-  """
-  Build Harmony and <other> indexes and compare them.
-
-  - missing_list: paths present in Harmony, absent in <other>.
-  - addendum_list: paths present in <other>, absent in Harmony.
-  - newer_list: file paths where <other> is newer than Harmony.
-  - older_list: file paths where <other> is older than Harmony.
-  """
-  other_root = other_root.resolve()
-
-  skeleton_dict = index_project(HARMONY_ROOT)
-  other_dict = index_project(other_root)
-
-  skeleton_paths_set: Set[Path] = set(skeleton_dict.keys())
-  other_paths_set: Set[Path] = set(other_dict.keys())
-
-  missing_list: List[Path] = sorted(
-    skeleton_paths_set - other_paths_set,
-    key=lambda p: (len(p.parts), str(p)),
-  )
-
-  addendum_list: List[Path] = sorted(
-    other_paths_set - skeleton_paths_set,
-    key=lambda p: (len(p.parts), str(p)),
-  )
-
-  newer_list: List[Path] = []
-  older_list: List[Path] = []
-
-  for rel_path in sorted(
-    skeleton_paths_set & other_paths_set,
-    key=lambda p: (len(p.parts), str(p)),
-  ):
-    skeleton_info = skeleton_dict[rel_path]
-    other_info = other_dict[rel_path]
-
-    if skeleton_info.path_type != "file" or other_info.path_type != "file":
-      continue
-
-    if other_info.mtime > skeleton_info.mtime:
-      newer_list.append(rel_path)
-    elif other_info.mtime < skeleton_info.mtime:
-      older_list.append(rel_path)
-
-  return ComparisonResults(
-    skeleton_dict=skeleton_dict,
-    other_dict=other_dict,
-    missing_list=missing_list,
-    addendum_list=addendum_list,
-    newer_list=newer_list,
-    older_list=older_list,
-  )
diff --git a/tool/deprecated/skeleton_config.py b/tool/deprecated/skeleton_config.py
deleted file mode 100644 (file)
index 1724b20..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python3
-"""
-skeleton_config — shared configuration for skeleton_diff
-
-Version: Major.Minor = 0.6
-Author: Thomas Walker Lynch, with Grok and Vaelorin
-Date: 2025-11-18
-"""
-
-import os
-import sys
-from pathlib import Path
-
-MAJOR = 0
-MINOR = 6
-VERSION = f"{MAJOR}.{MINOR}"
-
-
-def _discover_harmony_root() -> Path:
-  repo_home = os.getenv("REPO_HOME")
-  if repo_home:
-    root_path = Path(repo_home).resolve()
-  else:
-    # Fallback: assume current working directory is inside Harmony
-    root_path = Path.cwd().resolve()
-  if not root_path.exists():
-    print("ERROR: $REPO_HOME not set or invalid. Source env_toolsmith.", file=sys.stderr)
-    sys.exit(1)
-  return root_path
-
-
-HARMONY_ROOT = _discover_harmony_root()
diff --git a/tool/deprecated/skeleton_diff_docs.py b/tool/deprecated/skeleton_diff_docs.py
deleted file mode 100644 (file)
index 3db2d1e..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-#!/usr/bin/env python3
-"""
-skeleton_diff_docs — long-form help text for skeleton_diff
-"""
-
-from pathlib import Path
-from skeleton_config import VERSION
-
-
-def work_help() -> int:
-  help_text = f"""
-skeleton_diff — Harmony Skeleton Auditor
-========================================
-
-Version: {VERSION}
-
-1. Purpose
-1.1  The skeleton_diff tool compares a Harmony project (the skeleton) with
-     another project (<other>) that was originally cloned from Harmony.
-1.2  Over time, individual projects tend to evolve:
-     - Some improvements are made in projects but never pulled back to the
-       Harmony skeleton.
-     - Some improvements make it back into Harmony, leaving older projects
-       with stale copies of skeleton files.
-     - Extra directories and files appear in projects, some intentional and
-       some accidental.
-1.3  skeleton_diff helps you see that drift clearly so that you can:
-     - Pull newer tooling back into the skeleton.
-     - Push newer skeleton files out into projects.
-     - Spot suspicious clutter and structural misuse of the skeleton.
-
-2. Invocation and Argument Rules
-2.1  Basic command line form:
-       skeleton_diff [<command>]...  [<other_project_path>]
-2.2  <other_project_path> is required if any of the specified commands
-     require a project to analyze.
-2.3  Commands are parsed from left to right as a list. The final argument
-     is interpreted as <other_project_path> only if:
-     2.3.1  At least one command that requires a project appears earlier in
-            the argument list, and
-     2.3.2  There is at least one argument left after that command.
-2.4  Dominating commands:
-     2.4.1  If any of the following appear anywhere on the command line:
-              usage, help, version
-            then that command is executed and all other arguments are
-            ignored (including other commands and paths).
-     2.4.2  This makes:
-              skeleton_diff usage
-              skeleton_diff usage .
-              skeleton_diff version structure ../subu
-            all behave as simple “usage” or “version” calls.
-2.5  Commands that require <other_project_path>:
-     2.5.1  structure
-     2.5.2  import
-     2.5.3  export
-     2.5.4  suspicious
-     2.5.5  addendum
-     2.5.6  all (which expands to a sequence of project commands)
-2.6  Commands that do not require a project:
-     2.6.1  version
-     2.6.2  help
-     2.6.3  usage
-     2.6.4  environment
-2.7  Missing project argument:
-     2.7.1  If the first command that requires a project is also the last
-            argument, there is no argument left to serve as
-            <other_project_path>, and skeleton_diff reports an error.
-     2.7.2  If a command that requires a project appears before the last
-            argument, the last argument is interpreted as <other>, even if
-            its spelling matches a command name.
-2.8  Effect of “all”:
-     2.8.1  The special command “all” is shorthand for:
-              environment, structure, import, export, suspicious, addendum
-     2.8.2  “all” may not be combined with other commands. If present, it
-            must be the only non-dominating command on the line.
-
-3. Environment Expectations
-3.1  Before running skeleton_diff you are expected to:
-     3.1.1  Be inside a Harmony-derived project.
-     3.1.2  Have already run:
-              source env_toolsmith
-            which in turn sources:
-              tool_shared/bespoke/env
-     3.1.3  Have $REPO_HOME set to your Harmony project root.
-3.2  All paths reported by skeleton_diff are relative to $REPO_HOME unless
-     otherwise stated.
-3.3  The tool does not modify any files. It only reports differences and
-     prints suggested copy commands for you to run (or edit) manually.
-
-4. Key Concepts
-4.1  Harmony root
-     4.1.1  The Harmony skeleton lives at:
-              $REPO_HOME
-     4.1.2  The tool treats $REPO_HOME as the reference layout.
-4.2  <other> project root
-     4.2.1  The <other> project root is the final argument when a project
-            is required, and must be a directory.
-     4.2.2  It is expected to have been created by cloning the Harmony
-            skeleton at some point.
-4.3  “Between” and “below” paths
-     4.3.1  A skeleton directory is any directory that exists in the Harmony
-            tree, rooted at $REPO_HOME.
-     4.3.2  “Between” paths:
-            - Consider any traversal from the project root down to a known
-              Harmony skeleton directory (for example, tool/, developer/,
-              tester/, document/, etc.).
-            - Any extra directories that appear along those routes in
-              <other>, but do not exist in the Harmony skeleton, are
-              “between” paths.
-            - Example: Harmony has tool/CLI/, but <other> has tool/custom/CLI/.
-              The inserted custom/ is a “between” directory.
-            - These often indicate that the developer has modified the
-              skeleton’s core structural spine.
-     4.3.3  “Below” paths:
-            - Directories that are nested under existing skeleton
-              directories (for example, tool/custom/new_script.py under
-              tool/).
-            - These are usually normal and represent project-specific
-              organization and additions.
-     4.3.4  skeleton_diff reports both:
-            - “Between” additions, which are more likely to be structural
-              misuse or deliberate skeleton changes.
-            - “Below” additions, which are more likely to be healthy
-              extensions of the skeleton.
-4.4  User-owned vs shared zones
-     4.4.1  Some areas are explicitly owned by a role and are not audited as
-            suspicious:
-            - $REPO_HOME/developer
-            - $REPO_HOME/tester
-            - $REPO_HOME/release
-     4.4.2  Tools are expected under:
-            - $REPO_HOME/tool
-            - $REPO_HOME/tool_shared
-     4.4.3  Directories that are covered by a .gitignore are treated as
-            intentionally messy and are not reported as suspicious clutter.
-
-5. Commands
-5.1  version, help, usage  (dominating, no project required)
-     5.1.1  version
-            - Prints:
-                skeleton_diff version <Major>.<Minor>
-            - Major and Minor are integers, not a decimal number.
-     5.1.2  help
-            - Shows this detailed documentation.
-     5.1.3  usage
-            - Shows a short, to-the-point command summary and examples.
-     5.1.4  If any of these appear, skeleton_diff executes that command and
-            ignores all other arguments.
-
-5.2  environment  (no project required)
-     5.2.1  Prints the key environment context that skeleton_diff relies on:
-            - $REPO_HOME
-            - Other Harmony-related variables (e.g., HARMONY_* and REPO_*)
-            - PATH and selected tool-related variables.
-     5.2.2  Useful for debugging configuration or confirming that
-            env_toolsmith has been sourced correctly.
-
-5.3  structure  (requires <other>)
-     5.3.1  Goal: discover structural drift in directories between Harmony
-            and <other>.
-     5.3.2  Step 1: missing Harmony directories in <other>
-            - Walk the Harmony skeleton to find all directories under
-              $REPO_HOME.
-            - For each Harmony directory, skeleton_diff checks whether the
-              corresponding directory exists at the same relative path in
-              <other>.
-            - Any directory that is present in Harmony but missing in <other>
-              is reported as:
-                [MISSING] <relative/path>
-     5.3.3  Step 2: new directories in <other> that are not in Harmony
-            - Walk all directories in <other>.
-            - Any directory that does not appear in Harmony at the same
-              relative path is considered “new”.
-            - New directories are classified as “between” or “below”
-              according to the rules in section 4.3 and reported so you can
-              see both structural misuse and legitimate extensions.
-
-5.4  import / export  (both require <other>)
-     5.4.1  Internal files step:
-            - Both import and export depend on a traversal of skeleton and
-              project files to classify them as missing/newer/older.
-            - The traversal is performed automatically as needed; there is no
-              user-visible “files” command.
-     5.4.2  import
-            - Goal: help you pull improvements *from* <other> *into* Harmony.
-            - Uses the list of files where <other> is newer than Harmony to
-              generate shell commands of the form:
-                cp <other>/<relative/path>  $REPO_HOME/<relative/path>
-            - Commands overwrite the older skeleton file. The old version is
-              preserved by git history.
-     5.4.3  export
-            - Goal: help you push newer skeleton files *from* Harmony *into*
-              <other>.
-            - Uses the list of files where <other> is older than Harmony to
-              generate shell commands of the form:
-                cp $REPO_HOME/<relative/path>  <other>/<relative/path>
-            - Commands overwrite stale files in <other>.
-     5.4.4  Both commands only print shell commands; they never execute them.
-
-5.5  suspicious  (requires <other>)
-     5.5.1  Goal: find “clutter” files that look out of place relative to the
-            Harmony skeleton.
-     5.5.2  A file is not considered suspicious if it is:
-            - Under $REPO_HOME/developer, which is owned by the developer.
-            - Under $REPO_HOME/tester, which is owned by the tester.
-            - Under $REPO_HOME/release, which is deliberately customized by
-              the developer.
-            - Under $REPO_HOME/tool or $REPO_HOME/tool_shared, where tools
-              are expected to live (including substructures).
-            - In a directory that carries a .gitignore file, which signals
-              that local clutter is intended and version-control rules exist.
-            - Present in the Harmony skeleton itself at the same relative
-              path (i.e., an expected file).
-     5.5.3  Any other file that appears in <other> but has no corresponding
-            skeleton file and is not in the roles’ owned zones or .gitignored
-            directories is reported as:
-              [SUSPICIOUS] <relative/path>
-     5.5.4  These “between” files are candidates to:
-            - Move under proper tool directories.
-            - Add to the skeleton.
-            - Remove from the project.
-
-5.6  addendum  (requires <other>)
-     5.6.1  Goal: find project-specific tools that might be candidates to
-            promote back into the Harmony skeleton.
-     5.6.2  For each tool directory in <other>:
-            - tool/
-            - tool_shared/
-            skeleton_diff walks all files under those directories and
-            compares them to the Harmony tool directories at the same
-            relative paths.
-     5.6.3  Any file that exists in <other>’s tool or tool_shared directory
-            but not in the Harmony skeleton is reported as:
-              [ADDENDUM] <relative/path>
-     5.6.4  These represent project-local tooling; you decide whether to:
-            - Keep them project-specific, or
-            - Move them into the shared skeleton.
-
-5.7  all  (requires <other>)
-     5.7.1  all is shorthand for running:
-              environment
-              structure
-              import
-              export
-              suspicious
-              addendum
-     5.7.2  It may not be combined with other commands. If you need a
-            different sequence, list the commands explicitly.
-
-6. Example Workflows
-6.1  Inspect a specific project’s drift
-     6.1.1  From a Harmony project:
-              source env_toolsmith
-              skeleton_diff all ../subu
-     6.1.2  Read:
-            - environment: sanity-check $REPO_HOME and related variables.
-            - structure: to see missing or extra directories.
-            - import/export: to copy improvements across.
-            - suspicious/addendum: to see clutter and candidate tools.
-6.2  Import improvements from a project
-     6.2.1  Run:
-              skeleton_diff import ../subu
-     6.2.2  Review the printed cp commands, then run them selectively.
-6.3  Refresh a stale project from the skeleton
-     6.3.1  Run:
-              skeleton_diff export ../some_project
-     6.3.2  Review cp commands, run them, and then commit in <other>.
-6.4  Quick environment and doc checks
-     6.4.1  Without a project:
-              skeleton_diff usage
-              skeleton_diff help
-              skeleton_diff version
-              skeleton_diff environment
-
-7. Safety and Limitations
-7.1  No automatic writes
-     7.1.1  skeleton_diff never changes files itself. It only prints commands
-            and reports.
-7.2  Time-based comparison
-     7.2.1  “Newer” and “older” are based on filesystem modification times.
-            If clocks or timestamps are misleading, results may need manual
-            interpretation.
-7.3  Directory semantics
-     7.3.1  “Between” and “below” classification is a heuristic based on
-            the current Harmony skeleton. Some edge cases may require human
-            judgment.
-7.4  Git integration
-     7.4.1  The tool assumes that Harmony is a git repository and relies on
-            git history for old versions. It does not attempt to archive or
-            back up overwritten files.
-7.5  Exit Status
-     7.5.1  skeleton_diff returns:
-            - 0 on success (even if differences are found).
-            - Non-zero if arguments are invalid (e.g., missing project path)
-              or if a subcommand fails before producing output.
-"""
-  print(help_text.strip())
-  return 0
diff --git a/tool/deprecated/skeleton_paths.py b/tool/deprecated/skeleton_paths.py
deleted file mode 100644 (file)
index 521d728..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/env python3
-"""
-skeleton_paths — filesystem indexing and ignore logic for skeleton_diff
-"""
-
-import os
-from dataclasses import dataclass
-from pathlib import Path
-from typing import Dict, Set, List
-
-
-# ----------------------------------------------------------------------
-# Node information
-# ----------------------------------------------------------------------
-
-@dataclass
-class NodeInfo:
-  path_type: str        # "file", "dir", or "other"
-  mtime: float
-  is_leaf_flag: bool = False
-
-
-# ----------------------------------------------------------------------
-# Built-in ignore rules and helper
-# ----------------------------------------------------------------------
-
-def _is_builtin_ignored(rel_path: Path) -> bool:
-  """
-  Cheap ignore filter for common junk:
-    - .git tree
-    - __pycache__ and Python bytecode
-    - notebook / pytest caches
-    - editor backup files (*~, *.bak)
-  """
-  parts = rel_path.parts
-
-  # Ignore anything under a .git directory
-  if ".git" in parts:
-    return True
-
-  name = parts[-1] if parts else ""
-
-  # Directories by name
-  if name in {
-    "__pycache__",
-    ".ipynb_checkpoints",
-    ".pytest_cache",
-  }:
-    return True
-
-  # Python bytecode / compiled
-  lower_name = name.lower()
-  if lower_name.endswith(".pyc") or lower_name.endswith(".pyo") or lower_name.endswith(".pyd"):
-    return True
-
-  # Editor backup / temp
-  if lower_name.endswith("~") or lower_name.endswith(".bak"):
-    return True
-
-  return False
-
-
-def should_ignore_node(project_root: Path, rel_path: Path) -> bool:
-  """
-  Single "ignore this?" decision point.
-
-  For now we:
-    - apply built-in patterns, and
-    - treat any directory that has a .gitignore file as fully ignored
-      (except for the .gitignore file itself).
-
-  TODO:
-    - Parse .gitignore files properly and obey their patterns.
-  """
-  if not rel_path.parts:
-    # Root is never ignored.
-    return False
-
-  # Built-in patterns
-  if _is_builtin_ignored(rel_path):
-    return True
-
-  absolute_path = project_root / rel_path
-  parent_dir = absolute_path.parent
-
-  # If parent directory has a .gitignore, ignore this node.
-  # (We do not ignore the .gitignore file itself.)
-  if (parent_dir / ".gitignore").exists() and absolute_path.name != ".gitignore":
-    return True
-
-  return False
-
-
-# ----------------------------------------------------------------------
-# Indexing
-# ----------------------------------------------------------------------
-
-def _make_node_info(path: Path) -> NodeInfo:
-  if path.is_file():
-    path_type = "file"
-  elif path.is_dir():
-    path_type = "dir"
-  else:
-    path_type = "other"
-
-  try:
-    mtime = path.stat().st_mtime
-  except OSError:
-    mtime = 0.0
-
-  return NodeInfo(
-    path_type=path_type,
-    mtime=mtime,
-    is_leaf_flag=False,
-  )
-
-
-def index_project(project_root: Path) -> Dict[Path, NodeInfo]:
-  """
-  Walk an entire project tree and build a dictionary mapping
-  relative paths -> NodeInfo, applying the ignore filter.
-
-  The relative path Path(".") is used for the project root.
-  """
-  project_root = project_root.resolve()
-  node_dict: Dict[Path, NodeInfo] = {}
-
-  # Always register the root
-  root_rel_path = Path(".")
-  node_dict[root_rel_path] = _make_node_info(project_root)
-
-  for dirpath_str, dirnames_list, filenames_list in os.walk(project_root):
-    dirpath = Path(dirpath_str)
-    rel_dir = dirpath.relative_to(project_root)
-
-    # Filter directory traversal in-place so os.walk will skip ignored dirs.
-    keep_dirnames_list: List[str] = []
-    for dirname in dirnames_list:
-      child_rel = (rel_dir / dirname) if rel_dir != Path(".") else Path(dirname)
-      if should_ignore_node(project_root, child_rel):
-        continue
-      keep_dirnames_list.append(dirname)
-    dirnames_list[:] = keep_dirnames_list
-
-    # Ensure directory node itself is recorded
-    if rel_dir not in node_dict:
-      node_dict[rel_dir] = _make_node_info(dirpath)
-
-    # Record files
-    for filename in filenames_list:
-      rel_file = (rel_dir / filename) if rel_dir != Path(".") else Path(filename)
-      if should_ignore_node(project_root, rel_file):
-        continue
-      abs_file = dirpath / filename
-      node_dict[rel_file] = _make_node_info(abs_file)
-
-  # Second pass: mark leaf directories
-  parent_dir_set: Set[Path] = set()
-  for rel_path in node_dict.keys():
-    if rel_path == Path("."):
-      continue
-    parent = rel_path.parent
-    parent_dir_set.add(parent)
-
-  for rel_path, info in node_dict.items():
-    if info.path_type == "dir":
-      if rel_path not in parent_dir_set:
-        info.is_leaf_flag = True
-
-  return node_dict
diff --git a/tool/skel.tgz b/tool/skel.tgz
deleted file mode 100644 (file)
index 7e2bf1a..0000000
Binary files a/tool/skel.tgz and /dev/null differ