Skip to content

Commit dd9b0c3

Browse files
OpsKernclaude
andcommitted
feat(writ): demo example — writ.New() + Messages.New + VerifyFull() flow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 9004ac1 commit dd9b0c3

3 files changed

Lines changed: 97 additions & 0 deletions

File tree

examples/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# writ examples
2+
3+
## demo
4+
5+
End-to-end flow: `writ.New()``Messages.New()``VerifyFull()`.
6+
7+
```
8+
ANTHROPIC_API_KEY=sk-ant-... go run ./examples/demo/
9+
```
10+
11+
Expected output:
12+
13+
```
14+
chain: /tmp/writ-demo-chain.jsonl
15+
response: writ demo ok
16+
chain verified: 2 entries, root=<hash prefix>
17+
```
18+
19+
The chain file at `/tmp/writ-demo-chain.jsonl` persists between runs. Delete it to start fresh.

examples/demo/main.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Demo: writ end-to-end flow.
2+
//
3+
// Opens a Merkle audit chain, makes one LLM call through the writ gate,
4+
// verifies the chain, and prints the result.
5+
//
6+
// Usage:
7+
//
8+
// ANTHROPIC_API_KEY=sk-ant-... go run ./examples/demo/
9+
package main
10+
11+
import (
12+
"context"
13+
"fmt"
14+
"log"
15+
"os"
16+
"path/filepath"
17+
"runtime"
18+
19+
"github.com/anthropics/anthropic-sdk-go"
20+
"github.com/opskernel-io/writ"
21+
)
22+
23+
func main() {
24+
if os.Getenv("ANTHROPIC_API_KEY") == "" {
25+
log.Fatal("ANTHROPIC_API_KEY is not set")
26+
}
27+
28+
chainPath := filepath.Join(os.TempDir(), "writ-demo-chain.jsonl")
29+
30+
// Locate the policy directory bundled with this demo.
31+
_, thisFile, _, _ := runtime.Caller(0)
32+
policyDir := filepath.Join(filepath.Dir(thisFile), "policy")
33+
34+
client, err := writ.New(writ.Config{
35+
PolicyPath: policyDir,
36+
AuditPath: chainPath,
37+
CallerID: "writ-demo",
38+
})
39+
if err != nil {
40+
log.Fatalf("writ.New: %v", err)
41+
}
42+
43+
fmt.Printf("chain: %s\n", chainPath)
44+
45+
msg, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
46+
Model: anthropic.ModelClaudeHaiku4_5,
47+
MaxTokens: 64,
48+
Messages: []anthropic.MessageParam{
49+
anthropic.NewUserMessage(anthropic.NewTextBlock("Reply with exactly: writ demo ok")),
50+
},
51+
})
52+
if err != nil {
53+
log.Fatalf("Messages.New: %v", err)
54+
}
55+
56+
if len(msg.Content) > 0 {
57+
fmt.Printf("response: %s\n", msg.Content[0].Text)
58+
}
59+
60+
result, err := client.VerifyFull()
61+
if err != nil {
62+
log.Fatalf("VerifyFull: %v", err)
63+
}
64+
65+
if result.Valid {
66+
fmt.Printf("chain verified: %d entries, root=%s\n", result.EntryCount, result.RootHash[:12])
67+
} else {
68+
fmt.Printf("chain INVALID\n")
69+
os.Exit(1)
70+
}
71+
}

examples/demo/policy/writ.rego

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package writ.gate
2+
3+
import rego.v1
4+
5+
default allow := true
6+
default tier := 2
7+
default denial_reason := ""

0 commit comments

Comments
 (0)