From 7304ff3d58a6acd56f93887f6a652ce4c8fac787 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 10 Sep 2026 18:04:19 -0400 Subject: [PATCH] chore: adopt shared engineering guidance --- .claude/settings.json | 6 ++++ .github/copilot-instructions.md | 19 ++++++++++++ .github/pull_request_template.md | 28 ++++-------------- .gitignore | 1 + .origin89/sync-engineering.py | 51 +++++++++++++++++++------------- AGENTS.md | 32 ++++++++++++++++++-- CLAUDE.md | 2 +- CONTRIBUTING.md | 4 +++ 8 files changed, 96 insertions(+), 47 deletions(-) create mode 100644 .claude/settings.json create mode 100644 .github/copilot-instructions.md diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..671a084 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,6 @@ +{ + "attribution": { + "commit": "", + "pr": "" + } +} diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..e257a4b --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,19 @@ +# Copilot reviews + +For code review, follow `Code Review Rules` in root `AGENTS.md` and the local +instructions that apply to changed files. Read the shared `origin89-review` +skill before reviewing behavior, with its relevant domain skills. + +Use shared skills only when they are already available in the review context. +The detailed criteria are maintained in +[engineering's review skill](https://github.com/origin89hq/engineering/blob/main/skills/origin89-review/SKILL.md). +If that skill is unavailable, follow the local review rules and disclose the +missing shared context. Do not install tooling or assume a developer's ignored +cache exists in the hosted review. A link is not evidence that a file was read. + +Review the requested head and its callers. Report a reproducible trigger, +consequence, and precise code location. Do not invent findings, duplicate an +existing finding without new evidence, or treat a CI pass as proof of safety. +Leave formatting to the configured linters. Keep review comments concise, with +one physical line per paragraph. A review request authorizes findings, not code +changes or publication. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 95b9560..251651c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,27 +1,11 @@ -## Problem and change + -Describe the problem and how the change fixes it. Include compatibility or -migration details when relevant. +## Change -## Validation - -List commands actually run and their results. For changed nontrivial behavior, -identify the distinct cases covered; add rows or explain why a category does not -apply. Include further branches and faults where the contract requires them. - -| Behavior | Success | Invalid input | Boundary | Failure / recovery | -| --- | --- | --- | --- | --- | -| Describe the behavior | Test or evidence | Test or reason | Test or reason | Test or reason | + -Name any unperformed checks and remaining uncertainty. Include UI screenshots or -hardware evidence when applicable. - -## When relevant +## Validation -Remove items that do not apply and complete the relevant ones: + -- New package, dependency, automation, or doc: why it is needed and how it stays current. -- Dependency update: verified stable version, source, compatibility, and lockfile. -- Package release: changeset and consumer impact, or why no release is needed. -- Brand change: package version, exported assets/tokens, and visual checks. -- Equipment behavior: safety-change record, fault evidence, and reviewer. + diff --git a/.gitignore b/.gitignore index c922b93..ff4284e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ __pycache__/ /.origin89/engineering/ /.agents/skills/origin89-* /.venv/ +/.claude/skills/origin89-* diff --git a/.origin89/sync-engineering.py b/.origin89/sync-engineering.py index 3a86ce9..6b60a3c 100644 --- a/.origin89/sync-engineering.py +++ b/.origin89/sync-engineering.py @@ -141,33 +141,42 @@ def current_state(cache): def activate(project, cache, state, previous): - directory(project / ".agents") - discovery = project / ".agents" / "skills" - directory(discovery) old_names = set(previous["skills"]) if previous else set() new_names = set(state["skills"]) targets = {} - for name in old_names | new_names: - link = discovery / name - target = os.path.relpath(cache / "current" / "skills" / name, discovery) - if link.is_symlink(): - if os.readlink(link) != target: - raise ValueError(f"Refusing to replace a custom skill link: {link}") - elif link.exists(): - raise ValueError(f"Refusing to replace local skill files: {link}") - targets[name] = target + # Check every discovery directory before changing links or the shared pointer. + for assistant in (".agents", ".claude"): + directory(project / assistant) + discovery = project / assistant / "skills" + directory(discovery) + for name in sorted(old_names | new_names): + link = discovery / name + target = os.path.relpath(cache / "current" / "skills" / name, discovery) + if link.is_symlink(): + if os.readlink(link) != target: + raise ValueError(f"Refusing to replace a custom skill link: {link}") + elif link.exists(): + raise ValueError(f"Refusing to replace local skill files: {link}") + targets[link] = target next_pointer = cache / "next" if next_pointer.exists() or next_pointer.is_symlink(): raise ValueError("Unexpected pending cache pointer; inspect it before retrying") - for name in sorted(new_names): - link = discovery / name - if not link.is_symlink(): - link.symlink_to(targets[name], target_is_directory=True) - next_pointer.symlink_to(f"versions/{state['revision']}", target_is_directory=True) - os.replace(next_pointer, cache / "current") - for name in sorted(old_names - new_names): - link = discovery / name - if link.is_symlink(): + created = [] + try: + for link, target in targets.items(): + if link.name in new_names and not link.is_symlink(): + link.symlink_to(target, target_is_directory=True) + created.append(link) + next_pointer.symlink_to(f"versions/{state['revision']}", target_is_directory=True) + created.append(next_pointer) + os.replace(next_pointer, cache / "current") + except OSError: + # Before the pointer changes, remove only links created by this attempt. + for link in reversed(created): + link.unlink() + raise + for link in targets: + if link.name not in new_names and link.is_symlink(): link.unlink() diff --git a/AGENTS.md b/AGENTS.md index c794a60..9042032 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,10 +1,12 @@ # Working in this repository -At the start of each new task, run `just skills-sync` from the repository root. +For hosted PR reviews, follow `Code Review Rules` below without running the local +skills refresh. For other tasks, run `just skills-sync` from the repository root. Read `skills/origin89-working/SKILL.md` and the relevant domain skills under the immutable `path` printed by that command. Keep that snapshot for the task; do not -refresh it halfway through work. Read local instructions and preserve stronger -project constraints and project-specific skills. +refresh it halfway through work. Before branch, commit, push, or PR operations, +read `skills/origin89-commits/SKILL.md` from that snapshot. Read local instructions +and preserve stronger project constraints and project-specific skills. If refresh reports cached content, continue with that verified cache and mention that the script could not check for updates. If no cache is available or @@ -18,6 +20,12 @@ and exceptions below. Internal RFCs and research belong in [internal-research](https://github.com/origin89hq/internal-research). Add documentation only when its value and upkeep are clear; remove AI filler from every message. +Confirmed problems left outside the current fix need an issue in the owning +repository: search with `gh`, reuse a matching issue or create one with evidence, +and return its URL. Follow the shared working skill's unfinished-work rule. +Respect posting restrictions; if filing is blocked, provide the draft and say why. +Finish authorized fixes instead of replacing them with backlog issues. + ## Board work Read `CONTRIBUTING.md`, `board/CAMERA-LAYOUT.md`, and the board's Gerber @@ -30,3 +38,21 @@ Run `just check` for the selected fabrication export. A failing copper rule is a board finding: report it and keep the gate failing until the artwork is fixed. Gerber validation does not establish electrical or bench qualification. This is a Python/CAD repo; do not add Node or Cargo workspaces without actual consumers. + +## Code Review Rules + +Read the shared `origin89-review` skill and relevant domain skills when available. +In hosted review jobs that already provide `.origin89/engineering/skills/`, use +that checkout without running the local refresh. If shared context is missing, +review against the rules below and disclose that limit. + +- Preserve EasyEDA source and filed fabrication exports. Board changes need + the corresponding layout rule and checker evidence; keep copper failures visible. +- Distinguish Gerber and placement checks from electrical or bench qualification. + Do not infer hardware safety from a passing host check or change artwork during review. +- Trace findings through callers and guards. Give the trigger, consequence, and + precise location; distinguish completed checks from missing evidence. Leave + formatting to the configured tools and avoid duplicate or speculative findings. +- Keep current PR defects in the review. Track confirmed pre-existing or explicitly + deferred problems as issues when filing is authorized; comments-only reviewers + provide a draft and state that it was not filed. diff --git a/CLAUDE.md b/CLAUDE.md index cf65511..43c994c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1 +1 @@ -Read `AGENTS.md` first. Follow its task-start skill refresh and repository checks. +@AGENTS.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 34076f4..ace1d15 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,6 +28,10 @@ for working practices, tests, writing, and commits. `AGENTS.md` loads shared skills at the start of a task; `just skills-sync` refreshes them from engineering. Keep local constraints and domain-specific checks alongside those shared rules. +Track confirmed problems left outside the current fix using the +[shared issue rule](https://github.com/origin89hq/engineering/blob/main/skills/origin89-working/SKILL.md#track-unfinished-work). +Use `gh` to find or create the issue, verify it, and return its URL. + Install just 1.58.0 and Python 3.9+ for the skill bootstrap. Run `just --list` for repository commands and `just check` before opening a pull request.