Files
gitlore/docs/plan-expose-discussion-ids.feedback-3.md
teernisse 16cc58b17f docs: remove references to deprecated show command
Update planning docs and audit tables to reflect the removal of
`lore show`:

- CLI_AUDIT.md: remove show row, renumber remaining entries
- plan-expose-discussion-ids.md: replace `show` with
  `issues <IID>`/`mrs <IID>`
- plan-expose-discussion-ids.feedback-3.md: replace `show` with
  "detail views"
- work-item-status-graphql.md: update example commands from
  `lore show issue 123` to `lore issues 123`
2026-03-10 14:21:03 -04:00

6.5 KiB
Raw Blame History

  1. Make gitlab_note_id explicit in all note-level payloads without breaking existing consumers Rationale: Your Bridge Contract already requires gitlab_note_id, but current plan keeps gitlab_id only in notes list while adding gitlab_note_id only in detail views. That forces agents to special-case commands. Add gitlab_note_id as an alias field everywhere note-level data appears, while keeping gitlab_id for compatibility.
@@ Bridge Contract (Cross-Cutting)
-Every read payload that surfaces notes or discussions MUST include:
+Every read payload that surfaces notes or discussions MUST include:
   - project_path
   - noteable_type
   - parent_iid
   - gitlab_discussion_id
   - gitlab_note_id (when note-level data is returned — i.e., in notes list and show detail)
+  - Back-compat rule: note payloads may continue exposing `gitlab_id`, but MUST also expose `gitlab_note_id` with the same value.

@@ 1. Add `gitlab_discussion_id` to Notes Output
-#### 1c. Add field to `NoteListRowJson`
+#### 1c. Add fields to `NoteListRowJson`
+Add `gitlab_note_id` alias in addition to existing `gitlab_id` (no rename, no breakage).

@@ 1f. Update `--fields minimal` preset
-"notes" => ["id", "author_username", "body", "created_at_iso", "gitlab_discussion_id"]
+"notes" => ["id", "gitlab_note_id", "author_username", "body", "created_at_iso", "gitlab_discussion_id"]
  1. Avoid duplicate flag semantics for discussion filtering Rationale: notes already has --discussion-id and it already maps to d.gitlab_discussion_id. Adding a second independent flag/field (--gitlab-discussion-id) increases complexity and precedence bugs. Keep one backing filter field and make the new flag an alias.
@@ 1g. Add `--gitlab-discussion-id` filter to notes
-Allow filtering notes directly by GitLab discussion thread ID...
+Normalize discussion ID flags:
+- Keep one backing filter field (`discussion_id`)
+- Support both `--discussion-id` (existing) and `--gitlab-discussion-id` (alias)
+- If both are provided, clap should reject as duplicate/alias conflict
  1. Add ambiguity guardrails for cross-project discussion IDs Rationale: gitlab_discussion_id is unique per project, not globally. Filtering by discussion ID without project can return multiple rows across repos, which breaks deterministic write bridging. Fail fast with an Ambiguous error and actionable fix (--project).
@@ Bridge Contract (Cross-Cutting)
+### Ambiguity Guardrail
+When filtering by `gitlab_discussion_id` without `--project`, if multiple projects match:
+- return `Ambiguous` error
+- include matching project paths in message
+- suggest retry with `--project <path>`
  1. Replace --include-notes N+1 retrieval with one batched top-N query Rationale: The current plans per-discussion follow-up query scales poorly and creates latency spikes. Use a single window-function query over selected discussion IDs and group rows in Rust. This is both faster and more predictable.
@@ 3c-ii. Note expansion query (--include-notes)
-When `include_notes > 0`, after the main discussion query, run a follow-up query per discussion...
+When `include_notes > 0`, run one batched query:
+WITH ranked_notes AS (
+  SELECT
+    n.*,
+    d.gitlab_discussion_id,
+    ROW_NUMBER() OVER (
+      PARTITION BY n.discussion_id
+      ORDER BY n.created_at DESC, n.id DESC
+    ) AS rn
+  FROM notes n
+  JOIN discussions d ON d.id = n.discussion_id
+  WHERE n.discussion_id IN ( ...selected discussion ids... )
+)
+SELECT ... FROM ranked_notes WHERE rn <= ?
+ORDER BY discussion_id, rn;
+
+Group by `discussion_id` in Rust and attach notes arrays without per-thread round-trips.
  1. Add hard output guardrails and explicit truncation metadata Rationale: --limit and --include-notes are unbounded today. For robot workflows this can accidentally generate huge payloads. Cap values and surface effective limits plus truncation state in meta.
@@ 3a. CLI Args
-    pub limit: usize,
+    pub limit: usize, // clamp to max (e.g., 500)

-    pub include_notes: usize,
+    pub include_notes: usize, // clamp to max (e.g., 20)

@@ Response Schema
-  "meta": { "elapsed_ms": 12 }
+  "meta": {
+    "elapsed_ms": 12,
+    "effective_limit": 50,
+    "effective_include_notes": 2,
+    "has_more": true
+  }
  1. Strengthen deterministic ordering and null handling Rationale: first_note_at, last_note_at, and note position can be null/incomplete during partial sync states. Add null-safe ordering to avoid unstable output and flaky automation.
@@ 2c. Update queries to SELECT new fields
-... ORDER BY first_note_at
+... ORDER BY COALESCE(first_note_at, last_note_at, 0), id

@@ show note query
-ORDER BY position
+ORDER BY COALESCE(position, 9223372036854775807), created_at, id

@@ 3c. SQL Query
-ORDER BY {sort_column} {order}
+ORDER BY COALESCE({sort_column}, 0) {order}, fd.id {order}
  1. Make write-bridging more useful with optional command hints Rationale: Exposing IDs is necessary but not sufficient; agents still need to assemble endpoints repeatedly. Add optional --with-write-hints that injects compact endpoint templates (reply, resolve) derived from row context. This improves usability without bloating default output.
@@ 3a. CLI Args
+    /// Include machine-actionable glab write hints per row
+    #[arg(long, help_heading = "Output")]
+    pub with_write_hints: bool,

@@ Response Schema (notes/discussions/show)
+    "write_hints?": {
+      "reply_endpoint": "string",
+      "resolve_endpoint?": "string"
+    }
  1. Upgrade robot-docs/contract validation from string-contains to parity checks Rationale: contains("gitlab_discussion_id") catches very little and allows schema drift. Build field-set parity tests that compare actual serialized JSON keys to robot-docs declared fields for notes, discussions, and show discussion nodes.
@@ 4f. Add robot-docs contract tests
-assert!(notes_schema.contains("gitlab_discussion_id"));
+let declared = parse_schema_field_list(notes_schema);
+let sample = sample_notes_row_json_keys();
+assert_required_subset(&declared, &["project_path","noteable_type","parent_iid","gitlab_discussion_id","gitlab_note_id"]);
+assert_schema_matches_payload(&declared, &sample);

@@ 4g. Add CLI-level contract integration tests
+Add parity tests for:
+- notes list JSON
+- discussions list JSON
+- issues show discussions[*]
+- mrs show discussions[*]

If you want, I can produce a full revised v3 plan text with these edits merged end-to-end so its ready to execute directly.