6 Commits

Author SHA1 Message Date
Steve Yegge f215b312cf docs: re-review and bump the three 90-day-stale freshness markers (#5394)
* docs: re-review and bump the three 90-day-stale freshness markers

azure-devops.md, json-schema.md, and otel-data-model.md all carried
Last reviewed: 2026-05-08 — exactly 91 days old today, so the doc-flags
freshness gate went red on every branch at once. Each doc was genuinely
re-reviewed against its Freshness source paths on main; drift found and
fixed:

- azure-devops.md: proxied-server mode note (ado sync/status/projects
  hard-error there); --parent and --project flags documented; duplicate
  --issues row dropped; real ado.org error text quoted; ado.pat's
  yaml-only secret storage noted. Source bug found during review filed
  separately: the cmd-level config reader cannot see a yaml-only PAT,
  so the documented Quick Start fails on main (bd-wvf77).

- json-schema.md: bd show/close/update --json return top-level ARRAYS
  (contract-test-pinned); jq recipes fixed accordingly; envelope
  pagination key documented; show's always-present revision field and
  import's unchanged counter added; error envelope (optional code/hint,
  envelope-mode shape, stdout paths, exit 1) corrected; deprecation
  notice's tty-only condition noted.

- otel-data-model.md: hard opt-in via BD_OTEL_ENABLED + standard OTel
  SDK env vars (BD_OTEL_* legacy); console-only trace export; dolt span
  attrs (shared doltSpanAttrs, dolt.remote, dolt.force_push,
  dolt.conflicts, dolt.merge_with_strategy); facade-wave storage role
  spans; seven new Dolt metrics; AI attrs (bd.ai.duration_ms, 4-attempt
  retry); appendix re-pinned to current main.

scripts/check-doc-freshness.sh passes locally.

* docs(otel): complete claim_verify_lost op label enumeration; qualify retry policy as compact-only

Review findings on #5394: op also takes guarded-update
(claim_verify.go:113) and ready-claim (issues.go:439); the retry-policy
sentence describes compact's loop, find_duplicates makes one unretried
call.
2026-08-07 02:35:11 -07:00
Steve Yegge 80af94c0a7 fix(export): promoted no-history wisps survive import round-trip (bd-r9uce) (#5368)
* fix(export): promoted no-history wisps survive import round-trip (bd-r9uce)

A promoted no-history wisp is a durable issues-table row that still
carried no_history=true (PromoteFromEphemeralInTx cleared only
Ephemeral), and both import routes inferred the storage plane from row
flags (issueops.IsWisp: Ephemeral || NoHistory). Importing an export
stream containing such a row silently re-planed it into the wisps table,
dropping its cross-plane relations as cross-bucket dependencies on the
way — classic-mode data loss across export->import->export.

Belt and braces, per triage + the #5351 review endorsement:

1. Promote clears NoHistory too (and normalizes an explicit ephemeral
   StorageClass to empty, the NormalizePersistenceMode promotion rule):
   a promoted wisp is fully durable and the flag has no post-promotion
   meaning.

2. Import routes the plane by an explicit marker, never by no_history.
   Export stamps "wisp": true on rows that live in the WISPS table and
   whose flags alone cannot prove it (the no_history shape; ephemeral
   rows self-describe), classified by table membership via a new
   PartitionWispIDs store capability (classic: batched wisps-membership
   query behind an Unwrap walk through the telemetry/hook decorators;
   proxied: the plane-pinned GetWispsByIDs read). Both parse loops
   (bd import in both storage modes, bootstrap/init/auto-import) resolve
   the plane through one shared helper, applyImportWispPlane, which pins
   marker-less no_history records to the durable plane via a new
   non-serialized Issue.WispPlaneOverride consulted by IsWisp. The
   no_history flag itself is preserved on the row, keeping the
   export->import->export byte-identity for wild data; the legacy
   v0.35-v0.37 "wisp"-as-ephemeral alias behavior is unchanged.

Tests: the promoted shape now lives IN the proxied round-trip fixture
(cross_mode_byte_identical covers it, with relations); a classic-mode
round-trip test (fails on base: cross-bucket dependency drop + missing
plane marker); a proxied import plane-routing subtest; embeddeddolt pins
for promote clearing NoHistory and PartitionWispIDs membership
classification.

* docs(schema): document the export stream's explicit wisp plane marker (bd-r9uce)

* fix(export): fresh wisp_plane marker key — legacy-alias reuse was lossy under rollout skew (bd-r9uce)

Adopts lion's #5368 review recommendation: pre-fix v0.38+ binaries' alias
branch (hasWisp && !Ephemeral => Ephemeral=true) would import a marked
genuine no-history wisp as ephemeral — purge-eligible and excluded from
that rig's next export — making the common skew case lossy. A fresh key
degrades to flag routing on older readers, data-safe in both directions.
Legacy 'wisp' read alias preserved verbatim.

* fix(storage): clone WispPlaneOverride in cloneIssueForHook (bd-r9uce)

The hook snapshot guard (TestCloneIssueForHookCoversReferenceFields)
correctly flagged the new *bool field as uncloned: a hook mutating the
snapshot could alias the live issue's plane pin. Deep-copy it and add
it to the guard's covered-fields manifest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FZXjihTayFcngYzo6xPd3p

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 12:48:44 -07:00
Athos Bernardes 3102cbd4d4 fix(show): flag comment_count as omitted when comments are not streamed (#4865)
* fix(show): flag comment_count as omitted when comments are not streamed

bd show --json's count-only default (be-ijck6q, pinned by
TestJSONContract_ShowOmitsOptInPayloadsByDefault) returns comment_count
with no comments key unless --include-comments is passed. A caller that
checks only `.comments` reads absence as "no comments" — wrong whenever
comment_count > 0. A caller that reads comment_count has no signal that
the array was left out on purpose rather than omitted by a client bug.

Add comments_omitted (bool, omitempty) to IssueDetails, set true only
when CommentCount > 0 and Comments was not populated. Leaves the
count-only default and its perf rationale untouched — this does not
revert cfcc95799/e538f2881, it makes the partial representation
self-announcing. Symmetric dependent_count/dependents case is a known,
separate gap left for a follow-up (not reported by ga-clgh, out of
scope here).

Did not bump JSONSchemaVersion / regen the golden corpus: this adds an
optional field via omitempty (no existing consumer's parse breaks,
no existing corpus fixture has comment_count > 0 for `show`), and
corpus-regen needs a live Dolt+Docker this sandbox doesn't have to
verify. Deferring that call to whoever can run `make corpus-regen` and
review the diff.

Fixes ga-clgh.

* fix(show): set comments_omitted on the proxied path too

The direct path flags comment_count as omitted when comments are not
streamed (ga-clgh); the proxied path silently left the flag unset. Mirror
the else-branch in proxiedBuildDetails, add proxied-path coverage for
present/included/zero cases, and document comments_omitted in the JSON
schema reference. No schema version bump: additive optional field already
emitted by the direct path.

Addresses the 2026-07-23 review on gastownhall/beads#4865.

Agent-Signature: claude-sonnet-5-medium on behalf of maphew

---------

Co-authored-by: matt wilkie <maphew@gmail.com>
2026-07-25 16:16:41 -07:00
Steve Yegge a530479774 test(protocol): pin the §J interchange clauses; fix the bd import header gap (wy-ltox1)
WP2 of the beads protocol conformance corpus (PROPOSAL-beads-protocol-v0 §11).
Seven §J clauses had no test; the keystone one had no test anywhere.

cmd/bd/protocol/interchange_test.go pins:

  J6.6  export -> import into an EMPTY store -> export reproduces the stream.
        bd-go had same-DB byte-stability and per-field round-trip tests, but
        nothing asserted CROSS-store equivalence — the exact blind spot where an
        import that drops, defaults, or rewrites a field hides. The fixture
        spans P0 (the zero-value priority), every core issue_type, a closed
        issue with close_reason, labels, inline comments, both dep orientations,
        metadata, assignee, and memories.
  J1.2  unknown fields ignored — a record carrying future fields at the top
        level, inside a dependency, and inside a comment still imports cleanly.
  J1.3  `_schema` header records skipped, on both the file and stdin readers.
  J6.1  import never deletes: a partial stream does not remove the ids it omits.
  J6.3  a dependency whose target id is absent is skipped AND reported
        (skipped_dependencies in `bd import --json`).
  J6.5  `bd import -` reads a stream from stdin.
  J2.4  zero/unknown timestamps export as the Unix epoch, never year-0001
        (which json.Marshal refuses outright, failing the whole export).

J1.3 needed a code fix, not just a test. parseJSONLFile (the bootstrap reader)
skipped the header record, but the `bd import` reader loop — the one `bd import`
and `bd import -` both run through — did not: the header line fell through to
the issue path, unmarshaled into an empty Issue, and aborted the WHOLE import
with "validation failed for issue : title is required". So a canonical export
carrying a provenance header could not be imported at all. Verified against the
new test: it fails with exactly that error without the guard.

Two stale artifacts found during the extraction, fixed here:

  - TestCLI_Import_PrefixValidation_E2E asserted that import REJECTS a foreign
    id prefix without --skip-prefix-validation, a flag that no longer exists
    (every import path now passes SkipPrefixValidation). Being build-tagged out
    of CI (cgo && integration), it rotted unnoticed. Rewritten as
    TestCLI_Import_ForeignPrefix_E2E, pinning the behavior bd actually has —
    which the protocol requires anyway: §J6.6 round-trips through a store with
    its own prefix, and §J7.1 makes ids opaque.
  - docs/reference/json-schema.md claimed export emits schema_version per line.
    It does not (and must not): schema_version belongs to the --json command
    envelope; the interchange's version marker is the optional _schema header.
    The import --json summary field list was also missing five fields.

Gates: gofmt + go vet clean, go build ./... ok, full cmd/bd/protocol package
green (280s, -count=1).
2026-07-13 11:20:06 -07:00
Chris Sells 69e33099b8 docs: apply PR #4722 review feedback to user docs
- FAQ: fix bulk migration/export commands (tracker pull/push need explicit
  IDs; bulk lives on sync --pull-only / --pull / --push-only / --push) and
  correct the cross-project isolation claim (hydration + external targets)
- quickstart: replace the broken DOLT.md blob URL with site links
- installation: Quick Install Script heading matches its macOS/Linux/FreeBSD
  body
- rewrite 33 stale SCREAMING_CASE link labels to the target pages' titles
- add description frontmatter to the 55 authored pages missing it
- docs.json: wildcard redirects for the old /next/ and version-prefixed
  route spaces (1.0.0, 1.0.4, 1.0.5)
2026-07-12 11:06:57 -07:00
Chris Sells a86a2c5dfc docs: port user docs into the Mintlify site tree under docs/
Port the website's current (non-versioned) authored pages into docs/ as
Mintlify pages: frontmatter title as H1 (body H1s removed), Docusaurus
admonitions converted to Mintlify components, root-relative extensionless
links, mermaid fences kept as-is. website/docs/** is untouched and keeps
serving the Docusaurus site until cutover.

git-mv the user-facing docs/ originals with no website twin into the new
IA (core-concepts/, architecture/, workflows/, recovery/, multi-agent/,
integrations/, reference/), converted to Mintlify form. The six files
previously mirrored by sync-website-docs.sh now live once in the site.
ERROR_HANDLING.md and CONTRIBUTOR_NAMESPACE_ISOLATION.md move to engdocs/
(contributor pattern guide and design doc per content review).

Pointer stubs remain at docs/{DOLT,STORAGE-BACKENDS,PLUGIN,RECOVERY,
JSON_SCHEMA}.md because released bd binaries print those paths; QUICKSTART
and DOLT-BACKEND stay as existing pointer stubs.

Corrected while porting: the intro's storage diagram claimed data lives at
.beads/dolt/; embedded mode (the default) uses .beads/embeddeddolt/
(internal/storage/embeddeddolt/store.go), server mode uses .beads/dolt/.
2026-07-12 10:37:07 -07:00