@gate-forge/core 0.1.0
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/LICENSE +202 -0
- package/dist/baselines/adoption.d.ts +76 -0
- package/dist/baselines/adoption.d.ts.map +1 -0
- package/dist/baselines/adoption.js +163 -0
- package/dist/baselines/adoption.js.map +1 -0
- package/dist/baselines/index.d.ts +102 -0
- package/dist/baselines/index.d.ts.map +1 -0
- package/dist/baselines/index.js +186 -0
- package/dist/baselines/index.js.map +1 -0
- package/dist/canonical-json.d.ts +51 -0
- package/dist/canonical-json.d.ts.map +1 -0
- package/dist/canonical-json.js +112 -0
- package/dist/canonical-json.js.map +1 -0
- package/dist/classifier/bind.d.ts +64 -0
- package/dist/classifier/bind.d.ts.map +1 -0
- package/dist/classifier/bind.js +188 -0
- package/dist/classifier/bind.js.map +1 -0
- package/dist/classifier/classify.d.ts +154 -0
- package/dist/classifier/classify.d.ts.map +1 -0
- package/dist/classifier/classify.js +1207 -0
- package/dist/classifier/classify.js.map +1 -0
- package/dist/classifier/glob.d.ts +48 -0
- package/dist/classifier/glob.d.ts.map +1 -0
- package/dist/classifier/glob.js +104 -0
- package/dist/classifier/glob.js.map +1 -0
- package/dist/classifier/index.d.ts +10 -0
- package/dist/classifier/index.d.ts.map +1 -0
- package/dist/classifier/index.js +21 -0
- package/dist/classifier/index.js.map +1 -0
- package/dist/classifier/schema.d.ts +150 -0
- package/dist/classifier/schema.d.ts.map +1 -0
- package/dist/classifier/schema.js +139 -0
- package/dist/classifier/schema.js.map +1 -0
- package/dist/config/index.d.ts +259 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +523 -0
- package/dist/config/index.js.map +1 -0
- package/dist/fingerprints.d.ts +56 -0
- package/dist/fingerprints.d.ts.map +1 -0
- package/dist/fingerprints.js +59 -0
- package/dist/fingerprints.js.map +1 -0
- package/dist/graph/build.d.ts +16 -0
- package/dist/graph/build.d.ts.map +1 -0
- package/dist/graph/build.js +423 -0
- package/dist/graph/build.js.map +1 -0
- package/dist/graph/index.d.ts +12 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +10 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/schema.d.ts +448 -0
- package/dist/graph/schema.d.ts.map +1 -0
- package/dist/graph/schema.js +237 -0
- package/dist/graph/schema.js.map +1 -0
- package/dist/graph/symbols.d.ts +129 -0
- package/dist/graph/symbols.d.ts.map +1 -0
- package/dist/graph/symbols.js +177 -0
- package/dist/graph/symbols.js.map +1 -0
- package/dist/graph/util.d.ts +40 -0
- package/dist/graph/util.d.ts.map +1 -0
- package/dist/graph/util.js +41 -0
- package/dist/graph/util.js.map +1 -0
- package/dist/index.d.ts +683 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +563 -0
- package/dist/index.js.map +1 -0
- package/dist/mapping/resolve.d.ts +177 -0
- package/dist/mapping/resolve.d.ts.map +1 -0
- package/dist/mapping/resolve.js +523 -0
- package/dist/mapping/resolve.js.map +1 -0
- package/dist/policy/coverage.d.ts +79 -0
- package/dist/policy/coverage.d.ts.map +1 -0
- package/dist/policy/coverage.js +119 -0
- package/dist/policy/coverage.js.map +1 -0
- package/dist/policy/evaluate.d.ts +275 -0
- package/dist/policy/evaluate.d.ts.map +1 -0
- package/dist/policy/evaluate.js +382 -0
- package/dist/policy/evaluate.js.map +1 -0
- package/dist/policy/index.d.ts +15 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +14 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/trusted.d.ts +59 -0
- package/dist/policy/trusted.d.ts.map +1 -0
- package/dist/policy/trusted.js +96 -0
- package/dist/policy/trusted.js.map +1 -0
- package/dist/provenance.d.ts +170 -0
- package/dist/provenance.d.ts.map +1 -0
- package/dist/provenance.js +306 -0
- package/dist/provenance.js.map +1 -0
- package/dist/receipt/index.d.ts +74 -0
- package/dist/receipt/index.d.ts.map +1 -0
- package/dist/receipt/index.js +154 -0
- package/dist/receipt/index.js.map +1 -0
- package/dist/report/index.d.ts +100 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +355 -0
- package/dist/report/index.js.map +1 -0
- package/dist/schemas/adoption.d.ts +40 -0
- package/dist/schemas/adoption.d.ts.map +1 -0
- package/dist/schemas/adoption.js +87 -0
- package/dist/schemas/adoption.js.map +1 -0
- package/dist/schemas/baseline.d.ts +19 -0
- package/dist/schemas/baseline.d.ts.map +1 -0
- package/dist/schemas/baseline.js +45 -0
- package/dist/schemas/baseline.js.map +1 -0
- package/dist/schemas/claim.d.ts +32 -0
- package/dist/schemas/claim.d.ts.map +1 -0
- package/dist/schemas/claim.js +34 -0
- package/dist/schemas/claim.js.map +1 -0
- package/dist/schemas/classification-policy.d.ts +84 -0
- package/dist/schemas/classification-policy.d.ts.map +1 -0
- package/dist/schemas/classification-policy.js +130 -0
- package/dist/schemas/classification-policy.js.map +1 -0
- package/dist/schemas/classification-signal.d.ts +125 -0
- package/dist/schemas/classification-signal.d.ts.map +1 -0
- package/dist/schemas/classification-signal.js +126 -0
- package/dist/schemas/classification-signal.js.map +1 -0
- package/dist/schemas/classification.d.ts +120 -0
- package/dist/schemas/classification.d.ts.map +1 -0
- package/dist/schemas/classification.js +154 -0
- package/dist/schemas/classification.js.map +1 -0
- package/dist/schemas/common.d.ts +73 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +60 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/coverage-policy.d.ts +89 -0
- package/dist/schemas/coverage-policy.d.ts.map +1 -0
- package/dist/schemas/coverage-policy.js +81 -0
- package/dist/schemas/coverage-policy.js.map +1 -0
- package/dist/schemas/evidence.d.ts +65 -0
- package/dist/schemas/evidence.d.ts.map +1 -0
- package/dist/schemas/evidence.js +64 -0
- package/dist/schemas/evidence.js.map +1 -0
- package/dist/schemas/execution-result.d.ts +214 -0
- package/dist/schemas/execution-result.d.ts.map +1 -0
- package/dist/schemas/execution-result.js +240 -0
- package/dist/schemas/execution-result.js.map +1 -0
- package/dist/schemas/gate-receipt.d.ts +86 -0
- package/dist/schemas/gate-receipt.d.ts.map +1 -0
- package/dist/schemas/gate-receipt.js +193 -0
- package/dist/schemas/gate-receipt.js.map +1 -0
- package/dist/schemas/index.d.ts +22 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +22 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/obligation.d.ts +37 -0
- package/dist/schemas/obligation.d.ts.map +1 -0
- package/dist/schemas/obligation.js +46 -0
- package/dist/schemas/obligation.js.map +1 -0
- package/dist/schemas/plugin.d.ts +19 -0
- package/dist/schemas/plugin.d.ts.map +1 -0
- package/dist/schemas/plugin.js +20 -0
- package/dist/schemas/plugin.js.map +1 -0
- package/dist/schemas/policy.d.ts +73 -0
- package/dist/schemas/policy.d.ts.map +1 -0
- package/dist/schemas/policy.js +46 -0
- package/dist/schemas/policy.js.map +1 -0
- package/dist/schemas/resource.d.ts +26 -0
- package/dist/schemas/resource.d.ts.map +1 -0
- package/dist/schemas/resource.js +29 -0
- package/dist/schemas/resource.js.map +1 -0
- package/dist/schemas/run-manifest.d.ts +72 -0
- package/dist/schemas/run-manifest.d.ts.map +1 -0
- package/dist/schemas/run-manifest.js +125 -0
- package/dist/schemas/run-manifest.js.map +1 -0
- package/dist/schemas/runner-adapter.d.ts +169 -0
- package/dist/schemas/runner-adapter.d.ts.map +1 -0
- package/dist/schemas/runner-adapter.js +2 -0
- package/dist/schemas/runner-adapter.js.map +1 -0
- package/dist/schemas/test-catalog.d.ts +472 -0
- package/dist/schemas/test-catalog.d.ts.map +1 -0
- package/dist/schemas/test-catalog.js +311 -0
- package/dist/schemas/test-catalog.js.map +1 -0
- package/dist/schemas/test-map.d.ts +99 -0
- package/dist/schemas/test-map.d.ts.map +1 -0
- package/dist/schemas/test-map.js +103 -0
- package/dist/schemas/test-map.js.map +1 -0
- package/dist/schemas/verdict.d.ts +73 -0
- package/dist/schemas/verdict.d.ts.map +1 -0
- package/dist/schemas/verdict.js +92 -0
- package/dist/schemas/verdict.js.map +1 -0
- package/dist/schemas/waiver.d.ts +36 -0
- package/dist/schemas/waiver.d.ts.map +1 -0
- package/dist/schemas/waiver.js +42 -0
- package/dist/schemas/waiver.js.map +1 -0
- package/dist/supervision/index.d.ts +170 -0
- package/dist/supervision/index.d.ts.map +1 -0
- package/dist/supervision/index.js +354 -0
- package/dist/supervision/index.js.map +1 -0
- package/dist/testing/clock.d.ts +50 -0
- package/dist/testing/clock.d.ts.map +1 -0
- package/dist/testing/clock.js +75 -0
- package/dist/testing/clock.js.map +1 -0
- package/dist/testing/env.d.ts +66 -0
- package/dist/testing/env.d.ts.map +1 -0
- package/dist/testing/env.js +106 -0
- package/dist/testing/env.js.map +1 -0
- package/dist/testing/gate-runner.d.ts +141 -0
- package/dist/testing/gate-runner.d.ts.map +1 -0
- package/dist/testing/gate-runner.js +173 -0
- package/dist/testing/gate-runner.js.map +1 -0
- package/dist/testing/gf19.d.ts +106 -0
- package/dist/testing/gf19.d.ts.map +1 -0
- package/dist/testing/gf19.js +282 -0
- package/dist/testing/gf19.js.map +1 -0
- package/dist/testing/index.d.ts +20 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +14 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/red-probe.d.ts +138 -0
- package/dist/testing/red-probe.d.ts.map +1 -0
- package/dist/testing/red-probe.js +251 -0
- package/dist/testing/red-probe.js.map +1 -0
- package/dist/testing/temp-repo.d.ts +126 -0
- package/dist/testing/temp-repo.d.ts.map +1 -0
- package/dist/testing/temp-repo.js +214 -0
- package/dist/testing/temp-repo.js.map +1 -0
- package/dist/verdict/cause.d.ts +99 -0
- package/dist/verdict/cause.d.ts.map +1 -0
- package/dist/verdict/cause.js +206 -0
- package/dist/verdict/cause.js.map +1 -0
- package/dist/verdict/evaluate.d.ts +135 -0
- package/dist/verdict/evaluate.d.ts.map +1 -0
- package/dist/verdict/evaluate.js +1513 -0
- package/dist/verdict/evaluate.js.map +1 -0
- package/dist/verdict/index.d.ts +21 -0
- package/dist/verdict/index.d.ts.map +1 -0
- package/dist/verdict/index.js +20 -0
- package/dist/verdict/index.js.map +1 -0
- package/dist/verdict/pack-verifiers.d.ts +97 -0
- package/dist/verdict/pack-verifiers.d.ts.map +1 -0
- package/dist/verdict/pack-verifiers.js +763 -0
- package/dist/verdict/pack-verifiers.js.map +1 -0
- package/dist/verdict/registry.d.ts +180 -0
- package/dist/verdict/registry.d.ts.map +1 -0
- package/dist/verdict/registry.js +67 -0
- package/dist/verdict/registry.js.map +1 -0
- package/dist/waivers/index.d.ts +103 -0
- package/dist/waivers/index.d.ts.map +1 -0
- package/dist/waivers/index.js +192 -0
- package/dist/waivers/index.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classification-signal schemas (ADR 0003 D1): the framework-neutral
|
|
3
|
+
* evidence contract detectors emit so core can classify resources
|
|
4
|
+
* automatically. A signal is a FACT — source-located, detector-versioned,
|
|
5
|
+
* basis-typed — never a classification and never authoritative. Core's
|
|
6
|
+
* deterministic rule lattice (ADR 0003 D2) turns signals into decisions.
|
|
7
|
+
*
|
|
8
|
+
* Anti-pattern guards encoded here:
|
|
9
|
+
* - no confidence score field (a signal has a `basis`, not a probability);
|
|
10
|
+
* - every signal must carry a `Location` and a detector identity;
|
|
11
|
+
* - `code-negative-closed-world` names the only basis allowed to
|
|
12
|
+
* suppress, and the classifier additionally demands a complete-scan
|
|
13
|
+
* attestation before honoring it.
|
|
14
|
+
*/
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
import { sha256Canonical } from '../canonical-json.js';
|
|
17
|
+
import { LocationSchema, PlaneSchema, SchemaVersionField } from './common.js';
|
|
18
|
+
/** What a signal addresses: bare name, plane-qualified id, or symbol. */
|
|
19
|
+
export const SignalTargetSchema = z
|
|
20
|
+
.object({
|
|
21
|
+
/** Bare resource name, e.g. `accounts`. */
|
|
22
|
+
resourceName: z.string().min(1).optional(),
|
|
23
|
+
/** Plane-qualified resource id, e.g. `tenant.accounts`. */
|
|
24
|
+
resourceId: z.string().min(1).optional(),
|
|
25
|
+
/** Class/function symbol, e.g. `app.models.Account` (matches a resource's `classQname` attribute). */
|
|
26
|
+
symbol: z.string().min(1).optional(),
|
|
27
|
+
})
|
|
28
|
+
.strict();
|
|
29
|
+
/** Every classification dimension a signal can speak about. */
|
|
30
|
+
export const SIGNAL_DIMENSIONS = [
|
|
31
|
+
'exposure',
|
|
32
|
+
'plane',
|
|
33
|
+
'identity',
|
|
34
|
+
'lifecycle.create',
|
|
35
|
+
'lifecycle.read',
|
|
36
|
+
'lifecycle.update',
|
|
37
|
+
'lifecycle.delete',
|
|
38
|
+
'delete-semantics',
|
|
39
|
+
'archive-state',
|
|
40
|
+
'adapter-binding',
|
|
41
|
+
'internality',
|
|
42
|
+
];
|
|
43
|
+
export const SignalDimensionSchema = z.enum(SIGNAL_DIMENSIONS);
|
|
44
|
+
/**
|
|
45
|
+
* The evidence basis of a signal (ADR 0003 D1). Only
|
|
46
|
+
* `code-negative-closed-world` may ever suppress obligations, and only
|
|
47
|
+
* when the classifier's complete-scan attestation holds.
|
|
48
|
+
*/
|
|
49
|
+
export const SignalBasisSchema = z.enum([
|
|
50
|
+
'code-positive',
|
|
51
|
+
'code-negative-closed-world',
|
|
52
|
+
'declaration',
|
|
53
|
+
'organization-policy',
|
|
54
|
+
]);
|
|
55
|
+
/**
|
|
56
|
+
* Dimension-typed assertion payload: `exposure`/`internality` carry a
|
|
57
|
+
* boolean or category string, `plane` a plane name, `identity` the
|
|
58
|
+
* ORDERED primary-key columns, `delete-semantics` `hard|archive`,
|
|
59
|
+
* `archive-state` the owner-owned archived field values, lifecycle
|
|
60
|
+
* dimensions a boolean.
|
|
61
|
+
*/
|
|
62
|
+
export const SignalAssertionSchema = z.union([
|
|
63
|
+
z.string().min(1),
|
|
64
|
+
z.boolean(),
|
|
65
|
+
z.array(z.string().min(1)).min(1),
|
|
66
|
+
z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])),
|
|
67
|
+
]);
|
|
68
|
+
/**
|
|
69
|
+
* One classification signal (ADR 0003 D1). Strict: unknown fields are
|
|
70
|
+
* detector bugs and must fail validation, not ride along.
|
|
71
|
+
*/
|
|
72
|
+
export const ClassificationSignalSchema = z
|
|
73
|
+
.object({
|
|
74
|
+
schemaVersion: SchemaVersionField,
|
|
75
|
+
/** What resource(s) this signal speaks about. */
|
|
76
|
+
target: SignalTargetSchema,
|
|
77
|
+
/** The classification dimension being evidenced. */
|
|
78
|
+
dimension: SignalDimensionSchema,
|
|
79
|
+
/** Dimension-typed assertion payload. */
|
|
80
|
+
assertion: SignalAssertionSchema,
|
|
81
|
+
/** Evidence basis — never a confidence score. */
|
|
82
|
+
basis: SignalBasisSchema,
|
|
83
|
+
/**
|
|
84
|
+
* Issuing source. For SUPPRESSIVE decisions (internality, closed-world
|
|
85
|
+
* lifecycle disable) only configured declaration sources or explicit
|
|
86
|
+
* `gateforge.declaration:<key>` references to configured keys are
|
|
87
|
+
* authoritative — a `gateforge.policy:` prefix alone proves nothing;
|
|
88
|
+
* policy-issued signals enter through engine-controlled minting.
|
|
89
|
+
*/
|
|
90
|
+
source: z.string().min(1),
|
|
91
|
+
/** Where the evidence lives in source. */
|
|
92
|
+
location: LocationSchema,
|
|
93
|
+
/**
|
|
94
|
+
* Detector that emitted the signal. The engine issuer
|
|
95
|
+
* (`gateforge.core@1`) is reserved: plugin-emitted signals whose
|
|
96
|
+
* detector identity is not the pinned plugin are rejected at the
|
|
97
|
+
* boundary, and `gateforge.core` cannot be configured as a plugin id.
|
|
98
|
+
*/
|
|
99
|
+
detector: z.strictObject({ id: z.string().min(1), version: z.string().min(1) }),
|
|
100
|
+
})
|
|
101
|
+
.strict();
|
|
102
|
+
/**
|
|
103
|
+
* Canonical signal identity (ADR 0003 D1): sha256 over the GF-canonical
|
|
104
|
+
* JSON of the full signal document. Any change of location, assertion,
|
|
105
|
+
* basis, or detector version changes the id — which is what makes
|
|
106
|
+
* `decisionFingerprint`s stale-aware (plan goal 8).
|
|
107
|
+
*
|
|
108
|
+
* Args:
|
|
109
|
+
* signal: a validated classification signal.
|
|
110
|
+
*
|
|
111
|
+
* Returns:
|
|
112
|
+
* string: 64-char lowercase sha256 hex.
|
|
113
|
+
*/
|
|
114
|
+
export function signalId(signal) {
|
|
115
|
+
return sha256Canonical(signal);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The plane-assertion payload narrowed, for signals that assert a plane.
|
|
119
|
+
*/
|
|
120
|
+
export function planeAssertion(signal) {
|
|
121
|
+
if (signal.dimension !== 'plane')
|
|
122
|
+
return null;
|
|
123
|
+
const parsed = PlaneSchema.safeParse(signal.assertion);
|
|
124
|
+
return parsed.success ? parsed.data : null;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=classification-signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classification-signal.js","sourceRoot":"","sources":["../../src/schemas/classification-signal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classification schemas (plan §4.3): business meaning attached to
|
|
3
|
+
* discovered resources that cannot be safely inferred — exposure, plane,
|
|
4
|
+
* lifecycle, identity columns, and the trusted evidence adapter.
|
|
5
|
+
*
|
|
6
|
+
* ADR 0001 encoded here:
|
|
7
|
+
* - composite identity = column-keyed `entityId` + mandatory ordered
|
|
8
|
+
* `primaryKey` attribute;
|
|
9
|
+
* - internal resources default to NO CRUD obligations and their claims
|
|
10
|
+
* are invalid (enforced downstream by the verdict engine, not here);
|
|
11
|
+
* - a user-facing resource cannot be proven without a trusted evidence
|
|
12
|
+
* adapter, so `evidenceAdapter` is mandatory for user-facing entries —
|
|
13
|
+
* on the BUSINESS-resource lane. `http.endpoint` resources are witnessed
|
|
14
|
+
* through the claims/witness-proxy lane (`http:frontend-request-observed`
|
|
15
|
+
* etc.), not through entity persistence adapters (whose contract — read
|
|
16
|
+
* by id, normalize body, deletion kind — is about business entities), so
|
|
17
|
+
* a user-facing classification may instead declare
|
|
18
|
+
* `evidenceLane: 'claims'` and omit the adapter.
|
|
19
|
+
*/
|
|
20
|
+
import { z } from 'zod';
|
|
21
|
+
/**
|
|
22
|
+
* Lifecycle surface of a resource. `create`/`read`/`update` are plain
|
|
23
|
+
* switches; `delete` additionally declares its semantics because archive
|
|
24
|
+
* and hard delete have different evidence contracts (plan §5.3).
|
|
25
|
+
*
|
|
26
|
+
* `archiveFields` is the OWNER-DECLARED archived state (audit round 5):
|
|
27
|
+
* the expected post-archive field values come from the classification —
|
|
28
|
+
* never from the tested suite — so a suite cannot bless an unarchived
|
|
29
|
+
* entity by declaring its current state as the expected result.
|
|
30
|
+
*/
|
|
31
|
+
export declare const LifecycleSchema: z.ZodObject<{
|
|
32
|
+
create: z.ZodBoolean;
|
|
33
|
+
read: z.ZodBoolean;
|
|
34
|
+
update: z.ZodBoolean;
|
|
35
|
+
delete: z.ZodBoolean;
|
|
36
|
+
deleteSemantics: z.ZodOptional<z.ZodEnum<{
|
|
37
|
+
hard: "hard";
|
|
38
|
+
archive: "archive";
|
|
39
|
+
}>>;
|
|
40
|
+
archiveFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
41
|
+
updateableFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
42
|
+
}, z.core.$strict>;
|
|
43
|
+
/** Inferred lifecycle shape. */
|
|
44
|
+
export type Lifecycle = z.infer<typeof LifecycleSchema>;
|
|
45
|
+
/**
|
|
46
|
+
* Classification entry for a single resource id.
|
|
47
|
+
*/
|
|
48
|
+
export declare const ClassificationSchema: z.ZodObject<{
|
|
49
|
+
exposure: z.ZodEnum<{
|
|
50
|
+
"user-facing": "user-facing";
|
|
51
|
+
internal: "internal";
|
|
52
|
+
}>;
|
|
53
|
+
plane: z.ZodEnum<{
|
|
54
|
+
tenant: "tenant";
|
|
55
|
+
master: "master";
|
|
56
|
+
global: "global";
|
|
57
|
+
}>;
|
|
58
|
+
lifecycle: z.ZodObject<{
|
|
59
|
+
create: z.ZodBoolean;
|
|
60
|
+
read: z.ZodBoolean;
|
|
61
|
+
update: z.ZodBoolean;
|
|
62
|
+
delete: z.ZodBoolean;
|
|
63
|
+
deleteSemantics: z.ZodOptional<z.ZodEnum<{
|
|
64
|
+
hard: "hard";
|
|
65
|
+
archive: "archive";
|
|
66
|
+
}>>;
|
|
67
|
+
archiveFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
68
|
+
updateableFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
69
|
+
}, z.core.$strict>;
|
|
70
|
+
primaryKey: z.ZodArray<z.ZodString>;
|
|
71
|
+
evidenceAdapter: z.ZodOptional<z.ZodString>;
|
|
72
|
+
evidenceLane: z.ZodOptional<z.ZodEnum<{
|
|
73
|
+
adapter: "adapter";
|
|
74
|
+
claims: "claims";
|
|
75
|
+
}>>;
|
|
76
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
77
|
+
}, z.core.$strict>;
|
|
78
|
+
/** Inferred per-resource classification shape. */
|
|
79
|
+
export type Classification = z.infer<typeof ClassificationSchema>;
|
|
80
|
+
/**
|
|
81
|
+
* The classifications document: `.gateforge` classification YAML mapping
|
|
82
|
+
* resource ids to their classification. Resources discovered but absent
|
|
83
|
+
* here are `unclassified` and fail closed downstream.
|
|
84
|
+
*/
|
|
85
|
+
export declare const ClassificationFileSchema: z.ZodObject<{
|
|
86
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
87
|
+
resources: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
88
|
+
exposure: z.ZodEnum<{
|
|
89
|
+
"user-facing": "user-facing";
|
|
90
|
+
internal: "internal";
|
|
91
|
+
}>;
|
|
92
|
+
plane: z.ZodEnum<{
|
|
93
|
+
tenant: "tenant";
|
|
94
|
+
master: "master";
|
|
95
|
+
global: "global";
|
|
96
|
+
}>;
|
|
97
|
+
lifecycle: z.ZodObject<{
|
|
98
|
+
create: z.ZodBoolean;
|
|
99
|
+
read: z.ZodBoolean;
|
|
100
|
+
update: z.ZodBoolean;
|
|
101
|
+
delete: z.ZodBoolean;
|
|
102
|
+
deleteSemantics: z.ZodOptional<z.ZodEnum<{
|
|
103
|
+
hard: "hard";
|
|
104
|
+
archive: "archive";
|
|
105
|
+
}>>;
|
|
106
|
+
archiveFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
107
|
+
updateableFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
108
|
+
}, z.core.$strict>;
|
|
109
|
+
primaryKey: z.ZodArray<z.ZodString>;
|
|
110
|
+
evidenceAdapter: z.ZodOptional<z.ZodString>;
|
|
111
|
+
evidenceLane: z.ZodOptional<z.ZodEnum<{
|
|
112
|
+
adapter: "adapter";
|
|
113
|
+
claims: "claims";
|
|
114
|
+
}>>;
|
|
115
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
116
|
+
}, z.core.$strict>>;
|
|
117
|
+
}, z.core.$strict>;
|
|
118
|
+
/** Inferred classifications-document shape. */
|
|
119
|
+
export type ClassificationFile = z.infer<typeof ClassificationFileSchema>;
|
|
120
|
+
//# sourceMappingURL=classification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classification.d.ts","sourceRoot":"","sources":["../../src/schemas/classification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;kBAgExB,CAAC;AAEL,gCAAgC;AAChC,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiD7B,CAAC;AAEL,kDAAkD;AAClD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAM1B,CAAC;AAEZ,+CAA+C;AAC/C,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classification schemas (plan §4.3): business meaning attached to
|
|
3
|
+
* discovered resources that cannot be safely inferred — exposure, plane,
|
|
4
|
+
* lifecycle, identity columns, and the trusted evidence adapter.
|
|
5
|
+
*
|
|
6
|
+
* ADR 0001 encoded here:
|
|
7
|
+
* - composite identity = column-keyed `entityId` + mandatory ordered
|
|
8
|
+
* `primaryKey` attribute;
|
|
9
|
+
* - internal resources default to NO CRUD obligations and their claims
|
|
10
|
+
* are invalid (enforced downstream by the verdict engine, not here);
|
|
11
|
+
* - a user-facing resource cannot be proven without a trusted evidence
|
|
12
|
+
* adapter, so `evidenceAdapter` is mandatory for user-facing entries —
|
|
13
|
+
* on the BUSINESS-resource lane. `http.endpoint` resources are witnessed
|
|
14
|
+
* through the claims/witness-proxy lane (`http:frontend-request-observed`
|
|
15
|
+
* etc.), not through entity persistence adapters (whose contract — read
|
|
16
|
+
* by id, normalize body, deletion kind — is about business entities), so
|
|
17
|
+
* a user-facing classification may instead declare
|
|
18
|
+
* `evidenceLane: 'claims'` and omit the adapter.
|
|
19
|
+
*/
|
|
20
|
+
import { z } from 'zod';
|
|
21
|
+
import { ExposureSchema, PlaneSchema, SchemaVersionField } from './common.js';
|
|
22
|
+
/**
|
|
23
|
+
* Lifecycle surface of a resource. `create`/`read`/`update` are plain
|
|
24
|
+
* switches; `delete` additionally declares its semantics because archive
|
|
25
|
+
* and hard delete have different evidence contracts (plan §5.3).
|
|
26
|
+
*
|
|
27
|
+
* `archiveFields` is the OWNER-DECLARED archived state (audit round 5):
|
|
28
|
+
* the expected post-archive field values come from the classification —
|
|
29
|
+
* never from the tested suite — so a suite cannot bless an unarchived
|
|
30
|
+
* entity by declaring its current state as the expected result.
|
|
31
|
+
*/
|
|
32
|
+
export const LifecycleSchema = z
|
|
33
|
+
.object({
|
|
34
|
+
/** New entities can be created through the UI. */
|
|
35
|
+
create: z.boolean(),
|
|
36
|
+
/** Entities can be read/viewed through the UI. */
|
|
37
|
+
read: z.boolean(),
|
|
38
|
+
/** Declared entity fields can be changed through the UI. */
|
|
39
|
+
update: z.boolean(),
|
|
40
|
+
/** Entities can be removed (hard) or archived (soft) through the UI. */
|
|
41
|
+
delete: z.boolean(),
|
|
42
|
+
/** Required when `delete` is true: how removal manifests. */
|
|
43
|
+
deleteSemantics: z.enum(['hard', 'archive']).optional(),
|
|
44
|
+
/**
|
|
45
|
+
* Required when `deleteSemantics` is 'archive': the owner-declared
|
|
46
|
+
* field values that identify the archived state (e.g. `{status:
|
|
47
|
+
* 'archived'}`). Graded by the engine against the witness's own
|
|
48
|
+
* engine-side observation.
|
|
49
|
+
*/
|
|
50
|
+
archiveFields: z
|
|
51
|
+
.record(z.string(), z.union([z.string(), z.number(), z.boolean()]))
|
|
52
|
+
.optional(),
|
|
53
|
+
/**
|
|
54
|
+
* Owner-declared fields whose change constitutes a real update
|
|
55
|
+
* (audit round 6). `persistence:update` is satisfied only when the
|
|
56
|
+
* engine-observed before/after delta touches at least one of these —
|
|
57
|
+
* bookkeeping columns (e.g. `updated_at`) alone never satisfy.
|
|
58
|
+
* Optional in the schema; the engine fails closed on update
|
|
59
|
+
* obligations for resources that omit it.
|
|
60
|
+
*/
|
|
61
|
+
updateableFields: z.array(z.string().min(1)).min(1).optional(),
|
|
62
|
+
})
|
|
63
|
+
.strict()
|
|
64
|
+
.superRefine((lifecycle, ctx) => {
|
|
65
|
+
if (lifecycle.delete && lifecycle.deleteSemantics === undefined) {
|
|
66
|
+
ctx.addIssue({
|
|
67
|
+
code: 'custom',
|
|
68
|
+
path: ['deleteSemantics'],
|
|
69
|
+
message: "lifecycle.delete is true: 'deleteSemantics' must be 'hard' or 'archive'",
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (lifecycle.deleteSemantics === 'archive' && lifecycle.archiveFields === undefined) {
|
|
73
|
+
ctx.addIssue({
|
|
74
|
+
code: 'custom',
|
|
75
|
+
path: ['archiveFields'],
|
|
76
|
+
message: "lifecycle.deleteSemantics is 'archive': 'archiveFields' must declare the " +
|
|
77
|
+
'owner-owned archived state (e.g. {status: archived})',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// An empty archiveFields map passes no postcondition check, so it is
|
|
81
|
+
// a config error, not a dormant one (fail closed at authoring time).
|
|
82
|
+
if (lifecycle.archiveFields !== undefined &&
|
|
83
|
+
Object.keys(lifecycle.archiveFields).length === 0) {
|
|
84
|
+
ctx.addIssue({
|
|
85
|
+
code: 'custom',
|
|
86
|
+
path: ['archiveFields'],
|
|
87
|
+
message: 'archiveFields must declare at least one field (an empty map can never ' +
|
|
88
|
+
'satisfy the archive postcondition)',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
/**
|
|
93
|
+
* Classification entry for a single resource id.
|
|
94
|
+
*/
|
|
95
|
+
export const ClassificationSchema = z
|
|
96
|
+
.object({
|
|
97
|
+
/** Whether the resource is exposed to end users. */
|
|
98
|
+
exposure: ExposureSchema,
|
|
99
|
+
/** Deployment plane the resource lives on. */
|
|
100
|
+
plane: PlaneSchema,
|
|
101
|
+
/** Lifecycle operations the UI supports for this resource. */
|
|
102
|
+
lifecycle: LifecycleSchema,
|
|
103
|
+
/**
|
|
104
|
+
* Mandatory ordered entity-identity columns (ADR 0001): a single
|
|
105
|
+
* column for simple identity, ordered lowest-index-first for
|
|
106
|
+
* composite identity.
|
|
107
|
+
*/
|
|
108
|
+
primaryKey: z.array(z.string().min(1)).min(1),
|
|
109
|
+
/**
|
|
110
|
+
* Trusted evidence adapter name (resolved against
|
|
111
|
+
* `.gateforge/adapters/<name>.mjs`). Required for user-facing
|
|
112
|
+
* BUSINESS resources; internal resources are never CRUD-obligated,
|
|
113
|
+
* so the adapter is optional there.
|
|
114
|
+
*/
|
|
115
|
+
evidenceAdapter: z.string().min(1).optional(),
|
|
116
|
+
/**
|
|
117
|
+
* Which evidence lane proves user-facing reachability. Omitted means
|
|
118
|
+
* the default `'adapter'` lane: a reviewed EntityAdapter must collect
|
|
119
|
+
* the evidence (the business-resource requirement — never weakened).
|
|
120
|
+
* `'claims'` is the http.endpoint lane: routes are witnessed through
|
|
121
|
+
* the claims/witness-proxy lane (`http:frontend-request-observed`),
|
|
122
|
+
* not through entity persistence adapters, so the adapter is not
|
|
123
|
+
* demanded. The classifier mints `'claims'` ONLY for `http.endpoint`
|
|
124
|
+
* resources; business resources must keep the adapter demand.
|
|
125
|
+
*/
|
|
126
|
+
evidenceLane: z.enum(['adapter', 'claims']).optional(),
|
|
127
|
+
/** Free-form classification note shown in reports. */
|
|
128
|
+
notes: z.string().optional(),
|
|
129
|
+
})
|
|
130
|
+
.strict()
|
|
131
|
+
.superRefine((entry, ctx) => {
|
|
132
|
+
if (entry.exposure === 'user-facing' &&
|
|
133
|
+
entry.evidenceAdapter === undefined &&
|
|
134
|
+
entry.evidenceLane !== 'claims') {
|
|
135
|
+
ctx.addIssue({
|
|
136
|
+
code: 'custom',
|
|
137
|
+
path: ['evidenceAdapter'],
|
|
138
|
+
message: "user-facing resources require an 'evidenceAdapter' (claims are not proof; trusted adapters collect evidence)",
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
/**
|
|
143
|
+
* The classifications document: `.gateforge` classification YAML mapping
|
|
144
|
+
* resource ids to their classification. Resources discovered but absent
|
|
145
|
+
* here are `unclassified` and fail closed downstream.
|
|
146
|
+
*/
|
|
147
|
+
export const ClassificationFileSchema = z
|
|
148
|
+
.object({
|
|
149
|
+
schemaVersion: SchemaVersionField,
|
|
150
|
+
/** Classification per resource id. */
|
|
151
|
+
resources: z.record(z.string().min(1), ClassificationSchema),
|
|
152
|
+
})
|
|
153
|
+
.strict();
|
|
154
|
+
//# sourceMappingURL=classification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classification.js","sourceRoot":"","sources":["../../src/schemas/classification.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared schema building blocks for every gateforge artifact.
|
|
3
|
+
*
|
|
4
|
+
* ADR 0001: every artifact carries `schemaVersion`. Unknown versions are
|
|
5
|
+
* rejected outright — gateforge never migrates old payloads (fail closed).
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
/**
|
|
9
|
+
* The only schemaVersion gateforge accepts on any artifact, config, or
|
|
10
|
+
* wire payload. Bumping this is a breaking, opt-in event per artifact —
|
|
11
|
+
* there is no automatic migration path, by design.
|
|
12
|
+
*/
|
|
13
|
+
export declare const GATEFORGE_SCHEMA_VERSION = 1;
|
|
14
|
+
/**
|
|
15
|
+
* schemaVersion field with the "unknown versions rejected" behavior:
|
|
16
|
+
* anything but `1` produces an explicit unsupported-version diagnostic
|
|
17
|
+
* rather than a silent type error.
|
|
18
|
+
*/
|
|
19
|
+
export declare const SchemaVersionField: z.ZodLiteral<1>;
|
|
20
|
+
/** Where in a source file an artifact was found (discovery-spike shape). */
|
|
21
|
+
export declare const LocationSchema: z.ZodObject<{
|
|
22
|
+
file: z.ZodString;
|
|
23
|
+
line: z.ZodNumber;
|
|
24
|
+
col: z.ZodNumber;
|
|
25
|
+
}, z.core.$strict>;
|
|
26
|
+
/** Inferred source location shape. */
|
|
27
|
+
export type Location = z.infer<typeof LocationSchema>;
|
|
28
|
+
/** Whether a resource is exposed to end users or purely internal. */
|
|
29
|
+
export declare const ExposureSchema: z.ZodEnum<{
|
|
30
|
+
"user-facing": "user-facing";
|
|
31
|
+
internal: "internal";
|
|
32
|
+
}>;
|
|
33
|
+
/** Inferred exposure shape. */
|
|
34
|
+
export type Exposure = z.infer<typeof ExposureSchema>;
|
|
35
|
+
/**
|
|
36
|
+
* Deployment plane of a resource (tenant-scoped, master/shared, or global).
|
|
37
|
+
*/
|
|
38
|
+
export declare const PlaneSchema: z.ZodEnum<{
|
|
39
|
+
tenant: "tenant";
|
|
40
|
+
master: "master";
|
|
41
|
+
global: "global";
|
|
42
|
+
}>;
|
|
43
|
+
/** Inferred plane shape. */
|
|
44
|
+
export type Plane = z.infer<typeof PlaneSchema>;
|
|
45
|
+
/**
|
|
46
|
+
* Transport a plugin speaks over the plugin boundary (ADR 0002):
|
|
47
|
+
* `subprocess` = GPP/3 JSON-lines child process, `in-process` = TS
|
|
48
|
+
* detector loaded into the engine.
|
|
49
|
+
*/
|
|
50
|
+
export declare const TransportSchema: z.ZodEnum<{
|
|
51
|
+
subprocess: "subprocess";
|
|
52
|
+
"in-process": "in-process";
|
|
53
|
+
}>;
|
|
54
|
+
/** Inferred transport shape. */
|
|
55
|
+
export type Transport = z.infer<typeof TransportSchema>;
|
|
56
|
+
/** Trust tier of an evidence record (ADR 0001: only witnessed can satisfy). */
|
|
57
|
+
export declare const TrustTierSchema: z.ZodEnum<{
|
|
58
|
+
claimed: "claimed";
|
|
59
|
+
witnessed: "witnessed";
|
|
60
|
+
}>;
|
|
61
|
+
/** Inferred trust-tier shape. */
|
|
62
|
+
export type TrustTier = z.infer<typeof TrustTierSchema>;
|
|
63
|
+
/**
|
|
64
|
+
* Contract-name grammar. Contracts carry their own namespace segment
|
|
65
|
+
* (`crud:update`, `crud:delete`), so interior colons are legal; the
|
|
66
|
+
* obligation id `<resourceId>:<contract>` splits at the FIRST colon,
|
|
67
|
+
* hence a contract must not START with one. Trailing colons are
|
|
68
|
+
* rejected as malformed.
|
|
69
|
+
*/
|
|
70
|
+
export declare const ContractNameSchema: z.ZodString;
|
|
71
|
+
/** Inferred contract-name shape. */
|
|
72
|
+
export type ContractName = z.infer<typeof ContractNameSchema>;
|
|
73
|
+
//# sourceMappingURL=common.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/schemas/common.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,iBAK7B,CAAC;AAEH,4EAA4E;AAC5E,eAAO,MAAM,cAAc;;;;kBAShB,CAAC;AAEZ,sCAAsC;AACtC,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,qEAAqE;AACrE,eAAO,MAAM,cAAc;;;EAAsC,CAAC;AAElE,+BAA+B;AAC/B,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,WAAW;;;;EAAyC,CAAC;AAElE,4BAA4B;AAC5B,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;EAAuC,CAAC;AAEpE,gCAAgC;AAChC,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,+EAA+E;AAC/E,eAAO,MAAM,eAAe;;;EAAmC,CAAC;AAEhE,iCAAiC;AACjC,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,aAM5B,CAAC;AAEJ,oCAAoC;AACpC,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared schema building blocks for every gateforge artifact.
|
|
3
|
+
*
|
|
4
|
+
* ADR 0001: every artifact carries `schemaVersion`. Unknown versions are
|
|
5
|
+
* rejected outright — gateforge never migrates old payloads (fail closed).
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
/**
|
|
9
|
+
* The only schemaVersion gateforge accepts on any artifact, config, or
|
|
10
|
+
* wire payload. Bumping this is a breaking, opt-in event per artifact —
|
|
11
|
+
* there is no automatic migration path, by design.
|
|
12
|
+
*/
|
|
13
|
+
export const GATEFORGE_SCHEMA_VERSION = 1;
|
|
14
|
+
/**
|
|
15
|
+
* schemaVersion field with the "unknown versions rejected" behavior:
|
|
16
|
+
* anything but `1` produces an explicit unsupported-version diagnostic
|
|
17
|
+
* rather than a silent type error.
|
|
18
|
+
*/
|
|
19
|
+
export const SchemaVersionField = z.literal(GATEFORGE_SCHEMA_VERSION, {
|
|
20
|
+
error: (issue) => issue.input === undefined
|
|
21
|
+
? `schemaVersion is required and must be ${GATEFORGE_SCHEMA_VERSION}`
|
|
22
|
+
: `unsupported schemaVersion: got ${String(issue.input)}, expected ${GATEFORGE_SCHEMA_VERSION} (gateforge never migrates old versions)`,
|
|
23
|
+
});
|
|
24
|
+
/** Where in a source file an artifact was found (discovery-spike shape). */
|
|
25
|
+
export const LocationSchema = z
|
|
26
|
+
.object({
|
|
27
|
+
/** Repo-root-relative path of the source file. */
|
|
28
|
+
file: z.string().min(1),
|
|
29
|
+
/** 1-based line number. */
|
|
30
|
+
line: z.number().int().min(1),
|
|
31
|
+
/** 0-based column offset. */
|
|
32
|
+
col: z.number().int().min(0),
|
|
33
|
+
})
|
|
34
|
+
.strict();
|
|
35
|
+
/** Whether a resource is exposed to end users or purely internal. */
|
|
36
|
+
export const ExposureSchema = z.enum(['user-facing', 'internal']);
|
|
37
|
+
/**
|
|
38
|
+
* Deployment plane of a resource (tenant-scoped, master/shared, or global).
|
|
39
|
+
*/
|
|
40
|
+
export const PlaneSchema = z.enum(['tenant', 'master', 'global']);
|
|
41
|
+
/**
|
|
42
|
+
* Transport a plugin speaks over the plugin boundary (ADR 0002):
|
|
43
|
+
* `subprocess` = GPP/3 JSON-lines child process, `in-process` = TS
|
|
44
|
+
* detector loaded into the engine.
|
|
45
|
+
*/
|
|
46
|
+
export const TransportSchema = z.enum(['subprocess', 'in-process']);
|
|
47
|
+
/** Trust tier of an evidence record (ADR 0001: only witnessed can satisfy). */
|
|
48
|
+
export const TrustTierSchema = z.enum(['claimed', 'witnessed']);
|
|
49
|
+
/**
|
|
50
|
+
* Contract-name grammar. Contracts carry their own namespace segment
|
|
51
|
+
* (`crud:update`, `crud:delete`), so interior colons are legal; the
|
|
52
|
+
* obligation id `<resourceId>:<contract>` splits at the FIRST colon,
|
|
53
|
+
* hence a contract must not START with one. Trailing colons are
|
|
54
|
+
* rejected as malformed.
|
|
55
|
+
*/
|
|
56
|
+
export const ContractNameSchema = z
|
|
57
|
+
.string()
|
|
58
|
+
.min(1)
|
|
59
|
+
.regex(/^[^:].*[^:]|^[^:]$/, "contract must not start or end with ':' (obligation ids split at the first colon)");
|
|
60
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/schemas/common.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAE1C;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,OAAO,CAAC,wBAAwB,EAAE;IACpE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,KAAK,CAAC,KAAK,KAAK,SAAS;QACvB,CAAC,CAAC,yCAAyC,wBAAwB,EAAE;QACrE,CAAC,CAAC,kCAAkC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,wBAAwB,0CAA0C;CAC5I,CAAC,CAAC;AAEH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC5B,MAAM,CAAC;IACN,kDAAkD;IAClD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,2BAA2B;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,6BAA6B;IAC7B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC7B,CAAC;KACD,MAAM,EAAE,CAAC;AAKZ,qEAAqE;AACrE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC;AAKlE;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAKlE;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;AAKpE,+EAA+E;AAC/E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;AAKhE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,KAAK,CACJ,oBAAoB,EACpB,mFAAmF,CACpF,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage-policy schemas (plan 2026-09-13 §3.6, Phase 0 item 7, ADR
|
|
3
|
+
* 0005 D5): a tracked, OWNER-OWNED configuration section enumerating
|
|
4
|
+
* user-facing tables, their required real-UI CRUD operations, and any
|
|
5
|
+
* owner disposition excusing a table from that coverage. Recording or
|
|
6
|
+
* approving a disposition is a trusted-policy act — an agent edit never
|
|
7
|
+
* self-approves, because the section participates in the trusted policy
|
|
8
|
+
* revision identity.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
/** The four real-UI operations a table may require coverage for. */
|
|
12
|
+
export declare const COVERAGE_OPERATIONS: readonly ["create", "read", "update", "delete"];
|
|
13
|
+
/** The operation union a coverage policy may require. */
|
|
14
|
+
export declare const CoverageOperationSchema: z.ZodEnum<{
|
|
15
|
+
create: "create";
|
|
16
|
+
read: "read";
|
|
17
|
+
update: "update";
|
|
18
|
+
delete: "delete";
|
|
19
|
+
}>;
|
|
20
|
+
/** Inferred coverage-operation type. */
|
|
21
|
+
export type CoverageOperation = (typeof COVERAGE_OPERATIONS)[number];
|
|
22
|
+
/**
|
|
23
|
+
* An OWNER disposition (plan §3.6): the recorded reason a table owes no
|
|
24
|
+
* real-UI coverage for its required operations. Kinds are closed-world;
|
|
25
|
+
* `other` requires the note to stay auditable. Approving one is a
|
|
26
|
+
* trusted-policy act, never an agent self-approval.
|
|
27
|
+
*/
|
|
28
|
+
export declare const CoverageDispositionSchema: z.ZodObject<{
|
|
29
|
+
kind: z.ZodEnum<{
|
|
30
|
+
"read-only-surface": "read-only-surface";
|
|
31
|
+
"admin-plane-unreachable": "admin-plane-unreachable";
|
|
32
|
+
"not-user-facing": "not-user-facing";
|
|
33
|
+
other: "other";
|
|
34
|
+
}>;
|
|
35
|
+
note: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}, z.core.$strict>;
|
|
37
|
+
/** Inferred coverage-disposition type. */
|
|
38
|
+
export type CoverageDisposition = z.infer<typeof CoverageDispositionSchema>;
|
|
39
|
+
/** One policy-enumerated user-facing table. */
|
|
40
|
+
export declare const CoverageTableSchema: z.ZodObject<{
|
|
41
|
+
name: z.ZodString;
|
|
42
|
+
requiredOperations: z.ZodArray<z.ZodEnum<{
|
|
43
|
+
create: "create";
|
|
44
|
+
read: "read";
|
|
45
|
+
update: "update";
|
|
46
|
+
delete: "delete";
|
|
47
|
+
}>>;
|
|
48
|
+
disposition: z.ZodOptional<z.ZodObject<{
|
|
49
|
+
kind: z.ZodEnum<{
|
|
50
|
+
"read-only-surface": "read-only-surface";
|
|
51
|
+
"admin-plane-unreachable": "admin-plane-unreachable";
|
|
52
|
+
"not-user-facing": "not-user-facing";
|
|
53
|
+
other: "other";
|
|
54
|
+
}>;
|
|
55
|
+
note: z.ZodOptional<z.ZodString>;
|
|
56
|
+
}, z.core.$strict>>;
|
|
57
|
+
}, z.core.$strict>;
|
|
58
|
+
/** Inferred coverage-table type. */
|
|
59
|
+
export type CoverageTable = z.infer<typeof CoverageTableSchema>;
|
|
60
|
+
/**
|
|
61
|
+
* The `coveragePolicy` config section (plan §3.6). Absent or empty
|
|
62
|
+
* (`tables: []`) means the feature is OFF — enabling it is an explicit,
|
|
63
|
+
* tracked owner decision. Table names must be unique (a duplicate would
|
|
64
|
+
* make the enforcement scope ambiguous); each name is validated against
|
|
65
|
+
* the current run's resource inventory on every run.
|
|
66
|
+
*/
|
|
67
|
+
export declare const CoveragePolicySchema: z.ZodObject<{
|
|
68
|
+
tables: z.ZodArray<z.ZodObject<{
|
|
69
|
+
name: z.ZodString;
|
|
70
|
+
requiredOperations: z.ZodArray<z.ZodEnum<{
|
|
71
|
+
create: "create";
|
|
72
|
+
read: "read";
|
|
73
|
+
update: "update";
|
|
74
|
+
delete: "delete";
|
|
75
|
+
}>>;
|
|
76
|
+
disposition: z.ZodOptional<z.ZodObject<{
|
|
77
|
+
kind: z.ZodEnum<{
|
|
78
|
+
"read-only-surface": "read-only-surface";
|
|
79
|
+
"admin-plane-unreachable": "admin-plane-unreachable";
|
|
80
|
+
"not-user-facing": "not-user-facing";
|
|
81
|
+
other: "other";
|
|
82
|
+
}>;
|
|
83
|
+
note: z.ZodOptional<z.ZodString>;
|
|
84
|
+
}, z.core.$strict>>;
|
|
85
|
+
}, z.core.$strict>>;
|
|
86
|
+
}, z.core.$strict>;
|
|
87
|
+
/** Inferred coverage-policy section type. */
|
|
88
|
+
export type CoveragePolicy = z.infer<typeof CoveragePolicySchema>;
|
|
89
|
+
//# sourceMappingURL=coverage-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-policy.d.ts","sourceRoot":"","sources":["../../src/schemas/coverage-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,oEAAoE;AACpE,eAAO,MAAM,mBAAmB,iDAAkD,CAAC;AAEnF,yDAAyD;AACzD,eAAO,MAAM,uBAAuB;;;;;EAA8B,CAAC;AAEnE,wCAAwC;AACxC,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAErE;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;kBAelC,CAAC;AAEL,0CAA0C;AAC1C,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,+CAA+C;AAC/C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;kBAarB,CAAC;AAEZ,oCAAoC;AACpC,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;kBAoB7B,CAAC;AAEL,6CAA6C;AAC7C,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|