asana-gate 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/agent-DZc-5ImE.mjs +0 -2
  2. package/dist/api-Cd3qXjya.mjs +0 -2
  3. package/dist/check-bGxfSyj4.mjs +0 -2
  4. package/dist/classification-CGLGDjUo.mjs +0 -2
  5. package/dist/cli.mjs +1 -3
  6. package/dist/commands-BG1kdDd7.mjs +0 -2
  7. package/dist/config-Cz5cQQ6V.mjs +0 -2
  8. package/dist/context-CtHiLMEu.mjs +0 -2
  9. package/dist/evaluate-B3QITkuM.mjs +0 -2
  10. package/dist/explain-DCu8srlb.mjs +0 -2
  11. package/dist/identity-BueTsN0P.mjs +0 -2
  12. package/dist/index.cjs +0 -2
  13. package/dist/index.d.cts +1 -2
  14. package/dist/index.d.mts +1 -2
  15. package/dist/index.mjs +0 -2
  16. package/dist/init-BxNrskT1.mjs +0 -2
  17. package/dist/listing-cache-DNPtaekS.mjs +0 -2
  18. package/dist/mcp-DwzrJ0jR.mjs +0 -2
  19. package/dist/objects-Bs6oIPKt.mjs +0 -2
  20. package/dist/policy-BsO51rPw.mjs +0 -2
  21. package/dist/run-Bd7MACE5.mjs +0 -2
  22. package/dist/session-Bm78YM5P.mjs +0 -2
  23. package/dist/token-CpUi1ReO.mjs +0 -2
  24. package/dist/token-command-BBRNF06S.mjs +0 -2
  25. package/dist/tools-CrftiOhp.mjs +0 -2
  26. package/package.json +2 -2
  27. package/skills/asana-gate/SKILL.md +1 -1
  28. package/skills/asana-gate/references/cli.md +1 -1
  29. package/skills/asana-gate/references/mcp.md +1 -1
  30. package/skills/asana-gate/references/policy.md +1 -1
  31. package/skills/asana-gate/references/tools.md +1 -1
  32. package/dist/agent-DZc-5ImE.mjs.map +0 -1
  33. package/dist/api-Cd3qXjya.mjs.map +0 -1
  34. package/dist/check-bGxfSyj4.mjs.map +0 -1
  35. package/dist/classification-CGLGDjUo.mjs.map +0 -1
  36. package/dist/cli.mjs.map +0 -1
  37. package/dist/commands-BG1kdDd7.mjs.map +0 -1
  38. package/dist/config-Cz5cQQ6V.mjs.map +0 -1
  39. package/dist/context-CtHiLMEu.mjs.map +0 -1
  40. package/dist/evaluate-B3QITkuM.mjs.map +0 -1
  41. package/dist/explain-DCu8srlb.mjs.map +0 -1
  42. package/dist/identity-BueTsN0P.mjs.map +0 -1
  43. package/dist/index.cjs.map +0 -1
  44. package/dist/index.d.cts.map +0 -1
  45. package/dist/index.d.mts.map +0 -1
  46. package/dist/index.mjs.map +0 -1
  47. package/dist/init-BxNrskT1.mjs.map +0 -1
  48. package/dist/listing-cache-DNPtaekS.mjs.map +0 -1
  49. package/dist/mcp-DwzrJ0jR.mjs.map +0 -1
  50. package/dist/objects-Bs6oIPKt.mjs.map +0 -1
  51. package/dist/policy-BsO51rPw.mjs.map +0 -1
  52. package/dist/run-Bd7MACE5.mjs.map +0 -1
  53. package/dist/session-Bm78YM5P.mjs.map +0 -1
  54. package/dist/token-CpUi1ReO.mjs.map +0 -1
  55. package/dist/token-command-BBRNF06S.mjs.map +0 -1
  56. package/dist/tools-CrftiOhp.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"classification-CGLGDjUo.mjs","names":[],"sources":["../src/gate/router.ts","../src/gate/errors.ts","../src/policy/compile-values.ts","../src/policy/scope.ts","../src/gate/cache.ts","../src/gate/portfolio-index.ts","../src/gate/selection.ts","../src/gate/facts.ts","../src/policy/constraints.ts","../src/policy/effective.ts","../src/gate/shape.ts","../src/gate/plan.ts","../src/catalog/classification.ts"],"sourcesContent":["// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { HttpMethod, OperationSpec } from \"../catalog/operation-spec.ts\";\nimport { type OperationId, OPERATIONS } from \"../catalog/operations.gen.ts\";\n\n/** A matched request path. */\ninterface RouteMatch {\n\treadonly operationId: OperationId;\n\treadonly spec: OperationSpec;\n\treadonly params: Readonly<Record<string, string>>;\n}\n\ninterface Route {\n\treadonly operationId: OperationId;\n\treadonly spec: OperationSpec;\n\treadonly pattern: RegExp;\n\treadonly params: readonly string[];\n\treadonly staticSegments: number;\n}\n\nconst PARAM = /\\{(?<name>[^}]+)\\}/u;\n\nfunction compileRoute(operationId: OperationId, spec: OperationSpec): Route {\n\tconst params: string[] = [];\n\tconst source = spec.path\n\t\t.split(\"/\")\n\t\t.map((segment) => {\n\t\t\tconst name = PARAM.exec(segment)?.groups?.name;\n\t\t\tif (name === undefined) {\n\t\t\t\treturn segment.replaceAll(/[$()*+.?[\\\\\\]^{|}]/gu, String.raw`\\$&`);\n\t\t\t}\n\t\t\tparams.push(name);\n\t\t\treturn \"([^/]+)\";\n\t\t})\n\t\t.join(\"/\");\n\treturn {\n\t\toperationId,\n\t\tspec,\n\t\tpattern: new RegExp(`^${source}$`, \"u\"),\n\t\tparams,\n\t\tstaticSegments: spec.path.split(\"/\").filter((segment) => !segment.startsWith(\"{\")).length,\n\t};\n}\n\n/** Every route, most static first so `/users/me`-like literals beat parameters. */\nconst ROUTES: readonly Route[] = (Object.entries(OPERATIONS) as [OperationId, OperationSpec][])\n\t.map(([operationId, spec]) => compileRoute(operationId, spec))\n\t.toSorted((a, b) => b.staticSegments - a.staticSegments);\n\nconst METHODS: ReadonlySet<string> = new Set([\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\n/** Whether `value` is an HTTP method the API uses. */\nfunction isHttpMethod(value: string): value is HttpMethod {\n\treturn METHODS.has(value);\n}\n\n/**\n * Normalizes a request path: strips a query string, a trailing slash, and\n * the `https://app.asana.com/api/1.0` prefix a caller may have copied.\n */\nfunction normalizePath(path: string): string {\n\tlet normalized = path.trim();\n\tif (/^https?:\\/\\//u.test(normalized)) {\n\t\tnormalized = URL.parse(normalized)?.pathname ?? normalized;\n\t}\n\tconst query = normalized.indexOf(\"?\");\n\tif (query !== -1) {\n\t\tnormalized = normalized.slice(0, query);\n\t}\n\tnormalized = normalized.replace(/^\\/api\\/1\\.0(?=\\/)/u, \"\");\n\tif (!normalized.startsWith(\"/\")) {\n\t\tnormalized = `/${normalized}`;\n\t}\n\treturn normalized.length > 1 ? normalized.replace(/\\/+$/u, \"\") : normalized;\n}\n\n/** A path segment, decoded; `undefined` when it is not a well-formed escape of well-formed text. */\nfunction decoded(segment: string): string | undefined {\n\ttry {\n\t\tconst value = decodeURIComponent(segment);\n\t\treturn value.isWellFormed() ? value : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Finds the operation a method and path address, with its path parameters. */\nfunction matchRoute(method: HttpMethod, path: string): RouteMatch | undefined {\n\tconst normalized = normalizePath(path);\n\tfor (const route of ROUTES) {\n\t\tconst match = route.spec.method === method ? route.pattern.exec(normalized) : null;\n\t\tif (match !== null) {\n\t\t\tconst params: Record<string, string> = {};\n\t\t\tfor (const [i, name] of route.params.entries()) {\n\t\t\t\tconst value = decoded(match[i + 1] ?? \"\");\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\t// A malformed escape or a lone surrogate names nothing: no route, like Asana's 404.\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\tparams[name] = value;\n\t\t\t}\n\t\t\treturn { operationId: route.operationId, spec: route.spec, params };\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** A path template (`/tasks/{task_gid}`) with its parameters filled in, each percent-encoded. */\nfunction fillPath(template: string, params: Readonly<Record<string, string | undefined>>): string {\n\treturn template.replaceAll(/\\{(?<name>[^}]+)\\}/gu, (_match, name: string) =>\n\t\tencodeURIComponent(params[name] ?? \"\"),\n\t);\n}\n\nexport { fillPath, isHttpMethod, matchRoute, normalizePath };\nexport type { RouteMatch };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport { ASANA_ERROR_HELP, type AsanaErrorEntry } from \"../asana/errors.ts\";\n\n/** HTTP statuses the gate itself produces. */\ntype GateStatus = 400 | 403 | 404 | 428 | 429;\n\n/**\n * A decision of the gate, shaped like an Asana error response so that\n * callers cannot tell an invisible object from a nonexistent one.\n */\nclass GateError extends Error {\n\tpublic override readonly name: string = \"GateError\";\n\tpublic readonly status: GateStatus;\n\tpublic readonly errors: readonly AsanaErrorEntry[];\n\n\tpublic constructor(status: GateStatus, message: string, help: string = ASANA_ERROR_HELP) {\n\t\tsuper(message);\n\t\tthis.status = status;\n\t\tthis.errors = [{ message, help }];\n\t}\n\n\t/** The response body, as Asana would send it. */\n\tpublic toBody(): { errors: AsanaErrorEntry[] } {\n\t\treturn { errors: this.errors.map((e) => ({ ...e })) };\n\t}\n}\n\nconst GATE_HELP =\n\t\"This request was refused by the asana-gate policy, not by Asana. Ask for the allowed actions of the object (they are listed as `allowed_actions` on every object the gate returns) before retrying.\";\n\n/**\n * The 404 Asana returns for a gid that does not exist (verified live:\n * `task: Not a recognized ID: 1234567890`); used for invisible objects too.\n */\nfunction notFound(type: string, gid: string): GateError {\n\treturn new GateError(404, `${type}: Not a recognized ID: ${gid}`);\n}\n\n/** The 404 Asana returns for a path that matches no operation (verified live). */\nfunction noRoute(): GateError {\n\treturn new GateError(404, \"No matching route for request\");\n}\n\n/** A visible object on which the policy does not allow `action`. */\nfunction forbidden(action: string, type: string, gid: string): GateError {\n\treturn new GateError(403, `asana-gate: ${action} is not permitted on ${type} ${gid}`, GATE_HELP);\n}\n\n/** A visible object whose update touches a field outside the policy's allowlist. */\nfunction forbiddenField(resource: string, field: string, allowed: Iterable<string>): GateError {\n\treturn new GateError(\n\t\t403,\n\t\t`asana-gate: updating ${resource}.${field} is not permitted here (allowed fields: ${[...allowed].join(\", \")})`,\n\t\tGATE_HELP,\n\t);\n}\n\n/** A request the gate cannot interpret. */\nfunction badRequest(message: string): GateError {\n\treturn new GateError(400, message, GATE_HELP);\n}\n\n/** A request whose content breaks the policy's constraints; `problems` name each one. */\nfunction constraintViolation(resource: string, problems: readonly string[]): GateError {\n\treturn new GateError(\n\t\t400,\n\t\t`asana-gate: the ${resource} does not satisfy the policy: ${problems.join(\"; \")}`,\n\t\tGATE_HELP,\n\t);\n}\n\n/** A request beyond a rate limit the policy sets. */\nfunction limitExceeded(limit: {\n\taction: string;\n\tmax: number;\n\tper: string;\n\truleIndex: number;\n}): GateError {\n\treturn new GateError(\n\t\t429,\n\t\t`asana-gate: ${limit.action} is limited to ${limit.max} per ${limit.per} by rules[${limit.ruleIndex}]; try again later`,\n\t\tGATE_HELP,\n\t);\n}\n\n/**\n * A refusal of action `unit` of a batch, its message prefixed\n * (`actions[2]: …`); a request's own refusal, and any other error, as it is.\n */\nfunction inAction(error: unknown, unit: number | undefined): unknown {\n\treturn error instanceof GateError && unit !== undefined\n\t\t? new GateError(error.status, `actions[${unit}]: ${error.message}`, error.errors[0]?.help)\n\t\t: error;\n}\n\n/** One action a person must confirm before it runs. */\ninterface PendingConfirmation {\n\treadonly action: string;\n\treadonly type: string;\n\treadonly gid: string;\n\treadonly name?: string;\n\treadonly ruleIndex: number;\n}\n\nexport {\n\tbadRequest,\n\tconstraintViolation,\n\tGATE_HELP,\n\tforbidden,\n\tforbiddenField,\n\tGateError,\n\tlimitExceeded,\n\tnoRoute,\n\tnotFound,\n\tinAction,\n};\nexport type { GateStatus, PendingConfirmation };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport { messageOf } from \"../log.ts\";\nimport type { CustomFieldDefinition, NameResolver } from \"./compile.ts\";\nimport type { FieldApplication, FieldRequirement, Scalar } from \"./constraints.ts\";\nimport { isGid, type PolicyApplication, type PolicyRequirement } from \"./schema.ts\";\nimport { PolicyError } from \"./types.ts\";\n\n/** Compilers of the values a rule's `require` and `apply` write: operators, regular expressions and the names they use. */\n\n/** Compiles a regular expression from a policy, with a readable error. */\nfunction compileRegExp(source: string, label: string): RegExp {\n\ttry {\n\t\treturn new RegExp(source, \"u\");\n\t} catch (error) {\n\t\tconst reason = messageOf(error);\n\t\tthrow new PolicyError(\n\t\t\t`${label}: invalid regular expression ${JSON.stringify(source)}: ${reason}`,\n\t\t);\n\t}\n}\n\n/**\n * Turns one value a policy writes for a request member into the gid Asana\n * expects (a tag, user, project or team name, or an enum option name); gids\n * and values that name nothing pass through unchanged.\n */\ntype ValueResolver = (value: Scalar) => Promise<Scalar>;\n\n/** Members whose values name objects of one kind, resolved like the names in `where`. */\nconst REFERENCE_MEMBERS: Readonly<Record<string, \"tag\" | \"user\" | \"project\" | \"team\">> = {\n\ttags: \"tag\",\n\tassignee: \"user\",\n\towner: \"user\",\n\tfollowers: \"user\",\n\tprojects: \"project\",\n\tteam: \"team\",\n};\n\n/** The resolver for a member's values, when they name objects. */\nfunction memberResolver(\n\tmember: string,\n\tcontext: { readonly resolver: NameResolver; readonly workspace: string },\n): ValueResolver | undefined {\n\tconst kind = REFERENCE_MEMBERS[member];\n\tif (kind === undefined) {\n\t\treturn undefined;\n\t}\n\tconst { resolver, workspace } = context;\n\treturn (value) =>\n\t\ttypeof value !== \"string\" || isGid(value)\n\t\t\t? Promise.resolve(value)\n\t\t\t: resolver[kind](value, workspace);\n}\n\n/** Enum option names of a custom field resolve to the option gids (unknown values stay as written). */\nfunction optionResolver(definition: CustomFieldDefinition): ValueResolver | undefined {\n\tif (definition.enumOptions.length === 0) {\n\t\treturn undefined;\n\t}\n\treturn (value) => {\n\t\tconst text = String(value);\n\t\tconst option = definition.enumOptions.find((o) => o.gid === text || o.name === text);\n\t\treturn Promise.resolve(option?.gid ?? value);\n\t};\n}\n\n/** The texts an `in` / `not_in` list matches: as written, and resolved to gids. */\nasync function referenceSet(\n\tvalues: readonly Scalar[],\n\tresolve: ValueResolver | undefined,\n): Promise<Set<string>> {\n\tconst resolved =\n\t\tresolve === undefined ? [] : await Promise.all(values.map((value) => resolve(value)));\n\treturn new Set([...values, ...resolved].map(String));\n}\n\nconst isScalarList = (value: Scalar | readonly Scalar[]): value is readonly Scalar[] =>\n\tArray.isArray(value);\n\nasync function compileRequirement(\n\traw: true | PolicyRequirement,\n\tlabel: string,\n\tresolve: ValueResolver | undefined,\n): Promise<FieldRequirement> {\n\tif (raw === true) {\n\t\treturn { present: true };\n\t}\n\treturn {\n\t\t...(raw.present !== undefined && { present: raw.present }),\n\t\t...(raw.prefix !== undefined && { prefix: raw.prefix }),\n\t\t...(raw.suffix !== undefined && { suffix: raw.suffix }),\n\t\t...(raw.contains !== undefined && { contains: raw.contains }),\n\t\t...(raw.matches !== undefined && { matches: compileRegExp(raw.matches, `${label}.matches`) }),\n\t\t...(raw.not_matches !== undefined && {\n\t\t\tnotMatches: compileRegExp(raw.not_matches, `${label}.not_matches`),\n\t\t}),\n\t\t...(raw.in !== undefined && { in: await referenceSet(raw.in, resolve) }),\n\t\t...(raw.not_in !== undefined && { notIn: await referenceSet(raw.not_in, resolve) }),\n\t\t...(raw.min_length !== undefined && { minLength: raw.min_length }),\n\t\t...(raw.max_length !== undefined && { maxLength: raw.max_length }),\n\t\t...(raw.min !== undefined && { min: raw.min }),\n\t\t...(raw.max !== undefined && { max: raw.max }),\n\t};\n}\n\ntype RawApplication =\n\t| PolicyApplication\n\t| string\n\t| number\n\t| boolean\n\t| readonly (string | number | boolean)[];\n\nconst isApplicationObject = (raw: RawApplication): raw is PolicyApplication =>\n\ttypeof raw === \"object\" && !Array.isArray(raw);\n\nasync function compileApplication(\n\traw: RawApplication,\n\tresolve: ValueResolver | undefined,\n): Promise<FieldApplication> {\n\tconst one = (value: Scalar): Promise<Scalar> =>\n\t\tresolve === undefined ? Promise.resolve(value) : resolve(value);\n\tconst values = (value: Scalar | readonly Scalar[]): Promise<Scalar | Scalar[]> =>\n\t\tisScalarList(value) ? Promise.all(value.map((item) => one(item))) : one(value);\n\tif (!isApplicationObject(raw)) {\n\t\treturn { default: await values(raw) };\n\t}\n\treturn {\n\t\t...(raw.default !== undefined && { default: await values(raw.default) }),\n\t\t...(raw.value !== undefined && { value: await values(raw.value) }),\n\t\t...(raw.prefix !== undefined && { prefix: raw.prefix }),\n\t\t...(raw.suffix !== undefined && { suffix: raw.suffix }),\n\t\t...(raw.add !== undefined && { add: await Promise.all(raw.add.map((item) => one(item))) }),\n\t};\n}\n\nexport { compileApplication, compileRegExp, compileRequirement, memberResolver, optionResolver };\nexport type { RawApplication, ValueResolver };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport { compileRegExp } from \"./compile-values.ts\";\nimport { durationMs } from \"./durations.ts\";\nimport type { PolicyWhere } from \"./schema.ts\";\nimport {\n\ttype CompiledNamePredicate,\n\ttype CompiledWhere,\n\tLEVELS,\n\ttype Policy,\n\ttype Specificity,\n} from \"./types.ts\";\n\nfunction compileName(name: NonNullable<PolicyWhere[\"name\"]>): CompiledNamePredicate {\n\treturn {\n\t\t...(name.prefix !== undefined && { prefix: name.prefix }),\n\t\t...(name.suffix !== undefined && { suffix: name.suffix }),\n\t\t...(name.contains !== undefined && { contains: name.contains }),\n\t\t...(name.matches !== undefined && { matches: compileRegExp(name.matches, \"name.matches\") }),\n\t};\n}\n\n/** The state predicates of a scope (none of them needs the resolver). */\nfunction compileState(where: PolicyWhere): Partial<CompiledWhere> {\n\tconst dueWithinMs = where.due_within === undefined ? undefined : durationMs(where.due_within);\n\tconst createdWithinMs =\n\t\twhere.created_within === undefined ? undefined : durationMs(where.created_within);\n\treturn {\n\t\t...(where.completed !== undefined && { completed: where.completed }),\n\t\t...(where.has_parent !== undefined && { hasParent: where.has_parent }),\n\t\t...(where.name !== undefined && { name: compileName(where.name) }),\n\t\t...(where.overdue !== undefined && { overdue: where.overdue }),\n\t\t...(dueWithinMs !== undefined && { dueWithinMs }),\n\t\t...(createdWithinMs !== undefined && { createdWithinMs }),\n\t};\n}\n\n/** How many cross-cutting and state predicates a scope carries. */\nfunction crossCount(where: CompiledWhere): number {\n\tconst flags = [\n\t\twhere.tags,\n\t\twhere.assignees,\n\t\twhere.createdBy,\n\t\twhere.completed,\n\t\twhere.hasParent,\n\t\twhere.name,\n\t\twhere.overdue,\n\t\twhere.dueWithinMs,\n\t\twhere.createdWithinMs,\n\t];\n\treturn flags.filter((flag) => flag !== undefined).length + (where.customFields?.length ?? 0);\n}\n\n/** The specificity of a compiled scope. */\nfunction specificityOf(where: CompiledWhere): Specificity {\n\tconst levels = [\n\t\tLEVELS.workspace,\n\t\twhere.teams ? LEVELS.team : 0,\n\t\twhere.portfolios ? LEVELS.portfolio : 0,\n\t\twhere.unhomed === true ? LEVELS.unhomed : 0,\n\t\twhere.projects ? LEVELS.project : 0,\n\t\twhere.sections ? LEVELS.section : 0,\n\t\twhere.subtrees ? LEVELS.subtree : 0,\n\t\twhere.tasks ? LEVELS.task : 0,\n\t];\n\treturn { level: Math.max(...levels), cross: crossCount(where) };\n}\n\n/** Every portfolio gid a scope of the policy names; the gate indexes their contents. */\nfunction portfoliosNamed(policy: Policy): ReadonlySet<string> {\n\treturn new Set(policy.rules.flatMap((rule) => [...(rule.where.portfolios ?? [])]));\n}\n\n/** Whether a scope of the policy names a task or a subtree, so a task's ancestors must be known. */\nfunction needsTaskChain(policy: Policy): boolean {\n\treturn policy.rules.some(\n\t\t(rule) => rule.where.tasks !== undefined || rule.where.subtrees !== undefined,\n\t);\n}\n\nexport { compileState, needsTaskChain, portfoliosNamed, specificityOf };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\n/** One cached value and when it stops being valid. */\ninterface CacheEntry<V> {\n\treadonly value: V;\n\treadonly expires: number;\n}\n\n/** Expired entries are swept once the cache holds this many, then at twice its size after each sweep. */\nconst SWEEP_AT = 256;\n\n/** A small in-memory cache whose entries expire after the cache's time to live, or their own. */\nclass TtlCache<V> {\n\tprivate readonly entries = new Map<string, CacheEntry<V>>();\n\tprivate readonly ttlMs: number;\n\tprivate sweepAt = SWEEP_AT;\n\n\tpublic constructor(ttlMs: number) {\n\t\tthis.ttlMs = ttlMs;\n\t}\n\n\tpublic get(key: string): V | undefined {\n\t\tconst entry = this.entries.get(key);\n\t\tif (entry === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (entry.expires <= Date.now()) {\n\t\t\tthis.entries.delete(key);\n\t\t\treturn undefined;\n\t\t}\n\t\treturn entry.value;\n\t}\n\n\tpublic set(key: string, value: V, ttlMs: number = this.ttlMs): void {\n\t\tthis.entries.set(key, { value, expires: Date.now() + ttlMs });\n\t\tif (this.entries.size >= this.sweepAt) {\n\t\t\tthis.sweep();\n\t\t}\n\t}\n\n\tpublic delete(key: string): void {\n\t\tthis.entries.delete(key);\n\t}\n\n\t/** Deletes every entry `drop` selects; resolves to their keys. */\n\tpublic deleteWhere(drop: (key: string, value: V) => boolean): string[] {\n\t\tconst keys: string[] = [];\n\t\t// Deleting the entry being visited does not disturb a Map's iteration.\n\t\tfor (const [key, entry] of this.entries) {\n\t\t\tif (drop(key, entry.value)) {\n\t\t\t\tthis.entries.delete(key);\n\t\t\t\tkeys.push(key);\n\t\t\t}\n\t\t}\n\t\treturn keys;\n\t}\n\n\t/** Drops every expired entry, so a long-running cache does not keep what nobody reads again. */\n\tprivate sweep(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [key, entry] of this.entries) {\n\t\t\tif (entry.expires <= now) {\n\t\t\t\tthis.entries.delete(key);\n\t\t\t}\n\t\t}\n\t\tthis.sweepAt = Math.max(SWEEP_AT, this.entries.size * 2);\n\t}\n}\n\nexport { TtlCache };\nexport type { CacheEntry };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { AsanaClient } from \"../asana/client.ts\";\nimport { isAbsent } from \"../asana/errors.ts\";\nimport { type Logger, silentLogger } from \"../log.ts\";\nimport { EMPTY } from \"../policy/evaluate.ts\";\nimport { type AsanaObject, stringOf } from \"./objects.ts\";\n\ninterface Index {\n\t/** project gid → the policy portfolios (transitively) containing it */\n\treadonly projects: Map<string, Set<string>>;\n\t/** portfolio gid → itself and the policy portfolios (transitively) containing it */\n\treadonly portfolios: Map<string, Set<string>>;\n}\n\n/** Options for {@link PortfolioIndex}. */\ninterface PortfolioIndexOptions {\n\treadonly client: AsanaClient;\n\t/** The portfolios the policy names. */\n\treadonly roots: ReadonlySet<string>;\n\t/** How long a snapshot is reused, in milliseconds. */\n\treadonly ttlMs: number;\n\treadonly logger?: Logger;\n}\n\n/**\n * Knows which projects (and nested portfolios) the portfolios named by the\n * policy contain, so `where: { portfolio }` rules can be evaluated without\n * an Asana call per request. Rebuilt lazily once the snapshot is older than\n * the TTL.\n */\nclass PortfolioIndex {\n\tprivate readonly client: AsanaClient;\n\tprivate readonly roots: ReadonlySet<string>;\n\tprivate readonly ttlMs: number;\n\tprivate readonly logger: Logger;\n\tprivate index: Index | undefined = undefined;\n\tprivate builtAt = 0;\n\tprivate building: Promise<Index> | undefined = undefined;\n\t/** Bumped by every invalidation, so a build that saw older contents is not kept. */\n\tprivate generation = 0;\n\n\tpublic constructor(options: PortfolioIndexOptions) {\n\t\tthis.client = options.client;\n\t\tthis.roots = options.roots;\n\t\tthis.ttlMs = options.ttlMs;\n\t\tthis.logger = options.logger ?? silentLogger;\n\t}\n\n\t/** The policy portfolios containing a project. */\n\tpublic async containing(projectGid: string): Promise<ReadonlySet<string>> {\n\t\tif (this.roots.size === 0) {\n\t\t\treturn EMPTY;\n\t\t}\n\t\tconst index = await this.current();\n\t\treturn index.projects.get(projectGid) ?? EMPTY;\n\t}\n\n\t/** A portfolio itself plus the policy portfolios containing it. */\n\tpublic async lineageOf(portfolioGid: string): Promise<ReadonlySet<string>> {\n\t\tif (this.roots.size === 0) {\n\t\t\treturn new Set([portfolioGid]);\n\t\t}\n\t\tconst index = await this.current();\n\t\treturn index.portfolios.get(portfolioGid) ?? new Set([portfolioGid]);\n\t}\n\n\t/**\n\t * Drops the snapshot after a write to `portfolioGid` when it (or one being\n\t * built) may list it, so the next lookup rebuilds it; a build under way is\n\t * not kept either.\n\t */\n\tpublic invalidateFor(portfolioGid: string): void {\n\t\tif (this.building !== undefined || this.index?.portfolios.has(portfolioGid) === true) {\n\t\t\tthis.index = undefined;\n\t\t\tthis.generation += 1;\n\t\t}\n\t}\n\n\tprivate current(): Promise<Index> {\n\t\tif (this.index !== undefined && Date.now() - this.builtAt < this.ttlMs) {\n\t\t\treturn Promise.resolve(this.index);\n\t\t}\n\t\tthis.building ??= this.buildOnce();\n\t\treturn this.building;\n\t}\n\n\tprivate async buildOnce(): Promise<Index> {\n\t\ttry {\n\t\t\treturn await this.build();\n\t\t} finally {\n\t\t\tthis.building = undefined;\n\t\t}\n\t}\n\n\tprivate async build(): Promise<Index> {\n\t\tconst started = this.generation;\n\t\tconst index: Index = { projects: new Map(), portfolios: new Map() };\n\t\t// A failed walk fails the build: nothing is kept, and the next lookup tries again.\n\t\tawait Promise.all([...this.roots].map((root) => this.walk(root, [root], index)));\n\t\tif (this.generation !== started) {\n\t\t\t// A portfolio changed while it was listed: list again.\n\t\t\treturn this.build();\n\t\t}\n\t\tthis.index = index;\n\t\tthis.builtAt = Date.now();\n\t\tthis.logger.debug(`portfolio index built: ${index.projects.size} projects`);\n\t\treturn index;\n\t}\n\n\tprivate async walk(portfolio: string, lineage: readonly string[], index: Index): Promise<void> {\n\t\tconst own = index.portfolios.get(portfolio) ?? new Set<string>();\n\t\tfor (const gid of lineage) {\n\t\t\town.add(gid);\n\t\t}\n\t\tindex.portfolios.set(portfolio, own);\n\t\tconst items: AsanaObject[] = [];\n\t\ttry {\n\t\t\tfor await (const item of this.client.paginate<AsanaObject>(`/portfolios/${portfolio}/items`, {\n\t\t\t\topt_fields: [\"resource_type\"],\n\t\t\t})) {\n\t\t\t\titems.push(item);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Only a portfolio that is not there (or not readable) is empty; a rate\n\t\t\t// limit or an expired token fails the request instead of silently\n\t\t\t// dropping the portfolio's rules.\n\t\t\tif (isAbsent(error)) {\n\t\t\t\tthis.logger.warn(\n\t\t\t\t\t`portfolio ${portfolio} is not readable (${error.status}); treating as empty`,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tconst nested: Promise<void>[] = [];\n\t\tfor (const item of items) {\n\t\t\tconst gid = stringOf(item.gid) ?? \"\";\n\t\t\tif (gid === \"\") {\n\t\t\t\tthis.logger.debug(`portfolio ${portfolio}: skipping an item without a gid`);\n\t\t\t} else if (item.resource_type === \"portfolio\") {\n\t\t\t\tif (!lineage.includes(gid)) {\n\t\t\t\t\tnested.push(this.walk(gid, [...lineage, gid], index));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst set = index.projects.get(gid) ?? new Set<string>();\n\t\t\t\tfor (const ancestor of lineage) {\n\t\t\t\t\tset.add(ancestor);\n\t\t\t\t}\n\t\t\t\tindex.projects.set(gid, set);\n\t\t\t}\n\t\t}\n\t\tawait Promise.all(nested);\n\t}\n}\n\nexport { PortfolioIndex };\nexport type { PortfolioIndexOptions };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport { splitList } from \"../asana/query.ts\";\nimport type { Resource } from \"../catalog/resources.ts\";\nimport { type AsanaObject, isObject } from \"./objects.ts\";\nimport type { ResponsePlan } from \"./plan.ts\";\n\n/**\n * Parsed `opt_fields`: per member, what is selected inside it; none when the\n * member is selected alone. A member named both alone and with a selection\n * inside it counts as the latter, as Asana answers it.\n */\ntype Selection = ReadonlyMap<string, Selection>;\n\n/** A plain `opt_fields` path (`name`, `memberships.project.team`). */\nconst PATH = /^[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*$/u;\n\n/**\n * Parses `opt_fields`; `undefined` when one is not a plain path (or starts\n * with the legacy `this.`), so what Asana answers for it is not known.\n */\nfunction parseSelection(fields: readonly string[]): Selection | undefined {\n\tif (!fields.every((field) => PATH.test(field) && field.split(\".\")[0] !== \"this\")) {\n\t\treturn undefined;\n\t}\n\tconst root = new Map<string, Map<string, unknown>>();\n\tfor (const field of fields) {\n\t\tlet node = root;\n\t\tfor (const name of field.split(\".\")) {\n\t\t\tlet next = node.get(name) as Map<string, Map<string, unknown>> | undefined;\n\t\t\tif (next === undefined) {\n\t\t\t\tnext = new Map();\n\t\t\t\tnode.set(name, next);\n\t\t\t}\n\t\t\tnode = next;\n\t\t}\n\t}\n\treturn root as Selection;\n}\n\n/**\n * The fields a request asks for: its comma-separated `opt_fields` and the\n * `options.fields` of an enveloped body (or of a batch action), trimmed,\n * with empty and repeated ones dropped.\n */\nfunction requestedFields(optFields: unknown, optionFields: readonly unknown[] = []): string[] {\n\tconst named = optionFields.filter((field): field is string => typeof field === \"string\");\n\treturn [\n\t\t...new Set(splitList([typeof optFields === \"string\" ? optFields : \"\", ...named].join(\",\"))),\n\t];\n}\n\n/** A request's comma-separated `opt_fields`, and their selection when every one is a plain path. */\nfunction parseOptFields(text: string | undefined): {\n\treadonly fields: readonly string[];\n\treadonly selection: Selection | undefined;\n} {\n\tconst fields = splitList(text ?? \"\");\n\treturn { fields, selection: fields.length === 0 ? undefined : parseSelection(fields) };\n}\n\n/** The `opt_fields` of a selection. */\nfunction fieldsOf(selection: Selection, prefix = \"\"): string[] {\n\treturn [...selection].flatMap(([name, inner]) =>\n\t\tinner.size === 0 ? [`${prefix}${name}`] : fieldsOf(inner, `${prefix}${name}.`),\n\t);\n}\n\n/**\n * The caller's selection together with what the gate needs, for a response\n * that {@link pick} then cuts back to the caller's. A member the caller\n * selects alone is left alone: selecting inside it would change what Asana\n * answers for it (`{ gid, resource_type }`), which no cut could restore, so\n * what the gate needed there is missing and `complete` is false.\n */\nfunction widenSelection(\n\tcaller: Selection,\n\tneeded: Selection,\n): { readonly sent: Selection; readonly complete: boolean } {\n\tconst sent = new Map(caller);\n\tlet complete = true;\n\tfor (const [name, inner] of needed) {\n\t\tconst own = caller.get(name);\n\t\tif (own === undefined) {\n\t\t\tsent.set(name, inner);\n\t\t} else if (own.size === 0) {\n\t\t\tcomplete &&= inner.size === 0;\n\t\t} else {\n\t\t\tconst widened = widenSelection(own, inner);\n\t\t\tsent.set(name, widened.sent);\n\t\t\tcomplete &&= widened.complete;\n\t\t}\n\t}\n\treturn { sent, complete };\n}\n\n/** {@link pick} on any value: lists item by item, objects member by member. */\nfunction cut(value: unknown, selection: Selection): unknown {\n\tif (Array.isArray(value)) {\n\t\treturn value.map((item: unknown) => cut(item, selection));\n\t}\n\tif (!isObject(value)) {\n\t\treturn value;\n\t}\n\tconst picked: AsanaObject = \"gid\" in value ? { gid: value.gid } : {};\n\tfor (const [name, inner] of selection) {\n\t\tif (name in value) {\n\t\t\tpicked[name] = inner.size === 0 ? value[name] : cut(value[name], inner);\n\t\t}\n\t}\n\treturn picked;\n}\n\n/**\n * An object cut back to the members `selection` names (and its `gid`), the\n * way Asana would have answered that selection alone: members selected\n * alone are kept as they are, since {@link widenSelection} never selects\n * inside them.\n */\nfunction pick(object: AsanaObject, selection: Selection): AsanaObject {\n\tconst picked = cut(object, selection);\n\treturn isObject(picked) ? picked : {};\n}\n\n/**\n * `opt_fields` with `resource_type` selected inside every member they reach\n * into. Asana answers a member with a selection inside it with only its\n * `gid` and that selection (`parent.name` gives `{ gid, name }`, and\n * `parent` next to `parent.memberships.project` gives `{ gid, memberships }`;\n * observed live), so without it a nested reference cannot be told from any\n * other object, and the gate could not check it. Inside a non-resource\n * object (a membership) the member is unknown, and Asana ignores it.\n */\nfunction withReferenceTypes(fields: readonly string[]): string[] {\n\tconst types = fields.flatMap((field) => {\n\t\tconst names = field.split(\".\");\n\t\treturn names.slice(1).map((_, depth) => `${names.slice(0, depth + 1).join(\".\")}.resource_type`);\n\t});\n\treturn [...new Set([...fields, ...types])];\n}\n\n/** Per resource, the fields a list item carries when the caller asks for none. */\nconst DEFAULT_LIST_FIELDS: Partial<Record<Resource, readonly string[]>> = {\n\tstory: [\"text\", \"resource_subtype\", \"created_at\", \"created_by\", \"type\"],\n\tstatus_update: [\"title\", \"status_type\", \"resource_subtype\", \"created_at\"],\n\tattachment: [\"name\", \"resource_subtype\", \"created_at\"],\n\ttime_tracking_entry: [\"duration_minutes\", \"entered_on\", \"created_by\"],\n\tmembership: [\"member\", \"parent\", \"access_level\", \"resource_subtype\"],\n\tproject_membership: [\"member\", \"parent\", \"access_level\"],\n\tportfolio_membership: [\"user\", \"portfolio\", \"access_level\"],\n\tteam_membership: [\"user\", \"team\", \"is_admin\", \"is_guest\"],\n\tworkspace_membership: [\"user\", \"workspace\", \"is_active\"],\n\tcustom_field_setting: [\"custom_field\", \"is_important\", \"parent\"],\n\twebhook: [\"resource\", \"target\", \"active\"],\n\tallocation: [\"assignee\", \"parent\", \"start_date\", \"end_date\"],\n\tbudget: [\"budget_type\", \"parent\"],\n\trate: [\"rate\", \"parent\", \"resource\"],\n\tgoal_relationship: [\"supporting_resource\", \"supported_goal\", \"resource_subtype\"],\n\tproject_portfolio_setting: [\"project\", \"portfolio\", \"is_access_control_inherited\"],\n\tooo_entry: [\"user\", \"start_date\", \"end_date\"],\n\ttimesheet_approval_status: [\"user\", \"start_date\", \"end_date\", \"approval_status\"],\n\ttime_period: [\"display_name\", \"period\", \"start_on\", \"end_on\"],\n\tnotification: [\"story\", \"work_objects\", \"is_read\", \"created_at\"],\n\taccess_request: [\"requester\", \"target\", \"approval_status\"],\n};\n\n/** Per resource, the `opt_fields` the loader needs to derive an object's facts. */\ntype RequiredFields = (type: Resource) => readonly string[];\n\n/** What post-processing needs the response to carry, as `opt_fields`. */\nfunction neededFields(\n\tresponse: ResponsePlan,\n\trequested: readonly string[] | undefined,\n\trequiredFields: RequiredFields,\n): readonly string[] | undefined {\n\tif (response.kind === \"raw\" || response.kind === \"custom\") {\n\t\treturn requested;\n\t}\n\tif (response.type === \"mixed\") {\n\t\t// Each item names its type, and carries what the facts of any expected type need.\n\t\tconst expected = response.expect ?? [];\n\t\tif (expected.length === 0) {\n\t\t\t// Asana names an item's type only when it is selected, and an item of no known type is dropped.\n\t\t\treturn requested === undefined ? undefined : [...new Set([...requested, \"resource_type\"])];\n\t\t}\n\t\treturn [\n\t\t\t...new Set([\n\t\t\t\t...(requested ?? [\"name\"]),\n\t\t\t\t\"resource_type\",\n\t\t\t\t...expected.flatMap((type) => requiredFields(type)),\n\t\t\t]),\n\t\t];\n\t}\n\tif (response.facts !== undefined) {\n\t\treturn requested;\n\t}\n\tconst required = requiredFields(response.type);\n\tif (response.kind === \"item\") {\n\t\t// Without `opt_fields` Asana returns the full object, which carries every required field.\n\t\treturn requested === undefined ? undefined : [...new Set([...requested, ...required])];\n\t}\n\tconst base = requested ?? DEFAULT_LIST_FIELDS[response.type] ?? [\"name\"];\n\treturn [...new Set([...base, ...required])];\n}\n\n/**\n * The `opt_fields` to send so the response carries what post-processing\n * needs; `undefined` leaves the caller's choice (or Asana's default) alone.\n */\nfunction augmentOptFields(\n\tresponse: ResponsePlan,\n\trequested: readonly string[] | undefined,\n\trequiredFields: RequiredFields,\n): readonly string[] | undefined {\n\tconst fields = neededFields(response, requested, requiredFields);\n\t// Every nested reference the response carries must name its type, or it could not be checked.\n\treturn fields === undefined ? undefined : withReferenceTypes(fields);\n}\n\nexport {\n\taugmentOptFields,\n\tfieldsOf,\n\tparseOptFields,\n\tparseSelection,\n\tpick,\n\trequestedFields,\n\twidenSelection,\n\twithReferenceTypes,\n};\nexport type { RequiredFields, Selection };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { AsanaClient } from \"../asana/client.ts\";\nimport { AsanaApiError, isAbsent } from \"../asana/errors.ts\";\nimport { READ_OPERATIONS } from \"../catalog/object-operations.ts\";\nimport { type OperationId, OPERATIONS } from \"../catalog/operations.gen.ts\";\nimport { RESOURCES, type Resource } from \"../catalog/resources.ts\";\nimport { RESPONSE_SCHEMAS } from \"../catalog/schemas.gen.ts\";\nimport { type Logger, silentLogger } from \"../log.ts\";\nimport {\n\ttype Branch,\n\ttype Facts,\n\ttype ObjectState,\n\tWORKSPACE_BRANCH,\n\tworkspaceFacts,\n} from \"../policy/evaluate.ts\";\nimport { needsTaskChain, portfoliosNamed } from \"../policy/scope.ts\";\nimport type { CompiledWhere, Policy } from \"../policy/types.ts\";\nimport { TtlCache } from \"./cache.ts\";\nimport {\n\ttype AsanaObject,\n\tgidOf,\n\tgidsOf,\n\tisObject,\n\ttype Ref,\n\trefOf,\n\trefsOf,\n\tresourceOfType,\n\tstringOf,\n} from \"./objects.ts\";\nimport { PortfolioIndex } from \"./portfolio-index.ts\";\nimport {\n\tfieldsOf,\n\tparseSelection,\n\ttype Selection,\n\twidenSelection,\n\twithReferenceTypes,\n} from \"./selection.ts\";\n\n/** How deep the parent chain of a subtask is followed (Asana nests subtasks up to 5 levels). */\nconst MAX_PARENT_DEPTH = 5;\n\n/** `parent.`, `parent.parent.`, … up to {@link MAX_PARENT_DEPTH}. */\nconst ANCESTOR_PREFIXES: readonly string[] = Array.from({ length: MAX_PARENT_DEPTH }, (_, depth) =>\n\t\"parent.\".repeat(depth + 1),\n);\n\n/**\n * Which facts of a task the policy reads: a rule's `where` is the only\n * reader, so a fact no rule names is neither asked of Asana nor derived.\n * `asana-gate explain` shows them all.\n */\n/** The members of a task's custom fields that {@link customFieldValues} reads. */\nconst CUSTOM_FIELD_MEMBERS: readonly string[] = [\n\t\"custom_fields.gid\",\n\t\"custom_fields.display_value\",\n\t\"custom_fields.enum_value.gid\",\n\t\"custom_fields.enum_value.name\",\n\t\"custom_fields.multi_enum_values.gid\",\n\t\"custom_fields.multi_enum_values.name\",\n];\n\n/** A fact of a task a rule's `where` may name, and the members it is derived from. */\ninterface TaskFact {\n\treadonly named: (where: CompiledWhere) => boolean;\n\treadonly fields: readonly string[];\n}\n\n/** Every such fact, in the order their members are asked for. */\nconst TASK_FACTS = {\n\tcompleted: { named: (where) => where.completed !== undefined, fields: [\"completed\"] },\n\tcreatedBy: { named: (where) => where.createdBy !== undefined, fields: [\"created_by\"] },\n\tcreatedAt: { named: (where) => where.createdWithinMs !== undefined, fields: [\"created_at\"] },\n\tdue: {\n\t\tnamed: (where) => where.overdue !== undefined || where.dueWithinMs !== undefined,\n\t\tfields: [\"due_on\", \"due_at\"],\n\t},\n\ttags: { named: (where) => where.tags !== undefined, fields: [\"tags\"] },\n\tassignee: { named: (where) => where.assignees !== undefined, fields: [\"assignee\"] },\n\tcustomFields: {\n\t\tnamed: (where) => (where.customFields?.length ?? 0) > 0,\n\t\tfields: CUSTOM_FIELD_MEMBERS,\n\t},\n\t// The team comes with the placement (`memberships.project.team`); see taskFields.\n\tteam: { named: (where) => where.teams !== undefined, fields: [] },\n} as const satisfies Record<string, TaskFact>;\n\ntype TaskFactName = keyof typeof TASK_FACTS;\n\ntype TaskNeeds = Readonly<Record<TaskFactName, boolean>>;\n\nconst TASK_FACT_NAMES = Object.keys(TASK_FACTS) as TaskFactName[];\n\nconst needsWhere = (needed: (name: TaskFactName) => boolean): TaskNeeds =>\n\tObject.fromEntries(TASK_FACT_NAMES.map((name) => [name, needed(name)])) as TaskNeeds;\n\nconst EVERY_TASK_FACT = needsWhere(() => true);\n\nfunction taskNeedsOf(policy: Policy): TaskNeeds {\n\treturn needsWhere((name) => policy.rules.some((rule) => TASK_FACTS[name].named(rule.where)));\n}\n\n/** The `opt_fields` the loader needs on a task to derive the facts in `needs`. */\nfunction taskFields(needs: TaskNeeds): string[] {\n\tconst placement = (prefix: string): string[] => [\n\t\t`${prefix}memberships.project`,\n\t\t`${prefix}memberships.section`,\n\t\t// The project's team in the same response (honoured on GET /tasks/{gid} and\n\t\t// typeahead; verified live), so placing a task costs no request per project.\n\t\t...(needs.team ? [`${prefix}memberships.project.team`] : []),\n\t];\n\treturn [\n\t\t\"name\",\n\t\t\"workspace\",\n\t\t\"parent\",\n\t\t...placement(\"\"),\n\t\t...TASK_FACT_NAMES.flatMap((name) => (needs[name] ? TASK_FACTS[name].fields : [])),\n\t\t// The ancestor chain with each ancestor's placement, in the same response\n\t\t// (nested `parent.…` selections work; verified live). A subtask's facts then\n\t\t// cost no extra request.\n\t\t...ANCESTOR_PREFIXES.flatMap((prefix) => placement(prefix)),\n\t];\n}\n\n/** Per resource, the `opt_fields` {@link FactsLoader.fromObject} needs. */\nconst REQUIRED_FIELDS: Partial<Record<Resource, readonly string[]>> = {\n\t// Tasks: see taskFields.\n\t// `name` too: a `where: { name }` filter applies to projects and sections.\n\tproject: [\"name\", \"workspace\", \"team\"],\n\tsection: [\"name\", \"project\"],\n\tportfolio: [\"workspace\"],\n\tteam: [\"organization\"],\n\tgoal: [\"workspace\", \"team\"],\n\tstory: [\"target\"],\n\tattachment: [\"parent\"],\n\tstatus_update: [\"parent\"],\n\tproject_brief: [\"project\"],\n\twebhook: [\"resource\"],\n\ttime_tracking_entry: [\"task\"],\n\tallocation: [\"parent\"],\n\tbudget: [\"parent\"],\n\trate: [\"parent\"],\n\ttask_template: [\"project\"],\n\tproject_template: [\"team\"],\n\tgoal_relationship: [\"supported_goal\"],\n\tmembership: [\"parent\"],\n\tproject_membership: [\"parent\"],\n\tportfolio_membership: [\"portfolio\"],\n\tteam_membership: [\"team\"],\n\tworkspace_membership: [\"workspace\"],\n\tproject_portfolio_setting: [\"project\"],\n\ttag: [\"workspace\"],\n\tuser: [\"workspaces\"],\n\tuser_task_list: [\"workspace\"],\n\ttable: [\"workspace\"],\n\trecord: [\"workspace\"],\n\trole: [\"workspace\"],\n\ttimesheet_approval_status: [\"workspace\"],\n\tagent: [\"workspace\"],\n};\n\n/** Response schemas to use instead of the read operation's. */\nconst SCHEMA_OVERRIDES: Partial<Record<Resource, string>> = {\n\t// The full object names its project `project`; the compact one (lists) names it `parent`, which the gate requests.\n\tproject_membership: \"ProjectMembershipCompact\",\n};\n\n/** The operation that reads one object of `type` by gid, where the loader fetches it. */\nfunction readOperationOf(type: Resource): OperationId | undefined {\n\treturn READ_OPERATIONS[type];\n}\n\n/** The `GET /<path>/{gid}` of a resource, as the path prefix; `undefined` when it has none. */\nfunction objectPath(type: Resource): string | undefined {\n\tconst id = READ_OPERATIONS[type];\n\treturn id === undefined ? undefined : OPERATIONS[id].path.replace(/\\/\\{[^}]+\\}$/u, \"\");\n}\n\n/** The OpenAPI response schema that describes a resource's objects, when the catalog names one. */\nfunction responseSchemaOf(type: Resource): string | undefined {\n\tconst id = READ_OPERATIONS[type];\n\treturn (\n\t\tSCHEMA_OVERRIDES[type] ?? (id === undefined ? undefined : (RESPONSE_SCHEMAS[id] ?? undefined))\n\t);\n}\n\n/**\n * The `opt_fields` a list or object response of `type` must carry for\n * {@link FactsLoader.fromObject} to derive the task facts in `needs` (by\n * default, all of them).\n */\nfunction requiredFields(type: Resource, needs: TaskNeeds = EVERY_TASK_FACT): readonly string[] {\n\treturn type === \"task\" ? taskFields(needs) : (REQUIRED_FIELDS[type] ?? []);\n}\n\n/** A member the gate reads from objects of a resource, and the response schema that describes it. */\ninterface ReliedMember {\n\treadonly resource: Resource;\n\treadonly schema: string;\n\treadonly member: string;\n\t/** The member read inside it (`memberships.project` reads `project`), if any. */\n\treadonly nested: string | undefined;\n}\n\n/** Every member the gate reads, for each resource whose objects a response schema describes. */\nfunction reliedMembers(): ReliedMember[] {\n\treturn RESOURCES.flatMap((resource) => {\n\t\tconst schema = responseSchemaOf(resource);\n\t\treturn schema === undefined\n\t\t\t? []\n\t\t\t: requiredFields(resource).map((field) => {\n\t\t\t\t\tconst [member = field, nested] = field.split(\".\");\n\t\t\t\t\treturn { resource, schema, member, nested };\n\t\t\t\t});\n\t});\n}\n\n/** Types a `parent`-like reference of unknown type is probed as. */\nconst PARENT_TYPES: readonly Resource[] = [\"project\", \"portfolio\", \"goal\", \"task\", \"project_brief\"];\n\n/**\n * Per resource that lives inside another object, the members that may name\n * its container (first present wins) and the container's possible types.\n * Every other resource lives at workspace level.\n */\nconst CONTAINER_MEMBERS: Partial<\n\tRecord<Resource, { members: readonly string[]; types: readonly Resource[] }>\n> = {\n\tstory: { members: [\"target\"], types: [\"task\", \"goal\"] },\n\tattachment: { members: [\"parent\"], types: PARENT_TYPES },\n\tstatus_update: { members: [\"parent\"], types: PARENT_TYPES },\n\tallocation: { members: [\"parent\"], types: PARENT_TYPES },\n\tbudget: { members: [\"parent\"], types: PARENT_TYPES },\n\trate: { members: [\"parent\"], types: PARENT_TYPES },\n\tmembership: { members: [\"parent\"], types: PARENT_TYPES },\n\tproject_brief: { members: [\"project\"], types: [\"project\"] },\n\ttask_template: { members: [\"project\"], types: [\"project\"] },\n\tproject_portfolio_setting: { members: [\"project\"], types: [\"project\"] },\n\twebhook: { members: [\"resource\"], types: [\"project\", \"task\", \"portfolio\", \"goal\", \"team\"] },\n\ttime_tracking_entry: { members: [\"task\"], types: [\"task\"] },\n\tproject_template: { members: [\"team\"], types: [\"team\"] },\n\tgoal_relationship: { members: [\"supported_goal\"], types: [\"goal\"] },\n\tportfolio_membership: { members: [\"portfolio\"], types: [\"portfolio\"] },\n\tteam_membership: { members: [\"team\"], types: [\"team\"] },\n\t// A project membership names its project `parent` when compact and `project` when full (verified live).\n\tproject_membership: { members: [\"parent\", \"project\"], types: [\"project\"] },\n};\n\n/** Options for {@link FactsLoader}. */\ninterface FactsLoaderOptions {\n\tclient: AsanaClient;\n\tpolicy: Policy;\n\tlogger?: Logger;\n\t/** How long a fetched object is reused, in milliseconds. */\n\tobjectTtlMs?: number;\n\t/** How long a project (whose team rarely changes) is reused, in milliseconds. */\n\tprojectTtlMs?: number;\n\t/** How long the portfolio contents snapshot is reused, in milliseconds. */\n\tportfolioTtlMs?: number;\n\t/** Derive every fact of a task, not only those the policy reads (for `explain`). */\n\tallFacts?: boolean;\n}\n\n/** A loaded object together with its resolved facts. */\ninterface Loaded {\n\treadonly type: Resource;\n\treadonly object: AsanaObject;\n\treadonly facts: Facts;\n\t/** The loader's own fetch of the object, when `object` is a read of it with other fields. */\n\treadonly fetched?: AsanaObject;\n}\n\n/** One project a task belongs to, and the section within it. */\ninterface Membership {\n\treadonly project: string;\n\treadonly section: string | undefined;\n\t/** The project's team when the membership embeds it (`null`: none); `undefined` when it does not. */\n\treadonly team?: string | null;\n}\n\ninterface Placement {\n\treadonly chain: readonly string[];\n\treadonly memberships: readonly Membership[];\n}\n\n/** One object fetch: the object, its cache key, and the generation it was asked for under. */\ninterface Fetch {\n\treadonly type: Resource;\n\treadonly gid: string;\n\treadonly key: string;\n\treadonly generation: number;\n}\n\n/** The parent a task embeds together with its placement (`parent.memberships.*`), if any. */\nfunction embeddedParent(task: Readonly<AsanaObject>): AsanaObject | undefined {\n\treturn isObject(task.parent) && Array.isArray(task.parent.memberships) ? task.parent : undefined;\n}\n\n/** Whether a membership names both its project and its section, as the loader asks for them. */\nfunction namesPlacement(membership: unknown): boolean {\n\treturn isObject(membership) && \"project\" in membership && \"section\" in membership;\n}\n\n/** The project memberships of a task (or a task body), from its `memberships` member. */\nfunction membershipsOf(task: Readonly<AsanaObject>): Membership[] {\n\tif (!Array.isArray(task.memberships)) {\n\t\treturn [];\n\t}\n\treturn task.memberships\n\t\t.filter((m): m is AsanaObject => isObject(m))\n\t\t.map((m) => ({\n\t\t\tproject: gidOf(m.project),\n\t\t\tsection: gidOf(m.section),\n\t\t\t...(isObject(m.project) && \"team\" in m.project && { team: gidOf(m.project.team) ?? null }),\n\t\t}))\n\t\t.filter((m): m is Membership => m.project !== undefined);\n}\n\n/**\n * Whether a cached task's facts derive from the object `gid`: an ancestor in\n * the parent chain it embeds, or a project its memberships (or an\n * ancestor's) name, whose team they carry.\n */\nfunction derivesFrom(task: AsanaObject | null, gid: string): boolean {\n\tlet node: unknown = task;\n\tfor (let depth = 0; depth <= MAX_PARENT_DEPTH && isObject(node); depth += 1) {\n\t\tif (depth > 0 && gidOf(node) === gid) {\n\t\t\treturn true;\n\t\t}\n\t\tif (membershipsOf(node).some((membership) => membership.project === gid)) {\n\t\t\treturn true;\n\t\t}\n\t\tnode = node.parent;\n\t}\n\treturn false;\n}\n\nfunction customFieldValues(value: unknown): ReadonlyMap<string, ReadonlySet<string>> | undefined {\n\tif (!Array.isArray(value)) {\n\t\treturn undefined;\n\t}\n\tconst map = new Map<string, ReadonlySet<string>>();\n\tfor (const field of value.filter(\n\t\t(f): f is AsanaObject => isObject(f) && typeof f.gid === \"string\",\n\t)) {\n\t\tconst values = new Set<string>();\n\t\tconst display = stringOf(field.display_value);\n\t\tif (display !== undefined) {\n\t\t\tvalues.add(display);\n\t\t}\n\t\tconst options = [refOf(field.enum_value), ...refsOf(field.multi_enum_values)];\n\t\tfor (const option of options) {\n\t\t\tif (option !== undefined) {\n\t\t\t\tvalues.add(option.gid);\n\t\t\t\tif (option.name !== undefined) {\n\t\t\t\t\tvalues.add(option.name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tmap.set(stringOf(field.gid) ?? \"\", values);\n\t}\n\treturn map;\n}\n\n/** The state predicates can see on a task (or a task body). */\nfunction taskState(task: Readonly<AsanaObject>): ObjectState {\n\tconst createdBy = gidOf(task.created_by);\n\tconst name = stringOf(task.name);\n\t// Asana sets `due_on` (the local date) whenever `due_at` is set; the instant is more precise.\n\tconst dueOn = stringOf(task.due_at) ?? stringOf(task.due_on);\n\tconst createdAt = stringOf(task.created_at);\n\treturn {\n\t\t...(name !== undefined && { name }),\n\t\t...(createdBy !== undefined && { createdBy }),\n\t\t...(typeof task.completed === \"boolean\" && { completed: task.completed }),\n\t\thasParent: gidOf(task.parent) !== undefined,\n\t\tdueOn: dueOn ?? null,\n\t\t...(createdAt !== undefined && { createdAt }),\n\t};\n}\n\n/**\n * Derives the facts (hierarchical placement and cross-cutting attributes) of\n * Asana objects, fetching from the API as needed and caching the results.\n */\nclass FactsLoader {\n\tprivate readonly client: AsanaClient;\n\tprivate readonly policy: Policy;\n\tprivate readonly logger: Logger;\n\tprivate readonly objects: TtlCache<AsanaObject | null>;\n\tprivate readonly projectTtlMs: number;\n\t/** Fetches under way (per object and generation, and per fields for reads), so concurrent requests share a call. */\n\tprivate readonly inflight = new Map<string, Promise<AsanaObject | undefined>>();\n\t/**\n\t * Per object, bumped by every invalidation: a fetch that started before a\n\t * write is not cached after it, and later lookups do not join it.\n\t */\n\tprivate readonly generations = new Map<string, number>();\n\tprivate readonly portfolios: PortfolioIndex;\n\t/** Whether a rule names a task or a subtree, so a task's ancestors must be known. */\n\tprivate readonly needsTaskChain: boolean;\n\tprivate readonly needs: TaskNeeds;\n\t/** The `opt_fields` a task's facts need under this policy (see taskFields). */\n\tprivate readonly taskFields: readonly string[];\n\tprivate readonly members = new Map<Resource, ReadonlySet<string>>();\n\n\tpublic constructor(options: FactsLoaderOptions) {\n\t\tthis.client = options.client;\n\t\tthis.policy = options.policy;\n\t\tthis.needs = options.allFacts === true ? EVERY_TASK_FACT : taskNeedsOf(options.policy);\n\t\tthis.taskFields = taskFields(this.needs);\n\t\tthis.logger = options.logger ?? silentLogger;\n\t\tthis.objects = new TtlCache(options.objectTtlMs ?? 30_000);\n\t\tthis.projectTtlMs = options.projectTtlMs ?? 300_000;\n\t\tthis.needsTaskChain = needsTaskChain(this.policy);\n\t\tthis.portfolios = new PortfolioIndex({\n\t\t\tclient: this.client,\n\t\t\troots: portfoliosNamed(this.policy),\n\t\t\tttlMs: options.portfolioTtlMs ?? 300_000,\n\t\t\tlogger: this.logger,\n\t\t});\n\t}\n\n\t/**\n\t * Loads an object by gid and derives its facts. Resolves to `undefined`\n\t * when Asana reports it missing or inaccessible, which the gate treats\n\t * exactly like an invisible object.\n\t */\n\tpublic async load(type: Resource, gid: string): Promise<Loaded | undefined> {\n\t\tif (type === \"workspace\") {\n\t\t\treturn { type, object: { gid, resource_type: \"workspace\" }, facts: workspaceFacts(gid) };\n\t\t}\n\t\tif (objectPath(type) === undefined) {\n\t\t\t// No GET-by-gid exists for this type; it lives at workspace level.\n\t\t\treturn { type, object: { gid }, facts: workspaceFacts(this.policy.workspace) };\n\t\t}\n\t\tconst object = await this.fetchObject(type, gid);\n\t\tif (object === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst facts = await this.fromObject(type, object);\n\t\treturn facts === undefined ? undefined : { type, object, facts };\n\t}\n\n\t/**\n\t * Reads an object afresh to answer a request for it and to judge it, in\n\t * one request: the fields sent are the caller's `selection` together with\n\t * what the facts need (none, for the whole object, when the caller names\n\t * none), and the object comes back as Asana sent it, for the gate to check\n\t * and then cut back to the caller's selection. When the response cannot\n\t * carry what the facts need (the caller selects alone a member they read\n\t * inside) or does not (Asana left a member out), the facts are loaded as\n\t * {@link load} does. Resolves to `undefined` when Asana reports the\n\t * object missing or inaccessible.\n\t */\n\tpublic async read(\n\t\ttype: Resource,\n\t\tgid: string,\n\t\tselection: Selection | undefined,\n\t): Promise<Loaded | undefined> {\n\t\tconst needed = parseSelection([\"name\", ...this.requiredFields(type)]) ?? new Map();\n\t\tconst widened = selection === undefined ? undefined : widenSelection(selection, needed);\n\t\tconst complete = widened?.complete ?? true;\n\t\tconst key = `${type}:${gid}`;\n\t\tconst fetch = { type, gid, key, generation: this.generations.get(key) ?? 0 };\n\t\tconst sent = widened === undefined ? undefined : withReferenceTypes(fieldsOf(widened.sent));\n\t\tconst derivable = (object: AsanaObject): boolean => complete && this.carries(type, object);\n\t\t// Reads of one object with the same fields under way together (a batch naming it twice)\n\t\t// share one request: it was still sent after each of them arrived.\n\t\tconst flight = `${key}#${fetch.generation}?${sent?.join(\",\") ?? \"\"}`;\n\t\tconst read = this.shared(flight, () => this.fetchFresh(fetch, sent, derivable));\n\t\tif (!complete) {\n\t\t\t// The response cannot carry what the facts need: they are loaded alongside.\n\t\t\treturn this.besides(type, gid, read);\n\t\t}\n\t\tconst object = await read;\n\t\tif (object === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (derivable(object)) {\n\t\t\tconst facts = await this.fromObject(type, object);\n\t\t\treturn facts === undefined ? undefined : { type, object, facts };\n\t\t}\n\t\treturn this.besides(type, gid, Promise.resolve(object));\n\t}\n\n\t/**\n\t * The object `read` brings back, judged by the facts {@link load} derives;\n\t * what the read finds (absence, an error) comes first.\n\t */\n\tprivate async besides(\n\t\ttype: Resource,\n\t\tgid: string,\n\t\tread: Promise<AsanaObject | undefined>,\n\t): Promise<Loaded | undefined> {\n\t\tconst [fresh, loaded] = await Promise.allSettled([read, this.load(type, gid)]);\n\t\tif (fresh.status === \"rejected\") {\n\t\t\tthrow fresh.reason;\n\t\t}\n\t\tif (fresh.value === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (loaded.status === \"rejected\") {\n\t\t\tthrow loaded.reason;\n\t\t}\n\t\treturn loaded.value === undefined\n\t\t\t? undefined\n\t\t\t: { type, object: fresh.value, facts: loaded.value.facts, fetched: loaded.value.object };\n\t}\n\n\t/**\n\t * Whether an object carries every member {@link fromObject} reads for\n\t * `type` (a response may lack one whose selection Asana did not honour); a\n\t * task must also carry its placement ({@link carriesPlacement}), or a\n\t * membership naming no section would pass for one outside any section.\n\t */\n\tpublic carries(type: Resource, object: AsanaObject): boolean {\n\t\tconst members = this.topMembers(type);\n\t\tif (![...members].every((member) => member in object)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn type !== \"task\" || this.carriesPlacement(object);\n\t}\n\n\t/** The `opt_fields` objects of `type` must carry for this loader (and its policy) to derive their facts. */\n\tpublic requiredFields(type: Resource): readonly string[] {\n\t\treturn type === \"task\" ? this.taskFields : requiredFields(type);\n\t}\n\n\t/** The top-level members of {@link requiredFields}, worked out once per type. */\n\tprivate topMembers(type: Resource): ReadonlySet<string> {\n\t\tlet members = this.members.get(type);\n\t\tif (members === undefined) {\n\t\t\tmembers = new Set(this.requiredFields(type).map((field) => field.split(\".\")[0] ?? field));\n\t\t\tthis.members.set(type, members);\n\t\t}\n\t\treturn members;\n\t}\n\n\t/**\n\t * Returns the first of `types` (in their order) that exists for `gid`.\n\t * The first type is tried alone, since the lists put the likely one first\n\t * and a hit then costs one request; the rest are tried at once, so a miss\n\t * costs one more round trip instead of one per type (the client keeps\n\t * them within Asana's 50 concurrent reads). The answer, and an error,\n\t * are what trying one type after another would give: an error counts only\n\t * when no earlier type exists.\n\t */\n\tpublic async probe(gid: string, types: readonly Resource[]): Promise<Loaded | undefined> {\n\t\tconst [first, ...rest] = types;\n\t\tif (first === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst loaded = await this.loadOrUnpaid(first, gid);\n\t\tif (loaded !== undefined) {\n\t\t\treturn loaded;\n\t\t}\n\t\tconst settled = await Promise.allSettled(rest.map((type) => this.loadOrUnpaid(type, gid)));\n\t\tfor (const result of settled) {\n\t\t\tif (result.status === \"rejected\") {\n\t\t\t\tthrow result.reason;\n\t\t\t}\n\t\t\tif (result.value !== undefined) {\n\t\t\t\treturn result.value;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/** Loads a probe candidate; a type the workspace's plan does not offer (402) is not this object's. */\n\tprivate async loadOrUnpaid(type: Resource, gid: string): Promise<Loaded | undefined> {\n\t\ttry {\n\t\t\treturn await this.load(type, gid);\n\t\t} catch (error) {\n\t\t\tif (error instanceof AsanaApiError && error.status === 402) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Whether a task carries everything its placement derives from, so that\n\t * {@link fromObject} judges it as it would the loader's own fetch of it:\n\t * its memberships, each naming its project and section, and, as far as\n\t * its placement follows the parent chain, a `parent` member on it and on\n\t * every ancestor it embeds (`null` at the root; a parent named without\n\t * its placement is fetched). A member that is not there is unknown, not\n\t * empty.\n\t */\n\tpublic carriesPlacement(task: Readonly<AsanaObject>, depth = 0): boolean {\n\t\tif (!Array.isArray(task.memberships) || !task.memberships.every(namesPlacement)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!this.followsParent(membershipsOf(task), depth)) {\n\t\t\treturn true;\n\t\t}\n\t\tif (!(\"parent\" in task)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst parent = embeddedParent(task);\n\t\treturn parent === undefined || this.carriesPlacement(parent, depth + 1);\n\t}\n\n\t/**\n\t * The ancestors a task embeds that carry their placement\n\t * ({@link carriesPlacement}), by gid. The loader's own fetch of a task\n\t * embeds them (`parent.…memberships.*`), so a reference to one of them\n\t * is judged without a fetch of its own.\n\t */\n\tpublic placedAncestors(task: Readonly<AsanaObject>): ReadonlyMap<string, AsanaObject> {\n\t\tconst placed = new Map<string, AsanaObject>();\n\t\tfor (let parent = embeddedParent(task); parent !== undefined; parent = embeddedParent(parent)) {\n\t\t\tconst gid = stringOf(parent.gid);\n\t\t\tif (gid !== undefined && this.carriesPlacement(parent)) {\n\t\t\t\tplaced.set(gid, parent);\n\t\t\t}\n\t\t}\n\t\treturn placed;\n\t}\n\n\t/** Loads the object a reference points at; `fallback` types are probed when it carries no known type. */\n\tpublic loadRef(ref: Ref, fallback: readonly Resource[]): Promise<Loaded | undefined> {\n\t\tconst type = resourceOfType(ref.resource_type);\n\t\treturn type === undefined ? this.probe(ref.gid, fallback) : this.load(type, ref.gid);\n\t}\n\n\t/**\n\t * Derives the facts of an already-fetched object that carries the fields\n\t * of {@link requiredFields}. Resolves to `undefined` when a container the\n\t * object points at cannot be loaded.\n\t */\n\tpublic fromObject(type: Resource, object: AsanaObject): Promise<Facts | undefined> {\n\t\tswitch (type) {\n\t\t\tcase \"task\": {\n\t\t\t\treturn this.taskFacts(object);\n\t\t\t}\n\t\t\tcase \"project\": {\n\t\t\t\treturn this.projectFacts(object);\n\t\t\t}\n\t\t\tcase \"section\": {\n\t\t\t\treturn this.sectionFacts(object);\n\t\t\t}\n\t\t\tcase \"portfolio\": {\n\t\t\t\treturn this.portfolioFacts(object);\n\t\t\t}\n\t\t\tcase \"team\": {\n\t\t\t\treturn Promise.resolve(this.teamFacts(object));\n\t\t\t}\n\t\t\tcase \"goal\": {\n\t\t\t\treturn Promise.resolve(this.goalFacts(object));\n\t\t\t}\n\t\t\tcase \"user\": {\n\t\t\t\treturn Promise.resolve(this.userFacts(object));\n\t\t\t}\n\t\t\tcase \"workspace\": {\n\t\t\t\treturn Promise.resolve(workspaceFacts(stringOf(object.gid) ?? this.policy.workspace));\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\treturn this.derivedFacts(type, object);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Facts of objects that live inside another object (stories, webhooks, memberships, …) or at workspace level. */\n\tprivate derivedFacts(type: Resource, object: AsanaObject): Promise<Facts | undefined> {\n\t\tconst container = CONTAINER_MEMBERS[type];\n\t\tif (container === undefined) {\n\t\t\treturn Promise.resolve(workspaceFacts(gidOf(object.workspace) ?? this.policy.workspace));\n\t\t}\n\t\tconst member = container.members.find((name) => refOf(object[name]) !== undefined);\n\t\treturn this.factsOfRef(\n\t\t\tmember === undefined ? undefined : refOf(object[member]),\n\t\t\tcontainer.types,\n\t\t);\n\t}\n\n\t/**\n\t * Forgets a cached object after it was modified. A task's cached\n\t * descendants go too: they carry its placement in their ancestor chain.\n\t */\n\tpublic invalidate(type: Resource, gid: string): void {\n\t\tconst key = `${type}:${gid}`;\n\t\tthis.objects.delete(key);\n\t\tthis.bump(key);\n\t\tif (type === \"task\" || type === \"project\") {\n\t\t\tconst dependents = this.objects.deleteWhere(\n\t\t\t\t(cachedKey, object) => cachedKey.startsWith(\"task:\") && derivesFrom(object, gid),\n\t\t\t);\n\t\t\tfor (const dependent of dependents) {\n\t\t\t\tthis.bump(dependent);\n\t\t\t}\n\t\t}\n\t\tif (type === \"portfolio\") {\n\t\t\tthis.portfolios.invalidateFor(gid);\n\t\t}\n\t}\n\n\t/**\n\t * Records a write to `key`, so that a fetch of it under way does not cache\n\t * what it brings back; with none under way there is nothing to record (the\n\t * cached copy is gone), which keeps the record as small as the fetches.\n\t */\n\tprivate bump(key: string): void {\n\t\tif (this.fetching(key)) {\n\t\t\tthis.generations.set(key, (this.generations.get(key) ?? 0) + 1);\n\t\t}\n\t}\n\n\tprivate fetching(key: string): boolean {\n\t\treturn [...this.inflight.keys()].some((flight) => flight.startsWith(`${key}#`));\n\t}\n\n\tprivate fetchObject(type: Resource, gid: string): Promise<AsanaObject | undefined> {\n\t\tconst key = `${type}:${gid}`;\n\t\tconst cached = this.objects.get(key);\n\t\tif (cached !== undefined) {\n\t\t\treturn Promise.resolve(cached ?? undefined);\n\t\t}\n\t\tconst generation = this.generations.get(key) ?? 0;\n\t\tconst fetch = { type, gid, key, generation };\n\t\treturn this.shared(`${key}#${generation}`, () => this.fetchUncached(fetch));\n\t}\n\n\t/** The fetch under way for `flight`, or a new one: concurrent requests for one object share a call. */\n\tprivate shared(\n\t\tflight: string,\n\t\tstart: () => Promise<AsanaObject | undefined>,\n\t): Promise<AsanaObject | undefined> {\n\t\tlet pending = this.inflight.get(flight);\n\t\tif (pending === undefined) {\n\t\t\tpending = this.landed(flight, start());\n\t\t\tthis.inflight.set(flight, pending);\n\t\t}\n\t\treturn pending;\n\t}\n\n\tprivate async landed(\n\t\tflight: string,\n\t\tpending: Promise<AsanaObject | undefined>,\n\t): Promise<AsanaObject | undefined> {\n\t\ttry {\n\t\t\treturn await pending;\n\t\t} finally {\n\t\t\tthis.inflight.delete(flight);\n\t\t\tconst key = flight.slice(0, flight.indexOf(\"#\"));\n\t\t\tif (!this.fetching(key)) {\n\t\t\t\tthis.generations.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate fetchUncached(fetch: Fetch): Promise<AsanaObject | undefined> {\n\t\tconst fields = this.requiredFields(fetch.type);\n\t\tconst sent = fields.length > 0 ? [...new Set([\"name\", ...fields])] : undefined;\n\t\treturn this.fetchFresh(fetch, sent, () => true);\n\t}\n\n\t/**\n\t * GETs an object with `fields` (the whole object without), and caches it,\n\t * or its absence, unless a write made it stale meanwhile or it is not\n\t * `cacheable`.\n\t */\n\tprivate async fetchFresh(\n\t\tfetch: Fetch,\n\t\tfields: readonly string[] | undefined,\n\t\tcacheable: (object: AsanaObject) => boolean,\n\t): Promise<AsanaObject | undefined> {\n\t\tconst { type, gid, key, generation } = fetch;\n\t\tconst path = objectPath(type);\n\t\t// A gid with a lone surrogate cannot be sent, and names nothing.\n\t\tif (path === undefined || !gid.isWellFormed()) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst ttl = type === \"project\" ? this.projectTtlMs : undefined;\n\t\t// Cache only what no write has made stale since the fetch began.\n\t\tconst keep = (value: AsanaObject | null): void => {\n\t\t\tif ((this.generations.get(key) ?? 0) === generation) {\n\t\t\t\tthis.objects.set(key, value, ttl);\n\t\t\t}\n\t\t};\n\t\ttry {\n\t\t\tconst object = await this.client.get<AsanaObject>(`${path}/${encodeURIComponent(gid)}`, {\n\t\t\t\t...(fields !== undefined && { opt_fields: fields }),\n\t\t\t});\n\t\t\tif (cacheable(object)) {\n\t\t\t\tkeep(object);\n\t\t\t}\n\t\t\treturn object;\n\t\t} catch (error) {\n\t\t\tif (isAbsent(error)) {\n\t\t\t\tthis.logger.debug(\n\t\t\t\t\t`${type} ${gid}: Asana responded ${error.status}; treating as nonexistent`,\n\t\t\t\t);\n\t\t\t\tkeep(null);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/** Facts of the object a reference points at (the workspace's when there is none). */\n\tprivate async factsOfRef(\n\t\tref: Ref | undefined,\n\t\tfallback: readonly Resource[],\n\t): Promise<Facts | undefined> {\n\t\tif (ref === undefined) {\n\t\t\treturn workspaceFacts(this.policy.workspace);\n\t\t}\n\t\tconst loaded = await this.loadRef(ref, fallback);\n\t\treturn loaded?.facts;\n\t}\n\n\tprivate async projectBranch(membership: Membership, chain: readonly string[]): Promise<Branch> {\n\t\tconst [team, portfolios] = await Promise.all([\n\t\t\tthis.teamOf(membership),\n\t\t\tthis.portfolios.containing(membership.project),\n\t\t]);\n\t\treturn {\n\t\t\t...(team !== undefined && { team }),\n\t\t\tportfolios,\n\t\t\tproject: membership.project,\n\t\t\t...(membership.section !== undefined && { section: membership.section }),\n\t\t\ttaskChain: chain,\n\t\t\tunhomed: false,\n\t\t};\n\t}\n\n\t/** Whether a task's placement takes in its parent's: it has no project of its own, or a rule names tasks. */\n\tprivate followsParent(memberships: readonly Membership[], depth: number): boolean {\n\t\treturn depth < MAX_PARENT_DEPTH && (memberships.length === 0 || this.needsTaskChain);\n\t}\n\n\t/**\n\t * The team of a task's project: from the membership when the response\n\t * embeds it, otherwise from the project itself; not looked up at all when\n\t * no rule names a team.\n\t */\n\tprivate async teamOf(membership: Membership): Promise<string | undefined> {\n\t\tif (!this.needs.team) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (membership.team !== undefined) {\n\t\t\treturn membership.team ?? undefined;\n\t\t}\n\t\tconst project = await this.fetchObject(\"project\", membership.project);\n\t\treturn project === undefined ? undefined : gidOf(project.team);\n\t}\n\n\tprivate async resolvePlacement(\n\t\ttask: AsanaObject,\n\t\tchain: readonly string[],\n\t\tdepth: number,\n\t): Promise<Placement> {\n\t\tconst memberships = membershipsOf(task);\n\t\tconst parent = gidOf(task.parent);\n\t\tif (parent === undefined || !this.followsParent(memberships, depth)) {\n\t\t\treturn { chain, memberships };\n\t\t}\n\t\t// Prefer the parent embedded in the response; fetch only when it lacks placement data.\n\t\tconst parentTask = embeddedParent(task) ?? (await this.fetchObject(\"task\", parent));\n\t\tif (parentTask === undefined) {\n\t\t\treturn { chain, memberships };\n\t\t}\n\t\tconst inherited = await this.resolvePlacement(parentTask, [...chain, parent], depth + 1);\n\t\treturn {\n\t\t\tchain: inherited.chain,\n\t\t\tmemberships: memberships.length > 0 ? memberships : inherited.memberships,\n\t\t};\n\t}\n\n\tprivate async taskFacts(task: AsanaObject): Promise<Facts> {\n\t\tconst gid = stringOf(task.gid) ?? \"\";\n\t\tconst placement = await this.resolvePlacement(task, [gid], 0);\n\t\tconst branches: Branch[] =\n\t\t\tplacement.memberships.length > 0\n\t\t\t\t? await Promise.all(\n\t\t\t\t\t\tplacement.memberships.map((m) => this.projectBranch(m, placement.chain)),\n\t\t\t\t\t)\n\t\t\t\t: [{ ...WORKSPACE_BRANCH, taskChain: placement.chain, unhomed: true }];\n\t\tconst customFields = customFieldValues(task.custom_fields);\n\t\treturn {\n\t\t\tworkspace: gidOf(task.workspace) ?? this.policy.workspace,\n\t\t\tbranches,\n\t\t\t// Only what the response carries: the loader asks for what the policy reads.\n\t\t\t...(\"tags\" in task && { tags: new Set(gidsOf(task.tags)) }),\n\t\t\t...(\"assignee\" in task && { assignee: gidOf(task.assignee) ?? null }),\n\t\t\t...(customFields && { customFields }),\n\t\t\tstate: taskState(task),\n\t\t};\n\t}\n\n\tprivate async projectFacts(project: AsanaObject): Promise<Facts | undefined> {\n\t\tconst gid = stringOf(project.gid);\n\t\tif (gid === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst team = gidOf(project.team);\n\t\tconst branch: Branch = {\n\t\t\t...(team !== undefined && { team }),\n\t\t\tportfolios: await this.portfolios.containing(gid),\n\t\t\tproject: gid,\n\t\t\ttaskChain: [],\n\t\t\tunhomed: false,\n\t\t};\n\t\tconst name = stringOf(project.name);\n\t\treturn {\n\t\t\tworkspace: gidOf(project.workspace) ?? this.policy.workspace,\n\t\t\tbranches: [branch],\n\t\t\t...(name !== undefined && { state: { name } }),\n\t\t};\n\t}\n\n\tprivate async sectionFacts(section: AsanaObject): Promise<Facts | undefined> {\n\t\tconst gid = stringOf(section.gid);\n\t\tconst project = gidOf(section.project);\n\t\tif (gid === undefined || project === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst loaded = await this.load(\"project\", project);\n\t\tif (loaded === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst name = stringOf(section.name);\n\t\treturn {\n\t\t\t...loaded.facts,\n\t\t\tbranches: loaded.facts.branches.map((branch) => ({ ...branch, section: gid })),\n\t\t\t...(name !== undefined && { state: { name } }),\n\t\t};\n\t}\n\n\tprivate async portfolioFacts(portfolio: AsanaObject): Promise<Facts | undefined> {\n\t\tconst gid = stringOf(portfolio.gid);\n\t\tif (gid === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tworkspace: gidOf(portfolio.workspace) ?? this.policy.workspace,\n\t\t\tbranches: [{ ...WORKSPACE_BRANCH, portfolios: await this.portfolios.lineageOf(gid) }],\n\t\t};\n\t}\n\n\tprivate teamFacts(team: AsanaObject): Facts | undefined {\n\t\tconst gid = stringOf(team.gid);\n\t\tif (gid === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tworkspace: gidOf(team.organization) ?? this.policy.workspace,\n\t\t\tbranches: [{ ...WORKSPACE_BRANCH, team: gid }],\n\t\t};\n\t}\n\n\tprivate goalFacts(goal: AsanaObject): Facts {\n\t\tconst team = gidOf(goal.team);\n\t\treturn {\n\t\t\tworkspace: gidOf(goal.workspace) ?? this.policy.workspace,\n\t\t\tbranches: [{ ...WORKSPACE_BRANCH, ...(team !== undefined && { team }) }],\n\t\t};\n\t}\n\n\tprivate userFacts(user: AsanaObject): Facts {\n\t\tconst workspaces = gidsOf(user.workspaces);\n\t\t// Without the opt-in `workspaces` member we cannot tell; trust the token's scope.\n\t\tconst member = workspaces.length === 0 || workspaces.includes(this.policy.workspace);\n\t\treturn workspaceFacts(member ? this.policy.workspace : \"\");\n\t}\n}\n\nexport {\n\tFactsLoader,\n\tmembershipsOf,\n\tPARENT_TYPES,\n\treadOperationOf,\n\treliedMembers,\n\trequiredFields,\n\tresponseSchemaOf,\n\ttaskState,\n};\nexport type { FactsLoaderOptions, Loaded, Membership, ReliedMember, TaskNeeds };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport { isObject } from \"../json.ts\";\nimport { resolveDateBound } from \"./durations.ts\";\n\n/**\n * The content constraints a rule may carry (require / apply / forbid /\n * redact / limit / confirm): the small evaluators that turn one requirement\n * or application into a verdict or a changed request body. They know nothing\n * about Asana; the gate feeds them request bodies and scopes.\n */\n\n/** A scalar a policy may name as a value. */\ntype Scalar = string | number | boolean;\n\n/** One requirement on a request member. Every operator present must hold. */\ninterface FieldRequirement {\n\t/** On create the member must be set and non-empty; on update it may not be cleared. */\n\treadonly present?: boolean;\n\treadonly prefix?: string;\n\treadonly suffix?: string;\n\treadonly contains?: string;\n\treadonly matches?: RegExp;\n\treadonly notMatches?: RegExp;\n\treadonly in?: ReadonlySet<string>;\n\treadonly notIn?: ReadonlySet<string>;\n\treadonly minLength?: number;\n\treadonly maxLength?: number;\n\t/** A number, or a date (`YYYY-MM-DD`, ISO 8601, `today`, `now`, `+7d`, `-1d`). */\n\treadonly min?: Scalar;\n\treadonly max?: Scalar;\n}\n\n/** One application to a request member. */\ninterface FieldApplication {\n\t/** Set when the member is absent or empty. */\n\treadonly default?: Scalar | readonly Scalar[];\n\t/** Always set, overriding what the request says. */\n\treadonly value?: Scalar | readonly Scalar[];\n\t/** Prepend to a string member unless it already starts with it. */\n\treadonly prefix?: string;\n\t/** Append to a string member unless it already ends with it. */\n\treadonly suffix?: string;\n\t/** Make sure a list member contains these values. */\n\treadonly add?: readonly Scalar[];\n}\n\n/** A rate limit: at most `max` requests per `perMs` milliseconds (`per` as written, for messages). */\ninterface RateLimit {\n\treadonly max: number;\n\treadonly perMs: number;\n\treadonly per: string;\n}\n\n/** Whether a request creates or updates the object. */\ntype Verb = \"create\" | \"update\";\n\n/** The verdict of one requirement: why it does not hold. */\ntype Violation = string;\n\n/** Whether a request value counts as empty (absent, null, \"\", []). */\nfunction isEmpty(value: unknown): boolean {\n\treturn (\n\t\tvalue === undefined ||\n\t\tvalue === null ||\n\t\t(typeof value === \"string\" && value.trim() === \"\") ||\n\t\t(Array.isArray(value) && value.length === 0)\n\t);\n}\n\n/** The text of one scalar or reference value, if it has one. */\nfunction textOf(value: unknown): string | undefined {\n\tif (typeof value === \"string\") {\n\t\treturn value;\n\t}\n\tif (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\treturn String(value);\n\t}\n\tif (isObject(value)) {\n\t\treturn typeof value.gid === \"string\" ? value.gid : undefined;\n\t}\n\treturn undefined;\n}\n\n/** The strings a value is compared with: the value itself, a reference's gid, or each list element. */\nfunction textsOf(value: unknown): string[] {\n\tconst items: unknown[] = Array.isArray(value) ? value : [value];\n\treturn items.map((item) => textOf(item)).filter((text): text is string => text !== undefined);\n}\n\n/** Checks a string member against the text operators. */\nfunction textViolations(text: string, requirement: FieldRequirement): Violation[] {\n\tconst checks: [boolean, string][] = [\n\t\t[\n\t\t\trequirement.prefix === undefined || text.startsWith(requirement.prefix),\n\t\t\t`must start with \"${requirement.prefix ?? \"\"}\"`,\n\t\t],\n\t\t[\n\t\t\trequirement.suffix === undefined || text.endsWith(requirement.suffix),\n\t\t\t`must end with \"${requirement.suffix ?? \"\"}\"`,\n\t\t],\n\t\t[\n\t\t\trequirement.contains === undefined || text.includes(requirement.contains),\n\t\t\t`must contain \"${requirement.contains ?? \"\"}\"`,\n\t\t],\n\t\t[\n\t\t\trequirement.matches === undefined || requirement.matches.test(text),\n\t\t\t`must match ${String(requirement.matches)}`,\n\t\t],\n\t\t[\n\t\t\trequirement.notMatches === undefined || !requirement.notMatches.test(text),\n\t\t\t`must not match ${String(requirement.notMatches)}`,\n\t\t],\n\t\t[\n\t\t\trequirement.minLength === undefined || text.length >= requirement.minLength,\n\t\t\t`must be at least ${requirement.minLength ?? 0} characters`,\n\t\t],\n\t\t[\n\t\t\trequirement.maxLength === undefined || text.length <= requirement.maxLength,\n\t\t\t`must be at most ${requirement.maxLength ?? 0} characters`,\n\t\t],\n\t];\n\treturn checks.filter(([ok]) => !ok).map(([, message]) => message);\n}\n\n/** Checks the value(s) of a member against the `in` / `not_in` sets. */\nfunction setViolations(texts: readonly string[], requirement: FieldRequirement): Violation[] {\n\tconst violations: Violation[] = [];\n\tconst allowed = requirement.in;\n\tif (allowed !== undefined && texts.some((text) => !allowed.has(text))) {\n\t\tviolations.push(`must be one of ${[...allowed].join(\", \")}`);\n\t}\n\tconst denied = requirement.notIn;\n\tif (denied !== undefined && texts.some((text) => denied.has(text))) {\n\t\tviolations.push(`must not be one of ${[...denied].join(\", \")}`);\n\t}\n\treturn violations;\n}\n\n/** A date without a time of day (`due_on`), compared as a calendar day. */\nconst DATE_ONLY = /^\\d{4}-\\d{2}-\\d{2}$/u;\n\nconst DAY_MS = 86_400_000;\n\n/** Compares a number or date member with a bound. */\nfunction boundViolation(\n\tvalue: unknown,\n\tbound: { limit: Scalar; kind: \"min\" | \"max\" },\n\tnow: Date,\n): Violation | undefined {\n\tconst atLeast = bound.kind === \"min\";\n\tif (typeof bound.limit === \"number\" && typeof value === \"number\") {\n\t\tconst ok = atLeast ? value >= bound.limit : value <= bound.limit;\n\t\treturn ok ? undefined : `must be ${atLeast ? \"at least\" : \"at most\"} ${bound.limit}`;\n\t}\n\tconst limit = typeof bound.limit === \"string\" ? resolveDateBound(bound.limit, now) : undefined;\n\tconst actual = typeof value === \"string\" ? Date.parse(value) : Number.NaN;\n\tif (limit === undefined || Number.isNaN(actual)) {\n\t\treturn `must be comparable with ${String(bound.limit)}`;\n\t}\n\t// A date-only member is a whole (UTC) day: `now`, `+7d` and `-1d` stand for\n\t// the day they fall on, so `min: \"+7d\"` admits the date seven days out.\n\tconst day = typeof value === \"string\" && DATE_ONLY.test(value);\n\tconst [left, right] = day\n\t\t? [Math.floor(actual / DAY_MS), Math.floor(limit / DAY_MS)]\n\t\t: [actual, limit];\n\tconst ok = atLeast ? left >= right : left <= right;\n\treturn ok\n\t\t? undefined\n\t\t: `must be ${atLeast ? \"on or after\" : \"on or before\"} ${String(bound.limit)}`;\n}\n\n/**\n * Checks a request member against a requirement. `verb` decides what\n * `present` means. `value` is the member as sent (`undefined` when absent).\n */\nfunction checkRequirement(\n\tvalue: unknown,\n\trequirement: FieldRequirement,\n\tcontext: { verb: Verb; now?: Date },\n): Violation[] {\n\tconst violations: Violation[] = [];\n\tconst now = context.now ?? new Date();\n\tif (\n\t\trequirement.present === true &&\n\t\tisEmpty(value) &&\n\t\t(context.verb === \"create\" || value !== undefined)\n\t) {\n\t\tviolations.push(context.verb === \"create\" ? \"is required\" : \"cannot be cleared\");\n\t}\n\tif (value === undefined || value === null) {\n\t\treturn violations;\n\t}\n\tif (typeof value === \"string\") {\n\t\tviolations.push(...textViolations(value, requirement));\n\t}\n\tviolations.push(...setViolations(textsOf(value), requirement));\n\tfor (const kind of [\"min\", \"max\"] as const) {\n\t\tconst limit = requirement[kind];\n\t\tconst violation = limit === undefined ? undefined : boundViolation(value, { limit, kind }, now);\n\t\tif (violation !== undefined) {\n\t\t\tviolations.push(violation);\n\t\t}\n\t}\n\treturn violations;\n}\n\n/** The value after `value` / `default`. */\nfunction applyValue(value: unknown, application: FieldApplication, verb: Verb): unknown {\n\tif (application.value !== undefined) {\n\t\treturn application.value;\n\t}\n\tif (\n\t\tapplication.default !== undefined &&\n\t\tisEmpty(value) &&\n\t\t(verb === \"create\" || value !== undefined)\n\t) {\n\t\treturn application.default;\n\t}\n\treturn value;\n}\n\n/** The list after `add`. */\nfunction applyAdd(value: unknown, add: readonly Scalar[]): unknown[] {\n\tlet list: unknown[] = [];\n\tif (Array.isArray(value)) {\n\t\tlist = [...(value as unknown[])];\n\t} else if (!isEmpty(value)) {\n\t\tlist = [value];\n\t}\n\tconst present = new Set(textsOf(list));\n\tfor (const item of add) {\n\t\tif (!present.has(String(item))) {\n\t\t\tlist.push(item);\n\t\t}\n\t}\n\treturn list;\n}\n\n/** The string after `prefix` / `suffix`. */\nfunction applyAffixes(text: string, application: FieldApplication): string {\n\tlet next = text;\n\tif (application.prefix !== undefined && !next.startsWith(application.prefix)) {\n\t\tnext = `${application.prefix}${next}`;\n\t}\n\tif (application.suffix !== undefined && !next.endsWith(application.suffix)) {\n\t\tnext = `${next}${application.suffix}`;\n\t}\n\treturn next;\n}\n\n/** Applies an application to a request member; returns the new value (or the old one when nothing changes). */\nfunction applyApplication(value: unknown, application: FieldApplication, verb: Verb): unknown {\n\tlet next = applyValue(value, application, verb);\n\tif (application.add !== undefined && (verb === \"create\" || next !== undefined)) {\n\t\tnext = applyAdd(next, application.add);\n\t}\n\tconst affixes = application.prefix !== undefined || application.suffix !== undefined;\n\tif (affixes && (typeof next === \"string\" || (next === undefined && verb === \"create\"))) {\n\t\tnext = applyAffixes(typeof next === \"string\" ? next : \"\", application);\n\t}\n\treturn next;\n}\n\nexport { applyApplication, checkRequirement, textsOf };\nexport type { FieldApplication, FieldRequirement, RateLimit, Scalar, Violation };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Action, Resource } from \"../catalog/resources.ts\";\nimport type { FieldApplication, FieldRequirement, RateLimit } from \"./constraints.ts\";\nimport { type Facts, whereMatches } from \"./evaluate.ts\";\nimport {\n\ttype CompiledConstraints,\n\tcompareSpecificity,\n\ttype CompiledRule,\n\ttype Policy,\n} from \"./types.ts\";\n\n/** One rate limit in force, with the rule that set it. */\ninterface EffectiveLimit {\n\treadonly rule: CompiledRule;\n\treadonly action: Action;\n\treadonly limit: RateLimit;\n}\n\n/**\n * The constraints in force for one object: every matching rule's\n * requirements together, the most specific rule's application per member,\n * and the union of forbidden members, redactions and confirmations.\n */\ninterface EffectiveConstraints {\n\treadonly require: ReadonlyMap<Resource, ReadonlyMap<string, readonly FieldRequirement[]>>;\n\treadonly apply: ReadonlyMap<Resource, ReadonlyMap<string, FieldApplication>>;\n\treadonly forbid: ReadonlyMap<Resource, ReadonlySet<string>>;\n\treadonly redact: ReadonlyMap<Resource, ReadonlySet<string>>;\n\treadonly limits: ReadonlyMap<Action, readonly EffectiveLimit[]>;\n\treadonly confirm: ReadonlyMap<Action, readonly CompiledRule[]>;\n\treadonly labels: ReadonlyMap<string, string>;\n\t/** The rules that contributed, for diagnostics. */\n\treadonly rules: readonly CompiledRule[];\n}\n\nfunction mergeInto<V>(\n\ttarget: Map<Resource, Map<string, V[]>>,\n\tsource: ReadonlyMap<Resource, ReadonlyMap<string, V>>,\n): void {\n\tfor (const [resource, members] of source) {\n\t\tconst perResource = target.get(resource) ?? new Map<string, V[]>();\n\t\tfor (const [member, value] of members) {\n\t\t\tconst list = perResource.get(member) ?? [];\n\t\t\tlist.push(value);\n\t\t\tperResource.set(member, list);\n\t\t}\n\t\ttarget.set(resource, perResource);\n\t}\n}\n\nfunction overrideInto<V>(\n\ttarget: Map<Resource, Map<string, V>>,\n\tsource: ReadonlyMap<Resource, ReadonlyMap<string, V>>,\n): void {\n\tfor (const [resource, members] of source) {\n\t\tconst perResource = target.get(resource) ?? new Map<string, V>();\n\t\tfor (const [member, value] of members) {\n\t\t\tperResource.set(member, value);\n\t\t}\n\t\ttarget.set(resource, perResource);\n\t}\n}\n\nfunction unionInto(\n\ttarget: Map<Resource, Set<string>>,\n\tsource: ReadonlyMap<Resource, ReadonlySet<string>>,\n): void {\n\tfor (const [resource, members] of source) {\n\t\tconst set = target.get(resource) ?? new Set<string>();\n\t\tfor (const member of members) {\n\t\t\tset.add(member);\n\t\t}\n\t\ttarget.set(resource, set);\n\t}\n}\n\n/** A compiled statement that carries constraints. */\ntype ConstrainRule = CompiledRule & { readonly constraints: CompiledConstraints };\n\n/** The constraint statements whose scope covers any branch of `facts`, least specific first. */\nfunction matchingConstraintRules(policy: Policy, facts: Facts): ConstrainRule[] {\n\tif (facts.workspace !== policy.workspace) {\n\t\treturn [];\n\t}\n\treturn policy.rules\n\t\t.filter(\n\t\t\t(rule): rule is ConstrainRule =>\n\t\t\t\trule.constraints !== undefined &&\n\t\t\t\tfacts.branches.some((branch) => whereMatches(rule.where, branch, facts)),\n\t\t)\n\t\t.toSorted((a, b) => compareSpecificity(a.specificity, b.specificity) || a.index - b.index);\n}\n\n/** Computes the constraints in force for an object. */\nfunction constraintsFor(policy: Policy, facts: Facts): EffectiveConstraints {\n\tconst rules = matchingConstraintRules(policy, facts);\n\tconst require = new Map<Resource, Map<string, FieldRequirement[]>>();\n\tconst apply = new Map<Resource, Map<string, FieldApplication>>();\n\tconst forbid = new Map<Resource, Set<string>>();\n\tconst redact = new Map<Resource, Set<string>>();\n\tconst limits = new Map<Action, EffectiveLimit[]>();\n\tconst confirm = new Map<Action, CompiledRule[]>();\n\tconst labels = new Map<string, string>();\n\tfor (const rule of rules) {\n\t\tconst { constraints } = rule;\n\t\tmergeInto(require, constraints.require);\n\t\toverrideInto(apply, constraints.apply);\n\t\tunionInto(forbid, constraints.forbid);\n\t\tunionInto(redact, constraints.redact);\n\t\tfor (const [action, limit] of constraints.limit) {\n\t\t\tlimits.set(action, [...(limits.get(action) ?? []), { rule, action, limit }]);\n\t\t}\n\t\tfor (const action of constraints.confirm) {\n\t\t\tconfirm.set(action, [...(confirm.get(action) ?? []), rule]);\n\t\t}\n\t\tfor (const [key, label] of constraints.labels) {\n\t\t\tlabels.set(key, label);\n\t\t}\n\t}\n\treturn { require, apply, forbid, redact, limits, confirm, labels, rules };\n}\n\n/** Whether any rule of the policy carries constraints (a cheap pre-check). */\nfunction hasConstraints(policy: Policy): boolean {\n\treturn policy.rules.some((rule) => rule.constraints !== undefined);\n}\n\n/** The human name of a member key (a custom field by its name), for messages. */\nfunction labelOf(effective: EffectiveConstraints, key: string): string {\n\treturn effective.labels.get(key) ?? key;\n}\n\nexport { constraintsFor, hasConstraints, labelOf };\nexport type { EffectiveConstraints, EffectiveLimit };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Resource } from \"../catalog/resources.ts\";\nimport { applyApplication, checkRequirement } from \"../policy/constraints.ts\";\nimport { constraintsFor, labelOf } from \"../policy/effective.ts\";\nimport type { Facts } from \"../policy/evaluate.ts\";\nimport type { Policy } from \"../policy/types.ts\";\nimport { isObject } from \"./objects.ts\";\n\ntype Body = Record<string, unknown>;\n\n/** Reads a member by key; a dotted key (`custom_fields.<gid>`) reaches into nested objects. */\nfunction readMember(body: Body, key: string): unknown {\n\tlet current: unknown = body;\n\tfor (const part of key.split(\".\")) {\n\t\tcurrent = isObject(current) ? current[part] : undefined;\n\t}\n\treturn current;\n}\n\n/** Returns a copy of `body` with the member set; a dotted key creates the objects it passes through. */\nfunction writeMember(body: Body, key: string, value: unknown): Body {\n\tconst [head, ...rest] = key.split(\".\");\n\tif (head === undefined || rest.length === 0) {\n\t\treturn { ...body, [key]: value };\n\t}\n\tconst nested = body[head];\n\treturn { ...body, [head]: writeMember(isObject(nested) ? nested : {}, rest.join(\".\"), value) };\n}\n\n/** The object a request acts on: the policy and the facts the constraints are evaluated against. */\ninterface Scope {\n\treadonly policy: Policy;\n\treadonly facts: Facts;\n}\n\n/** A shaped request body, and the constraints it still breaks (empty when it satisfies them). */\ninterface Shaped {\n\treadonly data: Body;\n\treadonly problems: readonly string[];\n}\n\n/**\n * Shapes a create or update request body under the constraints in force for\n * its target: applies the `apply` rules, then lists every `forbid` or\n * `require` rule the result does not satisfy. It never throws: the gate\n * refuses the request only after its permissions are checked, so that a\n * constraint message cannot reveal an object the policy hides.\n */\nfunction shapeBody(\n\tscope: Scope,\n\ttarget: { resource: Resource; verb: \"create\" | \"update\" },\n\tbody: Body,\n): Shaped {\n\tconst effective = constraintsFor(scope.policy, scope.facts);\n\tlet data = { ...body };\n\tfor (const [key, application] of effective.apply.get(target.resource) ?? []) {\n\t\tconst current = readMember(data, key);\n\t\tconst next = applyApplication(current, application, target.verb);\n\t\tif (next !== current) {\n\t\t\tdata = writeMember(data, key, next);\n\t\t}\n\t}\n\tconst problems: string[] = [];\n\tfor (const key of effective.forbid.get(target.resource) ?? []) {\n\t\tif (readMember(data, key) !== undefined) {\n\t\t\tproblems.push(`${labelOf(effective, key)} may not be set`);\n\t\t}\n\t}\n\tfor (const [key, requirements] of effective.require.get(target.resource) ?? []) {\n\t\tconst value = readMember(data, key);\n\t\tfor (const requirement of requirements) {\n\t\t\tfor (const violation of checkRequirement(value, requirement, { verb: target.verb })) {\n\t\t\t\tproblems.push(`${labelOf(effective, key)} ${violation}`);\n\t\t\t}\n\t\t}\n\t}\n\treturn { data, problems };\n}\n\n/** Removes the members the policy redacts for an object of `resource`. */\nfunction redactObject(scope: Scope, resource: Resource, object: Body): Body {\n\tconst redact = constraintsFor(scope.policy, scope.facts).redact.get(resource);\n\tif (redact === undefined || redact.size === 0) {\n\t\treturn object;\n\t}\n\treturn Object.fromEntries(Object.entries(object).filter(([key]) => !redact.has(key)));\n}\n\nexport { redactObject, shapeBody };\nexport type { Scope, Shaped };\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { OperationSpec } from \"../catalog/operation-spec.ts\";\nimport type { OperationId } from \"../catalog/operations.gen.ts\";\nimport type { Action, Resource } from \"../catalog/resources.ts\";\nimport { type Facts, isVisible, workspaceFacts } from \"../policy/evaluate.ts\";\nimport type { Policy } from \"../policy/types.ts\";\nimport { badRequest, notFound } from \"./errors.ts\";\nimport { type FactsLoader, type Loaded, readOperationOf } from \"./facts.ts\";\nimport { type AsanaObject, gidOf, gidsOf, isObject } from \"./objects.ts\";\nimport { parseOptFields, type Selection } from \"./selection.ts\";\nimport { shapeBody } from \"./shape.ts\";\n\n/** An object the request acts on, with its facts resolved. */\ninterface Target {\n\treadonly type: Resource;\n\treadonly gid: string;\n\treadonly facts: Facts;\n\t/** The object as loaded, when it was fetched. */\n\treadonly object?: AsanaObject;\n}\n\n/** One authorization requirement of a request. */\ninterface Check {\n\treadonly target: Target;\n\t/** Actions that must all be allowed on the target (its visibility is always required). */\n\treadonly actions: readonly Action[];\n\t/** Body keys to validate against the policy's field allowlist for `<resource>:update`. */\n\treadonly fields?: { readonly resource: Resource; readonly keys: readonly string[] };\n\t/** In a batch, the index of the action the check belongs to (refusals name it; limits count each action). */\n\treadonly unit?: number;\n\t/**\n\t * Actions whose `limit` and `confirm` apply to the request although their\n\t * permission is decided per item (the reads of a filtered list).\n\t */\n\treadonly counted?: readonly Action[];\n}\n\n/** How the Asana response is post-processed. */\ntype ResponsePlan =\n\t/** Pass the body through unchanged. */\n\t| { readonly kind: \"raw\" }\n\t/**\n\t * `data` is one object of `type`: attach `allowed_actions`. With `facts`\n\t * the object's facts are already known; with `verify` an invisible object\n\t * becomes a 404 (for lookups that could not be authorized up front).\n\t * With `loaded`, the object as the loader fetched it to authorize the\n\t * request, references to the ancestors it embeds with their placement\n\t * are judged by that placement instead of being loaded.\n\t */\n\t| {\n\t\t\treadonly kind: \"item\";\n\t\t\treadonly type: Resource;\n\t\t\treadonly facts?: Facts;\n\t\t\treadonly verify?: boolean;\n\t\t\treadonly loaded?: AsanaObject;\n\t\t\t/** The caller's `opt_fields`, which the object is cut back to once checked (the gate asked for more). */\n\t\t\treadonly selection?: Selection;\n\t }\n\t/**\n\t * `data` is a list of objects of `type` (or of mixed types): drop invisible\n\t * ones, attach `allowed_actions`. The items of a mixed list expected to be\n\t * of the `expect` types are asked for what their facts need and judged by\n\t * themselves; one that lacks it (Asana may not honour a selection on every\n\t * path) is loaded by gid, like every item of a list that expects nothing.\n\t */\n\t| {\n\t\t\treadonly kind: \"list\";\n\t\t\treadonly type: Resource | \"mixed\";\n\t\t\treadonly facts?: Facts;\n\t\t\treadonly expect?: readonly Resource[];\n\t }\n\t/** Custom handling of the whole body. */\n\t| {\n\t\t\treadonly kind: \"custom\";\n\t\t\treadonly transform: (body: Record<string, unknown>) => Promise<Record<string, unknown>>;\n\t };\n\n/** Everything the gate needs to authorize, send and post-process one request. */\ninterface Plan {\n\treadonly checks: readonly Check[];\n\treadonly response: ResponsePlan;\n\t/** Objects whose cached state is stale after the request succeeds. */\n\treadonly invalidate?: readonly { readonly type: Resource; readonly gid: string }[];\n\t/** Body to send instead of the caller's. */\n\treadonly data?: unknown;\n\t/** Asana's response, already read while planning: the request is not sent, and this is answered instead. */\n\treadonly answer?: Record<string, unknown>;\n}\n\n/** What {@link PlanContext.read} found: the target, and Asana's answer to the request when it read that. */\ninterface Read {\n\treadonly target: Target;\n\treadonly answer?: {\n\t\treadonly body: Record<string, unknown>;\n\t\t/** The object whose embedded ancestors carry their placement (the loader's fetch of it). */\n\t\treadonly placement?: AsanaObject;\n\t\treadonly selection?: Selection;\n\t};\n}\n\n/** A request body that breaks the constraints in force for its target. */\ninterface ShapeViolation {\n\treadonly resource: Resource;\n\treadonly problems: readonly string[];\n\t/** In a batch, the index of the action whose body breaks the constraints. */\n\treadonly unit?: number;\n}\n\n/** One request as the planners see it. */\ninterface PlanInputs {\n\treadonly operationId: OperationId;\n\treadonly spec: OperationSpec;\n\treadonly params: Readonly<Record<string, string>>;\n\treadonly query: Readonly<Record<string, string>>;\n\t/** The request's `data` object (`{}` when there is none). */\n\treadonly body: Readonly<Record<string, unknown>>;\n\treadonly policy: Policy;\n\treadonly loader: FactsLoader;\n\t/** Post-processes a response body according to a response plan (supplied by the gate). */\n\treadonly postProcess: (\n\t\tresponse: ResponsePlan,\n\t\tbody: Record<string, unknown>,\n\t) => Promise<Record<string, unknown>>;\n}\n\n/** The request a classification entry plans for, with what it can ask of the gate. */\ninterface PlanContext extends PlanInputs {\n\t/**\n\t * Loads a target of `type`; 404 when `gid` is missing, when the object\n\t * cannot be loaded, and when the policy hides it, so a hidden object\n\t * refuses a request exactly where a nonexistent one would.\n\t */\n\tanchor(type: Resource, gid: string | undefined): Promise<Target>;\n\t/**\n\t * {@link anchor} for a request that reads the object itself (its type's\n\t * own GET by gid): the object is read afresh with the request's\n\t * `opt_fields` and what its facts need, and `answer` is Asana's response,\n\t * to serve instead of sending the request. Without `answer` (another\n\t * operation, or fields that are not plain paths), the request is sent.\n\t */\n\tread(type: Resource, gid: string | undefined): Promise<Read>;\n\t/** Loads a target whose type is unknown, trying `types` in order; 404 when none exists or it is hidden. */\n\tprobe(gid: string | undefined, types: readonly Resource[]): Promise<Target>;\n\t/** The governed workspace as a target; 404 when `gid` names another workspace. */\n\tworkspace(gid?: string): Target;\n\t/** A gid from the body, given as a string or a `{ gid }` object. */\n\tbodyGid(field: string): string | undefined;\n\t/** Gids from a body list member. */\n\tbodyGids(field: string): string[];\n\t/**\n\t * Shapes the request body (or `body`) for creating or updating an object\n\t * of `resource` whose facts are `facts`: applies the policy's `apply`\n\t * rules and records a violation when `require` or `forbid` is not met.\n\t * The gate refuses the request for it once the permissions are checked.\n\t */\n\tshape(\n\t\tfacts: Facts,\n\t\ttarget: { resource: Resource; verb: \"create\" | \"update\" },\n\t\tbody?: Readonly<Record<string, unknown>>,\n\t): Record<string, unknown>;\n\t/** The violations {@link shape} recorded, shared with the contexts of sub-requests. */\n\treadonly violations: readonly ShapeViolation[];\n\t/** Plans another operation with this context's policy and loader (used by the Batch API). */\n\tplanSub(\n\t\tinputs: Pick<PlanContextInputs, \"operationId\" | \"spec\" | \"params\" | \"query\" | \"body\" | \"unit\">,\n\t): Promise<Plan>;\n}\n\n/** Inputs of {@link createPlanContext}. */\ninterface PlanContextInputs extends PlanInputs {\n\t/** Plans a request for its operation (the gate supplies the classification lookup). */\n\treadonly planner: (context: PlanContext) => Promise<Plan>;\n\t/** The list violations are recorded in (a sub-request shares its parent's). */\n\treadonly violations?: ShapeViolation[];\n\t/** For a sub-request of a batch, the index of its action. */\n\treadonly unit?: number;\n}\n\n/** The gid a request names for a target of `type`; 400 when it names none. */\nfunction given(type: string, gid: string | undefined): string {\n\tif (gid === undefined || gid === \"\") {\n\t\tthrow badRequest(`${type}: Missing input`);\n\t}\n\treturn gid;\n}\n\n/** Builds the context a classification entry plans against. */\nfunction createPlanContext(inputs: PlanContextInputs): PlanContext {\n\tconst { planner, violations: shared, unit, ...request } = inputs;\n\tconst { policy, loader } = request;\n\tconst violations = shared ?? [];\n\t/** The target `loaded` is, when the policy lets the request see it; 404 otherwise. */\n\tconst visible = (type: Resource, gid: string, loaded: Loaded | undefined): Target => {\n\t\tif (loaded === undefined || !isVisible(policy, loaded.facts, type)) {\n\t\t\tthrow notFound(type, gid);\n\t\t}\n\t\treturn { type, gid, facts: loaded.facts, object: loaded.object };\n\t};\n\treturn {\n\t\t...request,\n\t\tasync anchor(type, gid) {\n\t\t\tconst named = given(type, gid);\n\t\t\treturn visible(type, named, await loader.load(type, named));\n\t\t},\n\t\tasync read(type, gid) {\n\t\t\tconst named = given(type, gid);\n\t\t\tconst { fields, selection } = parseOptFields(request.query.opt_fields);\n\t\t\tif (readOperationOf(type) !== request.operationId || (fields.length > 0 && !selection)) {\n\t\t\t\treturn { target: visible(type, named, await loader.load(type, named)) };\n\t\t\t}\n\t\t\tconst loaded = await loader.read(type, named, selection);\n\t\t\tconst target = visible(type, named, loaded);\n\t\t\tconst placement = loaded?.fetched ?? loaded?.object;\n\t\t\tconst body = { data: target.object };\n\t\t\treturn {\n\t\t\t\ttarget,\n\t\t\t\tanswer: { body, ...(placement && { placement }), ...(selection && { selection }) },\n\t\t\t};\n\t\t},\n\t\tasync probe(gid, types) {\n\t\t\tconst label = types[0] ?? \"object\";\n\t\t\tconst named = given(label, gid);\n\t\t\tconst loaded = await loader.probe(named, types);\n\t\t\tif (loaded === undefined) {\n\t\t\t\tthrow notFound(label, named);\n\t\t\t}\n\t\t\treturn visible(loaded.type, named, loaded);\n\t\t},\n\t\tworkspace(gid) {\n\t\t\tif (gid !== undefined && gid !== policy.workspace) {\n\t\t\t\tthrow notFound(\"workspace\", gid);\n\t\t\t}\n\t\t\treturn { type: \"workspace\", gid: policy.workspace, facts: workspaceFacts(policy.workspace) };\n\t\t},\n\t\tbodyGid(field) {\n\t\t\treturn gidOf(request.body[field]);\n\t\t},\n\t\tbodyGids(field) {\n\t\t\treturn gidsOf(request.body[field]);\n\t\t},\n\t\tshape(facts, target, body) {\n\t\t\tconst shaped = shapeBody({ policy, facts }, target, { ...(body ?? request.body) });\n\t\t\tif (shaped.problems.length > 0) {\n\t\t\t\tviolations.push({\n\t\t\t\t\tresource: target.resource,\n\t\t\t\t\tproblems: shaped.problems,\n\t\t\t\t\t...(unit !== undefined && { unit }),\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn shaped.data;\n\t\t},\n\t\tviolations,\n\t\t// The sub-context shares `violations`, so what the action violates is the request's.\n\t\tplanSub: (subInputs) => planner(createPlanContext({ ...inputs, ...subInputs, violations })),\n\t};\n}\n\n/**\n * Parses a request body into its `data` object: a bare object, or Asana's\n * envelope `{ data, options }`; an envelope with other members is refused,\n * since Asana would read only its `data`.\n */\nfunction dataOf(body: unknown): Record<string, unknown> {\n\tif (!isObject(body)) {\n\t\treturn {};\n\t}\n\tif (!isObject(body.data)) {\n\t\treturn body;\n\t}\n\tconst others = Object.keys(body).filter((key) => key !== \"data\" && key !== \"options\");\n\tif (others.length > 0) {\n\t\tthrow badRequest(\n\t\t\t`body: expected the data object, or { data, options } (also given: ${others.join(\", \")})`,\n\t\t);\n\t}\n\treturn body.data;\n}\n\n/** The `options.fields` of an enveloped body, which Asana reads like `opt_fields`. */\nfunction optionFieldsOf(body: unknown): string[] {\n\tconst options =\n\t\tisObject(body) && isObject(body.data) && isObject(body.options) ? body.options : {};\n\tconst fields: unknown[] = Array.isArray(options.fields) ? options.fields : [];\n\treturn fields.filter((field): field is string => typeof field === \"string\");\n}\n\nexport { createPlanContext, dataOf, optionFieldsOf };\nexport type {\n\tCheck,\n\tPlan,\n\tPlanContext,\n\tPlanContextInputs,\n\tRead,\n\tResponsePlan,\n\tShapeViolation,\n\tTarget,\n};\n","// Copyright 2026 Shinsuke Mori\n// SPDX-License-Identifier: Apache-2.0\n\nimport { BATCH_LIMIT } from \"../asana/client.ts\";\nimport { splitList } from \"../asana/query.ts\";\nimport { badRequest, inAction, noRoute, notFound } from \"../gate/errors.ts\";\nimport { type Membership, membershipsOf, PARENT_TYPES, taskState } from \"../gate/facts.ts\";\nimport { gidsOf, isObject, type Ref, refOf, resourceOfType, stringOf } from \"../gate/objects.ts\";\nimport {\n\ttype Check,\n\tdataOf,\n\ttype Plan,\n\ttype PlanContext,\n\ttype ResponsePlan,\n\ttype Target,\n} from \"../gate/plan.ts\";\nimport { isHttpMethod, matchRoute } from \"../gate/router.ts\";\nimport { augmentOptFields, requestedFields } from \"../gate/selection.ts\";\nimport { textsOf } from \"../policy/constraints.ts\";\nimport { type Facts, isVisible, type ObjectState, WORKSPACE_BRANCH } from \"../policy/evaluate.ts\";\nimport { isGid } from \"../policy/schema.ts\";\nimport { type ObjectOperationId, objectOperationOf } from \"./object-operations.ts\";\nimport type { OperationSpec } from \"./operation-spec.ts\";\nimport { type OperationId, OPERATIONS } from \"./operations.gen.ts\";\nimport { type Action, actionOf, FIELD_VERBS, type Resource, type Verb } from \"./resources.ts\";\n\n/** How an operation's scope is found, for documentation. */\ntype ScopeKind = \"path\" | \"body\" | \"query\" | \"workspace\" | \"filter\" | \"batch\";\n\n/** A planning function for one operation. */\ntype Planner = (ctx: PlanContext) => Promise<Plan>;\n\n/** The classification of one operation: its action and how it is scoped. */\ninterface OperationRule {\n\t/** The resource the operation acts on (absent for the Batch API, which has none of its own). */\n\treadonly resource?: Resource;\n\treadonly verb?: Verb;\n\t/** `<resource>:<verb>`, when the operation has one action of its own. */\n\treadonly action?: Action;\n\treadonly scope: ScopeKind;\n\treadonly plan: Planner;\n}\n\n/** The static part of a rule. */\ninterface RuleSpec {\n\treadonly resource?: Resource;\n\treadonly verb?: Verb;\n\treadonly scope: ScopeKind;\n}\n\nconst RAW: ResponsePlan = { kind: \"raw\" };\n\ntype ResponseKind = \"item\" | \"raw\" | \"list\";\n\nfunction responseOf(kind: ResponseKind | undefined, type: Resource, facts?: Facts): ResponsePlan {\n\tswitch (kind) {\n\t\tcase \"raw\": {\n\t\t\treturn RAW;\n\t\t}\n\t\tcase \"list\": {\n\t\t\treturn { kind: \"list\", type, ...(facts && { facts }) };\n\t\t}\n\t\tdefault: {\n\t\t\treturn { kind: \"item\", type, ...(facts && { facts }) };\n\t\t}\n\t}\n}\n\nfunction make(spec: RuleSpec, plan: Planner): OperationRule {\n\tconst action =\n\t\tspec.resource === undefined || spec.verb === undefined\n\t\t\t? undefined\n\t\t\t: actionOf(spec.resource, spec.verb);\n\treturn { ...spec, ...(action !== undefined && { action }), plan };\n}\n\nfunction sharedFacts(shared: boolean | undefined, target: Target): Facts | undefined {\n\tif (shared === true) {\n\t\treturn target.facts;\n\t}\n\treturn undefined;\n}\n\n/** Awaits two independent lookups together; when either fails, the first's refusal comes first. */\nasync function both<A, B>(first: Promise<A>, second: Promise<B>): Promise<[A, B]> {\n\tconst settled = await Promise.allSettled([first, second]);\n\tif (settled.some((result) => result.status === \"rejected\")) {\n\t\tawait first;\n\t\tawait second;\n\t}\n\treturn Promise.all([first, second]);\n}\n\n/** The check an update body implies: special verbs for mapped members, `update` for the rest. */\nfunction updateCheck(\n\ttarget: Target,\n\tresource: Resource,\n\tbody: Readonly<Record<string, unknown>>,\n): Check {\n\tconst verbs = FIELD_VERBS[resource] ?? {};\n\tconst special = new Set<Action>();\n\tconst plain: string[] = [];\n\tfor (const key of Object.keys(body)) {\n\t\tconst verb = verbs[key];\n\t\tif (verb === undefined) {\n\t\t\tplain.push(key);\n\t\t} else {\n\t\t\tspecial.add(actionOf(resource, verb));\n\t\t}\n\t}\n\tconst actions = [...special];\n\tif (plain.length > 0 || actions.length === 0) {\n\t\tactions.push(actionOf(resource, \"update\"));\n\t}\n\treturn { target, actions, fields: { resource, keys: plain } };\n}\n\n/**\n * How an operation's body relates to the resource it acts on. `shaped`: the\n * resource's own create or update body, completed and checked by the\n * policy's constraints. `checked`: members of the resource that are not\n * shaped but still pass the update field allowlist (followers,\n * dependencies). `opaque`: the body describes something else (a duplicate,\n * an instantiation, an enum option, a metric, a portfolio item); only the\n * action is checked and the body is sent as written.\n */\ntype Shaping = \"shaped\" | \"checked\" | \"opaque\";\n\n/** What a request must pass to act on `target`; creates and updates come with their body shaped by the policy. */\nfunction writeCheck(\n\tctx: PlanContext,\n\ttarget: Target,\n\taction: { resource: Resource; verb: Verb; shaping?: Shaping | undefined },\n): { check: Check; data?: Record<string, unknown> } {\n\tconst { resource, verb, shaping = \"shaped\" } = action;\n\tconst plain: Check = { target, actions: [actionOf(resource, verb)] };\n\tif (shaping === \"opaque\" || (verb !== \"update\" && verb !== \"create\")) {\n\t\treturn { check: plain };\n\t}\n\tif (shaping === \"checked\") {\n\t\treturn { check: verb === \"update\" ? updateCheck(target, resource, ctx.body) : plain };\n\t}\n\tconst data = ctx.shape(target.facts, { resource, verb });\n\treturn { check: verb === \"update\" ? updateCheck(target, resource, data) : plain, data };\n}\n\n/** Verbs after which the path object's cached facts are still right. */\nconst KEEPS_FACTS: ReadonlySet<Verb> = new Set([\"read\", \"create\", \"manage_members\", \"reorder\"]);\n\nconst EVENT_TYPES: readonly Resource[] = [\"project\", \"task\", \"goal\", \"portfolio\", \"section\"];\nconst WEBHOOK_TYPES: readonly Resource[] = [\n\t\"project\",\n\t\"task\",\n\t\"portfolio\",\n\t\"goal\",\n\t\"team\",\n\t\"workspace\",\n];\n\n/** Loads a target when the request names one. */\nasync function anchorIfGiven(\n\tctx: PlanContext,\n\ttype: Resource,\n\tgid: string | undefined,\n): Promise<Target | undefined> {\n\tconst target = gid === undefined ? undefined : await ctx.anchor(type, gid);\n\treturn target;\n}\n\n/**\n * The gid the operation's path names first (`/tasks/{task_gid}/…`), read\n * through the catalog so a renamed path parameter cannot go unnoticed.\n */\nfunction pathGid(ctx: PlanContext): string | undefined {\n\tconst [param] = ctx.spec.pathParams;\n\treturn param === undefined ? undefined : ctx.params[param];\n}\n\n/**\n * `GET /<type>s/{gid}`: read one object addressed by a path parameter. The\n * object that is checked is the one answered, read once (afresh), so the\n * request is not sent again; `limit` and `confirm` still apply before it is.\n */\nfunction getOne(type: Resource): OperationRule {\n\treturn make({ resource: type, verb: \"read\", scope: \"path\" }, async (ctx) => {\n\t\tconst { target, answer } = await ctx.read(type, pathGid(ctx));\n\t\treturn {\n\t\t\tchecks: [{ target, actions: [actionOf(type, \"read\")] }],\n\t\t\tresponse: {\n\t\t\t\tkind: \"item\",\n\t\t\t\ttype,\n\t\t\t\tfacts: target.facts,\n\t\t\t\t...((answer?.placement ?? target.object) && {\n\t\t\t\t\tloaded: answer?.placement ?? target.object,\n\t\t\t\t}),\n\t\t\t\t...(answer?.selection && { selection: answer.selection }),\n\t\t\t},\n\t\t\t...(answer && { answer: answer.body }),\n\t\t};\n\t});\n}\n\n/** `PUT /<type>s/{gid}`: update one object; the body decides the verbs. */\nfunction updateOne(type: Resource): OperationRule {\n\treturn make({ resource: type, verb: \"update\", scope: \"path\" }, async (ctx) => {\n\t\tconst target = await ctx.anchor(type, pathGid(ctx));\n\t\tconst { check, data } = writeCheck(ctx, target, { resource: type, verb: \"update\" });\n\t\treturn {\n\t\t\tchecks: [check],\n\t\t\tdata,\n\t\t\tresponse: { kind: \"item\", type },\n\t\t\tinvalidate: [{ type, gid: target.gid }],\n\t\t};\n\t});\n}\n\n/** `DELETE /<type>s/{gid}`. */\nfunction deleteOne(type: Resource): OperationRule {\n\treturn make({ resource: type, verb: \"delete\", scope: \"path\" }, async (ctx) => {\n\t\tconst target = await ctx.anchor(type, pathGid(ctx));\n\t\treturn {\n\t\t\tchecks: [{ target, actions: [actionOf(type, \"delete\")] }],\n\t\t\tresponse: RAW,\n\t\t\tinvalidate: [{ type, gid: target.gid }],\n\t\t};\n\t});\n}\n\n/**\n * A body member naming an object (or, with `many`, objects) that must be\n * visible, and on which `actions` must be allowed when it is changed too.\n */\ninterface BodyRef {\n\treadonly field: string;\n\treadonly types: readonly Resource[];\n\treadonly many?: boolean;\n\treadonly actions?: readonly Action[];\n}\n\nfunction bodyRefs(ctx: PlanContext, refs: readonly BodyRef[]): Promise<Check[]> {\n\treturn Promise.all(\n\t\trefs.flatMap((ref) =>\n\t\t\t(ref.many === true ? ctx.bodyGids(ref.field) : [ctx.bodyGid(ref.field)]).map(async (gid) => ({\n\t\t\t\ttarget: await ctx.probe(gid, ref.types),\n\t\t\t\tactions: ref.actions ?? [],\n\t\t\t})),\n\t\t),\n\t);\n}\n\n/** Options of {@link actOn}. */\ninterface ActOnOptions {\n\t/** The path object's type. */\n\treadonly on: Resource;\n\treadonly verb: Verb;\n\t/** The action's resource when it differs from the path object's type. */\n\treadonly resource?: Resource;\n\treadonly response?: ResponseKind;\n\t/** Objects the body names that must be visible. */\n\treadonly also?: readonly BodyRef[];\n\t/** How the body relates to the action's resource (default `shaped`). */\n\treadonly shaping?: Shaping;\n}\n\n/**\n * `POST /<type>s/{gid}/<action>`: an action on the path object (optionally of\n * another resource living in it). Creates and updates are shaped by the\n * policy's constraints, and the path object's cached facts are dropped unless\n * the verb leaves them untouched.\n */\nfunction actOn(options: ActOnOptions): OperationRule {\n\tconst resource = options.resource ?? options.on;\n\treturn make({ resource, verb: options.verb, scope: \"path\" }, async (ctx) => {\n\t\tconst [target, refs] = await both(\n\t\t\tctx.anchor(options.on, pathGid(ctx)),\n\t\t\tbodyRefs(ctx, options.also ?? []),\n\t\t);\n\t\tconst { check, data } = writeCheck(ctx, target, {\n\t\t\tresource,\n\t\t\tverb: options.verb,\n\t\t\tshaping: options.shaping,\n\t\t});\n\t\treturn {\n\t\t\tchecks: [check, ...refs],\n\t\t\t...(data && { data }),\n\t\t\tresponse: responseOf(options.response ?? \"raw\", resource, target.facts),\n\t\t\t...(!KEEPS_FACTS.has(options.verb) && {\n\t\t\t\tinvalidate: [{ type: options.on, gid: target.gid }],\n\t\t\t}),\n\t\t};\n\t});\n}\n\n/** Options of {@link listUnder}. */\ninterface ListUnderOptions {\n\treadonly under: Resource;\n\treadonly items: Resource | \"mixed\";\n\t/** For mixed items, the types they are expected to be of. */\n\treadonly expect?: readonly Resource[];\n\t/** Items take the anchor's facts (stories of a task) instead of their own. */\n\treadonly shared?: boolean;\n}\n\n/** `GET /<anchor>s/{gid}/<items>`: a list under the path object. */\nfunction listUnder(options: ListUnderOptions): OperationRule {\n\tconst resource = options.items === \"mixed\" ? options.under : options.items;\n\treturn make({ resource, verb: \"read\", scope: \"filter\" }, async (ctx) => {\n\t\tconst target = await ctx.anchor(options.under, pathGid(ctx));\n\t\tconst shared = options.shared === true && options.items !== \"mixed\";\n\t\tconst read = actionOf(resource, \"read\");\n\t\treturn {\n\t\t\tchecks: [\n\t\t\t\t{\n\t\t\t\t\ttarget,\n\t\t\t\t\tactions: shared ? [read] : [],\n\t\t\t\t\t...(!shared && options.items !== \"mixed\" && { counted: [read] }),\n\t\t\t\t},\n\t\t\t],\n\t\t\tresponse: {\n\t\t\t\tkind: \"list\",\n\t\t\t\ttype: options.items,\n\t\t\t\t...(shared && { facts: target.facts }),\n\t\t\t\t...(options.expect && { expect: options.expect }),\n\t\t\t},\n\t\t};\n\t});\n}\n\n/** Options of {@link createUnder}. */\ninterface CreateUnderOptions {\n\treadonly under: Resource;\n\treadonly item: Resource;\n\treadonly shared?: boolean;\n\treadonly response?: ResponseKind;\n}\n\n/** `POST /<anchor>s/{gid}/<items>`: create an item under the path object. */\nfunction createUnder(options: CreateUnderOptions): OperationRule {\n\treturn make({ resource: options.item, verb: \"create\", scope: \"path\" }, async (ctx) => {\n\t\tconst target = await ctx.anchor(options.under, pathGid(ctx));\n\t\tconst { check, data } = writeCheck(ctx, target, { resource: options.item, verb: \"create\" });\n\t\treturn {\n\t\t\tchecks: [check],\n\t\t\tdata,\n\t\t\tresponse: responseOf(options.response, options.item, sharedFacts(options.shared, target)),\n\t\t};\n\t});\n}\n\n/** Options of {@link onWorkspace}. */\ninterface WorkspaceOptions {\n\t/** The workspace is the one the path names (`/workspaces/{workspace_gid}/…`). */\n\treadonly path?: true;\n\treadonly query?: string;\n\treadonly body?: string;\n\treadonly response?: ResponseKind;\n\treadonly scope?: ScopeKind;\n\t/** How the request body relates to the resource (default `shaped`). */\n\treadonly shaping?: Shaping;\n}\n\nfunction workspaceGidOf(ctx: PlanContext, options: WorkspaceOptions): string | undefined {\n\tif (options.path === true) {\n\t\treturn pathGid(ctx);\n\t}\n\tif (options.query !== undefined) {\n\t\treturn ctx.query[options.query];\n\t}\n\tif (options.body !== undefined) {\n\t\treturn ctx.bodyGid(options.body);\n\t}\n\treturn undefined;\n}\n\n/** A workspace-level operation; the workspace named by the request must be the governed one. */\nfunction onWorkspace(\n\tresource: Resource,\n\tverb: Verb,\n\toptions: WorkspaceOptions = {},\n): OperationRule {\n\treturn make({ resource, verb, scope: options.scope ?? \"workspace\" }, (ctx) => {\n\t\tconst target = ctx.workspace(workspaceGidOf(ctx, options));\n\t\tconst { check, data } = writeCheck(ctx, target, { resource, verb, shaping: options.shaping });\n\t\treturn Promise.resolve({\n\t\t\tchecks: [check],\n\t\t\t...(data && { data }),\n\t\t\tresponse: responseOf(options.response ?? \"raw\", resource),\n\t\t});\n\t});\n}\n\n/** Options of {@link onBody}. */\ninterface OnBodyOptions {\n\treadonly resource: Resource;\n\treadonly verb: Verb;\n\t/** The body member naming the object. */\n\treadonly field: string;\n\treadonly types: readonly Resource[];\n\treadonly response?: ResponseKind;\n\treadonly shared?: boolean;\n}\n\n/** An operation on the object a body member names, whose type is one of `types`. */\nfunction onBody(options: OnBodyOptions): OperationRule {\n\treturn make({ resource: options.resource, verb: options.verb, scope: \"body\" }, async (ctx) => {\n\t\tconst target = await ctx.probe(ctx.bodyGid(options.field), options.types);\n\t\tconst { check, data } = writeCheck(ctx, target, {\n\t\t\tresource: options.resource,\n\t\t\tverb: options.verb,\n\t\t});\n\t\treturn {\n\t\t\tchecks: [check],\n\t\t\t...(data && { data }),\n\t\t\tresponse: responseOf(options.response, options.resource, sharedFacts(options.shared, target)),\n\t\t\t...(!KEEPS_FACTS.has(options.verb) && {\n\t\t\t\tinvalidate: [{ type: target.type, gid: target.gid }],\n\t\t\t}),\n\t\t};\n\t});\n}\n\n/** A query member that may name the object a list is anchored on, and the types it may have. */\ninterface ListAnchor {\n\treadonly query: string;\n\treadonly types: readonly Resource[];\n}\n\n/** Options of {@link listBy}. */\ninterface ListByOptions {\n\t/** Items take the anchor's facts (they live inside it) instead of their own. */\n\treadonly shared?: boolean;\n\t/** The first anchor must be given; otherwise an absent anchor means the workspace. */\n\treadonly required?: boolean;\n}\n\n/**\n * A list anchored on the object a query member names (`?project=`, `?parent=`),\n * the first present of `anchors`, or on the workspace when none is given.\n */\nfunction listBy(\n\tresource: Resource,\n\tanchors: readonly ListAnchor[],\n\toptions: ListByOptions = {},\n): OperationRule {\n\tconst scope: ScopeKind = options.required === true ? \"query\" : \"filter\";\n\treturn make({ resource, verb: \"read\", scope }, async (ctx) => {\n\t\tconst [first] = anchors;\n\t\tconst found =\n\t\t\tanchors.find((anchor) => ctx.query[anchor.query] !== undefined) ??\n\t\t\t(options.required === true ? first : undefined);\n\t\t// A `workspace` query must name the governed workspace, anchor or not.\n\t\tconst workspace = ctx.workspace(ctx.query.workspace);\n\t\tconst target =\n\t\t\tfound === undefined ? workspace : await ctx.probe(ctx.query[found.query], found.types);\n\t\tconst shared = options.shared === true && target.type !== \"workspace\";\n\t\tconst read = actionOf(resource, \"read\");\n\t\treturn {\n\t\t\tchecks: [{ target, actions: shared ? [read] : [], ...(!shared && { counted: [read] }) }],\n\t\t\tresponse: { kind: \"list\", type: resource, ...(shared && { facts: target.facts }) },\n\t\t};\n\t});\n}\n\n/** The user gid a body's `assignee` names (`me`, a gid, an email or a `{ gid }` reference). */\nasync function assigneeOf(\n\tctx: PlanContext,\n\tbody: Readonly<Record<string, unknown>>,\n): Promise<string | null> {\n\tconst raw = body.assignee;\n\tconst { me } = ctx.policy;\n\tif (raw === \"me\" || raw === me.gid || raw === me.email) {\n\t\treturn me.gid;\n\t}\n\tif (typeof raw !== \"string\") {\n\t\treturn refOf(raw)?.gid ?? null;\n\t}\n\tif (raw === \"\" || isGid(raw)) {\n\t\treturn raw === \"\" ? null : raw;\n\t}\n\t// An email: assignee scopes compare user gids, so the request is judged by the user it names.\n\tconst user = await ctx.loader.load(\"user\", raw);\n\tconst gid = user === undefined ? undefined : stringOf(user.object.gid);\n\tif (gid === undefined) {\n\t\tthrow badRequest(`assignee: Unknown object: ${raw}`);\n\t}\n\treturn gid;\n}\n\nfunction customFieldValuesOf(\n\tbody: Readonly<Record<string, unknown>>,\n): Map<string, ReadonlySet<string>> {\n\tconst customFields = new Map<string, ReadonlySet<string>>();\n\tif (isObject(body.custom_fields)) {\n\t\tfor (const [gid, value] of Object.entries(body.custom_fields)) {\n\t\t\tcustomFields.set(gid, new Set(textsOf(value)));\n\t\t}\n\t}\n\treturn customFields;\n}\n\n/** Tags, assignee and custom field values a task body sets, as facts. */\nasync function crossFactsOf(\n\tctx: PlanContext,\n\tbody: Readonly<Record<string, unknown>>,\n): Promise<Pick<Facts, \"tags\" | \"assignee\" | \"customFields\">> {\n\treturn {\n\t\ttags: new Set(gidsOf(body.tags)),\n\t\tassignee: await assigneeOf(ctx, body),\n\t\tcustomFields: customFieldValuesOf(body),\n\t};\n}\n\n/** The state of a task about to be created, from its request body. */\nfunction createdTaskState(\n\tctx: PlanContext,\n\tbody: Readonly<Record<string, unknown>>,\n\tparent: Target | undefined,\n): ObjectState {\n\treturn {\n\t\t...taskState(body),\n\t\tcreatedBy: ctx.policy.me.gid,\n\t\tcompleted: body.completed === true,\n\t\thasParent: parent !== undefined,\n\t\tcreatedAt: new Date().toISOString(),\n\t};\n}\n\n/**\n * The projects a task body places the task in: `memberships` with their\n * sections, plus the `projects` no membership names (Asana wants both for a\n * section, so a project named in both is one home, in its section).\n */\nfunction membershipsOfBody(body: Readonly<Record<string, unknown>>): Membership[] {\n\tconst listed = membershipsOf(body);\n\tconst unlisted = gidsOf(body.projects).filter(\n\t\t(project) => !listed.some((membership) => membership.project === project),\n\t);\n\treturn [...unlisted.map((project) => ({ project, section: undefined })), ...listed];\n}\n\n/** Where a task about to be created will live: its parent, and the projects of its memberships. */\ninterface NewTaskPlacement {\n\treadonly parent: Target | undefined;\n\treadonly homes: readonly { membership: Membership; project: Target }[];\n}\n\n/** The facts of a task about to be created, from its request body. */\nasync function createdTaskFacts(\n\tctx: PlanContext,\n\tplacement: NewTaskPlacement,\n\tbody: Readonly<Record<string, unknown>>,\n): Promise<Facts> {\n\tconst cross = {\n\t\t...(await crossFactsOf(ctx, body)),\n\t\tstate: createdTaskState(ctx, body, placement.parent),\n\t};\n\tif (placement.homes.length === 0 && placement.parent !== undefined) {\n\t\treturn { ...placement.parent.facts, ...cross };\n\t}\n\tconst workspace = ctx.workspace(ctx.bodyGid(\"workspace\"));\n\tif (placement.homes.length === 0) {\n\t\treturn {\n\t\t\tworkspace: workspace.gid,\n\t\t\tbranches: [{ ...WORKSPACE_BRANCH, unhomed: true }],\n\t\t\t...cross,\n\t\t};\n\t}\n\tconst branches = placement.homes.map(({ membership, project }) => {\n\t\tconst [branch] = project.facts.branches;\n\t\tif (branch === undefined || project.facts.workspace !== ctx.policy.workspace) {\n\t\t\tthrow notFound(\"project\", project.gid);\n\t\t}\n\t\treturn { ...branch, ...(membership.section !== undefined && { section: membership.section }) };\n\t});\n\treturn { workspace: workspace.gid, branches, ...cross };\n}\n\n/** `POST /tasks` (the parent, if any, in the body) and `POST /tasks/{gid}/subtasks` (in the path). */\nfunction createTaskRule(scope: \"body\" | \"path\"): OperationRule {\n\treturn make({ resource: \"task\", verb: \"create\", scope }, async (ctx) => {\n\t\tconst parentGid = scope === \"path\" ? pathGid(ctx) : ctx.bodyGid(\"parent\");\n\t\tconst [parent, homes] = await both(\n\t\t\tanchorIfGiven(ctx, \"task\", parentGid),\n\t\t\tPromise.all(\n\t\t\t\tmembershipsOfBody(ctx.body).map(async (membership) => ({\n\t\t\t\t\tmembership,\n\t\t\t\t\tproject: await ctx.anchor(\"project\", membership.project),\n\t\t\t\t})),\n\t\t\t),\n\t\t);\n\t\tconst preliminary = await createdTaskFacts(ctx, { parent, homes }, ctx.body);\n\t\tconst data = ctx.shape(preliminary, { resource: \"task\", verb: \"create\" });\n\t\t// The shaped body may carry other tags, assignee or custom field values.\n\t\tconst facts = {\n\t\t\t...preliminary,\n\t\t\t...(await crossFactsOf(ctx, data)),\n\t\t\tstate: createdTaskState(ctx, data, parent),\n\t\t};\n\t\t// The new task has no gid yet; its name tells a person what is being created.\n\t\tconst target: Target = {\n\t\t\ttype: \"task\",\n\t\t\tgid: \"(new)\",\n\t\t\tfacts,\n\t\t\t...(typeof data.name === \"string\" && { object: { name: data.name } }),\n\t\t};\n\t\tconst checks: Check[] = [\n\t\t\t...(parent === undefined ? [] : [{ target: parent, actions: [] }]),\n\t\t\t{ target, actions: [actionOf(\"task\", \"create\")] },\n\t\t];\n\t\treturn { checks, data, response: { kind: \"item\", type: \"task\" } };\n\t});\n}\n\n/** The task as it would be placed in `container` (a project or a section), optionally in `section`. */\nfunction homedIn(task: Target, container: Facts, section?: string): Target {\n\treturn {\n\t\ttype: \"task\",\n\t\tgid: task.gid,\n\t\tfacts: {\n\t\t\t...task.facts,\n\t\t\tworkspace: container.workspace,\n\t\t\tbranches: container.branches.map((branch) => ({\n\t\t\t\t...branch,\n\t\t\t\t...(section !== undefined && { section }),\n\t\t\t\ttaskChain: [task.gid],\n\t\t\t})),\n\t\t},\n\t};\n}\n\n/**\n * The task as it would be placed under `parent` (or made top-level when\n * `parent` is undefined): a task without a project of its own takes the\n * parent's placement, and its ancestor chain becomes the parent's.\n */\nfunction placedUnder(task: Target, parent: Target | undefined): Target {\n\tconst own = membershipsOf(task.object ?? {}).length > 0;\n\tconst chainOf = (branch: { readonly taskChain: readonly string[] }): string[] => [\n\t\ttask.gid,\n\t\t...branch.taskChain.filter((gid) => gid !== task.gid),\n\t];\n\tlet branches = task.facts.branches.map((branch) => ({ ...branch, taskChain: [task.gid] }));\n\tif (parent === undefined && !own) {\n\t\tbranches = [{ ...WORKSPACE_BRANCH, unhomed: true, taskChain: [task.gid] }];\n\t} else if (parent !== undefined) {\n\t\tconst source = own ? task.facts.branches : parent.facts.branches;\n\t\tconst [parentBranch] = parent.facts.branches;\n\t\tbranches = source.map((branch) => ({\n\t\t\t...branch,\n\t\t\ttaskChain: chainOf(own ? (parentBranch ?? branch) : branch),\n\t\t}));\n\t}\n\treturn {\n\t\ttype: \"task\",\n\t\tgid: task.gid,\n\t\tfacts: {\n\t\t\t...task.facts,\n\t\t\tworkspace: parent?.facts.workspace ?? task.facts.workspace,\n\t\t\tbranches,\n\t\t\tstate: { ...task.facts.state, hasParent: parent !== undefined },\n\t\t},\n\t};\n}\n\n/** `POST /tasks/{gid}/setParent`: the moved task must be creatable where it lands, as itself. */\nconst setParentRule = make({ resource: \"task\", verb: \"set_parent\", scope: \"path\" }, async (ctx) => {\n\tconst [task, parent] = await both(\n\t\tctx.anchor(\"task\", pathGid(ctx)),\n\t\tanchorIfGiven(ctx, \"task\", ctx.bodyGid(\"parent\")),\n\t);\n\tconst unparented = parent === undefined && ctx.body.parent === null;\n\treturn {\n\t\tchecks: [\n\t\t\t{ target: task, actions: [actionOf(\"task\", \"set_parent\")] },\n\t\t\t...(parent === undefined ? [] : [{ target: parent, actions: [] }]),\n\t\t\t...(parent !== undefined || unparented\n\t\t\t\t? [{ target: placedUnder(task, parent), actions: [actionOf(\"task\", \"create\")] }]\n\t\t\t\t: []),\n\t\t],\n\t\tresponse: { kind: \"item\", type: \"task\" },\n\t\tinvalidate: [{ type: \"task\", gid: task.gid }],\n\t};\n});\n\n/** `POST /tasks/{gid}/addProject`: the task may be added, and may be created where it lands. */\nconst addProjectRule = make(\n\t{ resource: \"task\", verb: \"add_project\", scope: \"path\" },\n\tasync (ctx) => {\n\t\tconst [task, project] = await both(\n\t\t\tctx.anchor(\"task\", pathGid(ctx)),\n\t\t\tctx.anchor(\"project\", ctx.bodyGid(\"project\")),\n\t\t);\n\t\tconst destination = homedIn(task, project.facts, ctx.bodyGid(\"section\"));\n\t\treturn {\n\t\t\tchecks: [\n\t\t\t\t{ target: task, actions: [actionOf(\"task\", \"add_project\")] },\n\t\t\t\t{ target: project, actions: [] },\n\t\t\t\t{ target: destination, actions: [actionOf(\"task\", \"create\")] },\n\t\t\t],\n\t\t\tresponse: RAW,\n\t\t\tinvalidate: [{ type: \"task\", gid: task.gid }],\n\t\t};\n\t},\n);\n\n/** `POST /tasks/{gid}/removeProject`: the project must be visible. */\nconst removeProjectRule = actOn({\n\ton: \"task\",\n\tverb: \"remove_project\",\n\talso: [{ field: \"project\", types: [\"project\"] }],\n});\n\n/**\n * `POST /sections/{gid}/addTask`: moving a task needs `move` where it is and\n * where it goes. A task from outside the project is added to it (verified\n * live), which additionally needs `create` there.\n */\nconst addTaskForSectionRule = make(\n\t{ resource: \"task\", verb: \"move\", scope: \"path\" },\n\tasync (ctx) => {\n\t\tconst [section, task] = await both(\n\t\t\tctx.anchor(\"section\", pathGid(ctx)),\n\t\t\tctx.anchor(\"task\", ctx.bodyGid(\"task\")),\n\t\t);\n\t\tconst [sectionBranch] = section.facts.branches;\n\t\tconst alreadyIn = task.facts.branches.some(\n\t\t\t(branch) => branch.project === sectionBranch?.project,\n\t\t);\n\t\tconst destination = homedIn(task, section.facts);\n\t\tconst moveActions = [actionOf(\"task\", \"move\")];\n\t\treturn {\n\t\t\tchecks: [\n\t\t\t\t{ target: section, actions: [] },\n\t\t\t\t{ target: task, actions: moveActions },\n\t\t\t\t{\n\t\t\t\t\ttarget: destination,\n\t\t\t\t\tactions: alreadyIn ? moveActions : [...moveActions, actionOf(\"task\", \"create\")],\n\t\t\t\t},\n\t\t\t],\n\t\t\tresponse: RAW,\n\t\t\tinvalidate: [{ type: \"task\", gid: task.gid }],\n\t\t};\n\t},\n);\n\n/** An update of a task that also changes the tasks the body names (dependencies, dependents): both ends are updated. */\nfunction taskLinkRule(field: string): OperationRule {\n\treturn actOn({\n\t\ton: \"task\",\n\t\tverb: \"update\",\n\t\talso: [{ field, types: [\"task\"], many: true, actions: [actionOf(\"task\", \"update\")] }],\n\t\tshaping: \"checked\",\n\t});\n}\n\n/** `POST /tasks/{gid}/addTag` and `removeTag`: `tag:apply` in the task's scope, on a visible tag. */\nconst tagApplyRule = actOn({\n\ton: \"task\",\n\tverb: \"apply\",\n\tresource: \"tag\",\n\talso: [{ field: \"tag\", types: [\"tag\"] }],\n});\n\nasync function refVisible(\n\tctx: PlanContext,\n\tref: Ref | undefined,\n\tfallback: readonly Resource[],\n): Promise<boolean> {\n\tif (ref === undefined) {\n\t\treturn true;\n\t}\n\tconst loaded = await ctx.loader.loadRef(ref, fallback);\n\treturn loaded !== undefined && isVisible(ctx.policy, loaded.facts, loaded.type);\n}\n\n/** The objects of `data`, each as `show` resolves it; the ones it resolves to `undefined` go. */\nasync function mapData(\n\tbody: Record<string, unknown>,\n\tshow: (item: Record<string, unknown>) => Promise<Record<string, unknown> | undefined>,\n): Promise<Record<string, unknown>> {\n\tconst items = Array.isArray(body.data) ? body.data : [];\n\tconst shown = await Promise.all(\n\t\titems.filter((item: unknown) => isObject(item)).map((item) => show(item)),\n\t);\n\treturn { ...body, data: shown.filter((item) => item !== undefined) };\n}\n\n/** The members of an event's `change` that may name another object. */\nconst CHANGE_VALUES = [\"new_value\", \"added_value\", \"removed_value\"] as const;\n\n/**\n * An event as an agent may see it, or `undefined` when it points at hidden\n * objects. A deleted object cannot be loaded any more, so a `deleted` event\n * is kept when its parent is visible; values in `change` that name hidden\n * objects are cleared.\n */\nasync function visibleEvent(\n\tctx: PlanContext,\n\tevent: Record<string, unknown>,\n): Promise<Record<string, unknown> | undefined> {\n\tconst parent = refOf(event.parent);\n\tconst deleted = event.action === \"deleted\";\n\tconst [resourceOk, parentOk] = await Promise.all([\n\t\tdeleted\n\t\t\t? Promise.resolve(parent !== undefined)\n\t\t\t: refVisible(ctx, refOf(event.resource), EVENT_TYPES),\n\t\trefVisible(ctx, parent, EVENT_TYPES),\n\t]);\n\tif (!resourceOk || !parentOk) {\n\t\treturn undefined;\n\t}\n\tconst { change } = event;\n\tif (!isObject(change)) {\n\t\treturn event;\n\t}\n\tconst values = await Promise.all(\n\t\tCHANGE_VALUES.map(async (key) => {\n\t\t\tconst value = change[key];\n\t\t\tconst named = isObject(value) && typeof value.resource_type === \"string\";\n\t\t\tconst visible = !named || (await refVisible(ctx, refOf(value), PARENT_TYPES));\n\t\t\treturn [key, visible ? value : null] as const;\n\t\t}),\n\t);\n\tconst kept = Object.fromEntries(values.filter(([key]) => key in change));\n\treturn { ...event, change: { ...change, ...kept } };\n}\n\n/** `GET /events` and `GET /workspaces/{gid}/events`: every event must point at visible objects. */\nfunction eventsRule(anchor: (ctx: PlanContext) => Promise<Target>): OperationRule {\n\treturn make({ resource: \"event\", verb: \"read\", scope: \"filter\" }, async (ctx) => {\n\t\tconst target = await anchor(ctx);\n\t\treturn {\n\t\t\tchecks: [{ target, actions: [actionOf(\"event\", \"read\")] }],\n\t\t\tresponse: {\n\t\t\t\tkind: \"custom\",\n\t\t\t\ttransform: (body): Promise<Record<string, unknown>> =>\n\t\t\t\t\tmapData(body, (event) => visibleEvent(ctx, event)),\n\t\t\t},\n\t\t};\n\t});\n}\n\n/** `GET /users/{gid}/notifications`: a notification is visible when all of its work objects are. */\nconst notificationsRule = make(\n\t{ resource: \"notification\", verb: \"read\", scope: \"filter\" },\n\tasync (ctx) => {\n\t\tconst user = await ctx.anchor(\"user\", pathGid(ctx));\n\t\tconst workspace = ctx.workspace(ctx.query.workspace);\n\t\treturn {\n\t\t\tchecks: [\n\t\t\t\t{ target: user, actions: [] },\n\t\t\t\t{ target: workspace, actions: [actionOf(\"notification\", \"read\")] },\n\t\t\t],\n\t\t\tresponse: {\n\t\t\t\tkind: \"custom\",\n\t\t\t\ttransform: (body): Promise<Record<string, unknown>> =>\n\t\t\t\t\tmapData(body, async (item) => {\n\t\t\t\t\t\tconst objects = Array.isArray(item.work_objects) ? item.work_objects : [];\n\t\t\t\t\t\tconst visible = await Promise.all(\n\t\t\t\t\t\t\tobjects.map((object: unknown) => refVisible(ctx, refOf(object), PARENT_TYPES)),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn visible.every(Boolean) ? item : undefined;\n\t\t\t\t\t}),\n\t\t\t},\n\t\t};\n\t},\n);\n\ninterface BatchAction {\n\treadonly plan: Plan;\n\treadonly action: Record<string, unknown>;\n}\n\n/**\n * Each action of a batch with its result, in order: Asana's for the actions\n * sent, the answer planned for the others; an action Asana returned no\n * result for has none.\n */\nfunction resultsInOrder(\n\tsubs: readonly BatchAction[],\n\tresults: readonly unknown[],\n): { readonly plan: Plan; readonly result: unknown }[] {\n\tconst fromAsana = results[Symbol.iterator]();\n\treturn subs.flatMap(({ plan }) => {\n\t\tif (plan.answer !== undefined) {\n\t\t\treturn [{ plan, result: { status_code: 200, headers: {}, body: plan.answer } }];\n\t\t}\n\t\tconst next = fromAsana.next();\n\t\treturn next.done === true ? [] : [{ plan, result: next.value }];\n\t});\n}\n\nasync function planBatchAction(\n\tctx: PlanContext,\n\taction: unknown,\n\tindex: number,\n): Promise<BatchAction> {\n\tif (!isObject(action)) {\n\t\tthrow badRequest(`actions[${index}]: expected an object`);\n\t}\n\tconst method = (stringOf(action.method) ?? \"\").toUpperCase();\n\tconst relativePath = stringOf(action.relative_path) ?? \"\";\n\tif (!isHttpMethod(method)) {\n\t\tthrow badRequest(`actions[${index}].method: unsupported method \"${method}\"`);\n\t}\n\tconst match = matchRoute(method, relativePath);\n\tif (match === undefined) {\n\t\tthrow inAction(noRoute(), index);\n\t}\n\t// Asana rejects query strings in relative_path; GET and DELETE actions carry\n\t// their parameters in `data` instead (verified live).\n\tconst data = dataOf(action.data);\n\tconst reads = method === \"GET\" || method === \"DELETE\";\n\t// A read's `opt_fields` joins `options.fields`, where Asana reads a batch\n\t// action's fields, so the caller's and the gate's arrive in one list.\n\tconst { opt_fields: dataFields, ...readData } = reads ? data : {};\n\tconst query = Object.fromEntries(Object.entries(readData).map(([k, v]) => [k, String(v)]));\n\tconst options = isObject(action.options) ? action.options : {};\n\tconst requested = requestedFields(\n\t\tdataFields,\n\t\tArray.isArray(options.fields) ? (options.fields as unknown[]) : [],\n\t);\n\tconst plan = await ctx\n\t\t.planSub({\n\t\t\toperationId: match.operationId,\n\t\t\tspec: match.spec,\n\t\t\tparams: match.params,\n\t\t\t// The read's fields, which a GET by gid answers with.\n\t\t\tquery: requested.length > 0 ? { ...query, opt_fields: requested.join(\",\") } : query,\n\t\t\tbody: reads ? {} : data,\n\t\t\tunit: index,\n\t\t})\n\t\t.catch((error: unknown) => {\n\t\t\tthrow inAction(error, index);\n\t\t});\n\tconst optFields = augmentOptFields(\n\t\tplan.response,\n\t\trequested.length > 0 ? requested : undefined,\n\t\t(type) => ctx.loader.requiredFields(type),\n\t);\n\t// Writes carry the body as the policy shaped it, exactly like a single request.\n\tlet sent: unknown = action.data;\n\tif (reads && dataFields !== undefined) {\n\t\tsent = readData;\n\t} else if (!reads && plan.data !== undefined) {\n\t\tsent = plan.data;\n\t}\n\treturn {\n\t\tplan,\n\t\taction: {\n\t\t\t...action,\n\t\t\t...(sent !== undefined && { data: sent }),\n\t\t\toptions: { ...options, ...(optFields && { fields: optFields }) },\n\t\t},\n\t};\n}\n\n/**\n * `POST /batch`: every action is planned on its own and checked like a\n * single request (limits count each action); one refusal refuses the whole\n * batch and names the action (`actions[i]`).\n */\nconst batchRule = make({ scope: \"batch\" }, async (ctx) => {\n\tconst actions = Array.isArray(ctx.body.actions) ? ctx.body.actions : [];\n\tif (actions.length > BATCH_LIMIT) {\n\t\tthrow badRequest(`actions: at most ${BATCH_LIMIT} per batch`);\n\t}\n\t// Every action is planned; the refusal reported is the first action's, whichever settles first.\n\tconst settled = await Promise.allSettled(\n\t\tactions.map((action: unknown, index) => planBatchAction(ctx, action, index)),\n\t);\n\tconst refused = settled.find((result) => result.status === \"rejected\");\n\tif (refused !== undefined) {\n\t\tthrow refused.reason;\n\t}\n\tconst subs = settled.map((result) => (result as PromiseFulfilledResult<BatchAction>).value);\n\t// Reads answered while planning are not sent; Asana runs a batch's actions in parallel and in\n\t// no order, so a read beside a write could have seen either state anyway.\n\tconst sent = subs.filter((sub) => sub.plan.answer === undefined);\n\treturn {\n\t\tchecks: subs.flatMap((sub, unit) => sub.plan.checks.map((check) => ({ ...check, unit }))),\n\t\tdata: { ...ctx.body, actions: sent.map((sub) => sub.action) },\n\t\t...(sent.length === 0 && { answer: { data: [] } }),\n\t\tinvalidate: subs.flatMap((sub) => sub.plan.invalidate ?? []),\n\t\tresponse: {\n\t\t\tkind: \"custom\",\n\t\t\tasync transform(body): Promise<Record<string, unknown>> {\n\t\t\t\tconst results = resultsInOrder(subs, Array.isArray(body.data) ? body.data : []);\n\t\t\t\tconst processed = await Promise.all(\n\t\t\t\t\tresults.map(async ({ plan, result }) => {\n\t\t\t\t\t\tif (!isObject(result) || !isObject(result.body)) {\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst status = typeof result.status_code === \"number\" ? result.status_code : 200;\n\t\t\t\t\t\tif (status >= 400) {\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn { ...result, body: await ctx.postProcess(plan.response, result.body) };\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn { ...body, data: processed };\n\t\t\t},\n\t\t},\n\t};\n});\n\n/** The body's `team` as a target, when it names one. */\nfunction teamTarget(ctx: PlanContext): Promise<Target | undefined> {\n\treturn anchorIfGiven(ctx, \"team\", ctx.bodyGid(\"team\"));\n}\n\n/**\n * `PUT /projects/{gid}` and `PUT /goals/{gid}`: an update whose body names\n * another team moves the object there, which needs `create` in that team\n * (and the team must be visible), like creating it there would.\n */\nfunction updateMovable(type: \"project\" | \"goal\"): OperationRule {\n\treturn make({ resource: type, verb: \"update\", scope: \"path\" }, async (ctx) => {\n\t\tconst [target, team] = await both(ctx.anchor(type, pathGid(ctx)), teamTarget(ctx));\n\t\tconst { check, data } = writeCheck(ctx, target, { resource: type, verb: \"update\" });\n\t\tconst current = target.facts.branches.map((branch) => branch.team);\n\t\tconst moves = team !== undefined && !current.includes(team.gid);\n\t\treturn {\n\t\t\tchecks: [check, ...(moves ? [{ target: team, actions: [actionOf(type, \"create\")] }] : [])],\n\t\t\tdata,\n\t\t\tresponse: { kind: \"item\", type },\n\t\t\tinvalidate: [{ type, gid: target.gid }],\n\t\t};\n\t});\n}\n\n/**\n * `POST /projects`, `POST /goals` (the workspace in the body) and `POST\n * /workspaces/{gid}/projects` (in the path): create in the body's team, or at\n * workspace level.\n */\nfunction createInTeam(resource: \"project\" | \"goal\", workspaceIn: \"body\" | \"path\"): OperationRule {\n\treturn make({ resource, verb: \"create\", scope: \"body\" }, async (ctx) => {\n\t\tconst workspace = ctx.workspace(\n\t\t\tworkspaceIn === \"path\" ? pathGid(ctx) : ctx.bodyGid(\"workspace\"),\n\t\t);\n\t\tconst target = (await teamTarget(ctx)) ?? workspace;\n\t\tconst { check, data } = writeCheck(ctx, target, { resource, verb: \"create\" });\n\t\treturn { checks: [check], data, response: { kind: \"item\", type: resource } };\n\t});\n}\n\n/** `GET /goals`: anchored on the first filter object the query names. */\nconst getGoalsRule = listBy(\"goal\", [\n\t{ query: \"portfolio\", types: [\"portfolio\"] },\n\t{ query: \"project\", types: [\"project\"] },\n\t{ query: \"task\", types: [\"task\"] },\n\t{ query: \"team\", types: [\"team\"] },\n]);\n\n/** `POST /portfolios/{gid}/addItem` and `removeItem`: the portfolio is updated, the item must be visible. */\nconst portfolioItemRule = actOn({\n\ton: \"portfolio\",\n\tverb: \"update\",\n\talso: [{ field: \"item\", types: [\"project\", \"portfolio\"] }],\n\tshaping: \"opaque\",\n});\n\n/** `POST /projects/{gid}/sections/insert`: reorder a visible section of the project. */\nconst insertSectionRule = actOn({\n\ton: \"project\",\n\tverb: \"reorder\",\n\tresource: \"section\",\n\talso: [{ field: \"section\", types: [\"section\"] }],\n});\n\n/** `POST /goals/{gid}/addSupportingRelationship` and `removeSupportingRelationship`. */\nfunction goalRelationshipRule(verb: Verb): OperationRule {\n\treturn actOn({\n\t\ton: \"goal\",\n\t\tverb,\n\t\tresource: \"goal_relationship\",\n\t\talso: [{ field: \"supporting_resource\", types: [\"goal\", \"project\", \"portfolio\", \"task\"] }],\n\t\tresponse: verb === \"create\" ? \"item\" : \"raw\",\n\t});\n}\n\n/** Options of {@link createFromRule}. */\ninterface CreateFromOptions {\n\t/** The path object's type. */\n\treadonly from: Resource;\n\t/** The path object must also allow `read` (a template being instantiated). */\n\treadonly read?: true;\n\t/** What is created. */\n\treadonly resource: Resource;\n\t/** How the body relates to `resource` (default `shaped`). */\n\treadonly shaping?: Shaping;\n}\n\n/** `POST /<type>s/{gid}/<action>` creating an object from the path object, in the body's team or where the path object lives. */\nfunction createFromRule(options: CreateFromOptions): OperationRule {\n\tconst { from, resource, shaping } = options;\n\treturn make({ resource, verb: \"create\", scope: \"path\" }, async (ctx) => {\n\t\tconst [source, team] = await both(ctx.anchor(from, pathGid(ctx)), teamTarget(ctx));\n\t\tconst { check, data } = writeCheck(ctx, team ?? source, { resource, verb: \"create\", shaping });\n\t\tconst actions = options.read === true ? [actionOf(from, \"read\")] : [];\n\t\treturn { checks: [{ target: source, actions }, check], data, response: RAW };\n\t});\n}\n\n/**\n * `POST /project_templates/{gid}/instantiateProject`: the template is read, a\n * project is created in the team. The body (name, team, dates, roles)\n * instantiates the template, not a project body.\n */\nconst instantiateProjectRule = createFromRule({\n\tfrom: \"project_template\",\n\tread: true,\n\tresource: \"project\",\n\tshaping: \"opaque\",\n});\n\n/** `POST /task_templates/{gid}/instantiateTask`: the template is read, a task is created in its project. */\nconst instantiateTaskRule = make(\n\t{ resource: \"task\", verb: \"create\", scope: \"path\" },\n\tasync (ctx) => {\n\t\tconst template = await ctx.anchor(\"task_template\", pathGid(ctx));\n\t\tconst { check, data } = writeCheck(ctx, template, {\n\t\t\tresource: \"task\",\n\t\t\tverb: \"create\",\n\t\t\tshaping: \"opaque\",\n\t\t});\n\t\treturn {\n\t\t\tchecks: [{ ...check, actions: [actionOf(\"task_template\", \"read\"), ...check.actions] }],\n\t\t\tdata,\n\t\t\tresponse: RAW,\n\t\t};\n\t},\n);\n\n/** `POST /projects/{gid}/saveAsTemplate`: a template is created where the project (or the body's team) lives. */\nconst saveAsTemplateRule = createFromRule({ from: \"project\", resource: \"project_template\" });\n\n/** `GET|PUT /users/{gid}` and `GET|PUT /workspaces/{wgid}/users/{gid}`. */\nfunction userRule(verb: \"read\" | \"update\"): OperationRule {\n\treturn make({ resource: \"user\", verb, scope: \"workspace\" }, async (ctx) => {\n\t\t// `/users/{user_gid}` takes the workspace from `?workspace=`,\n\t\t// `/workspaces/{workspace_gid}/users/{user_gid}` from its path.\n\t\tconst gids = ctx.spec.pathParams.map((param) => ctx.params[param]);\n\t\tconst [workspaceGid, userGid] = gids.length > 1 ? gids : [ctx.query.workspace, gids[0]];\n\t\tconst workspace = ctx.workspace(workspaceGid);\n\t\tconst user = await ctx.anchor(\"user\", userGid);\n\t\tconst { check, data } = writeCheck(ctx, user, { resource: \"user\", verb });\n\t\treturn {\n\t\t\tchecks: [{ target: workspace, actions: [] }, check],\n\t\t\t...(data && { data }),\n\t\t\tresponse: responseOf(\"item\", \"user\", verb === \"read\" ? user.facts : undefined),\n\t\t};\n\t});\n}\n\n/**\n * The results of a request whose `resource_type` query names their type\n * (typeahead, favorites): judged as objects of that type, or one by one when\n * it names none the gate knows.\n */\nfunction listOfQueried(resourceType: string | undefined): ResponsePlan {\n\tconst type = resourceOfType(resourceType);\n\treturn { kind: \"list\", type: \"mixed\", ...(type !== undefined && { expect: [type] }) };\n}\n\n/** Options of {@link forUserRule}. */\ninterface ForUserOptions {\n\t/** The list holds objects of the type its `resource_type` query names (favorites) rather than `resource`s. */\n\treadonly mixed?: true;\n\t/** The response is one object at workspace level (the user's task list), not a filtered list. */\n\treadonly one?: true;\n\t/** The query member naming the workspace (default `workspace`). */\n\treadonly workspaceQuery?: string;\n}\n\n/** `GET /users/{gid}/<things>`: `resource:read` in the workspace the query names, on a visible user. */\nfunction forUserRule(resource: Resource, options: ForUserOptions = {}): OperationRule {\n\tconst scope: ScopeKind = options.one === true ? \"workspace\" : \"filter\";\n\treturn make({ resource, verb: \"read\", scope }, async (ctx) => {\n\t\tconst user = await ctx.anchor(\"user\", pathGid(ctx));\n\t\tconst workspace = ctx.workspace(ctx.query[options.workspaceQuery ?? \"workspace\"]);\n\t\tconst list: ResponsePlan =\n\t\t\toptions.mixed === true\n\t\t\t\t? listOfQueried(ctx.query.resource_type)\n\t\t\t\t: { kind: \"list\", type: resource };\n\t\treturn {\n\t\t\tchecks: [\n\t\t\t\t{ target: user, actions: [] },\n\t\t\t\t{ target: workspace, actions: [actionOf(resource, \"read\")] },\n\t\t\t],\n\t\t\tresponse:\n\t\t\t\toptions.one === true ? { kind: \"item\", type: resource, facts: workspace.facts } : list,\n\t\t};\n\t});\n}\n\n/** `GET /workspaces`: only the governed workspace is listed. */\nconst getWorkspacesRule = make({ resource: \"workspace\", verb: \"read\", scope: \"filter\" }, (ctx) =>\n\tPromise.resolve({\n\t\tchecks: [{ target: ctx.workspace(), actions: [] }],\n\t\tresponse: { kind: \"list\", type: \"workspace\" },\n\t}),\n);\n\n/** `GET /workspaces/{gid}/typeahead`: results of the type asked for (`type` is its deprecated name). */\nconst typeaheadRule = make({ resource: \"workspace\", verb: \"read\", scope: \"filter\" }, (ctx) =>\n\tPromise.resolve({\n\t\tchecks: [{ target: ctx.workspace(pathGid(ctx)), actions: [] }],\n\t\tresponse: listOfQueried(ctx.query.resource_type ?? ctx.query.type),\n\t}),\n);\n\n/**\n * `GET /workspaces/{gid}/tasks/custom_id/{id}`: the task can only be checked\n * once found; `limit` and `confirm` on `task:read` apply at workspace level\n * before it is fetched.\n */\nconst taskForCustomIdRule = make({ resource: \"task\", verb: \"read\", scope: \"workspace\" }, (ctx) =>\n\tPromise.resolve({\n\t\tchecks: [\n\t\t\t{\n\t\t\t\ttarget: ctx.workspace(pathGid(ctx)),\n\t\t\t\tactions: [],\n\t\t\t\tcounted: [actionOf(\"task\", \"read\")],\n\t\t\t},\n\t\t],\n\t\tresponse: { kind: \"item\", type: \"task\", verify: true },\n\t}),\n);\n\n/** An object a request names in a query or body member, which must be visible. */\ninterface Named {\n\treadonly gid: string;\n\treadonly types: readonly Resource[];\n}\n\n/** The rule, after the objects the request names (`named(ctx)`) are found visible. */\nfunction naming(rule: OperationRule, named: (ctx: PlanContext) => readonly Named[]): OperationRule {\n\treturn {\n\t\t...rule,\n\t\tasync plan(ctx) {\n\t\t\tconst targets = await Promise.all(named(ctx).map(({ gid, types }) => ctx.probe(gid, types)));\n\t\t\tconst plan = await rule.plan(ctx);\n\t\t\treturn {\n\t\t\t\t...plan,\n\t\t\t\tchecks: [...targets.map((target) => ({ target, actions: [] })), ...plan.checks],\n\t\t\t};\n\t\t},\n\t};\n}\n\n/** The gid-valued filters of `GET /workspaces/{gid}/tasks/search` (`projects.any`, …) and what they name. */\nconst SEARCH_FILTERS: Readonly<Record<string, Resource>> = {\n\tprojects: \"project\",\n\tsections: \"section\",\n\ttags: \"tag\",\n\tteams: \"team\",\n\tportfolios: \"portfolio\",\n\tcustom_fields: \"custom_field\",\n};\n\n/** The objects a task search names: the gids of its filters, and the custom fields its keys name. */\nfunction searchNamed(ctx: PlanContext): Named[] {\n\treturn Object.entries(ctx.query).flatMap(([key, value]): Named[] => {\n\t\tconst [member = \"\", field] = key.split(\".\");\n\t\tconst type = SEARCH_FILTERS[member];\n\t\tif (type === undefined) {\n\t\t\treturn [];\n\t\t}\n\t\tif (type === \"custom_field\") {\n\t\t\treturn field !== undefined && isGid(field) ? [{ gid: field, types: [type] }] : [];\n\t\t}\n\t\treturn splitList(value)\n\t\t\t.filter((gid) => isGid(gid))\n\t\t\t.map((gid) => ({ gid, types: [type] }));\n\t});\n}\n\n/** The project or portfolio an access request names (`target`), from the query or the body. */\nconst ACCESS_TARGET_TYPES: readonly Resource[] = [\"project\", \"portfolio\"];\n\nfunction accessTarget(gid: string | undefined): Named[] {\n\treturn gid === undefined ? [] : [{ gid, types: ACCESS_TARGET_TYPES }];\n}\n\n/** A subset of the object operations (naming another is a type error). */\ntype ObjectOperations<Ids extends ObjectOperationId> = Ids;\n\n/**\n * Object operations classified otherwise: jobs, organization exports, users\n * and workspaces are judged at workspace level, and an update that moves a\n * project or a goal to another team needs `create` there.\n */\ntype ClassifiedOtherwise = ObjectOperations<\n\t| \"getJob\"\n\t| \"getOrganizationExport\"\n\t| \"getUser\"\n\t| \"updateUser\"\n\t| \"getWorkspace\"\n\t| \"updateWorkspace\"\n\t| \"updateProject\"\n\t| \"updateGoal\"\n>;\n\n/** The operations classified from their path alone. */\ntype DerivedId = Exclude<ObjectOperationId, ClassifiedOtherwise>;\n\n/** The rule of a plain read, update or delete of one object, when `spec` is one. */\nfunction objectRule(spec: OperationSpec): OperationRule | undefined {\n\tconst operation = objectOperationOf(spec);\n\tif (operation === undefined) {\n\t\treturn undefined;\n\t}\n\tconst rules = { read: getOne, update: updateOne, delete: deleteOne };\n\treturn rules[operation.verb](operation.resource);\n}\n\n/**\n * The classification of every operation that is not a plain read, update or\n * delete of one object (those are derived from their path); a missing entry\n * is a type error, and so is an entry for a derived operation not listed in\n * {@link ClassifiedOtherwise}.\n */\nconst RULES = {\n\t// Access requests\n\tgetAccessRequests: naming(\n\t\tonWorkspace(\"access_request\", \"read\", { response: \"list\", scope: \"filter\" }),\n\t\t(ctx) => accessTarget(ctx.query.target),\n\t),\n\tcreateAccessRequest: naming(\n\t\tonWorkspace(\"access_request\", \"create\", { response: \"item\" }),\n\t\t(ctx) => accessTarget(ctx.bodyGid(\"target\")),\n\t),\n\tapproveAccessRequest: onWorkspace(\"access_request\", \"update\", {\n\t\tresponse: \"item\",\n\t\tshaping: \"opaque\",\n\t}),\n\trejectAccessRequest: onWorkspace(\"access_request\", \"update\", {\n\t\tresponse: \"item\",\n\t\tshaping: \"opaque\",\n\t}),\n\t// Agents\n\tgetAgentsForWorkspace: onWorkspace(\"agent\", \"read\", {\n\t\tpath: true,\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\t// AI Studio usage API\n\tgetAiStudioRuns: onWorkspace(\"ai_studio_usage\", \"read\", { path: true }),\n\tgetAiStudioSeats: onWorkspace(\"ai_studio_usage\", \"read\", { path: true }),\n\t// Allocations\n\tgetAllocations: listBy(\"allocation\", [{ query: \"parent\", types: [\"project\", \"portfolio\"] }]),\n\tcreateAllocation: onBody({\n\t\tresource: \"allocation\",\n\t\tverb: \"create\",\n\t\tfield: \"parent\",\n\t\ttypes: [\"project\", \"portfolio\"],\n\t}),\n\t// Attachments\n\tgetAttachmentsForObject: listBy(\n\t\t\"attachment\",\n\t\t[{ query: \"parent\", types: [\"task\", \"project_brief\"] }],\n\t\t{ required: true, shared: true },\n\t),\n\tcreateAttachmentForObject: onBody({\n\t\tresource: \"attachment\",\n\t\tverb: \"create\",\n\t\tfield: \"parent\",\n\t\ttypes: [\"task\", \"project_brief\"],\n\t\tshared: true,\n\t}),\n\t// Audit log API\n\tgetAuditLogEvents: onWorkspace(\"audit_log\", \"read\", { path: true }),\n\t// Batch API\n\tcreateBatchRequest: batchRule,\n\t// Budgets\n\tgetBudgets: listBy(\"budget\", [{ query: \"parent\", types: [\"project\", \"portfolio\"] }], {\n\t\trequired: true,\n\t\tshared: true,\n\t}),\n\tcreateBudget: onBody({\n\t\tresource: \"budget\",\n\t\tverb: \"create\",\n\t\tfield: \"parent\",\n\t\ttypes: [\"project\", \"portfolio\"],\n\t}),\n\t// Custom field settings\n\tgetCustomFieldSettingsForGoal: listUnder({\n\t\tunder: \"goal\",\n\t\titems: \"custom_field_setting\",\n\t\tshared: true,\n\t}),\n\tgetCustomFieldSettingsForPortfolio: listUnder({\n\t\tunder: \"portfolio\",\n\t\titems: \"custom_field_setting\",\n\t\tshared: true,\n\t}),\n\tgetCustomFieldSettingsForProject: listUnder({\n\t\tunder: \"project\",\n\t\titems: \"custom_field_setting\",\n\t\tshared: true,\n\t}),\n\tgetCustomFieldSettingsForTeam: listUnder({\n\t\tunder: \"team\",\n\t\titems: \"custom_field_setting\",\n\t\tshared: true,\n\t}),\n\t// Custom fields\n\tcreateCustomField: onWorkspace(\"custom_field\", \"create\", { body: \"workspace\", response: \"item\" }),\n\tcreateEnumOptionForCustomField: actOn({\n\t\ton: \"custom_field\",\n\t\tverb: \"update\",\n\t\tshaping: \"opaque\",\n\t}),\n\tinsertEnumOptionForCustomField: actOn({\n\t\ton: \"custom_field\",\n\t\tverb: \"update\",\n\t\tshaping: \"opaque\",\n\t}),\n\tupdateEnumOption: onWorkspace(\"custom_field\", \"update\", { shaping: \"opaque\" }),\n\tgetCustomFieldsForWorkspace: onWorkspace(\"custom_field\", \"read\", {\n\t\tpath: true,\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\t// Custom types\n\tgetCustomTypes: listBy(\"custom_type\", [{ query: \"project\", types: [\"project\"] }]),\n\t// Events\n\tgetEvents: eventsRule((ctx) => ctx.probe(ctx.query.resource, EVENT_TYPES)),\n\t// Exports\n\tcreateGraphExport: onBody({\n\t\tresource: \"export\",\n\t\tverb: \"create\",\n\t\tfield: \"parent\",\n\t\ttypes: [\"project\", \"portfolio\", \"goal\", \"team\"],\n\t\tresponse: \"raw\",\n\t}),\n\tcreateResourceExport: onWorkspace(\"export\", \"create\", { body: \"workspace\" }),\n\t// Goal relationships\n\tgetGoalRelationships: listBy(\n\t\t\"goal_relationship\",\n\t\t[{ query: \"supported_goal\", types: [\"goal\"] }],\n\t\t{ shared: true },\n\t),\n\taddSupportingRelationship: goalRelationshipRule(\"create\"),\n\tremoveSupportingRelationship: goalRelationshipRule(\"delete\"),\n\t// Goals\n\tupdateGoal: updateMovable(\"goal\"),\n\tgetGoals: getGoalsRule,\n\tcreateGoal: createInTeam(\"goal\", \"body\"),\n\tcreateGoalMetric: actOn({\n\t\ton: \"goal\",\n\t\tverb: \"update\",\n\t\tresponse: \"item\",\n\t\tshaping: \"opaque\",\n\t}),\n\tupdateGoalMetric: actOn({\n\t\ton: \"goal\",\n\t\tverb: \"update\",\n\t\tresponse: \"item\",\n\t\tshaping: \"opaque\",\n\t}),\n\taddFollowers: actOn({\n\t\ton: \"goal\",\n\t\tverb: \"update\",\n\t\tresponse: \"item\",\n\t\tshaping: \"checked\",\n\t}),\n\tremoveFollowers: actOn({\n\t\ton: \"goal\",\n\t\tverb: \"update\",\n\t\tresponse: \"item\",\n\t\tshaping: \"checked\",\n\t}),\n\tgetParentGoalsForGoal: listUnder({ under: \"goal\", items: \"goal\" }),\n\taddCustomFieldSettingForGoal: actOn({\n\t\ton: \"goal\",\n\t\tverb: \"create\",\n\t\tresource: \"custom_field_setting\",\n\t}),\n\tremoveCustomFieldSettingForGoal: actOn({\n\t\ton: \"goal\",\n\t\tverb: \"delete\",\n\t\tresource: \"custom_field_setting\",\n\t}),\n\t// Jobs\n\t// An item, so the objects a job created (`new_project`, `new_task`) are checked like any nested reference.\n\tgetJob: onWorkspace(\"job\", \"read\", { response: \"item\" }),\n\t// Memberships\n\tgetMemberships: listBy(\n\t\t\"membership\",\n\t\t[{ query: \"parent\", types: [\"project\", \"portfolio\", \"goal\", \"custom_field\"] }],\n\t\t{ shared: true },\n\t),\n\tcreateMembership: onBody({\n\t\tresource: \"membership\",\n\t\tverb: \"create\",\n\t\tfield: \"parent\",\n\t\ttypes: [\"project\", \"portfolio\", \"goal\", \"custom_field\"],\n\t\tshared: true,\n\t}),\n\t// Notifications\n\tgetNotificationsForUser: notificationsRule,\n\tmarkNotificationsReadForUser: onWorkspace(\"notification\", \"update\", { body: \"workspace\" }),\n\tmarkNotificationsUnreadForUser: onWorkspace(\"notification\", \"update\", { body: \"workspace\" }),\n\t// Ooo entries\n\tgetOooEntries: onWorkspace(\"ooo_entry\", \"read\", {\n\t\tquery: \"workspace\",\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\tcreateOooEntry: onWorkspace(\"ooo_entry\", \"create\", { body: \"workspace\", response: \"item\" }),\n\t// Organization exports\n\tcreateOrganizationExport: onWorkspace(\"organization_export\", \"create\", { body: \"organization\" }),\n\tgetOrganizationExport: onWorkspace(\"organization_export\", \"read\"),\n\t// Portfolio memberships\n\tgetPortfolioMemberships: listBy(\n\t\t\"portfolio_membership\",\n\t\t[{ query: \"portfolio\", types: [\"portfolio\"] }],\n\t\t{ shared: true },\n\t),\n\tgetPortfolioMembershipsForPortfolio: listUnder({\n\t\tunder: \"portfolio\",\n\t\titems: \"portfolio_membership\",\n\t\tshared: true,\n\t}),\n\t// Portfolios\n\tgetPortfolios: onWorkspace(\"portfolio\", \"read\", {\n\t\tquery: \"workspace\",\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\tcreatePortfolio: onWorkspace(\"portfolio\", \"create\", { body: \"workspace\", response: \"item\" }),\n\tgetItemsForPortfolio: listUnder({\n\t\tunder: \"portfolio\",\n\t\titems: \"mixed\",\n\t\texpect: [\"project\", \"portfolio\"],\n\t}),\n\taddItemForPortfolio: portfolioItemRule,\n\tremoveItemForPortfolio: portfolioItemRule,\n\taddCustomFieldSettingForPortfolio: actOn({\n\t\ton: \"portfolio\",\n\t\tverb: \"create\",\n\t\tresource: \"custom_field_setting\",\n\t}),\n\tremoveCustomFieldSettingForPortfolio: actOn({\n\t\ton: \"portfolio\",\n\t\tverb: \"delete\",\n\t\tresource: \"custom_field_setting\",\n\t}),\n\taddMembersForPortfolio: actOn({\n\t\ton: \"portfolio\",\n\t\tverb: \"manage_members\",\n\t\tresponse: \"item\",\n\t}),\n\tremoveMembersForPortfolio: actOn({\n\t\ton: \"portfolio\",\n\t\tverb: \"manage_members\",\n\t\tresponse: \"item\",\n\t}),\n\tduplicatePortfolio: actOn({\n\t\ton: \"portfolio\",\n\t\tverb: \"create\",\n\t\tshaping: \"opaque\",\n\t}),\n\t// Project briefs\n\tcreateProjectBrief: createUnder({\n\t\tunder: \"project\",\n\t\titem: \"project_brief\",\n\t\tshared: true,\n\t}),\n\t// Project memberships\n\tgetProjectMembershipsForProject: listUnder({\n\t\tunder: \"project\",\n\t\titems: \"project_membership\",\n\t\tshared: true,\n\t}),\n\t// Project portfolio settings\n\tgetProjectPortfolioSettingsForProject: listUnder({\n\t\tunder: \"project\",\n\t\titems: \"project_portfolio_setting\",\n\t\tshared: true,\n\t}),\n\tgetProjectPortfolioSettingsForPortfolio: listUnder({\n\t\tunder: \"portfolio\",\n\t\titems: \"project_portfolio_setting\",\n\t}),\n\t// Project statuses (the older status update API)\n\tgetProjectStatus: getOne(\"status_update\"),\n\tdeleteProjectStatus: deleteOne(\"status_update\"),\n\tgetProjectStatusesForProject: listUnder({\n\t\tunder: \"project\",\n\t\titems: \"status_update\",\n\t\tshared: true,\n\t}),\n\tcreateProjectStatusForProject: createUnder({\n\t\tunder: \"project\",\n\t\titem: \"status_update\",\n\t\tshared: true,\n\t}),\n\t// Project templates\n\tgetProjectTemplates: listBy(\"project_template\", [{ query: \"team\", types: [\"team\"] }]),\n\tgetProjectTemplatesForTeam: listUnder({\n\t\tunder: \"team\",\n\t\titems: \"project_template\",\n\t}),\n\tinstantiateProject: instantiateProjectRule,\n\t// Projects\n\tgetProjects: listBy(\"project\", [{ query: \"team\", types: [\"team\"] }]),\n\tcreateProject: createInTeam(\"project\", \"body\"),\n\tupdateProject: updateMovable(\"project\"),\n\tduplicateProject: actOn({\n\t\ton: \"project\",\n\t\tverb: \"create\",\n\t\tshaping: \"opaque\",\n\t}),\n\tgetProjectsForTask: listUnder({ under: \"task\", items: \"project\" }),\n\tgetProjectsForTeam: listUnder({ under: \"team\", items: \"project\" }),\n\tcreateProjectForTeam: createUnder({ under: \"team\", item: \"project\" }),\n\tgetProjectsForWorkspace: onWorkspace(\"project\", \"read\", {\n\t\tpath: true,\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\tcreateProjectForWorkspace: createInTeam(\"project\", \"path\"),\n\tsearchProjectsForWorkspace: onWorkspace(\"project\", \"read\", {\n\t\tpath: true,\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\taddCustomFieldSettingForProject: actOn({\n\t\ton: \"project\",\n\t\tverb: \"create\",\n\t\tresource: \"custom_field_setting\",\n\t}),\n\tremoveCustomFieldSettingForProject: actOn({\n\t\ton: \"project\",\n\t\tverb: \"delete\",\n\t\tresource: \"custom_field_setting\",\n\t}),\n\tgetTaskCountsForProject: actOn({ on: \"project\", verb: \"read\" }),\n\taddMembersForProject: actOn({\n\t\ton: \"project\",\n\t\tverb: \"manage_members\",\n\t\tresponse: \"item\",\n\t}),\n\tremoveMembersForProject: actOn({\n\t\ton: \"project\",\n\t\tverb: \"manage_members\",\n\t\tresponse: \"item\",\n\t}),\n\taddFollowersForProject: actOn({\n\t\ton: \"project\",\n\t\tverb: \"update\",\n\t\tresponse: \"item\",\n\t\tshaping: \"checked\",\n\t}),\n\tremoveFollowersForProject: actOn({\n\t\ton: \"project\",\n\t\tverb: \"update\",\n\t\tresponse: \"item\",\n\t\tshaping: \"checked\",\n\t}),\n\tprojectSaveAsTemplate: saveAsTemplateRule,\n\trollupProject: actOn({\n\t\ton: \"project\",\n\t\tverb: \"update\",\n\t\tshaping: \"checked\",\n\t}),\n\t// Rates\n\tgetRates: listBy(\"rate\", [{ query: \"parent\", types: [\"project\", \"portfolio\"] }], {\n\t\trequired: true,\n\t\tshared: true,\n\t}),\n\tcreateRate: onBody({\n\t\tresource: \"rate\",\n\t\tverb: \"create\",\n\t\tfield: \"parent\",\n\t\ttypes: [\"project\", \"portfolio\"],\n\t}),\n\t// Reactions\n\tgetReactionsOnObject: listBy(\n\t\t\"reaction\",\n\t\t[{ query: \"target\", types: [\"story\", \"task\", \"status_update\", \"project_brief\"] }],\n\t\t{ required: true, shared: true },\n\t),\n\t// Records\n\tgetRecordsForTable: listUnder({\n\t\tunder: \"table\",\n\t\titems: \"record\",\n\t\tshared: true,\n\t}),\n\tsearchRecordsForWorkspace: onWorkspace(\"record\", \"read\", {\n\t\tpath: true,\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\tcreateRecord: onWorkspace(\"record\", \"create\", { response: \"item\" }),\n\t// Roles\n\tgetRoles: onWorkspace(\"role\", \"read\", { query: \"workspace\", response: \"list\", scope: \"filter\" }),\n\tcreateRole: onWorkspace(\"role\", \"create\", { body: \"workspace\", response: \"item\" }),\n\t// Rules\n\ttriggerRule: onBody({\n\t\tresource: \"rule\",\n\t\tverb: \"trigger\",\n\t\tfield: \"resource\",\n\t\ttypes: [\"task\", \"project\"],\n\t\tresponse: \"raw\",\n\t}),\n\t// Sections\n\tgetSectionsForProject: listUnder({ under: \"project\", items: \"section\" }),\n\tcreateSectionForProject: createUnder({ under: \"project\", item: \"section\" }),\n\taddTaskForSection: addTaskForSectionRule,\n\tinsertSectionForProject: insertSectionRule,\n\t// Status updates\n\tgetStatusesForObject: listBy(\n\t\t\"status_update\",\n\t\t[{ query: \"parent\", types: [\"project\", \"portfolio\", \"goal\"] }],\n\t\t{ required: true, shared: true },\n\t),\n\tcreateStatusForObject: onBody({\n\t\tresource: \"status_update\",\n\t\tverb: \"create\",\n\t\tfield: \"parent\",\n\t\ttypes: [\"project\", \"portfolio\", \"goal\"],\n\t\tshared: true,\n\t}),\n\t// Stories\n\tgetStoriesForTask: listUnder({ under: \"task\", items: \"story\", shared: true }),\n\tcreateStoryForTask: createUnder({\n\t\tunder: \"task\",\n\t\titem: \"story\",\n\t\tshared: true,\n\t}),\n\tgetStoriesForRecord: listUnder({\n\t\tunder: \"record\",\n\t\titems: \"story\",\n\t\tshared: true,\n\t}),\n\tcreateStoryForRecord: createUnder({\n\t\tunder: \"record\",\n\t\titem: \"story\",\n\t\tshared: true,\n\t}),\n\tgetStoriesForGoal: listUnder({ under: \"goal\", items: \"story\", shared: true }),\n\tcreateStoryForGoal: createUnder({\n\t\tunder: \"goal\",\n\t\titem: \"story\",\n\t\tshared: true,\n\t}),\n\t// Tables\n\tgetTablesForWorkspace: onWorkspace(\"table\", \"read\", {\n\t\tpath: true,\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\tcreateTable: onWorkspace(\"table\", \"create\", { body: \"workspace\", response: \"item\" }),\n\taddCustomFieldSettingForTable: actOn({\n\t\ton: \"table\",\n\t\tverb: \"create\",\n\t\tresource: \"custom_field_setting\",\n\t}),\n\tremoveCustomFieldSettingForTable: actOn({\n\t\ton: \"table\",\n\t\tverb: \"delete\",\n\t\tresource: \"custom_field_setting\",\n\t}),\n\tgetCustomFieldSettingsForTableLegacy: listUnder({\n\t\tunder: \"table\",\n\t\titems: \"custom_field_setting\",\n\t\tshared: true,\n\t}),\n\tgetCustomFieldSettingsForTable: listUnder({\n\t\tunder: \"table\",\n\t\titems: \"custom_field_setting\",\n\t\tshared: true,\n\t}),\n\t// Tags\n\tgetTags: onWorkspace(\"tag\", \"read\", { query: \"workspace\", response: \"list\", scope: \"filter\" }),\n\tcreateTag: onWorkspace(\"tag\", \"create\", { body: \"workspace\", response: \"item\" }),\n\tgetTagsForTask: listUnder({ under: \"task\", items: \"tag\" }),\n\tgetTagsForWorkspace: onWorkspace(\"tag\", \"read\", {\n\t\tpath: true,\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\tcreateTagForWorkspace: onWorkspace(\"tag\", \"create\", { path: true, response: \"item\" }),\n\t// Task templates\n\tgetTaskTemplates: listBy(\"task_template\", [{ query: \"project\", types: [\"project\"] }], {\n\t\tshared: true,\n\t}),\n\tinstantiateTask: instantiateTaskRule,\n\t// Tasks\n\tgetTasks: listBy(\"task\", [\n\t\t{ query: \"project\", types: [\"project\"] },\n\t\t{ query: \"section\", types: [\"section\"] },\n\t\t{ query: \"tag\", types: [\"tag\"] },\n\t]),\n\tcreateTask: createTaskRule(\"body\"),\n\tduplicateTask: actOn({ on: \"task\", verb: \"create\", shaping: \"opaque\" }),\n\tgetTasksForProject: listUnder({ under: \"project\", items: \"task\" }),\n\tgetTasksForSection: listUnder({ under: \"section\", items: \"task\" }),\n\tgetTasksForTag: listUnder({ under: \"tag\", items: \"task\" }),\n\tgetTasksForUserTaskList: listUnder({\n\t\tunder: \"user_task_list\",\n\t\titems: \"task\",\n\t}),\n\tgetSubtasksForTask: listUnder({ under: \"task\", items: \"task\" }),\n\tcreateSubtaskForTask: createTaskRule(\"path\"),\n\tsetParentForTask: setParentRule,\n\tgetDependenciesForTask: listUnder({ under: \"task\", items: \"task\" }),\n\taddDependenciesForTask: taskLinkRule(\"dependencies\"),\n\tremoveDependenciesForTask: taskLinkRule(\"dependencies\"),\n\tgetDependentsForTask: listUnder({ under: \"task\", items: \"task\" }),\n\taddDependentsForTask: taskLinkRule(\"dependents\"),\n\tremoveDependentsForTask: taskLinkRule(\"dependents\"),\n\taddProjectForTask: addProjectRule,\n\tremoveProjectForTask: removeProjectRule,\n\taddTagForTask: tagApplyRule,\n\tremoveTagForTask: tagApplyRule,\n\taddFollowersForTask: actOn({\n\t\ton: \"task\",\n\t\tverb: \"update\",\n\t\tresponse: \"item\",\n\t\tshaping: \"checked\",\n\t}),\n\tremoveFollowerForTask: actOn({\n\t\ton: \"task\",\n\t\tverb: \"update\",\n\t\tresponse: \"item\",\n\t\tshaping: \"checked\",\n\t}),\n\trollupTask: actOn({ on: \"task\", verb: \"update\", shaping: \"checked\" }),\n\tgetTaskForCustomID: taskForCustomIdRule,\n\tsearchTasksForWorkspace: naming(\n\t\tonWorkspace(\"task\", \"read\", {\n\t\t\tpath: true,\n\t\t\tresponse: \"list\",\n\t\t\tscope: \"filter\",\n\t\t}),\n\t\tsearchNamed,\n\t),\n\t// Team memberships\n\tgetTeamMemberships: listBy(\"team_membership\", [{ query: \"team\", types: [\"team\"] }], {\n\t\tshared: true,\n\t}),\n\tgetTeamMembershipsForTeam: listUnder({\n\t\tunder: \"team\",\n\t\titems: \"team_membership\",\n\t\tshared: true,\n\t}),\n\tgetTeamMembershipsForUser: forUserRule(\"team_membership\"),\n\t// Teams\n\tcreateTeam: onWorkspace(\"team\", \"create\", { body: \"organization\", response: \"item\" }),\n\tgetTeamsForWorkspace: onWorkspace(\"team\", \"read\", {\n\t\tpath: true,\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\tgetTeamsForUser: forUserRule(\"team\", { workspaceQuery: \"organization\" }),\n\taddUserForTeam: actOn({ on: \"team\", verb: \"manage_members\" }),\n\tremoveUserForTeam: actOn({ on: \"team\", verb: \"manage_members\" }),\n\tgetUsersForTeam: listUnder({ under: \"team\", items: \"user\", shared: true }),\n\t// Time periods\n\tgetTimePeriods: onWorkspace(\"time_period\", \"read\", {\n\t\tquery: \"workspace\",\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\t// Time tracking categories\n\tgetTimeTrackingEntriesForTimeTrackingCategory: listUnder({\n\t\tunder: \"time_tracking_category\",\n\t\titems: \"time_tracking_entry\",\n\t}),\n\tgetTimeTrackingCategories: onWorkspace(\"time_tracking_category\", \"read\", {\n\t\tquery: \"workspace\",\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\tcreateTimeTrackingCategory: onWorkspace(\"time_tracking_category\", \"create\", {\n\t\tbody: \"workspace\",\n\t\tresponse: \"item\",\n\t}),\n\t// Time tracking entries\n\tgetTimeTrackingEntriesForTask: listUnder({\n\t\tunder: \"task\",\n\t\titems: \"time_tracking_entry\",\n\t\tshared: true,\n\t}),\n\tcreateTimeTrackingEntry: createUnder({\n\t\tunder: \"task\",\n\t\titem: \"time_tracking_entry\",\n\t\tshared: true,\n\t}),\n\tgetTimeTrackingEntries: listBy(\"time_tracking_entry\", [\n\t\t{ query: \"task\", types: [\"task\"] },\n\t\t{ query: \"portfolio\", types: [\"portfolio\"] },\n\t]),\n\t// Timesheet approval statuses\n\tgetTimesheetApprovalStatuses: onWorkspace(\"timesheet_approval_status\", \"read\", {\n\t\tquery: \"workspace\",\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\tcreateTimesheetApprovalStatus: onWorkspace(\"timesheet_approval_status\", \"create\", {\n\t\tbody: \"workspace\",\n\t\tresponse: \"item\",\n\t}),\n\t// Typeahead\n\ttypeaheadForWorkspace: typeaheadRule,\n\t// User task lists\n\tgetUserTaskListForUser: forUserRule(\"user_task_list\", { one: true }),\n\t// Users\n\tgetUsers: listBy(\"user\", [{ query: \"team\", types: [\"team\"] }], { shared: true }),\n\tgetUser: userRule(\"read\"),\n\tupdateUser: userRule(\"update\"),\n\tgetFavoritesForUser: forUserRule(\"user\", { mixed: true }),\n\tgetUsersForWorkspace: onWorkspace(\"user\", \"read\", {\n\t\tpath: true,\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\tgetUserForWorkspace: userRule(\"read\"),\n\tupdateUserForWorkspace: userRule(\"update\"),\n\t// Webhooks\n\tgetWebhooks: listBy(\"webhook\", [{ query: \"resource\", types: WEBHOOK_TYPES }]),\n\tcreateWebhook: onBody({\n\t\tresource: \"webhook\",\n\t\tverb: \"create\",\n\t\tfield: \"resource\",\n\t\ttypes: WEBHOOK_TYPES,\n\t\tshared: true,\n\t}),\n\t// Workspace memberships\n\tgetWorkspaceMembershipsForUser: forUserRule(\"workspace_membership\"),\n\tgetWorkspaceMembershipsForWorkspace: onWorkspace(\"workspace_membership\", \"read\", {\n\t\tpath: true,\n\t\tresponse: \"list\",\n\t\tscope: \"filter\",\n\t}),\n\t// Workspaces\n\tgetWorkspaces: getWorkspacesRule,\n\tgetWorkspace: onWorkspace(\"workspace\", \"read\", { path: true, response: \"item\" }),\n\tupdateWorkspace: onWorkspace(\"workspace\", \"update\", { path: true, response: \"item\" }),\n\taddUserForWorkspace: onWorkspace(\"workspace\", \"manage_members\", { path: true }),\n\tremoveUserForWorkspace: onWorkspace(\"workspace\", \"manage_members\", { path: true }),\n\tgetWorkspaceEvents: eventsRule((ctx) => Promise.resolve(ctx.workspace(pathGid(ctx)))),\n} satisfies Record<Exclude<OperationId, DerivedId>, OperationRule>;\n\n/** Operation classification, one entry per Asana operation. */\nconst CLASSIFICATION = Object.fromEntries(\n\tObject.entries(OPERATIONS).flatMap(([id, spec]) => {\n\t\tconst rule = (RULES as Partial<Record<string, OperationRule>>)[id] ?? objectRule(spec);\n\t\treturn rule === undefined ? [] : [[id, rule] as const];\n\t}),\n) as Record<OperationId, OperationRule>;\n\n/** The classification of an operation. */\nfunction ruleFor(operationId: OperationId): OperationRule {\n\treturn CLASSIFICATION[operationId];\n}\n\nexport { CLASSIFICATION, ruleFor };\nexport type { OperationRule, ScopeKind };\n"],"mappings":"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"}