Merge pull request 'One work log per bundle: the rule, the gate that enforces it, and the second log it came out of' (#57) from docs/single-work-log-rule into main
This commit was merged in pull request #57.
This commit is contained in:
commit
ab94c91bcf
10 files changed
+187
-44
No files matched your search
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bats
|
||||
# tests/kb-coverage.bats — black-box tests for scripts/kb-coverage.py
|
||||
#
|
||||
# Contract: exit 0 when every directory of a knowledge bundle has an index.md and each
|
||||
# index links its siblings. Observable surface: stdout lines and exit status.
|
||||
|
||||
setup() {
|
||||
CHECK="$BATS_TEST_DIRNAME/../scripts/kb-coverage.py"
|
||||
KB="$(mktemp -d)/kb"
|
||||
mkdir -p "$KB/sub"
|
||||
printf '# Index\n\n* [Good](good.md)\n* [Sub](sub/)\n' > "$KB/index.md"
|
||||
printf '# Sub\n\n* [Deep](deep.md)\n' > "$KB/sub/index.md"
|
||||
printf 'body\n' > "$KB/good.md"
|
||||
printf 'body\n' > "$KB/sub/deep.md"
|
||||
}
|
||||
|
||||
teardown() { rm -rf "$(dirname "$KB")"; }
|
||||
|
||||
@test "a bundle whose directories index their contents passes" {
|
||||
run python3 "$CHECK" "$KB"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"0 issue(s)"* ]]
|
||||
}
|
||||
|
||||
@test "a directory nobody indexes is reported" {
|
||||
mkdir "$KB/stray"
|
||||
printf 'body\n' > "$KB/stray/thing.md"
|
||||
run python3 "$CHECK" "$KB"
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"stray: no index.md"* ]]
|
||||
}
|
||||
|
||||
@test "an index that forgets a sibling page is reported" {
|
||||
printf 'body\n' > "$KB/orphan.md"
|
||||
run python3 "$CHECK" "$KB"
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"does not link orphan.md"* ]]
|
||||
}
|
||||
|
||||
@test "the quarantine trash directory is not part of the bundle" {
|
||||
# Pages deleted from the KB wait in .AGENTTRASH/ for a pruning session with Frank.
|
||||
# Requiring an index there, or listing its contents, would push an agent to delete
|
||||
# the quarantined copy just to make the gate green.
|
||||
mkdir -p "$KB/.AGENTTRASH"
|
||||
printf 'retired page\n' > "$KB/.AGENTTRASH/old-page.md"
|
||||
run python3 "$CHECK" "$KB"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"0 issue(s)"* ]]
|
||||
}
|
||||
@@ -91,6 +91,35 @@ EOF
|
||||
[ "$status" -eq 2 ]
|
||||
}
|
||||
|
||||
@test "a second work log in a subdirectory is reported" {
|
||||
# One bundle, one work log. Per-directory logs are how a bundle ends up with fifty
|
||||
# of them: the entry is never where the next agent looks, and each copy re-dates the
|
||||
# same event on its own.
|
||||
printf -- '---\ntype: changelog\n---\n## 2026-01-01\n- created a log\n' > "$KB/log.md"
|
||||
printf -- '---\ntype: changelog\n---\n## 2026-01-02\n- also a log\n' > "$KB/sub/log.md"
|
||||
run bash "$LINT" "$KB"
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"one work log"*"at the bundle root"* ]]
|
||||
[[ "$output" == *"sub/log.md"* ]]
|
||||
}
|
||||
|
||||
@test "a work log that is not at the bundle root is reported" {
|
||||
printf -- '---\ntype: changelog\n---\n## 2026-01-02\n- misplaced log\n' > "$KB/sub/log.md"
|
||||
run bash "$LINT" "$KB"
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"one work log"*"at the bundle root"* ]]
|
||||
}
|
||||
|
||||
@test "the quarantine trash directory is not part of the bundle" {
|
||||
# Deleted pages wait in .AGENTTRASH/ for a pruning session with Frank. Holding them
|
||||
# to frontmatter and one-log rules would push an agent to delete history to go green.
|
||||
mkdir -p "$KB/.AGENTTRASH"
|
||||
printf 'no frontmatter, and a second log besides\n' > "$KB/.AGENTTRASH/log.md"
|
||||
run bash "$LINT" "$KB"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"0 violation(s)"* ]]
|
||||
}
|
||||
|
||||
@test "the shipped knowledge base itself is conformant" {
|
||||
# The tests above exercise the linter against fixtures; nothing else in the
|
||||
# suite ever points it at the real bundle, so a page added without frontmatter
|
||||
|
||||
Reference in new issue
Block a user