**/scratchpad/*
!**/scratchpad/.gitignore
-# so that .gitignore is not required in consumer/release
-/consumer/made
# Python
__pycache__/
-# RT-style
+# RT-Style
-A JavaScript based layout, themes, and semantic elements for HTML documents. Used for documents on RT projects.
+RT-Style is a client-side, JavaScript-driven publishing framework designed for Reasoning Technology projects. It transforms raw HTML into high-readability technical documentation.
-## To build the library
+Instead of wrestling with complex CSS classes or static site generators, authors write structural HTML using custom semantic tags. The RT-Style engine intercepts the DOM at load time to handle complex layout tasks, dynamic pagination, and theme injection.
-This project is based on RT's **Harmony** project skeleton. Hence there are role directories. After cloning the repo, go to the top of the project and type:
+## Capabilities
-```bash
-. setup developer
-make
-release write
-```
-
-The resulting JavaScript library will be located in `consumer/release/RT`.
-
-## To use the library
-
-Using the library requires creating two files, and then including one of them in the document.
-
-One file is a js dictionary that maps names to style directory paths. The other does some setup and loads the dictionary.
-
-### 1. The Style Dictionary
-
-First, create a `style_directory_dict.js` file at a central location in the project. We will refer to this location as `<path_0>`. This dictionary tells the inclusion engine where the named style directories are located. Suppose that a style directory is located at `<path_1>`, the dictionary will appear as:
-
-```javascript
-window.StyleRT_namespaces = {
- "RT": window.RT_REPO_ROOT + "<path_1>/consumer/release/RT"
-};
-```
-
-In the Harmony skeleton, there is a good example of a style dictionary located at `shared/style_directory_dict.js`. The style dictionary in this project is probably not a good example, because, for practical reasons, it points back into the developer's code.
-
-### 2. The Document Setup Script
-
-Next, create a `setup.js` script in the same directory with the HTML document. In our projects, this is typically a general document directory that can have many documents. This `setup.js` script sets the relative path back to the project root, loads the `style_directory_dict.js` file, and pulls in the core js code needed for all documents.
-
-Here is an example `setup.js`. Find other examples in the document directories in this project and other RT projects, such as the Harmony project.
-
-```javascript
-window.RT_REPO_ROOT = "<relative_path_to_root>";
-document.write('<script src="' + window.RT_REPO_ROOT + '<path_0>/style_directory_dict.js"></script>');
-document.write('<script src="' + window.RT_REPO_ROOT + '<path_1>/consumer/release/RT/core/loader.js"></script>');
-document.write('<script src="' + window.RT_REPO_ROOT + '<path_1>/consumer/release/RT/core/body_visibility_hidden.js"></script>');
-```
+By linking a document to the RT-Style engine, authors can accomplish the following natively in the browser:
-### 3. The HTML Document
+* **Semantic Abstraction:** Separate structure from presentation using tags like `<RT-article>`, `<RT-title>`, and `<RT-constraint>`.
+* **Dynamic Typography:** Automatically format mathematical equations (`<RT-math>`), code blocks (`<RT-code>`), and technical symbols without manual styling.
+* **Smart Terminology:** Use `<RT-term>` and `<RT-neologism>` to automatically emphasize and anchor the first occurrence of technical jargon for future indexing.
+* **Automated Navigation:** Generate document-aware Tables of Contents (`<RT-TOC>`) that scan heading depths dynamically.
+* **Intelligent Pagination:** Break long documents into readable, soft-limited pages that respect paragraph and heading boundaries.
+* **Hot-Swappable Themes:** Toggle between dark and light modes seamlessly.
-Typically the `style_directory_dict.js` and `setup.js` files are created by an administrator in advance. The same person who creates the `document` directory that the documents live in.
+## Initial Setup (Reading the Manuals)
-With the bootstrap script in place alongside the HTML file, the document authoring using the style library requires only that `setup.js` is included, as shown in the example code below.
+This repository is built on the **Harmony** project skeleton. Because the layout engine is an artifact that must be built, a freshly cloned repository will display raw, unstyled HTML if you attempt to read the manuals immediately.
-```html
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Example Document</title>
-
- <script src="setup.js"></script>
+To view the project documentation locally, you must first compile and stage the semantic engine. Navigate to the root of the project and execute:
- <script>
- window.StyleRT.include('RT/theme');
- window.StyleRT.include('RT/layout/article_tech_ref');
- </script>
- </head>
- <body>
- <RT-article>
- <RT-title
- title="Example Document"
- author="Thomas Walker Lynch"
- date="2026-03-06">
- </RT-title>
-
- <RT-TOC level="1"></RT-TOC>
-
- <h1>Introduction</h1>
- <p>
- This is a demonstration of the <RT-term>RT-style</RT-term> engine in action.
- </p>
- </RT-article>
- </body>
-</html>
-```
-
-### Using Harmony Conventions
-
-If the project utilizes the **Harmony** skeleton, these paths map directly to standard locations:
-
-* `<path_0>` is `shared/`.
-* `<path_1>` is `shared/third_party/RT-style`.
-* The `setup.js` script is placed in the role-specific document folder (e.g., `administrator/document/setup.js`).
-* `<relative_path_to_root>` is `../../` (stepping up out of `document/` and `administrator/` back to the root).
-
-Hence, when starting with the Harmony skeleton the `style_directory_dict.js` file will already exist in the `shared` directory, and existing `document` directories will already have a `setup.js` file.
-
-## Semantic Elements
-
-The engine targets custom HTML tags to apply formatting and behavior.
-
-* `<RT-article>` : The primary container for standard documentation.
-* `<RT-title>` : Generates a standardized document header. Accepts `title`, `author`, and `date` attributes.
-* `<RT-TOC>` : Automatically generates a Table of Contents. Uses the `level` attribute to target specific heading depths.
-* `<RT-term>` / `<RT-neologism>` : Italicizes the first occurrence of a specific term and generates an anchor ID for indexing.
-* `<RT-code>` : Code block formatting with auto-dedentation and syntax highlighting hooks.
-* `<RT-math>` : Integration hooks for MathJax rendering.
-
-## Developer information
-
-This project follows the **RT Code Format** convention for all JavaScript source files. See the documents in the `developer/document` directory for more information.
+```bash
+. setup developer
+build Manuscript
+promote write
/*
We have four scenarios
- immediate - used in the RT-style distribution itself (authored, consummer, staged)
- direct - used in the RT-style project itself, but not in the distribution
+ immediate - used in the RT-Style distribution itself (authored, consumer, staged)
+ direct - used in the RT-Style project itself, but not in the distribution
indirect - the version all Harmony projects use
- URL_only - always pulls style through a URL, a webserver must be present
+ URL-only - always pulls style through a URL, a webserver must be present
*/
window.RT = window.RT || {};
+// --- Configuration ---
+// Define the consumer project name to allow dynamic local file:// calculation.
+window.RT.project_name = "Harmony";
+
+// Fallback URL when served over a network where the project root is not in the URI.
+window.RT.server_url = "http://localhost:8000/shared/linked-project/RT-Style/Manuscript";
+
(function() {
- const project_name = "RT-Style";
- const path = window.location.pathname;
- const project_root_index = path.indexOf('/' + project_name + '/');
-
- if (project_root_index !== -1) {
- // substring(0, x) excludes the trailing slash. We must prepend it to the payload.
- const absolute_project_root = path.substring(0, project_root_index + project_name.length + 1);
- window.RT.dirpr_library = absolute_project_root + "/consumer/made/Manuscript";
- } else {
- // Fallback for when served via local Python HTTP daemon from the project root
- window.RT.dirpr_library = "../consumer/made/Manuscript";
+ let style_path = window.RT.server_url;
+
+ if (window.RT.project_name) {
+ const path = window.location.pathname;
+ const project_root_index = path.indexOf('/' + window.RT.project_name + '/');
+
+ if (project_root_index !== -1) {
+ // substring(0, stop) extracts up to the project name, leaving off the trailing slash.
+ // We append the explicit forward slash before navigating into the shared boundary.
+ const absolute_project_root = path.substring(0, project_root_index + window.RT.project_name.length + 1);
+
+ // The symlink 'RT-Style' already drops us inside the 'consumer/' directory,
+ // so we proceed directly to 'Manuscript'.
+ style_path = absolute_project_root + "/shared/linked-project/RT-Style/Manuscript";
+ } else {
+ console.warn("RT-Style: Cannot locate project root '/" + window.RT.project_name + "/' in URI. Falling back to server_url.");
+ }
}
+ window.RT.dirpr_library = style_path;
+
+ // 1. Inject the loader script
document.write('<script src="' + window.RT.dirpr_library + '/Core/loader.js"><\/script>');
+ // 2. Inject the secondary script block for core dependencies
document.write(
'<script>' +
'window.RT.load("Core/utility");' +
<RT-article>
<RT-title
author="Thomas Walker Lynch"
- date="2026-03-10"
+ date="2026-06-24"
title="How to release a project">
</RT-title>
<h1>Prerequisites</h1>
<p>
- A release requires a tested promotion candidate. The developer compiles the code and promotes it to the <RT-code>consumer/made</RT-code> directory. The tester validates the candidate. The product manager gives the order to release.
+ A developer works in the developer branch of the project, and makes use of the <RT-code>build</RT-code> and <RT-code>promote</RT-code> tools to stage release candidates into the <RT-code>$REPO_HOME/consumer</RT-code> directory. The <RT-code>tester</RT-code> then validates the release candidate. This constitutes a cycle of work, developing, promoting candidates, testing, and then further developing. Once the project manager agrees this cycle is complete, the release flow moves to the next step.
</p>
- <h1>Create the release branch</h1>
+ <h1>Make the release branch</h1>
<p>
The <RT-term>administrator</RT-term> executes the release. Open a terminal. Enter the project workspace.
</p>
Switch to the core development branch. Ensure the local repository is current.
</p>
<RT-code>
- > git checkout core_developer_branch
+ > git checkout core-developer_branch
> git pull
</RT-code>
<p>
- Create a new branch for the release. Use the major version number.
+ Make a new branch for the release. Use the major version number.
</p>
<RT-code>
> git checkout -b release_v<major>
The administrator tags the new commit with the full version number, such as <RT-code>v<major>.<minor></RT-code>. Minor versions are edits on the major release branch. They are visible to a person by running the version command.
</p>
<p>
- The developer must ensure the fix is also ported to the <RT-code>core_developer_branch</RT-code>. This prevents the defect from reappearing in future major releases.
+ The developer must ensure the fix is also ported to the <RT-code>core-developer_branch</RT-code>. This prevents the defect from reappearing in future major releases.
</p>
<h1>Tag and push</h1>
--- /dev/null
+#+TITLE: Python Installation Guide
+#+AUTHOR: Project Administrator
+
+This project requires a dedicated Python environment. The configuration plugin (`shared/linked-project/Python.init`) was written targeting Python 3.12.3, though the architecture does not rely on any known version-dependent features.
+
+* 1. Download and Extract
+Download the Python source code and extract it as a sibling to the main project directory. Assuming you are at the top level of your project workspace:
+
+#+begin_src bash
+cd ../
+wget https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tgz
+tar -xzf Python-3.12.3.tgz
+cd Python-3.12.3
+#+end_src
+
+* 2. Build the Environment
+Compile the Python binaries in place. Setting the installation prefix to the current directory isolates the build, and enabling shared libraries ensures compatibility with C extensions.
+
+#+begin_src bash
+./configure --prefix="$(pwd)" --enable-optimizations --enable-shared
+make -j8
+make install
+#+end_src
+
+* 3. Link the Project
+
+Python-3.12.3 is linked to a Harmony derived project by default.
+
+See installation_generic.org for details about linking a project, if you want to check the setup.
+
+If you are installing a different version, then at least the Python-3.12.3 version project linking is there as a good example.
+
+Project linking is not difficult, make a sym link to `project/<linked-project>`, and then add an init file, that is described in installation_generic.org. The 'project' in the link is literal.
+
+
+
+
+
--- /dev/null
+#+TITLE: Generic Third-Party Installation Guide
+#+AUTHOR: Project Administrator
+
+This project utilizes the Harmony skeleton's `.init` architecture for managing external dependencies. Third-party tools and projects are maintained outside the main repository boundary and linked into the workspace.
+
+* 1. The Neighbor Directory
+Download, clone, or extract the external tool into the same parent directory that contains this project workspace. It must sit as a sibling directory to your current project.
+
+* 2. The Symlink
+Navigate to the `$REPO_HOME/shared/linked-project` directory. You will notice a pre-existing symlink named `project` that points to the parent directory of this project. Use that to create a clean symlink to the external tool.
+
+#+begin_src bash
+cd shared/linked-project
+ln -s project/<external_tool_directory> <link_name>
+#+end_src
+
+* 3. The Initialization File
+Create a configuration file named `<link_name>.init` inside the `$REPO_HOME/shared/linked-project/` directory. This file is automatically sourced when a project participate enters their role environment using `. setup <role>` as part of the project setup. Use this file to update the `PATH` or export necessary environment variables needed for using the linked project.
+
+Review existing `.init` files in the directory for structural examples.
+
+++ /dev/null
-#+TITLE: Installing Python in Harmony
-#+AUTHOR: Thomas Walker Lynch
-#+OPTIONS: toc:2 num:nil
-
-* Overview
-
-This document describes how to install a project-local Python environment under:
-
-#+begin_src bash
-shared/linked-project/Python
-#+end_src
-
-* Precondition
-
-Ensure the following:
-
-- You are in a POSIX shell with =python3= installed.
-- The =python3-venv= package is available (on Debian: =sudo apt install python3-venv=).
-- You have sourced the Harmony environment via =env_toolsmith= to initialize =REPO_HOME= and related variables.
-
-* Step-by-Step Installation
-
-1. Source the Harmony environment:
- #+begin_src bash
- source env_toolsmith
- #+end_src
-
-2. Create the virtual environment:
- #+begin_src bash
- python3 -m venv "$REPO_HOME/shared/linked-project/Python"
- #+end_src
-
-3. Activate it temporarily to install required packages:
- #+begin_src bash
- source "$REPO_HOME/shared/linked-project/Python/bin/activate"
- pip install --upgrade pip
- pip install pytest # Add any shared packages here
- deactivate
- #+end_src
-
-4. Rename Python's default activate and deactivate:
- Harmony provides its own role-aware environment management. Using Python’s default activation scripts may interfere with prompt logic, PATH order, and role-specific behavior.
-
- Disable the default scripts by renaming them:
- #+begin_src bash
- mv "$REPO_HOME/shared/linked-project/Python/bin/activate" \
- "$REPO_HOME/shared/linked-project/Python/bin/activate_deprecated"
- #+end_src
-
- This ensures that accidental sourcing of Python’s =activate= script won't override Harmony's environment setup.
-
-5. Verify installation:
- #+begin_src bash
- ls "$REPO_HOME/shared/linked-project/Python/bin/python3"
- #+end_src
-
- The binary should exist and report a working Python interpreter when run.
-
-* Notes
-
-- The virtual environment is deliberately named =Python=, not =venv=, to reflect its role as a shared system component.
-- Harmony environment scripts define and control =VIRTUAL_ENV=, =PYTHON_HOME=, and =PATH=, making Python activation seamless and uniform.
-- There is no need to use Python’s =bin/activate= directly — it is fully replaced by Harmony’s environment logic.
-
-* Related Files
-
-- =shared/authored/env=
-- =shared/authored/env_source=
-- =env_developer=, =env_tester=, =env_toolsmith=
-
-* Last Verified
-
-2025-05-19 :: Activate/deactivate renamed post-install. Requires Harmony environment sourcing prior to execution.
+++ /dev/null
-
-This is the generic install.org doc that comes with the skeleton.
-
-1. $REPO_HOME/shared/linked-project/.gitignore:
-
- *
- !/.gitignore
- !/patch
-
- The only things from the third party directory that will be pushed to the repo origin is the .gitignore file and the patches.
-
-
-2. downloaded tar files etc. go into the directory `upstream`
-
- $REPO_HOME/shared/upstream
-
- Typically the contents of upstream are deleted after the install.
-
-3. for the base install
-
- cd $REPO_HOME/shared/linked-project
- do whatever it takes to install tool, as examples:
- git clone <tool_path>
- tar -xzf ../upstream/tar
- ...
-
- Be sure to add the path to the tool executable(s) in the $REPO_HOME/env_$ROLE files for the $ROLE who uses the tool.
-
- Assuming you are not also developing the tool, for safety
- change each installed git project to a local branch:
-
- b=<site>_<project>_local_$USER
- git switch -c "$b"
-
-
-4. Define some variables to simplify our discussion. Lowercase variable names
- are not exported from the shell.
-
- # already set in the environment
- # REPO_HOME
- # PROJECT
- # USER
-
- # example tool names: 'RT_gcc' 'RT-project share` etc.
- tool=<tool-name>
- tool_dpath="$REPO_HOME/shared/linked-project/$tool"
- patch_dpath="$REPO_HOME/shared/patch/"
-
-
-5. create a patch series (from current vendor state → your local edits)
-
- # this can be repeated and will create an encompassing diff file
-
- # optionally crate a new branch after cloning the third party tool repo and work from there. You won't make any commits, but in case you plan to ever check the changes in, or have a the bad habit of doing ommits burned into your brain-stem, making a brnch will help.
-
- # make changes
-
- cd "$tool_dpath"
-
- # do your edits
-
- # Stage edits. Do not commit them!! Be sure you are in the third party
- # tool directory when doing `git add -A` and `git diff` commands.
- git add -A
-
- # diff the stage from the current repo to create the patch file
- git diff --staged > "$patch_dpath/$tool"
-
- # the diff file can be added to the project and checked in at the project level.
-
-
-6. how to apply an existing patch
-
- Get a fresh clone of the tool into $tool_dpath.
-
- cd "$tool_dpath"
- git apply "$patch_dpath/$tool"
-
- You can see what `git apply` would do by running
-
- git apply --check /path/to/your/patch_dpath/$tool
--- /dev/null
+#!/usr/bin/env python3
+import sys
+import os
+import stat
+import shutil
+from pathlib import Path
+
+def deploy_RT_Style_indirect_locators(locator_dir_path):
+ locator_dir = Path(locator_dir_path)
+ if not locator_dir.is_dir():
+ print(f"Error: Locator directory not found at {locator_dir_path}")
+ sys.exit(1)
+
+ indirect_js = locator_dir / "indirect.js"
+ if not indirect_js.exists():
+ print("Error: indirect.js missing in the specified directory.")
+ sys.exit(1)
+
+ repo_home = Path(os.environ.get("REPO_HOME", "."))
+ IGNORED_DIRS = {".git"}
+
+ for root, dirs, files in os.walk(repo_home):
+ # Prune ignored directories in place
+ dirs[:] = [d for d in dirs if d not in IGNORED_DIRS]
+
+ current_path = Path(root)
+ if current_path.name.lower() == "document":
+ target_file = current_path / "RT-Style_locator.js"
+
+ # Eliminate permission denial on read-only artifacts
+ if target_file.exists():
+ target_file.chmod(target_file.stat().st_mode | stat.S_IWUSR)
+
+ shutil.copyfile(indirect_js, target_file)
+ print(f"Copied indirect.js -> {target_file}")
+
+if __name__ == "__main__":
+ if len(sys.argv) != 2:
+ print("Usage: python3 deploy_RT_Style_indirect_locators.py <path_to_Locator_directory>")
+ sys.exit(1)
+
+ deploy_RT_Style_indirect_locators(sys.argv[1])
+
+++ /dev/null
-#!/usr/bin/env python3
-import sys
-import os
-import stat
-import shutil
-from pathlib import Path
-
-def deploy_internal_locators(locator_dir_path):
- locator_dir = Path(locator_dir_path)
- if not locator_dir.is_dir():
- print(f"Error: Locator directory not found at {locator_dir_path}")
- sys.exit(1)
-
- immediate_js = locator_dir / "immediate.js"
- direct_js = locator_dir / "direct.js"
-
- if not immediate_js.exists() or not direct_js.exists():
- print("Error: Source locator files missing in the specified directory.")
- sys.exit(1)
-
- repo_home = Path(os.environ.get("REPO_HOME", "."))
- IGNORED_DIRS = {".git", "scratchpad", "consumer"}
-
- for root, dirs, files in os.walk(repo_home):
- # Prune ignored directories in place to prevent descending into them
- dirs[:] = [d for d in dirs if d not in IGNORED_DIRS]
-
- current_path = Path(root)
- if current_path.name.lower() == "document":
- target_file = current_path / "RT-Style_locator.js"
-
- # Evaluate the path to determine the correct structural locator
- if "developer/authored/Manuscript" in current_path.as_posix():
- source_file = immediate_js
- else:
- source_file = direct_js
-
- # Eliminate permission denial on read-only consumer artifacts
- if target_file.exists():
- target_file.chmod(target_file.stat().st_mode | stat.S_IWUSR)
-
- shutil.copyfile(source_file, target_file)
- print(f"Copied {source_file.name} -> {target_file}")
-
-if __name__ == "__main__":
- if len(sys.argv) != 2:
- print("Usage: python3 deploy_internal_locators.py <path_to_Locator_directory>")
- sys.exit(1)
-
- deploy_internal_locators(sys.argv[1])
+++ /dev/null
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# Enforce execution for this administrative tool
-if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
- echo "$script_afp:: This script must be executed, not sourced."
- return 1
-fi
-
-# without this bash takes non-matching globs literally
-shopt -s nullglob
-
-# does not presume sharing or world permissions
-umask 0077
-
-# Ensure required environment variables exist
-if [[ -z "$REPO_HOME" || -z "$PROJECT" ]]; then
- echo "Error: REPO_HOME or PROJECT variables are undefined. Please source the setup administrator first."
- exit 1
-fi
-
-echo "Repository Home: $REPO_HOME"
-echo "Project Name: $PROJECT"
-
-# The scratchpad must exist at the top level of the project for scanning clarity
-scratchpad="$REPO_HOME"/scratchpad
-if [[ ! -d "$scratchpad" ]]; then
- echo "Error: scratchpad directory missing at $scratchpad"
- exit 1
-fi
-
-#--------------------------------------------------------------------------------
-# Python name/version
-#
-
-version=3.12.3
-Python_dn=Python-"$version"
-tarf="$Python_dn".tgz
-
-# Python install directory, sibling to this project
-Python_da="$(realpath "$REPO_HOME"/../)"/"$Python_dn"
-
-#--------------------------------------------------------------------------------
-
-# Verify if the requested Python version is already built
-if [[ -x "$Python_da/bin/python3" ]]; then
- echo "Python $version is already built and installed at $Python_da."
-else
- # Download only if the archive is absent
- wget -nc -P "$scratchpad" https://www.python.org/ftp/python/"$version"/"$tarf"
-
- # Extract into the scratchpad to prevent source and installation collisions
- source_dn="$scratchpad"/Python-src-"$version"
- mkdir -p "$source_dn"
- tar xzf "$scratchpad"/"$tarf" -C "$source_dn" --strip-components=1
-
- # Explicit error reporting prevents silent administrative failures
- cd "$source_dn" || {
- echo "Error: Failed to change directory to $source_dn. Extraction likely failed."
- exit 1
- }
-
- # Configure with developer baseline (--enable-shared) required for C extensions
- LDFLAGS="-Wl,-rpath=$Python_da/lib" ./configure --prefix="$Python_da" --enable-optimizations --enable-shared
-
- make -j8
- make install
-fi
-
-# Establish the versioned executable link
-link_dir="$REPO_HOME"/shared/linked-project
-mkdir -p "$link_dir"
-cd "$link_dir" || {
- echo "Error: Failed to navigate to linked-project directory at $link_dir"
- exit 1
-}
-
-if [[ ! -L "$Python_dn" ]]; then
- # The depth accurately escapes linked-project, shared, and REPO_HOME
- ln -s ../../../"$Python_dn"/ "$Python_dn"
- echo "Successfully created symlink for $Python_dn"
-else
- echo "The symlink for $Python_dn already exists."
-fi
-
-# --------------------------------------------------------------------------------
-# Path & Environment Configuration Plugin
-# --------------------------------------------------------------------------------
-path_sh="$REPO_HOME"/shared/tool/PATH.sh
-touch "$path_sh"
-
-# Define the cluster of variables required by the python plugin environment
-line_env="export VIRTUAL_ENV=\"\$REPO_HOME/shared/linked-project/$Python_dn\""
-line_home="export PYTHON_HOME=\"\$VIRTUAL_ENV\""
-line_unset="unset PYTHONHOME"
-line_path="PATH=\"\$VIRTUAL_ENV/bin:\$PATH\""
-
-# Append the variables sequentially if they are missing from the configuration file
-for line in "$line_env" "$line_home" "$line_unset" "$line_path"; do
- if ! grep -Fq "$line" "$path_sh"; then
- echo "$line" >> "$path_sh"
- echo "Appended plugin configuration line to PATH.sh."
- else
- echo "Configuration line already present in PATH.sh."
- fi
-done
-
#!/usr/bin/env python3
# -*- mode: python; coding: utf-8; python-indent-offset: 2; indent-tabs-mode: nil -*-
+"""
+new-project
+
+This administrative tool instantiates a fresh project workspace modeled after
+the Harmony skeleton architecture.
+
+The script executes the following sequential lifecycle:
+ 1. Validates the execution environment (requires an active role session).
+ 2. Safely extracts a clean copy of all Git-tracked files using an archive stream.
+ 3. Renames the boilerplate 0pus_Harmony anchor file to reflect the new project.
+ 4. Injects an initial version tracking entry into the shared configuration space.
+ 5. Initializes a fresh Git repository bound to the core-developer_branch.
+ 6. Stages and commits the pristine skeleton infrastructure as a baseline.
+ 7. Maps any upstream remote network targets passed via CLI parameters.
+"""
+
import sys ,os ,subprocess
from pathlib import Path
def get_Z_date() -> str:
+ """Retrieves the current date utilizing the system Z timestamp tool."""
try:
res = subprocess.run(["Z" ,"format-%year-%month-%day"] ,capture_output=True ,text=True ,check=True)
return res.stdout.strip()
return "1970-01-01"
def work(project_name: str ,remotes: list[str]) -> int:
+ """Orchestrates the assembly of the new skeleton instance."""
repo_home = os.environ.get("REPO_HOME")
if not repo_home:
print("Error: REPO_HOME is not set. A person must run this from within a sourced role environment." ,file=sys.stderr)
repo_path = Path(repo_home).resolve()
+ # Resolve destination relative to the parent space of the current repository
dest_path = Path(project_name)
if not dest_path.is_absolute():
dest_path = (repo_path.parent / project_name).resolve()
print(f"Error: Destination {dest_path} already exists." ,file=sys.stderr)
return 1
- print(f"Creating new project at: {dest_path}")
+ print(f"Making new project at: {dest_path}")
dest_path.mkdir(parents=True)
+ # Export tracked files without duplicating untracked scratchpads or git histories
archive_cmd = "git archive HEAD | tar -x -C " + str(dest_path)
res = subprocess.run(archive_cmd ,shell=True ,cwd=str(repo_path))
if res.returncode != 0:
print("Error extracting archive." ,file=sys.stderr)
return 1
+ # Personalize the project baseline anchor file
opus_src = dest_path / "0pus_Harmony"
opus_dst = dest_path / f"0pus_{dest_path.name}"
if opus_src.exists():
opus_src.rename(opus_dst)
+ # Record the lineage in the shared version history
version_file = dest_path / "shared" / "tool" / "version"
date_str = get_Z_date()
version_line = f"echo \"{dest_path.name} v0.1 {date_str}\"\n"
with open(version_file ,"w" ,encoding="utf-8") as vf:
vf.write(version_line)
+ # Initialize the pristine Git environment tracking system
print("Initializing git repository...")
subprocess.run(["git" ,"init" ,"-b" ,"core-developer_branch"] ,cwd=str(dest_path) ,check=True)
subprocess.run(["git" ,"add" ,"."] ,cwd=str(dest_path) ,check=True)
subprocess.run(["git" ,"commit" ,"-m" ,f"Initial commit of {dest_path.name} from Harmony skeleton"] ,cwd=str(dest_path) ,check=True)
+ # Configure tracking addresses for upstreams
for idx ,remote_url in enumerate(remotes):
remote_name = f"remote_{idx}"
if "github.com" in remote_url:
print(f"Adding remote '{remote_name}': {remote_url}")
subprocess.run(["git" ,"remote" ,"add" ,remote_name ,remote_url] ,cwd=str(dest_path) ,check=True)
- print(f"Project '{dest_path.name}' successfully created.")
+ print(f"Project '{dest_path.name}' successfully made.")
return 0
def CLI(argv=None) -> int:
+ """Parses user input tokens from the shell execution frame."""
if argv is None:
argv = sys.argv[1:]
--- /dev/null
+#!/usr/bin/env python3
+# -*- mode: python; coding: utf-8; python-indent-offset: 2; indent-tabs-mode: nil -*-
+
+import sys ,os ,filecmp ,stat ,subprocess
+from pathlib import Path
+
+def get_project_name(repo_path: Path) -> str:
+ return repo_path.resolve().name
+
+def get_git_branch(repo_path: Path) -> str:
+ try:
+ result = subprocess.run(
+ ["git" ,"-C" ,str(repo_path) ,"branch" ,"--show-current"],
+ capture_output=True ,text=True ,check=True
+ )
+ branch = result.stdout.strip()
+ return branch if branch else "unknown_branch"
+ except (subprocess.CalledProcessError ,FileNotFoundError):
+ return "unknown_branch"
+
+def format_perms(mode: int) -> str:
+ # Extract the 9-character permission string (e.g., rwxr-xr-x), dropping the leading file type char
+ return stat.filemode(mode)[1:]
+
+def CLI(argv=None) -> int:
+ if argv is None:
+ argv = sys.argv[1:]
+
+ if len(argv) != 2:
+ print("Usage: skeleton_diff <path_to_Harmony> <path_to_project>")
+ return 1
+
+ harmony_dir = Path(argv[0]).resolve()
+ project_dir = Path(argv[1]).resolve()
+
+ if not harmony_dir.is_dir() or not project_dir.is_dir():
+ print("Error: Both arguments must be valid directories." ,file=sys.stderr)
+ return 1
+
+ project_name = get_project_name(project_dir)
+ harmony_branch = get_git_branch(harmony_dir)
+ project_branch = get_git_branch(project_dir)
+
+ # Data structures for the output sections
+ opus_warnings = []
+ missing_files = []
+
+ # Time-based modification buckets
+ mod_harmony_newer = []
+ mod_same_time = []
+ mod_project_newer = []
+
+ perms_only_changes = []
+ added_files = []
+
+ # --- Section 1: Opus File Structural Audit ---
+ project_opus = f"0pus_{project_name}"
+ harmony_opus = "0pus_Harmony"
+ found_opus = False
+
+ for TM_item in os.listdir(project_dir):
+ if TM_item.startswith("0pus_") and os.path.isfile(project_dir / TM_item):
+ if TM_item == project_opus:
+ found_opus = True
+ else:
+ opus_warnings.append(f"Incorrectly named Opus file found: '{TM_item}'. Expected '{project_opus}'.")
+
+ if not found_opus:
+ opus_warnings.append(f"Expected Opus file '{project_opus}' is MISSING from project root.")
+
+ # Semantic boundaries: isolate the skeleton by ignoring user zones
+ IGNORED_DIRS = {".git" ,"scratchpad" ,"consumer" ,"authored" ,"__pycache__"}
+ IGNORED_EXTS = {".pyc" ,".pyo" ,".swp" ,".bak"}
+
+ def is_ignored(path_obj: Path) -> bool:
+ if path_obj.name in IGNORED_DIRS: return True
+ if path_obj.suffix in IGNORED_EXTS: return True
+ if path_obj.name.endswith("~"): return True
+ return False
+
+ harmony_files = set()
+ for TM_root ,TM_dirs ,TM_files in os.walk(harmony_dir):
+ TM_dirs[:] = [TM_d for TM_d in TM_dirs if not is_ignored(Path(TM_d))]
+ for TM_f in TM_files:
+ f_path = Path(TM_root) / TM_f
+ if not is_ignored(f_path):
+ rel_path = f_path.relative_to(harmony_dir)
+ harmony_files.add(str(rel_path))
+
+ project_files = set()
+ for TM_root ,TM_dirs ,TM_files in os.walk(project_dir):
+ TM_dirs[:] = [TM_d for TM_d in TM_dirs if not is_ignored(Path(TM_d))]
+ for TM_f in TM_files:
+ f_path = Path(TM_root) / TM_f
+ if not is_ignored(f_path):
+ rel_path = f_path.relative_to(project_dir)
+ project_files.add(str(rel_path))
+
+ # Align the Opus file names for comparison
+ if project_opus in project_files:
+ project_files.remove(project_opus)
+ project_files.add(harmony_opus)
+ else:
+ for TM_item in list(project_files):
+ if TM_item.startswith("0pus_") and "/" not in TM_item:
+ project_files.remove(TM_item)
+
+ all_files = sorted(list(harmony_files | project_files))
+
+ for TM_rel in all_files:
+ if TM_rel not in project_files:
+ if TM_rel == harmony_opus and not found_opus:
+ continue
+ missing_files.append(TM_rel)
+ elif TM_rel not in harmony_files:
+ added_files.append(TM_rel)
+ else:
+ h_abs = harmony_dir / TM_rel
+ p_abs = project_dir / TM_rel
+
+ if TM_rel == harmony_opus:
+ p_abs = project_dir / project_opus
+
+ if p_abs.exists():
+ h_stat = h_abs.stat()
+ p_stat = p_abs.stat()
+
+ h_perms = format_perms(h_stat.st_mode)
+ p_perms = format_perms(p_stat.st_mode)
+ perms_differ = (h_perms != p_perms)
+
+ display_str = f"({h_perms}, {p_perms}) {TM_rel}" if perms_differ else TM_rel
+ content_differs = not filecmp.cmp(h_abs ,p_abs ,shallow=False)
+
+ if content_differs:
+ h_time = h_stat.st_mtime
+ p_time = p_stat.st_mtime
+
+ if h_time > p_time:
+ mod_harmony_newer.append(display_str)
+ elif h_time < p_time:
+ mod_project_newer.append(display_str)
+ else:
+ mod_same_time.append(display_str)
+ elif perms_differ:
+ perms_only_changes.append(display_str)
+
+ # --- Output Generation ---
+ print("Skeleton Audit:")
+ print(f" Harmony {harmony_branch}")
+ print(" vs")
+ print(f" {project_name} {project_branch}")
+ print("=" * 60)
+
+ print("\n1. 0pus File Audit")
+ print("-" * 20)
+ if not opus_warnings:
+ print(" [OK] Opus file is correctly named and present.")
+ else:
+ for TM_w in opus_warnings:
+ print(f" [WARNING] {TM_w}")
+
+ print("\n2. Missing from Project (In Harmony, missing locally)")
+ print("-" * 20)
+ if not missing_files:
+ print(" [OK] No Harmony skeleton files are missing.")
+ else:
+ for TM_f in missing_files:
+ print(f" - {TM_f}")
+
+ print("\n3. Modified Skeleton Files (Diverged from Harmony)")
+ print("-" * 20)
+ if not (mod_harmony_newer or mod_same_time or mod_project_newer):
+ print(" [OK] No shared skeleton files have been modified.")
+ else:
+ if mod_harmony_newer:
+ print(" [Harmony newer]")
+ for TM_f in mod_harmony_newer:
+ print(f" ~ {TM_f}")
+ if mod_same_time:
+ print(" [Same modification time]")
+ for TM_f in mod_same_time:
+ print(f" ~ {TM_f}")
+ if mod_project_newer:
+ print(" [Project newer]")
+ for TM_f in mod_project_newer:
+ print(f" ~ {TM_f}")
+
+ print("\n4. Permissions Only Changes")
+ print("-" * 20)
+ if not perms_only_changes:
+ print(" [OK] No permission-only changes detected.")
+ else:
+ for TM_f in perms_only_changes:
+ print(f" * {TM_f}")
+
+ print("\n5. Project-Specific Files (Not in Harmony)")
+ print("-" * 20)
+ if not added_files:
+ print(" [INFO] No additional files outside the standard skeleton.")
+ else:
+ for TM_f in added_files:
+ print(f" + {TM_f}")
+
+ print("\n" + "=" * 60)
+ drift_count = len(opus_warnings) + len(missing_files) + len(mod_harmony_newer) + len(mod_same_time) + len(mod_project_newer) + len(perms_only_changes)
+ if drift_count == 0:
+ print("Result: Skeleton is perfectly synchronized with Harmony.")
+ else:
+ print(f"Total Structural Drift (Sections 1-4): {drift_count} issues.")
+
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(CLI())
+
/*
We have four scenarios
- immediate - used in the RT-Style distribution itself (authored, consummer, staged)
+ immediate - used in the RT-Style distribution itself (authored, consumer, staged)
direct - used in the RT-Style project itself, but not in the distribution
indirect - the version all Harmony projects use
- URL_only - always pulls style through a URL, a webserver must be present
+ URL-only - always pulls style through a URL, a webserver must be present
*/
window.RT.project_name = "Harmony";
// Fallback URL when served over a network where the project root is not in the URI.
-window.RT.server_url = "http://localhost:8000/shared/linked-project/RT-Style/made/Manuscript";
+window.RT.server_url = "http://localhost:8000/shared/linked-project/RT-Style/Manuscript";
(function() {
let style_path = window.RT.server_url;
const absolute_project_root = path.substring(0, project_root_index + window.RT.project_name.length + 1);
// The symlink 'RT-Style' already drops us inside the 'consumer/' directory,
- // so we proceed directly to 'made/Manuscript'.
- style_path = absolute_project_root + "/shared/linked-project/RT-Style/made/Manuscript";
+ // so we proceed directly to 'Manuscript'.
+ style_path = absolute_project_root + "/shared/linked-project/RT-Style/Manuscript";
} else {
console.warn("RT-Style: Cannot locate project root '/" + window.RT.project_name + "/' in URI. Falling back to server_url.");
}
<RT-article>
<RT-title
author="Thomas Walker Lynch"
- date="2026-03-09"
+ date="2026-06-23"
title="Introduction to Harmony">
</RT-title>
<ul>
<li>Sources the project-wide setup (<RT-code>shared/tool/setup</RT-code>) to establish the core environment variables (e.g., <RT-code>REPO_HOME</RT-code> and <RT-code>PROJECT</RT-code>).</li>
<li>Conditionally sources <RT-code>shared/authored/setup</RT-code> (if present) to apply administrator-injected, project-specific tool configurations.</li>
+ <li>Dynamically sources all <RT-code>.init</RT-code> files found in the <RT-code>shared/linked-project/</RT-code> directory.</li>
<li>Configures the <RT-code>PATH</RT-code> to include shared tools, library environments, and the specific <RT-code><role>/tool</RT-code> directory.</li>
<li>Changes the working directory into the specified role's workspace.</li>
<li>Sources the <RT-code><role>/tool/setup</RT-code> script. While the earlier steps apply the standard Harmony skeleton setup, this final step applies the role setup that is customized for this specific project.</li>
<h1>After git clone</h1>
<p>
- Because git does not track certain directories (such as <RT-code>shared/linked-project/</RT-code> and <RT-code>consumer/made/</RT-code>), a freshly cloned repository lacks external dependencies and consumable products. Team members must perform a few steps to populate these areas.
+ Because git does not track certain artifact directories (such as <RT-code>consumer/</RT-code> outputs), a freshly cloned repository lacks external dependencies and consumable products. Team members must perform a few steps to populate these areas.
</p>
<h2>Third-party tools</h2>
<p>
- Harmony is language agnostic. When a project makes use of project-specific C, Python, NodeJS, Java, or other tools, the project administrator configures the project to expect these tools in the <RT-code>shared/linked-project</RT-code> directory.
+ Harmony is language agnostic. When a project makes use of project-specific C, Python, NodeJS, Java, or other tools, the project administrator configures the project to expect these tools in the <RT-code>shared/linked-project</RT-code> directory via the `.init` plugin system.
</p>
<p>
- Because multiple team members will have to repeat the third-party install process after cloning a project, the administrator should carefully document the third party tools installation steps and place the resulting documents in the <RT-code>shared/document</RT-code> directory. (The most common installation method is to clone the third party tool next to the project, then to symbolic link it under <RT-code>shared/linked-project/</RT-code>.)
- </p>
- <p>
- If a person clones the project and does not set up third-party tools, commands will fall through the search path and perhaps find system-installed tools. Using system default tools is generally undesirable because each person who clones the project might be running different versions. This variation makes it harder for team members to coordinate and for consumers of the project work product to build functioning tools.
+ Because multiple team members will have to repeat the third-party install process after cloning a project, the administrator should carefully document the installation steps and place the resulting documents in the <RT-code>administrator/document</RT-code> directory. The standard installation method is to clone the external tool into the parent directory alongside the project, create a symlink to it under <RT-code>shared/linked-project/</RT-code> using the <RT-code>project/</RT-code> parent link, and supply an <RT-code>.init</RT-code> script to manage the local environment variables.
</p>
<h2>Consumer build</h2>
In this section we use the term 'consumer' to mean any team member that wants to make use of the project work product. The tester will want to test it, and the consumer role will want to deploy it, etc.
</p>
<p>
- An earlier version of Harmony used platform-specific <RT-code>made</RT-code> directories, but this left binaries in the repository and added excessive complexity.
- So as to avoid that mess, the current version of Harmony requires a work product consumer to run a local build after cloning the project. The results of the build will appear in the <RT-code>consumer/made</RT-code> directory.
+ Because compiled binaries and final layouts are not tracked in the repository, the current version of Harmony requires a work product consumer to run a local build after cloning the project. The results of the build will appear directly in the <RT-code>consumer/</RT-code> directory.
</p>
<p>
- To facilitate this, the developer must explicitly document the project's build and promote procedure, saving this guide as <RT-code>developer/document/build.html</RT-code>.
- </p>
- <p>
- The consumer must then read this document and execute the described steps to compile the source and locally populate their <RT-code>consumer/made</RT-code> directory.
+ To facilitate this, the developer must explicitly document the project's build and promote procedure, saving this guide as <RT-code>developer/document/build.html</RT-code>. The consumer must then read this document and execute the described steps to locally populate their <RT-code>consumer/</RT-code> directory.
</p>
<p>
<li><RT-code>> bash</RT-code></li>
<li><RT-code>> cd <project></RT-code></li>
<li><RT-code>> . setup developer</RT-code></li>
- <li><RT-code>> make CLI</RT-code></li>
+ <li><RT-code>> build <namespace></RT-code></li>
<li><RT-code>> promote write</RT-code></li>
<li><RT-code>> exit</RT-code></li>
<li><RT-code>> bash</RT-code></li>
</ol>
<p>
- This sequence opens a bash shell, assumes the developer role to orchestrate the build, makes the work product, then promotes it to the consumer's workspace. The <RT-code>exit</RT-code> command drops the developer role. The last two lines put the person into the <role> workspace, typically for testing or deploying. Commonly, deployment is a matter of adding the <RT-code>consumer/made</RT-code> directory into the executable search path.
+ This sequence opens a bash shell, assumes the developer role to orchestrate the build, makes the work product, then promotes it to the consumer's workspace. The <RT-code>exit</RT-code> command drops the developer role. The last two lines put the person into the <role> workspace, typically for testing or deploying.
</p>
Files found in a directory named <RT-code>authored</RT-code> were written by project team members. They did not come with the Harmony skeleton, nor with the installation of other software. Project build tools treat <RT-code>authored</RT-code> directories as strictly read-only. Typically these files constitute the intellectual property of a project.
</p>
<p>
- All source code that gets built into a promotion or project release must be placed in the developers' <RT-code>authored</RT-code> directory. The story is not as clean for build tools and other files. New documents go into document directories, and new tools go into the tool directories, etc. As a specific example, the developer will almost certainly edit the <RT-code>developer/tool/make</RT-code> file.
+ All source code that gets built into a promotion or project release must be placed in the developers' <RT-code>authored</RT-code> directory. The story is not as clean for build tools and other files. New documents go into document directories, and new tools go into the tool directories, etc. As a specific example, the developer will almost certainly edit the <RT-code>developer/tool/build</RT-code> file.
</p>
<p>
When the Harmony version line in the <RT-code>shared/tool/version</RT-code> file is left in place, it is straightforward for a project administrator to determine which Harmony skeleton files have been edited in a project, and which new files have been added.
<li><RT-code>administrator/</RT-code> : Project-local tools and skeleton maintenance.</li>
<li><RT-code>developer/</RT-code> : Primary workspace for developers.</li>
<li><RT-code>tester/</RT-code> : Regression and validation workspace for testers.</li>
- <li><RT-code>consumer/</RT-code> : Consumption workspace holding the <RT-code>consumer/made</RT-code> directory.</li>
+ <li><RT-code>consumer/</RT-code> : Consumption workspace acting as the final artifact sink.</li>
<li><RT-code>shared/</RT-code> : Shared ecosystem tools and global environments.</li>
</ul>
<li><RT-code>authored/</RT-code> : Human-written source. Tracked by Git.</li>
<li><RT-code>made/</RT-code> : Tracked artifacts generated by tools (e.g., links to CLI entry points).</li>
<li><RT-code>experiment/</RT-code> : Try-it-here code. Short-lived spot testing.</li>
- <li><RT-code>scratchpad/</RT-code> : Git-ignored directory. Holds all intermediate build outputs, including the <RT-code>made</RT-code> directory for promotions.</li>
- <li><RT-code>tool/</RT-code> : Developer-specific tools (like the promote and make scripts).</li>
+ <li><RT-code>scratchpad/</RT-code> : Git-ignored directory. Holds all intermediate build outputs, including the staged namespace directories for promotions.</li>
+ <li><RT-code>tool/</RT-code> : Developer-specific tools (like the promote and build scripts).</li>
</ul>
<h2>The tester work area</h2>
<h2>The shared tree</h2>
<p>
- This directory contains ecosystem tools and global environments available to all roles. This includes the shared tool directory, as well as third-party installations (like Python virtual environments or compilers) required by the project. To assist in project specific modifications to the Harmony skeleton, Harmony comes with an empty <RT-code>shared/authored</RT-code> directory that is listed earlier in the executable search path than <RT-code>shared/tool</RT-code>.
+ This directory contains ecosystem tools and global environments available to all roles. This includes the shared tool directory, as well as third-party symlinks and <RT-code>.init</RT-code> scripts required by the project. To assist in project specific modifications to the Harmony skeleton, Harmony comes with an empty <RT-code>shared/authored</RT-code> directory that is listed earlier in the executable search path than <RT-code>shared/tool</RT-code>.
</p>
<h2>The consumer tree</h2>
<p>
- The <RT-code>consumer/made/</RT-code> tree is where developers put work product that is ready to be consumed. The entire <RT-code>consumer/made</RT-code> directory is git-ignored and treated as a transient deployment target.
- </p>
- <p>
- Artifacts arrive in the <RT-code>consumer/made/</RT-code> tree <em>only</em> when the promote script is invoked, which performs a flat-copy from the developer's <RT-code>scratchpad/made</RT-code> directory.
+ The <RT-code>consumer/</RT-code> tree is where developers put work product that is ready to be consumed. The entire directory is git-ignored and treated as a transient deployment target. Artifacts arrive in the <RT-code>consumer/</RT-code> tree <em>only</em> when the promote script is invoked, which performs a flat-copy from the developer's <RT-code>scratchpad/made</RT-code> directory.
</p>
<h2>Document directories</h2>
</p>
<ul>
<li><RT-code>document/</RT-code> : Top-level onboarding, project-wide structure, such as this document.</li>
- <li><RT-code>consumer/made/document/</RT-code> : Documentation for end-users of made code (e.g., man pages, application manuals, library API references).</li>
+ <li><RT-code>consumer/<namespace>/document/</RT-code> : Documentation for end-users of made code (e.g., man pages, application manuals, library API references).</li>
<li><RT-code>administrator/document/</RT-code> : Documentation for maintaining the project skeleton and global tools.</li>
<li><RT-code>developer/document/</RT-code> : Documentation for developers, including coding standards and internal API guides.</li>
<li><RT-code>tester/document/</RT-code> : Documentation for testers detailing test plans and tools.</li>
</ul>
<p>
- Note that the <RT-code>consumer/made</RT-code> directory is untracked by git and maintained by a tool. (Said tool is <RT-code>developer/tool/promote</RT-code>. It is owned and used by the developer as part of the build process.) Documents that are being promoted for eventual release, and appear in the <RT-code>made</RT-code> directory originate from somewhere from the <RT-code>developer/authored</RT-code> directory depending on how the developer has organized his workspace, but probably in <RT-code>developer/authored/document</RT-code>. Perhaps a future version of Harmony will have a tech-writer role, but that is not the case now.
- </p>
-
- <p>
- Currently, our developers write documents directly in HTML using the RT semantic tags. See the <RT-code>RT-style</RT-code> project and the documentation there. A common approach is to copy another document and the <RT-code>setup.js</RT-code> file, then to type over the top of that other document. Only one <RT-code>setup.js</RT-code> file is used per directory. Be sure to edit the relative root path found at the top of <RT-code>setup.js</RT-code>. Plain text, emacs org, and mark down have all been used in prior versions of Harmony.
+ Currently, our developers write documents directly in HTML using the RT semantic tags. See the <RT-code>RT-Style</RT-code> project and the documentation there. A common approach is to copy another document and the <RT-code>setup.js</RT-code> file, then to type over the top of that other document.
</p>
<h2>Untracked directories</h2>
<ol>
- <li><RT-code>consumer/made/</RT-code></li>
- <li><RT-code>shared/linked-project/</RT-code></li>
+ <li><RT-code>consumer/</RT-code> (Excluding the base <RT-code>.gitignore</RT-code>)</li>
+ <li><RT-code>shared/linked-project/</RT-code> (Excluding <RT-code>.init</RT-code> and <RT-code>.gitignore</RT-code> files)</li>
<li><RT-code>**/scratchpad/</RT-code></li>
</ol>
<h1>Developer promotion and project releases</h1>
<p>
- As a first step, a developer creates a <RT-term>promotion candidate</RT-term> inside of the <RT-code>consumer/made/</RT-code> directory. This is typically done by running <RT-code>make</RT-code> to stage the artifacts into <RT-code>scratchpad/made</RT-code>, where they can be experimented on, followed by running <RT-code>promote write</RT-code>. The developer will often modify the versions of one or both of those tools that come with the Harmony skeleton. The promotion candidate remains stable until the next <RT-term>promotion</RT-term>.
+ As a first step, a developer creates a <RT-term>promotion candidate</RT-term> inside of the <RT-code>consumer/</RT-code> directory. This is typically done by running <RT-code>build</RT-code> to stage the artifacts into <RT-code>scratchpad/made</RT-code>, followed by running <RT-code>promote write</RT-code>. The developer will often modify the versions of one or both of those tools that come with the Harmony skeleton. The promotion candidate remains stable until the next <RT-term>promotion</RT-term>.
</p>
<p>
- Then the tester runs tests on the promotion candidate. Tests must only read from the <RT-code>consumer/made/</RT-code> directory, though local copies can be made and edited as experiments. Currently bugs are filed using an external issues tool.
+ Then the tester runs tests on the promotion candidate. Tests must only read from the <RT-code>consumer/</RT-code> directory, though local copies can be made and edited as experiments.
</p>
<p>
It is common for a developer to open a second window on his desktop, and then enter the project as a tester in that second window. The developer can then make a promotion candidate, run the tests, edit source code, and perhaps tests, and then quickly spin through the test-debug-fix-promote cycle repeatedly.
When the product manager determines the work product to be sufficiently reliable and feature rich, the administrator will make a <RT-term>project release</RT-term>. He will do this by creating a branch called <RT-code>release_v<major></RT-code> and tagging it. The major release numbers go up incrementally.
</p>
- <h1>The version 2.2 Harmony directory tree</h1>
+ <h1>The Harmony directory tree</h1>
<RT-code>
- 2026-03-09 01:42:16 Z [Harmony:administrator] Thomas_developer@StanleyPark
+ 2026-06-23 13:41:45 Z [Harmony:administrator] Thomas_developer@StanleyPark
§/home/Thomas/subu_data/developer/project§
> tree Harmony
Harmony
│ ├── archive
│ └── setup
├── consumer
- │ ├── scratchpad
- │ └── tool
- │ └── env
+ │ └── .gitignore
├── developer
│ ├── authored
│ │ └── hello.CLI.c
- </RT-code>
- <RT-code>
│ ├── document
│ │ ├── 02_RT_Code_Format.html
│ │ ├── 03_Naming_and_Directory_Conventions.html
│ ├── scratchpad
│ └── tool
│ ├── do_all
- │ ├── make
+ │ ├── build
│ ├── makefile
│ ├── promote
│ └── setup
│ ├── role-and-workflow_product-development.html
│ └── setup.js
├── LICENSE
- </RT-code>
- <RT-code>
├── README.md
├── scratchpad
- │ ├── Harmony__79f9d52__2026-03-07_085628Z.tar
- │ └── Harmony__e665bb7__2026-03-09_013712Z.tar
├── setup
├── shared
│ ├── authored
│ ├── document
- │ │ ├── installation_generic.org
- │ │ ├── installation_Python.org
+ │ │ ├── install_generic.org
+ │ │ ├── install_Python.org
│ │ └── setup.js
│ ├── made
│ ├── dictionary_style-directory.js
- │ ├── third_party
- │ │ ├── RT-style -> ../../../RT-style/
- │ │ └── upstream
+ │ ├── linked-project
+ │ │ ├── project -> ../../../
+ │ │ ├── Python-3.12.3 -> project/Python-3.12.3
+ │ │ ├── Python.init
+ │ │ ├── RT-Style -> project/RT-Style/consumer
+ │ │ └── RT-Style.init
│ └── tool
│ ├── scratchpad
│ ├── setup
- </RT-code>
- <RT-code>
│ ├── style
│ └── version
└── tester
│ └── data_test-1.py
└── tool
└── setup
-
- 30 directories, 36 files
-
- 2026-03-09 01:42:19 Z [Harmony:administrator] Thomas_developer@StanleyPark
- §/home/Thomas/subu_data/developer/project§
- >
</RT-code>
</RT-article>
+++ /dev/null
-2026-03-26 03:41:44
-
-when making a skeleton from Harmony, set skeleton docs and other files not to be edited to read only
-
+++ /dev/null
-#!/usr/bin/env python3
-# -*- mode: python; coding: utf-8; python-indent-offset: 2; indent-tabs-mode: nil -*-
-
-import os ,sys
-
-def process_file(file_path ,replacements) -> bool:
- try:
- with open(file_path ,"r" ,encoding="utf-8") as f:
- content = f.read()
- except UnicodeDecodeError:
- return False
-
- new_content = content
- for old_str ,new_str in replacements:
- new_content = new_content.replace(old_str ,new_str)
-
- if new_content != content:
- with open(file_path ,"w" ,encoding="utf-8") as f:
- f.write(new_content)
- return True
- return False
-
-def work(root_dir: str) -> list[str]:
- replacements = [
- ("shared/linked-project" ,"shared/linked-project")
- ,("linked-project/" ,"linked-project/")
- ,("how-to_release.html" ,"how-to_release.html")
- ,("naming_file-and-directory.html" ,"naming_file-and-directory.html")
- ,("format_RT-code.html" ,"format_RT-code.html")
- ,("format_RT-code.html" ,"format_RT-code.html")
- ,("format_RT-code-Lisp.html" ,"format_RT-code-Lisp.html")
- ,("single-file_C-module-and-namespace.html" ,"single-file_C-module-and-namespace.html")
- ,("developer/tool/do-all" ,"developer/tool/do-all")
- ,("introduction_Harmony.html" ,"introduction_Harmony.html")
- ,("role-and-workflow_product-development.html" ,"role-and-workflow_product-development.html")
- ,("role-and-workflow_product-development.html" ,"role-and-workflow_product-development.html")
- ,("role-and-workflow_product-maintenance.html" ,"role-and-workflow_product-maintenance.html")
- ,("installation_Python.org" ,"installation_Python.org")
- ,("installation_generic.org" ,"installation_generic.org")
- ,("dictionary_style-directory.js" ,"dictionary_style-directory.js")
- ,("target_kernel-module.mk" ,"target_kernel-module.mk")
- ,("tester/RT-formatter" ,"tester/RT-formatter")
- ,("RT-formatter pipe" ,"RT-formatter pipe")
- ,("RT-formatter pipe" ,"RT-formatter pipe")
- ,("RT-formatter-buffer" ,"RT-formatter-buffer")
- ,("RT-formatter-buffer" ,"RT-formatter-buffer")
- ,("RT-formatter-buffer" ,"RT-formatter-buffer")
- ,("RT-formatter-buffer" ,"RT-formatter-buffer")
- ,("\"RTfmt\"" ,"\"RT-formatter\"")
- ,("\"RTfmt0\"" ,"\"RT-formatter\"")
- ,("\"RT_format\"" ,"\"RT-formatter\"")
- ,("RT-formatter formatting" ,"RT-formatter formatting")
- ,("RT-formatter failed" ,"RT-formatter failed")
- ,("RT-formatter formatting" ,"RT-formatter formatting")
- ,("RT-formatter failed" ,"RT-formatter failed")
- ,("data_test-0.c" ,"data_test-0.c")
- ,("data_test-1.py" ,"data_test-1.py")
- ,("RT-formatter.el" ,"RT-formatter.el")
- ,("RT-formatter.el" ,"RT-formatter.el")
- ,("RT-formatter.el" ,"RT-formatter.el")
- ]
-
- changed_files = []
-
- for dirpath ,dirnames ,filenames in os.walk(root_dir):
- path_parts = dirpath.split(os.sep)
- if ".git" in path_parts or "scratchpad" in path_parts:
- continue
-
- for fn in filenames:
- if fn.endswith(".tar") or fn.endswith(".tar.gz") or fn.endswith(".zip"):
- continue
-
- fp = os.path.join(dirpath ,fn)
- if process_file(fp ,replacements):
- changed_files.append(fp)
-
- return changed_files
-
-def CLI(argv=None) -> int:
- root_dir = "."
- print(f"Scanning '{root_dir}' for outdated internal references...")
- changed = work(root_dir)
-
- if not changed:
- print("No references needed updating.")
- else:
- print(f"Updated internal references in {len(changed)} files:")
- for fp in changed:
- print(f" {fp}")
-
- return 0
-
-if __name__ == "__main__":
- sys.exit(CLI())
+++ /dev/null
-# Ignore all files
-*
-
-# But don't ignore the .gitignore file itself
-!/.gitignore
-
--- /dev/null
+project/Python-3.12.3
\ No newline at end of file
--- /dev/null
+# -*- mode: sh; sh-shell: bash; -*-
+# init files are bash script
+
+# Python.init
+# --------------------------------------------------------------------------------
+# Ensure the local Python build is prioritized in the PATH.
+# The user must establish the Python-3.12.3 symlink for this to activate.
+
+if [[ -d "$REPO_HOME/shared/linked-project/Python-3.12.3/bin" ]]; then
+ PATH="$REPO_HOME/shared/linked-project/Python-3.12.3/bin:$PATH"
+else
+ # Optional: Issue a quiet warning for the administrator role
+ if [[ "$ROLE" == "administrator" ]]; then
+ echo "Notice: Local Python-3.12.3 bin not found. Using system Python."
+ fi
+fi
--- /dev/null
+project/RT-Style/consumer
\ No newline at end of file
--- /dev/null
+# -*- mode: sh; sh-shell: bash; -*-
+# init files are bash script
+
+# RT-Style.init
+# --------------------------------------------------------------------------------
+# Establishes aliases and environment variables for the semantic layout engine.
+# The user must establish the RT-Style -> ../../../RT-Style/consumer symlink.
+
+# If the RT-Style project provides command-line tools (e.g., in a 'tool' directory),
+# they would be prepended here. Otherwise, this serves as documentation.
+export RT_STYLE_HOME="$REPO_HOME/shared/linked-project/RT-Style"
+
+if [[ ! -d "$RT_STYLE_HOME/Manuscript" && "$ROLE" == "administrator" ]]; then
+ echo "Notice: RT-Style layout engine is not linked or built. HTML styling will fail."
+fi
--- /dev/null
+../../../
\ No newline at end of file
}
clean_path
- # Sourcing is wrapped in a conditional guard to prevent failure on initial bootstrapping
- installed_tool_sh="$REPO_HOME/$(script_dp)/PATH.sh"
- if [[ -f "$installed_tool_sh" ]]; then
- source "$installed_tool_sh"
- fi
+ # Plugin Sourcing: Dynamically load all the linked project configurations
+ for init_file in "$REPO_HOME/shared/linked-project/"*.init; do
+ if [[ -f "$init_file" ]]; then
+ source "$init_file"
+ fi
+ done
export PATH