tawa skills sync pulls Claude Code rules and slash-commands onto every dev's
machine. This is where that content comes from, and how to change it.
tawa-docs (git, PR-reviewed) ← SOURCE OF TRUTH
conventions/*.md → rules/tawa-*.md
commands/*.md → commands/tawa-*.md
│
│ .forgejo/workflows/sync.yml — on every push to main, runs
│ iec-builder's scripts/seed-skills.ts (plus Koko + Bible sync)
▼
iec-builder skills registry (MongoDB)
│
│ tawa skills sync
▼
~/.claude/rules/ and ~/.claude/commands/ on every dev's machine
The database is not the source of truth. It is a distribution cache. Editing a skill directly in the registry works right up until the next seed run overwrites it.
| Kind | Source | Lands at | Becomes |
|---|---|---|---|
| rule | conventions/<slug>.md | ~/.claude/rules/tawa-<slug>.md | Always-on guidance |
| command | commands/tawa-<name>.md | ~/.claude/commands/tawa-<name>.md | A /tawa-<name> slash command |
Rules are loaded into context automatically. Commands are invoked deliberately. Write a rule when the guidance should always apply; write a command when it is a procedure someone runs.
tawa-docs: conventions/ for a rule, commands/ for a command.main, .forgejo/workflows/sync.yml seeds the builder registry. It
uses the canonical scripts/seed-skills.ts from iec-builder, authenticated by the
repo secret BUILDER_INTERNAL_KEY, and also syncs Koko and the Bible. Nobody runs a
seed by hand, and nobody needs the builder key.tawa skills sync.Checking it published. The run log for the merge commit says
Found N skills/rules to seed … Done: 0 created, N updated, 0 errors (Forgejo →
tawa-docs → Actions). Or run tawa skills sync and look for your skill's new version.
The skills step fails soft. It is continue-on-error, and it skips with
BUILDER_INTERNAL_KEY not set if the secret disappears. So a green run is not proof
that the registry updated: check for the Done: line. workflow_dispatch re-runs it
by hand (Actions → sync → Run workflow).
Seeding by hand is for recovery only, for example when CI is down. Run it on the builder host, where the key already lives, so it never passes through a laptop:
git -C ~/dev/tawa-docs fetch origin
git -C ~/dev/tawa-docs archive origin/main conventions commands \
| ssh tawa 'rm -rf /tmp/tawa-docs-seed && mkdir -p /tmp/tawa-docs-seed && tar -x -C /tmp/tawa-docs-seed'
ssh tawa 'cd /opt/iec-builder && INTERNAL_SERVICE_KEY="$(grep ^INTERNAL_SERVICE_KEY= .env | cut -d= -f2-)" \
TAWA_DOCS_DIR=/tmp/tawa-docs-seed npx tsx scripts/seed-skills.ts; rm -rf /tmp/tawa-docs-seed'
Correction (2026-09-22): this page used to say seeding was "manual and deliberate" and that merging did not publish, with a laptop command needing
INTERNAL_SERVICE_KEY.sync.ymlhad been seeding on every merge for some time, so that guidance sent people after a key they never needed. The PR review is the gate.
version = 1.0.<sha256(content)[0:6] as int % 100000>
A version is a function of the content, so:
1.1.0) will be
overwritten by the next seed and, worse, may not match the content it claims to
describe.name:version, so a static version would hide
updates from tawa skills sync entirely.A convention seeds as tawa-<slug> with ['platform'] tags unless it appears in
CONVENTION_MAP in the seed script. Add an entry there when the rule name should
differ from the file name — for example conventions/auth.md seeds as
tawa-oauth.
Command files must be named tawa-*.md; anything else in commands/ is ignored.
~/.claude/commands/ directly is a dead end. It is the output of
the pipeline. Your change survives until the next tawa skills sync, then
disappears.CLAUDE.md.last_updated is a lie with a date on it. Update it when you change
a doc; it is the only signal a reader has about whether the content is current.Until 2026-08-28 the five slash-commands (tawa-auth, tawa-domains, tawa-pm,
tawa-scaffold, tawa-troubleshoot) were seeded from ~/.claude/commands on a
single machine — no backup, no review, no history. They now live in
tawa-docs/commands/ alongside the conventions.
Last updated: October 6, 2026