# 001: Timeline human output omits project path from entity references

- **Severity:** medium
- **Component:** `src/cli/commands/timeline.rs`
- **Status:** open

## Problem

The `lore timeline` human-readable output renders entity references as bare `#42` or
`!234` without the project path. When multiple projects are synced, this makes the
output ambiguous — issue `#42` in `group/backend` and `#42` in `group/frontend` are
indistinguishable.

### Affected code

`format_entity_ref` at `src/cli/commands/timeline.rs:201-207`:

```rust
fn format_entity_ref(entity_type: &str, iid: i64) -> String {
    match entity_type {
        "issue" => format!("#{iid}"),
        "merge_request" => format!("!{iid}"),
        _ => format!("{entity_type}:{iid}"),
    }
}
```

This function is called in three places:

1. **Event lines** (`print_timeline_event`, line 130) — each event row shows `#42`
   with no project context
2. **Footer seed list** (`print_timeline_footer`, line 161) — seed entities listed as
   `#42, !234` with no project disambiguation
3. **Collect stage summaries** (`timeline_collect.rs:107`) — the `summary` field itself
   bakes in `"Issue #42 created: ..."` without project

### Current output (ambiguous)

```
2025-01-20  CREATED       #42      Issue #42 created: Login timeout bug        @alice
2025-01-21  LABEL+        #42      Label added: priority::high                 @dave
2025-01-22  CREATED       !234     MR !234 created: Refactor auth middleware   @alice
2025-01-25  MERGED        !234     MR !234 merged                              @bob

  Seed entities: #42, !234
```

When multiple projects are synced, a reader cannot tell which project `#42` belongs to.

## Robot mode is partially affected

The robot JSON output (`EventJson`, line 387-416) DOES include a `project` field per
event, so programmatic consumers can disambiguate. However, the `summary` string field
still bakes in bare `#42` without project context, which is misleading if an agent uses
the summary for display.

## Proposed fix

### 1. Add project to `format_entity_ref`

Pass `project_path` into `format_entity_ref` and use GitLab's full reference format:

```rust
fn format_entity_ref(entity_type: &str, iid: i64, project_path: &str) -> String {
    match entity_type {
        "issue" => format!("{project_path}#{iid}"),
        "merge_request" => format!("{project_path}!{iid}"),
        _ => format!("{project_path}/{entity_type}:{iid}"),
    }
}
```

### 2. Smart elision for single-project timelines

When all events belong to the same project, the full path is visual noise. Detect
this and fall back to bare `#42` / `!234`:

```rust
fn should_show_project(events: &[TimelineEvent]) -> bool {
    let mut projects = events.iter().map(|e| &e.project_path).collect::<HashSet<_>>();
    projects.len() > 1
}
```

Then conditionally format:

```rust
let entity_ref = if show_project {
    format_entity_ref(&event.entity_type, event.entity_iid, &event.project_path)
} else {
    format_entity_ref_short(&event.entity_type, event.entity_iid)
};
```

### 3. Fix summary strings in collect stage

`timeline_collect.rs:107` bakes the summary as `"Issue #42 created: title"`. This
should include the project when multi-project:

```rust
let prefix = if multi_project {
    format!("{type_label} {project_path}#{iid}")
} else {
    format!("{type_label} #{iid}")
};
summary = format!("{prefix} created: {title_str}");
```

Same pattern for the merge summary at lines 317 and 347.

### 4. Update footer seed list

`print_timeline_footer` (line 155-164) should also use the project-aware format:

```rust
result.seed_entities.iter()
    .map(|e| format_entity_ref(&e.entity_type, e.entity_iid, &e.project_path))
```

## Expected output after fix

### Single project (no change)

```
2025-01-20  CREATED       #42      Issue #42 created: Login timeout bug        @alice
```

### Multi-project (project path added)

```
2025-01-20  CREATED   group/backend#42   Issue group/backend#42 created: Login timeout  @alice
2025-01-22  CREATED   group/frontend#42  Issue group/frontend#42 created: Broken layout @eve
```

## Impact

- Human output: ambiguous for multi-project users (the primary use case for gitlore)
- Robot output: summary field misleading, but `project` field provides workaround
- Timeline footer: seed entity list ambiguous
- Collect-stage summaries: baked-in bare references propagate to both renderers
