@@ -19,16 +19,24 @@ export function Appendix() {
1919 < div className = "flex flex-col gap-8" >
2020 < AppendixCard
2121 label = "A"
22+ title = { t ( "appendix.access.title" ) }
23+ description = { t ( "appendix.access.desc" ) }
24+ note = { t ( "appendix.access.note" ) }
25+ diagram = { < AccessControlDiagram /> }
26+ />
27+
28+ < AppendixCard
29+ label = "B"
2230 title = { t ( "appendix.observability.title" ) }
2331 description = { t ( "appendix.observability.desc" ) }
2432 note = { t ( "appendix.observability.note" ) }
2533 referenceLabel = { t ( "appendix.observability.ref" ) }
26- referenceHref = "https://github.com/bubbuild/bub "
34+ referenceHref = "https://bub.build/architecture/ "
2735 diagram = { < ObservabilityDiagram /> }
2836 />
2937
3038 < AppendixCard
31- label = "B "
39+ label = "C "
3240 title = { t ( "appendix.eval.title" ) }
3341 description = { t ( "appendix.eval.desc" ) }
3442 note = { t ( "appendix.eval.note" ) }
@@ -38,7 +46,7 @@ export function Appendix() {
3846 />
3947
4048 < AppendixCard
41- label = "C "
49+ label = "D "
4250 title = { t ( "appendix.training.title" ) }
4351 description = {
4452 < >
@@ -79,8 +87,8 @@ function AppendixCard({
7987 title : string
8088 description : ReactNode
8189 note : string
82- referenceLabel : string
83- referenceHref : string
90+ referenceLabel ? : string
91+ referenceHref ? : string
8492 diagram : ReactNode
8593} ) {
8694 const { locale } = useI18n ( )
@@ -99,30 +107,129 @@ function AppendixCard({
99107
100108 < div className = "bg-foreground px-5 py-3 flex flex-col md:flex-row md:items-center md:justify-between gap-2" >
101109 < p className = "text-xs font-mono text-background/70 leading-relaxed" > { note } </ p >
102- < a
103- href = { referenceHref }
104- target = "_blank"
105- rel = "noopener noreferrer"
106- className = "inline-flex items-center gap-2 text-[11px] font-mono text-background/50 hover:text-background/75 transition-colors"
107- >
108- < span > { locale === "zh" ? "参考" : "ref" } </ span >
109- < span > { referenceLabel } </ span >
110- < svg width = "10" height = "10" viewBox = "0 0 10 10" className = "text-current" >
111- < path
112- d = "M 2 8 L 8 2 M 4 2 L 8 2 L 8 6"
113- stroke = "currentColor"
114- strokeWidth = "1.2"
115- fill = "none"
116- strokeLinecap = "round"
117- strokeLinejoin = "round"
118- />
119- </ svg >
120- </ a >
110+ { referenceLabel && referenceHref ? (
111+ < a
112+ href = { referenceHref }
113+ target = "_blank"
114+ rel = "noopener noreferrer"
115+ className = "inline-flex items-center gap-2 text-[11px] font-mono text-background/50 hover:text-background/75 transition-colors"
116+ >
117+ < span > { locale === "zh" ? "参考" : "ref" } </ span >
118+ < span > { referenceLabel } </ span >
119+ < svg width = "10" height = "10" viewBox = "0 0 10 10" className = "text-current" >
120+ < path
121+ d = "M 2 8 L 8 2 M 4 2 L 8 2 L 8 6"
122+ stroke = "currentColor"
123+ strokeWidth = "1.2"
124+ fill = "none"
125+ strokeLinecap = "round"
126+ strokeLinejoin = "round"
127+ />
128+ </ svg >
129+ </ a >
130+ ) : null }
121131 </ div >
122132 </ div >
123133 )
124134}
125135
136+ function AccessControlDiagram ( ) {
137+ const { locale, t } = useI18n ( )
138+
139+ return (
140+ < svg viewBox = "0 0 700 240" className = "w-full" fill = "none" >
141+ < defs >
142+ < marker id = "acl-arr" viewBox = "0 0 10 10" refX = "9" refY = "5" markerWidth = "6" markerHeight = "6" orient = "auto" >
143+ < path d = "M0 1L9 5L0 9" className = "fill-none stroke-foreground" strokeWidth = "1.5" />
144+ </ marker >
145+ < marker id = "acl-arr-a" viewBox = "0 0 10 10" refX = "9" refY = "5" markerWidth = "6" markerHeight = "6" orient = "auto" >
146+ < path d = "M0 1L9 5L0 9" className = "fill-none stroke-accent" strokeWidth = "1.5" />
147+ </ marker >
148+ </ defs >
149+
150+ < rect x = "28" y = "90" width = "120" height = "64" rx = "12" className = "fill-foreground" />
151+ < text x = "88" y = "114" textAnchor = "middle" className = "fill-primary-foreground text-[11px] font-mono font-semibold" >
152+ { locale === "zh" ? "Admin" : "Admin" }
153+ </ text >
154+ < text x = "88" y = "132" textAnchor = "middle" className = "fill-primary-foreground/70 text-[8px] font-mono" >
155+ { locale === "zh" ? "audit scope" : "audit scope" }
156+ </ text >
157+ < text x = "88" y = "144" textAnchor = "middle" className = "fill-primary-foreground/70 text-[8px] font-mono" >
158+ { locale === "zh" ? "read role" : "read role" }
159+ </ text >
160+
161+ < rect x = "196" y = "70" width = "152" height = "104" rx = "12" className = "fill-secondary/35 stroke-border" strokeWidth = "1" />
162+ < text x = "272" y = "98" textAnchor = "middle" className = "fill-muted-foreground text-[10px] font-mono font-semibold" >
163+ { locale === "zh" ? "Boundary" : "Boundary" }
164+ </ text >
165+ { [
166+ { y : 110 , label : locale === "zh" ? "owner" : "owner" } ,
167+ { y : 134 , label : locale === "zh" ? "grant" : "grant" } ,
168+ { y : 158 , label : locale === "zh" ? "read-only" : "read-only" } ,
169+ ] . map ( ( item ) => (
170+ < g key = { item . label } >
171+ < rect x = "224" y = { item . y } width = "96" height = "14" rx = "5" className = "fill-card stroke-border" strokeWidth = "0.8" />
172+ < text x = "272" y = { item . y + 9 } textAnchor = "middle" className = "fill-muted-foreground text-[7px] font-mono" >
173+ { item . label }
174+ </ text >
175+ </ g >
176+ ) ) }
177+
178+ < rect x = "390" y = "36" width = "132" height = "78" rx = "12" className = "fill-card stroke-border" strokeWidth = "1" />
179+ < text x = "456" y = "58" textAnchor = "middle" className = "fill-foreground text-[10px] font-mono font-semibold" >
180+ { locale === "zh" ? "User A" : "User A" }
181+ </ text >
182+ < text x = "456" y = "72" textAnchor = "middle" className = "fill-muted-foreground text-[8px] font-mono" >
183+ { locale === "zh" ? "Database" : "Database" }
184+ </ text >
185+ < rect x = "416" y = "80" width = "80" height = "20" rx = "6" className = "fill-secondary/30 stroke-border" strokeWidth = "1" />
186+ < text x = "456" y = "93" textAnchor = "middle" className = "fill-foreground text-[8px] font-mono font-semibold" >
187+ { locale === "zh" ? "Tape Table" : "Tape Table" }
188+ </ text >
189+
190+ < rect x = "390" y = "126" width = "132" height = "78" rx = "12" className = "fill-card stroke-border" strokeWidth = "1" />
191+ < text x = "456" y = "148" textAnchor = "middle" className = "fill-foreground text-[10px] font-mono font-semibold" >
192+ { locale === "zh" ? "User B" : "User B" }
193+ </ text >
194+ < text x = "456" y = "162" textAnchor = "middle" className = "fill-muted-foreground text-[8px] font-mono" >
195+ { locale === "zh" ? "Database" : "Database" }
196+ </ text >
197+ < rect x = "416" y = "170" width = "80" height = "20" rx = "6" className = "fill-secondary/30 stroke-border" strokeWidth = "1" />
198+ < text x = "456" y = "183" textAnchor = "middle" className = "fill-foreground text-[8px] font-mono font-semibold" >
199+ { locale === "zh" ? "Tape Table" : "Tape Table" }
200+ </ text >
201+
202+ < rect x = "560" y = "84" width = "112" height = "76" rx = "12" className = "fill-accent/10 stroke-accent" strokeWidth = "1" />
203+ < text x = "616" y = "108" textAnchor = "middle" className = "fill-accent text-[10px] font-mono font-semibold" >
204+ { locale === "zh" ? "Audit" : "Audit" }
205+ </ text >
206+ < text x = "616" y = "126" textAnchor = "middle" className = "fill-accent/70 text-[8px] font-mono" >
207+ { locale === "zh" ? "read-only" : "read-only" }
208+ </ text >
209+ < text x = "616" y = "142" textAnchor = "middle" className = "fill-accent/70 text-[8px] font-mono" >
210+ { locale === "zh" ? "multi-user" : "multi-user" }
211+ </ text >
212+
213+ < line x1 = "148" y1 = "122" x2 = "196" y2 = "122" className = "stroke-muted-foreground/40" strokeWidth = "1" markerEnd = "url(#acl-arr)" />
214+
215+ < line x1 = "348" y1 = "122" x2 = "366" y2 = "122" className = "stroke-muted-foreground/35" strokeWidth = "1" />
216+ < line x1 = "366" y1 = "90" x2 = "366" y2 = "166" className = "stroke-muted-foreground/25" strokeWidth = "1" />
217+ < line x1 = "366" y1 = "90" x2 = "390" y2 = "90" className = "stroke-muted-foreground/35" strokeWidth = "1" markerEnd = "url(#acl-arr)" />
218+ < line x1 = "366" y1 = "166" x2 = "390" y2 = "166" className = "stroke-muted-foreground/35" strokeWidth = "1" markerEnd = "url(#acl-arr)" />
219+
220+ < line x1 = "522" y1 = "90" x2 = "540" y2 = "90" className = "stroke-accent/60" strokeWidth = "1" />
221+ < line x1 = "522" y1 = "180" x2 = "540" y2 = "180" className = "stroke-accent/60" strokeWidth = "1" />
222+ < line x1 = "540" y1 = "90" x2 = "540" y2 = "180" className = "stroke-accent/35" strokeWidth = "1" />
223+ < line x1 = "540" y1 = "122" x2 = "560" y2 = "122" className = "stroke-accent/60" strokeWidth = "1" markerEnd = "url(#acl-arr-a)" />
224+
225+ < line x1 = "560" y1 = "176" x2 = "672" y2 = "176" className = "stroke-muted-foreground/20" strokeWidth = "1" strokeDasharray = "4 3" />
226+ < text x = "616" y = "168" textAnchor = "middle" className = "fill-muted-foreground/45 text-[7px] font-mono" >
227+ { t ( "appendix.access.writeBlock" ) }
228+ </ text >
229+ </ svg >
230+ )
231+ }
232+
126233function ObservabilityDiagram ( ) {
127234 const { locale } = useI18n ( )
128235
@@ -147,13 +254,7 @@ function ObservabilityDiagram() {
147254 Tape
148255 </ text >
149256
150- < rect x = "548" y = "18" width = "122" height = "34" rx = "7" className = "fill-accent" />
151- < text x = "609" y = "40" textAnchor = "middle" className = "fill-accent-foreground text-[12px] font-mono font-semibold" >
152- Web UI
153- </ text >
154-
155257 < line x1 = "148" y1 = "35" x2 = "198" y2 = "35" className = "stroke-foreground" strokeWidth = "1.2" markerEnd = "url(#obs-arr)" />
156- < line x1 = "344" y1 = "35" x2 = "538" y2 = "35" className = "stroke-accent" strokeWidth = "1.2" markerEnd = "url(#obs-arr-a)" />
157258
158259 { [
159260 { x : 224 , y : 82 , label : locale === "zh" ? "anchor" : "anchor" , className : "fill-accent/12 stroke-accent" } ,
@@ -170,42 +271,41 @@ function ObservabilityDiagram() {
170271 ) ) }
171272
172273 < text x = "276" y = "70" textAnchor = "middle" className = "fill-muted-foreground/45 text-[9px] font-mono" >
173- { locale === "zh" ? "append-only trace " : "append-only trace " }
274+ { locale === "zh" ? "same append-only facts " : "same append-only facts " }
174275 </ text >
175276
176- < rect x = "420 " y = "88 " width = "92 " height = "96 " rx = "10 " className = "fill-secondary/35 stroke-border" strokeWidth = "1" />
177- < text x = "466 " y = "108 " textAnchor = "middle" className = "fill-muted-foreground text-[10px] font-mono font-semibold" >
178- { locale === "zh" ? "filters " : "filters " }
277+ < rect x = "378 " y = "78 " width = "128 " height = "106 " rx = "12 " className = "fill-secondary/35 stroke-border" strokeWidth = "1" />
278+ < text x = "442 " y = "100 " textAnchor = "middle" className = "fill-muted-foreground text-[10px] font-mono font-semibold" >
279+ { locale === "zh" ? "derived views " : "derived views " }
179280 </ text >
180- { [ "session " , "tool " , "event " ] . map ( ( item , index ) => (
281+ { [ "timeline " , "replay " , "qa context " ] . map ( ( item , index ) => (
181282 < g key = { item } >
182- < rect x = "435 " y = { 120 + index * 18 } width = "62 " height = "12 " rx = "4 " className = "fill-card stroke-border" strokeWidth = "0.8" />
183- < text x = "466 " y = { 129 + index * 18 } textAnchor = "middle" className = "fill-muted-foreground text-[7px] font-mono" >
283+ < rect x = "400 " y = { 114 + index * 20 } width = "84 " height = "14 " rx = "5 " className = "fill-card stroke-border" strokeWidth = "0.8" />
284+ < text x = "442 " y = { 123 + index * 20 } textAnchor = "middle" className = "fill-muted-foreground text-[7px] font-mono" >
184285 { item }
185286 </ text >
186287 </ g >
187288 ) ) }
188289
189- { [
190- { y : 86 , title : locale === "zh" ? "Timeline" : "Timeline" , detail : locale === "zh" ? "turn / tool / event" : "turn / tool / event" } ,
191- { y : 126 , title : locale === "zh" ? "Replay" : "Replay" , detail : locale === "zh" ? "inspect exact path" : "inspect exact path" } ,
192- { y : 166 , title : locale === "zh" ? "Usage" : "Usage" , detail : locale === "zh" ? "token + anchor stats" : "token + anchor stats" } ,
193- ] . map ( ( panel ) => (
194- < g key = { panel . title } >
195- < rect x = "556" y = { panel . y } width = "106" height = "28" rx = "6" className = "fill-accent/10 stroke-accent" strokeWidth = "1" / >
196- < text x = "568" y = { panel . y + 12 } className = "fill-accent text-[9px] font-mono font-semibold" >
197- { panel . title }
198- </ text >
199- < text x = "568" y = { panel . y + 21 } className = "fill-accent/60 text-[7px] font-mono" >
200- { panel . detail }
201- </ text >
202- </ g >
203- ) ) }
290+ < rect x = "548" y = "104" width = "108" height = "28" rx = "8" className = "fill-accent/12 stroke-accent" strokeWidth = "1" />
291+ < text x = "562" y = "116" className = "fill-accent text-[9px] font-mono font-semibold" >
292+ { locale === "zh" ? "Trace UI" : "Trace UI" }
293+ </ text >
294+ < text x = "562" y = "125" className = "fill-accent/65 text-[7px] font-mono" >
295+ { locale === "zh" ? "timeline / replay" : "timeline / replay" }
296+ </ text >
297+
298+ < rect x = "548" y = "144" width = "108" height = "28" rx = "8" className = "fill-secondary/40 stroke-border" strokeWidth = "1" />
299+ < text x = "562" y = "156" className = "fill-foreground text-[9px] font-mono font-semibold" >
300+ { locale === "zh" ? "Ask Bub" : "Ask Bub" }
301+ </ text >
302+ < text x = "562" y = "165" className = "fill-muted-foreground text-[7px] font-mono" >
303+ { locale === "zh" ? "inspect / explain" : "inspect / explain" }
304+ </ text >
204305
205- < line x1 = "328" y1 = "124" x2 = "420" y2 = "124" className = "stroke-muted-foreground/35" strokeWidth = "1" strokeDasharray = "4 3" markerEnd = "url(#obs-arr)" />
206- < line x1 = "512" y1 = "136" x2 = "556" y2 = "100" className = "stroke-accent/55" strokeWidth = "1" markerEnd = "url(#obs-arr-a)" />
207- < line x1 = "512" y1 = "148" x2 = "556" y2 = "140" className = "stroke-accent/55" strokeWidth = "1" markerEnd = "url(#obs-arr-a)" />
208- < line x1 = "512" y1 = "160" x2 = "556" y2 = "180" className = "stroke-accent/55" strokeWidth = "1" markerEnd = "url(#obs-arr-a)" />
306+ < line x1 = "328" y1 = "124" x2 = "378" y2 = "124" className = "stroke-muted-foreground/35" strokeWidth = "1" strokeDasharray = "4 3" markerEnd = "url(#obs-arr)" />
307+ < line x1 = "506" y1 = "126" x2 = "548" y2 = "118" className = "stroke-accent/55" strokeWidth = "1" markerEnd = "url(#obs-arr-a)" />
308+ < line x1 = "506" y1 = "146" x2 = "548" y2 = "158" className = "stroke-foreground/45" strokeWidth = "1" markerEnd = "url(#obs-arr)" />
209309 </ svg >
210310 )
211311}
0 commit comments