creating-applications — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited creating-applications (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.
An application is a compiled distribution: a corpus subset projected onto a task axis (optionally through a lens-set and a practitioner-role agent-set), bundled with a CLAUDE.md template and packaged at corpus.commons/{corpus}/apps/{profile}/. This skill scopes and assembles one application end-to-end.
The skill is the single user-facing entry point for creating an application. Internally it delegates to two sub-skills:
corpus.commons/{corpus}/tasks/{task-slug}.md, invoke the creating-tasks flow inline. The dialogue happens in this skill's conversation; the task spec drops at the right path; the skill continues onward without re-prompting the user. If a task spec already exists, skip.creating-distillations once. Pass G's applicability gate decides which distillations fire. Often dispatched as parallel sub-agents.Between those two delegations, the skill does its own scaffolding work: distillation directory, distillation index (seeded from the task spec's practitioner questions and runtime listener grain), build profile in builds.yaml, package.json build script, build-profiles/{profile}.md CLAUDE.md template, and one agent file per agent declared in the task spec.
creating-distillations directly.builds.yaml and the per-task distillation indexes.The skill expects a task-axis spec at corpus.commons/{corpus}/tasks/{task-slug}.md. If the spec does not exist, the skill invokes creating-tasks inline (Step 0 below).
The task spec carries (per the creating-tasks contract):
2a. Runtime listener grain. Trigger unit, response unit, and a seed trigger→response table with at least five rows per phase. Required, not optional. creating-applications reads it to author the distillation index's runtime tables; creating-distillations reads it at Pass G to map each source's content to the triggers it can address. Without it the application is a catalogue, not a coach.
corpus.commons/{corpus}/lenses/ will reach for this task. Per-distillation applicability decided downstream at Pass G.4a. Intended runtime agents. List of agent slugs and role descriptions. Zero-or-more agents per axis. This skill authors one file per declared agent at .claude/agents/{agent-slug}.md in Step 4a.
If any required field is missing, the skill fails with a specific message rather than degrading silently. The operator returns to creating-tasks to fill the gap, then re-invokes this skill.
Step 0 ensures a task spec exists; Steps 1-4 scaffold the application; Step 4a authors any declared agents; Step 5 orchestrates per-distillation distillation.
When invoked, the skill identifies the intended task slug. Sources of the slug, in order of preference:
/creating-applications learning-from-incidents or "create an app for learning-from-incidents"), use it directly.learning-from-incidents for AAR work; coaching-engagements for coaching). State the inference back to the operator and ask them to confirm or rename before continuing.Once the slug is provisional, check whether corpus.commons/{corpus}/tasks/{task-slug}.md exists.
If the spec exists: read it. Verify the six required fields. If any are missing, surface the gap and ask whether to update via creating-tasks (re-running the relevant phases) or proceed as-is. Default: update; the missing fields are usually load-bearing.
If the spec does not exist: invoke the creating-tasks skill at .claude/skills/creating-tasks/SKILL.md inline. The 9-phase JTBD dialogue runs in this conversation as part of this skill's flow.
When creating-tasks returns with a verdict:
finding-resources to ingest more material, or wait until practitioner work is clearer).Read corpus.commons/{corpus}/tasks/{task-slug}.md. Confirm all six required fields are present. If any are missing, abort with the operator-facing message naming the missing fields.
Record the task spec in working memory:
learning-from-incidents)learning-from-incidents; operator may override)Create corpus.commons/{corpus}/distillations/{task-slug}/ if it does not already exist.
Author corpus.commons/{corpus}/distillations/{task-slug}/{TASK-UPPERCASE}-DISTILLATION-INDEX.md (the operator-inspection view; the runtime reads task-index.json generated by scripts/build_indexes/build_task_index.py). Use the existing distillation indexes as the structural model: see corpus.commons/demo/distillations/decision-making/DECISION-MAKING-DISTILLATION-INDEX.md and corpus.commons/demo/distillations/stakeholder-engagement/STAKEHOLDER-ENGAGEMENT-DISTILLATION-INDEX.md for reference.
Seed the index with:
The index is created with the structure in place but minimal content. Step 5's per-distillation projections populate the rows.
Two routing layers, not one. Phase-routing is the macro-router (query mentions a phase or situation type → candidate distillations). Runtime listener table is the micro-router (query mentions an observable trigger → framework that fires in the moment). Both ship; the assistant uses the listener table first when a query carries observable signals, the phase-routing table when the query is at the situation-type level.
Author {corpus-root}/build-profiles/{profile-slug}.md. Use existing profile templates as the structural model: see corpus.commons/demo/build-profiles/decision.md and corpus.commons/demo/build-profiles/stakeholder.md for reference.
The template carries:
## Capability binding section: see Step 3a.Adapt the template to the application's specifics. Do not copy-paste decision.md without reshaping: the template's structure is reusable, its content is not.
Per docs/architecture/capability-binding.md, every application declares the abstract capabilities it benefits from at the profile boundary: never inside a substrate skill, rarely inside a corpus-bound skill. This skill is substrate; it MUST NOT declare capabilities itself. It MUST scaffold capability declarations into the artefacts it produces (the builds.yaml entry in Step 4 and the CLAUDE.md template in this step). The distinction is load-bearing: the substrate stays capability-blind, the apps it generates carry capability-awareness at the right layer.
Ask the operator (one prompt, batched): "Does this application ride on user-owned work tools, chat (Slack / Teams), issue trackers (Shortcut / Linear / Jira), notes archives (Obsidian / Confluence / Notion / Drive), calendar, delivery metrics, or anything similar? For each: what does the app do when it's bound, and what's the graceful fallback when it isn't?"
The operator's answer falls into one of three shapes:
notes-archive with a "paste markdown manually" fallback) so the conformance pattern is visible to the runtime. Every app shows the pattern; the field's presence is itself the conformance signal.chat-export, issue-tracker, notes-archive, calendar, delivery-metrics are the names already in use across the repo's profiles. Avoid naming a concrete server (slack, shortcut, obsidian): those belong in the user's ~/.claude/capabilities.toml, not in the profile. If the operator names a capability that doesn't fit any existing name, accept the new name ad-hoc (vocabulary governance is open question §5 in the spec)./foo-start [id] skill that structurally cannot run without a binding. Surface this in the prompt and route the operator to Step 4b (skill-level declaration) after this step. Most apps will have zero or one such skill; the bar is structural impossibility, not would be nice to have.Write the ## Capability binding section into the CLAUDE.md template using the worked example in docs/architecture/capability-binding.md §4 as the structural model. The section names each abstract capability, the bound behaviour, and the unbound (fallback) behaviour. The unbound path is the conformance test: every framework citation, every distillation read, every routing decision still works when nothing is bound.
Append a new entry to builds.yaml following the existing entries' shape. The entry carries:
name: {profile-slug}.description: one paragraph explaining the application's purpose, target audience, and corpus scope. Visible in build output.source_dir: the corpus root (typically corpus.commons/{corpus}).output_dir: corpus.commons/{corpus}/apps/{profile-slug}.claude_md: build-profiles/{profile-slug}.md (created in Step 3).distillations: which distillation directories to include. The new task-slug must be in the list. Optionally include sibling axes if the application is meant to be multi-axis (rare; most applications are single-task).lenses: true if the application ships the lens set, false if not.agents: include: [list of agent slugs] per the task spec's field 4a. Empty list ([]) if the task spec declares no runtime agents.recommends_capabilities: one or more {name, purpose, fallback} entries per the operator's Step 3a answers. Always present; even apps with no MCP integration carry a minimal generic entry so the conformance pattern is visible. Capabilities are abstract names; the user's ~/.claude/capabilities.toml binds concretes. See docs/architecture/capability-binding.md §4 for the shape.ignore_dangling: the standard list of paths the validation should not chase. Copy from a sibling profile and adjust.Append a new build script to package.json following the existing scripts' shape:
"build:{profile-slug}": "node build.js {profile-slug}"Run npm run build:{profile-slug} to verify the profile scaffolds cleanly. The build will run against an empty (or stub) distillation directory at this point: that's expected. The validation should pass on structure and referential integrity. If it fails, fix the scaffolding before proceeding to Step 4a (if agents declared) or Step 5.
If the task spec carries field 4a with one or more agent slugs, author one file per declared agent at .claude/agents/{agent-slug}.md. Each agent file has YAML frontmatter (name, description, tools, model, color) plus a markdown system prompt. The shape follows Claude Code's custom-agent conventions. The demo profiles ship no runtime agents; the .claude/agents/ directory is empty in the shipped demo. When a downstream application defines its first agent, the resulting file becomes the local precedent for the shape.
Skill-placement rule for any practitioner-role skills authored alongside this application. Skills that cite this application's references or task axis are corpus-bound and belong at {corpus-root}/.claude/skills/{skill-slug}/SKILL.md: they travel with the corpus. Skills that are corpus-agnostic patterns (e.g. a new variant of matching-references or audit-attribution) are substrate and belong at the repo-root .claude/skills/{skill-slug}/SKILL.md. The build resolver checks the corpus first, then substrate; either location ships into the compiled app's flat .claude/skills/. If the operator authors a new corpus-bound skill, also enumerate it in this profile's skills: list in builds.yaml. See the substrate-vs-corpus-bound section of the repo-root CLAUDE.md for the discovery model.
Each authored agent carries:
name (matches slug), description (when to invoke this agent), tools (constrained palette: typically Read, Grep, Glob, Edit, Write, Skill for runtime agents; runtime agents rarely need WebFetch / WebSearch / Bash), model (default sonnet; opus only when the role's reasoning grain genuinely needs it), color (visual marker).matching-references SKILL.md), with the specific listener tables for this task axis named.If the agent file already exists (operator hand-authored it earlier), read it and validate against the task spec's role description for that agent rather than overwriting. Surface discrepancies for the operator to reconcile.
Update builds.yaml's agents.include list for this profile to include all declared agent slugs. Re-run npm run build:{profile-slug} to confirm the agents copy into apps/{profile}/.claude/agents/ cleanly.
If Step 3a identified one or more corpus-bound skills that are structurally impossible without a binding (the classic case: /foo-start [id] cannot synthesise an id it cannot fetch), declare them per docs/architecture/capability-binding.md §3. For each integration-heavy skill, append to its frontmatter:
requires_capabilities: [{capability-name}]
fallback_for_capabilities: [{capability-name}]Then add a ## Capability binding paragraph below the frontmatter naming the bound behaviour, the unbound fallback (either fail closed with a clear binding instruction or a precisely-bounded degraded path), and the discipline of never fabricating data the binding would have produced.
The bar is structural impossibility, not convenience. Most corpus-bound skills are framework-application: they read the corpus and apply distillations, with optional MCP enrichment when present. Those skills MUST NOT declare capabilities (they SHOULD NOT clutter their frontmatter with bindings they only opportunistically use). The repo's worked examples are: aar-start, aar-new, obs-coach, obs-health, obs-report carry frontmatter declarations; aar-actions, aar-deep, retro-*, aletheia-session, coaching-feedback, mentoring-feedback, meeting-review do not. Most new applications will produce zero integration-heavy skills.
For each source slug in the task spec's field 3, invoke creating-distillations with the (source, task) pair. Pass G's source-applicability gate inside creating-distillations decides whether the source applies; if it does, the distillation is produced and the index is updated. If it doesn't, the skip is logged with the reason.
Two ways to invoke:
creating-distillations once per (source, task) distillation. Slower; appropriate for small source sets (≤ 5 sources) or when the operator wants to review each distillation.ingesting-resources/SKILL.md is the model.Concurrency hazard. Multiple sub-agents updating the same distillation index file race. Mitigation: each sub-agent writes its index entries to a staging file (_ingest_{task}_{source-slug}.md in the distillations directory); a final consolidator step merges all staging files into the canonical index.
Lens applicability is handled inside creating-distillations at Pass G: this skill passes the lens-set through and does nothing extra.
After all per-distillation invocations complete:
Output a list at the end recording:
The orchestrator step sometimes reveals the task spec was wrong:
ingesting-resources and re-orchestrate, or accept thin coverage and document it.When the orchestrator reveals a spec problem, update the spec and re-run. Do not paper over the gap by editing the distillation index by hand.
The skill does not silently overwrite an existing application. Two paths:
creating-distillations directly for each new source.npm run build are not optional. The validation catches dangling references and structural problems.creating-tasks rather than improvising scoping here.requires: slack in builds.yaml is a conformance failure (capability-binding.md). Profile declares the abstract capability (chat-export, issue-tracker); the user's ~/.claude/capabilities.toml binds the concrete. The scaffolded text should not name a server..claude/skills/creating-applications/SKILL.md. If a future maintainer reaches for requires_capabilities: here, the bright line is broken.creating-tasks: scopes a new task axis. Upstream; produces the task spec this skill consumes.creating-distillations: per-distillation projection. Downstream; this skill invokes it once per applicable distillation.creating-lenses: designs a lens spec. Run before this skill when the task spec names lenses that don't yet exist.ingesting-resources: ingests a new source. Use when the orchestrator reveals thin source coverage.creating-corpus: scaffolds a new corpus directory tree. The corpus must exist before this skill can compile into it.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.