Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ All notable changes to TangleClaw are documented in this file.

### Fixed

- **CLAUDE.md regeneration no longer silently clobbers PR-driven rule edits (closes #240)** — `data/global-rules.md` (renamed from `data/default-global-rules.md` and populated with the full 191-line ruleset) becomes the single canonical source for global rules. `store.globalRules.load/save` read/write the tracked file directly; the legacy `~/.tangleclaw/global-rules.md` is ignored with a one-time warn + auto-backup to `*.pre-240-backup`. New `engines.writeEngineConfig` helper wraps every engine-config write with drift detection — warns loudly when the on-disk file differs from regenerated content, surfacing the silent-clobber failure mode at all four write sites (`createProject`, `syncAllProjects`, `updateProject` engine-switch, `launchSession`). Comparator normalizes CRLF→LF + trims so Windows editors and auto-formatters don't false-positive. Helper returns `{skipped: true, ...}` for engines without config files (openclaw, genesis) so callers don't surface spurious errors. **Going forward:** PR-driven rule changes edit `data/global-rules.md` and commit; UI/API edits land in the same file. The competing-sources-of-truth class of bug is structurally impossible. Reset button in the Global Rules editor is now a no-op pending UI cleanup in #243. Full suite 2463/2464 pass.

- **Recover global rules from #234 + #236 silently clobbered by CLAUDE.md regeneration (#240)** — `lib/engines.js#_generateClaudeMd` regenerates `CLAUDE.md` from the DB-stored global rules on every session launch / engine PATCH / startup sync, overwriting the on-disk file in place. PR-driven raw-file edits to `CLAUDE.md` (e.g. via `git`) are silently discarded the next time TC restarts — the content lives on in `git log` but is functionally absent from the live ruleset. Two PRs this session were affected: **#234** (the versioning bump-level decision table) and **#236** (the stale-plan archive rule + `gh issue view <N> --json state` issue-state check). Both rule blocks were clobbered after the first TC restart following each merge; the celebrated "structural lessons codified in CLAUDE.md" claim in those PR descriptions was technically true in git history and functionally false in the running ruleset. **Recovery procedure run this session:** read the live DB content via `store.globalRules.load()`, splice the two missing rule blocks back into their respective sections (`Build Plans & Chunks` for #236, `Releases & Versioning` for #234) preserving sibling content, write back via `store.globalRules.save(merged)` (which normalizes and persists to `_globalRulesPath()`). Verified end-to-end: the regenerated `CLAUDE.md` is now byte-for-byte identical to HEAD (diff is empty), so the next TC restart produces no surprise drift. **Defensive comment added** to `lib/engines.js#_generateClaudeMd` documenting the regeneration contract and pointing future readers (or automated agents tempted to commit directly to `CLAUDE.md`) at the durable edit paths: landing-page editor, `PUT /api/rules/global` (10 KB body cap), or `store.globalRules.save()` from a node script. The same regeneration pattern applies to Codex / Aider / Gemini config files — same trap, less commonly hit because TC-v3 itself uses Claude. Public diagnostic + recovery procedure for any other cloner who is affected is documented in #240. Structural fix (preventing the trap from ever firing again — likely either a tracked-file canonical source with startup sync, or an append-only marker pattern that regeneration preserves) is tracked in #240 as separate work.

### Changed
Expand Down
11 changes: 0 additions & 11 deletions data/default-global-rules.md

This file was deleted.

190 changes: 190 additions & 0 deletions data/global-rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# Global Rules

These rules apply to all projects managed by TangleClaw, across all engines.
Edit them from the TangleClaw landing page or via the API.

## General

- Follow the project's existing code style and conventions
- Prefer small, focused commits over large monolithic ones
- Keep functions short and single-purpose
- Write clear commit messages that explain why, not just what

## Build Plans & Chunks

Claude Code stores plan files globally at `~/.claude/plans/`. This causes problems _ plans get lost across sessions and can collide between projects.

**Rule: Keep plans local to the project.**
- After creating or updating a plan in Claude Code's plan mode, copy the plan file into the project directory at `<project-root>/.claude/plans/<plan-name>.md`.
- All memory entries and session handoffs must reference the **project-local copy** using its absolute path (e.g.,
`/Users/jasonvaughan/Documents/Projects/MyProject/.claude/plans/my-plan.md`).
- Never reference plans with ambiguous relative paths like `.claude/plans/...` _ always use absolute paths.
- Each project's plans live inside that project. Do not rely on `~/.claude/plans/` as the source of truth across sessions.

**Rule: Archive plans whose chunk has shipped.**

A plan file outlives its purpose the moment the corresponding chunk's PR merges. Leaving shipped plans next to active ones traps future sessions into treating closed work as ready-to-execute — exactly the failure mode that bit the 2026-05-23 session (recommended #137 as next chunk because `build-plan.md` was present at the repo root; the issue had been closed 18 days earlier).

- When a plan's referenced issue closes (or its PR merges), **move the plan to `<project-root>/.claude/plans/archive/`** rather than deleting. Archive preserves the design rationale for historical greppability without polluting the active plan listing.
- Sessions starting work on a "next chunk" must verify the referenced issue is still **OPEN** via `gh issue view <N> --json state -q .state` before treating any plan as canonical, even if the file is in the active (non-archive) directory. This is the structural guard — archiving is the convention, the issue-state check is the contract.
- The `.claude/plans/` directory and `build-plan*.md` at the repo root are gitignored on TC; the archive is local-only. A fresh clone has no archive — only this clone benefits from the historical record. That's fine; the issue-state check is what protects across clones.

## Memory Hygiene

Memory entries that exist only to bridge a specific gap (e.g., "decisions ratified in chat that haven't yet landed in the canonical plan", "context for an in-progress
migration", "notes for an open incident") should not be allowed to outlive their purpose. They turn into stale canon and quietly mislead future sessions.

**Rule: Bridge memos must self-delete.**

When you create a bridging memory entry:
- Frontmatter `description` must explicitly state the file is **self-deleting** and reference the cleanup criterion.
- File body must include a prominent "**__ Auto-cleanup check**" section near the top with:
1. A short, mechanical procedure to verify whether the bridging condition is still relevant (e.g., "read this file path, check whether these specific items appear in
it").
2. The action to take if the condition is resolved: `rm` the memory file AND prune its line from `MEMORY.md`.
3. The action to take if the condition is still pending: leave the file alone, treat its contents as canonical until ratified.
- `MEMORY.md` index line should signal the self-deleting nature (e.g., "**Self-deleting**: read its top 'Auto-cleanup check' section every session_").

When you read a bridging memory entry at session start:
- Run the cleanup check before treating the file as canon.
- If the check says delete, delete the file and prune `MEMORY.md` before continuing.

This prevents memory pollution and ensures bridging notes resolve cleanly into the permanent canonical docs (build plans, specs, ADRs) rather than accumulating as stale
background.

## Priming Prompts

When a project develops a recurring "session role" (e.g., advisor session for a parallel build, on-call review session, debugging session), the priming prompt for that role should be saved as a durable artifact, not kept in chat memory.

**Rule: Save priming prompts as git-tracked files.**
- Path convention: `<project-root>/.claude/priming/<role>.md`.
- The file should contain the verbatim block to paste, plus a short "How to use" section.
- Update history at the bottom (date + what changed) so divergence over time is visible.

## Cross-Session Write Boundaries

When two Claude Code sessions are working on related but distinct repos (e.g., an advisor session and a builder session, or a coordinator and an executor), the sessions
should respect repo ownership.

**Rule: Don't write to the other session's repo from yours.**
- The advisor / coordinator session should not commit to the builder / executor's repo, even when "it would be faster."
- Suggestions go via memo-back: produce a paste-able block the other session can apply, or write to a shared bridge memo (subject to the Memory Hygiene rule above).
- Both sessions can edit shared infrastructure (TangleClaw config, ports, etc.) since neither owns it.
- This prevents merge conflicts, surprises in the other session's git log, and ambiguity about who's responsible for which commit.

## Issues & Feature Requests

GitHub Issues are the canonical place to surface work that doesn't fit the current scope. They're searchable, citeable, assignable, and contribute to the project's public activity stats.

**Rule: File issues for bugs, deferred features, and open questions — don't bury them in chat or memory files.**

When the agent surfaces a bug, scope creep, deferred feature, or unresolved question that exceeds the current work item, suggest filing a GitHub issue before continuing.

- Title format: `[type] subject` where type is `bug`, `feature`, `chore`, `docs`, `question`.
- Body covers: what / why / how-to-reproduce (for bugs) or expected behavior (for features).
- Use templates from `.github/ISSUE_TEMPLATE/` if the repo has them.
- Link issues from PRs and commits with `Fixes #N` / `Closes #N` syntax — auto-closes the issue on merge.
- For solo projects: even when you'll fix it yourself, file the issue first, close it via the PR. The history is the value.

## Branches & Pull Requests

Substantive work goes through a feature branch and a pull request, even for solo projects. The PR is documentation of why a change happened — it's not just process overhead.

**Rule: Branch + PR for substantive work; direct main commits only for trivial doc edits or incident hot-fixes.**

- Branch naming: `feat/<short-name>`, `fix/<short-name>`, `chore/<short-name>`, `docs/<short-name>`, `refactor/<short-name>`.
- PR titles in active voice ("Add X", "Fix Y when Z", "Update W to vN.N").
- PR body has "What", "Why", and "Test plan" sections; link to issues with `Fixes #N`.
- Delete branches after merge.

**Rule: Pair `gh pr create` with `gh pr merge --auto --squash --delete-branch` for routine PRs.**

Routine PRs are docs, chore, version bumps, dependency updates, and test-only changes. Once branch protection gates clear, GitHub merges the PR server-side — no waiting on the session.

When opening a PR for routine work, immediately follow with:

```
gh pr merge <PR#> --auto --squash --delete-branch
```

GitHub holds the PR and merges the instant required checks pass.

**When to use `--auto`:**
- Documentation-only changes (README, CHANGELOG, MEMORY, plan files, comments, JSDoc).
- Chore PRs (dependency bumps, version updates, gitignore tweaks) where the change is mechanical and doesn't shift active methodology.
- Test-only PRs where the test code is the entire change.

**When NOT to use `--auto`:**
- Feature PRs (anything user-facing or behavior-changing).
- Refactors with non-trivial code movement.
- Anything that triggered an Independent Critic review — wait until findings are addressed and the user has signed off.
- PRs touching CI workflows, deploy config, secrets, or branch protection rules.
- Any PR the user has explicitly said they want to review before merging.

**Why `--squash`:** keeps `main` history linear and CHANGELOG-friendly. Matches the one-squash-commit-per-PR pattern most projects already use.

**Safety note:** branch protection rules still gate. If `main` requires a review, `--auto` waits for that review before merging. This rule never *overrides* protection — it only *removes the wait* once gates clear. Safe to apply broadly.

**If auto-merge isn't enabled on the repo:** `gh pr merge --auto` will error. Either enable it in repo Settings → General → Pull Requests, or fall back to `gh pr checks <PR#> --watch` followed by a manual merge.

## Releases & Versioning

Substantive milestones become tagged releases on GitHub. Releases create permanent, citeable URLs and contribute to the project's public activity.

**Rule: Tag releases with semver and create GitHub Releases with CHANGELOG-driven notes.**

- Use semver: MAJOR for breaking changes, MINOR for new features, PATCH for bug fixes. Pre-1.0 projects can use 0.x freely.
- After a substantive merge, suggest tagging: `git tag -a vX.Y.Z -m "..." && git push --tags`.
- Create the GitHub release: `gh release create vX.Y.Z --notes-from-tag` (or `-F <notes-file>` for hand-curated notes from CHANGELOG).
- Maintain a `CHANGELOG.md` in Keep a Changelog format with `[Unreleased]` section + dated release entries. Each merged PR adds to `[Unreleased]`; releases promote those entries to a dated section.

**Rule: TC's `version-bump` wrap step picks the bump level from `[Unreleased]` content. Author CHANGELOG entries under the subsection that produces the intended bump.**

| `[Unreleased]` content | Bump |
|---|---|
| `BREAKING:` or `BREAKING(` marker anywhere in body | **major** |
| Any `### Added`, `### Changed`, `### Removed`, or `### Deprecated` | **minor** |
| Only `### Fixed`, `### Security`, or `### Internal` | **patch** |

Rows are evaluated **top-down with first-match-wins** — a body that contains both `### Added` AND `### Internal` matches the minor row (user-visible subsection wins; `### Internal` does not veto a real feature). The patch row only fires when no minor- or major-triggering content is present.

`### Internal` is a non-Keep-a-Changelog subsection (introduced in #231) for refactors, test-only changes, dev tooling, CI tweaks, and doc-only edits that don't change user-facing behavior. Entries logged here still appear in `CHANGELOG.md` for full auditable history, but the wrap step treats them as patch-tier so a release made up entirely of internal churn doesn't inflate the minor counter.

Pick the subsection by **user-visible impact**, not file footprint: a one-line behavior change for the user is `### Added` / `### Changed`; a 500-line refactor with zero user-visible effect is `### Internal`. When in doubt between `### Changed` and `### Internal`, ask "would an operator notice a difference next session?" — yes → `### Changed`, no → `### Internal`.

## Repository Standards

Every repo should look professional and ready for visitors — future-self, contributors, and hiring evaluators reviewing the user's portfolio.

**Rule: Maintain a baseline of repository hygiene files; the agent suggests creating missing ones when the project's stage warrants.**

Baseline:
- `README.md` — what / why / install / use / status
- `LICENSE` — even private repos benefit from explicit licensing for future open-sourcing
- `CHANGELOG.md` — Keep a Changelog format
- `.gitignore` — language defaults + project-specific (env files, build outputs, OS noise)
- `.github/ISSUE_TEMPLATE/bug.md` and `feature.md` — for projects expecting contributions
- `.github/PULL_REQUEST_TEMPLATE.md` — checklist + What/Why/Test-plan sections
- Branch protection rule on `main` — require status checks; require review when contributors arrive

The agent suggests adding any of these only when it would add real value at the project's current stage (not boilerplate spam). A pre-public solo project doesn't need ISSUE_TEMPLATEs yet; a project being shown to a potential client does.

## Contributor Readiness

Once a project is shown to potential contributors, clients, or hiring evaluators, the agent should help the user flip from "solo project hygiene" to "open project hygiene."

**Rule: Anticipate contributor readiness; flag gaps proactively when the project signals it's going public.**

Triggers for the agent to do a readiness sweep: user says "this is going public" / "I'm bringing in a contributor" / "this is my dev-for-hire showcase" / "I want this on my portfolio" / project is about to be unprivated on GitHub.

Readiness checklist the agent runs through:
- README explains setup clearly enough that a stranger can get the project running with no prior context.
- LICENSE is present and intentional (MIT, Apache 2.0, BSL, AGPL — match the project's commercial stance).
- CONTRIBUTING.md exists with: dev setup, branch/PR conventions, test requirements, code-style expectations, where to file issues.
- CODE_OF_CONDUCT.md if the project is open to public participation (Contributor Covenant is a sensible default).
- CI is green and visible (status badges in README link to the CI workflow).
- Recent activity is visible — no months-stale main branch.
- Issue + PR templates are present.
- Discoverable from the user's GitHub profile (pinned repo if it's a showcase; mentioned in the user's profile README if relevant).

The agent should treat the user's GitHub profile as the user's public portfolio. Public commit activity, public repos, GitHub Releases, stars on others' projects, and contributions to others' repos all feed the user's profile stats and contribute to dev-for-hire credibility. Visibility is a feature, not a side-effect — when work crosses a milestone worth showing, suggest the visibility action.
Loading