rule

package
v0.1.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 13, 2026 License: MIT Imports: 2 Imported by: 0

README

pkg/rule

fullend validate/crosscheck 공통 toulmin 룰 함수.

모든 함수는 func(claim, ground, backing any) (bool, any) 시그니처를 따른다. backing이 판정 기준을 담고, 같은 함수를 backing만 바꿔 재사용한다.

공통 타입

Ground

모든 룰 함수가 공유하는 검증 컨텍스트. 호출자가 그래프 평가 전에 구성한다.

type Ground struct {
    Lookup  map[string]StringSet // "target.kind" -> set of names
    Types   map[string]string    // "target.kind.name" -> type string
    Pairs   map[string]StringSet // "target.pairKind" -> set of "key:value"
    Config  map[string]bool      // config key -> present
    Vars    StringSet            // declared variable names
    Flags   StringSet            // flags for defeaters
    Schemas map[string][]string  // "target.schema" -> ordered field list
}

LookupKey 컨벤션: "SSOT.kind" 또는 "SSOT.kind.scope" 형식.

"OpenAPI.operationId"          → {"CreateGig", "ListGigs"}
"DDL.column.users"             → {"id", "email", "name"}
"SSaC.funcName"                → {"CreateGig", "ListGigs"}
"Config.claims"                → {"ID", "Email", "Role"}
"Func.request.HoldEscrow"     → {"GigID", "Amount", "ClientID"}
Evidence

위반 시 반환되는 결과 상세.

type Evidence struct {
    Rule    string // 규칙 ID: "X-1", "S-48" 등
    Level   string // "ERROR" 또는 "WARNING"
    Ref     string // 검사 대상 이름
    Message string // 에러 메시지 템플릿
}

type SchemaEvidence struct {
    Rule    string
    Level   string
    Missing []string // 누락된 필드 목록
    Message string
}

Warrant 함수

RefExists

A가 참조하는 이름이 B에 존재해야 한다.

  • claim: string (참조 이름)
  • ground: *Ground (Lookup 사용)
  • evidence: *Evidence
type RefExistsBacking struct {
    LookupKey string // Ground.Lookup 키: "OpenAPI.operationId", "DDL.column.users" 등
    Rule      string
    Level     string
    Message   string
}
LookupKey 예시 원래 규칙 설명
OpenAPI.operationId X-15 SSaC funcName → OpenAPI
DDL.column.users X-1 x-sort column → DDL
SSaC.funcName X-23 States transition → SSaC
States.diagram X-24 @state → diagram 존재
DDL.table X-31 @ownership table → DDL
OpenAPI.path X-35 Hurl path → OpenAPI
Func.spec X-39 @call → func 구현 존재
Config.claims X-49, X-53 currentUser/Rego → claims
Config.roles X-63 Rego role → Config
OpenAPI.operationId TM-1 STML data-fetch → OpenAPI
SymbolTable.model S-48 SSaC Model → 심볼 테이블

커버 규칙: ~31개.

CoverageCheck

B에 정의된 것이 A에서 사용되어야 한다. RefExists의 역방향.

  • claim: string (정의된 항목 이름)
  • ground: *Ground (Lookup 사용)
  • evidence: *Evidence
type CoverageCheckBacking struct {
    LookupKey string // Ground.Lookup 키: 사용처의 이름 집합
    Rule      string
    Level     string
    Message   string
}
LookupKey 예시 원래 규칙 설명
SSaC.funcName X-16 OpenAPI operationId가 SSaC에서 사용되는지
SSaC.response X-18 OpenAPI response field가 @response에 있는지
SSaC.modelRef X-55 DDL table이 SSaC에서 참조되는지
SSaC.callRef X-62 func spec이 @call에서 사용되는지
Rego.claims X-54 Config claims가 Rego에서 참조되는지
Rego.roles X-64 Config roles가 Rego에서 사용되는지

커버 규칙: ~9개.

PairMatch

A의 (key:value) 쌍이 B에 매칭되어야 한다.

  • claim: string ("key:value" 형식)
  • ground: *Ground (Pairs 사용)
  • evidence: *Evidence
type PairMatchBacking struct {
    LookupKey string // Ground.Pairs 키
    Rule      string
    Level     string
    Message   string
}
LookupKey 예시 원래 규칙 설명
Policy.auth X-28 SSaC @auth (action:resource) → Rego allow
SSaC.auth X-29 Rego allow → SSaC @auth
Config.middleware X-50 OpenAPI security → Config middleware
OpenAPI.security X-51 Config middleware → OpenAPI security
SSaC.subscribe X-57 @publish topic → @subscribe
SSaC.publish X-58 @subscribe topic → @publish

커버 규칙: ~6개.

TypeMatch

A의 타입이 B의 타입과 일치해야 한다. 호출자가 타입을 정규화한 뒤 Ground.Types에 저장한다.

  • claim: *TypeClaim (Name + SourceType)
  • ground: *Ground (Types 사용)
  • evidence: *Evidence
type TypeMatchBacking struct {
    LookupKey string // Ground.Types 키 접두사 (+ ".name" 자동 연결)
    Rule      string
    Level     string
    Message   string
}

type TypeClaim struct {
    Name       string // 필드/파라미터 이름
    SourceType string // 소스 측 타입 (정규화 후)
}
LookupKey 예시 원래 규칙 설명
Func.request.HoldEscrow X-44 @call input type ↔ Request field type
DDL.check.users X-69 DDL CHECK values ↔ OpenAPI enum

커버 규칙: ~4개.

SchemaMatch

A의 필드 집합이 B의 스키마에 존재해야 한다.

  • claim: []string (소스 필드 이름 목록)
  • ground: *Ground (Schemas 사용)
  • evidence: *SchemaEvidence (Missing 포함)
type SchemaMatchBacking struct {
    LookupKey string // Ground.Schemas 키
    Rule      string
    Level     string
    Message   string
}
LookupKey 예시 원래 규칙 설명
OpenAPI.response.CreateGig X-17 @response fields → OpenAPI response
Func.request.HoldEscrow X-42 @call Inputs → FuncRequest fields
SSaC.publish.topic X-59 @subscribe fields → @publish payload
OpenAPI.required.CreateGig X-66 SSaC used fields → OpenAPI required

커버 규칙: ~7개.

ConfigRequired

기능을 사용하면 Config에 해당 설정이 있어야 한다.

  • claim: 무시 (nil 가능)
  • ground: *Ground (Config 사용)
  • evidence: *Evidence
type ConfigRequiredBacking struct {
    ConfigKey string // Ground.Config 키: "backend.auth.claims", "queue.backend" 등
    Rule      string
    Level     string
    Message   string
}
ConfigKey 원래 규칙 설명
backend.auth.claims X-48 currentUser 사용 시 필수
backend.middleware X-52 endpoint security 사용 시 필수
queue.backend X-56 @publish/@subscribe 사용 시 필수

커버 규칙: ~3개.

FieldRequired

필드가 있어야 하거나(Required=true) 없어야 한다(Required=false). SSaC 전용.

  • claim: map[string]bool (필드명 → 값 존재 여부)
  • ground: 무시
  • evidence: *Evidence
type FieldRequiredBacking struct {
    SeqType  string // "@get", "@post", "@put", "@delete", "@empty", "@state", "@auth", "@call", "@publish"
    Field    string // "Model", "Result", "Inputs", "Target", "Message" 등
    Required bool   // true = 있어야 함, false = 없어야 함
    Rule     string
    Level    string
    Message  string
}

backing 하나당 필드 하나. 그래프에서 규칙 ID가 분리된다.

SeqType Field Required 원래 규칙
@get Model true S-1
@get Result true S-2
@post Model true S-3
@post Result true S-4
@post Inputs true S-5
@put Model true S-6
@put Result false S-7
@put Inputs true S-8
@delete Model true S-9
@delete Result false S-10
@empty Target true S-12
@empty Message true S-13
@state DiagramID true S-14
@state Inputs true S-15
@state Transition true S-16
@state Message true S-17
@auth Action true S-18
@auth Resource true S-19
@auth Message true S-20
@call Model true S-21
@publish Topic true S-23
@publish Payload true S-24

커버 규칙: ~22개.

VarDeclared

변수는 선언 후 사용해야 한다. SSaC 전용.

  • claim: string (변수명)
  • ground: *Ground (Vars 사용)
  • evidence: *Evidence
type VarDeclaredBacking struct {
    Rule    string
    Level   string
    Message string
}

커버 규칙: 4개 (S-27S-30).

ForbiddenRef

이름이 금지 목록에 있으면 안 된다. RefExists의 역논리.

  • claim: string (검사 대상 이름)
  • ground: *Ground (Lookup 사용 — 금지 이름 집합)
  • evidence: *Evidence
type ForbiddenRefBacking struct {
    LookupKey string // Ground.Lookup 키 (금지 이름 집합)
    Rule      string
    Level     string
    Message   string
}
LookupKey 예시 원래 규칙 설명
go.reserved S-34, S-35 Go 예약어 (type, select, func 등)
ssac.reservedSource S-33 예약 소스 (config, currentUser, request, query)
ssac.configPrefix S-31 config.* 입력 금지
publish.forbidden S-32 @publish에서 query 금지
subscribe.forbidden S-42, S-43 @subscribe에서 request, query 금지
http.forbidden S-44 HTTP 함수에서 message 금지

커버 규칙: ~7개.

NameFormat

이름이 형식 규칙을 만족해야 한다.

  • claim: string (검사 대상 이름)
  • ground: 무시
  • evidence: *Evidence
type NameFormatBacking struct {
    Pattern string // "uppercase-start", "no-dot-prefix", "dot-method"
    Rule    string
    Level   string
    Message string
}
Pattern 원래 규칙 설명
uppercase-start S-46 Result 타입 대문자 시작
no-dot-prefix S-47 package-prefix @model 금지
dot-method S-26 Model.Method 형식 필수

커버 규칙: ~3개.

Defeater 함수

예외 조건이 충족되면 warrant를 무력화한다. 모두 Ground.Flags 기반. 호출자가 평가 전에 해당 플래그를 설정한다.

함수 backing Flags 키 면제 대상
IsSkipped string (SSOT kind) skipped.<kind> 해당 SSOT 관련 warrant 전체
IsPkgModel nil pkgModel RefExists(SSaC→DDL), CoverageCheck(DDL→SSaC)
IsDTO nil dto RefExists(Model→DDL table)
IsArchived nil archived CoverageCheck(DDL→SSaC)
IsSensitiveCol nil sensitive CoverageCheck(DDL→OpenAPI)
IsNoSensitive nil nosensitive RefExists(sensitive pattern)
IsSubscribe nil subscribe FieldRequired(HTTP 전용), RefExists(request→OpenAPI)
IsImplicitVar nil implicit.<name> VarDeclared (claim=변수명)
IsCustomTS nil customTS.<name> RefExists(STML bind→OpenAPI) (claim=필드명)

커버리지

함수 규칙 수 비율
RefExists ~31 22%
FieldRequired ~22 15%
CoverageCheck ~9 6%
ForbiddenRef ~7 5%
SchemaMatch ~7 5%
PairMatch ~6 4%
TypeMatch ~4 3%
VarDeclared ~4 3%
ConfigRequired ~3 2%
NameFormat ~3 2%
공통 합계 ~96 68%
고유 규칙 ~46 32%
Defeater 9

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ConfigRequired

func ConfigRequired(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

ConfigRequired checks that a config key is set. claim: ignored. Returns (true, evidence) when the key is NOT set.

func CoverageCheck

func CoverageCheck(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

CoverageCheck checks that a defined item is used somewhere. claim: string (defined item name). Returns (true, evidence) when NOT used.

func FieldRequired

func FieldRequired(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

FieldRequired checks that a field is present or absent. claim: map[string]bool (field name -> has value). Required=true: must be present. Required=false: must be absent.

func ForbiddenRef

func ForbiddenRef(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

ForbiddenRef checks that a name is NOT in the forbidden set. claim: string (name). Returns (true, evidence) when name IS found (violation).

func IsArchived

func IsArchived(ctx toulmin.Context, _ toulmin.Specs) (bool, any)

IsArchived checks if the current table is marked @archived. Ground.Flags["archived"] must be set by the caller.

func IsCustomTS

func IsCustomTS(ctx toulmin.Context, _ toulmin.Specs) (bool, any)

IsCustomTS checks if the claimed field exists in custom.ts. Ground.Flags["customTS.<name>"] must be set by the caller. claim: string (field name).

func IsDTO

func IsDTO(ctx toulmin.Context, _ toulmin.Specs) (bool, any)

IsDTO checks if the current type is marked // @dto. Ground.Flags["dto"] must be set by the caller.

func IsImplicitVar

func IsImplicitVar(ctx toulmin.Context, _ toulmin.Specs) (bool, any)

IsImplicitVar checks if the claimed variable is implicitly declared. Ground.Flags["implicit.<name>"] must be set by the caller. claim: string (variable name).

func IsNoSensitive

func IsNoSensitive(ctx toulmin.Context, _ toulmin.Specs) (bool, any)

IsNoSensitive checks if the current column has @nosensitive annotation. Ground.Flags["nosensitive"] must be set by the caller.

func IsPkgModel

func IsPkgModel(ctx toulmin.Context, _ toulmin.Specs) (bool, any)

IsPkgModel checks if the current model is a pkg model (no DDL table). Ground.Flags["pkgModel"] must be set by the caller.

func IsSensitiveCol

func IsSensitiveCol(ctx toulmin.Context, _ toulmin.Specs) (bool, any)

IsSensitiveCol checks if the current column has @sensitive annotation. Ground.Flags["sensitive"] must be set by the caller.

func IsSkipped

func IsSkipped(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

IsSkipped checks if a SSOT kind is excluded via --skip flag. Ground.Flags["skipped.<kind>"] must be set by the caller.

func IsSubscribe

func IsSubscribe(ctx toulmin.Context, _ toulmin.Specs) (bool, any)

IsSubscribe checks if the current function is a @subscribe handler. Ground.Flags["subscribe"] must be set by the caller.

func ModelRefExists

func ModelRefExists(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

ModelRefExists checks that a referenced model name exists in Ground.Models. claim: string (model name). Returns (true, evidence) when NOT found. 구조적 g.Models 기반이라 legacy Lookup["SymbolTable.model"] 을 대체한다.

func NameFormat

func NameFormat(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

NameFormat checks that a name satisfies a format rule. claim: string (name). Returns (true, evidence) when format violated.

func PairMatch

func PairMatch(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

PairMatch checks that a (key:value) pair exists in the target. claim: string ("key:value" joined). Returns (true, evidence) when NOT found.

func RefExists

func RefExists(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

RefExists checks that a referenced name exists in the target. claim: string (reference name). Returns (true, evidence) when NOT found.

func SchemaMatch

func SchemaMatch(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

SchemaMatch checks that source fields exist in the target schema. claim: []string (source field names). Returns (true, evidence) when any missing.

func TypeMatch

func TypeMatch(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

TypeMatch checks that the source type matches the target type. claim: *TypeClaim. Returns (true, evidence) when types do NOT match.

func VarDeclared

func VarDeclared(ctx toulmin.Context, specs toulmin.Specs) (bool, any)

VarDeclared checks that a variable is declared before use. claim: string (variable name). Returns (true, evidence) when NOT declared.

Types

type BaseSpec

type BaseSpec struct {
	Rule    string
	Level   string
	Message string
}

BaseSpec provides common fields for all rule specs. Embed this in concrete spec types to satisfy toulmin.Spec.

func (BaseSpec) SpecName

func (s BaseSpec) SpecName() string

func (BaseSpec) Validate

func (s BaseSpec) Validate() error

type ConfigRequiredSpec

type ConfigRequiredSpec struct {
	BaseSpec
	ConfigKey string
}

ConfigRequiredSpec configures a ConfigRequired rule. ConfigKey selects which Ground.Config key must be set.

type CoverageCheckSpec

type CoverageCheckSpec struct {
	BaseSpec
	LookupKey string
}

CoverageCheckSpec configures a CoverageCheck rule. LookupKey selects which Ground.Lookup set to check usage against.

type Evidence

type Evidence struct {
	Rule    string
	Level   string
	Ref     string
	Message string
}

Evidence is the result detail returned by a violated rule.

type FieldConstraint

type FieldConstraint struct {
	Required  bool
	Format    string
	MinLength *int
	MaxLength *int
	Minimum   *float64
	Maximum   *float64
	Pattern   string
	Enum      []string
}

FieldConstraint — 필드 하나의 JSON Schema 제약.

type FieldRequiredSpec

type FieldRequiredSpec struct {
	BaseSpec
	SeqType  string
	Field    string
	Required bool
}

FieldRequiredSpec configures a FieldRequired rule. Required=true means the field must be present; false means absent.

type FilterSpec

type FilterSpec struct {
	Allowed []string
}

FilterSpec — x-filter.

type ForbiddenRefSpec

type ForbiddenRefSpec struct {
	BaseSpec
	LookupKey string
}

ForbiddenRefSpec configures a ForbiddenRef rule. LookupKey selects which Ground.Lookup set holds forbidden names.

type Ground

type Ground struct {
	// 기존 — 주로 validate/crosscheck 소비
	Lookup  map[string]StringSet // "target.kind" -> set of names
	Types   map[string]string    // "target.kind.name" -> type string
	Pairs   map[string]StringSet // "target.pairKind" -> set of "key:value"
	Config  map[string]bool      // config key -> present
	Vars    StringSet            // declared variable names
	Flags   StringSet            // flags for defeaters
	Schemas map[string][]string  // "target.schema" -> ordered field list

	// 신규 — 주로 generate 소비 (Phase002)
	Models     map[string]ModelInfo         // "User" → {Methods}
	Tables     map[string]TableInfo         // "users" → {Columns, ColumnOrder}
	Ops        map[string]OperationInfo     // operationID → operation 메타
	ReqSchemas map[string]RequestSchemaInfo // operationID → requestBody 필드 제약
}

Ground holds lookup data for validation rules and code generation. Populated by the caller, stored in ctx via ctx.Set("ground", g).

type MethodInfo

type MethodInfo struct {
	Cardinality string   // "one" / "many" / "exec" (sqlc 유래 또는 빈값)
	Params      []string // 매개변수 이름 순서 (sqlc 의 $N 또는 iface 시그니처 유래)
	ErrStatus   int      // FuncSpec @error 코드 (기본 0 = 미지정)
}

MethodInfo — 모델 메서드 하나의 메타.

type ModelInfo

type ModelInfo struct {
	Name    string
	Methods map[string]MethodInfo
}

ModelInfo — Go 인터페이스 + sqlc 쿼리 + FuncSpec @error 가 결합된 모델 메타. 키는 일반 모델명("User") 또는 @call 함수 모델("auth._func").

type ModelRefExistsSpec

type ModelRefExistsSpec struct {
	BaseSpec
}

ModelRefExistsSpec configures a ModelRefExists rule. Ground.Models 를 조회하므로 LookupKey 가 불필요하다.

type NameFormatSpec

type NameFormatSpec struct {
	BaseSpec
	Pattern string
}

NameFormatSpec configures a NameFormat rule. Pattern: "uppercase-start", "no-dot-prefix", "dot-method".

type OperationInfo

type OperationInfo struct {
	ID             string
	Method         string
	Path           string
	PathParams     []PathParam
	HasRequestBody bool
	Pagination     *PaginationSpec
	Sort           *SortSpec
	Filter         *FilterSpec
}

OperationInfo — OpenAPI operation 하나의 메타. Pagination/Sort/Filter 는 해당 x- 확장이 있을 때만 nil 이 아님.

type PaginationSpec

type PaginationSpec struct {
	Style        string // "offset" / "cursor"
	DefaultLimit int
	MaxLimit     int
}

PaginationSpec — x-pagination.

type PairMatchSpec

type PairMatchSpec struct {
	BaseSpec
	LookupKey string
}

PairMatchSpec configures a PairMatch rule. LookupKey selects which Ground.Pairs set to check against.

type PathParam

type PathParam struct {
	Name   string
	GoType string
}

PathParam — operation 의 경로 파라미터.

type RefExistsSpec

type RefExistsSpec struct {
	BaseSpec
	LookupKey string
}

RefExistsSpec configures a RefExists rule. LookupKey selects which Ground.Lookup set to check against.

type RequestSchemaInfo

type RequestSchemaInfo struct {
	Fields map[string]FieldConstraint
}

RequestSchemaInfo — OpenAPI requestBody 의 필드 제약 집합.

type SchemaEvidence

type SchemaEvidence struct {
	Rule    string
	Level   string
	Missing []string
	Message string
}

SchemaEvidence extends Evidence with missing field details.

type SchemaMatchSpec

type SchemaMatchSpec struct {
	BaseSpec
	LookupKey string
}

SchemaMatchSpec configures a SchemaMatch rule. LookupKey selects which Ground.Schemas to check against.

type SkipSpec

type SkipSpec struct {
	BaseSpec
	Kind string
}

SkipSpec configures an IsSkipped defeater. Kind is the SSOT kind to check (e.g., "DDL", "SSaC").

type SortSpec

type SortSpec struct {
	Allowed   []string
	Default   string
	Direction string
}

SortSpec — x-sort.

type StringSet

type StringSet = map[string]bool

StringSet is a set of strings for O(1) lookup.

type TableInfo

type TableInfo struct {
	Name        string
	Columns     map[string]string
	ColumnOrder []string
}

TableInfo — DDL 테이블의 컬럼 메타. Columns 는 이름→타입 조회용 맵, ColumnOrder 는 원본 DDL 선언 순서 (map 비결정성 해소).

type TypeClaim

type TypeClaim struct {
	Name       string
	SourceType string
}

TypeClaim holds a name and its source type for TypeMatch comparison.

type TypeMatchSpec

type TypeMatchSpec struct {
	BaseSpec
	LookupKey string
}

TypeMatchSpec configures a TypeMatch rule. LookupKey is the prefix into Ground.Types (appends ".name").

type VarDeclaredSpec

type VarDeclaredSpec struct {
	BaseSpec
}

VarDeclaredSpec configures a VarDeclared rule.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL