Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions reference-implementations/dacs-directory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ vendor directory.
| `DACS_SCAN_MAX_TXS` | No | Maximum transactions scanned per pass; defaults to `100000` and fails closed if insufficient |
| `DACS_SCAN_FINALITY_DEPTH` | No | Newest transaction count held back before indexing; defaults to `2` |
| `DACS_SCAN_REPLAY_DEPTH` | No | Finalized transaction overlap replayed on every pass; defaults to `2` |
| `DACS_INDEX_INTERVAL_SECONDS` | No | Seconds between production reindex passes; defaults to `900` |
| `DACS_CURSOR_STALL_SECONDS` | No | Cursor-stall alert threshold; defaults to twice the valid index interval (minimum `300`, default `1800`, maximum `86400`) |
| `DACS_RECIPE_POLICIES` | For tier elevation | JSON array of version-pinned DACS-2 recipe policies (`scheme`, `recipeVersion`, `methods`, `defaultMaxAgeSec`, `availability`, `trustedResultSigners`); absent/invalid policy fails closed to `self-declared` |
| `DACS_TRUST_PROXY` | No | Set to `1` only behind a trusted proxy that overwrites client-IP headers; otherwise the in-process rate limiter is disabled and the deployment must enforce its edge limit |
| `NEXT_PUBLIC_DIRECTORY_URL` | Production | Public origin used by canonical URLs, sitemap, `llms.txt`, and machine-discovery documents; defaults to `http://localhost:3400`, which silently poisons production canonical URLs and the sitemap — the server logs a warning when unset in production |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export const DEAD_LETTER_DEFAULT_LIMIT = 20;
export const DEAD_LETTER_MAX_LIMIT = 100;
export const CURSOR_STALL_DEFAULT_SECONDS = 5 * 60;
export const CURSOR_STALL_MIN_SECONDS = 5 * 60;
export const CURSOR_STALL_MAX_SECONDS = 24 * 60 * 60;
export const INDEX_INTERVAL_DEFAULT_SECONDS = 15 * 60;
export const INDEX_INTERVAL_MAX_SECONDS = 12 * 60 * 60;

export type StatusDiagnosticsQuery =
| { ok: true; deadLetterLimit: number; deadLetterLocator?: string }
Expand All @@ -26,11 +28,21 @@ export function parseStatusDiagnosticsQuery(params: URLSearchParams): StatusDiag

export function cursorStallThresholdSeconds(
raw = process.env.DACS_CURSOR_STALL_SECONDS,
rawIndexInterval = process.env.DACS_INDEX_INTERVAL_SECONDS,
): number {
const configured = raw === undefined ? CURSOR_STALL_DEFAULT_SECONDS : Number(raw);
const indexInterval = Number(rawIndexInterval ?? INDEX_INTERVAL_DEFAULT_SECONDS);
const boundedInterval = Number.isSafeInteger(indexInterval) && indexInterval >= 1 && indexInterval <= INDEX_INTERVAL_MAX_SECONDS
? indexInterval
: INDEX_INTERVAL_DEFAULT_SECONDS;
const scheduleAwareDefault = Math.min(
CURSOR_STALL_MAX_SECONDS,
Math.max(CURSOR_STALL_MIN_SECONDS, boundedInterval * 2),
);
if (raw === undefined) return scheduleAwareDefault;
const configured = Number(raw);
return Number.isSafeInteger(configured) && configured >= 1 && configured <= CURSOR_STALL_MAX_SECONDS
? configured
: CURSOR_STALL_DEFAULT_SECONDS;
: scheduleAwareDefault;
}

export function cursorProgressDiagnostics(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ test("listing binding rejections are persistent, public-safe, filterable, and re
test("cursor progress diagnostics distinguish caught-up, stalled, and unknown cursors", () => {
const now = 1_000_000;
assert.equal(cursorStallThresholdSeconds("60"), 60);
assert.equal(cursorStallThresholdSeconds("0"), 300);
assert.equal(cursorStallThresholdSeconds(undefined, "900"), 1_800);
assert.equal(cursorStallThresholdSeconds(undefined, "60"), 300);
assert.equal(cursorStallThresholdSeconds(undefined, "600"), 1_200);
assert.equal(cursorStallThresholdSeconds("0", "600"), 1_200);
assert.equal(cursorStallThresholdSeconds(undefined, "invalid"), 1_800);
assert.deepEqual(cursorProgressDiagnostics(
{ lastSeenTxId: 10, cursorAdvancedAt: now - 61_000 },
12,
Expand Down