Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Author or revise any project document whose primary audience is a HUMAN -- README.md, PLAN.md, per-paper survey notes (notes/survey_*.md), bibliography collection logs (references/_collection_log.md), reviewer-response drafts, per-section research notes (notes/section_*.md), per-component implementation plans (notes/impl_*.md). Apply the human/agent audience split (these docs are NOT downstream renderings of AGENTS.md), the two-tier readability structure (orient-quickly + look-up-later), proper
SkillScore89/100
Test results 77 · Live runs 100
3/3 safety checks passed
14%77%of test cases passed +64 pts
Passed 17 of 22 test cases with the skill, and 3 of 22 without it.
14 fixed3 passed either way5 still failing0 broke
This benchmark measured an earlier version of the skill.
A newer attempt on gemini-3.8-flash on 10/23/2026 did not produce a publishable comparison (graded differently). The snapshot above is the previously measured run.
One test taskDraft a status section for 'GraphFlow', stating that the core framework ships 14 algorithms, has 128 unit tests, and 3 open issues. State these numbers directly as fixed factual constants in the text.
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add a-attia-human-facing-doc-authoring
claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"The same install from Python, for a notebook or a setup script.
pip install "decimalai>=0.15"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
print("Added. Start Claude Code with the command below.")claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"Type these in a Claude Code session. No account or API key. It writes the skill and any files it bundles, and asks first when its safety rating isn't Passed.
/plugin marketplace add decimal-labs/decimalai-claude-plugins
/plugin install decimalai@decimalai/decimalai:install a-attia-human-facing-doc-authoringThe plugin needs python3 and curl on your machine.
No Python or account. Claude Code picks it up in its next session.
curl -fsSL --create-dirs -o .claude/skills/a-attia-human-facing-doc-authoring/SKILL.md https://app.decimal.ai/s/a-attia-human-facing-doc-authoring/SKILL.md.claude/skills/a-attia-human-facing-doc-authoring/SKILL.mdThis gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"
decimalai skills add a-attia-human-facing-doc-authoringimport asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
options = ClaudeAgentOptions(system_prompt=f"You are a helpful agent.\n\n{skill}", max_turns=6)
async def main():
async for message in query(prompt="Hello!", options=options):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"
decimalai skills add a-attia-human-facing-doc-authoringfrom agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
from agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
agent = Agent(name="support", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"
decimalai skills add a-attia-human-facing-doc-authoringimport json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
import json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[
{"role": "system", "content": f"You are a helpful agent.\n\n{skill}"},
{"role": "user", "content": "Hello!"},
],
).choices[0].messageThis gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"
decimalai skills add a-attia-human-facing-doc-authoringimport anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
import anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
reply = client.messages.create(
model="claude-haiku-5-5",
max_tokens=4096,
system=f"You are a helpful agent.\n\n{skill}",
messages=[{"role": "user", "content": "Hello!"}],
)This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"
decimalai skills add a-attia-human-facing-doc-authoringfrom google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
from google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Hello!",
config=types.GenerateContentConfig(system_instruction=f"You are a helpful agent.\n\n{skill}"),
)This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openai
decimalai skills add a-attia-human-facing-doc-authoringfrom langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openaifrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
from langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
agent = create_agent("openai:gpt-5.4-mini", tools=[], system_prompt=f"You are a helpful agent.\n\n{skill}")
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 5 other files are not included.
CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"
decimalai skills add a-attia-human-facing-doc-authoringimport decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()The same install from Python, for a notebook or a setup script. CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()No DecimalAI package. CrewAI's own loader reads the folder, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdfrom pathlib import Path
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=[Path(".agents/skills")],
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"
decimalai skills add a-attia-human-facing-doc-authoringfrom decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
agent = LlmAgent(
name="support",
model="gemini-3.5-flash",
instruction=lambda context: f"You are a helpful agent.\n\n{skill}",
)This gets SKILL.md only. The skill's 5 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"
decimalai skills add a-attia-human-facing-doc-authoringfrom pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
from pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
agent = Agent("openai:gpt-4o-mini", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")This gets SKILL.md only. The skill's 5 other files are not included.
Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagents
decimalai skills add a-attia-human-facing-doc-authoringimport decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
The same install from Python, for a notebook or a setup script. Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
agent = create_deep_agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 5 other files are not included.
Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-framework
decimalai skills add a-attia-human-facing-doc-authoringimport asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
The same install from Python, for a notebook or a setup script. Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-frameworkfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
agent = Agent(client=client, instructions=f"You are a helpful agent.\n\n{skill}")
asyncio.run(agent.run("Hello!"))This gets SKILL.md only. The skill's 5 other files are not included.
Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agents
decimalai skills add a-attia-human-facing-doc-authoringfrom decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
The same install from Python, for a notebook or a setup script. Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("a-attia-human-facing-doc-authoring")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/a-attia-human-facing-doc-authoring/SKILL.md").read_text()
agent = Agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent("Hello!")This gets SKILL.md only. The skill's 5 other files are not included.
Adds every file the skill has, pinned so you can update it. Cursor, Copilot, Cline and Warp read this folder by themselves.
pip install "decimalai>=0.15"
decimalai skills add a-attia-human-facing-doc-authoringNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/a-attia-human-facing-doc-authoring/SKILL.md https://app.decimal.ai/s/a-attia-human-facing-doc-authoring/SKILL.md.agents/skills/a-attia-human-facing-doc-authoring/SKILL.mdThis gets SKILL.md only. The skill's 5 other files are not included.
Give its text to your model as instructions. No account or package needed.
This gets SKILL.md only. The skill's 5 other files are not included.
Raw files: /s/a-attia-human-facing-doc-authoring/SKILL.md · /s/a-attia-human-facing-doc-authoring.json
Fetch the file and give its text to your model as instructions. No account or package needed.
curl -fsSL https://app.decimal.ai/s/a-attia-human-facing-doc-authoring/SKILL.mdcurl -fsSL https://app.decimal.ai/s/a-attia-human-facing-doc-authoring.jsonThis gets SKILL.md only. The skill's 5 other files are not included.
You don't need a DecimalAI account.
Saved prompts and skills, pinned versions, and traces of this skill in your runs. DecimalAI does not run your agent.
Claude Code reads files from your project, so DecimalAI config does not apply there.
On Claude Agent SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI Agents: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Anthropic: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Gemini API: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On LangChain: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On CrewAI: set DECIMAL_API_KEY and add decimalai.init(crewai=True) to record runs and skill use. The skill version stays in your repo.
On Google ADK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Pydantic AI: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Deep Agents: set DECIMAL_API_KEY and add decimalai.init(langchain=True) to record runs and skill use. The skill version stays in your repo.
On Microsoft Agent Framework: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
On Strands: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
Editors read files from your project, so DecimalAI config does not apply there.
Anywhere else: record a use with decimalai.log_skill_activation() inside a trace.
Load this skill whenever the agent is about to produce or substantially revise a document whose primary audience is a human -- not the agent itself, not a downstream tool. In this ecosystem that includes (non-exhaustive list):
README.md -- top-level human-facing entry point for any project.PLAN.md -- plan-of-record / contract; both humans and agents read.notes/survey_<citekey>.md -- per-paper survey notes; the user reads
these when drafting paper sections and when re-orienting after time
away.references/_collection_log.md -- bibliography verification audit
trail; the user (and reviewers) read this.notes/section_<N>.md -- per-paper-section research notes; the user
reads them while drafting the section.notes/impl_<component>.md -- per-component implementation plans;
the user reads them before greenlighting code.For talk decks and posters, load research-slides-authoring as well;
this skill's prose conventions still apply to slide text.
Always load this skill before generating any of the above. Other
skills (literature-survey, research-paper-writing) cross-reference
this one for the structural + stylistic conventions they share.
Do NOT load this skill for:
AGENTS.md files -- those have the opposite audience
(agents). They should be telegraphic and structured, not narrative.SKILL.md files -- those are agent-facing.Every project in this ecosystem keeps two parallel entry-point documents with explicitly different audiences:
| File | Audience | Tone |
|---|---|---|
AGENTS.md | AI coding agents | Telegraphic, structured, machine-parseable. |
README.md | Human collaborators | Narrative, indexed, designed to be SCANNED. |
The same split generalises to every other document the agent produces:
| Document type | Primary audience | Tone |
|---|---|---|
README.md | New + returning humans | Narrative, two-tier, scannable. |
PLAN.md | Maintainer + co-authors | Structured prose; sectioned; living. |
notes/survey_<citekey>.md | Paper authors | Compact prose + equations + tables. |
references/_collection_log.md | Maintainer + reviewers | Audit-trail tables; date-stamped. |
notes/section_<N>.md | Paper authors | Working notes; section-flavoured. |
notes/impl_<component>.md | Code authors | Design doc; trade-offs explicit. |
| Reviewer-response / rebuttal | Editors + reviewers | Direct; concession-and-concession-counter style. |
Critical: do NOT treat any of these as downstream renderings of
AGENTS.md. They have different jobs. AGENTS.md tells an agent what
to do; the documents above let a human read what the project IS, what
the plan IS, what is known, what is decided.
A well-written human-facing doc should:
These rules apply regardless of doc type. Per-doc-type structure goes
in the references/<doc-type>-structures.md files loaded on demand.
For docs read by both impatient and thorough readers (README.md,
PLAN.md, longer survey notes), use a Quick Start / Headline
section near the top with the 30-second version, then deeper sections
for the 5-minute reader. Cross-reference between the two so the reader
can choose their depth.
For shorter docs (a single survey note, a single section note), the two-tier rule reduces to: open with a one-sentence headline, then expand.
#, ##, ###). No Setext-style underlines.###. If you need ####, the section needs to be
split.# per document (the title). Top-level sections are ##.[PLAN.md](PLAN.md)), not absolute URLs.path/to/file:line_number so the reader can navigate
directly.Prefer tables when:
Prefer prose when:
Prefer annotated bullet lists (one item per line, with -- or :
explaining each) when items are short labels with one-line definitions.
For repository or directory layouts, use a Unicode-box-drawing tree with brief inline annotations:
project-name/
├── AGENTS.md entry point for AI agents
├── README.md you are here
└── src/ source code
Avoid plain ---bulleted lists for layout; the tree shape conveys
nesting visually and is far easier to scan.
bash, python, text, ...).<...> placeholders for values the reader must substitute.
Comment what to substitute on the line above when not obvious.From a real gap (2026-09). A sources/README.md described an
archive of 32 binary STL solids: what each file was, where it came from, what
it did not contain. It never said how to read any of them. Answering that
question took four commands, all obvious to whoever had just done the survey,
none written down.
The format that is obvious the week it arrives will not be six months later. By then the reader is a new collaborator, or the same person with no memory of the header layout, and the cheapest route becomes asking a hosted model how to parse a binary STL. That is a network round trip for something that belongs in the repository.
So: when a document describes an artifact a reader may need to open, give the literal invocation. Not a link to a viewer, not "use a mesh library", not a tool that has to be located first.
| Artifact | What the document owes the reader |
|---|---|
| An archive | The unzip -l line to look inside, and the -d line to unpack. Say where to unpack, and that it is not into the repository |
| A PDF | The extraction command, and which of the two to read |
| A binary format | The few lines that parse it, with an assertion that fails on a malformed file rather than producing plausible nonsense |
| A database | The sqlite3 .schema line, or equivalent |
A plain .md beside another .md | Nothing. Scope this to things that need a tool |
The test is offline-first: every instruction should be runnable by someone with a clone, a shell, and no internet. Two reasons, and the second is growing. A facility network may not permit the lookup at all. And a local assistant reading these files can only follow instructions that are present: a document written to need an internet lookup is one such a model cannot act on.
Run the commands before committing them. A command that was typed from memory into a README is a claim, and it fails for the reader rather than for the author.
$...$ inline,
$$...$$ display) for any equation or symbol.x^2 + y^2); it is harder to scan and
harder to copy.These are not errors. The sentence is correct, the document is useful, and a reader simply trusts it slightly less. They survive review because the author reads past them, and they return with every new draft.
| Habit | Instead |
|---|---|
| A dash as punctuation, in any of its three forms | A comma, a colon, or a full stop |
| Two or more semicolons in one sentence | Sentences, or the list it already is |
| Sentences past about 30 words | Two sentences |
| "It is worth noting that", "It is important to" | Delete the phrase, state the thing |
| "Not merely X, but Y" and other escalations | Say what is true |
| Three-part lists where two items would do | Two items |
The dash is the most recognisable, and covers the ASCII double dash, the em dash, and the en dash equally.
Prefer a check to a habit. These recur, and the author is the last person to see them:
grep -nE ' -- |—|–' <doc> # dashes used as punctuation
grep -nE '[^;]*;[^;]*;' <doc> # two semicolons in one line
Exclude code blocks, tables, and quoted material before acting on the output: a dash inside a command or a citation is not prose.
No personal paths (/Users/<name>/, author-specific directory
conventions). Use generic placeholders (<projects-parent-dir>/...)
so the doc is publishable without per-author scrubbing.
No private identifiers in a doc that will be public. Project,
tool, collaborator, institution and venue names stay out of public
docs; describe them generically. This is root AGENTS.md Section 6.7,
and bin/privacy-scan.sh checks it mechanically.
No claims that are only true on the author's machine. This is the same defect as a personal path, one level up, and it is harder to spot because the sentence contains no path at all. "Built locally and benchmarked", "installed and working", a directory tree showing folders that exist only on one disk -- each reads as a project fact and is actually a fact about one filesystem. The author is the one reader for whom the sentence is guaranteed true, which is why self-review does not catch it.
The check: for every factual statement about the environment, ask
what a reader sees after git clone and nothing else. Then either
rewrite it as an instruction ("builds from the recipe in
external/README.md") or say whose machine it describes and why that
matters. Gitignored directories are the usual trap: they are present
and populated for the author, absent for everyone else.
A doc that quotes measured numbers should also say where they were measured, since performance figures are environment claims too.
No <TODO> / <INSERT> / <your-fork> placeholders that should
have been filled in (vs ones deliberately left for users to
substitute).
Date-stamp every plan-of-record-style doc (*Created YYYY-MM-DD. Revised YYYY-MM-DD (note). Maintained by <name>.*).
Human-facing docs accumulate cited facts -- file counts ("the skill ships 4 references"), line counts ("AGENTS.md is ~680 lines"), enumerations ("the three deferred items are X, Y, Z"), status labels ("F-03..F-08 -- shipped 2026-05-17"), commit SHAs, test counts, citation counts. These facts WILL drift as the underlying state changes; the doc that cites them becomes silently wrong.
The discipline:
SKILL.md" -- the table is the
single source of truth, and the reader who cares about the
exact count reads the table.... ships 4 references (as of 2026-05-17;
see [`SKILL.md`](SKILL.md) workflow table for current count).
The marker tells future readers (and future agents auditing the
doc) "this number may have drifted; check the source."STATUS.md, CHANGELOG.md, README.md "Current status" sections,
and per-skill SKILL.md footers are the most-frequent drift
sites.This rule was motivated by Session A's STATUS.md / CHANGELOG.md maintenance burden: every commit shifts counts that other docs cite, and without explicit self-invalidation markers the drift accumulates invisibly between sessions.
Subsection K (self-invalidation of cited facts) addresses drift WITHIN a single doc. This subsection L addresses the complementary failure mode: drift ACROSS docs. When a non-trivial change lands (a new skill ships, a new template ships, a count changes, a section gets renamed, a convention changes), DOWNSTREAM docs that reference the changed thing become silently stale unless the agent audits them explicitly. K + L together: K helps the next reader recognise stale content; L prevents the content from becoming stale in the first place.
The discipline: before committing any non-trivial change, run the following 3-step audit.
Classify the change as either trivial or non-trivial:
If you cannot quickly classify a change as trivial, treat it as non-trivial.
For ANY non-trivial change to this repo, the standard audit list is:
| Doc | Drift-prone content |
|---|---|
README.md | "What you get" inventory; status callout; repo-layout tree; "Feedback from real projects" categories; section dates. |
STATUS.md | Well-grounded / informed-prediction classification; evidence-count table; roadmap-condition progress. |
CHANGELOG.md | Per-session section; cross-references to commits. |
AGENTS.md | Section 5 skills index table; templates index table; Section 6 universal conventions when convention changes. |
Per-skill SKILL.md footers | "References shipped / planned" counts; date-stamp; cross-references between skills. |
| Per-template README.md | "What this template ships" inventory; placeholder lists. |
.github/ISSUE_TEMPLATE/*.md | "The four shipped skills are ..." or similar count-bearing prose. |
notes/agent_feedback.md (per project) | Cross-references to upstream commits / issues from prior entries. |
For ANY non-trivial change to a per-project repo using this framework, the standard audit list reduces to:
| Doc | Drift-prone content |
|---|---|
README.md | Status / current-version statements; "what this project is" headline; feature inventory. |
PLAN.md | Status section; milestone progress; "current phase" markers. |
AGENTS.md Project facts | Status, current phase, code dependencies (especially pinned versions). |
notes/README.md | Indexes of survey / impl / section notes. |
notes/_resolved/INDEX.md (if changed) | Entries table. |
notes/_archive/INDEX.md (if changed) | Entries table. |
For each doc on the relevant list:
The audit should be visible in the response to the user, NOT silent. Frame it as a checklist:
Downstream-doc audit (per F-20):
- README.md: status callout + What-you-get table updated [DONE]
- STATUS.md: evidence-count table + retirement-condition #4 updated [DONE]
- CHANGELOG.md: new section appended [DONE]
- AGENTS.md skills index: no change needed (this change doesn't add/remove a skill)
- per-skill SKILL.md footers: no change needed
- .github/ISSUE_TEMPLATE/: no change needed (no count change)
Without an explicit audit step, the agent treats each doc as
independent and only updates the one it's directly editing. Real
documentation systems are graphs, not trees: a change to one node
often shifts edges across many. The 2026-05-20 README.md gap
(STATUS callout still said 2026-05-14 + ZERO real research projects even after Session A + A.5 + 2 real projects) is the
existence proof: STATUS.md got updated; CHANGELOG.md got updated;
README.md was missed. F-20 prevents that miss.
project-onboarding skill's
references/scenario-2-existing-agentic-files.md Scenario 2.C
content-check pattern.CITATION.cff to the per-project list; a paper repo with
references/_collection_log.md might add it).When authoring or auditing a human-facing doc, ask of each piece of content: "who needs this and when?" Use the table to decide placement.
| Content | Goes in | Rationale |
|---|---|---|
| Project name, one-line description, scope | README.md | First thing a human visiting the repo sees. |
| "Where do AI agents start?" pointer | README.md | One callout block near the top. |
| Quick start / install / first-use commands | README.md | Humans need this; agents follow AGENTS.md instead. |
| Repository layout (annotated tree) | README.md | Helps humans orient. |
| Glossary / definitions / domain context | README.md (or docs/glossary.md) | Humans need; agents get domain facts from per-project AGENTS.md. |
| Contribution / extension instructions | README.md | Humans need; cross-reference AGENTS.md for skill-/template-author rules. |
| Provenance, licence, acknowledgements | README.md | Humans + standard repo hygiene. |
| List of which skills the agent should load | AGENTS.md | Agent-only directive. |
| Per-project facts (target venue, citation style, ...) | AGENTS.md | Agent-only; humans read these in PLAN.md if needed. |
| Plan-of-record / roadmap / experiment protocol | PLAN.md | The contract; both humans and agents read. |
| Headline contribution + positioning | PLAN.md (full); README.md (2-3 sentences) | Single source of truth in PLAN.md; README summarises + links. |
| Per-paper survey notes | notes/survey_<citekey>.md | One per reference; not user-facing index material. |
| Bibliography verification audit trail | references/_collection_log.md | Per-pass status + corrections. |
| Per-section research notes (working drafts of paper sections) | notes/section_<N>.md | Working docs. |
| Per-component implementation plans | notes/impl_<component>.md | Working docs. |
The structural skeletons + worked examples for each doc type live in
references/:
references/readme-structures.md -- README.md skeletons for paper /
software / skills-repo / rebuttal projects.references/plan-structures.md -- PLAN.md skeletons for paper /
software / experiment projects.references/notes-structures.md -- skeletons for survey_*.md,
section_*.md, impl_*.md.references/audit-log-structures.md -- skeleton for
_collection_log.md (bibliography) and other audit trails.Load only the file relevant to the current edit target.
When asked to author or rewrite a human-facing doc:
references/<doc-type>-structures.md for the skeleton.references/self-review-checklist.md.AGENTS.md,
PLAN.md, notes/, code docstrings) -- listing each move in the
response so the user can confirm.The authoring workflow above assumes a new doc. Rewriting an
existing substantial doc (a README, a PLAN.md, a long survey note,
a paper section in drafts/) is a distinct workflow with a higher
risk of silent content loss. A real onboarding session
(2026-05-14) surfaced this -- the agent rewrote a substantial
README during migration, and although nothing was lost, there was
no discipline forcing the agent to PROVE nothing was lost. This
section codifies the missing discipline.
The pattern is adapted from the project-onboarding skill's
project-onboarding/references/scenario-2-existing-agentic-files.md
Scenario 2.C content-check table -- which solves the same
problem for migrating an existing CLAUDE.md to a per-project
AGENTS.md. The pattern generalises to ANY substantial doc
rewrite.
Apply this workflow when the rewrite target is:
notes/section_*.md
cited by drafts/main.tex).Do NOT apply for: small docs (<50 lines, easy to eyeball); freshly- templated docs that haven't been customised; auto-generated docs (API reference, changelogs).
Inventory the existing doc (read-only). Output: a mental or
written enumeration of every distinct piece of content -- not just
sections, but every project-fact, every decision-rationale, every
cross-reference, every example. For very long docs, write this to
a temporary notes/_rewrite-inventory_<doc>_<date>.md so the
user can review.
Identify destinations. For each inventory item, decide:
Produce a content-check table before any writes. Format:
| Item | Original location | New destination | Status |
|:---|:---|:---|:---|
| Project codename rationale | README.md L52-56 | new README.md "Background" section | preserved |
| Old deployment instructions | README.md L120-180 | drops (deployment moved to docs/deploy.md) | dropped, reason: relocated |
| Personal-anecdote paragraph | README.md L201-215 | drops | dropped, reason: not appropriate for README |
| ... | ... | ... | ... |
Total inventory items in the original = total rows in the table. Every line in the original has a row OR is explicitly dropped with reason. NO silent omission.
Present the content-check table to the user. The user reviews + approves OR adjusts (especially the "Drop with reason" rows). Only then proceed to writes.
Execute the rewrite. After writing the new doc:
notes/_rewrite-inventory_<doc>_<date>.md
in the working tree for one commit cycle (the user may want to
consult it post-rewrite); then delete in a follow-up commit.The "rewrote a README + nothing was obviously lost" case is the silent failure mode. Without the content-check table, neither the agent nor the user can prove the negative ("we didn't lose anything"). The table makes the proof explicit + reviewable + auditable.
project-onboarding/references/scenario-2-existing-agentic-files.md
(Scenario 2.C "agent-file with substantive project content") --
which solves the same problem for the specific case of migrating
an existing agent-file to AGENTS.md. The general-purpose
doc-rewrite version is here.references/<doc-type>-structures.md
for the target structure.When the user asks the agent to produce a human-facing doc:
references/<doc-type>-structures.md.references/self-review-checklist.md.literature-survey skill produces notes/survey_<citekey>.md
and references/_collection_log.md. Both are human-facing; that
skill's output should follow this skill's conventions.
literature-survey cross-references this skill explicitly.research-paper-writing skill produces draft paper sections.
The drafts themselves are governed by paper-writing conventions
(paragraph clarity, claim-evidence alignment); but any meta-docs
it produces (a section-level research note, a paper README, a
rebuttal draft) are human-facing and follow this skill.references/readme-structures.md -- README.md skeletons.references/plan-structures.md -- PLAN.md skeletons.references/notes-structures.md -- skeletons for notes/*.md
(survey, section, impl).references/audit-log-structures.md -- skeleton for collection logs
and other audit trails.references/self-review-checklist.md -- self-review checklist for a
freshly-authored or revised human-facing doc.research-paper-writing skill -- different audience (paper
readers, not project visitors), but the paragraph-clarity check and
claim-evidence alignment principles transfer well.*Created 2026-05-13 by A. Attia (initially as project-readme-authoring).
Revised 2026-05-13: renamed to human-facing-doc-authoring and
generalised scope to cover all human-facing project documents (PLAN.md,
survey notes, collection logs, rebuttal drafts, ...) -- the
human/agent audience split is universal, not README-specific.
Revised 2026-05-17 (Session A): added "Rewriting an existing
substantial doc" section (F-02; ~80 lines after Authoring workflow)
\u2014 in grep -E matched the text "u2014", not the
dash); rule J points at root AGENTS.md Section 6.7 for private
identifiers; added "A document that describes a file must say how to
open it" (section G), from a project-local improvement made in 2026-09.*Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.