Licensing of contributions
Fracta is source-available under FSL-1.1-ALv2. Contributions follow the inbound = outbound rule: by submitting a Pull Request, you license your contribution to the project (and to all downstream users) under the same FSL-1.1-ALv2 terms the project itself is released under. You retain copyright in the lines you author. The license you grant the project is broad — perpetual, royalty-free, sublicensable — and is sufficient for the project to continue under FSL indefinitely, including granting commercial licenses to third parties and the automatic Apache-2.0 conversion two years after each release. Practical mechanics:- The repo’s PR template auto-populates a licensing acknowledgement checkbox in every new PR. Maintainers will not merge PRs where this checkbox is unchecked.
- This is not a separate Contributor License Agreement — it’s the inbound = outbound rule made explicit at the point of submission.
- The full text of the contribution licensing terms lives in CONTRIBUTING.md at the repo root.
Project layout
| Directory | Purpose |
|---|---|
cmd/ | CLI commands (cobra) |
internal/ | All implementation packages |
internal/project/scaffolds/templates/{local,docker-compose,k8s}/ | Embedded scaffold sources for fracta init --scaffold <mode> — the files materialized into operator projects |
mcp-servers/ | Canonical MCP server catalog (fetched by fracta config mcp fetch; spec-43) |
strategies/ | Python DAG strategy runner |
internal/schema/embedfs/graph-schema/ | Knowledge graph node and edge schema (baked into the binary via //go:embed; resolved at runtime as embed://graph-schema/<family>) |
scripts/ | Helper scripts |
docs/ | This documentation |
deployment/ directory was removed in spec-43 Concern L. Its contents split two ways: the operator-facing scaffolds (Compose stack, K8s manifests, auth-helper templates) moved into the embedded templates at internal/project/scaffolds/templates/, and the MCP server catalog moved to mcp-servers/ at the repo root. Editing a scaffold template changes what fracta init writes; editing mcp-servers/<id>/server.yaml changes what fracta config mcp fetch distributes.
Build
Test
testdata/ is organized, when to use t.TempDir()) lives in CI and tests. Default to writing unit tests that exercise pure logic; reach for integration only when the behavior under test is the integration itself.
Code conventions
Logging
All logging goes throughinternal/fractalog:
slog.Info or slog.Default().With(...) — the handler is captured at call time, before config-driven AttachFile runs.
Errors
Wrap with%w and a package-scoped prefix so callers can errors.Is / errors.As upward and tracebacks read as a chain:
- Prefix with the package name, lowercase, followed by what the function was attempting. Reads top-down when nested:
cmd: config mcp add: mcpcatalog: load local catalog: open <path>: .... - Always
%w, never%vwhen wrapping.%vflattens the chain and breakserrors.Is. - Standard library only. No
pkg/errors, noerrors.Wrap. The standarderrorspackage andfmt.Errorfcover everything. - Sentinel errors for callers to match on. Declare as package-level
var ErrFoo = errors.New("mcpcatalog: foo"). Callers useerrors.Is(err, mcpcatalog.ErrFoo).
Package boundaries
internal/ is the implementation; only cmd/ and main.go may import the world. Within internal/, packages depend downward (orchestrator → host adapters → graph / state stores), never upward. If you find yourself wanting to import internal/orchestrator from a lower-level package, the type wants to live one level up.
Adding a feature
Fracta uses spec-first development. Feature specs live in a peer repo at../fracta-specs/. The pattern:
- Open or claim a spec number under
fracta-specs/N-feature-name/(kebab-case feature name). Numbers are sequential — check the directory listing for the next free integer. Completed specs are renameddone-N-feature-name/once their implementation ships. - Write the spec set:
research.md— gap analysis, prior art, constraints. Optional for tiny specs.spec.md— the design contract: goals, non-goals, architecture rules, the full CLI/config surface, breaking changes, risks.plan.md— execution sequencing: phases, concerns (lettered A, B, C…), dependencies.tasks.md— checkbox-style work breakdown referencing the plan’s concerns (e.g.J6 — implement add).
- Get the spec reviewed. The review gate is the spec document; coding starts after spec consensus, not before.
- Implement against the plan. Commit messages reference the concern (
cli: implement 'fracta config mcp add' (J6)).
done-* directory under fracta-specs/ for a worked example — done-43-config-mcp-server-management/ is recent and exercises the full pattern.
Pull requests
PR template and licensing checkbox
The repo’s PR template auto-populates when you open a Pull Request. It includes a required licensing-acknowledgement checkbox (see Licensing of contributions above). Maintainers will not merge a PR while that checkbox is unchecked. If your PR was opened in a way that bypassed the template, edit the PR description to include the checkbox line manually.Branch naming
No enforced convention. Use whatever helps you. The author’s preference is a short kebab-case slug (mcp-catalog-fetch, fix-codex-race); spec-driven work often uses the concern key (spec-43-j6-add).
Commit messages
Short, imperative, and prefixed with the area of the codebase touched. Look atgit log for the style — recent examples:
<area>: <imperative summary>in the subject line. Area is usually the package name or a recognized short tag (cli,docs,merge).- No conventional-commits prefixes (
feat:/fix:/ etc.). Domain prefixes are clearer for this codebase. - Reference the concern when working from a spec (
(J6),(K1-K3)). Future-you readinggit logwants the link back to the plan. - Body for the “why.” Subject is the “what.” Use the body for context that wouldn’t be obvious from the diff — design trade-offs, why this approach over an alternative, what won’t work and why.
Review process
PRs are reviewed before merge. Aim for a small, single-purpose PR — easier to review, easier to revert if something regresses. If a feature naturally spans many concerns (spec-43 had 13), split into a series of PRs that build on each other (merge: commits chain them on main).
CI must be green before merge. The pipeline is described in CI and tests. If CI fails for a flake (not a real regression), re-run the failed jobs — don’t force-merge.
What’s next
Adding a Runtime
How to onboard a new LLM CLI as a fracta host runtime.
Changelog
Notable changes to fracta.

