Presence was decided by a LINQ predicate inline in the controller, so the semantics SR-002 sets were nowhere stated in code -- the read path complied by accident rather than by requirement. PresenceLookup is now the unit that decides, tagged, with the reasoning next to it. JR-004: windows are served exactly as given. UT-021 pins that [0,10] and [10,20] are not merged despite looking mergeable -- two windows mean a genuine departure and return, and collapsing them answers a different question from the one the truth file asked. UT-022 pins a byte-identical round trip. JR-005: bounds inclusive at both ends, zero-length windows are real sightings rather than degenerate ones to discard, overlaps resolve. The wording was the larger half of JR-005. The overlay rendered a bare list: it asserted nothing, but told the viewer nothing either, and the default reading of a paused frame is "these people are on screen" -- exactly what SR-002 forbids. It now carries an "In this scene" heading. ActorAtTime became ActorInScene, and README no longer contains "on screen" anywhere; it stated the forbidden reading outright in seven places, including the opening sentence. JR-006: measured rather than assumed. UT-023 builds 50 actors x 1000 windows and asserts the response is bounded by actor count, never window count. The lookup is a full scan on purpose -- an early exit on `start > t` would exploit the sortedness the format requires, but would silently under-report the moment one producer emitted windows out of order. UT-020 pins that unsorted input still resolves; WindowsAreSorted is a diagnostic, not a correctness dependency. Third mutation check: making the end bound exclusive fails UT-016 and UT-018 and nothing else. One character turns an inclusive window into a half-open one, dropping an actor at exactly the moment a scene ends. TRACES: UT-016, UT-017, UT-018, UT-019, UT-020, UT-021, UT-022, UT-023 TRACES: JR-004, JR-005, JR-006 | SR-002 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
54 lines
1.9 KiB
C#
54 lines
1.9 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace Jellyfin.Plugin.JRay.Models;
|
|
|
|
/// <summary>
|
|
/// One actor entry in a <see cref="TruthFile"/>, with the time windows during
|
|
/// which they are present in the scene.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// "Present in the scene", not "visible on screen": a window is a claim about
|
|
/// scene membership, so an actor who turns away or is off-camera during a
|
|
/// reverse shot is still present. Two windows mean a genuine departure and
|
|
/// return, not a break in detection.
|
|
///
|
|
/// Identity is public identifiers — never a name alone, which is ambiguous and
|
|
/// unstable. <c>jellyfin_id</c> is preferred locally and stripped on
|
|
/// contribution, being meaningless outside the instance that produced it.
|
|
/// </remarks>
|
|
// TRACES: JR-004, JR-007 | SR-001, SR-002
|
|
public class TruthActor
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the actor's display name.
|
|
/// </summary>
|
|
[JsonPropertyName("name")]
|
|
public string Name { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the actor's IMDB person id (e.g. "nm0000158"), or "" if unresolved.
|
|
/// </summary>
|
|
[JsonPropertyName("imdb_id")]
|
|
public string ImdbId { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the actor's TMDB person id, or "" if unresolved.
|
|
/// </summary>
|
|
[JsonPropertyName("tmdb_id")]
|
|
public string TmdbId { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the actor's Jellyfin Person item GUID, or "" if unresolved.
|
|
/// </summary>
|
|
[JsonPropertyName("jellyfin_id")]
|
|
public string JellyfinId { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Gets the list of [start_sec, end_sec] windows during which the actor is in the scene.
|
|
/// </summary>
|
|
[JsonPropertyName("scenes")]
|
|
[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
|
|
public Collection<double[]> Scenes { get; } = new();
|
|
}
|