Skip to content
Merged
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
8 changes: 6 additions & 2 deletions docs/SITH-NOTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -2553,15 +2553,19 @@ where trustworthy denominators exist, abstention rates, and PDP latency.

**How it works.**
1. The hub exposes metrics for scraping (control-plane health, DB, queue depths).
2. Federation metrics track per-spoke read freshness and dispatch success.
2. Federation metrics use only closed, bounded `outcome` label values for request-time fleet-read
results (`complete|degraded|empty|error`), freshness
(`fresh|stale|unknown|empty|error`), and spoke-snapshot attempts
(`success|transport|deadline|invalid-snapshot|store-error|canceled`). They expose no workspace,
spoke, endpoint, actor, trace, or other identity labels.
3. Governance metrics track intents proposed/allowed/denied, abstention rate, and approval
latency.
4. These describe Sith itself; Sith does not retain other systems' metric series.

```mermaid
flowchart TD
A["Sith hub"] --> B["Control-plane metrics: liveness, DB, queues"]
A --> C["Federation metrics: per-spoke freshness, dispatch success"]
A --> C["Federation metrics: aggregate request-time result/freshness + spoke-attempt outcomes"]
A --> D["Governance metrics: intents allowed/denied, abstention rate, approval latency"]
B --> E["Exposed for scraping (about Sith itself)"]
C --> E
Expand Down
2 changes: 1 addition & 1 deletion docs/specs/E2-readfed-brain-integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ the *reasoning*. Decision deferred to the owner (see §7).
| Connector | Kind | Verbs | Lenses | Tier | Mode | Notes |
|---|---|---|---|---|---|---|
| **Kubernetes** (core) | RA + TA | di, rd, qy, df, (pl/ex/vf via actions) | LIVE, TIMELINE (Events/RS history), DESIRED (last-applied), GRAPH | **T0** | both | The substrate — this *is* F2.1/F11.1. Feeds every rule. |
| **GitHub** | RA + TA | di, rd, qy, df, **pl/ex** (`gitops.open-pr`), vf | DESIRED (manifests), TIMELINE (commits/PR/deploys) | **T1** | read=local, write=hub | Bounded pure projectors now normalize caller-fetched merged-PR and completed workflow-run failure evidence; the HTTP/token reader remains future. `gitops.open-pr` is the first governed write (P2). |
| **GitHub** | RA + planned TA (P2) | di, rd, qy, df; planned P2: **pl/ex** (`gitops.open-pr`), vf | DESIRED (manifests), TIMELINE (commits/PR/deploys) | **T1** | read=local, write=planned hub | Bounded pure projectors normalize caller-fetched merged-PR and completed workflow-run failure evidence; the HTTP/token reader remains future. `GitSourceSnapshot` and `DesiredChange` are separate pure contracts with no Brain/PEP/Hub execution wiring. Governed `gitops.open-pr` remains planned for P2, and GitHub-derived R2/R4 remediation evidence stays advisory-only. |
| **ArgoCD** | RA + BR + TA | di, rd, qy, **df**, pl/ex (`argocd.sync`,`argocd.rollback`), vf | DESIRED, LIVE, TIMELINE (sync history), drift | **T1** | read=local, sync=hub | Richest single connector — 3 lenses + the exemplar of the `diff` verb. Central to R1, R4. Application CRDs read via kubeconfig. |
| **Prometheus** | RA + query-through | di, **qy**, rd (alerts) | TELEMETRY | **T1** | local-if-reachable / hub | Query-through, not retained. Central to R2, R5, R6 and R1 validation. |
| **Elasticsearch** | RA + query-through | di, **qy** | TELEMETRY (logs) | **T2** | hub (local if creds) | Bounded sanitized `search/ecs-v1` cause facts now bridge into R3; HTTP/auth/index/query execution remains future. Auth/index-mapping variance → T2. |
Expand Down
4 changes: 3 additions & 1 deletion internal/connector/argocd/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ func projectChanges(status map[string]any) ([]projectedChange, error) {
history = history[len(history)-maxApplicationHistory:]
truncated = true
}
historyTruncationPending := truncated
for index, raw := range history {
entry, ok := raw.(map[string]any)
if !ok {
Expand All @@ -360,10 +361,11 @@ func projectChanges(status map[string]any) ([]projectedChange, error) {
changes = append(changes, projectedChange{
observation: changeObservation{
ChangeKind: "argocd-sync", Revision: revision, EventAt: at, HistoryID: id,
HistoryTruncated: truncated && index == 0,
HistoryTruncated: historyTruncationPending,
},
nativeID: "history/" + stableChangeID(id, revision, at),
})
historyTruncationPending = false
}

operation, operationPresent, err := optionalMap(status, "operationState")
Expand Down
37 changes: 37 additions & 0 deletions internal/connector/argocd/project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,43 @@ func TestProjectApplicationBoundsHistoryAndMarksTruncation(t *testing.T) {
}
}

func TestProjectApplicationMarksTruncationOnFirstEmittedHistory(t *testing.T) {
t.Parallel()
application := minimalApplication()
history := make([]any, maxApplicationHistory+1)
for index := range history {
entry := map[string]any{
"id": int64(index), "revision": fmt.Sprintf("revision-%02d", index),
"deployedAt": time.Date(2026, 7, 1, 0, index, 0, 0, time.UTC).Format(time.RFC3339),
}
if index == 1 {
delete(entry, "deployedAt")
}
history[index] = entry
}
application.Object["status"] = map[string]any{"history": history}

facts, err := ProjectApplication(Projection{
Workspace: "workspace-a", Scope: "cluster-a", ObservedAt: time.Now(), Application: application,
})
if err != nil {
t.Fatalf("ProjectApplication() error = %v", err)
}
if len(facts) < 3 {
t.Fatalf("fact count = %d, want desired plus at least two emitted history facts", len(facts))
}
var first, second changeObservation
if err := json.Unmarshal(facts[1].Fact.Observed, &first); err != nil {
t.Fatalf("decode first emitted history: %v", err)
}
if err := json.Unmarshal(facts[2].Fact.Observed, &second); err != nil {
t.Fatalf("decode second emitted history: %v", err)
}
if first.HistoryID != "2" || !first.HistoryTruncated || second.HistoryTruncated {
t.Fatalf("first/second emitted history = %#v / %#v", first, second)
}
}

func TestProjectApplicationRejectsMalformedOrAmbiguousEvidence(t *testing.T) {
t.Parallel()
valid := Projection{Workspace: "workspace-a", Scope: "cluster-a", ObservedAt: time.Now(), Application: completeApplication()}
Expand Down
26 changes: 14 additions & 12 deletions internal/hubserver/console_assets/console.css
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ select:focus-visible {
.workspace-stamp dd,
.rail-legend,
.cluster-sequence {
font-family: "SFMono-Regular", Consolas, monospace;
font-family: SFMono-Regular, Consolas, monospace;
font-size: 0.72rem;
letter-spacing: 0.08em;
text-transform: uppercase;
Expand Down Expand Up @@ -232,7 +232,7 @@ h2 {

.inventory-form label span {
color: #c9d5dc;
font-family: "SFMono-Regular", Consolas, monospace;
font-family: SFMono-Regular, Consolas, monospace;
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.06em;
Expand Down Expand Up @@ -343,7 +343,7 @@ h2 {
.inventory-metrics dd,
.inventory-freshness {
margin: 0;
font-family: "SFMono-Regular", Consolas, monospace;
font-family: SFMono-Regular, Consolas, monospace;
font-size: 0.72rem;
letter-spacing: 0.05em;
text-transform: uppercase;
Expand Down Expand Up @@ -375,7 +375,7 @@ h2 {
.correlation-form label span,
.cve-form label span,
.match-freshness {
font-family: "SFMono-Regular", Consolas, monospace;
font-family: SFMono-Regular, Consolas, monospace;
font-size: 0.72rem;
letter-spacing: 0.06em;
text-transform: uppercase;
Expand Down Expand Up @@ -486,17 +486,17 @@ h2 {
.digest-address {
margin: 0.2rem 0 0;
color: #46535f;
font-family: "SFMono-Regular", Consolas, monospace;
font-family: SFMono-Regular, Consolas, monospace;
font-size: 0.72rem;
overflow-wrap: anywhere;
}

.severity-badge {
min-width: 6.5rem;
padding: 0.45rem 0.65rem;
border: 1px solid currentColor;
border: 1px solid currentcolor;
color: #46535f;
font-family: "SFMono-Regular", Consolas, monospace;
font-family: SFMono-Regular, Consolas, monospace;
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.06em;
Expand Down Expand Up @@ -589,6 +589,8 @@ h2 {
border: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip-path: inset(50%) !important;
/* stylelint-disable-next-line property-no-deprecated -- compatible fallback for screen-reader-only content */
clip: rect(0 0 0 0) !important;
white-space: nowrap !important;
}
Expand Down Expand Up @@ -635,9 +637,9 @@ h2 {
.health-badge {
min-width: 7.5rem;
padding: 0.45rem 0.65rem;
border: 1px solid currentColor;
border: 1px solid currentcolor;
color: #8f321f;
font-family: "SFMono-Regular", Consolas, monospace;
font-family: SFMono-Regular, Consolas, monospace;
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.06em;
Expand Down Expand Up @@ -717,7 +719,7 @@ h2 {
padding: 1rem 1rem 1rem 2.25rem;
border-left: 0.35rem solid var(--amber);
background: rgba(247, 250, 251, 0.78);
font-family: "SFMono-Regular", Consolas, monospace;
font-family: SFMono-Regular, Consolas, monospace;
font-size: 0.78rem;
line-height: 1.45;
}
Expand Down Expand Up @@ -812,10 +814,10 @@ h2 {
.state-badge {
min-width: 7.5rem;
padding: 0.45rem 0.65rem;
border: 1px solid currentColor;
border: 1px solid currentcolor;
color: var(--oxide);
background: transparent;
font-family: "SFMono-Regular", Consolas, monospace;
font-family: SFMono-Regular, Consolas, monospace;
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.06em;
Expand Down
2 changes: 1 addition & 1 deletion sessions/2026-07-15-e10-loopback-metrics.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Session — 2026-07-15 — e10-loopback-metrics

**Builder:** Gnani Rahul Nutakki · **Model/effort:** autonomous · **Branch:** gnanirahulnutakki/feat/e10-loopback-metrics
**Slice(s):** E10 F10.1b / #177 · **Status:** in-progress
**Slice(s):** E10 F10.1b / #177 · **Status:** done

---

Expand Down
2 changes: 1 addition & 1 deletion sessions/2026-07-15-e10-process-audit-sink.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Session — 2026-07-15 — e10-process-audit-sink

**Builder:** Gnani Rahul Nutakki · **Model/effort:** autonomous · **Branch:** gnanirahulnutakki/feat/e10-process-audit-sink
**Slice(s):** E10 F10.3b / #140 · **Status:** in-progress
**Slice(s):** E10 F10.3b / #140 · **Status:** done

---

Expand Down
2 changes: 1 addition & 1 deletion sessions/2026-07-15-e8-browser-oidc-session.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Session — 2026-07-15 — e8-browser-oidc-session

**Builder:** gnanirahulnutakki · **Branch:** gnanirahulnutakki/feat/e8-browser-oidc-session
**Slice(s):** E8 F8.1a · #175 · **Status:** in-progress
**Slice(s):** E8 F8.1a · #175 · **Status:** done

---

Expand Down
4 changes: 2 additions & 2 deletions sessions/2026-07-16-brain-image-evidence.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ Require fresh, cited, deterministic image repo-digest evidence before Sith emits
- Stale digest rejection, cited correlation, duplicate selection, full input-order reversal, and canonical source-reference tie-break coverage.
- `make ci`
- `make e2e-isolation`
- `make e2e-kind KIND=/Volumes/EXTENDED/MacData/tools/bin/kind`
- `GOPATH=/Volumes/EXTENDED/MacData/go make release-check GORELEASER=/Volumes/EXTENDED/MacData/tools/bin/goreleaser`
- `make e2e-kind`
- `make release-check`

## Review

Expand Down
8 changes: 4 additions & 4 deletions sessions/2026-07-16-fleetcache-workspace-scope.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ Keep discovery metadata for identically named cluster scopes isolated by workspa
## Tests

- `go test -race -count=1 ./internal/fleetcache`
- `PATH=/Users/nutakki/.local/bin:/Volumes/EXTENDED/MacData/tools/bin:/opt/homebrew/bin:/usr/bin:/bin GOPATH=/Volumes/EXTENDED/MacData/go make ci`
- `PATH=/Users/nutakki/.local/bin:/Volumes/EXTENDED/MacData/tools/bin:/opt/homebrew/bin:/usr/bin:/bin GOPATH=/Volumes/EXTENDED/MacData/go make e2e-isolation`
- `PATH=/Users/nutakki/.local/bin:/Volumes/EXTENDED/MacData/tools/bin:/opt/homebrew/bin:/usr/bin:/bin GOPATH=/Volumes/EXTENDED/MacData/go make e2e-kind KIND=/Volumes/EXTENDED/MacData/tools/bin/kind`
- `PATH=/Users/nutakki/.local/bin:/Volumes/EXTENDED/MacData/tools/bin:/opt/homebrew/bin:/usr/bin:/bin GOPATH=/Volumes/EXTENDED/MacData/go make release-check GORELEASER=/Volumes/EXTENDED/MacData/tools/bin/goreleaser`
- `make ci`
- `make e2e-isolation`
- `make e2e-kind`
- `make release-check`

## Review

Expand Down
3 changes: 2 additions & 1 deletion sessions/2026-07-21-deep-quality-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ boundaries.
audit-hash fuzz-oracle correctness, and lifecycle ownership for coalesced spoke refreshes.
- Release-policy drift, dependency/toolchain updates, desktop-build version drift, approval expiry,
and remaining open-issue slices stay separate so each can be reviewed and reverted independently.
- No credential, authorization, schema, cloud resource, external package, or API surface changes.
- No credential, authorization, schema, cloud resource, external package, or externally visible API
surface changes. The collector lifecycle context change below is limited to `internal/hubfleet`.

## [A] Action

Expand Down
19 changes: 19 additions & 0 deletions sessions/2026-07-23-beta5-review-remediation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Session — 2026-07-23 — beta5-review-remediation

**Builder:** Gnani Rahul Nutakki · **Model/effort:** autonomous · **Branch:** gnanirahulnutakki/fix/release-review-findings
**Slice(s):** v0.3.0-beta.5 release review / #318 · **Status:** done

---

[G] Goal: Resolve every valid aggregate-review finding from release promotion PR #317 before cutting v0.3.0-beta.5 (#318).
[S] Scope: Argo CD history projection, release-facing feature and metric descriptions, console CSS compatibility, and stale session metadata. No credentials, external API, dependency, schema, cloud-resource, package-visibility, cluster-write, or R2/R4 execution changes.
[A] Action: Preserve Argo CD truncation evidence on the first emitted retained history entry; add regression coverage; align GitHub GitOps and federation-metric documentation with implemented boundaries; normalize console CSS; close stale journals; remove developer-local paths; clarify the internal-only API change.
[T] Test: `go mod verify`; focused Argo CD race test repeated 100 times; `make ci`; `make e2e-isolation`; `make release-check`; `make e2e-kind`; `git diff --check`. All passed. The Kubernetes gate used ephemeral two-cluster fixtures and left no kind clusters behind.
[C] Checkpoint #1: this commit — all seven aggregate-review findings remediated and locally release-gated; next: require green PR review and CI into `dev`, promote the fix to `main`, then resume the separately approval-gated package-visibility and beta-tag steps.
[A] Action: Verified and resolved two PR #319 follow-up wording findings: federation metrics now name the single closed `outcome` dimension without implying zero labels, and the advisory-only restriction is scoped to GitHub-derived R2/R4 remediation evidence.
[T] Test: `git diff --check`; full race suite; exact-tree `make ci`, including current vulnerability data, policy tests, Prometheus rule validation, integration tests, and build. All passed. Two earlier `make ci` attempts failed closed at the vulnerability-database fetch during a transient DNS outage and made no repository changes.
[C] Checkpoint #2: this commit — both follow-up findings resolved without changing write authority or diagnostic confidence from non-GitHub evidence; next: require fresh PR review and CI on this commit before merge.

---

**Session close:** release-review remediation complete locally; publication evidence remains external · **Open questions touched:** none; R2/R4 remain advisory-only