Skip to content

report truth (Session C1): byDepth, domainCounts, changeDetection, docPathsUnknown + reconcile-docs (F-455, F-454, F-451, F-459; plugin 0.40.0) - #20

Merged
BradleyDB merged 10 commits into
devfrom
round-c1-report-truth
Sep 15, 2026
Merged

BradleyDB merged 10 commits into
devfrom
round-c1-report-truth

Conversation

@BradleyDB

Copy link
Copy Markdown
Owner

Base branch: dev. Regenerated output: the five derived generators reproduce the committed generated set byte-for-byte (the full npm run build at the pinned CLI moves only the catalog's wall-clock generatedAt stamp, which was restored — it changes only on a CLI adoption).

What

Session C1 of the September rounds (handoff plan items RP-1, RP-2, RP-3, RP-5): the report is the account of KB state, and it now carries depth, domain counts, change-detection honesty and doc_path truth. Plugin 0.40.0.

  • RP-1 · F-455manifest.mjs report carries byDepth = { full, metadata, listOnly, unrecorded } over documented entries, in total and per domain under a new domains.<domain> row (ruling: four states, per-domain block; a stub under a domain with no describe recording is unrecorded, never folded into metadata — the F-346 false-complete class; nothing new inside byDomain rows because describe-batch's progress probe sums them). One helper, describeStateOf, is now shared by the stub banner and the report. Setup's Phase 5 close, --deep relay, Phase 6 precondition and final report, and the budget-report shapes, quote ONE report invocation at a quiescent point instead of narrating.
  • RP-2 · F-454domainCounts: { indexed, withAssets, empty }; the Phase 4 relay quotes indexed, names every emptyDomains entry, and names a stamped: false domain separately instead of counting byDomain keys.
  • RP-3 · F-451 — per domain changeDetection: "date" | "none" | "unrecorded" (T-2's dateField tri-state; a legacy no-key stamp is never read as none) and datelessEntries; refresh's report ends with a Not checked for change this run: block naming every such domain and count, or the word none — never silence. Honest statement only; fingerprint-based staleness stays Deep ingest performance: concurrent describes + batched marks to fit a full run inside one token lifetime #12.
  • RP-5 · F-459mark --status documented refuses an entry with no recorded doc_path when none is passed (and a blank value as malformed); report and remove carry docPathsUnknown; new verb reconcile-docs --domain <d> [--dir] [--out] [--dry-run] backfills doc_path from the docs on disk through doc-lib's docNameMatcher — the claimer's read-side twin, both resolving through ONE private resolveStem and both claiming — and names recorded-missing, unmatched and orphan files; it refuses, before any write, a working directory the recorded paths do not resolve from. The reconcile-on-resume step Deep ingest performance: concurrent describes + batched marks to fit a full run inside one token lifetime #12 will reuse.
  • Contract: report's output is T-2 v3 (GsReport in manifest.mjs's header), additive, pinned by test/contract-conformance.mjs. docPathFor in doc-lib is the one doc_path spelling (stub, describe-batch, the template writer, reconcile).

Why

  • F-455 (rank 4): the user was told a deep crawl had finished while eight domains were entirely stubs, and the report held no fact that could contradict the claim — documented asserted completeness from a status that describes doc existence, not depth (Class: outcome-from-proxy, all four).
  • F-454 (polish): the relay's domain count came from a fold over entries, which drops every listed-but-empty domain.
  • F-451 (rank 6): nearly half of one production inventory sits outside change detection, and the refresh report said "Unchanged" for rows it could not compare.
  • F-459 (normal): documented entries with no recorded doc path are invisible to every path consumer, and a cleanup list read 0 where the truth was unknown — 20 such entries on the sandbox today (down from the 25 logged; the B-V round re-marked five), zero on prod.

Design rulings (Bradley, 2026-09-15, in the bus Fix notes and the plan's As-shipped notes): four-state byDepth in a per-domain block; refuse in mark, count in report and remove, backfill as its own verb — report stays read-only.

Review notes

  • Measured locally, read-only, over both real manifests in the consumer workspace: prod reads six list-only domains as listOnly (722 entries), none as metadata, report 1754 dateless under none (2362 across five recorded-none domains); the sandbox reads domainCounts 18/17/1 with its surveys domain empty, five legacy stamps unrecorded, 557 dateless templates under date, docPathsUnknown 20 across three domains. Neither manifest was written.

  • Fixtures: test/manifest-ops.mjs "c1" section (42 arms over a manifest carrying all four states, a pre-depth doc, an empty stamp, a legacy stamp, a partial registration; the refusal incl. all-or-nothing and blank-value arms; remove's count; reconcile over a scratch folder — matched, the Co/co collision pair, recorded-missing, unmatched, orphans, dry-run, --out, idempotent re-run, missing folder, CWD-mismatch refusal, win32 folder case); 27 of the original 35 red against the pre-fix script (the rest rig setup and controls). test/doc-lib-fixtures.mjs +18 (matcher, deleted-partner, .MD agreement, docPathFor). test/contract-conformance.mjs +10 (T-2 v3 key sets, byDomain numbers-only, remove's keys). test/relationships-build.mjs and the older manifest-ops arms pass --doc-path on their hand-run marks — the closed route.

  • /code-review medium (8 finders + 5 file-batched verifiers): 16 findings, all fixed on the branch — the F-459 Fix note lists them; the matcher's missing claim on a null read (a deleted doc's collision partner as an orphan) was the one real bug.

  • Verbatim battery from validate-plugin.yml and docs-drift.yml: 0 failures locally (npm ci + npm run typecheck included); both claude plugin validate … --strict pass; derived generators reproduce the committed output.

  • Banked arm (dev/VALIDATION.md, Session C1): F-459 — the tester's reconcile-docs over the three sandbox domains, docPathsUnknown 20 → 0 with every orphan named; report reads over both real manifests; setup and refresh walks (both slash-only).

  • Carried, not built: a manifest quiescence sequence (save() counter echoed by report) would make "quoted at a quiescent point" checkable rather than prose; upsert-batch's unchanged folds dateless rows in (named in the F-451 sweep). Draft PR change-request: a Before-building read, and the admin's job in the operating model (plugin 0.39.0) #17 stages 0.39.0 and rebases its bump.

  • Plugin version bumped in .claude-plugin/plugin.json with a CHANGELOG entry (user-visible plugin change).

  • Safety boundary: this PR does not touch hooks/gs-admin-guard.mjs or ask-rules generation.

  • Skill edits: cross-document consistency checked (operating model, managed CLAUDE.md block and the cheatsheet renderer state nothing about report's fields; setup, its mechanics reference, refresh, MAINTAINERS and the CHANGELOG agree), and the changed skills are walked in the tester round (Session C1-V): setup and refresh, both slash-only. Session / verdict: C1-V, pending.

  • No test or dev step touched real gs-admin state (~/.gs-admin/, live tenants) — fixtures only; the two real manifests were read, never written.

  • No tenant/instance/org-specific data in commit messages or this PR body.

… docPathsUnknown on report; mark refuses a pathless documented mark; reconcile-docs backfills doc_path (F-455, F-454, F-451, F-459; plugin 0.40.0)

manifest.mjs report now carries the T-2 v3 GsReport contract: byDepth
{full, metadata, listOnly, unrecorded} over documented entries in total and
per domain under domains.<d>, domainCounts {indexed, withAssets, empty},
per-domain changeDetection (date | none | unrecorded) + datelessEntries, and
docPathsUnknown; describeStateOf is the one helper the stub banner and the
report share. mark --status documented refuses an entry with no recorded
doc_path when none is passed; remove reports docPathsUnknown beside docPaths;
the new reconcile-docs verb backfills doc_path through doc-lib's docNameMatcher
(the claimer's read-side twin, sharing readDocStems). Setup Phase 4 relay,
Phase 5 close, --deep relay, Phase 6 precondition, final report and the
mechanics §4 shapes quote ONE quiescent report; refresh's report ends with a
Not-checked-for-change block. Fixtures: manifest-ops c1 section (35 arms),
doc-lib matcher arms (14), contract pin (T-2 v3), relationships-build marks
pass --doc-path. Bus: F-455/F-454/F-451/F-459 FIXED with Class/Judge/Sibling
sweep; plan As-shipped notes; C1-V prompt refreshed.
…ed, reconcile-docs refuses a wrong CWD, one hasDocPath / docPathFor, report refuses a non-T-2 depth, six prose repairs

/code-review medium (8 finders, 5 file-batched verifiers): 16 findings fixed.
doc-lib: resolveStem is the ONE -dup grammar the claimer and the matcher
both resolve through and both claim from (a matcher that skipped the claim
on a null orphaned a deleted doc's collision partner); readDocStems agrees
with listMdFiles on `.md`; docDirNorm/docPathFor are the one doc_path
spelling (stub, describe-batch, the template writer, reconcile). manifest:
hasDocPath type guard for mark/report/remove/reconcile; `--doc-path ""`
refused; report refuses a depth outside metadata|full; reconcile-docs
refuses a recorded path that does not resolve from this CWD while its file
sits in the folder, and treats a different-case folder as the same folder
on win32. Prose: F/S/L/U substitution rule, --deep paragraph is a pointer
plus the --doc-path clause, Phase 4 relay names a stamped:false domain,
refresh's block reads <t> as the byDomain row sum, omits emptyDomains and
states a legacy stamp's recording from step 3's dateFieldSource. Arms:
doc-lib (+4), manifest-ops (+7).
BradleyDB added a commit that referenced this pull request Sep 15, 2026
…55/F-454/F-451/F-459 FIXED on the branch, hb-20260915-01, dispatches quoted [skip ci]
…-451 REOPENED; VALIDATION F-459 OPEN; walk line (setup, refresh) and guard wiring [skip ci]
…ented entries and reconcile records only that set; refresh's Not-checked block is derived from a fresh post-step-3 report

F-459: everDocumented(e) (documented, or last_verified/depth present) decides the
unknown count in report and remove; reconcile-docs records a path only for that
set, so per domain dry-run recorded <= docPathsUnknown by construction (measured
read-only over both real manifests: 36 domains, 0 violations, files untouched);
a never-documented entry's stray file is reported as docsForUndocumented, claimed,
not recorded. F-451: the refresh report's block states each domain's state as the
next run will read it — a fresh report after step 3 compared with step 1's, one
literal line per transition (the explicit-none case now reads "outside change
detection from now on"), with the tester's check as an instruction. Arms: manifest-ops
c1 reopen (+6; 4 red pre-fix). Second arm banked in dev/VALIDATION.md.
BradleyDB added a commit that referenced this pull request Sep 15, 2026
…ified F-454/F-455, reopened F-451/F-459, both re-FIXED; hb-20260915-02; dispatches quoted [skip ci]
…ION second arm CLEARED; walk line (refresh) and guard wiring [skip ci]
BradleyDB added a commit that referenced this pull request Sep 15, 2026
…n the head commit and the [skip ci] verdict commit carries none (no content change)
@BradleyDB BradleyDB closed this Sep 15, 2026
@BradleyDB BradleyDB reopened this Sep 15, 2026
…res drift (full) on the head (VALIDATION CI note)
@BradleyDB
BradleyDB merged commit 9d52e9f into dev Sep 15, 2026
5 checks passed
@BradleyDB
BradleyDB deleted the round-c1-report-truth branch September 15, 2026 18:15
BradleyDB added a commit that referenced this pull request Sep 15, 2026
…findings VERIFIED, post-merge dispatches quoted [skip ci]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant