Skip to content
Closed
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: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ jobs:
# current. This found two dead references to a workflow and a makefile
# that the CI split had already removed.
if: ${{ !cancelled() }}
run: python3 scripts/check-skill-refs.py
run: python3 scripts/check-skill-refs.py AGENTS.md

# What follows needs LINT_PKGS, and the three checks that use it read
# only C sources, the style file, and the .ci scripts that implement
Expand Down
70 changes: 70 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Working on elfuse

elfuse runs Linux ELF binaries from the macOS shell: each guest runs in a
Hypervisor.framework VM the `elfuse` process owns, and Linux syscalls are
translated to macOS behavior in host-side handlers rather than served by a
kernel. `README.md` states the scope and the limitations, `docs/internals.md`
the design, `docs/testing.md` the build and lane requirements.

This file routes. It restates nothing that is settled elsewhere, because a
rule copied to a second place is a rule that can drift.

## Before writing C

`CONTRIBUTING.md` is the tracked style guide and it wins over everything
here. Read it rather than working from a memory of typical C style: several
of its rules are not the common default.

## The skills

The conventions `CONTRIBUTING.md` does not cover live in `.claude/skills/`,
reachable as `.agents/skills/` as well. Each directory holds one SKILL.md
whose description states when it applies; read the one covering the change
before making it, not after review asks for it.

- `elfuse-conventions`: comments, commit messages, PR text, `docs/`, naming,
atomics, and the prose register every written surface obeys.
- `elfuse-syscall`: adding or changing a Linux syscall, the translation
boundary, `src/syscall/dispatch.tbl`, fd classes, lock order.
- `elfuse-guest-abi`: HVC calls, the EL1 shim, page tables, TLBI, and
anything that changes what the guest observes on return.
- `elfuse-verify`: which lanes an area needs, the test matrix, and the
Frama-C proof targets.
- `elfuse-security`: the guest as an attacker, and what a handler on the
trust boundary owes.
- `elfuse-debug`: a guest that faults, hangs, or answers the wrong errno.
- `elfuse-refactor`: behavior-preserving cleanup of code that works.
- `elfuse-skills`: editing these skill files themselves.

## Gates

`make check` builds, runs the tests, and runs the checkers. `make indent`
formats and `make check-format` verifies without rewriting; between them
they settle most review comments before they are written.

Run what the change touched before calling the work done, and say what ran
and what it reported; effort is not a finding. `elfuse-verify` settles which
lanes an area needs, and which of them skip rather than fail when a tool is
missing.

## Prose

Two rules bind before the first sentence. Source comments and commit

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The file's stated purpose is to route and restate nothing, because "a rule copied to a second place is a rule that can drift," but the ## Prose section restates the two prose rules (ASCII with no markdown syntax; em dash ban) that are already settled in .claude/skills/elfuse-conventions/references/prose-register.md ("The two rules that come first, ASCII with no markdown syntax and the em dash ban"), the conventions SKILL.md, and CONTRIBUTING.md. This creates exactly the drift the opening claim warns against: if the em dash or ASCII rule changes in the skill, this section goes stale silently. Route to the canonical home (prose-register.md / elfuse-conventions) in the section instead of restating the rules, or qualify the "restates nothing" claim to say the two grep-checkable prose rules are restated deliberately.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At AGENTS.md, line 52:

<comment>The file's stated purpose is to route and restate nothing, because "a rule copied to a second place is a rule that can drift," but the `## Prose` section restates the two prose rules (ASCII with no markdown syntax; em dash ban) that are already settled in `.claude/skills/elfuse-conventions/references/prose-register.md` ("The two rules that come first, ASCII with no markdown syntax and the em dash ban"), the conventions `SKILL.md`, and `CONTRIBUTING.md`. This creates exactly the drift the opening claim warns against: if the em dash or ASCII rule changes in the skill, this section goes stale silently. Route to the canonical home (prose-register.md / elfuse-conventions) in the section instead of restating the rules, or qualify the "restates nothing" claim to say the two grep-checkable prose rules are restated deliberately.</comment>

<file context>
@@ -0,0 +1,70 @@
+
+## Prose
+
+Two rules bind before the first sentence. Source comments and commit
+messages are ASCII with no markdown syntax, which `make check-ascii` and the
+commit-message hook enforce. The em dash (U+2014) is banned on every surface,
</file context>

messages are ASCII with no markdown syntax, which `make check-ascii` and the
commit-message hook enforce. The em dash (U+2014) is banned on every surface,
including the ones no gate reaches: `docs/`, PR bodies, and review replies. A
spaced double hyphen carries the same register rather than avoiding it.

The rest of the machine register, effort claims and inflation words and
prompt echo among them, is defined once in
`.claude/skills/elfuse-conventions/references/prose-register.md`. A PR thread
is a technical discussion between people; walkthroughs, status tables, and
replies that hand the choice back to the reviewer are rejected on sight.

## Files that are not yours

Untracked working docs at the repo root or under `.claude/` belong to
whoever put them there. Never `git add`, commit, stage, gitignore, or delete
another person's: untracked and visible in `git status` is deliberate.
Anything that has to survive a fresh clone belongs in `CONTRIBUTING.md`,
`docs/`, or a skill.
1 change: 1 addition & 0 deletions CLAUDE.md
4 changes: 2 additions & 2 deletions mk/tests.mk
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ check-svc-tails:
@python3 scripts/check-svc-tails.py --self-test
@python3 scripts/check-svc-tails.py

## Verify every path, target, and section the skills name still resolves
## Verify every path, target, and section the skills and AGENTS.md name resolve
check-skill-refs:
@python3 scripts/check-skill-refs.py --self-test
@python3 scripts/check-skill-refs.py
@python3 scripts/check-skill-refs.py AGENTS.md

define RUN_OPTIONAL_SKIP77
@set -e; \
Expand Down
6 changes: 3 additions & 3 deletions scripts/check-skill-refs.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,9 +555,9 @@ def main():
SKILL_DIR.glob("*/references/*.md")
)

# A routing file is checked the same way, but only when its owner names
# it: whether one exists is local to a working copy. It is checked even in
# a clone with no skills directory, where its references rot fastest.
# A routing file is checked the same way, when named: AGENTS.md is the
# tracked one and a working copy may name its own. It is checked even in a
# clone with no skills directory, where its references rot fastest.
for extra in sys.argv[1:]:
path = pathlib.Path(extra)
if not path.is_absolute():
Expand Down
Loading