Commit all in-flight work — ckb-module and ckb-reset skills, the .agents/modules/ scaffold, OPENSPEC docs, decision records D-0001 and D-0002, graph edges and workload summaries — so the reset that follows is fully recoverable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
113 lines
5.7 KiB
Markdown
113 lines
5.7 KiB
Markdown
---
|
|
type: decision
|
|
tldr: The `software` module keeps code as gitignored plain clones in `src/`, runs OpenSpec at both KB-root and per-repo level with a hybrid vendor/depend split, and links the two spec levels with `implements`/`implemented_by`.
|
|
status: accepted
|
|
decided_on: 2026-09-20
|
|
decided_by: Michał Kopeć
|
|
affects: /wiki/decisions/0001-opt-in-file-based-kb-modules.md, /wiki/index.md
|
|
confidence: 0.85
|
|
quality: 0.8
|
|
last_updated: 2026-09-20
|
|
freshness_window_days: 365
|
|
retention: high
|
|
---
|
|
|
|
# D-0002 — Design of the opt-in `software` module
|
|
|
|
**Status:** Accepted · **Decided:** 2026-09-20 · **Deciders:** Michał Kopeć
|
|
|
|
## Context
|
|
|
|
Some knowledge bases document software the user is actively building. In that
|
|
case the source code lives in `src/`, usually as one or more *independent* git
|
|
repositories with their own remotes — a git repo inside a git repo. The user
|
|
also wants OpenSpec-driven iterative development available in that mode.
|
|
|
|
This is the first concrete module under
|
|
[[D-0001]] / [D-0001](/wiki/decisions/0001-opt-in-file-based-kb-modules.md),
|
|
and four sub-questions had to be settled: how code is hosted, where specs live,
|
|
whether OpenSpec's own workflow instructions are vendored or depended on, and
|
|
how two spec levels avoid becoming two sources of truth.
|
|
|
|
## Decision
|
|
|
|
**Code hosting.** `src/<repo>/` holds plain clones, gitignored (`src/*`, as
|
|
`libs/*` already is). No submodules. Because the code may be absent from a
|
|
fresh clone, each repo also gets a durable `type: repository` entity page in
|
|
`wiki/` recording its remote URL, default branch, language, build command,
|
|
`src/` path, and owner — that page, not the clone, is the durable artifact.
|
|
|
|
**`src/` is not a cascade layer.** It is primary evidence, like `raw/archive/`:
|
|
`ckb-retrieve` may open and cite it when verifying a claim, but it never answers
|
|
"what is entity X", and `ckb-ingest` does not treat code as inbox material.
|
|
|
|
**Spec location — both levels.** OpenSpec runs at the KB root (cross-cutting
|
|
capabilities spanning multiple `src/` repos) *and* inside each `src/<repo>/`
|
|
(implementation specs that travel with the code in its own repo).
|
|
|
|
**Vendoring — hybrid.** The KB-root spec layer is served by a module-owned
|
|
skill, because a KB-root `openspec/` is not a normal OpenSpec repo install (no
|
|
code beneath it, no single repo it governs) and the module must own instructions
|
|
for it regardless. The per-`src`-repo layer delegates to OpenSpec's own native
|
|
install and instructions, and the module reports plainly when OpenSpec is
|
|
missing rather than substituting its own workflow. The module additionally owns
|
|
the bridge in both directions: an archived OpenSpec change becomes a
|
|
`wiki/decisions/NNNN-*.md` record, and current specs sync into `type: spec`
|
|
entity pages.
|
|
|
|
**Drift rule.** KB-level specs state *what* and *why* across repos; `src`-level
|
|
specs state *how* a given repo implements it. The two are linked by
|
|
`implements:` / `implemented_by:` frontmatter, which becomes graph edges.
|
|
`ckb-lint` gains checks for KB-level specs with no implementer and `src`-level
|
|
specs whose parent was archived or superseded.
|
|
|
|
## Rationale
|
|
|
|
Gitignored clones avoid embedded-repo warnings and keep code out of KB history,
|
|
while each repo keeps pushing to its own origin; submodules would pin commits
|
|
that go stale against daily work in `src/`. Specs at both levels reflect a real
|
|
distinction — cross-repo contracts genuinely differ from per-repo implementation
|
|
— and the hybrid vendoring split follows from that same distinction rather than
|
|
splitting the difference: only the level OpenSpec doesn't natively serve is
|
|
owned locally. The `implements`/`implemented_by` link exists specifically so the
|
|
two-level arrangement produces a lint signal when the levels disagree, instead
|
|
of two silently divergent truths.
|
|
|
|
## Consequences
|
|
|
|
- `.gitignore` gains `src/*` rules.
|
|
- New frontmatter types `repository`, `component`, `spec`, and optional `repo:`,
|
|
`commit:`, `spec_id:`, `implements:`, `implemented_by:` fields — a
|
|
`kb_schema_version` bump to `1.5`, additive only.
|
|
- Module skills needed: a code-mapping skill (`src/<repo>` → entity pages, with
|
|
a recorded commit hash so staleness is detectable) and a KB-root OpenSpec +
|
|
bridge skill.
|
|
- `ckb-sync-changes` must never `git add` under `src/`, and should report each
|
|
`src/` repo's dirty/ahead state separately.
|
|
- `ckb-retrieve` gains code as a verification source; `ckb-lint` gains the src
|
|
and spec-drift checks; OKF and Starlight exports exclude `src/`.
|
|
- The module is unusable at the `src/` level until OpenSpec is installed
|
|
separately — it is not on PATH as of this decision.
|
|
|
|
## Alternatives considered
|
|
|
|
- **Git submodules for `src/`** — code travels with the KB and is pinned to a
|
|
commit, which is genuinely attractive for "what did the wiki describe at that
|
|
point". Rejected for submodule friction on every sync and pins going stale.
|
|
- **Specs only inside each `src/` repo** — OpenSpec's native case, nothing to
|
|
own locally, but no home for contracts spanning several repos.
|
|
- **Specs only at KB root** — one place to look, but specs stop travelling with
|
|
the code they govern and fall out of the repo's own PR flow.
|
|
- **Vendoring OpenSpec's workflow wholesale** — self-contained, works with
|
|
nothing installed, tailorable to KB conventions. Rejected: it means
|
|
maintaining a fork of an external workflow, and `ckb-upgrade` would have two
|
|
upstreams to track.
|
|
- **Depending on OpenSpec at both levels** — nothing to maintain, but leaves the
|
|
KB-root layer with no instructions at all, since OpenSpec doesn't serve that
|
|
case.
|
|
|
|
## Sources
|
|
|
|
Chat conversation, 2026-09-20 — design evaluation of a source-code/software KB
|
|
mode, including the user's explicit choices on mechanism, code hosting, spec
|
|
location, and vendoring. See `workload/2026-09-20_summary.md`.
|