@neat.is/types 0.7.5 → 0.7.6

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.
package/dist/index.js CHANGED
@@ -102,7 +102,22 @@ var NodeType = {
102
102
  // file (observed-first edges, one grain finer than §4 file grain). The node is
103
103
  // language-neutral; the per-language tree-sitter extractor is the adapter. See
104
104
  // docs/contracts/static-extraction.md and docs/contracts/file-awareness.md §1.
105
- SymbolNode: "SymbolNode"
105
+ SymbolNode: "SymbolNode",
106
+ // A Next.js Server Action at (service, module, exportName) granularity
107
+ // (ADR-168). A Server Action is the RPC boundary of an App Router app: the
108
+ // client posts to it, Next serialises the call to an opaque `Next-Action`
109
+ // hash, and it runs on the server. At HTTP grain the whole surface collapses
110
+ // onto one POST edge — like a GraphQL operation — so this node recovers the
111
+ // per-action topology the client actually names. It is EXTRACTED-first: the
112
+ // static extractor mints one per exported action from a `"use server"`
113
+ // directive (module-level or in-body) and the file owns it through a
114
+ // `file ──CONTAINS──▶ action` edge; a client reference to the imported action
115
+ // binding lands a `file ──CALLS──▶ action` edge, so the client→action call
116
+ // path is a real edge the reasoning core walks like any other. OBSERVED
117
+ // fusion is deferred (the `Next-Action` hash carries no action name), the
118
+ // same posture GraphQLOperationNode took before its static extractor. See
119
+ // docs/contracts/static-extraction.md and docs/contracts/file-awareness.md.
120
+ ServerActionNode: "ServerActionNode"
106
121
  };
107
122
  var NodeTypeSchema = z.enum([
108
123
  NodeType.ServiceNode,
@@ -115,7 +130,8 @@ var NodeTypeSchema = z.enum([
115
130
  NodeType.GraphQLOperationNode,
116
131
  NodeType.GrpcMethodNode,
117
132
  NodeType.WebSocketChannelNode,
118
- NodeType.SymbolNode
133
+ NodeType.SymbolNode,
134
+ NodeType.ServerActionNode
119
135
  ]);
120
136
 
121
137
  // src/nodes.ts
@@ -286,7 +302,15 @@ var ConfigNodeSchema = z3.object({
286
302
  var ColumnAttrSchema = z3.object({
287
303
  name: z3.string(),
288
304
  provenances: z3.array(ProvenanceSchema),
289
- confidence: z3.number().min(0).max(1)
305
+ confidence: z3.number().min(0).max(1),
306
+ // Which SDK wrote this field, for a `firestore-collection` node (ADR-167): a
307
+ // deduped set, the write-side analog of `provenances`. `client` =
308
+ // firebase/firestore (governed by security rules), `admin` =
309
+ // firebase-admin/firestore (bypasses rules entirely). This is the seam the
310
+ // field-guard policy (ADR-169) joins on — client-written fields must be guarded
311
+ // — and is absent on a non-Firestore column. Optional growth, no version step
312
+ // (`kind` is an open string); folded by `foldSdkWrites`, never `foldColumns`.
313
+ sdkWrites: z3.array(z3.enum(["client", "admin"])).optional()
290
314
  });
291
315
  var InfraNodeSchema = z3.object({
292
316
  id: z3.string(),
@@ -299,7 +323,15 @@ var InfraNodeSchema = z3.object({
299
323
  // Absent on a non-table InfraNode (a project node, a queue, a route). Optional
300
324
  // schema growth (ADR-031); ADR-157 stamps the snapshot version because the field
301
325
  // records a new grain the graph can now carry. See docs/contracts/schema.md.
302
- columns: z3.array(ColumnAttrSchema).optional()
326
+ columns: z3.array(ColumnAttrSchema).optional(),
327
+ // Guard set folded from a checked-in declared policy artifact (ADR-169): for a
328
+ // `firestore-collection` node, the fields `firestore.rules` explicitly names on
329
+ // the client write path, read by the standalone rules producer. The
330
+ // `field-guard` policy asserts every client-written column appears here. Absent
331
+ // ⇒ the collection's guard is indeterminate ⇒ the check stays silent. Optional
332
+ // growth (ADR-031); no version step — it only appears on nodes a post-ADR-169
333
+ // pass folds it onto.
334
+ guardedFields: z3.array(z3.string()).optional()
303
335
  });
304
336
  var FrontierNodeSchema = z3.object({
305
337
  id: z3.string(),
@@ -392,6 +424,17 @@ var SymbolNodeSchema = z3.object({
392
424
  relPath: z3.string(),
393
425
  discoveredVia: DiscoveredViaSchema.optional()
394
426
  });
427
+ var ServerActionNodeSchema = z3.object({
428
+ id: z3.string(),
429
+ type: z3.literal(NodeType.ServerActionNode),
430
+ name: z3.string(),
431
+ service: z3.string(),
432
+ module: z3.string(),
433
+ exportName: z3.string(),
434
+ path: z3.string().optional(),
435
+ line: z3.number().int().nonnegative().optional(),
436
+ discoveredVia: DiscoveredViaSchema.optional()
437
+ });
395
438
  var GraphNodeSchema = z3.discriminatedUnion("type", [
396
439
  ServiceNodeSchema,
397
440
  DatabaseNodeSchema,
@@ -403,7 +446,8 @@ var GraphNodeSchema = z3.discriminatedUnion("type", [
403
446
  GraphQLOperationNodeSchema,
404
447
  GrpcMethodNodeSchema,
405
448
  WebSocketChannelNodeSchema,
406
- SymbolNodeSchema
449
+ SymbolNodeSchema,
450
+ ServerActionNodeSchema
407
451
  ]);
408
452
 
409
453
  // src/events.ts
@@ -556,6 +600,7 @@ var GRAPHQL_OP_PREFIX = "graphql:";
556
600
  var GRPC_METHOD_PREFIX = "grpc:";
557
601
  var WEBSOCKET_CHANNEL_PREFIX = "ws:";
558
602
  var SYMBOL_PREFIX = "symbol:";
603
+ var SERVER_ACTION_PREFIX = "action:";
559
604
  var ENV_UNKNOWN = "unknown";
560
605
  function serviceId(name, env) {
561
606
  if (env === void 0 || env === ENV_UNKNOWN) return `${SERVICE_PREFIX}${name}`;
@@ -703,6 +748,23 @@ function parseSymbolId(id) {
703
748
  if (qualname.length === 0) return null;
704
749
  return { service, relPath, qualname, ...disambiguator !== void 0 ? { disambiguator } : {} };
705
750
  }
751
+ function serverActionId(service, module, exportName) {
752
+ return `${SERVER_ACTION_PREFIX}${service}:${module}#${exportName}`;
753
+ }
754
+ function parseServerActionId(id) {
755
+ if (!id.startsWith(SERVER_ACTION_PREFIX)) return null;
756
+ const rest = id.slice(SERVER_ACTION_PREFIX.length);
757
+ const colon = rest.indexOf(":");
758
+ if (colon === -1) return null;
759
+ const service = rest.slice(0, colon);
760
+ const tail = rest.slice(colon + 1);
761
+ const hash = tail.lastIndexOf("#");
762
+ if (hash === -1) return null;
763
+ const module = tail.slice(0, hash);
764
+ const exportName = tail.slice(hash + 1);
765
+ if (service.length === 0 || module.length === 0 || exportName.length === 0) return null;
766
+ return { service, module, exportName };
767
+ }
706
768
  var EDGE_ARROW = "->";
707
769
  function extractedEdgeId(source, target, type) {
708
770
  return `${type}:${source}${EDGE_ARROW}${target}`;
@@ -789,12 +851,29 @@ var BlastRadiusRuleSchema = z6.object({
789
851
  // default (10) when omitted.
790
852
  depth: z6.number().int().positive().optional()
791
853
  });
854
+ var FieldGuardRuleSchema = z6.object({
855
+ type: z6.literal("field-guard"),
856
+ // Node type the rule governs. InfraNode for the Firestore instance.
857
+ nodeType: NodeTypeSchema,
858
+ // Optional narrowing on InfraNode's free-string `kind` sub-type, so the rule
859
+ // applies to `firestore-collection` nodes without governing every InfraNode.
860
+ nodeKind: z6.string().optional(),
861
+ // Set A — the named selector the evaluator resolves into the "must be covered"
862
+ // set. 'client-written-columns' reads ColumnAttr whose sdkWrites includes
863
+ // 'client'. A new instance adds a value here plus a resolver branch.
864
+ subjectSet: z6.enum(["client-written-columns"]),
865
+ // Set B — the covering set: the node attribute (a string[]) whose members must
866
+ // include all of set A. 'guardedFields' for Firestore. Absent ⇒ indeterminate
867
+ // ⇒ silent.
868
+ guardSet: z6.string()
869
+ });
792
870
  var PolicyRuleSchema = z6.discriminatedUnion("type", [
793
871
  StructuralRuleSchema,
794
872
  CompatibilityRuleSchema,
795
873
  ProvenanceRuleSchema,
796
874
  OwnershipRuleSchema,
797
- BlastRadiusRuleSchema
875
+ BlastRadiusRuleSchema,
876
+ FieldGuardRuleSchema
798
877
  ]);
799
878
  var PolicySchema = z6.object({
800
879
  // Unique within the file. Duplicates fail PolicyFileSchema.parse.
@@ -853,7 +932,7 @@ var ApplicablePolicySchema = z6.object({
853
932
  // from policy.onViolation or the severity default. Shown for awareness only;
854
933
  // the soft guardrail never acts on it.
855
934
  onViolation: PolicyActionSchema,
856
- ruleType: z6.enum(["structural", "compatibility", "provenance", "ownership", "blast-radius"]),
935
+ ruleType: z6.enum(["structural", "compatibility", "provenance", "ownership", "blast-radius", "field-guard"]),
857
936
  match: z6.enum(["subject", "region"]),
858
937
  // Human-readable reason the policy applies here — rides into agent context.
859
938
  reason: z6.string().min(1)
@@ -872,7 +951,7 @@ var PolicyViolationSchema = z6.object({
872
951
  // Resolved at evaluation time — either the explicit policy.onViolation or
873
952
  // the severity-derived default per ADR-044.
874
953
  onViolation: PolicyActionSchema,
875
- ruleType: z6.enum(["structural", "compatibility", "provenance", "ownership", "blast-radius"]),
954
+ ruleType: z6.enum(["structural", "compatibility", "provenance", "ownership", "blast-radius", "field-guard"]),
876
955
  subject: z6.object({
877
956
  nodeId: z6.string().optional(),
878
957
  edgeId: z6.string().optional(),
@@ -1220,6 +1299,7 @@ export {
1220
1299
  EdgeTypeSchema,
1221
1300
  ErrorEventSchema,
1222
1301
  ExtractionCoverageSchema,
1302
+ FieldGuardRuleSchema,
1223
1303
  FileNodeSchema,
1224
1304
  FrontierNodeSchema,
1225
1305
  GraphDiffResultSchema,
@@ -1266,6 +1346,7 @@ export {
1266
1346
  SearchMatchSchema,
1267
1347
  SearchResponseSchema,
1268
1348
  SerializedGraphSchema,
1349
+ ServerActionNodeSchema,
1269
1350
  ServiceNodeSchema,
1270
1351
  SingleProjectResponseSchema,
1271
1352
  SpanAttributesSchema,
@@ -1302,11 +1383,13 @@ export {
1302
1383
  parseGrpcMethodId,
1303
1384
  parseInfraId,
1304
1385
  parseRouteId,
1386
+ parseServerActionId,
1305
1387
  parseServiceId,
1306
1388
  parseSymbolId,
1307
1389
  parseWebsocketChannelId,
1308
1390
  passesExtractedFloor,
1309
1391
  routeId,
1392
+ serverActionId,
1310
1393
  serviceId,
1311
1394
  symbolId,
1312
1395
  websocketChannelId