geno-init — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited geno-init (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Bootstrap an OpenGeno feature tree for a project. Run once per project. If feat-tree/ already exists, abort and direct the user to /geno-sync instead.
This skill is the only command needed to set up the tree — and the only way to introduce the OpenGeno workflow rules into CLAUDE.md / AGENTS.md.
test -d feat-tree && echo "tree exists, abort" || echo "ok to init"If the tree exists, stop. Tell the user to use /geno-sync for drift, or to manually add new feature docs from the templates in this skill's templates/ directory.
Use AskUserQuestion:
Store the choice as LANG = "en" or LANG = "zh". Critical: from this point on, every file you write under feat-tree/, every section heading, every prose line, every comment, every example value, every TODO placeholder MUST be in the chosen language. Do not mix languages within the tree.
If the user picks Chinese, you must write Chinese exclusively for the rest of this skill's execution. Do not silently fall back to English even for "small" things like field labels — the user will read every doc in their chosen language; mixing is jarring.
Use AskUserQuestion, phrased in the chosen language:
Store as DRIFT_MODE.
Use AskUserQuestion, phrased in the chosen language:
Store as MODE = "stub" or MODE = "full".
stub is the default because deeper code reading is expensive and hallucination-prone — the user should opt in deliberately. full is useful when the codebase is small and stable, and the user wants a complete first-pass tree to review wholesale rather than incrementally.
MODE controls two things downstream: scan depth in Step 4, and L3 body content in Step 8. Everything else is identical between modes.
Scan depth depends on MODE:
MODE=stub → shallow scan, structure only (current behavior).MODE=full → after the shallow pass identifies features, open therelevant route/controller/page/screen files for each feature and read enough to populate L3 sections in Step 8.
Glob for likely feature surfaces. Useful patterns:
| Stack | Look at |
|---|---|
| Flutter | lib/features/**/, lib/pages/**/, lib/screens/**/, route files |
| React/Next.js | app/**/page.tsx, pages/**/*.tsx, src/features/**/, src/routes/**/ |
| iOS (Swift) | *ViewController*, Scene*, navigation graph |
| Android | *Activity*, *Fragment*, navigation graph |
| Backend | route/controller files, top-level service classes |
Identify:
For MODE=stub, keep the scan shallow — the goal is a proposal, not a finished tree. For MODE=full, the proposal pass is still shallow; the deeper read happens per-feature during Step 8.
Show the user the draft module list with one-line descriptions, in the chosen language. Use AskUserQuestion (also in the chosen language) to ask whether the proposal is acceptable.
Iterate until they accept.
Pick the right template:
LANG=en → templates/root-index.mdLANG=zh → templates/root-index.zh.mdWrite feat-tree/index.md from the template, replacing placeholders:
{{PROJECT_NAME}} — from package.json / pubspec.yaml / go.mod / etc.last_synced_commit: left emptyAll generated prose (module descriptions, etc.) must be in the chosen language.
For each accepted module, write feat-tree/<module>/index.md from templates/module-index.md or templates/module-index.zh.md. List the proposed features as table rows. Module description and any free-form text in the chosen language.
For each proposed feature, write an L3 doc using:
templates/feature-ui.md (en) or templates/feature-ui.zh.md (zh)templates/feature-logic.md (en) or templates/feature-logic.zh.md (zh)Frontmatter is the same in both modes:
type, kind, feature, module filled incode: filled from scan when knownlast_synced_commit: "" (always empty at init — the doc has notbeen reviewed against code yet, even in full mode)
last_reviewed: today's dateSection bodies depend on MODE:
language; section bodies set to placeholder text — TODO (English) or 待补充 (Chinese). L3 details get filled in incrementally on the first real task that touches each feature, driven by the workflow rules in CLAUDE.md.
Step 4) and write best-effort prose for each section, in the chosen language. Keep last_synced_commit: "" regardless — full-mode output is unverified by definition and a stale-or-empty SHA is what tells /geno-sync (and the user) that the doc still needs a review pass before any session bumps the SHA. Be honest in tone: if a section can't be inferred from the code, leave it as the placeholder text rather than guessing.
In neither mode should you set last_synced_commit to current HEAD — the SHA represents verified-against-code, and init has not done that work.
.feat-tree.jsonCopy templates/feat-tree.json to project root, then patch drift_mode and gen_mode to the chosen values:
{
"version": 1,
"tree_path": "feat-tree",
"drift_mode": "warn",
"gen_mode": "stub"
}This file controls downstream behavior:
drift_mode is read by the Stop hook at session-end.gen_mode records which generation mode the tree was bootstrappedwith. /geno-sync reads it to distinguish empty-SHA docs that are unwritten stubs from empty-SHA docs that are written-but-unverified full-mode prose — the two need different reconciliation actions.
Read the corresponding injection template:
LANG=en → templates/claude-md-injection.mdLANG=zh → templates/claude-md-injection.zh.mdThen for each of CLAUDE.md and AGENTS.md that already exists at project root: append the injection text. Don't overwrite existing content. Don't insert above existing content.
If neither file exists at project root, create CLAUDE.md with just the injection text (AGENTS.md only created if it already exists).
The injection block is wrapped in <!-- BEGIN OpenGeno --> / <!-- END OpenGeno --> markers so future re-runs or removals can target it precisely.
If a BEGIN OpenGeno marker already exists in the target file, abort the injection for that file (it was already injected) and warn the user.
Print a summary in the chosen language:
stub or full)CLAUDE.md / AGENTS.md was created or appendedMODE=stub: "Fill in L3 details on demand as you work — the firsttask that touches each feature should expand its stub."
MODE=full: "L3 bodies were generated from a one-shot code readand are unverified. Review each doc against the code before letting any session bump last_synced_commit. /geno-sync will keep flagging them as STUB until the SHA is set."
The user picked a language; they expect the tree to be in that language end-to-end.
not language)
(file-system-friendly, AI-stable)
If you find yourself about to write English in a Chinese tree because "it's just a placeholder" or "the term is hard to translate" — stop and translate. The user will notice; they will be annoyed.
The injection text in CLAUDE.md / AGENTS.md tells the AI on future sessions to keep writing in the chosen language. Get it right on this first pass and the rule perpetuates.
| Don't | Why |
|---|---|
| Mix languages within the tree | Defeats the language-selection contract; will be visibly wrong |
| Auto-fill all L3 docs from code without the user opting in | Expensive, hallucination-prone — only do this when the user explicitly chose full mode in Step 3, and warn them in Step 11 that the output needs review |
Set last_synced_commit to HEAD on a full-mode doc | Defeats the whole drift system — full output is unverified; SHA must stay empty until a human reviews against code |
| Silently merge with an existing tree | Risks overwriting hand-written content |
| Use the AI's first-pass module guess without user review | Module boundaries are a project-specific judgment call |
| Treat infra items (i18n, theme tokens, etc.) as features | Pollutes the tree, dilutes the signal |
Set last_synced_commit to current HEAD on a stub | Misleading — stubs aren't synced |
| Forget to inject rules into CLAUDE.md / AGENTS.md | Without these, future sessions have no instruction to follow the workflow |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.