Skip to content
4 changes: 4 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ jobs:
HOME="$tmp_home" ./install.sh --claude-user --only reduce-to-facts,clear-ask
test -f "$tmp_home/.claude/skills/reduce-to-facts/SKILL.md"
test -f "$tmp_home/.claude/skills/clear-ask/SKILL.md"
grep -q "Portable Output Contract" "$tmp_home/.claude/skills/reduce-to-facts/SKILL.md"
grep -q "without new source support" "$tmp_home/.claude/skills/clear-ask/SKILL.md"
! grep -R -E '\.\./\.\./(references|templates)' "$tmp_home/.claude/skills"
HOME="$tmp_home" ./install.sh --claude-user --only reduce-to-facts,clear-ask
HOME="$tmp_home" ./install.sh --claude-user --only reduce-to-facts,clear-ask --dry-run

Expand All @@ -46,6 +49,7 @@ jobs:
./install.sh --codex-project "$tmp_project" --only status-update --include-templates
test -f "$tmp_project/.agents/skills/status-update/SKILL.md"
test -f "$tmp_project/docs/context-to-action-skills/templates/ACTIONS.md"
grep -q "Portable Output Contract" "$tmp_project/.agents/skills/status-update/SKILL.md"

tmp_home="$(mktemp -d)"
HOME="$tmp_home" ./install.sh --claude-user --only reduce-to-facts
Expand Down
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@
- `LLM.md` as a compact agent-readable guide to the repo.
- README front-door cleanup, including the routing table and compatibility/control matrix.
- A clearer repo-specific `AGENTS.md`.
- A portable output contract inside every installed skill.
- Validation that rejects skill links escaping the installed skill folder.

### Changed

- README sections were consolidated for faster scanning.
- The quickstart now asks users to choose one install target instead of running both installers.
- Downstream skills now accept fact ledgers or conversation-state records explicitly and preserve their source classifications.
- Optional template references no longer use repository-relative paths that break after installation.

### Notes
### Fixed

- This branch is documentation and productization only; skill behavior is unchanged.
- Installed skills no longer depend on `../../references` or `../../templates` paths that are absent from the installed layout.
- Assumptions, open questions, proposed actions, and stakeholder positions may not be promoted into facts, decisions, commitments, owners, or deadlines without new source support.
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ It is not a deterministic workflow engine, ticketing system, MCP server, or proj

The skills provide reusable instruction contracts and examples. They help an assistant preserve uncertainty, identify asks, surface owners, draft replies, and avoid unsafe action.

Each installed `SKILL.md` is self-contained: the critical uncertainty, handoff, and mutation rules travel with the skill folder rather than depending on repository-only links.

Slack threads, email chains, doc comments, tickets, and transcripts can all carry the same source state as a live meeting. Treat them as async collaboration: extract facts first, then move to the next clear action.

For machine-validated workflows, use the optional schemas and examples as a stricter handoff layer.
Expand All @@ -35,10 +37,24 @@ For machine-validated workflows, use the optional schemas and examples as a stri

No coding is required.

Clone the repo:

```sh
git clone https://github.com/tmusser/context-to-action-skills.git
cd context-to-action-skills
```

Then choose one install target.

Claude Code:

```sh
./install.sh --claude-user --only reduce-to-facts,clear-ask,decision-brief,follow-up-draft
```

Codex:

```sh
./install.sh --codex-user --only reduce-to-facts,clear-ask,decision-brief,follow-up-draft
```

Expand Down Expand Up @@ -115,9 +131,9 @@ Choose the mode that gives you the right control.
| Mode | What it uses | Default behavior | Validation confidence | Caveat |
| --- | --- | --- | --- | --- |
| Pasted-context mode | Pasted notes, transcripts, docs, or thread text | Read and draft from pasted source only | High | This is the primary validated usage pattern. |
| Claude/Cowork-style skills | Local `SKILL.md` files plus pasted context | Read and draft through the hosted skill pack | Medium | Validated mainly when used with pasted context; host UI behavior is outside this repo. |
| Codex install path | `install.sh` or copied skill folders | Places the same skill pack in Codex-friendly paths | Medium | Install layout is validated; host features are not. |
| Other assistants / manual prompt reuse | Copied `SKILL.md` text or pasted prompts | Same output contract when the host follows it | Low | Compatibility target, not a tested integration. |
| Claude/Cowork-style skills | Local self-contained `SKILL.md` files plus pasted context | Read and draft through the hosted skill pack | Medium | Validated mainly when used with pasted context; host UI behavior is outside this repo. |
| Codex install path | `install.sh` or copied skill folders | Places the same self-contained skill pack in Codex-friendly paths | Medium | Install layout is validated; host features are not. |
| Other assistants / manual prompt reuse | Copied `SKILL.md` text or skill folders | Same output contract when the host follows it | Low | Compatibility target, not a tested integration. |
| Connected-context mode | Approved tools the user explicitly authorizes | Reads only approved tools | Low | This repo does not grant connector access. |
| Action mode | Host tool invocation plus user approval | Mutates systems only when explicitly asked | Low | This repo provides guardrails, not mutation rights. |

Expand All @@ -133,7 +149,7 @@ Connector and action-mode behavior depends on the host assistant and the tools t

For why MCP stays out of scope for now, see [integration roadmap](docs/integration-roadmap.md).

Shared guidance for mixed-source inputs lives in [source-packet.md](references/source-packet.md).
Shared authoring guidance for mixed-source inputs lives in [source-packet.md](references/source-packet.md). The installed skills carry their critical output contract inline.

## Privacy and control

Expand Down
7 changes: 7 additions & 0 deletions references/shared-output-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,11 @@ Rules:
- Use the smallest useful output.
- Label assumptions.
- Preserve source gaps.
- Preserve source anchors and confidence labels when they are available.
- When consuming a fact ledger or conversation state, do not promote an
assumption, inference, open question, proposed action, or stakeholder position
into a fact, decision, commitment, owner, or deadline without new source support.
- If new source changes a classification, name the new source and explain the
change.
- Keep unresolved approvals, owners, timing, and blockers explicit in drafts.
- Do not send, publish, update tickets, create events, or mutate systems unless explicitly asked.
74 changes: 55 additions & 19 deletions scripts/validate_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@
]


PORTABLE_CONTRACT_PHRASES = [
"portable output contract",
"use the smallest useful output",
"label assumptions",
"preserve source gaps",
"source anchors",
"confidence labels",
"without new source support",
"do not send, publish, update tickets, create events, or mutate systems unless explicitly asked",
]


def fail(message: str) -> None:
print(f"FAIL: {message}", file=sys.stderr)
raise SystemExit(1)
Expand Down Expand Up @@ -99,6 +111,45 @@ def line_has_allowed_former_name(path: Path, line: str) -> bool:
return "Formerly ai-business-skills" in normalized or "Formerly ai-business-skills." in normalized


def resolve_link(source_file: Path, link: str) -> Path | None:
target = link.strip()
if not target:
return None
if target.startswith(("http://", "https://", "mailto:", "#")):
return None
if target.startswith("<") and target.endswith(">"):
target = target[1:-1]
target = target.split("#", 1)[0].split("?", 1)[0]
if not target:
return None
path = Path(target)
if path.is_absolute():
return path
return (source_file.parent / path).resolve()


def validate_skill_portability(skill_file: Path, skill_dir: Path, text: str) -> None:
lowered = text.lower()
for phrase in PORTABLE_CONTRACT_PHRASES:
if phrase not in lowered:
fail(f"{skill_file.relative_to(ROOT)} is missing portable contract phrase: {phrase}")

link_pattern = re.compile(r"\[[^\]]+\]\(([^)]+)\)")
skill_root = skill_dir.resolve()
for match in link_pattern.finditer(text):
link = match.group(1)
resolved = resolve_link(skill_file, link)
if resolved is None:
continue
if not resolved.is_relative_to(skill_root):
fail(
f"{skill_file.relative_to(ROOT)} has a non-portable relative link: {link}. "
"Installed skill folders must be self-contained."
)
if not resolved.exists():
fail(f"{skill_file.relative_to(ROOT)} has a broken local link: {link}")


def validate_repo_identity() -> None:
if not README.exists():
fail("README.md is missing")
Expand All @@ -125,6 +176,9 @@ def validate_repo_identity() -> None:
"use the smallest useful output",
"label assumptions",
"preserve source gaps",
"preserve source anchors and confidence labels",
"without new source support",
"keep unresolved approvals, owners, timing, and blockers explicit",
"do not send, publish, update tickets, create events, or mutate systems unless explicitly asked",
]
for phrase in shared_required:
Expand Down Expand Up @@ -152,8 +206,7 @@ def validate_repo_identity() -> None:
fail(f"{skill_file.relative_to(ROOT)} frontmatter name {name!r} does not match folder {skill_dir.name!r}")
if "Read before write" not in text:
fail(f"{skill_file.relative_to(ROOT)} is missing read-before-write guardrail")
if "shared-output-contract.md" not in text:
fail(f"{skill_file.relative_to(ROOT)} does not reference shared-output-contract.md")
validate_skill_portability(skill_file, skill_dir, text)

reduce_to_facts = SKILLS_DIR / "reduce-to-facts" / "SKILL.md"
reduce_text = read_text(reduce_to_facts)
Expand Down Expand Up @@ -207,23 +260,6 @@ def validate_readme() -> None:
fail(f"{template.relative_to(ROOT)} is missing the schema mapping note")


def resolve_link(source_file: Path, link: str) -> Path | None:
target = link.strip()
if not target:
return None
if target.startswith(("http://", "https://", "mailto:", "#")):
return None
if target.startswith("<") and target.endswith(">"):
target = target[1:-1]
target = target.split("#", 1)[0].split("?", 1)[0]
if not target:
return None
path = Path(target)
if path.is_absolute():
return path
return (source_file.parent / path).resolve()


def validate_markdown_links() -> None:
link_pattern = re.compile(r"\[[^\]]+\]\(([^)]+)\)")
for path in markdown_files():
Expand Down
16 changes: 13 additions & 3 deletions skills/brief-me/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Turn messy connected or pasted context into a short conversation-state brief the
- Hex or other data output
- Pasted notes
- Any combination of the above
- A `reduce-to-facts` ledger or conversation-state record

## Guardrails

Expand All @@ -37,9 +38,17 @@ Turn messy connected or pasted context into a short conversation-state brief the
- Do not dump raw transcript content by default.
- Keep the output workplace-user friendly.

## Shared Output Contract
## Portable Output Contract

See [shared-output-contract.md](../../references/shared-output-contract.md) for the common cross-skill output rules.
- Use only the useful subset of source-backed facts, assumptions, source gaps,
stakeholder sensitivities, potential misreads, and the suggested next action.
- Use the smallest useful output.
- Label assumptions and preserve source gaps, source anchors, and confidence labels.
- When consuming upstream state, do not promote an assumption, inference, open
question, proposed action, or stakeholder position into a fact, decision,
commitment, owner, or deadline without new source support.
- Keep unresolved approvals, owners, timing, and blockers explicit in the brief.
- Do not send, publish, update tickets, create events, or mutate systems unless explicitly asked.

## Output

Expand All @@ -53,7 +62,8 @@ See [shared-output-contract.md](../../references/shared-output-contract.md) for
- Suggested follow-ups
- Source gaps

When the user wants a fuller record, map the result into [CONVERSATION_STATE.md](../../templates/CONVERSATION_STATE.md).
When the user wants a fuller record, use the optional `CONVERSATION_STATE.md`
template from this pack when it is available.

## Success Standard

Expand Down
15 changes: 12 additions & 3 deletions skills/clear-ask/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Convert a fuzzy request, thread, or note into a direct ask someone can understan
- Meeting notes
- Project context
- Pasted workplace context
- A `reduce-to-facts` ledger or conversation-state record

## Guardrails

Expand All @@ -30,9 +31,17 @@ Convert a fuzzy request, thread, or note into a direct ask someone can understan
- Flag missing owner, timing, or decision context.
- Prefer the smallest useful ask.

## Shared Output Contract

See [shared-output-contract.md](../../references/shared-output-contract.md) for the common cross-skill output rules.
## Portable Output Contract

- Use only the useful subset of source-backed facts, assumptions, source gaps,
stakeholder sensitivities, potential misreads, and the suggested next action.
- Use the smallest useful output.
- Label assumptions and preserve source gaps, source anchors, and confidence labels.
- When consuming upstream state, do not promote an assumption, inference, open
question, proposed action, or stakeholder position into a fact, decision,
commitment, owner, or deadline without new source support.
- Keep unresolved approvals, owners, timing, and blockers explicit in the ask and draft.
- Do not send, publish, update tickets, create events, or mutate systems unless explicitly asked.

## Output

Expand Down
15 changes: 12 additions & 3 deletions skills/decision-brief/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Build a lightweight decision snapshot from mixed workplace context, ticket histo
- Ticket or project context
- Supporting evidence
- Hex or other data output
- A `reduce-to-facts` ledger or conversation-state record

## Guardrails

Expand All @@ -30,9 +31,17 @@ Build a lightweight decision snapshot from mixed workplace context, ticket histo
- Make trade-offs and reversal cost visible.
- Surface source gaps and uncertainty.

## Shared Output Contract

See [shared-output-contract.md](../../references/shared-output-contract.md) for the common cross-skill output rules.
## Portable Output Contract

- Use only the useful subset of source-backed facts, assumptions, source gaps,
stakeholder sensitivities, potential misreads, and the suggested next action.
- Use the smallest useful output.
- Label assumptions and preserve source gaps, source anchors, and confidence labels.
- When consuming upstream state, do not promote an assumption, inference, open
question, proposed action, or stakeholder position into a fact, decision,
commitment, owner, or deadline without new source support.
- Keep unresolved approvals, owners, timing, and blockers explicit in the recommendation.
- Do not send, publish, update tickets, create events, or mutate systems unless explicitly asked.

## Output

Expand Down
16 changes: 13 additions & 3 deletions skills/follow-up-draft/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Draft a concise follow-up that preserves the ask, owner, timing, context, and ne
- Open ask
- Project context
- Prior thread context
- A `reduce-to-facts` ledger or conversation-state record

## Guardrails

Expand All @@ -32,9 +33,17 @@ Draft a concise follow-up that preserves the ask, owner, timing, context, and ne
- Label assumptions or missing details.
- Keep the message concise and workplace-user friendly.

## Shared Output Contract
## Portable Output Contract

See [shared-output-contract.md](../../references/shared-output-contract.md) for the common cross-skill output rules.
- Use only the useful subset of source-backed facts, assumptions, source gaps,
stakeholder sensitivities, potential misreads, and the suggested next action.
- Use the smallest useful output.
- Label assumptions and preserve source gaps, source anchors, and confidence labels.
- When consuming upstream state, do not promote an assumption, inference, open
question, proposed action, or stakeholder position into a fact, decision,
commitment, owner, or deadline without new source support.
- Keep unresolved approvals, owners, timing, and blockers explicit or conditional in the draft.
- Do not send, publish, update tickets, create events, or mutate systems unless explicitly asked.

## Output

Expand All @@ -43,7 +52,8 @@ See [shared-output-contract.md](../../references/shared-output-contract.md) for
- Executive concise version
- Context note, when helpful

If the user wants a fuller record before drafting, map the source state into [CONVERSATION_STATE.md](../../templates/CONVERSATION_STATE.md).
If the user wants a fuller record before drafting, use the optional
`CONVERSATION_STATE.md` template from this pack when it is available.

## Success Standard

Expand Down
16 changes: 13 additions & 3 deletions skills/meeting-to-actions/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Turn meeting content into a compact action record without making the user reread
- Notes
- Agenda
- Related ticket or doc context when useful
- A `reduce-to-facts` ledger or conversation-state record

## Guardrails

Expand All @@ -36,9 +37,17 @@ Turn meeting content into a compact action record without making the user reread
- Surface missing owners, due dates, and unclear blockers.
- Do not dump raw transcript content by default.

## Shared Output Contract
## Portable Output Contract

See [shared-output-contract.md](../../references/shared-output-contract.md) for the common cross-skill output rules.
- Use only the useful subset of source-backed facts, assumptions, source gaps,
stakeholder sensitivities, potential misreads, and the suggested next action.
- Use the smallest useful output.
- Label assumptions and preserve source gaps, source anchors, and confidence labels.
- When consuming upstream state, do not promote an assumption, inference, open
question, proposed action, or stakeholder position into a fact, decision,
commitment, owner, or deadline without new source support.
- Keep unresolved approvals, owners, timing, and blockers explicit in the action record.
- Do not send, publish, update tickets, create events, or mutate systems unless explicitly asked.

## Output

Expand All @@ -50,7 +59,8 @@ See [shared-output-contract.md](../../references/shared-output-contract.md) for
- Tickets/docs to update if applicable
- Source gaps

If the user wants a reusable record, map the result into [CONVERSATION_STATE.md](../../templates/CONVERSATION_STATE.md).
If the user wants a reusable record, use the optional `CONVERSATION_STATE.md`
template from this pack when it is available.

## Success Standard

Expand Down
Loading
Loading