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
3 changes: 2 additions & 1 deletion README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ $EDITOR .sdlc/config.md # build, test, lint, run, e2e,
프로젝트마다 다른 값은 `.sdlc/config.md` 한 곳에만 둡니다. `build`, `test`,
`lint`, `run`, `e2e` 명령, 화면이나 API를 다룰 `qa` 도구, `human_gates`(기본값
`intent`, 모든 plan을 직접 승인하려면 `plan` 추가, 위험 플래그가 있는 plan은
설정과 상관없이 사람이 승인), `knowledge` 폴더입니다. `.sdlc/`는
설정과 상관없이 사람이 승인), `knowledge` 폴더, `repos`(리뷰가 묶을 저장소.
프로젝트 루트 아래 저장소가 많으면 나열하고, 비우면 루트 아래 전부)입니다. `.sdlc/`는
`.git/info/exclude`로 git에서 빠집니다. 팀이 배운 것을 공유하려면 `knowledge:`를
git이 추적하는 폴더로 지정하세요.

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ Closed features move to `.sdlc/archive/`. Verified facts move to the
`.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,
`human_gates` (default `intent`; add `plan` to approve every plan yourself — a
plan with a risk flag always asks), and the `knowledge` folder. `.sdlc/` stays
plan with a risk flag always asks), the `knowledge` folder, and `repos` (the
repositories a review binds — list them when the project root holds many;
empty means every one under it). `.sdlc/` stays
out of git through `.git/info/exclude`; point `knowledge:` at a tracked folder
to share what the team learns.

Expand Down
8 changes: 6 additions & 2 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ finds `.git`.
subagents, open a new session with only the role file and paths; if that
is impossible too, write `no independent review: <reason>` in the
artifact. Every dispatch states the goal, input paths, what it may write,
the config.md commands, the output format, and when to stop.
the config.md commands, the output format, and when to stop. A role that
cannot write the feature folder writes to a temporary folder and reports
its path; you copy the files in.
5. **Proof, not claims.** Every PASS cites what was run or observed and its
log. No environment to run it in is BLOCKED, never PASS; a unit test never
stands in for the real interface. A bug fix needs a test that fails before
Expand All @@ -74,7 +76,9 @@ finds `.git`.

`.sdlc/config.md` holds every project value: `build`, `test`, `lint`, `run`,
`e2e`, `qa` (the tool that drives screens or APIs), `human_gates` (default
`intent`) and `knowledge` (the durable knowledge folder). Records are working
`intent`), `knowledge` (the durable knowledge folder) and `repos` (the
repositories a review binds; empty means every one under the project root).
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
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.1.0
2.2.0
62 changes: 62 additions & 0 deletions log/changelog-v2.2.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# v2.2.0 — friction from a large monorepo

Six fixes from using the kit on a project root that holds hundreds of git
worktrees, where a human approves every commit.

## Changes

- **`repos:` in config.md.** A space-separated list of repository top
folders, relative to the project root (`.` for the repository holding the
root; no spaces inside a path), limits which repositories a review PASS
binds. Empty or absent binds every repository under the root, as before,
but `review` now also runs one `git status` per repository to find
uncommitted changes, so a root with many repositories is slower than in
v2.1.0: list them in `repos:` to bound it. On a root with hundreds of
worktrees the full scan took over 30 s per `review`. An entry that is not a
folder under the root (`../x`, or a symlink resolving outside it), not in a
repository, or a plain folder inside one is refused by name, and a Commit
outside the list says the list limited the review.
- **Review before commit.** `sdlc.sh review` on uncommitted changes binds the
PASS to each such repository's HEAD and the tree its working tree would
commit (untracked, unignored files included; the store and untracked
repositories nested inside it excluded, so a root full of worktrees is not
dirty and `review` prints no git warning per nested repository). `score`
then accepts, with no new round, a Commit that is or descends from that HEAD,
holds the reviewed tree inside its Commit path, and changes nothing outside
the path that the reviewed tree lacks. Anything else needs a new round:
reverting or stashing the change and scoring the reviewed HEAD itself, an
amended or rebased commit, or any other content. Only repositories named on
Commit lines are compared. Reviewing a commit works as before: uncommitted
changes outside every Commit path still do not block it. Renames count as
a deletion plus an addition, so an unreviewed rename outside the path is
refused too. The store stays out of the tree whether it is untracked,
ignored or partly tracked. If git cannot read the working tree (an
unreadable file, say), `review` prints one line saying why and binds HEAD
alone, as v2.1.0 did. The temporary index used for the tree is removed on
interrupt too.
- **Cell counts.** A Scenarios row in PLAN.md or a Results row in evidence.md
with more cells than its header is reported as `S1: row has 6 cells, header
has 5` instead of a misleading log error. A row with fewer cells (GFM allows
it, e.g. `| S1 | BLOCKED | | no env |`) reads as in v2.1.0. `\|` still
counts as text.
- **Repository paths.** A Commit or Delivered path that is not a folder under
the project root says so, quoted, with the line format
`<sha> <relative-path>`, instead of `repository missing`.
- **QA sandbox.** QA that cannot write the feature folder writes evidence.md
and `logs/` to a temporary folder and reports its path; the coordinator
copies them in (roles/qa.md, SKILL.md rule 4).
- **Real-use evidence in Intent.** Before logs, error records, reports or
metrics count as evidence, Intent checks their source shows real use, not
tests, automation or synthetic traffic.

Selftest adds eight regression groups (`repos`, `cells`, `paths`,
`uncommitted`, `nested`, `interrupt`, `scoped`, `fingerprint`); each fails
without its fix for the reported reason. `interrupt` and the unreadable-file
check in `fingerprint` skip on Git Bash, whose signals and permissions are
untested.

## Compatibility

Existing records stay valid. A review recorded by v2.1.0 binds HEADs as
before; a `.state` written by v2.2.0 for an uncommitted review stores
`<head>+<tree>` for that repository, which v2.1.0 cannot read as a match.
5 changes: 4 additions & 1 deletion phases/1-intent.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ risks in that understanding — confirmed before anyone explores deeply.
success criteria `O1..On`, each observable so a scenario can check it.
- **Risks in this intent** — ambiguity, a claim the code or data already
contradicts (with the evidence), a policy the request would change and
who owns it, work that needs authority (rule 3).
who owns it, work that needs authority (rule 3). Before logs, error
records, reports or metrics count as evidence, check their source (the
user, agent or job behind them) shows real use, not tests, automation
or synthetic traffic.
- **Blocking questions** — only those whose wrong answer changes what
gets built or leaves the authorized scope. Ask them one at a time and
record each answer in place as `— resolved: <answer, source>`. Other
Expand Down
22 changes: 16 additions & 6 deletions phases/3-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,22 @@ Changes:

Commit the change locally (the project's rules decide the message), then
dispatch the reviewer (`roles/reviewer.md`, diff mode) with intent.md,
PLAN.md, `refs/` and the commit. It appends a round to `review.md` ending in
`VERDICT: PASS` or `VERDICT: FAIL`. Record it with `sdlc.sh review <slug>
pass|fail "<one line>"`: the script reads the verdict of the newest round
(every recording needs a new one) and binds a PASS to the HEAD of every
repository under the project root. Code changed after a PASS needs a new
commit and a new round.
PLAN.md, `refs/` and the commit. Where every commit needs the human's
approval, review the uncommitted change instead. The reviewer appends a round
to `review.md` ending in `VERDICT: PASS` or `VERDICT: FAIL`. Record it with
`sdlc.sh review <slug> pass|fail "<one line>"`: the script reads the verdict
of the newest round (every recording needs a new one) and binds a PASS to the
HEAD of every repository under the project root (or in config `repos:`), and
to the working tree of any with uncommitted changes: tracked and untracked
files that are not ignored, leaving out the store and untracked repositories
nested inside it (if git cannot read that tree, the PASS binds HEAD alone
and says so). `score` and `close` compare only the repositories named on
evidence `Commit` lines. Each Commit must be the reviewed HEAD or descend
from it, hold the reviewed working tree inside its Commit path, and change
nothing outside that path that the reviewed tree does not hold; uncommitted
changes outside every Commit path do not count. Reverting or stashing the
change, amending or rebasing needs a new round, as does any code changed
after a PASS.
FAIL → fix the blocking findings, commit, review again. The third FAIL stops
the loop: show the human the trail; only `sdlc.sh approve plan <slug>
--human` resumes it. Then phase 4.
Expand Down
5 changes: 4 additions & 1 deletion roles/qa.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ Inputs: intent.md, PLAN.md, `refs/`, config.md, and the commit(s) to verify.
7. Each FAIL gets a cause, with evidence: `plan` if the plan was wrong or
missed something, `code` if the plan was right and the code is not.

Fill `evidence.md` from `templates/evidence.md` and stop. Signs you did not
Fill `evidence.md` from `templates/evidence.md` and stop. If the feature
folder is not writable from your sandbox (a symlink outside the allowed
roots, say), write `evidence.md` and `logs/` to a temporary folder and report
its path; the coordinator copies them in. Signs you did not
really run it: a PASS without a log, every scenario through one caller, a
write without read-back, a role checked only by being refused.

Expand Down
3 changes: 2 additions & 1 deletion roles/reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ Inputs: intent.md, PLAN.md, `refs/`. Blocking:

## Diff mode (phase 3)

Inputs: intent.md, PLAN.md, `refs/`, the commit. Read every changed file.
Inputs: intent.md, PLAN.md, `refs/`, the commit or uncommitted diff
(untracked files included). Read every changed file.
Blocking:
- it does not do what PLAN.md says, or does more;
- a side effect PLAN.md names is left unhandled; input that callers send
Expand Down
Loading
Loading