@operato/ops-contract 0.1.0 → 0.3.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.
@@ -0,0 +1,86 @@
1
+ /** 개체 관측 — 물건 하나가 어디서 무엇이 됐나. */
2
+ export interface CanonicalRecord {
3
+ /**
4
+ * 개체 하나의 식별자. **`quantityList` 를 쓰면 없어도 된다** — 낱개 번호가 없는 자재(밀가루 3.5kg)는
5
+ * 개체가 없다. 둘 다 없으면 무엇을 관측했는지 말하지 않은 것이므로 커널 매핑이 거부한다.
6
+ */
7
+ epc?: string;
8
+ /**
9
+ * 클래스와 수량 — `{ epcClass, quantity, uom? }`. **잔량 절대값을 싣는다**(「얼마 뺐다」가 아니라
10
+ * 「얼마 남았다」). 그래야 사건 하나를 놓쳐도 다음 사건이 정답을 다시 말해 주고 오차가 쌓이지 않는다.
11
+ *
12
+ * 담김(`childQuantityList`)이 하루 먼저 이 자리를 받았다 — 그때와 같은 이유다. 원본이 비직렬 수량을
13
+ * 말할 길이 없어서, 그것이 주된 경로인 시스템(식품 제조 MES)은 라이브를 낼 수 없었다. 커널의
14
+ * 관측 리듀서는 처음부터 이 값을 읽었고 문만 없었다.
15
+ */
16
+ quantityList?: {
17
+ epcClass: string;
18
+ quantity?: number;
19
+ uom?: string;
20
+ }[];
21
+ action: string;
22
+ bizStep: string;
23
+ disposition?: string;
24
+ readPoint?: string;
25
+ bizLocation?: string;
26
+ }
27
+ /**
28
+ * 담김 관측 — **부모와 자식**으로 말한다. 자리 필드는 개체 관측과 같은 이름이다(문자열).
29
+ *
30
+ * 이름은 표준의 것을 그대로 쓴다(`parentID`·`childEPCs`) — 여기서 다시 지으면 매핑이 번역이 되고,
31
+ * 같은 사실에 두 어휘가 생긴다.
32
+ */
33
+ /**
34
+ * 변환 관측 — **무엇으로 무엇이 되었나.** 입력과 출력이 **한 사실에 함께** 있어야 계보가 남는다.
35
+ *
36
+ * 따로 보내면(「이 로트가 없어졌다」와 「이 제품이 생겼다」) 그 둘을 이을 근거가 없다. 그래서 표준이
37
+ * 한 사건에 둘을 담고, 우리 레코드도 같은 모양이다.
38
+ *
39
+ * 이름은 **표준의 것을 그대로** 쓴다(`inputQuantityList` 등). 갈래 판정이 이 이름으로 이루어지므로
40
+ * 커넥터 낱말(`consumed`·`produced`)로 담으면 판정되지 않는다 — 커넥터가 정규 이름으로 담아 보내고
41
+ * 매핑은 그 안에서 값을 고른다.
42
+ *
43
+ * **없는 쪽은 필드를 만들지 않는다.** 빈 배열을 실으면 「없다」고 말하는 것이 된다. 소실(N→0)과
44
+ * 생성(0→N)도 표준이 인정하는 변환이다.
45
+ *
46
+ * `transformationID` 가 한 오더의 여러 단계를 잇는다 — 소비를 먼저 알고 산출을 나중에 알게 되는 원본에서
47
+ * 그 둘을 묶는 유일한 자리다.
48
+ */
49
+ export interface CanonicalTransformationRecord {
50
+ /** 개체로 소비된 것. */
51
+ inputEPCList?: string[];
52
+ /** 클래스와 수량으로 소비된 것 — 로트 단위 소비가 이 자리다. */
53
+ inputQuantityList?: {
54
+ epcClass: string;
55
+ quantity?: number;
56
+ uom?: string;
57
+ }[];
58
+ outputEPCList?: string[];
59
+ outputQuantityList?: {
60
+ epcClass: string;
61
+ quantity?: number;
62
+ uom?: string;
63
+ }[];
64
+ /** 한 오더의 여러 단계를 잇는 식별자. */
65
+ transformationID?: string;
66
+ bizStep: string;
67
+ disposition?: string;
68
+ readPoint?: string;
69
+ bizLocation?: string;
70
+ }
71
+ export interface CanonicalAggregationRecord {
72
+ parentID: string;
73
+ /** 개체로 담긴 자식. 수량으로만 담겼으면 없다(둘 중 하나는 있어야 한다). */
74
+ childEPCs?: string[];
75
+ /** 수량으로 담긴 자식 — `{ epcClass, quantity, uom? }`. 값의 옳고 그름은 커널 검증이 본다. */
76
+ childQuantityList?: {
77
+ epcClass: string;
78
+ quantity?: number;
79
+ uom?: string;
80
+ }[];
81
+ action: string;
82
+ bizStep: string;
83
+ disposition?: string;
84
+ readPoint?: string;
85
+ bizLocation?: string;
86
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -394,7 +394,7 @@ export interface TestResult {
394
394
  * 함께 움직인다. 열린 문자열로 두지 않는 이유는, 처분이 **자원에 효과를 주기** 때문이다 — 커널이 모르는
395
395
  * 결정을 받으면 무엇을 해야 할지 알 수 없고, 그때 조용히 아무것도 하지 않는 것이 가장 나쁘다.
396
396
  */
397
- export declare const DISPOSITION_DECISION: readonly ["rework", "use-as-is", "scrap", "return-to-supplier", "hold"];
397
+ export declare const DISPOSITION_DECISION: readonly ["rework", "repair", "use-as-is", "regrade", "scrap", "return-to-supplier", "hold"];
398
398
  export type DispositionDecision = (typeof DISPOSITION_DECISION)[number];
399
399
  /**
400
400
  * **부적합 처분** — `OP_EVENT.disposition` 의 데이터.
@@ -555,7 +555,7 @@ export interface TestSpecificationCriterion {
555
555
  /** 표준 `EvaluatedPropertyID` — 이 기준이 **무엇을 재어** 판정하나. 측정값과 짝을 맞추는 키다. */
556
556
  evaluatedPropertyId?: string;
557
557
  }
558
- export interface TestSpecification {
558
+ export interface TestSpecification extends EffectivePeriod {
559
559
  /** 표준 `ID` — 자원의 `testSpecificationIds` 가 이 값을 가리킨다. */
560
560
  id: string;
561
561
  /** 표준 `Description`. i18n 키일 수 있다(사람 언어는 표현 계층이 렌더한다). */
@@ -3219,7 +3219,7 @@ export interface TwinModelDef {
3219
3219
  */
3220
3220
  identity?: IdentityDeclaration;
3221
3221
  /** parallelism = 동시 처리 수(LocationState.parallelism 참조). capacity 는 저장 용량. */
3222
- locations: {
3222
+ locations: (EffectivePeriod & {
3223
3223
  id: string;
3224
3224
  type: string;
3225
3225
  capacity: number;
@@ -3227,7 +3227,7 @@ export interface TwinModelDef {
3227
3227
  parentId?: string;
3228
3228
  properties?: ResourceProperty[];
3229
3229
  testSpecificationIds?: TestSpecificationRefs;
3230
- }[];
3230
+ })[];
3231
3231
  /**
3232
3232
  * 설비(설비). mtbfMs/mttrMs 지정 시 확률적 고장 모델 참여(OEE Availability 손실). 미지정=고장 없음.
3233
3233
  * `window` 지정 시 그 시간대에만 일한다(교대·가동시간) — 미지정이면 24시간 가용(기존 거동).
package/dist/contract.js CHANGED
@@ -226,7 +226,32 @@ levelOfType) {
226
226
  * 함께 움직인다. 열린 문자열로 두지 않는 이유는, 처분이 **자원에 효과를 주기** 때문이다 — 커널이 모르는
227
227
  * 결정을 받으면 무엇을 해야 할지 알 수 없고, 그때 조용히 아무것도 하지 않는 것이 가장 나쁘다.
228
228
  */
229
- export const DISPOSITION_DECISION = ['rework', 'use-as-is', 'scrap', 'return-to-supplier', 'hold'];
229
+ export const DISPOSITION_DECISION = [
230
+ /** 원 규격으로 되돌린다 — 공정에 다시 들어가고, 산출물은 원 품목이다. */
231
+ 'rework',
232
+ /**
233
+ * 쓸 수 있게 만들되 **원 규격은 아니다** — 공정에 다시 들어가지만 산출물이 원 품목이 아니다.
234
+ *
235
+ * `rework` 와 나눈 이유는 이름이 아니라 **효과**다. 되돌린 것과 고쳐 쓴 것은 산출물의 정체성이
236
+ * 다르고, 그것을 한 낱말로 묶으면 계보가 「원 품목을 만들었다」고 거짓을 말한다.
237
+ */
238
+ 'repair',
239
+ /** 그대로 쓴다 — 공정도 정체성도 바뀌지 않는다. */
240
+ 'use-as-is',
241
+ /**
242
+ * **등급을 내려 다른 품목으로 판다** — 공정에 다시 들어가지 않고, 그 자리에서 품목 정의가 바뀐다.
243
+ *
244
+ * 다른 넷과 축이 다르다. 폐기도 특채도 아니고 **자재의 품목 자체가 달라진다**(GTIN 이 바뀐다).
245
+ * 식품·철강·섬유에서 일상이다.
246
+ */
247
+ 'regrade',
248
+ /** 재고에서 뺀다. */
249
+ 'scrap',
250
+ /** 공급자에게 돌려보낸다 — 재고에서 빠지되 폐기와 다른 사실이다. */
251
+ 'return-to-supplier',
252
+ /** 아직 정하지 않았다 — 묶어 두고 쓰지 않는다. */
253
+ 'hold'
254
+ ];
230
255
  /**
231
256
  * 이 시험 결과가 **이 시각에 유효한 합격인가.**
232
257
  *
@@ -1,3 +1,4 @@
1
+ import type { EffectivePeriod } from './contract.ts';
1
2
  /** 표준 온톨로지 투영(열린 문자열 — 하드코딩 enum 금지). */
2
3
  /**
3
4
  * 표준 온톨로지 투영 — 이 개념을 각 표준이 무엇이라 부르나.
@@ -129,7 +130,7 @@ export interface DurationVariability {
129
130
  * 걸리나·얼마나 성공하나" 는 커널 소스의 상수(30·20·40초, 수율 0.8)였다. 그래서 현장마다 다른 값을
130
131
  * 데이터로 줄 방법이 없었고, 그 상수가 주목 신호(불량률 높음)까지 만들어 냈다.
131
132
  */
132
- export interface OperationDef {
133
+ export interface OperationDef extends EffectivePeriod {
133
134
  key: string;
134
135
  label: string;
135
136
  intent: OperationIntent;
@@ -3,7 +3,8 @@
3
3
  * 커널이 "무엇이 있고 어떻게 흐르나"(타입 + 공정 route/BOM)를 **데이터로** 받는 형식. zero-dep(자기 타입).
4
4
  *
5
5
  * 특정 공정이 커널 코드에 하드코딩되던 것을 이 데이터 계약으로 대체한다(design/plans/domain-catalog-layering.md).
6
- * 스토어 패키지 `@operato/twin-catalog` 가 이 타입을 import 스토어 메타(version/supplier)를 얹어 배포한다(catalog → kernel 의존).
6
+ * 스토어 패키지 `@operato/twin-catalog` 가 이 타입을 import type { EffectivePeriod } from './contract.ts'
7
+ import 해 스토어 메타(version/supplier)를 얹어 배포한다(catalog → kernel 의존).
7
8
  * 표준 앵커: GS1 EPCIS 2.0(bizStep) · ISA-95(WorkCenter·OperationsDefinition·BOM) · ISO 55000(Asset).
8
9
  */
9
10
  /**
package/dist/index.d.ts CHANGED
@@ -16,3 +16,5 @@ export * from './scenario-validate.ts';
16
16
  export * from './vocabulary.ts';
17
17
  export * from './wms-profile.ts';
18
18
  export * from './yms-profile.ts';
19
+ export * from './canonical-record.ts';
20
+ export * from './version.ts';
package/dist/index.js CHANGED
@@ -37,3 +37,5 @@ export * from "./scenario-validate.js";
37
37
  export * from "./vocabulary.js";
38
38
  export * from "./wms-profile.js";
39
39
  export * from "./yms-profile.js";
40
+ export * from "./canonical-record.js";
41
+ export * from "./version.js";
@@ -1,6 +1,6 @@
1
1
  import type { IngestResult } from './face2-adapter.ts';
2
2
  /** 이 문이 받는 여섯 가지 — 리듀서가 다루는 것과 같은 목록(주목 확인은 우리 안의 행위라 제외). */
3
- export type OperationalKind = 'task' | 'equipment' | 'person' | 'asset' | 'order' | 'quality' | 'test' | 'observation' | 'complete';
3
+ export type OperationalKind = 'task' | 'equipment' | 'person' | 'asset' | 'order' | 'quality' | 'test' | 'disposition' | 'observation' | 'complete';
4
4
  /**
5
5
  * 정규 운영 레코드 — **델타의 필드 이름 + 시각(`at`)**.
6
6
  *
@@ -34,7 +34,7 @@
34
34
  * 모르는 필드는 **조용히 버리지 않고 거부한다.** `taskID` 처럼 한 글자 틀린 이름은 통과시키면 영원히
35
35
  * 보이지 않는 손실이 된다(이 문에는 아직 옛 발신자가 없어 호환 부담도 없다).
36
36
  */
37
- import { OP_EVENT } from "./contract.js";
37
+ import { OP_EVENT, DISPOSITION_DECISION } from "./contract.js";
38
38
  /**
39
39
  * 닫아 둔 낱말과 그 이유.
40
40
  * · 작업 상태 — 성과 폴드가 `completed`·`in-progress` 로 갈린다(`kpi-fold`).
@@ -130,6 +130,32 @@ const SPECS = {
130
130
  * `propertyMeasurements` 안쪽은 재검사하지 않는다 — 그 모양은 `PropertyMeasurement` 계약이고,
131
131
  * 여기서 두 번 지키면 두 벌이 된다(설비 `motion` 과 같은 규율).
132
132
  */
133
+ /*
134
+ * **부적합 처분** — 재고 판정을 받은 것을 어떻게 하기로 정했나.
135
+ *
136
+ * ── 이 통이 늦게 생긴 이유 (2026-08-30) ──────────────────────────────────
137
+ * 사건 이름(`OP_EVENT.disposition`)과 모양(`DispositionFact`)을 먼저 만들고 **여기로 오는 길을
138
+ * 내지 않았다.** 그래서 처분 사실을 보내면 어느 통도 아니어서 떨어진 목록에도 남지 않고 사라졌다.
139
+ * MES 전문가가 소스를 읽다 찾았다.
140
+ *
141
+ * 이 파일의 위 주석이 말한 부류 그대로다 — `OP_EVENT.test` 와 `OP_EVENT.observation` 이 같은 일을
142
+ * 겪었고 이번이 셋째다. **계약에 자리를 만드는 것과 그 자리로 가는 길을 내는 것은 다른 일이다.**
143
+ *
144
+ * ── 판정과 다른 사실이다 ─────────────────────────────────────────────────
145
+ * 근거가 된 판정(`specId`)을 가리킬 수 있지만 **필수가 아니다** — 판정 없이 현장 재량으로 빼는 일이
146
+ * 정상이다. 그래서 정체성은 처분 대상(`subjectId`)이다.
147
+ */
148
+ disposition: {
149
+ eventType: OP_EVENT.disposition,
150
+ identity: 'subjectId',
151
+ /* 무엇을 어떻게 하기로 했나 — 둘 중 하나가 없으면 그 결정은 아무 데도 붙지 못한다. */
152
+ required: ['subjectId', 'decision'],
153
+ fields: {
154
+ subjectId: 'string', decision: 'string', quantity: 'number', uom: 'string',
155
+ specId: 'string', decidedBy: 'string', reason: 'string', decidedAt: 'string', recordTime: 'string'
156
+ },
157
+ enums: { decision: DISPOSITION_DECISION }
158
+ },
133
159
  test: {
134
160
  eventType: OP_EVENT.test,
135
161
  identity: 'testableObjectId',
@@ -221,6 +247,15 @@ export function operationalKindOf(record) {
221
247
  */
222
248
  if (has('testableObjectId'))
223
249
  return 'test';
250
+ /*
251
+ * **처분** — 같은 부류가 또 났다(2026-08-30). `OP_EVENT.disposition` 을 계약에 내고 여기로 오는 길을
252
+ * 내지 않아, MES 가 보내면 어느 통도 아니어서 사라졌다. 위 주석이 적은 것이 **셋째**다.
253
+ *
254
+ * 시험 결과 뒤에 둔다 — 처분은 판정을 가리킬 수 있고(`specId`), 그때 정체성은 처분 대상이지
255
+ * 시험 대상이 아니다. 앞에 두면 판정에 딸린 처분이 시험으로 읽힌다.
256
+ */
257
+ if (has('subjectId') && has('decision'))
258
+ return 'disposition';
224
259
  /*
225
260
  * ── ★ **채널을 열고 또 길을 내지 않았다** (2026-08-24) ──────────────────────
226
261
  * `OP_EVENT.observation`(`location.measured`)을 내고 상태(`LocationState.observations`)와 조회
@@ -0,0 +1 @@
1
+ export declare const CONTRACT_VERSION = "0.3.0";
@@ -0,0 +1,14 @@
1
+ /*
2
+ * 이 계약의 **판**.
3
+ *
4
+ * ── 왜 내보내나 (2026-08-30) ─────────────────────────────────────────────
5
+ * 소비처가 「내가 어느 판의 계약을 지키고 있나」를 사실로 남겨야 한다. MES 의 아웃박스가 그 값을
6
+ * 레코드에 싣는데, 계약이 내보내지 않아 **상수로 손으로 적고 있었다.** `exports` 맵이 `package.json`
7
+ * 을 막아 런타임에 읽을 수도 없다.
8
+ *
9
+ * 손으로 적은 판은 계약이 올라갈 때 같이 올라가지 않는다. 그러면 그 값은 「지킨다고 말한 판」이지
10
+ * 「실제로 지킨 판」이 아니게 되고, 그것이 어긋난 날 아무도 모른다.
11
+ *
12
+ * **정본은 `package.json` 이다.** 이 값이 그것과 같은지는 시험이 지킨다(§`version-matches`).
13
+ */
14
+ export const CONTRACT_VERSION = '0.3.0';
@@ -27,6 +27,7 @@ __export(index_exports, {
27
27
  CAPABILITY_KEYS: () => CAPABILITY_KEYS,
28
28
  CBV_BIZSTEP: () => CBV_BIZSTEP,
29
29
  CMD: () => CMD,
30
+ CONTRACT_VERSION: () => CONTRACT_VERSION,
30
31
  DISP: () => DISP,
31
32
  DISPOSITION_DECISION: () => DISPOSITION_DECISION,
32
33
  DOMAIN_CATALOG: () => DOMAIN_CATALOG,
@@ -408,7 +409,32 @@ function hierarchyOf(s, levelOfType) {
408
409
  }
409
410
  };
410
411
  }
411
- var DISPOSITION_DECISION = ["rework", "use-as-is", "scrap", "return-to-supplier", "hold"];
412
+ var DISPOSITION_DECISION = [
413
+ /** 원 규격으로 되돌린다 — 공정에 다시 들어가고, 산출물은 원 품목이다. */
414
+ "rework",
415
+ /**
416
+ * 쓸 수 있게 만들되 **원 규격은 아니다** — 공정에 다시 들어가지만 산출물이 원 품목이 아니다.
417
+ *
418
+ * `rework` 와 나눈 이유는 이름이 아니라 **효과**다. 되돌린 것과 고쳐 쓴 것은 산출물의 정체성이
419
+ * 다르고, 그것을 한 낱말로 묶으면 계보가 「원 품목을 만들었다」고 거짓을 말한다.
420
+ */
421
+ "repair",
422
+ /** 그대로 쓴다 — 공정도 정체성도 바뀌지 않는다. */
423
+ "use-as-is",
424
+ /**
425
+ * **등급을 내려 다른 품목으로 판다** — 공정에 다시 들어가지 않고, 그 자리에서 품목 정의가 바뀐다.
426
+ *
427
+ * 다른 넷과 축이 다르다. 폐기도 특채도 아니고 **자재의 품목 자체가 달라진다**(GTIN 이 바뀐다).
428
+ * 식품·철강·섬유에서 일상이다.
429
+ */
430
+ "regrade",
431
+ /** 재고에서 뺀다. */
432
+ "scrap",
433
+ /** 공급자에게 돌려보낸다 — 재고에서 빠지되 폐기와 다른 사실이다. */
434
+ "return-to-supplier",
435
+ /** 아직 정하지 않았다 — 묶어 두고 쓰지 않는다. */
436
+ "hold"
437
+ ];
412
438
  function testPassedAt(r, at) {
413
439
  if (r.result !== "pass") return false;
414
440
  if (!r.expiresAt || !at) return r.result === "pass";
@@ -3270,6 +3296,39 @@ var SPECS = {
3270
3296
  * `propertyMeasurements` 안쪽은 재검사하지 않는다 — 그 모양은 `PropertyMeasurement` 계약이고,
3271
3297
  * 여기서 두 번 지키면 두 벌이 된다(설비 `motion` 과 같은 규율).
3272
3298
  */
3299
+ /*
3300
+ * **부적합 처분** — 재고 판정을 받은 것을 어떻게 하기로 정했나.
3301
+ *
3302
+ * ── 이 통이 늦게 생긴 이유 (2026-08-30) ──────────────────────────────────
3303
+ * 사건 이름(`OP_EVENT.disposition`)과 모양(`DispositionFact`)을 먼저 만들고 **여기로 오는 길을
3304
+ * 내지 않았다.** 그래서 처분 사실을 보내면 어느 통도 아니어서 떨어진 목록에도 남지 않고 사라졌다.
3305
+ * MES 전문가가 소스를 읽다 찾았다.
3306
+ *
3307
+ * 이 파일의 위 주석이 말한 부류 그대로다 — `OP_EVENT.test` 와 `OP_EVENT.observation` 이 같은 일을
3308
+ * 겪었고 이번이 셋째다. **계약에 자리를 만드는 것과 그 자리로 가는 길을 내는 것은 다른 일이다.**
3309
+ *
3310
+ * ── 판정과 다른 사실이다 ─────────────────────────────────────────────────
3311
+ * 근거가 된 판정(`specId`)을 가리킬 수 있지만 **필수가 아니다** — 판정 없이 현장 재량으로 빼는 일이
3312
+ * 정상이다. 그래서 정체성은 처분 대상(`subjectId`)이다.
3313
+ */
3314
+ disposition: {
3315
+ eventType: OP_EVENT.disposition,
3316
+ identity: "subjectId",
3317
+ /* 무엇을 어떻게 하기로 했나 — 둘 중 하나가 없으면 그 결정은 아무 데도 붙지 못한다. */
3318
+ required: ["subjectId", "decision"],
3319
+ fields: {
3320
+ subjectId: "string",
3321
+ decision: "string",
3322
+ quantity: "number",
3323
+ uom: "string",
3324
+ specId: "string",
3325
+ decidedBy: "string",
3326
+ reason: "string",
3327
+ decidedAt: "string",
3328
+ recordTime: "string"
3329
+ },
3330
+ enums: { decision: DISPOSITION_DECISION }
3331
+ },
3273
3332
  test: {
3274
3333
  eventType: OP_EVENT.test,
3275
3334
  identity: "testableObjectId",
@@ -3339,6 +3398,7 @@ function operationalKindOf(record) {
3339
3398
  if (has("taskId")) return "task";
3340
3399
  if (has("orderId")) return "order";
3341
3400
  if (has("testableObjectId")) return "test";
3401
+ if (has("subjectId") && has("decision")) return "disposition";
3342
3402
  if (has("locationId") && has("propertyId")) return "observation";
3343
3403
  if (has("completeAxis")) return "complete";
3344
3404
  return void 0;
@@ -3609,6 +3669,9 @@ function retiredVocabularyIn(line) {
3609
3669
  }
3610
3670
  return hits;
3611
3671
  }
3672
+
3673
+ // src/version.ts
3674
+ var CONTRACT_VERSION = "0.3.0";
3612
3675
  // Annotate the CommonJS export names for ESM import in node:
3613
3676
  0 && (module.exports = {
3614
3677
  BIZSTEP,
@@ -3619,6 +3682,7 @@ function retiredVocabularyIn(line) {
3619
3682
  CAPABILITY_KEYS,
3620
3683
  CBV_BIZSTEP,
3621
3684
  CMD,
3685
+ CONTRACT_VERSION,
3622
3686
  DISP,
3623
3687
  DISPOSITION_DECISION,
3624
3688
  DOMAIN_CATALOG,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@operato/ops-contract",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Operations domain contract — the standard vocabulary that producers and readers agree on (EPCIS 2.0/GS1, ISA-95, IEC 61850/ISO 50001). Types, guards, validation. No state, no engine.",
5
5
  "type": "module",
6
6
  "main": "./dist-cjs/index.cjs",