1
0
Fork 0
polaris-task-force/src/collections/operations/OperationReadiness.ts
Z8MB1E 3c70160dfc feat(operations): readiness and zone pressure aggregates
Deterministic, explainable, advisory readiness aggregates per subject behind a permission gate, and mission-scoped zone pressure with read-time decay yielding route-risk and yield multipliers.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-20 02:43:53 -04:00

152 lines
4.1 KiB
TypeScript

import type { CollectionConfig } from "payload";
import { requirePermission } from "@/utils/access-control/hasPermission";
/**
* Role-scoped, advisory operation readiness + planning-confidence aggregates.
*
* One row per (subjectType, subjectId, windowStart). Writes are internal only
* (create/update/delete denied; the readiness service writes via `overrideAccess`
* with its own permission gate). Read is gated by the NEW
* `operation-readiness:read` permission, so it is role-scoped, not open to any
* logged-in user.
*
* The stored row carries only normalized scores, category weights, and input
* counts plus a generated explanation. It never contains raw evaluation content
* (evaluator names, rater ids, or comment text), which is what the privacy
* guarantee rests on.
*/
export const OperationReadiness: CollectionConfig = {
slug: "operation-readiness",
admin: {
group: "Operations",
useAsTitle: "subjectLabel",
defaultColumns: ["subjectType", "subjectLabel", "windowStart", "readinessScore", "planningConfidenceScore"],
},
access: {
read: requirePermission("operation-readiness:read"),
create: () => false,
update: () => false,
delete: () => false,
},
fields: [
{
name: "subjectType",
type: "select",
required: true,
options: [
{ label: "User", value: "user" },
{ label: "Role", value: "role" },
],
admin: {
description: "Who the aggregate is for: a specific user, or a whole role.",
},
},
{
name: "subjectId",
type: "number",
admin: {
description: "Id of the subject (user id for user-scoped; null for role-scoped).",
},
},
{
name: "subjectLabel",
type: "text",
admin: {
description: "Human-readable label for the subject (role name or username). Display only.",
},
},
{
name: "windowStart",
type: "date",
required: true,
admin: {
description: "Start of the explicit time window this aggregate covers.",
},
},
{
name: "windowEnd",
type: "date",
admin: {
description: "End of the time window.",
},
},
{
name: "windowLabel",
type: "text",
admin: {
description: "Optional human label for the window (e.g. an ISO week).",
},
},
{
name: "operationId",
type: "text",
admin: {
description: "Optional operation identity the window's data is attributed to.",
},
},
{
name: "calculationVersion",
type: "text",
required: true,
defaultValue: "1.0.0",
admin: {
description: "Readiness calculation model version.",
},
},
{
name: "nature",
type: "select",
required: true,
defaultValue: "advisory",
options: [{ label: "Advisory (non-gating)", value: "advisory" }],
admin: {
description:
"Advisory-only. Never used to gate, punish, or rank players against one another.",
},
},
{
name: "readinessScore",
type: "number",
admin: {
description: "Weighted 0-100 readiness score over present contributing categories.",
},
},
{
name: "planningConfidenceScore",
type: "number",
admin: {
description: "Weighted 0-100 planning-confidence sub-score from pre-op signals.",
},
},
{
name: "contributingCategories",
type: "json",
admin: {
description:
"Structured per-category breakdown ({ category, weight, score, inputCount }). No evaluator data.",
},
},
{
name: "inputCount",
type: "number",
admin: {
description: "Total component inputs consumed by the aggregate.",
},
},
{
name: "explanation",
type: "textarea",
admin: {
description:
"Human-readable explanation enumerating contributing categories and weights. Never contains evaluator names, ids, or comments.",
},
},
{
name: "recomputedAt",
type: "date",
admin: {
description: "When the aggregate was last computed.",
},
},
],
};