Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
05e1f98
Delete the unused served pages: sandbox, instrument labs, repo atlas,…
briansrls Oct 4, 2026
dd6b68f
Cut the /roadmap page and /ROADMAP.md from serving and from the surfa…
briansrls Oct 4, 2026
d81a91d
Typed media conditions in the CSS register: MediaRule over a cited Me…
briansrls Oct 5, 2026
905b037
Typed @font-face rule and the pinned google/fonts sources for Roboto …
briansrls Oct 5, 2026
9885c38
Serve vocabulary: an immutable cache header arm and the text/css and …
briansrls Oct 5, 2026
234c859
Self-hosted Roboto and Google Sans as one content-addressed styleshee…
briansrls Oct 5, 2026
97dbd10
Answer where an issue sits and what relates to it once, as typed view…
briansrls Oct 5, 2026
bc73f61
Model the measured Issue Tracker design language and derive one front…
briansrls Oct 5, 2026
93b9861
Give the displayed issue status a typed vocabulary
briansrls Oct 5, 2026
079edf6
Add the frontend tokens, the nine text roles and the first four elements
briansrls Oct 5, 2026
3120e53
Nest the chain breadcrumb root-outermost and pin the nesting order
briansrls Oct 5, 2026
7af03f4
Serve the element specimen at /specimen and guard the elements
briansrls Oct 5, 2026
d02c013
Merge ui/hierarchy-view into the foundations: one typed status
briansrls Oct 5, 2026
42b8677
Give the hierarchy view its count, empty, refusal and closed answers …
briansrls Oct 5, 2026
d82d4d4
Model the measured header chip, priority mark and relation table
briansrls Oct 5, 2026
b2d1b83
Add the hierarchy elements: Chip, PriorityMark, NodeRow, RelationTabl…
briansrls Oct 5, 2026
d21913b
Show the hierarchy elements on the specimen and guard them
briansrls Oct 5, 2026
db21c14
Give the breadcrumb nesting order its own claim
briansrls Oct 5, 2026
5bba389
Read closure, unmet prerequisites and omitted-node status from their …
briansrls Oct 5, 2026
739fed6
Add the BuildMeter element: a compact strip with a deadpan gunbai worker
briansrls Oct 5, 2026
18e74aa
Derive the build meter view from one attempt, and name it on the work…
briansrls Oct 5, 2026
3deca52
Show the build meter under the assignee for Fabric-held issues, and o…
briansrls Oct 5, 2026
f85798d
Witness the build meter: view derivation, element, rail inhabitance, …
briansrls Oct 5, 2026
e4cb527
State round coverage honestly: an empty stream is no round yet, a leg…
briansrls Oct 5, 2026
da4b880
Give the Work tab and its failure events one route spelling; move the…
briansrls Oct 5, 2026
dd7deaa
Make the BuildMeter a quiet visual link: no prose, a failure digest, …
briansrls Oct 5, 2026
f35d7db
Produce the compact work summary, its failure digest and a content-ha…
briansrls Oct 5, 2026
1e04a15
Place the producer's summary in the rail, anchor failure rows, guard …
briansrls Oct 5, 2026
d472828
Witness the compact work summary: coverage, digest, no prose, distinc…
briansrls Oct 5, 2026
53a217c
Keep the wire revision claim within its eval-step budget
briansrls Oct 5, 2026
e6fa5ae
FieldList element: the issue rail as one field list at one row pitch
briansrls Oct 5, 2026
ca646df
The meter's worker is the robot mark, derived from its numbers
briansrls Oct 5, 2026
fab92cc
PriorityMark is the one priority renderer, left-aligned at one geometry
briansrls Oct 5, 2026
0c746d5
Meter: typed operations preferred over proxies, producer-fed tool spe…
briansrls Oct 5, 2026
99c9959
Accepted and Withheld statuses; FieldList values disclose their full …
briansrls Oct 5, 2026
bcb8c76
Keep the rail inside the page: wrap the meter's hover digest, anchor …
briansrls Oct 5, 2026
1546ffa
FieldList labels stay on one line: one shared label column sized to t…
briansrls Oct 5, 2026
014cffb
Wrap the meter's hover digest at 24ch so it stays inside the page bes…
briansrls Oct 5, 2026
f254777
FieldList label column is the fixed measured maximum, so values start…
briansrls Oct 5, 2026
a03510b
Adapt the frontend to main: ts_if's then_stmt and the typed attempt s…
briansrls Oct 6, 2026
e2aa49c
Fonts through the tokens: Title and Control set Google Sans, every ot…
briansrls Oct 6, 2026
b38fe3f
Touch targets: every interactive element takes 40px under a coarse po…
briansrls Oct 6, 2026
051f0f8
Waiting for a seat is a nap in a waiting room; the published worker n…
briansrls Oct 6, 2026
82cb018
chore: regenerate drifted generated artifacts (ci auto-heal)
gunbai-bot[bot] Oct 6, 2026
7210e73
Specimen sections come from the element identity, checked one section…
briansrls Oct 6, 2026
0fc4096
Split the frontend's conjunctions so every new claim stays well under…
briansrls Oct 6, 2026
f557022
Font byte witnesses: size by base64 length, decode inhabitance on a p…
briansrls Oct 6, 2026
106c0d5
The meter settles on a scene before drawing it, and changes scene by …
briansrls Oct 6, 2026
f975042
Specimen: the meter's changes of scene, playable
briansrls Oct 6, 2026
2581169
Merge remote-tracking branch 'origin/main' into own/ui-visual-overhaul
Oct 7, 2026
fb2a813
Merge remote-tracking branch 'origin/ui/visual-overhaul' into own/ui-…
Oct 7, 2026
22c58b3
Provision the roadmap event worktree in the dashboard instance plan
Oct 7, 2026
c5adb4b
Supply the launch standing to the issue-query surface claim from #13476
Oct 8, 2026
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
355 changes: 331 additions & 24 deletions dag/extdeps/google/issue_tracker.dag

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions dag/extdeps/languages/css/properties.dag
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type CssPropertyName
| BorderStyle
| BoxShadow
| BoxSizing
| ClipPath
| Color
| ColorScheme
| Cursor
Expand All @@ -53,6 +54,7 @@ type CssPropertyName
| FontVariantNumeric
| FontWeight
| Gap
| GridArea
| GridColumn
| GridTemplateColumns
| Height
Expand Down Expand Up @@ -105,6 +107,7 @@ fn css_property_wire(p: CssPropertyName) -> String {
BorderStyle => "border-style"
BoxShadow => "box-shadow"
BoxSizing => "box-sizing"
ClipPath => "clip-path"
Color => "color"
ColorScheme => "color-scheme"
Cursor => "cursor"
Expand All @@ -119,6 +122,7 @@ fn css_property_wire(p: CssPropertyName) -> String {
FontVariantNumeric => "font-variant-numeric"
FontWeight => "font-weight"
Gap => "gap"
GridArea => "grid-area"
GridColumn => "grid-column"
GridTemplateColumns => "grid-template-columns"
Height => "height"
Expand Down
14 changes: 10 additions & 4 deletions dag/gunbc/design/scale.dag
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
module gunbc.design.scale

import std.types { Int, String, Bool }
import std.types { Int, String, Bool, List }
import gunbc.design.material { CssDecl, decl, css_block }
import extdeps.languages.css.values {
CssLength, css_ch, css_px, css_length_wire,
CssFontStack, CssFontFamily, NamedFamily, GenericFamily,
CssGenericFamily, GenericSansSerif, GenericMonospace, GenericSystemUi,
css_font_stack_wire,
}
import extdeps.fonts.google_fonts { roboto_source }

// Layer 2 token axes (design-register-library.md, the sibling axes to material/theme): spacing,
// type, font stack, plus the dimension tokens (radius, border width, measure, fixed element
Expand Down Expand Up @@ -110,11 +111,16 @@ data type_scale: List<ScaleToken> = [
text_10, text_11, text_12, text_13, text_14, text_15, text_18, text_24,
]

data font_sans: ScaleToken = font_token(name: "font-sans", families: [
NamedFamily { name: "Roboto" },
// The body stack. Its first family is the self-hosted Roboto face (ruling R2; gunbc.site.web_fonts
// serves it), named by the same upstream source row the served @font-face rule names
// (extdeps.fonts.google_fonts roboto_source), so this token cannot ask for a family the stylesheet
// does not declare. The fallbacks are the product's measured stack.
data font_sans_families: List<CssFontFamily> = [
NamedFamily { name: roboto_source.family },
NamedFamily { name: "Arial" },
GenericFamily { kind: GenericSansSerif },
])
]
data font_sans: ScaleToken = font_token(name: "font-sans", families: font_sans_families)
data font_mono: ScaleToken = font_token(name: "font-mono", families: [
NamedFamily { name: "JetBrains Mono" },
GenericFamily { kind: GenericMonospace },
Expand Down
38 changes: 28 additions & 10 deletions dag/gunbc/harness/harness_throughput.dag
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@ fn ledger_read_line(line: String) -> LineRead {
// FIRST GAP WINS, IN STREAM ORDER, and it decides for the whole ledger before any row is kept --
// the fail-closed half of the same fold. A ledger missing the rows it could not read is a shorter
// run that looks complete.
//
// A READ STREAM WITH NO ROUND ROW IS AN OBSERVATION OF NO ROUND, NOT A GAP. It used to answer
// RoundsUnobserved, which made an attempt whose agent has not finished its first round look the
// same as one whose rounds were never captured. Whether a stream was captured at all is the
// caller's fact (gunbc.roadmap_workflow_progress reads the events only of a modeled attempt with a
// readable stream), so this reader states only what the stream it was given holds.
fn harness_round_ledger_from_events(body: String) -> HarnessRoundLedger {
let reads = map(split(s: body, delimiter: "\n"), l => ledger_read_line(line: l))
match fold(reads, init: none, f: (acc, r) =>
Expand All @@ -293,11 +299,7 @@ fn harness_round_ledger_from_events(body: String) -> HarnessRoundLedger {
LineIsNotOurs => []
LineIsGap { cause: _ } => []
})
if list_length(items: rows) == 0 {
RoundsUnobserved { reason: "no clocked round.usage row in the event stream" as NonEmptyStr }
} else {
RoundsObserved { rounds: rows }
}
RoundsObserved { rounds: rows }
}
}
}
Expand All @@ -316,7 +318,9 @@ fn harness_throughput_from_ledger(ledger: HarnessRoundLedger) -> HarnessThroughp
match ledger {
RoundsUnobserved { reason: r } => ThroughputUnobserved { reason: r }
RoundsObserved { rounds: rs } =>
if list_length(items: rs) < 2 {
if list_length(items: rs) == 0 {
ThroughputUnobserved { reason: "no clocked round yet" as NonEmptyStr }
} else if list_length(items: rs) < 2 {
ThroughputUnobserved { reason: "one clocked round so far; an interval needs two" as NonEmptyStr }
} else {
let first = rs.first()
Expand Down Expand Up @@ -389,17 +393,31 @@ type SegmentFold {
segments: List<RoundSegment>
}

fn round_segment_kind(now: Int?, last_measured: Int?, tool_calls: Int?) -> RoundSegmentKind {
// HOW FAR THE WORKTREE'S CHANGED-PATH COUNT ROSE OVER THE LAST MEASURED VALUE. It is an
// observation of the tree, not a count of writes: it is the one statement of "kind is a delta"
// above, read by the strip's kind below and by the build meter's changed-path marks
// (gunbc.roadmap.roadmap_build_meter), so the two cannot disagree about which rounds changed the
// tree. An unread count has no rise; a first measurement rises from an unmeasured tree, which is
// a fresh worktree with nothing changed. The result may be zero or negative (a commit lowers the
// count); only a positive rise is drawn.
fn round_changed_path_count_rise(now: Int?, last_measured: Int?) -> Int? {
match now {
Absent => UnmeasuredRound
Absent => none
Present { value: n } =>
match last_measured {
Absent => if n > 0 { WriteRound } else { round_segment_kind_unwritten(tool_calls: tool_calls) }
Present { value: m } => if n > m { WriteRound } else { round_segment_kind_unwritten(tool_calls: tool_calls) }
Absent => Present { value: n }
Present { value: m } => Present { value: n - m }
}
}
}

fn round_segment_kind(now: Int?, last_measured: Int?, tool_calls: Int?) -> RoundSegmentKind {
match round_changed_path_count_rise(now: now, last_measured: last_measured) {
Absent => UnmeasuredRound
Present { value: rise } => if rise > 0 { WriteRound } else { round_segment_kind_unwritten(tool_calls: tool_calls) }
}
}

fn round_segment_kind_unwritten(tool_calls: Int?) -> RoundSegmentKind {
match tool_calls {
Absent => ReadRound
Expand Down
11 changes: 11 additions & 0 deletions dag/gunbc/roadmap/roadmap_belt_actuate.dag
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,8 @@ import gunbc.roadmap_session_placement {
import gunbc.roadmap_workflow_command {
WorkflowModeledStateStanding, WorkflowModeledStateObserved, WorkflowModeledStateAbsent, WorkflowModeledStateUnreadable,
}
import gunbc.roadmap.roadmap_build_meter { attempt_view_revision }
import gunbc.site.element.build_meter { build_meter_wire_revision_member }
import gunbc.roadmap_workflow_progress {
AttemptWorktreeObservation, AttemptWorktreePresent, AttemptWorktreeAbsent, AttemptWorktreeUnobserved, attempt_worktree_observation_of,
WorkflowAttemptEvidence,
Expand Down Expand Up @@ -9290,6 +9292,9 @@ fn belt_workflow_attempts_observe_scoped(
}
}

// The 'attempt_view_revision' member names the compact work view that is current for this
// attempt (gunbc.roadmap.roadmap_build_meter attempt_view_revision), for a page that already shows
// it. Its staleness is the caller's revision comparison; a caller that made none passes none.
// The wire join of the two authorities the client must never re-derive: the attempt's progress
// members (gunbc.roadmap_workflow_progress, unchanged) plus the DECIDED activity view
// (gunbc.roadmap_presentation) appended as one 'activity' member. The seam reads process and
Expand Down Expand Up @@ -9320,12 +9325,14 @@ fn belt_workflow_attempt_presentation_json_for_instance(
fn belt_workflow_attempt_presentation_json_with_tick_read(
progress: WorkflowAttemptProgress,
tick_read: BeltTickReceiptRead,
stale_nodes: List<String> = [],
) -> JsonValue {
json_object(members: concat(
workflow_attempt_progress_json_members(progress: progress),
[
json_kv(key: "activity", value: activity_view_json_value(
view: activity_view_from_progress(progress: progress))),
json_kv(key: build_meter_wire_revision_member, value: json_string(s: attempt_view_revision(progress: progress, stale: any(stale_nodes, n => n == progress.node_id)))),
json_kv(
key: "verification_presentation",
value: json_string(
Expand Down Expand Up @@ -9371,6 +9378,7 @@ fn belt_tick_receipt_wire_json_for_instance(
fn belt_workflow_attempts_json_value_for_instance(
instance: HostDashboardInstance,
observed: BeltWorkflowAttempts,
stale_nodes: List<String> = [],
) -> JsonValue {
let tick_read = belt_tick_receipt_read_for_instance(instance: instance)
match observed {
Expand All @@ -9392,6 +9400,7 @@ fn belt_workflow_attempts_json_value_for_instance(
progress => belt_workflow_attempt_presentation_json_with_tick_read(
progress: progress,
tick_read: tick_read,
stale_nodes: stale_nodes,
),
)),
),
Expand All @@ -9412,10 +9421,12 @@ fn belt_workflow_attempts_json_value(
fn belt_workflow_attempts_observed_json_for_instance(
instance: HostDashboardInstance,
observed: BeltWorkflowAttempts,
stale_nodes: List<String> = [],
) -> String {
serialize_json(v: belt_workflow_attempts_json_value_for_instance(
instance: instance,
observed: observed,
stale_nodes: stale_nodes,
))
}

Expand Down
Loading
Loading