Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ $EDITOR .sdlc/config.md # build, test, lint, run, e2e,
logs/ 모든 PASS·FAIL 뒤의 원본 출력, scripts/는 시나리오별 재실행 스크립트
```

끝난 기능은 `.sdlc/archive/`로 옮겨집니다. 검증된 사실은 `knowledge` 폴더로
끝난 기능은 `.sdlc/archive/`로 옮겨집니다. 검증된 사실은 `memory` 폴더로
옮기고, 다음 기능의 scout가 그 폴더부터 읽습니다.

## 설정
Expand All @@ -94,9 +94,9 @@ $EDITOR .sdlc/config.md # build, test, lint, run, e2e,
`lint`, `run`, `e2e` 명령, 화면이나 API를 다룰 `qa` 도구, 선택 실행기 어댑터 `qa_runner`와
그 로그인 명령 `qa_session`, `human_gates`(기본값
`intent`, 모든 plan을 직접 승인하려면 `plan` 추가, 위험 플래그가 있는 plan은
설정과 상관없이 사람이 승인), `knowledge` 폴더, `repos`(리뷰가 묶을 저장소.
설정과 상관없이 사람이 승인), `memory` 폴더, `repos`(리뷰가 묶을 저장소.
프로젝트 루트 아래 저장소가 많으면 나열하거나 리뷰마다 `sdlc.sh review <slug> pass --repos "<경로> ..." "<메모>"`로 지정하고, 비우면 루트 아래 전부)입니다. `.sdlc/`는
`.git/info/exclude`로 git에서 빠집니다. 팀이 배운 것을 공유하려면 `knowledge:`를
`.git/info/exclude`로 git에서 빠집니다. 팀이 배운 것을 공유하려면 `memory:`를
git이 추적하는 폴더로 지정하세요.

`adapters/e2e/`가 그런 실행기 하나입니다. `qa_runner: e2e`이면 QA는 브라우저·모바일
Expand Down Expand Up @@ -138,7 +138,8 @@ v2는 새 계약입니다. 기록은 있던 자리에 그대로 남습니다.
- `lazymode`는 계속 읽힙니다. 0–1 → `human_gates: intent plan`, 2–3 → `intent`,
4 → 없음. 직접 정하려면 `human_gates:`를 쓰세요. `intent`, `plan`이 아닌
값은 둘 다로 처리합니다.
- `knowledge:`를 정하기 전까지 `.sdlc/memory/`를 knowledge 폴더로 읽습니다.
- v0처럼 `.sdlc/memory/`가 기본 memory 폴더입니다. 예전 `knowledge:` 줄도 폴더를
지정하고, 지정한 폴더가 아닌 기본 폴더가 있으면 `sdlc.sh`가 알립니다.
- `init.sh` → `sdlc.sh init`, `gates/status.sh --json`과 `tools/auto.sh next` →
`sdlc.sh status --json`과 `sdlc.sh next`(종료 코드 동일). spec.md, summary.md,
delivery.md, qa-guide.md, map.md, harvest, 검증 영수증, handoff, tripwire,
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,19 @@ always says what comes next.
```

Closed features move to `.sdlc/archive/`. Verified facts move to the
`knowledge` folder, which the next feature's scouts read first.
`memory` folder, which the next feature's scouts read first.

## Config

`.sdlc/config.md` is the only project-specific file: the `build`, `test`,
`lint`, `run` and `e2e` commands, the `qa` tool that drives screens or APIs,
an optional `qa_runner` adapter with its `qa_session` sign-in command,
`human_gates` (default `intent`; add `plan` to approve every plan yourself — a
plan with a risk flag always asks), the `knowledge` folder, and `repos` (the
plan with a risk flag always asks), the `memory` folder, and `repos` (the
repositories a review binds — list them when the project root holds many,
or name them per review with `sdlc.sh review <slug> pass --repos "<path> ..." "<note>"`;
empty means every one under it). `.sdlc/` stays
out of git through `.git/info/exclude`; point `knowledge:` at a tracked folder
out of git through `.git/info/exclude`; point `memory:` at a tracked folder
to share what the team learns.

`adapters/e2e/` is one such runner: with `qa_runner: e2e`, QA writes each
Expand Down Expand Up @@ -144,7 +144,8 @@ v2 is a new contract. Your records stay where they are.
- `lazymode` keeps working: 0–1 → `human_gates: intent plan`, 2–3 → `intent`,
4 → none. Write `human_gates:` to choose explicitly; a word other than
`intent` or `plan` means both.
- `.sdlc/memory/` is read as the knowledge folder until you set `knowledge:`.
- `.sdlc/memory/` is the default memory folder, as in v0; a `knowledge:` line still
names the folder, and `sdlc.sh` reports a default folder that is not it.
- `init.sh` → `sdlc.sh init`; `gates/status.sh --json` and `tools/auto.sh
next` → `sdlc.sh status --json` and `sdlc.sh next` (same exit codes).
spec.md, summary.md, delivery.md, qa-guide.md, map.md, harvest, verification
Expand Down
10 changes: 5 additions & 5 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ finds `.git`.
## Route a request

- A change or fix, and `.sdlc/` exists → `sdlc.sh new <slug>`, then phase 1.
- No `.sdlc/` yet → `sdlc.sh init` (`--knowledge <folder>` keeps knowledge
- No `.sdlc/` yet → `sdlc.sh init` (`--memory <folder>` keeps memory
elsewhere); fill `.sdlc/config.md` from the repo
(scripts, Makefile, CI) and run each command once; ask only what the repo
cannot show. Then phase 1.
Expand Down Expand Up @@ -78,15 +78,15 @@ finds `.git`.
`e2e`, `qa` (the tool that drives screens or APIs), `qa_runner` (an optional
adapter in `adapters/`, such as `e2e`) and `qa_session` (its sign-in command),
`human_gates` (default
`intent`), `knowledge` (the durable knowledge folder) and `repos` (the
`intent`), `memory` (older configs: `knowledge:`) and `repos` (the
repositories a review binds; empty means every one under the project root;
`review --repos` names them for one review).
Records are working
knowledge, not source: `init` keeps `.sdlc/` out of git through
`.git/info/exclude`, changing no tracked file. Closed features move
to `.sdlc/archive/<slug>/`. Scouts read `knowledge` first; Evidence adds what
was verified. Empty `knowledge:` is `.sdlc/memory` if present, else
`.sdlc/knowledge`, both local; name a tracked folder to share.
to `.sdlc/archive/<slug>/`. Scouts read `memory` first; Evidence adds what
was verified. The default `.sdlc/memory` stays on this machine; point
`memory:` at a tracked folder to share it.

## Automation

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.7.1
2.8.0
4 changes: 2 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ <h2 id="install-h" data-i18n="inst-h">For the person who sets it up</h2>
</li>
<li>
<span class="cmd">$EDITOR .sdlc/config.md</span>
<p class="note" data-i18n="st3-n">The only project-specific file: the <code>build</code>, <code>test</code>, <code>lint</code>, <code>run</code> and <code>e2e</code> commands, the <code>qa</code> tool, <code>human_gates</code> (default <code>intent</code>; add <code>plan</code> to approve every plan) and the <code>knowledge</code> folder.</p>
<p class="note" data-i18n="st3-n">The only project-specific file: the <code>build</code>, <code>test</code>, <code>lint</code>, <code>run</code> and <code>e2e</code> commands, the <code>qa</code> tool, <code>human_gates</code> (default <code>intent</code>; add <code>plan</code> to approve every plan) and the <code>memory</code> folder.</p>
</li>
</ol>
</div>
Expand Down Expand Up @@ -470,7 +470,7 @@ <h2 id="install-h" data-i18n="inst-h">For the person who sets it up</h2>
"inst-lede": '여기부터는 명령어를 씁니다. 세 단계면 프로젝트에 설치되며, 자세한 내용은 <a href="https://github.com/cskwork/sdlc-kit/blob/main/README.ko.md#빠른-시작">GitHub의 README</a>에 있습니다. 그다음에는 평소 말로 변경을 요청하면 됩니다.',
"st1-n": '컴퓨터마다 한 번. 두 번째 줄은 Claude Code 기준이며, 쓰는 도구의 스킬 폴더에 연결하세요. 스킬 폴더가 없으면 <code>AGENTS.md</code>, <code>CLAUDE.md</code>, <code>GEMINI.md</code> 중 해당 파일에 <code>For SDLC work, read ~/sdlc-kit/SKILL.md and follow it.</code>을 넣으세요.',
"st2-n": '프로젝트마다, 또는 모노레포의 배포 단위마다 한 번. <code>.sdlc/</code> 폴더를 만들며 git은 이 폴더를 무시합니다. Windows에서는 <code>sdlc.sh</code>를 Git Bash나 WSL에서 실행하세요.',
"st3-n": '프로젝트마다 다른 값은 이 파일 한 곳에만 둡니다. <code>build</code>, <code>test</code>, <code>lint</code>, <code>run</code>, <code>e2e</code> 명령, <code>qa</code> 도구, <code>human_gates</code>(기본값 <code>intent</code>, 모든 계획을 직접 승인하려면 <code>plan</code> 추가), <code>knowledge</code> 폴더입니다.',
"st3-n": '프로젝트마다 다른 값은 이 파일 한 곳에만 둡니다. <code>build</code>, <code>test</code>, <code>lint</code>, <code>run</code>, <code>e2e</code> 명령, <code>qa</code> 도구, <code>human_gates</code>(기본값 <code>intent</code>, 모든 계획을 직접 승인하려면 <code>plan</code> 추가), <code>memory</code> 폴더입니다.',
"foot-p": 'sdlc-kit은 Anthropic이 공개한 안내서를 바탕으로 만든 독립 프로젝트로, Anthropic과는 관계가 없습니다.',
"foot-gh": 'GitHub에서 보기',
"foot-pb": 'Anthropic의 안내서'
Expand Down
21 changes: 0 additions & 21 deletions log/changelog-v2.7.1.md

This file was deleted.

52 changes: 52 additions & 0 deletions log/changelog-v2.8.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# v2.8.0 — one memory folder

The durable folder scouts read first and Evidence writes to has one name
again: `memory`, the folder v0 stores already have. A default folder that is
not the configured one is now reported instead of silently ignored. Also, a
bug fix keeps its failing run in `logs/`. (v2.7.1 went to `dev` only and is
folded in here.)

## Why

- **Two names hid a store's knowledge.** v2 called the folder `knowledge`
and defaulted to `.sdlc/knowledge`, reading `.sdlc/memory` only when
config.md had no value. One v0 store had its config.md rewritten from the
template, which wrote `knowledge: .sdlc/knowledge`. Its 36 pages in
`.sdlc/memory` stopped reaching scouts for a week, nothing said so, and
Evidence wrote six new pages into `.sdlc/knowledge` next to them instead of
updating them.
- Run on that store's layout, v2.7.0 prints nothing; this release prints
`sdlc: .sdlc/memory is not the memory folder (.sdlc/knowledge): move its
pages there or name it in config.md memory:`.

## Changes

- **`memory` everywhere.** SKILL.md, the phases, the scout role, the
template, the READMEs and the site say `memory`. config.md's key is
`memory:`, its template value `.sdlc/memory`, and `init --memory <path>`
replaces `init --knowledge <path>`. An empty or missing value means
`.sdlc/memory` for every store, new or from v0.
- **Older configs keep working.** A `knowledge:` line is still read when
there is no `memory:` line, and SKILL.md tells agents so, so a store that
names `.sdlc/knowledge` keeps using it.
- **A stray default folder is reported.** On every command, `sdlc.sh` prints
one line for `.sdlc/memory` or `.sdlc/knowledge` when it exists and is not
the configured folder. The selftest drives this (126 checks): init's
default, an older `knowledge:` line, and a stray folder of either name.
- **A bug fix keeps its failing run.** Build's bug-fix rule keeps the
regression test's failing output in `logs/`, where the v2.7.0 reviewer
looks for it. A blocking review finding fixed as a bug fix inherits this.

## Compatibility

- `init --knowledge` is refused with the usage line; use `--memory`.
- A store with no memory line and a `.sdlc/knowledge` folder now uses
`.sdlc/memory` and is told about `.sdlc/knowledge` on every command: move
its pages to `.sdlc/memory`, or add `memory: .sdlc/knowledge`.
- To move a store that names `.sdlc/knowledge` to the one name: move the
folder's pages to `.sdlc/memory` and change the line to
`memory: .sdlc/memory`.

## Known limits

- The word budget is unchanged: the plan load stays at 2500 of 2500.
2 changes: 1 addition & 1 deletion phases/1-intent.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plans how to build it.
1. `sdlc.sh new <slug>`. Prefix the slug with the ticket key or the date
(`abc-123-fix-login`, `261012-fix-login`).
2. Read the request and its source (ticket, issue, pull request, document)
with its comments and links, and `knowledge` pages with the same words.
with its comments and links, and pages in the `memory` folder with the same words.
3. Fill `intent.md` (`templates/intent.md`):
- **Request** — the human's words, verbatim or a faithful excerpt.
- **Understood as** — the outcome, what is in and out of scope, and
Expand Down
2 changes: 1 addition & 1 deletion phases/2-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ enough that side effects are found here, before any code. Scouts write

## 1. Scout

`sdlc.sh check intent <slug>` must print GATE OPEN. Read the `knowledge`
`sdlc.sh check intent <slug>` must print GATE OPEN. Read the `memory`
folder and phase 1's `refs/` and `logs/` first: a fact they already give
with a source is not scouted again.
Dispatch one scout (`roles/scout.md`) per open question, in parallel, each
Expand Down
2 changes: 1 addition & 1 deletion phases/4-evidence.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ that checked it and its deciding output line. A changed policy is updated
where it is written in the same delivery, or its follow-up and owner go in
Delivery's `Policy:` line. Then:
- move verified facts from the refs (and `refs/learnings.md`, if any) into
`knowledge`: one place per fact, updating a page rather than adding a
the `memory` folder: one place per fact, updating a page rather than adding a
duplicate; a fact that rests on code ends with its file (path from the
project root) and the delivered commit of that file's repository, after
re-checking the fact there if the file changed since it was checked:
Expand Down
4 changes: 2 additions & 2 deletions roles/scout.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
Answer one question about the code and its data with evidence, in one file
under `refs/`. Change nothing else.

Inputs: the question, intent.md, the project root, the `knowledge` folder,
Inputs: the question, intent.md, the project root, the `memory` folder,
and config.md.

- Read `knowledge` first; cite what it already answers. Re-check, or mark
- Read `memory` first; cite what it already answers. Re-check, or mark
assumed, a cited code fact with no commit or whose file changed since (its
repository's `git log`).
- Trace from the entry the question names to the end: every caller in every
Expand Down
15 changes: 7 additions & 8 deletions sdlc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ err() { printf 'sdlc: %s\n' "$*" >&2; }
die() { err "$1"; exit "${2:-1}"; }
usage() {
cat <<'USAGE'
Usage: sdlc.sh init [--knowledge path] | new slug | status [slug] [--json]
Usage: sdlc.sh init [--memory path] | new slug | status [slug] [--json]
sdlc.sh next slug | check intent|plan slug
sdlc.sh approve intent|plan slug --human words|--agent review
sdlc.sh review slug pass|fail [--uncommitted] [--repos "path ..."] note
Expand Down Expand Up @@ -47,11 +47,10 @@ config() {
# An unknown word fails closed, as an unknown lazymode does.
gates=$(printf '%s' "$gates" | awk '{gsub(/,/," ");for(i=1;i<=NF;i++){v=tolower($i);if(v!="intent"&&v!="plan"){bad=$i;break}if(!seen[v]++)out=out (out==""?"":" ") v}}END{if(bad!="")print "!" bad;else print out}')
case "$gates" in '!'*) err "unknown human_gates value '${gates#!}' (write intent, plan, or leave it empty): the human approves intent and plan"; gates='intent plan';; esac
knowledge=$(value "$STORE/config.md" knowledge)
memory=$(value "$STORE/config.md" memory); [ -n "$memory" ] || memory=$(value "$STORE/config.md" knowledge)
bound=$(value "$STORE/config.md" repos); boundby='config repos:'
if [ -z "$knowledge" ]; then
if [ -d "$STORE/memory" ]; then knowledge=.sdlc/memory; else knowledge=.sdlc/knowledge; fi
fi
[ -n "$memory" ] || memory=.sdlc/memory
for d in memory knowledge; do [ ! -d "$STORE/$d" ] || [ ".sdlc/$d" = "$memory" ] || [ "$STORE/$d" -ef "$ROOT/$memory" ] || [ "$STORE/$d" -ef "$memory" ] || err ".sdlc/$d is not the memory folder ($memory): move its pages there or name it in config.md memory:"; done
}
human_gate() { case " $gates " in *" $1 "*) return 0;; *) return 1;; esac; }
find_store() {
Expand Down Expand Up @@ -422,14 +421,14 @@ case "$command" in
help) [ "$#" -eq 0 ] || die 'unexpected arguments' 2; usage; exit;;
--version) [ "$#" -eq 0 ] || die 'unexpected arguments' 2; cat "$KIT/VERSION"; exit;;
init)
custom=; if [ "$#" -gt 0 ]; then [ "$#" -eq 2 ] && [ "$1" = --knowledge ] && [ -n "$2" ] || die 'init [--knowledge path]' 2; custom=$2; fi
custom=; if [ "$#" -gt 0 ]; then [ "$#" -eq 2 ] && [ "$1" = --memory ] && [ -n "$2" ] || die 'init [--memory path]' 2; custom=$2; fi
if [ -f .sdlc/config.md ]; then printf 'Existing .sdlc/config.md left as is.\n'; exit; fi
mkdir -p .sdlc/work .sdlc/archive
tmp=$(mktemp .sdlc/config.md.XXXXXX)
awk -v kit="$KIT" -v k="$custom" '/^kit:/{print "kit: " kit;next}/^knowledge:/{if(k!=""){print "knowledge: " k;next}}{print}' "$KIT/templates/config.md" > "$tmp"
awk -v kit="$KIT" -v k="$custom" '/^kit:/{print "kit: " kit;next}/^memory:/{if(k!=""){print "memory: " k;next}}{print}' "$KIT/templates/config.md" > "$tmp"
mv "$tmp" .sdlc/config.md
ROOT=$PWD; STORE=$PWD/.sdlc; config
case "$knowledge" in /*|[A-Za-z]:*) :;; *) mkdir -p "$knowledge";; esac
case "$memory" in /*|[A-Za-z]:*) :;; *) mkdir -p "$memory";; esac
# Records stay out of git through the clone-local exclude list, so init never changes a tracked file.
if git rev-parse --is-inside-work-tree >/dev/null 2>&1 && ! git check-ignore -q .sdlc 2>/dev/null; then
exclude=$(git rev-parse --git-path info/exclude); mkdir -p "$(dirname "$exclude")"
Expand Down
4 changes: 2 additions & 2 deletions templates/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ qa_runner:
qa_session:
# gates a human approves: intent, plan. Plan also needs the human when PLAN.md raises a risk flag.
human_gates: intent
# durable knowledge: scouts read it first, Evidence adds verified facts to it; empty = .sdlc/memory if it exists (a store from v0), else .sdlc/knowledge
knowledge:
# durable memory: scouts read it first, Evidence adds verified facts to it (older configs call it knowledge:)
memory: .sdlc/memory
# repositories a review PASS binds: top folders, separated by spaces or commas, of repositories under the project root (relative, no spaces in a path), "." for the repository holding the root; empty = every repository under the root; review --repos replaces it for one review
repos:
Loading
Loading