npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@operato/ops-contract

v0.9.41

Published

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.

Readme

@operato/ops-contract

운영 도메인의 계약 — 사실을 만드는 쪽과 읽는 쪽이 합의해야 하는 것.

EPCIS 2.0 · GS1          물품의 이동과 계보
ISA-95                   자재 · 설비 · 사람 · 공정
IEC 61850 · ISO 50001    전기 계통과 성과지표

무엇이 여기 있고 무엇이 없나

여기 있는 것은 타입 · 판별 함수 · 정합 검증 · 어휘 상수입니다. 인자만 보고 답합니다.

여기 없는 것은 정책과 엔진입니다. 그 사실로 무엇을 할지는 @operato/twin-kernel 이 정합니다.

제품 간 AI 분석 입력 — OperationalAttentionV1

OperationalAttentionV1은 Plant·WMS·YMS·EMS가 자신이 관측한 운영 주의 사실을 Twin 또는 AI 분석기에 보낼 때 쓰는 공통 봉투입니다. 국제 표준의 알람 포맷을 새로 만드는 것이 아닙니다. EPCIS/ISA-95 등의 원본 사실을 어떤 제품이, 어떤 근거로, 무엇을 분석 대상으로 열었거나 닫았는지 안전하게 전달하는 Operato의 제품 간 계약입니다.

import {
  OPERATIONAL_ATTENTION_CONTRACT,
  assertOperationalAttentionV1,
  type OperationalAttentionV1
} from '@operato/ops-contract'

const attention: OperationalAttentionV1 = {
  contract: OPERATIONAL_ATTENTION_CONTRACT,
  domainId: 'factory-a',
  attentionId: 'schedule-overdue:line-a:101',
  dedupeKey: 'schedule-overdue:line-a:101',
  kind: 'plant.schedule-overdue',
  subjectLabel: 'Line A schedule 101',
  transition: 'opened',
  impact: 'high',
  observedAt: '2026-09-12T01:00:00.000Z',
  evidenceFingerprint: 'sha256:...',
  facts: [{ system: 'operato-plant', type: 'schedule-entry', id: '101' }]
}

assertOperationalAttentionV1(attention)

공통으로 고정한 것

  • 식별·재전송: attentionId, dedupeKey
  • 분석 수명주기: opened, changed, resolved, reopened
  • 분석 우선순위: medium, high
  • 근거: 최소 하나 이상의 안정된 { system, type, id } 원본 사실 참조와 evidenceFingerprint

사람이 읽는 제목만 있고 원본 사실 ID가 없는 입력은 거부합니다. AI가 그럴듯한 설명을 만들더라도 근거를 다시 열어 볼 수 없으면 운영 분석의 입력이 될 수 없기 때문입니다.

제품별로 남기는 것

kind와 facts[].type은 생산자가 소유합니다. 예를 들어 Plant는 plant.schedule-overdue, WMS는 wms.short-pick을 쓰며 서로의 업무 모델을 흉내 내지 않습니다. 또한 acknowledged, suppressed, 승인, 실제 조치 결과는 생산 제품의 업무 흐름에 남습니다. 이 계약은 분석에 필요한 사실 변화만 전달하며, 수신자가 현장을 조치할 권한을 주지 않습니다.

새 제품이 붙을 때는 공통 봉투를 넓히기 전에 그 제품의 adapter에서 자기 kind·사실 유형·판정 기준을 검증합니다. 모든 제품이 실제로 공유하는 필드만 이 계약에 추가합니다.

기존 webhook을 통한 전송

새 URL은 만들지 않는다. attention도 기존 POST /domain/{domain}/twin/hook/{source}/{instanceId}로 보내며, 봉투의 lane: 'ATTENTIONS'가 Twin의 AI inbox 경로를 고른다. scope는 계속 원천의 순번 흐름 이름이며 lane과 합치지 않는다. lane을 생략한 기존 커넥터는 FACTS로 읽혀 기존 canonical ingest 경로를 그대로 쓴다. 따라서 주소·서명·재시도·순번 규약은 하나이고, 사실과 attention의 저장·처리만 Twin 내부에서 갈린다.

Webhook 봉투에서의 구분

lane은 전달 목적, scope는 생산자의 순번 스트림 이름이다. 같은 값으로 쓰거나 scope를 ATTENTIONS로 바꾸지 않는다.

const batch = {
  lane: 'ATTENTIONS',       // 없으면 FACTS: 기존 커넥터와 호환
  scope: 'mes-line-a',      // 이 생산자가 관리하는 순번 스트림
  items: [{
    eventId: 'outbox-1002',
    seq: 1002,
    record: attention
  }]
}

| lane | Twin 내부 목적지 | 정본 저널 반영 | | --- | --- | --- | | FACTS 또는 생략 | 기존 canonical ingest | 예. EPCIS/운영 사실로 유입한다. | | ATTENTIONS | 제품이 등록한 AI attention inbox | 아니오. 분석을 요청하는 근거 묶음으로 분리한다. |

두 lane 모두 같은 webhook 인증·서명·순번·재시도 응답 계약을 쓴다. 수신자는 OperationalAttentionV1의 도메인 일치와 원본 사실 참조를 검증하고, 같은 domain/source/instance/attention/evidenceFingerprint는 중복으로 처리한다. 이 계약은 attention을 현장 명령으로 바꾸지 않는다.

왜 나뉘어 있나

사실을 만드는 쪽(MES · 커넥터)은 계약만 필요하고 엔진은 필요 없습니다. 한 패키지에 두면 레코드 하나를 만들려고 시뮬레이션 엔진과 네 도메인 커널을 의존 그래프에 올리게 됩니다.

타입만이면 import type 으로 피할 수 있지만, 판별 함수는 런타임 함수입니다(isEnergyRecord 계열). 보내는 쪽이 보내기 전에 스스로 검증하려면 실제로 필요합니다.