One work log per bundle: the rule, the gate that enforces it, and the second log it came out of #57
No files matched your search
@@ -69,6 +69,13 @@ Documentation exists for ONE reason: **point of use**. A page earns its bytes on
|
|||||||
4. Always update the documentation when you've completed a task — and when updating means deleting a page or a paragraph, delete it.
|
4. Always update the documentation when you've completed a task — and when updating means deleting a page or a paragraph, delete it.
|
||||||
5. Compact the work log when necessary; a work log holds laws and incidents, never bookkeeping.
|
5. Compact the work log when necessary; a work log holds laws and incidents, never bookkeeping.
|
||||||
|
|
||||||
|
#### THE WORK LOG IS ONE FILE.
|
||||||
|
The work log is a single page in the knowledge base: `omp-docs/log.md` in this repo, or whichever change-log page the repo's docs index names. Write the entry when the change lands — in the same commit as the change — and read that page to recover where things stand before starting. It follows its own entry law: a dated entry is what changed plus the durable lesson, a few lines.
|
||||||
|
|
||||||
|
- NEVER create a second log: not per directory, not per project, feature, branch or run, not `NOTES.md` / `PROGRESS.md` / `STATUS.md` / `worklog/`, not a dated diary. Logging in fifty places is not logging — the entry is never where the next reader looks, and each copy re-dates the same event on its own authority. In `dank/command-center` the KB linter reports any `log.md` that is not the bundle root's.
|
||||||
|
- A log holds laws and incidents, never bookkeeping: no per-file inventories, no run-by-run numbers, no transcripts. A number in a log still has to pass the purpose test above.
|
||||||
|
- If a knowledge base has no log page, add one at its root and list it in the index. That is the fix — never a log somewhere else.
|
||||||
|
|
||||||
#### USE PROGRESSIVE DISCLOSURE.
|
#### USE PROGRESSIVE DISCLOSURE.
|
||||||
Always ensure that all produced documentation is laid out in files following WIKI conventions: start with a top level README.md index file that provides a brief, concise introduction to the item being documented, and then SPLIT OFF individual aspects, features, or arguments into their own interlinked pages so that future agents can read the documentation in a piecewise fashion, only taking in the details they need. Where relevant, crosslink any created documentation with other relevant documentation. This structure may also be nested, if necessary.
|
Always ensure that all produced documentation is laid out in files following WIKI conventions: start with a top level README.md index file that provides a brief, concise introduction to the item being documented, and then SPLIT OFF individual aspects, features, or arguments into their own interlinked pages so that future agents can read the documentation in a piecewise fashion, only taking in the details they need. Where relevant, crosslink any created documentation with other relevant documentation. This structure may also be nested, if necessary.
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,4 @@ These files define the structural conventions that govern the agent system itsel
|
|||||||
* [OMP Status Line Customization](statusline.md) — How presets, composer shapes, and segment arrays actually interact; the fleet's tuned bar. (moved from /pi/, 2026-10-19)
|
* [OMP Status Line Customization](statusline.md) — How presets, composer shapes, and segment arrays actually interact; the fleet's tuned bar. (moved from /pi/, 2026-10-19)
|
||||||
* [OMP Subagent Limits & Fan-out Policy](subagent-limits.md) — Live caps: concurrency 2, no nested spawns (the `maxRecursionDepth: 0` trap), per-endpoint in-flight ceilings, isolation policy. (moved from /pi/, 2026-10-19)
|
* [OMP Subagent Limits & Fan-out Policy](subagent-limits.md) — Live caps: concurrency 2, no nested spawns (the `maxRecursionDepth: 0` trap), per-endpoint in-flight ceilings, isolation policy. (moved from /pi/, 2026-10-19)
|
||||||
|
|
||||||
## Change Tracking
|
**Change log:** the bundle keeps exactly one, one level up — [Bundle Change Log](../log.md). A directory here never has its own.
|
||||||
|
|
||||||
* [Bundle Change Log](log.md) — Chronological update history.
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
type: changelog
|
|
||||||
title: Core Bundle Change Log
|
|
||||||
description: Change log for the core documentation directory — tracks migrations and structural changes.
|
|
||||||
tags:
|
|
||||||
- core
|
|
||||||
- changelog
|
|
||||||
- okf
|
|
||||||
timestamp: 2026-07-18
|
|
||||||
---
|
|
||||||
|
|
||||||
# Core Bundle Change Log
|
|
||||||
|
|
||||||
## 2026-07-18
|
|
||||||
- **Migration**: Converted `index.md` (root) to `core/index-doc.md` — moved root bundle index into core domain
|
|
||||||
- **Migration**: Converted `agents-md-format.md` (root) to `core/agents-md-format.md` — agents-md format belongs in core
|
|
||||||
- **Creation**: Established `core/` directory with `index.md` as the domain entry point
|
|
||||||
- **Creation**: This change log for tracking core directory modifications
|
|
||||||
|
|
||||||
## 2026-07-15
|
|
||||||
- **Initialization**: OKF v0.1 conversion of the entire docs bundle — frontmatter applied, structure established, first `log.md` entries created
|
|
||||||
@@ -16,6 +16,27 @@ lesson, a few lines. Full incident narratives are recoverable from git
|
|||||||
(`git log --follow omp-docs/log.md`); knowledge that outlives an entry lives
|
(`git log --follow omp-docs/log.md`); knowledge that outlives an entry lives
|
||||||
on its concept page, linked here. Never re-expand an entry in place.
|
on its concept page, linked here. Never re-expand an entry in place.
|
||||||
|
|
||||||
|
This page is the bundle's **only** work log: one file, at the root. Never start a
|
||||||
|
second one in a subdirectory or under another name — `scripts/kb-lint.sh` reports any
|
||||||
|
`log.md` that is not this one.
|
||||||
|
|
||||||
|
## 2026-10-20 — one work log per bundle
|
||||||
|
|
||||||
|
The bundle had two: this page and `core/log.md`, created "for tracking core
|
||||||
|
directory modifications" — two entries of pure migration bookkeeping (file moved,
|
||||||
|
directory created, log created), and a date for the OKF conversion that neither this
|
||||||
|
page nor git agrees with: 2026-07-15 there, 2026-01-15 here, while `git log` dates the
|
||||||
|
OKF rebuild 2026-08-28. `core/index.md` was still pointing readers at it, which is how
|
||||||
|
a stale page stays alive. Trashed to `omp-docs/core/.AGENTTRASH/log.md` — its content
|
||||||
|
is recoverable from git, which is the entire argument against a second log.
|
||||||
|
|
||||||
|
Laws, now written down in [references/okf-spec.md](references/okf-spec.md) and
|
||||||
|
[references/okf-maintenance.md](references/okf-maintenance.md), and gated: a bundle has
|
||||||
|
ONE work log, `log.md`, at its root, and `scripts/kb-lint.sh` reports any `log.md` that
|
||||||
|
is not the root's — so the sprawl that made logging useless once cannot restart
|
||||||
|
quietly. The agent-side duty is in `agent/APPEND_SYSTEM.md` § 1: log here, read here,
|
||||||
|
never start another.
|
||||||
|
|
||||||
## 2026-10-20 — two instruments rescued from `$HOME` script sediment
|
## 2026-10-20 — two instruments rescued from `$HOME` script sediment
|
||||||
|
|
||||||
`$HOME` had accumulated 123 loose scripts at its root (archived to
|
`$HOME` had accumulated 123 loose scripts at its root (archived to
|
||||||
|
|||||||
@@ -21,32 +21,46 @@ Knowledge bundles rot. It is the nature of knowledge to attract cobwebs, much li
|
|||||||
|
|
||||||
## Change Tracking with `log.md`
|
## Change Tracking with `log.md`
|
||||||
|
|
||||||
Every OKF bundle has a `log.md` file. It is not optional. It is the bundle's memory.
|
Every OKF bundle has a `log.md`, and it is the bundle's **only** work log: one file,
|
||||||
|
at the bundle root. A subdirectory never gets its own — not `core/log.md`, not
|
||||||
|
`notes.md`, not a per-project, per-branch or per-run diary. Sprawl is not caution:
|
||||||
|
with fifty logs the entry is never where the next agent looks, and each copy re-dates
|
||||||
|
the same event on its own authority. `scripts/kb-lint.sh` reports any `log.md` that is
|
||||||
|
not the root's.
|
||||||
|
|
||||||
**Format:** Date-grouped entries, newest first. One line per change with timestamp, file path, and what changed.
|
**Format:** one dated section per day, newest first; a few lines per change — what
|
||||||
|
happened, and the durable lesson. It is not a file manifest.
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Bundle Change Log
|
# Bundle Change Log
|
||||||
|
|
||||||
## 2026-01-15
|
## 2026-01-15 — the gate was reading the wrong files
|
||||||
- `/docs/ghostty.md` — Updated keybind table after v1.2 release
|
|
||||||
- `/docs/pi-permission-system/` — Added `policy.md` and `audit.md`
|
A gate that gets an empty file list reports success. Law: a check MUST fail closed;
|
||||||
- `/docs/index.md` — Synced with directory contents
|
a silently-passing gate is worse than none, because it buys the belief of safety.
|
||||||
|
Details: [secret gate](../tools/index.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
**Rules:**
|
**Rules:**
|
||||||
- **Newest entries first.** Putting old entries at the top inverts the timeline and makes it impossible to see what just happened.
|
- **Newest entries first.** Old entries at the top invert the timeline.
|
||||||
- **One line per change.** A single line is sufficient. The git history is there if someone wants the gory details.
|
- **What changed + the durable lesson, a few lines.** Full narratives are recoverable
|
||||||
- **Group by date.** Batch all changes from the same day together.
|
from git (`git log --follow log.md`); never re-expand one in place.
|
||||||
- **Always date-stamp the section.** Use `## YYYY-MM-DD`.
|
- **Laws and incidents, never bookkeeping.** No per-file inventories, no run-by-run
|
||||||
- **Mention `index.md` whenever you change a bundle.** If you added or removed a file, update the index and note it in the log.
|
numbers, no transcripts. Measured numbers still have to pass the purpose test.
|
||||||
|
- **Link, do not duplicate.** Knowledge that outlives the entry belongs on its concept
|
||||||
|
page; the entry points there.
|
||||||
|
- **One dated section per day** (`## YYYY-MM-DD`), and mention `index.md` whenever a
|
||||||
|
file is added or removed.
|
||||||
|
|
||||||
### Common Mistakes
|
### Common Mistakes
|
||||||
|
|
||||||
- ❌ Writing `"Updated ghostty.md"` — Updated it with what? Be specific.
|
- ❌ `Updated ghostty.md` — updated it with what, and what did it teach?
|
||||||
- ❌ Forgetting to write to `log.md` — This is the equivalent of doing surgery without keeping a record.
|
- ❌ Forgetting the entry — the change lands undocumented and the next agent rediscovers
|
||||||
- ❌ Using relative paths — Use absolute paths (`/docs/ghostty.md`).
|
the failure the hard way.
|
||||||
- ❌ Leaving stale entries from manual edits — The log is the single source of truth.
|
- ❌ Starting a second log in a subdirectory — the sprawl that makes logging useless.
|
||||||
|
- ❌ Invented absolute paths in links — links resolve relative to the page, and the
|
||||||
|
linter checks them.
|
||||||
|
- ❌ Re-expanding an old entry in place — the entry is a pointer; git is the transcript.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -84,6 +98,14 @@ OKF is built on the principle that a file is one concept.
|
|||||||
- ❌ Don't create a file called `misc.md` — `misc` is a graveyard, not a category.
|
- ❌ Don't create a file called `misc.md` — `misc` is a graveyard, not a category.
|
||||||
- ❌ Don't use `# Other` or `# Additional Notes` sections — these are taping things to the wall.
|
- ❌ Don't use `# Other` or `# Additional Notes` sections — these are taping things to the wall.
|
||||||
|
|
||||||
|
## Quarantine, Not Deletion
|
||||||
|
|
||||||
|
A page is never deleted outright: it moves to `.AGENTTRASH/` beside where it lived and
|
||||||
|
waits for a pruning session with Frank present. The quarantine is not part of the
|
||||||
|
bundle — `scripts/kb-lint.sh` and `scripts/kb-coverage.py` skip any path containing
|
||||||
|
`.AGENTTRASH`. That exemption is deliberate: a gate that goes green only once the
|
||||||
|
quarantined copy is gone is a gate that deletes history.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Auto-Generation Strategies
|
## Auto-Generation Strategies
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ An OKF knowledge bundle is a directory tree. Every concept is one file. The file
|
|||||||
```
|
```
|
||||||
my-bundle/
|
my-bundle/
|
||||||
├── index.md # Optional directory listing
|
├── index.md # Optional directory listing
|
||||||
├── log.md # Optional update history
|
├── log.md # The bundle's ONE update history — root only
|
||||||
├── concept-one.md # A concept at the root level
|
├── concept-one.md # A concept at the root level
|
||||||
└── subdirectory/
|
└── subdirectory/
|
||||||
├── index.md # Optional subdirectory listing
|
├── index.md # Optional subdirectory listing
|
||||||
@@ -55,7 +55,13 @@ my-bundle/
|
|||||||
| Filename | Purpose |
|
| Filename | Purpose |
|
||||||
|----------|---------|
|
|----------|---------|
|
||||||
| `index.md` | Directory listing for progressive disclosure |
|
| `index.md` | Directory listing for progressive disclosure |
|
||||||
| `log.md` | Chronological update history |
|
| `log.md` | Chronological update history — **exactly one, at the bundle root** |
|
||||||
|
|
||||||
|
**One work log per bundle.** `log.md` is reserved, and it is reserved for a single
|
||||||
|
file: the bundle root's. A subdirectory never keeps its own change log — a bundle
|
||||||
|
that logs in fifty places has no log, because the entry is never where the next
|
||||||
|
reader looks and every copy re-dates the same event. `scripts/kb-lint.sh` reports
|
||||||
|
any `log.md` that is not the root's.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+13
-1
@@ -4,7 +4,15 @@ import re, sys
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
kb = Path(sys.argv[1])
|
kb = Path(sys.argv[1])
|
||||||
issues = []
|
issues = []
|
||||||
dirs = sorted({p.parent for p in kb.rglob("*.md")})
|
|
||||||
|
|
||||||
|
def kept(p):
|
||||||
|
# `.AGENTTRASH/` is quarantine, not bundle content: a gate that flags it pushes an
|
||||||
|
# agent to delete a page that is only waiting for a pruning session with the operator.
|
||||||
|
return ".AGENTTRASH" not in p.parts
|
||||||
|
|
||||||
|
|
||||||
|
dirs = sorted({p.parent for p in kb.rglob("*.md") if kept(p)})
|
||||||
for d in dirs:
|
for d in dirs:
|
||||||
idx = d / "index.md"
|
idx = d / "index.md"
|
||||||
if not idx.is_file() and d != kb:
|
if not idx.is_file() and d != kb:
|
||||||
@@ -21,12 +29,16 @@ for d in dirs:
|
|||||||
# wikilinks too
|
# wikilinks too
|
||||||
wl_names = {m.group(1).strip().rsplit("/", 1)[-1] for m in re.finditer(r"\[\[([^\]|#]+)", text)}
|
wl_names = {m.group(1).strip().rsplit("/", 1)[-1] for m in re.finditer(r"\[\[([^\]|#]+)", text)}
|
||||||
for sib in sorted(d.iterdir()):
|
for sib in sorted(d.iterdir()):
|
||||||
|
if sib.name == ".AGENTTRASH":
|
||||||
|
continue
|
||||||
if sib.suffix != ".md" or sib.name == "index.md":
|
if sib.suffix != ".md" or sib.name == "index.md":
|
||||||
continue
|
continue
|
||||||
if sib.resolve() not in linked and sib.stem not in wl_names:
|
if sib.resolve() not in linked and sib.stem not in wl_names:
|
||||||
issues.append(f"{d.relative_to(kb)}/index.md: does not link {sib.name}")
|
issues.append(f"{d.relative_to(kb)}/index.md: does not link {sib.name}")
|
||||||
# subdirs of d linked as their index?
|
# subdirs of d linked as their index?
|
||||||
for sub in sorted(d.iterdir()):
|
for sub in sorted(d.iterdir()):
|
||||||
|
if sub.name == ".AGENTTRASH":
|
||||||
|
continue
|
||||||
if sub.is_dir() and (sub / "index.md").is_file():
|
if sub.is_dir() and (sub / "index.md").is_file():
|
||||||
subidx = (sub / "index.md").resolve()
|
subidx = (sub / "index.md").resolve()
|
||||||
dirref = sub.resolve()
|
dirref = sub.resolve()
|
||||||
|
|||||||
+22
-2
@@ -12,7 +12,15 @@ from pathlib import Path
|
|||||||
kb = Path(sys.argv[1])
|
kb = Path(sys.argv[1])
|
||||||
violations = []
|
violations = []
|
||||||
|
|
||||||
for p in sorted(kb.rglob("*.md")):
|
def pages():
|
||||||
|
"""Markdown pages that belong to the bundle. `.AGENTTRASH/` is a quarantine, not
|
||||||
|
content: linting a deleted-but-not-yet-pruned page would demand its destruction to
|
||||||
|
make the gate go green, which is the wrong incentive."""
|
||||||
|
for p in kb.rglob("*.md"):
|
||||||
|
if ".AGENTTRASH" not in p.parts:
|
||||||
|
yield p
|
||||||
|
|
||||||
|
for p in pages():
|
||||||
rel = p.relative_to(kb)
|
rel = p.relative_to(kb)
|
||||||
text = p.read_text(errors="replace")
|
text = p.read_text(errors="replace")
|
||||||
lines = text.splitlines()
|
lines = text.splitlines()
|
||||||
@@ -38,9 +46,21 @@ for p in sorted(kb.rglob("*.md")):
|
|||||||
if not isinstance(fm, dict) or not str(fm.get("type", "")).strip():
|
if not isinstance(fm, dict) or not str(fm.get("type", "")).strip():
|
||||||
violations.append(f"{rel}: frontmatter lacks required 'type:'")
|
violations.append(f"{rel}: frontmatter lacks required 'type:'")
|
||||||
|
|
||||||
|
|
||||||
|
# One work log per bundle, at the bundle root. A `log.md` is a reserved name, but
|
||||||
|
# reserved does not mean "allowed in every directory": per-directory logs are how a
|
||||||
|
# bundle ends up with fifty of them, the entry never where the next agent looks, and
|
||||||
|
# each copy dating the same event differently. A bundle with no log at all is left to
|
||||||
|
# the maintenance page to nag about; this gate's job is sprawl.
|
||||||
|
logs = sorted(str(p.relative_to(kb)) for p in pages() if p.name == "log.md")
|
||||||
|
if len(logs) > 1 or (logs and logs[0] != "log.md"):
|
||||||
|
violations.append(
|
||||||
|
"a bundle has one work log, log.md, at the bundle root; found: " + ", ".join(logs)
|
||||||
|
)
|
||||||
|
|
||||||
# link integrity: fenced code blocks hold example paths, not live links — strip first.
|
# link integrity: fenced code blocks hold example paths, not live links — strip first.
|
||||||
# Vendored spec is exempt: its example paths are illustrations, not live links.
|
# Vendored spec is exempt: its example paths are illustrations, not live links.
|
||||||
for p in sorted(kb.rglob("*.md")):
|
for p in pages():
|
||||||
if str(p.relative_to(kb)) == "references/okf-spec.md":
|
if str(p.relative_to(kb)) == "references/okf-spec.md":
|
||||||
continue
|
continue
|
||||||
text = re.sub(r"^```[^\n]*$^```[^\n]*$", "", p.read_text(errors="replace"), flags=re.M)
|
text = re.sub(r"^```[^\n]*$^```[^\n]*$", "", p.read_text(errors="replace"), flags=re.M)
|
||||||
|
|||||||
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 ]
|
[ "$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" {
|
@test "the shipped knowledge base itself is conformant" {
|
||||||
# The tests above exercise the linter against fixtures; nothing else in the
|
# 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
|
# suite ever points it at the real bundle, so a page added without frontmatter
|
||||||
|
|||||||
Reference in new issue
Block a user