# tools/core/reporters/claim.reporter.ts

> 82 lines of code and 20 definitions.

Tree: Coordination tree
Language: typescript
Layer: operations
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-reporters-claim-reporter-ts
Source text: https://banes-lab.com/source/coordination/tools/core/reporters/claim.reporter.ts.txt

Listed in [tools/core/reporters](https://banes-lab.com/api/source/coordination/tools/core/reporters.md), after [tools/core/reporters/board.reporter.ts](https://banes-lab.com/source/coordination/tools/core/reporters/board.reporter.ts.md) and before [tools/core/reporters/rule.reporter.ts](https://banes-lab.com/source/coordination/tools/core/reporters/rule.reporter.ts.md).

## Definitions

- `ownClaimEcho` (lexical_declaration, line 40, exported)
- `workMovedPast` (lexical_declaration, line 27)
- `ownDischargeEcho` (lexical_declaration, line 71, exported)
- `heldOn` (lexical_declaration, line 62)
- `ECHOED_FIELDS` (lexical_declaration, line 21)
- `textIfPresent` (lexical_declaration, line 23)
- `since` (lexical_declaration, line 28)
- `surfaces` (lexical_declaration, line 29)
- `boardPath` (lexical_declaration, line 41, exported)
- `record` (lexical_declaration, line 47, exported)
- `value` (lexical_declaration, line 55, exported)
- `marker` (lexical_declaration, line 63)
- `board` (lexical_declaration, line 72, exported)
- `source` (lexical_declaration, line 77, exported)
- `index` (lexical_declaration, line 78, exported)
- `active` (lexical_declaration, line 79, exported)
- `addressed` (lexical_declaration, line 80, exported)
- `owed` (lexical_declaration, line 85, exported)
- `closable` (lexical_declaration, line 86, exported)
- `lines` (lexical_declaration, line 91, exported)

## Uses

- [tools/core/resolvers/sweep.resolver.ts](https://banes-lab.com/source/coordination/tools/core/resolvers/sweep.resolver.ts.md)
- [tools/core/runners/mark.runner.ts](https://banes-lab.com/source/coordination/tools/core/runners/mark.runner.ts.md)
- [tools/core/strings/board.strings.ts](https://banes-lab.com/source/coordination/tools/core/strings/board.strings.ts.md)

## Used by

- [tools/core/coordinators/record.coordinator.ts](https://banes-lab.com/source/coordination/tools/core/coordinators/record.coordinator.ts.md)

## Source

```typescript
import { BLOCKING_SUFFIX, VENUE_ARCHIVE } from "../constants/blocking.constants.ts";
import { READ_FIELD, stampOf } from "../formatters/board.formatter.ts";
import { activeSeats, boardRecords } from "../analyzers/board.analyzer.ts";
import { authorOf, unmarkedReaders } from "../runners/mark.runner.ts";
import {
    awaitingMark,
    claimEcho,
    claimFieldAbsent,
    claimNoRecord,
    closableByYou,
    dischargeEcho,
} from "../strings/board.strings.ts";
import { existsSync, readFileSync } from "node:fs";
import { itemSpans, openVenues, surfaceEntries } from "../resolvers/sweep.resolver.ts";
import type { ItemSpan } from "../types/sweep.types.ts";
import { clipped } from "../formatters/text.formatter.ts";
import { readFieldMark } from "../registries/snapshot.registry.ts";
import { resolve } from "node:path";
import { surfacePath } from "../../../config/surface.config.ts";

const ECHOED_FIELDS = ["Status", "Flags"];

const textIfPresent = function textIfPresent(absolute: string): string {
    return existsSync(absolute) ? readFileSync(absolute, "utf8") : "";
};

const workMovedPast = function workMovedPast(repoRoot: string, caller: string): boolean {
    const since = readFieldMark(repoRoot, caller);
    const surfaces = [surfacePath("board"), ...openVenues(surfaceEntries(repoRoot), VENUE_ARCHIVE, BLOCKING_SUFFIX)];

    return surfaces.some((surface) => {
        const source = textIfPresent(resolve(repoRoot, surface));
        const lines = source.split("\n");
        return itemSpans(source).some(
            (span) => authorOf(span.key) === caller && stampOf(lines[span.from] ?? "") > since,
        );
    });
};

export const ownClaimEcho = function ownClaimEcho(repoRoot: string, caller: string): string {
    const boardPath = surfacePath("board");
    const board = resolve(repoRoot, boardPath);
    if (!workMovedPast(repoRoot, caller) || !existsSync(board)) {
        return "";
    }

    const record = boardRecords(readFileSync(board, "utf8")).find(
        (held) => held.kind === "agent" && held.label.endsWith(` ${caller}`),
    );
    if (record === undefined) {
        return claimNoRecord(boardPath, caller);
    }

    const lines = ECHOED_FIELDS.map((field) => {
        const value = record.fields.get(field);
        return value === undefined ? claimFieldAbsent(field) : `  ${field}: ${clipped(value, 200)}`;
    });

    return claimEcho(boardPath, lines);
};

const heldOn = function heldOn(source: string, active: readonly string[], span: ItemSpan): string[] {
    const marker = source.split("\n")[span.from] ?? "";
    if (!marker.includes(READ_FIELD)) {
        return [];
    }

    return unmarkedReaders(marker, span.to, active, authorOf(span.key));
};

export const ownDischargeEcho = function ownDischargeEcho(repoRoot: string, caller: string): string {
    const board = resolve(repoRoot, surfacePath("board"));
    if (!existsSync(board)) {
        return "";
    }

    const source = readFileSync(board, "utf8");
    const index = textIfPresent(resolve(repoRoot, surfacePath("agent_index")));
    const active = activeSeats(source, index);
    const addressed = itemSpans(source)
        .filter((span) => authorOf(span.key) !== caller)
        .filter((span) => (span.to.length === 0 ? active : span.to).includes(caller))
        .map((span) => ({ held: heldOn(source, active, span), key: span.key }));

    const owed = addressed.filter((entry) => entry.held.includes(caller)).map((entry) => entry.key);
    const closable = addressed.filter((entry) => entry.held.length === 0).map((entry) => entry.key);
    if (owed.length === 0 && closable.length === 0) {
        return "";
    }

    const lines = [
        owed.length === 0 ? "" : awaitingMark(owed),
        closable.length === 0 ? "" : closableByYou(closable),
    ].filter((line) => line.length > 0);

    return dischargeEcho(lines);
};
```
