Skip to content

internal/model: Event, Report, Warning types and ordering #4

Description

@Saber5656

Title

internal/model: Event, Report, Warning types and ordering

Summary

Implement the canonical data types every other package exchanges: Event
(one activity record), the Report tree, Warning, the enums, and the
deterministic sort/dedup helpers, exactly as specified in DESIGN.md §6.2–§6.3
and §13.

Context

Providers (issues 09–15) emit []Event; aggregation (18) consumes them and
produces Report; renderers (20–21) and the LLM prompt builder (24) consume
Report. Deterministic ordering here is what makes golden-file testing
possible everywhere downstream.

Scope

  • internal/model/event.go, report.go, warning.go, plus _test.go
    files. No I/O, no dependencies outside stdlib.

Detailed Requirements

  1. Types exactly per DESIGN.md §6.2/§6.3:
    • type SourceID string with constants SourceZsh("zsh"),
      SourceGit("git"), SourceClaudeCode("claude-code"),
      SourceCodex("codex").
    • type EventKind string with KindCommand, KindCommit,
      KindAgentSession (values "command", "commit", "agent-session").
    • Event{Source, Kind, Start, End, Project, Ref, Title, Body, Meta}.
    • Warning{Source SourceID, Code, Message string}Code values are the
      stable strings from DESIGN §13; define them as constants in this
      package (e.g. WarnZshNoTimestamps = "zsh_no_timestamps"), one constant
      per code listed there.
    • Report, ReportKind ("daily", "standup"), ProjectActivity,
      AgentSession, Commit, ShellActivity, CommandGroup, Totals,
      Narrative{Text, Model string}, GenerationMeta{Version string, Sources []SourceID, LLMModel string, RedactionMode string},
      StandupData{YesterdayDate string, Yesterday []ProjectActivity, Today []ProjectActivity, YesterdayShell, TodayShell ShellActivity, YesterdayTotals, TodayTotals Totals}.
    • Commit{Repo, Hash, Subject string, When time.Time, Files, Insertions, Deletions int}; AgentSession{Agent, Title, Ref string, Start, End time.Time, UserMsgs, AgentMsgs, Tasks int}; CommandGroup{Head string, Count int, First, Last time.Time, Examples []string};
      Totals{Commits, Insertions, Deletions, Sessions, AgentUserMsgs, Commands int, SpanStart, SpanEnd time.Time}.
  2. Ordering helpers (pure functions, stable):
    • SortEvents([]Event) — by Start, then Source, then Ref, then Title.
    • SortProjects([]ProjectActivity) — activity score desc
      (3*len(Commits) + 2*len(Sessions)), then name asc — exactly the
      DESIGN §6.3 rule (shell commands are unattributed in v1 and never
      contribute to the score).
    • Within ProjectActivity: commits by When asc then Hash; sessions by
      Start asc then Ref; command groups by Count desc then Head asc.
  3. Event.Validate() error — non-zero Start, known Source/Kind, End zero or
    ≥ Start.
  4. Dedup helper DedupSessions([]Event) []Event — for KindAgentSession
    events with non-empty Ref, keep the first occurrence per (Source, Ref)
    pair; events with empty Ref are never deduplicated (unrelated sessions
    must not collapse); preserve order.
  5. No JSON tags on Report yet except where needed by the LLM prompt
    builder later — add lower_snake_case JSON tags to all Report-tree structs
    now (they are also useful for tests).

Acceptance Criteria

  • All types and constants above exist with the exact names/values.
  • Sort helpers are deterministic under permutation (property-style table
    tests shuffle inputs and assert identical output).
  • DedupSessions collapses two events with identical (Source, Ref) to
    one (the live-vs-archived Codex case) and never collapses events with
    empty Ref (two empty-Ref sessions stay two).
  • Event.Validate rejects: zero Start, unknown Source, unknown Kind,
    End < Start — one test case each.
  • Package has zero non-stdlib imports; ≥ 90% statement coverage.

Validation

go test -race -cover ./internal/model/ output pasted into the PR;
scripts/check_net_imports.sh still green.

Dependencies

01, 04 (Report.Range is a timeutil.Range; timeutil has no model
dependency, so no cycle).

Non-goals

Aggregation logic (18), warning emission (sources do that), rendering,
serialization formats beyond struct tags.

Design References

  • docs/DESIGN.md §6.2, §6.3, §9.3 (ordering), §13 (warning codes)

Source of truth: docs/issues/03-model-package.md (PR #1, branch docs/v1-design). If this issue and the repo docs disagree, the docs win. Execution order and dependencies: docs/ISSUE_PLAN.md (this is issue 03 of 33).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions