Skip to content

feat(cli): add /combo to distil a thread into a skill draft - #243

Merged
oratis merged 1 commit into
mainfrom
feat/combo-distill
Aug 8, 2026
Merged

feat(cli): add /combo to distil a thread into a skill draft#243
oratis merged 1 commit into
mainfrom
feat/combo-distill

Conversation

@oratis

@oratis oratis commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Summary

PR 6 of docs/FLOATBOAT_ADOPTION_PLAN.md §2.D — the plan's highest-value-per-line item, because the hard part already existed.

/combo                     # preview the draft
/combo my-name --write     # commit it to .deepcode/skills/<name>/SKILL.md

The skill system was already complete: loader, frontmatter schema, three source layers, overrides. What was missing was the generating end — every SKILL.md had to be hand-written up front, before anyone knew what the work would involve. Floatboat's insight is that automation should be extracted after the work; the moment you finish a task is the moment you understand it best.

allowed-tools is derived, not guessed

The draft lists exactly the tools the thread actually called.

This is the security angle Floatboat doesn't advertise. Hand-written skills are almost always broader than needed — a skill that only reads files ends up with Bash "just in case", because guessing generously is easier than auditing. Deriving from a real run gives least privilege for free.

Nothing is written until you've seen it

/combo previews and writes nothing; --write commits. A skill assembled from a transcript is a shareable artifact, so it gets read before it exists on disk. --write refuses to overwrite an existing skill.

Writing one is recorded on the governance timeline — creating a skill changes what future runs may do, which isn't an ordinary file edit.

Two filters on the way out

Filter Why
Credential-shaped values → [REDACTED] API keys, GitHub tokens, AWS key ids, JWTs, PEM keys, password:-style assignments
Paths the file contract denies reading → dropped A rule that stops at the tool call but not at the export isn't much of a rule — the filename alone leaks

Both report what was withheld (withheld: redacted API key) rather than leaving the user to guess.

Explicitly not built

Floatboat's Combo sits on a "Tacit Engine" that passively observes files, browser tabs, and system apps to model habits. /combo reads the current thread, only when you type it, and never aggregates across threads or runs in the background. The useful half of the idea needs no passive collection — which is the position docs/research/floatboat.md §7.2 took, now backed by the implementation.

Per the plan's open question, distillation is pure and offline. Model prose is optional; without it the deterministic body is a real draft, not a placeholder — the step sequence and touched files are exactly recoverable and are what a reader most needs.

Test plan

  • pnpm test1385 passed, 16 skipped (+28: 937 core, 237 cli)
  • pnpm typecheck · pnpm lint · pnpm format:check · pnpm build · node scripts/check-docs.mjs
Area Cases
Least privilege allowed-tools from actual calls; deduped; Bash absent when unused
Loader compatibility Frontmatter parsed by the real parseFrontmatter, not a regex — a draft the loader rejects is worthless
Redaction 5 secret shapes each redacted; withheld items named
Contract filtering .env dropped from paths and from the body; exclusion reported
Name safety ../../etc/passwdetc-passwd; no separator or .. survives, since the name becomes a directory
Fallbacks Empty thread; outside-workspace paths ignored; model prose still redacted
CLI Preview writes nothing; --write writes and logs governance; refuses overwrite; empty thread

Documentation

  • New docs/combo.md — why after-not-before, the derived allowed-tools argument, the preview/write split, both filters, and an explicit section on what this deliberately is not

Release notes label

  • release-notes:feature

Related

Plan §2.D (PR 6). Research: docs/research/floatboat.md §3.1(b) and §7.2.

🤖 Generated with Claude Code

The skill system was already complete — loader, frontmatter schema, three source
layers, overrides. What was missing was the generating end: every SKILL.md had
to be hand-written up front, before anyone knew what the work would involve.

Floatboat's insight is that automation should be extracted after the work, not
configured before it. The moment someone finishes a task is the moment they
understand it best.

The security angle Floatboat does not advertise: deriving `allowed-tools` from
what the thread actually called yields least privilege for free. Hand-written
skills are almost always broader than needed, because guessing generously is
easier than auditing.

`/combo` previews and writes nothing; `--write` commits. A skill assembled from
a transcript is a shareable artifact, so it gets read before it exists on disk.
Writing one lands on the governance timeline — creating a skill changes what
future runs may do.

Two filters on the way out. Credential-shaped values become [REDACTED], and
paths the file contract denies reading are dropped entirely: a rule that stops
at the tool call but not at the export is not much of a rule, since the filename
alone leaks. Both report what was withheld rather than leaving the user to
guess.

Distillation is pure and offline. Model prose is optional; without it the
deterministic body is a real draft rather than a placeholder, because the step
sequence and touched files are exactly recoverable and are what a reader needs.

Explicitly not built: Floatboat's Tacit Engine passively observes files, browser
tabs and system apps to model habits. /combo reads the current thread, only when
typed, and never aggregates across threads. The useful half of the idea needs no
passive collection.

Skill names are sanitized to a single path segment — the name becomes a
directory under .deepcode/skills/, so `../escape` must not survive.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@oratis
oratis merged commit d55d4c9 into main Aug 8, 2026
5 checks passed
@oratis
oratis deleted the feat/combo-distill branch August 8, 2026 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant