🌱 sync: forward-port v4 (v4.12.5…v4.14.1) into v5 - #6046
Conversation
Move legacy/v2 hub session-cookie minting and telemetry helpers into test-only code so production binaries no longer compile the forgery-capable HMAC lane while rejection tests keep their fixtures.\n\nFixes #5812\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit 8e4d93e) Signed-off-by: Andy Anderson <andy@clubanderson.com>
Fixes #5803 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Strip inbound X-Hive identity headers before dispatching public routes, and only restore hub identity when X-Hive-Proxy-Auth proves the trusted proxy path. Add regression tests for forged contributor controls and self-service impersonation paths. Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…fail-closed path (#5826) reconcileNetAdmin (pkg/hub/netadmin_reconcile.go) was 18.4% covered: the kubectl get/patch remediation, unreachable-breaker arming, suppressed and unresolvable cluster skips, and the empty-selection warn branch were all untested. This is the sweep that once shipped as silent dead code (#2674), so the selection/remediation paths are pinned with a scripted fake kubectl on PATH (established pkg/hub test pattern) against saasHivesDir fixtures. reconcileNetAdmin is now 100% covered. lookupGitHubInstallationAccount (pkg/hub/gh_setup.go) was 22.2% covered: the real (non-hook) path's fail-closed missing-App-key branch was untested, as was the router degrading to the friendly page when the lookup fails. Signed-off-by: sec-check <sec-check@hive.kubestellar.io> Co-authored-by: sec-check <sec-check@hive.kubestellar.io> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
) src/pkg/dashboard/branding.go has always honoured two operator-facing env overrides, and neither appeared in env-vars.md or branding.md. env-vars.md's parity guard is one-directional, so the omission never failed CI. Adds both rows to the core runtime table with the real lookup chain, and an "Overriding the paths" section to branding.md covering the part that surprises people: HIVE_BRANDING_JSON defaults to branding.json beside the *resolved* CSS path, so setting only HIVE_BRANDING_CSS silently relocates the strings file too. The section is explicit about what the code does not do. handleBrandingCSS reads the resolved path with no ownership, mode, or size check; the default directory sits on the same volume as agents_dir, so an agent-writable /data is a CSS-injection path into the operator dashboard, and with img-src 'self' data: https: in force a stylesheet can beacon out. Documented as operator responsibilities rather than implied safety, with a read-only Secret-mounted example that keeps the path operator-owned. Also records why branding and CSP are coupled: setting `mark` rewrites bytes inside an inline script (the flyer's 🐝 entity), which is why Start() feeds the served document to setBrandedIndex and script-src-elem hashes are computed over served rather than embedded bytes. Fixes #5807 Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Fixes #5822 Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Route trusted v4 CI jobs to the repository self-hosted runner pool while keeping fork pull requests and risky privileged lanes on hosted runners. Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* 🐛 bug fix: stop hosted-spoke provisioning leaking namespaces, and report the ones already leaked A console Live Promote canary found 76 stuck pods — 64 Unschedulable and 12 Pending on unbound PVCs — spread across dozens of leaked `hive-hosted-hosted-*` namespaces on one CI cluster (#5768). Those are hosted-spoke provisioning namespaces that were created and never torn down. They hold quota and PVCs on a shared cluster and put permanent noise into every health surface that reads pod issues. Two independent things let that accumulate. PRODUCTION. provisionHive renders the whole spoke into one manifest and applies it with a single `kubectl apply -f`. The Namespace is necessarily the first object — every other object is namespaced into it — so when the apply fails partway (a rejected Deployment, a missing StorageClass, an exhausted quota) the namespace has already been created and kubectl rolls nothing back. provisionHive returns an error, the caller marks the hive record "error", and the namespace stays forever with whatever partial objects preceded the failure. provisionHive now records whether the namespace existed immediately BEFORE the apply, via `get namespace --ignore-not-found` so that "absent" and "could not tell" stay distinguishable, and deletes it on failure in exactly one case: it was absent beforehand. A pre-existing namespace is left alone — deleting it would cascade to a live spoke's pods and PVCs — and so is one whose pre-check failed, because "could not tell" must never be resolved into a destructive verb. The rollback is best-effort and never changes the error the admin sees. DETECTION. Every hub-side sweep over hosted namespaces derives its namespace list FROM the hive registry — reapOrphanedPods walks listSaaSHives() and calls hostedNamespaceForHive on each — which is what confines those sweeps to namespaces the hub provisioned, and which makes a namespace with no registry entry invisible to them by construction. The stuck-pod signal could not see these either: its predicate requires a deletionTimestamp, and these pods were never asked to terminate. Per-cluster health gains `leaked_namespaces`: hive-hosted-* namespaces the cluster holds that no hive record accounts for, older than six hours, oldest first, carrying the hive-id label when one was stamped (its absence is itself diagnostic — the stamp only happens after a successful apply). It is strictly READ-ONLY. A janitor that reclaims these is deliberately not in this change: a namespace delete is the widest destructive verb the hub owns, and the rule that would drive it has never been measured against a real cluster. This report is that measurement. The load-bearing safety property is the registry-empty guard. listSaaSHives() returns nil both when the hub genuinely hosts nothing and when it cannot read the hive directory at all. Under an empty known set every hosted namespace in the fleet satisfies "has no registry entry", so without the guard one transient disk error would report the entire fleet as leaked — and would hand any future janitor a delete list containing every live spoke. Collection therefore reports UNKNOWN, loudly, rather than a report, when the known set is empty; the same nil-means-unknown contract StuckPods already follows for an unreachable cluster. The known set is built once per health build from the union of the on-disk hive records and the in-memory registry, and matched fleet-wide rather than per-cluster, so a hive whose ClusterID is stale cannot be convicted of being a leak. Tests assert counts and executed commands, not field presence: the predicate is exercised against a population whose leak count is known by construction and seeded with every shape a looser rule would wrongly convict (registry-known, Terminating, inside the age window, exactly at the boundary, unreadable timestamp, not a hive namespace), and the rollback is asserted against a recording fake kubectl — the harm being guarded against is an executed delete, not a returned bool. Signed-off-by: Danathar <doug.baggett@gmail.com> * 🐛 bug fix: avoid false leaked namespace reports Skip leaked-namespace reporting whenever the durable SaaS hive record scan fails, even if the in-memory registry still has entries. Otherwise a partial known set can report live hosted namespaces as leaked. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> --------- Signed-off-by: Danathar <doug.baggett@gmail.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Danathar <doug.baggett@gmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve display labels for pending access requests and provision decision attribution while preserving raw identity keys for auth actions. Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move the same-repository Go test shards and SUID runtime contract lanes onto the self-hosted runner pool while preserving hosted fallback for forks. Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* 🌱 ci: run v2 CI and backend-smoke on self-hosted runners Push/schedule/dispatch-only lanes; no fork exposure. Relieves the hosted-runner queue by moving the heaviest recurring jobs to the fleet. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🌱 ci: keep image-heavy jobs hosted; ensure PyYAML on fleet docker/overlayfs-exec-guard revert to ubuntu-latest (Docker Hub 429 via shared cluster egress); build-and-test installs PyYAML when missing; fragment renamed to a valid category. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🌱 ci: runner image has no pip3 — bootstrap via ensurepip Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🌱 ci: PyYAML bootstrap via apt with get-pip fallback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🐛 test: model masked selinuxfs in podman host preflight test The host-preflight test only modeled two SELinux states (readable enforce, absent selinuxfs). On container runners atop SELinux hosts, /sys/fs/selinux is mounted but enforce is unreadable — the script correctly reports 'could not be determined'; the test now asserts that instead of failing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> --------- Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep fleet pending access-request panels expanded across periodic row re-renders by remembering expanded hive ids and reapplying the state as rows are rebuilt. Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…5866) * 🌱 ci: path-filter podman lanes and quadlet gate to src/deploy changes These lanes probe the published image plus repo deploy scripts; they do not build PR Go code, so PRs that don't touch src/deploy, the justfile, or the lane workflow itself gain nothing from running them. Filtering cuts ~4 hosted-runner runs per PR during queue starvation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🌱 ci: rename changelog fragment to PR number Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🌱 ci: fix changelog fragment name format Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🌱 ci: fragment must be a '- ' bullet entry Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> --------- Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* migrate: point GHCR image identity at ghcr.io/hivecommons Fleet-migration lockstep change (kubestellar -> hivecommons org transfer, merges only after transfer day): every runtime GHCR literal for the spoke, hub, and contributor images now names ghcr.io/hivecommons/... — the ghcrRepoSpoke/ghcrRepoHub constants, the branch-switch and self-patch image strings, the embedded provisioning Deployment templates, the bulk repo constant, the dashboard GHCR token/manifest probes, the GHCR tag-list poller, the Justfile contributor image, the standalone kustomize overlay and README, and the arm64 lane's documented probe default. The io.kubestellar.hive.* OCI label prefix in docker.yml is deliberately KEPT (data-format identifier, not an org pointer) — recorded in a comment there. Signed-off-by: Andrew Anderson <andy@clubanderson.com> * migrate: repoint GitHub API literals and org-gated behavior at hivecommons The hub's SHA poller (branch list, branch head, docker-workflow runs, commit message), the commit-order and commit-behind compare URLs, the /api/reach repo constants, the dashboard's compare/hash/commit-message calls, and the hub-mode reach client now name hivecommons/hive. Behavior fixes riding along: - metrics_collector: the adopters/ACMM/outreach gate now accepts BOTH org "kubestellar" and "hivecommons", since pre-transfer hive configs still report the old org (commented at the site). - github client: documented that the search org:/-org: qualifiers take the configured org verbatim and GitHub search does NOT follow repo transfers (verified both already use the caller-supplied org). - saas.go pulls-chart tooltip/comment text updated to the hivecommons image the counter now tracks (pullPackagePageURL derives from ghcrRepoSpoke). Signed-off-by: Andrew Anderson <andy@clubanderson.com> * migrate: move frontend and doc deep links to github.com/hivecommons/hive - Agent-import example/raw URLs now point at hivecommons; the blob->raw rewrite handles BOTH github.com/hivecommons/hive and the legacy github.com/kubestellar/hive spelling so pre-transfer links keep importing (commented at the site). - Advisory digest footer links now name github.com/hivecommons/hive. - Wiki getting-started/agents deep links moved to hivecommons. The kubestellar-hive GitHub App slug copy in index.html is deliberately untouched: the App is NOT renamed by the org transfer. Signed-off-by: Andrew Anderson <andy@clubanderson.com> * 🔁 migrate: install pluk from its new npm home @hivecommons/pluk The pluk package moved scopes as part of the hivecommons migration (@kubestellar/pluk is deprecated with a pointer). Same package, same versions, new name. Signed-off-by: Andrew Anderson <andy@clubanderson.com> * 🌱 migrate: add fleet identity changelog Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🐛 fix: keep ACMM on legacy docs during org migration Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🐛 fix: tolerate pluk npm mirror lag Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🌱 migrate: retrigger fleet identity gate Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🌱 chore: refresh NOTICE for fleet identity branch Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🌱 chore: restore deterministic NOTICE source Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> * 🌱 ci: route v2 test matrix for trusted PRs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> --------- Signed-off-by: Andrew Anderson <andy@clubanderson.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Manual release PR for v4.8.0 after tagged-release.yml published immutable GHCR tags but could not open its own PR.
Automated release commit. Compiles changelog.d/ fragments and moves the CHANGELOG.md Unreleased section into a dated v4.9.0 entry. See src/docs/releases.md. Signed-off-by: hive-release-bot <actions@github.com>
Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…symlink (#5854) handleBrandingCSS did a bare os.ReadFile and wrote the bytes as text/css with only nosniff + no-cache. The default path <data>/branding/custom.css resolves to the parent of agents_dir — the same volume agents write to — and the dashboard CSP is `img-src 'self' data: https:`, so a stylesheet dropped there renders in the operator's browser and can beacon out via an image URL. Safety rested entirely on documentation asking operators to own the path. Both branding reads (custom.css per request, branding.json at startup) now go through readBrandingFile, which refuses a file that is: - group- or world-writable — somebody other than the owner can replace the served bytes, which is the agent-on-the-shared-volume threat; - owned by neither the hive process uid nor root; - larger than 128 KiB — reusing customStyleMaxBytes, the cap the ?style= feature already applies, rather than inventing a second number. Refused outright, never truncated: half a stylesheet is a differently-broken page and truncated JSON is invalid JSON; - reached through a symlink resolving outside its own directory. A refusal 404s exactly as an absent file does and logs once (custom.css is read on every request, so an unguarded Warn would emit per page load) with the path, the offending mode or owner, and the chmod/chown that fixes it. The reason never reaches the browser — that would leak the file layout. Two allowances are deliberate, so hardening is not punished. Root-owned files pass, because the documented read-only Secret mount is uid 0 / defaultMode 0444 and the process cannot rewrite it; and symlinks *within* the branding directory pass, because Kubernetes projected volumes are built entirely out of links into ..data/ and rejecting them would break every ConfigMap and Secret mount. HIVE_BRANDING_ALLOW_UNSAFE_OWNER waives the ownership check alone — group/world-writable has no legitimate shape. Ownership lookup is split behind unix/!unix build tags, mirroring the existing pkg/github/fileowner_{unix,other}.go, so off-unix degrades to the portable mode and size checks rather than failing to build. branding.md's "Operator responsibilities" section shrinks accordingly: the three obligations it listed are now enforced, and what remains is the part the code still cannot do — the guards check who may write the file, not what is in it. Fixes #5849 Signed-off-by: Andy Anderson <andy@clubanderson.com>
…5874) Issues route to one agent by matching lane keywords against the title AND the labels, and the label side was strings.Contains over the space-joined label list. Scanner's L4 keyword `fix` is a substring of `ai-fix-requested` — the label the dashboard's ACMM evaluator stamps on every maturity-gap issue it files (api_acmm_eval.go) — so EVERY ACMM gap issue routed to scanner, which is ISSUES_ONLY at L4 and cannot open a pull request. Nothing logged an error. The issues were enumerated as actionable correctly; they simply arrived in the one queue with no ability to act on them, while quality, ci-maintainer and sec-check never saw them at all — filterByLane admits an issue to an agent only when issue.Lane == agentName || issue.Lane == "". A live 4-repo L4 hive had 11 of 11 ACMM issues parked there indefinitely. The label whose entire purpose is to mark an issue AI-fixable was the reason nothing fixed it. Reproduced by toggling ONLY the label, title and lane table held fixed: "[ACMM L4] Add AI security policy" labels="" -> sec-check "[ACMM L4] Add AI security policy" labels="acmm ai-fix-requested" -> scanner THE RULE NOW: a keyword or lane name matches a label only as the WHOLE label, or as a whole "/"-delimited segment of it. The two separator characters are treated differently on purpose, and that asymmetry is the whole fix. "/" is a GitHub label NAMESPACE separator — kind/bug, kind/regression, area/api — so the segment after it is the label's actual subject, and ci-maintainer's `regression` keyword matching `kind/regression` is routing working as intended; this package already relies on that convention (classifyTier tests kind/security by name). "-" is part of a single label's own name: `ai-fix-requested` is one word meaning one thing, and it is no more a request about "fix" than `do-not-merge` is a request about "merge". Splitting on "-" would have left the bug exactly where it was. A SECOND BUG THIS CLOSES: the joined-string test let a multi-word keyword straddle two unrelated labels. Keyword `breaking change` matched an issue labelled `breaking` + `change` — two separate labels — because the join put a space between them. Matching per-label makes that impossible. Titles are untouched and keep substring matching, which is right for prose: "fix the login crash" should reach the `fix` lane. LANE ORDER IS NOW DETERMINISTIC. classifyLane is first-match-wins over a slice that initAgentConfigDrivenSystems built by ranging over cfg.Agents — a Go map, whose iteration order is randomized per range. An issue matching two lanes went to whichever came out first, and the winner could differ between two runs of the same binary on the same config, with nothing recording which it had been. That is live on an L4 hive: "[ACMM L4] Add AI fix workflow" matches ci-maintainer's `workflow` and scanner's `fix`, and those two have different modes, so the coin flip decided whether the issue could be fixed at all. Sorting by name is a STABLE order, not a claim about precedence; choosing a deliberate precedence between colliding lanes is a separate call. WHAT THIS DOES NOT DO, measured rather than estimated. The fix makes the ACMM labels routing-NEUTRAL; it does not re-home every ACMM issue. Of the 13 titles in the report, 11 still reach scanner — one on the title keyword `issue`, ten on DefaultLane, which is "scanner" rather than "", so an unmatched issue stays invisible to every other agent. The report raises that as a separate matter and does not propose changing it; flipping the fallback to "" would make every unclassified issue in the fleet visible to every agent, which is a routing-policy decision and not a bug fix. TestACMMLabelIsRoutingNeutral asserts the count of 11 so the follow-up decision has data attached and moving it is deliberate. Also not done, and for the same reason: dropping `fix` from scanner's default L4 keywords, which the report lists as optional. Measured against the reported issue set it changes nothing (none of those titles contain `fix`), and it would narrow scanner's triage reach on every L4 hive. While measuring, one finding not in the report: `quality` is ISSUES_AND_PRS at L4 and declares NO lane_keywords, so it is absent from the lane table entirely and can never be routed anything. That is a second, independent reason the reported issues could not reach it. TestInitAgentConfigDrivenSystemsKeywordlessAgentsStayOutOfTheTable pins the build behaviour that makes it so. Both defects were confirmed to reproduce before the fix: the pre-fix classifier routes the security-policy title to scanner with the label and sec-check without it, and the determinism test fails on its first iteration without the sort. Signed-off-by: Danathar <doug.baggett@gmail.com>
release: v4.9.0
…5827) The panel scores how ready a repo is for agentic contribution and reports one level for the whole hive. That level is the BEST CASE across every watched repo: evaluateAllRepos marks a criterion passed if ANY repo has it. A repo meeting none of the 43 criteria therefore does not move the headline at all, so it is invisible — and an operator reading L3 reasonably assumes every watched repo is at L3. A per-repo drill-down existed but was half-wired, and that was the more confusing half. acmmRenderCard wrote the four headline tiles from the aggregate payload and only THEN resolved the active repo view, which was consumed by the level bars alone. Clicking a repo chip moved the bars and left the tiles above them on hive-wide numbers: two halves of one card disagreeing, with nothing to indicate which of them had followed the click. THE TILES NOW FOLLOW THE SELECTOR. The active view is resolved before the tiles are written, and the second, now-redundant resolution below them is gone — two resolutions are how the halves came to disagree in the first place. Codebase Readiness and Criteria Passed read the selected repo. Overall ACMM is min(codebase, operational) and the server computes it against the UNION, so it is recomputed for a selection; leaving it would have put a fleet-wide reading directly beside a per-repo one. Unscoped, the server's value stands, so the panel never disagrees with the payload it was handed. Operational Autonomy deliberately does NOT follow the selector: it measures the hive's own operating behaviour, not a repository. That makes the card's scope mixed, which is fine as long as it is stated — an unlabelled tile that ignores a click is indistinguishable from one that failed to follow it — so each tile label now carries its scope, and the ops tile is marked hive-wide whenever a repo is selected. THE RANKING ANSWERS THE QUESTION DIRECTLY. Finding the weakest repo used to mean opening the Codebase Readiness dialog and expanding each repo row one at a time, with nothing sorted by gap; the chips carried a level but not the ratio, so "lacking, and by how much" cost one click per repo. A per-repo table now ranks every repo worst-first with its level, passed/total, and the level it is blocked at, and its rows select their repo so the table and the selector are one control. The chips carry the ratio too. The rank key is the raw GAP (unmet criteria), not the percentage: with a fixed criteria set the two agree, and the count is what an operator acts on — "14 things to fix" is a work estimate, "67%" is not. Ties break on the lower level, then on name, because this table is read repeatedly and an order that shuffles between identical renders reads as churn that is not there. "Blocked at" is the FIRST failing level, since levels must pass in order; counting failures instead would rank a repo stuck at L2 below one with gaps at L5. The "weakest" badge appears only when the repos actually differ — on a level fleet, singling one out would invent a problem. The panel now also states that the aggregate is a union. That was mentioned only inside the Codebase Readiness dialog, and only when more than one repo was configured. Nit from the report, fixed: the repo selector carried both display:none and display:flex in one style attribute. The later declaration won, so it rendered visible — holding only the "All (aggregate)" chip — until the first evaluation response let acmmRenderCard hide it. NO SERVER CHANGE. The evaluation already returns repo_results[] with each repo's level, ratio, per-level scores and full criterion list, so this is a presentation gap and not a collection gap; nothing here adds an API call. The optional min-across-repos field the report floats is deliberately not added: it is derivable from repo_results, no Go consumer outside this panel reads codebase_level at all, and a duplicated derivable field is a second source of truth that can drift. The ordering rule is tested by EXECUTION, not by pattern-matching: the test extracts acmmRepoGapRows and acmmFirstFailingLevel from index.html and runs them under node against a fixture whose correct order is known by construction and is neither the input order nor its reverse. Asserting that a sort comparator appears verbatim would catch a rule that was changed and miss one that was always wrong, which for a ranking is the failure that matters. The remaining tests pin the wiring that cannot be executed — including the ORDERING of the active-view resolution against the tile writes, since an edit that moves it back down reintroduces the original defect while every value-reading assertion still passes. All six were confirmed to fail against the pristine file before the fix. Signed-off-by: Danathar <doug.baggett@gmail.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ter (#5881) `ClusterConfig.InCluster` is a claim, not a fact. For an InCluster cluster, kubectlArgsForCluster appended --server/--certificate-authority/--token only when KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT were both set, and appended nothing at all otherwise. "Nothing at all" is not a safe default. kubectl with no --server and no --kubeconfig resolves against its ambient configuration -- $KUBECONFIG or ~/.kube/config -- so the command targets whatever cluster the machine's current context happens to name. That is the mechanism behind #5768. Six of the seven test files that drive handleCreateHive install no scripted kubectl, and the hub test package had no TestMain isolation before 2026-07-31. Any of those tests reaching a provisioning entry point issued a real `kubectl apply` of a Namespace and Deployment named from its own fixture org. The hub kept no record because saveSaaSHive writes under saasHivesDir, which each test redirects to a t.TempDir() -- the bookkeeping was written and then deleted with the temp dir while the cluster-side objects persisted. The guard goes at the single argv chokepoint both kubectl constructors funnel through, not in individual tests: a per-test fix would have to be repeated forever and re-missed once. Absence of both ServiceAccount env vars is positive, reliable evidence the process is not in a pod -- the kubelet always injects them -- so genuine in-cluster provisioning is untouched, which TestRealInClusterStillUsesServiceAccount pins. TestKubectlForCluster asserted "in-cluster should not use --kubeconfig" with those vars unset, encoding the bug as expected behaviour. It now sets them, pinning the real-pod behaviour it meant to describe. Refs #5768 Signed-off-by: Andrew Anderson <andy@clubanderson.com>
) (#5880) Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: clubanderson The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
e7ba319 to
21e7678
Compare
|
New changes are detected. LGTM label has been removed. |
Merge origin/v4 through v4.16.1 while keeping v5 release-generated changelog content unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com>
21e7678 to
fb05be5
Compare
|
Thanks for your pull request. Before we can look at it, you'll need to add a 'DCO signoff' to your commits. 📝 Please follow instructions in the contributing guide to update your commits with the DCO Full details of the Developer Certificate of Origin can be found at developercertificate.org. The list of commits missing DCO signoff:
DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
|
Thank you for your contribution! Your PR has been merged. We'd love to hear how your experience was: share feedback |
…nc-policy.md) (#6052) * [strategist] planning: document v4→v5 forward-port sync policy Adds src/docs/v5-sync-policy.md proposing cadence (v4 minor release or 50-commit drift), single-owner rotation, the merge-commit top-up procedure already used by #5845/#6046, DCO expectations, and explicit PR-body and review contracts for sync PRs. Links it from the docs index. Refs #6051 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: sec-check <sec-check@hive.kubestellar.io> * 📖 document active v5 sync policy Align the v4-to-v5 sync policy with the current merge-commit top-up process, weekly/release cadence, maintainer ownership, verification checklist, and zero-delta check. Closes #6051 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Andy Anderson <andy@clubanderson.com> --------- Signed-off-by: sec-check <sec-check@hive.kubestellar.io> Signed-off-by: Andy Anderson <andy@clubanderson.com> Co-authored-by: sec-check <sec-check@hive.kubestellar.io> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Andy Anderson <andy@clubanderson.com>
Summary
origin/v4intov5using the same merge-commit top-up style as prior v5 syncs (for example 🔄 sync: top up v5 with latest v4 #5845).origin/v4tip (v4.16.1) soorigin/v4is no longer ahead of this branch.Ported PRs / changes
hive validatesource reporting.Conflict resolutions
cmd/hive/main.go: kept v5's decomposed 114-line entrypoint; moved v4 logic intomain_helpers.go,hubwire.go, andstate_restore.go.pkg/agent/manager.go: kept v5 split layout; ported provider/start-failure and restart telemetry into split files (provider_error.go,start_failure.go,restart_telemetry.go,manager_poll.go,manager_restart.go,manager_pane_signals.go).pkg/config/config.go: kept v5 split config files; ported overlay source provenance and validation intoagent_config.go,agent_overlay.go,load.go, andvalidate.go.pkg/hub/saas.go: kept v5 split SaaS files; ported leaked namespace detection, channel targeting, image build status/staleness, wildcard TLS, restart reset, and version-absent drift into their split homes.pkg/hub/saas_provision.go: preserved the provisioning template filename for source-reading tests, but split vanity mint budget helpers to keep the v5 size ratchet green.pkg/github/*: preserved v5 package split and applied compatible v4 client/proxy intent without reintroducing config coupling..github/workflows/docker.yml/ image tag scripts: kept v5 channel ownership (edge) and did not add v4stable/candidatepublishing to v5..github/workflows/v2-ci.yml: kept v5's safer PR runner expression while carrying applicable v4 workflow changes.CHANGELOG.mdand release-generated content: kept v5 versions/content; kept changelog fragments from both sides instead of importing v4 release-generated sections.pkg/dashboard/static/index.html: resolved ACMM active view once before tile rendering, preserved repo-scoped labels/tables, and ported terminal handoff auth hardening.pkg/dashboard/server.go: kept v5 imports/wiring while adding inference gateway/terminal auth fixes; bumped the dashboard import ratchet for the new legitimateinferencehealthdependency.pkg/dashboard/webstatic/static_index_test.go: ported v4 static terminal renewal test to v5'swebstaticpackage path.Validation
cd src && go build ./... && go vet ./...cd src && golangci-lint run ./...cd src && go test -race ./pkg/... ./cmd/...bash bin/test_kick_governor.shbash src/deploy/test_entrypoint_egress_ruleset.shbash src/deploy/test_entrypoint_iptables_gate.shbash src/deploy/test_entrypoint_xt_module_preflight.shbash bin/test_dibs_cutover_preflight.shbash bin/test_dibs_cutover_verify.shpython3 src/scripts/check-docs-links.pycd dashboard && npm ci --quiet && npm test -- --test-reporter=dotcd src/proxy && npm ci --quiet && npm test -- --test-reporter=dotRemaining v4 delta
git rev-list --count HEAD..origin/v4=0after final fetch.