Skip to Content
核心概念座標運算子

座標公式、Command 與規則

已合併 PR1 #1988,核對 c15a12f9b01aa3e88e7b0cf65fe4735a48e03718:capture ingress、不確定 condition、受信任原點/filter 引用與 IaC rule 轉譯對應合併 master。請見型別、幾何與出勤 how-to。空間紀錄查詢篩選與距離排序是獨立功能,自 backend 5.21.0 起提供,請見座標查詢。REST rule 不會自動成為已驗收的可攜式 package;不推定瀏覽器或部署驗收。

Formula v2

必須宣告 formula_version: 2;省略仍為 version 1。座標 reference 是同一筆 record 的 v2 source。Live/stored resolver 使用座標的 system、ordered axes、length-unit metadata,不會自動換算單位。

函式結果與條件
DISTANCE(a, b [, "metric" [, scale]])精確 decimal;literal metric 名稱,0–18 的 literal 整數 scale
AXIS(a, "axis_key")Decimal component;literal axis 必須存在
WITHIN(a, b, radius)Boolean;decimal radius;只有幾何,不是出勤 capture 閘門
BEARING(a, b)Decimal 角度;僅 geographic
DOT(a, b)Decimal 內積;僅 Cartesian
NORM(a)Decimal 歐幾里得範數;僅 Cartesian

Null operand 在公式求值中傳播。System/axes/units 不相容不會隱式轉換。一般 computed dependency ACL 遮罩仍保護 live/stored result;隱藏 source 不能藉公式顯露。公式依賴必須是 v2,stored dependency 限制仍有效。

已有 geographic Location 與 Origin 欄位時,column-create body:

{ "name": "Distance m", "type": "formula", "formula_version": 2, "expression": "DISTANCE([Location], [Origin], \"geodesic\", 3)" }

WITHIN([Location], [Origin], DECIMAL("150")) 沒有 sources、最大 accuracy、capture age 參數,不能取代出勤規則。這些函式不替 formula v1 加入座標 SQL pushdown。

此 pin 的 unit inference:geographic 是公尺,相容 DISTANCE 結果承接 operand unit,AXIS/NORM 承接第一個 operand unit。WITHIN、BEARING、DOT 檢查相容性但不帶結果單位;沒有為 DOT 或 squared metric 推導平方單位代數。

Command expressions

這些是 version-2 expression,不是 formula 名稱或 version-1 placeholder。

Expression結果
{"$distance":[a,b,options?]}Decimal wire 字串,或 null
{"$axis":[point,"axis_key"]}Decimal wire 字串;literal axis
{"$within":[point,origin,radius,options?]}Nullable Boolean;null point/origin 或 capture 證據失敗回 null
{"$within_any":[point,origins,options?]}{matched, origin_id, distance_m};確定未命中為 false/null/null;null subject 或 capture 失敗為 null/null/null

Indeterminate 不等於 false。$within 與 $within_any.matched 的型別為 nullable Boolean;$not(null) 仍是 null。Command assert 要求 condition 必須恰為 true,因此對未知圍欄結果取反不能授權寫入;不可把未知結果替換為成功的預設值。

當 $case branch condition 或 step when 求值為 null,且 expression subtree 含 $within/$within_any,執行會以 ct.coordinate_invalid、phase execute、message Coordinate condition is indeterminate 拒絕,不會走 else branch 或跳過 step。Frozen temporal condition 重新驗證保留此 typed refusal,不改標為一般 stale guard。這是 coordinate-subtree 檢查,不是對所有一般 null condition,或 subtree 不含幾何 expression 的間接 variable,新增全面拒絕規則。

宣告 point input,例如:

{"name":"location","type":"coordinate","coordinate_system":"geographic","capture":true,"required":true}

Input 預設 geographic,也可宣告 axes、length_unit。capture 是 strict boolean、預設 false;非座標 input 拒絕座標設定。Capture 宣告是 device provenance 必要條件,不是身分驗證。

Version-2 execution step 的 field schema 可回報 type: "coordinate"。Step response 仍只有 metadata;值必須透過明訂 output 與既有權限檢查輸出。

Expression operand 不是裸 JSON object,必須用 typed input/reference 或既有 JSON expression。此例明確 parse options:

{ "$distance": [ "$input.location", "$input.origin", {"$json_parse":{"value":"{\"metric\":\"geodesic\",\"scale\":3}","on_error":"fail"}} ] }

$distance 選項為 metric、weights、include_altitude、scale、rounding;rounding 接受 half_even、half_up、down、floor、ceiling。Geofence 選項包括 metric、accuracy_policy、sources、max_accuracy_m、max_capture_age_s;最大 accuracy 必須為正,最大 age 為 1–86400 整數。一般幾何相容性檢查仍適用。

若提供 geofence helper 的 disclose_nearest,必須為 boolean。Command helper 與 rule authoring 都拒絕以 true 開啟;兩條路徑都尚未實作 nearest 錯誤揭露。

$within/$within_any 的 capture/quality options 要求 schema-typed coordinate input 或 reference。Untyped JSON/object point 沒有 provenance,在幾何求值前會移除 src、acc_m、at、accuracy_m、captured_at;把這些 key 複製進 JSON 不會產生 capture 證據。Typed reference 會還原 stored coordinate evidence,不重新指定來源。非座標 subject 搭配 dynamic options,或 static sources、最大 accuracy/age、accuracy_policy:"strict",會在 authoring 被拒絕;literal $json_parse options 也會檢查。這些設定拒絕使用 Command authoring error invalid_expression、phase author、message Coordinate configuration refused,不是保證對外回傳 ct.coordinate_capture_operand_required。

Command $within_any 接受最多 50 個 object,每個只能有 {id, point, radius}:字串 ID、相容座標、decimal radius。它不接受規則的 {via, location, radius, where} resolver。應以授權 native-link query 選 active assigned sites,再 collect 有界 array;不能以呼叫者提供的 employee ID 或 origin list 作出勤授權。

此例只示範 array 語法,不是 assigned-site 出勤 Command:

{ "$within_any": [ "$input.location", {"$json_parse":{"value":"[{\"id\":\"site-example\",\"point\":{\"lat\":\"25.0339640\",\"lon\":\"121.5644680\"},\"radius\":\"150\"}]","on_error":"fail"}}, {"$json_parse":{"value":"{\"sources\":[\"device_geolocation\"],\"max_accuracy_m\":\"50\",\"max_capture_age_s\":120,\"accuracy_policy\":\"strict\"}","on_error":"fail"}} ] }

以 $json_get 擷取結果,例如 pointer /matched、type boolean、on_error: "fail",沒有 $var.match.matched reference。Insert 前應 assert。不要 stringify/重新 parse captured input 本身:sealed、綁定 principal 的 server provenance 不是一般 JSON 聲明。

這些運算子是 runtime-bounded,一般 where、join、order_by 不會自動 lowering,unsupported clause 在 authoring 失敗。唯一例外是依單一升序 $distance expression 排序的最近鄰 select 步驟,說明見座標查詢;仍沒有通用幾何 SQL compiler。Runtime 幾何錯誤封裝為 ct.coordinate_invalid、phase execute、message Coordinate evaluation refused;安全 structural code 如 ct.geofence_origin_cap、ct.geofence_origin_missing、system/axes/unit mismatch 與 unknown axis 保留 typed code。Assert condition 不恰為 true 時走一般 assertion_failed rollback。Coordinate reference 或 $lookup/$rollup 結果缺少 coordinate column context,會以 ct.coordinate_invalid、phase execute、message Coordinate context required 拒絕。

Coordinate check 規則

規則以 kernel authority 解析 origin,不依賴呼叫者能否讀隱藏座標。Operand column 必須為 coordinate。建立時驗證 options、systems、axes、units、native-link scope 及目標欄位。

Operatorvalue
within/outside{origin, radius, ...capture_options};literal 或同 row $row.<column>
within_any/outside_all{origins:{via,location,radius,where?}, ...capture_options}
in_box只能有 {min:<完整 point>,max:<完整 point>}

Event table 的 native employee → employee → allowed_sites → site links,可用 rules.set:

{ "rules": [{ "type": "check", "name": "Active assigned attendance fence", "column": "location", "op": "within_any", "value": { "origins": { "via": "employee.allowed_sites", "location": "location", "radius": "radius_m", "where": [{"column":"active","op":"eq","value":true}] }, "sources": ["device_geolocation"], "max_accuracy_m": "50", "max_capture_age_s": 120, "accuracy_policy": "strict" } }] }

via 為 一至三段 native-link hop 的 dotted path,每段上限 50 個 ID;missing/deleted record 都 fail closed。最後 table 的 location 必須相容,radius 為 decimal 欄位 name/key 或 decimal literal;where 是一般 target predicate,禁止巢狀 spatial predicate。空 eligible set 不滿足 outside_all;negation 不能授權 missing capture/origin。

每一段 origins.via link、linked target location、欄位型 target radius,以及每個 origins.where predicate 欄位,都必須設定 column_acl.write 為 "managers" 或 "none"。未受保護的 filter 在 rule authoring 以設定訊息 ct.coordinate_reference_untrusted 拒絕;求值時再檢查目前同列/linked origin 與 filter ACL,保護失效會以 origin_untrusted reason 成為 indeterminate。Kernel read authority 並不授權一般寫入者重新連結 row、移動原點或切換合格條件。

Column-ACL PATCH 與 IaC apply 會拒絕移除既有 coordinate rule/trigger origin dependency 的寫入保護:HTTP 409、detail.error:"ct.coordinate_dependency",並回傳 dependent_column_acl conflict。Filter 欄位也列入此 dependency guard;dependency analysis 遇到不合法 rule 證據時,以該 conflict fail closed。此 guard 保護原點寫入信任,不代表 history 保密性。

省略 origins.where 會正規化為空 predicate list。Rule authoring 保留具型別的維度錯誤碼 ct.coordinate_system_mismatch、ct.coordinate_axes_mismatch 與 ct.coordinate_unit_mismatch;其他不合法值仍可能使用 ct.coordinate_rule_value_invalid。

同 row fence 用 {"origin":"$row.origin","radius":"$row.radius_m"};每個被引用的 origin/radius 欄位都必須設定 column_acl.write 為 "managers" 或 "none",否則 authoring 以設定訊息 ct.coordinate_reference_untrusted 拒絕。Cartesian box 可用 {"min":{"x":"0","y":"0"},"max":{"x":"10","y":"20"}},axes 必須完整相符。邊界含等號,使用未 rounding 的幾何值。

與 scalar check 跳過空值不同,coordinate check 以 null_value reason 拒絕 null location。失敗為 HTTP 409,例如:

{"detail":{"error":"ct.rule_violation","rule_id":"server-rule-id","reason":"outside_geofence"}}

Capture reason 包括 capture_untrusted、capture_accuracy、capture_missing_time、capture_stale;缺少 literal/row origin 可給 origin_missing。Strict-accuracy 邊界不確定性使用 accuracy_ambiguous,不是 origin_missing。安全 structural failure 使用 {error:<typed_code>,rule_id},包括 ct.geofence_origin_cap、ct.geofence_origin_missing,不含座標。disclose_nearest:true 以 ct.coordinate_disclosure_unsupported 拒絕;尚未實作 nearest label/distance 錯誤揭露。

aggregate_limit.when 在 rule authoring 拒絕 coordinate predicates,不會將它們當作 aggregate filter 求值。

不確定的座標 condition

Null subject(null_value)、capture 證據失敗(原 capture reason)、缺少 literal/row origin,linked-origin eligible set 為空(origin_missing)、原點/filter 寫入保護失效(origin_untrusted),或 strict-accuracy 不確定性(accuracy_ambiguous),都使座標 condition 成為 indeterminate。一般 rule when 對此已求值的 condition 以 HTTP 409、ct.rule_violation、rule ID 與 reason 拒絕,不再悄悄視為未命中。Approval matching 與 immutable_when.prior_when 保守地把該不確定座標 predicate 視為命中;其他 predicates 仍參與判斷。

Consumer不確定座標 predicate 的結果
Check-rule when以 409 ct.rule_violation、rule ID 及 reason 拒絕
require_approval.whenPredicate 視為命中;符合其餘條件的 rule 仍要求審批
immutable_when.prior_whenPredicate 視為命中;符合其餘條件的 pre-image lock 保持鎖定
Event-trigger when不觸發、不執行 action,並記錄 reason
date_column_reached schedule when消耗 occurrence;done run 記錄 skipped condition 及 reason,不 dispatch action

Event trigger 對此不確定 condition 不執行任何 action,並儲存 done receipt:action_results:[{"type":"when","status":"skipped","reason":"…"}]、payload:{"condition_outcome":"indeterminate","reason":"…"}。date_column_reached scheduler 現會 claim 到期 occurrence,並以相同 skipped-when/indeterminate-reason 欄位持久化 done run,不再只記錄 diagnostic 並視為 false。此 record-based receipt 合約不宣稱其他不相關 schedule type 也有相同行為。這些僅是 source 合約,不是 owner 驗收結果。

此 pin 的 IaC plan/apply 會逐跳跟隨 origins.via 原生 link,再於 target table 轉譯 location、欄位型 radius 及 where[].column。Export 使用 linked tables 的 context 反向轉譯。同列 $row. origin/radius 則使用自身 table。How-to已含可攜式 rule;開放前仍須由 owner 完成 round-trip 與 runtime 驗收。

Capture policy 與 ACL

Device provenance 需要 geographic capture column/input、明訂 allowlisted 單欄 ingress marker、互動式非 service JWT 及同一 acting tenant/user。Command capture 另需 manual invocation origin。Reading 包含 lat、lon、正數 accuracy_m、最多領先 server 五秒的 captured_at。Client src 不是授權來源;marker 在 nested automation、trigger、cascade、thread 或 background work 前重設。Ingress → source 合約 明訂 import 為 import、IaC 為 iac、普通非 capture ingress 為 client,undo/replay 原樣保留 stored evidence。匯入永遠不得取得 device provenance。

出勤預設需 sources: ["device_geolocation"]、正数最大 accuracy、新鮮 capture time、strict geometry。欄位 ACL保護精確位置,並另行保護 derived distance、selected site、receipt、history、output。Definer read ceiling 不代表 caller 能直接讀隱藏 source row。

拒絕 nearest 錯誤揭露仍不能消除位置推論。即使不回傳座標、最近站點名稱或距離,重複的 accept/refuse 結果仍可用於二分搜尋隱藏原點。Column ACL 與 private outputs 並不保證圍欄的隱藏原點無法被推測。

Helper 的較弱 LINE opt-in 明確列 channel:line 並省略 maximum accuracy;null accuracy 在幾何視為零 uncertainty,即使是 strict,stored acc_m 仍為 null。Native LINE factory 已將 persisted latest human location message 綁定同 tenant live room、native external identity、channel 與 group digest,並以 server reading 取代明訂 capture input。有效 numeric latitude/longitude 以 half-even rounding 按 1e-7 精度保留七位小數;event timestamp 必須是正整數 milliseconds。格式不合法的 event/message/time/coordinates 不產生 reading,更不產生 capture value。Native handler 儲存此 location message 時,line_location metadata 為 null,沒有可用的 location reading。缺少/無效 binding 回 ct.coordinate_source_unavailable,caller metadata 不能創造此 binding。這是 source behavior,不是 native-channel 驗收或 device attestation。預設出勤拒絕可自選 LINE pin、typed value、import、IaC seed;device spoofing 仍是 kernel 以外的 residual,kernel 不提供 capture UI 或 GPS hardware attestation。

Last updated on