From 1979bf64f0435ccf974f935ceb5f1659d03420e7 Mon Sep 17 00:00:00 2001 From: REPPL <77722411+REPPL@users.noreply.github.com> Date: Sun, 12 Jul 2026 23:00:03 +0100 Subject: [PATCH 1/2] fix: relocate memory-lint + scanner runtime output out of .abcd/logbook (iss-73) .abcd/logbook/ is a retired runtime-output location (iss-36/iss-56). The 2026-07-12 maintainer adjudication placed runtime artefacts in the gitignored .abcd/.work.local/logs/ tier. Two Go sites still named the retired location: - memory lint wrote its report dir under .abcd/logbook/memory/ (lint.go) - the PII scanner's defaultSkipFragments referenced .abcd/logbook/pii-scan/ and .abcd/logbook/audit-history/ (scanner.go) Both now use .abcd/.work.local/logs/. No reader hardcoded the old path (memory lint returns ReportDir; the scanner uses the fragments only to skip its own output), so the relocation is transparent. The shipped plugin doc for the verb (commands/abcd/memory.md) is updated to the new report path (a correctness-review FIX-FIRST: it is a user-facing front door, not the deferred .abcd/development markdown). Detector-first: TestNoRetiredLogbookLocationInSource walks internal/ and fails if any non-test Go source names the retired 'logbook' location. Watched it flag both sites, then pass after the relocation. Purely-internal (gitignored runtime output, no committed/API surface), so no CHANGELOG entry. Arming the .abcd/logbook record-lint markdown ban (iss-36/ iss-56) is a separate follow-up: record-lint scans .abcd/development/**/*.md, where several research notes still reference the path (some historical, one current, plus an unimplemented publish spec) -- a markdown reconciliation pass out of scope here. Assisted-by: Claude:claude-opus-4-8 --- commands/abcd/memory.md | 2 +- .../adapter/scanner/retired_location_test.go | 45 +++++++++++++++++++ internal/adapter/scanner/scanner.go | 2 +- internal/core/memory/lint.go | 14 +++--- 4 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 internal/adapter/scanner/retired_location_test.go diff --git a/commands/abcd/memory.md b/commands/abcd/memory.md index 4e1319c3..b7a13503 100644 --- a/commands/abcd/memory.md +++ b/commands/abcd/memory.md @@ -60,7 +60,7 @@ abcd memory lint --json ``` It rebuilds the regenerable `.coverage_index.json` and writes a report under -`.abcd/logbook/memory/lint-/`. Summarise `summary.blockers` / +`.abcd/.work.local/logs/memory/lint-/`. Summarise `summary.blockers` / `summary.warnings` / `summary.infos` and each finding's `code` and `message`. Blockers exit nonzero; warn-only exits 0. diff --git a/internal/adapter/scanner/retired_location_test.go b/internal/adapter/scanner/retired_location_test.go new file mode 100644 index 00000000..74fe17dd --- /dev/null +++ b/internal/adapter/scanner/retired_location_test.go @@ -0,0 +1,45 @@ +package scanner + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +// TestNoRetiredLogbookLocationInSource is the iss-73 detector: `.abcd/logbook/` +// is a retired runtime-output location (iss-36/iss-56). A 2026-07-12 maintainer +// adjudication placed runtime artefacts in the gitignored `.abcd/.work.local/logs/` +// tier instead, so no non-test Go source under internal/ may name the retired +// `logbook` location — not memory's lint-report dir, not the scanner's skip +// fragments. It walks internal/ from this package (internal/adapter/scanner). +func TestNoRetiredLogbookLocationInSource(t *testing.T) { + internalRoot := filepath.Join("..", "..") // internal/adapter/scanner -> internal/ + var offenders []string + err := filepath.WalkDir(internalRoot, func(path string, d os.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() { + return nil + } + if !strings.HasSuffix(d.Name(), ".go") || strings.HasSuffix(d.Name(), "_test.go") { + return nil + } + data, err := os.ReadFile(path) + if err != nil { + return err + } + if strings.Contains(string(data), "logbook") { + offenders = append(offenders, path) + } + return nil + }) + if err != nil { + t.Fatalf("walk internal/: %v", err) + } + if len(offenders) > 0 { + t.Fatalf("retired '.abcd/logbook' location named in Go source (relocate to .abcd/.work.local/logs/):\n %s", + strings.Join(offenders, "\n ")) + } +} diff --git a/internal/adapter/scanner/scanner.go b/internal/adapter/scanner/scanner.go index c3b4f371..4e23fd29 100644 --- a/internal/adapter/scanner/scanner.go +++ b/internal/adapter/scanner/scanner.go @@ -79,7 +79,7 @@ var ( ".sqlite", ".db", ".lock", } defaultSkipFilenames = []string{".DS_Store", "Thumbs.db", ".gitignore"} - defaultSkipFragments = []string{".abcd/logbook/pii-scan/", ".abcd/logbook/audit-history/"} + defaultSkipFragments = []string{".abcd/.work.local/logs/pii-scan/", ".abcd/.work.local/logs/audit-history/"} repoConfigRelPath = filepath.Join(".abcd", "config", "pii.json") ) diff --git a/internal/core/memory/lint.go b/internal/core/memory/lint.go index 3d017b10..8f0d9405 100644 --- a/internal/core/memory/lint.go +++ b/internal/core/memory/lint.go @@ -13,7 +13,7 @@ import ( // lint.go — the `abcd memory lint` verb (fn-39): a full-store curator // health-check. Page-local checks (MS001/MS002/ML001/MQ001/MQ003) per typed // page, plus a corpus pass (MQ002 + per-source MQ003) that rebuilds the -// regenerable .coverage_index.json. Writes ONE logbook report; mutates no +// regenerable .coverage_index.json. Writes ONE run-log report; mutates no // memory-store state. Exit contract: blocker -> 1; warn/info/clean -> 0. // Finding is a single memory-lint finding. @@ -388,7 +388,7 @@ func runMemoryCoverageLint(repoRoot string) ([]Finding, map[string]any, error) { // Lint orchestration // --------------------------------------------------------------------------- -// Lint runs the full-store curator health-check and writes one logbook report. +// Lint runs the full-store curator health-check and writes one run-log report. // Mutates no memory-store state (only the regenerable coverage index + report). func Lint(req LintRequest) (LintResult, error) { root := req.RepoRoot @@ -484,18 +484,20 @@ func Lint(req LintRequest) (LintResult, error) { func lintReportDir(repoRoot string, now time.Time) (string, error) { ts := now.Format("20060102T150405.000000Z") - logbook := filepath.Join(repoRoot, ".abcd", "logbook", "memory") - base := filepath.Join(logbook, "lint-"+ts) + // Runtime artefacts live in the gitignored .abcd/.work.local/logs/ tier, not + // the retired runtime location (iss-36/iss-56 adjudication, iss-73). + logs := filepath.Join(repoRoot, ".abcd", ".work.local", "logs", "memory") + base := filepath.Join(logs, "lint-"+ts) if _, err := os.Stat(base); os.IsNotExist(err) { return base, nil } for n := 1; n < 1000; n++ { - candidate := filepath.Join(logbook, fmt.Sprintf("lint-%s-%03d", ts, n)) + candidate := filepath.Join(logs, fmt.Sprintf("lint-%s-%03d", ts, n)) if _, err := os.Stat(candidate); os.IsNotExist(err) { return candidate, nil } } - return "", fmt.Errorf("could not allocate a unique lint logbook dir for %s", ts) + return "", fmt.Errorf("could not allocate a unique lint run-log dir for %s", ts) } func findingsToMaps(findings []Finding) []any { From 2c3d32fa2645bcb98574c59980a2e6692d0e1e7c Mon Sep 17 00:00:00 2001 From: REPPL <77722411+REPPL@users.noreply.github.com> Date: Sun, 12 Jul 2026 23:03:28 +0100 Subject: [PATCH 2/2] chore(ledger): resolve iss-73 (logbook relocation) Assisted-by: Claude:claude-opus-4-8 --- ...locate-memory-lint-logbook-output-and-scanner-skip-paths-f.md | 1 + 1 file changed, 1 insertion(+) rename .abcd/work/issues/{open => resolved}/iss-73-relocate-memory-lint-logbook-output-and-scanner-skip-paths-f.md (78%) diff --git a/.abcd/work/issues/open/iss-73-relocate-memory-lint-logbook-output-and-scanner-skip-paths-f.md b/.abcd/work/issues/resolved/iss-73-relocate-memory-lint-logbook-output-and-scanner-skip-paths-f.md similarity index 78% rename from .abcd/work/issues/open/iss-73-relocate-memory-lint-logbook-output-and-scanner-skip-paths-f.md rename to .abcd/work/issues/resolved/iss-73-relocate-memory-lint-logbook-output-and-scanner-skip-paths-f.md index 1b4ea5f7..a9641944 100644 --- a/.abcd/work/issues/open/iss-73-relocate-memory-lint-logbook-output-and-scanner-skip-paths-f.md +++ b/.abcd/work/issues/resolved/iss-73-relocate-memory-lint-logbook-output-and-scanner-skip-paths-f.md @@ -7,6 +7,7 @@ category: "tech-debt" source: "user-observation" found_during: "abcd-run-design" found_at: "internal/core/memory/lint.go" +resolution: "relocated memory-lint report dir + scanner skip fragments from .abcd/logbook to .abcd/.work.local/logs; source-grep detector armed; plugin doc updated. Record-lint markdown ban-arming deferred (needs research-note reconciliation)" --- Relocate memory-lint logbook output and scanner skip-paths from .abcd/logbook/ (a retired location per iss-36) to .abcd/.work.local/logs/, the gitignored runtime-artefact tier. Maintainer adjudication of iss-56 (2026-07-12): runtime artefacts belong in .work.local/logs/, not a tracked dir. Sites: internal/core/memory/lint.go writes .abcd/logbook/memory/lint dirs; internal/adapter/scanner/scanner.go defaultSkipFragments references .abcd/logbook/pii-scan/ and audit-history/. Fix both plus tests; once the binary no longer writes there the .abcd/logbook retired-location ban (iss-36/iss-56) can be armed. Actionable fix behind iss-56 adjudication. \ No newline at end of file