Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions adapters/go/adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// adapter.go — LongHun Standard Adapter for Go
package lhstandard

import (
"fmt"
"time"
)

type Adapter struct {
UID, Device, Locale string
dnaGen *DNAGenerator
audit *AuditWrapper
validator *Validator
}

func NewAdapter(uid, device, locale string) *Adapter {
if uid == "" { uid = "9622" }
if device == "" { device = "HM-9622-001" }
if locale == "" { locale = "Asia/Shanghai" }
return &Adapter{
UID:uid, Device:device, Locale:locale,
dnaGen:NewDNAGenerator(uid,device,locale),
audit:NewAuditWrapper(uid),
validator:NewValidator(),
}
}

func (a *Adapter) Wrap(data interface{}, taskType, persona, action, version string) map[string]interface{} {
if taskType == "" { taskType = "default" }
if persona == "" { persona = "P04" }
if action == "" { action = "WRAP" }
if version == "" { version = "V1.0" } else { _ = version }
dna := a.dnaGen.Generate(taskType, action, version)
audit := a.audit.Wrap(data, taskType, persona)
return map[string]interface{}{
"dna":dna,"audit":audit,"payload":data,"meta":map[string]interface{}{
"adapter_version":"1.0.0","uid":a.UID,"device":a.Device,
"task_type":taskType,"persona":persona,
"generated_at":time.Now().UTC().Format(time.RFC3339),"format":"longhun-v∞",
},
}
}

func (a *Adapter) Validate(wrapped map[string]interface{}) ValidationResult {
return a.validator.Validate(wrapped)
}

func (a *Adapter) GetSchemas() (map[string]interface{}, map[string]interface{}) {
dnaSchema := map[string]interface{}{"type":"string","description":"v∞ DNA traceability code"}
auditSchema := map[string]interface{}{"type":"object","required":requiredAudit}
return dnaSchema, auditSchema
}
var _ = fmt.Sprintf
136 changes: 136 additions & 0 deletions adapters/go/adapter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package lhstandard

import "testing"

func assert(t *testing.T, cond bool, msg string) { if !cond { t.Error(msg) } }

func TestDNAGeneratorInstance(t *testing.T) {
g := NewDNAGenerator("","","")
if g.UID != "9622" { t.Error("default uid") }
if g.Device != "HM-9622-001" { t.Error("default device") }
}

func TestDNAGeneratorCustom(t *testing.T) {
g := NewDNAGenerator("9999","T1","")
if g.UID != "9999" || g.Device != "T1" { t.Error("custom") }
}

func TestGeneratePrefix(t *testing.T) {
g := NewDNAGenerator("","","")
dna := g.Generate("","","")
if len(dna) == 0 || dna[:10] != "#LongHun⚡️" { t.Error("prefix") }
}

func TestGenerateDnaUnique(t *testing.T) {
g := NewDNAGenerator("","","")
seen := make(map[string]bool)
for i := 0; i < 10; i++ {
dna := g.Generate("code","GEN",fmt.Sprintf("V%d",i))
if seen[dna] { t.Error("duplicate dna") }
seen[dna] = true
}
}

func TestAuditWrapperInstance(t *testing.T) {
w := NewAuditWrapper("")
if w.UID != "9622" { t.Error("default uid") }
}

func TestAuditWrap(t *testing.T) {
w := NewAuditWrapper("")
r := w.Wrap(map[string]interface{}{"x":1},"","")
if r["audit_version"] != "v1.0" { t.Error("version") }
if r["uid"] != "UID9622" { t.Error("uid") }
}

func TestAuditSignature(t *testing.T) {
w := NewAuditWrapper("")
r := w.Wrap(map[string]interface{}{},"","")
sig := r["behavior_signature"].(map[string]interface{})
for _, k := range []string{"P","F","T","E","C","R","A","X","Y","Z"} {
if _, ok := sig[k]; !ok { t.Error("missing sig key:",k) }
}
}

func TestAuditPattern(t *testing.T) {
w := NewAuditWrapper("")
r := w.Wrap(map[string]interface{}{},"","")
if r["behavior_pattern"] != "MODE-StableDisciplined" { t.Error("pattern") }
}

func TestValidatorNil(t *testing.T) {
v := NewValidator()
r := v.Validate(nil)
if r.Valid { t.Error("nil should be invalid") }
}

func TestValidatorValid(t *testing.T) {
a := NewAdapter("","","")
w := a.Wrap(map[string]interface{}{"h":"w"},"","","","")
v := NewValidator()
r := v.Validate(w)
if !r.Valid { t.Error("should be valid:", r.Errors) }
}

func TestValidatorMissingDNA(t *testing.T) {
v := NewValidator()
r := v.Validate(map[string]interface{}{"audit":map[string]interface{}{},"payload":map[string]interface{}{},"meta":map[string]interface{}{}})
if r.Valid { t.Error("missing dna should be invalid") }
}

func TestQuickValidate(t *testing.T) {
a := NewAdapter("","","")
w := a.Wrap(map[string]interface{}{},"","","","")
if !QuickValidate(w) { t.Error("quick should pass") }
if QuickValidate(nil) { t.Error("nil should fail") }
}

func TestAdapterInstance(t *testing.T) {
a := NewAdapter("","","")
if a.UID != "9622" || a.Device != "HM-9622-001" { t.Error("defaults") }
}

func TestAdapterWrap(t *testing.T) {
a := NewAdapter("","","")
r := a.Wrap(map[string]interface{}{"code":"x"},"","","","")
for _, k := range []string{"dna","audit","payload","meta"} {
if _, ok := r[k]; !ok { t.Error("missing key:",k) }
}
}

func TestAdapterValidate(t *testing.T) {
a := NewAdapter("","","")
w := a.Wrap(map[string]interface{}{},"","","","")
r := a.Validate(w)
if !r.Valid { t.Error("self-validate fail:", r.Errors) }
}

func TestGetSchemas(t *testing.T) {
a := NewAdapter("","","")
d, au := a.GetSchemas()
if d == nil || au == nil { t.Error("schemas should not be nil") }
}

func TestUIDConsistency(t *testing.T) {
a := NewAdapter("8888","","")
w := a.Wrap(map[string]interface{}{},"","","","")
meta := w["meta"].(map[string]interface{})
audit := w["audit"].(map[string]interface{})
if meta["uid"] != "8888" { t.Error("meta uid") }
if audit["uid"] != "UID8888" { t.Error("audit uid") }
}

func TestClassifyDD(t *testing.T) {
sig := map[string]interface{}{"F":"Unfulfilled","X":"OverExplain"}
if classify(sig) != "MODE-DefensiveDefaulter" { t.Error("dd") }
}

func TestClassifyID(t *testing.T) {
sig := map[string]interface{}{"F":"Unfulfilled","Y":"Indifferent"}
if classify(sig) != "MODE-InternalDestroyer" { t.Error("id") }
}

func TestClassifyFluc(t *testing.T) {
sig := map[string]interface{}{"Z":3.0}
if classify(sig) != "MODE-Fluctuating" { t.Error("fluc") }
}
72 changes: 72 additions & 0 deletions adapters/go/audit_wrapper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// audit_wrapper.go — seven-factor behavioral audit metadata
package lhstandard

import (
"crypto/sha256"
"encoding/json"
"fmt"
"sort"
"time"
)

var labelMap = map[string]map[string]string{
"P": {"HasPromise":"7F-P-有承诺","NoPromise":"7F-P-无承诺"},
"F": {"Fulfilled":"7F-F-已兑现","Unfulfilled":"7F-F-未兑现","Partial":"7F-F-部分兑现"},
"E": {"Willing":"7F-E-心甘情愿","Perfunctory":"7F-E-敷衍","Resentful":"7F-E-怨恨","Numb":"7F-E-麻木"},
"A": {"Self":"7F-A-自己","Partner":"7F-A-伴侣","Family":"7F-A-家庭","Outsider":"7F-A-外人","Public":"7F-A-公众"},
"X": {"OverExplain":"7F-X-过度解释","Silent":"7F-X-沉默","Genuine":"7F-X-真诚","Indifferent":"7F-X-冷漠"},
"Y": {"Changed":"7F-Y-改正","Resisted":"7F-Y-抗拒","Indifferent":"7F-Y-无视","NoResponse":"7F-Y-无响应"},
}

type AuditWrapper struct{ UID string }
func NewAuditWrapper(uid string) *AuditWrapper {
if uid == "" { uid = "9622" }
return &AuditWrapper{uid}
}

func (w *AuditWrapper) Wrap(payload interface{}, taskType, persona string) map[string]interface{} {
if taskType == "" { taskType = "default" }
if persona == "" { persona = "P04" }
sig := map[string]interface{}{"P":"HasPromise","F":"Fulfilled","T":0.0,"E":"Willing","C":0,"R":0,"A":"Self","X":"Genuine","Y":"NoResponse","Z":1.0}
pattern := classify(sig)
labels := makeLabels(sig, pattern)
color := determineColor(pattern, int(sig["R"].(int)))
pj, _ := json.Marshal(payload)
ph := fmt.Sprintf("%x", sha256.Sum256(pj))[:16]
return map[string]interface{}{
"audit_version":"v1.0","uid":fmt.Sprintf("UID%s",w.UID),"persona":persona,"task_type":taskType,
"behavior_signature":sig,"behavior_pattern":pattern,"behavior_labels":labels,
"color":color,"timestamp":time.Now().UTC().Format(time.RFC3339),"payload_hash":ph,
}
}

func classify(sig map[string]interface{}) string {
f,_ := sig["F"].(string); x,_ := sig["X"].(string); a,_ := sig["A"].(string)
y,_ := sig["Y"].(string); z,_ := sig["Z"].(float64)
if f=="Unfulfilled" && x=="OverExplain" { return "MODE-DefensiveDefaulter" }
if f=="Fulfilled" && a=="Outsider" { return "MODE-ExternalTrustSpender" }
if f=="Unfulfilled" && y=="Indifferent" { return "MODE-InternalDestroyer" }
if z > 2.0 { return "MODE-Fluctuating" }
return "MODE-StableDisciplined"
}

func makeLabels(sig map[string]interface{}, pattern string) []string {
var labels []string
for _, factor := range []string{"P","F","E","A","X","Y"} {
if v, ok := sig[factor].(string); ok {
if lm, ok2 := labelMap[factor]; ok2 {
if lb, ok3 := lm[v]; ok3 { labels = append(labels, lb) }
}
}
}
labels = append(labels, pattern)
return labels
}

func determineColor(pattern string, repeat int) string {
if pattern == "MODE-InternalDestroyer" { return "🔴" }
if pattern == "MODE-Fluctuating" && repeat > 3 { return "🟡" }
if pattern == "MODE-DefensiveDefaulter" && repeat > 2 { return "🟡" }
return "🟢"
}
var _ = sort.Ints
93 changes: 93 additions & 0 deletions adapters/go/dna_generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// dna_generator.go — v∞ DNA traceability code generation
package lhstandard

import (
"crypto/sha256"
"fmt"
"math"
"time"
)

var tianGan = []string{"Jia","Yi","Bing","Ding","Wu","Ji","Geng","Xin","Ren","Gui"}
var diZhi = []string{"Zi","Chou","Yin","Mao","Chen","Si","Wu","Wei","Shen","You","Xu","Hai"}
var shiChen = []string{"ZiShi","ChouShi","YinShi","MaoShi","ChenShi","SiShi","WuShi","WeiShi","ShenShi","YouShi","XuShi","HaiShi"}

type Hexagram struct{ Symbol, EnName, CnName, Domain string }

var hexagrams = []Hexagram{
{"䷀","Qian","乾","governance"},{"䷁","Kun","坤","archive"},
{"䷂","Zhun","屯","init"},{"䷃","Meng","蒙","learn"},
{"䷄","Xu","需","async"},{"䷅","Song","讼","legal"},
{"䷜","Kan","坎","engine"},{"䷝","Li","离","audit"},
{"䷲","Zhen","震","security"},{"䷳","Gen","艮","privacy"},
{"䷸","Xun","巽","deploy"},{"䷹","Dui","兑","trust"},
{"䷾","JiJi","既济","complete"},{"䷿","WeiJi","未济","progress"},
}

var taskHexagramMap = map[string]string{
"default":"governance","code":"engine","deploy":"deploy","audit":"audit",
"security":"security","archive":"archive","init":"init","learn":"learn",
"legal":"legal","privacy":"privacy","trust":"trust","complete":"complete","progress":"progress",
}

type DNAGenerator struct {
UID, Device, Locale string
}

func NewDNAGenerator(uid, device, locale string) *DNAGenerator {
if uid == "" { uid = "9622" }
if device == "" { device = "HM-9622-001" }
if locale == "" { locale = "Asia/Shanghai" }
return &DNAGenerator{uid, device, locale}
}

func (g *DNAGenerator) Generate(taskType, action, version string) string {
if taskType == "" { taskType = "default" }
if action == "" { action = "WRAP" }
if version == "" { version = "V1.0" }
now := time.Now().UTC()
stem := g.computeStemBranch(now)
hex := g.selectHexagram(taskType)
body := fmt.Sprintf("ADAPTER-%s-%s-%s", toUpper(taskType), toUpper(action), version)
raw := fmt.Sprintf("%s%s%s%s%s%s%s%s%s", stem["year"],stem["month"],stem["day"],stem["shichen"],hex.Symbol,hex.EnName,body,g.Device,now.Format(time.RFC3339))
h := sha256.Sum256([]byte(raw))
return fmt.Sprintf("#LongHun⚡️%s·%s·%s·%s·%s%s-%s-%x", stem["year"],stem["month"],stem["day"],stem["shichen"],hex.Symbol,hex.EnName,body,h[:4])
}

func toUpper(s string) string {
r := []rune(s)
for i, c := range r {
if c >= 'a' && c <= 'z' { r[i] = c - 32 }
}
return string(r)
}

func (g *DNAGenerator) computeStemBranch(dt time.Time) map[string]string {
cycleYear, cycleMonth := 1984, []int{2,4,6,8,10,0,2,4,6,8,10,0}
y := dt.Year(); m := int(dt.Month()); doy := dt.YearDay(); h := dt.Hour()
ys := (y-cycleYear) % 10; if ys < 0 { ys += 10 }
yb := (y-cycleYear) % 12; if yb < 0 { yb += 12 }
mb := cycleMonth[(y-cycleYear)%10]; if mb < 0 { mb += 10 }
ms := (mb + m - 1) % 10; if ms < 0 { ms += 10 }
mbr := (m + 1) % 12
ds := (y - 1900 + (y-1900)/4 + doy) % 10; if ds < 0 { ds += 10 }
db := (y - 1900 + (y-1900)/4 + doy) % 12; if db < 0 { db += 12 }
si := h / 2
return map[string]string{
"year": tianGan[ys]+diZhi[yb], "month": tianGan[ms]+diZhi[mbr],
"day": tianGan[ds]+diZhi[db], "shichen": shiChen[si],
}
}

func (g *DNAGenerator) selectHexagram(taskType string) Hexagram {
domain := taskHexagramMap[taskType]
if domain == "" { domain = "governance" }
for _, h := range hexagrams {
if h.Domain == domain { return h }
}
return hexagrams[0]
}

func absMod(a, b int) int { r := a % b; if r < 0 { r += b }; return r }
var _ = absMod // suppress unused
var _ = math.Abs
3 changes: 3 additions & 0 deletions adapters/go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/UID9622/lh-standard-adapter/adapters/go

go 1.19
3 changes: 3 additions & 0 deletions adapters/go/schemas.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// schemas.go — DNA and Audit JSON Schemas
package lhstandard
// Schemas are dynamically generated by GetSchemas() for runtime flexibility.
Loading