Skip to content
Closed
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ Hive did not historically maintain a complete changelog. This file starts a prag

## Unreleased

## 2026-11-12 (v5.228.6)

### Fixed

- Detect missing GitHub App repository coverage at boot, during self-heal, and when connecting a repository, with a settings link to fix the installation selection (#17696).

## 2026-11-12 (v5.228.5)

### Fixed
Expand Down
1 change: 1 addition & 0 deletions changelog.d/added-inbox-voice-quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added an Inbox voice sources quickstart link to Plaud setup and Integrations ([#17882](https://github.com/hivecommons/hive/issues/17882)).
1 change: 1 addition & 0 deletions changelog.d/added-workflow-enabled-toggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Settings β†’ Workflows β†’ Library gains an owner-only **Derive stages from bound models** switch (`workflow.enabled`, [#17620](https://github.com/hivecommons/hive/issues/17620)) backed by the new `PUT /api/workflows/enabled {enabled}`, so a hosted hive with no `hive.yaml` access can turn model-based stage derivation on or off from the dashboard. Off: a binding only changes the Activity Monitor's columns; on: a bound repository's stages are derived by its model's rules and the model's labels are provisioned in the repository immediately. Persists `hive.yaml`, takes effect on the next derivation pass without a restart, audited as `workflow_enabled` / `workflow_disabled`; the Repos binding row now says *columns only β€” turn on derivation in Workflows* when a repository is bound while the flag is off.
1 change: 0 additions & 1 deletion changelog.d/fixed-17696-app-repo-coverage.md

This file was deleted.

1 change: 1 addition & 0 deletions changelog.d/fixed-proxy-plain-forward-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Classify repeated plain HTTP proxy forwarding failures separately, with diagnostics for the requested host and network path.
72 changes: 72 additions & 0 deletions dashboard/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -36029,6 +36029,78 @@
}
}
},
"/api/workflows/enabled": {
"put": {
"tags": [
"Workflows"
],
"summary": "Turn model-based stage derivation on or off",
"description": "Owner only. Sets workflow.enabled from the dashboard so a hosted hive with no hive.yaml access can enable it (hivecommons/hive#17620). Body {enabled}. Persists hive.yaml; the stage engine and the tracker read the live flag, so it takes effect on the next derivation pass without a restart. Turning it on also provisions every bound repository's model labels immediately; a repository that could not be provisioned is listed in warnings and the next sweep retries it. Audited as workflow_enabled / workflow_disabled; a no-op is not audited.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"enabled"
],
"properties": {
"enabled": {
"type": "boolean"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Flag after the change",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"changed": {
"type": "boolean"
},
"bindings": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WorkflowBinding"
}
},
"warnings": {
"type": "array",
"items": {
"type": "string"
},
"description": "Bound repositories whose labels could not be provisioned now (only when turning on)"
}
}
}
}
}
},
"400": {
"description": "Body is not {enabled: boolean}"
},
"403": {
"description": "Not an owner"
},
"500": {
"description": "hive.yaml could not be saved; the flag is left unchanged"
},
"503": {
"description": "No config"
}
}
}
},
"/api/workflows/{name}/{version}": {
"get": {
"tags": [
Expand Down
11 changes: 6 additions & 5 deletions src/cmd/hive/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@ func (b *boot) wireBootClosures() {
WorkflowItemSnapshot: func(ctx context.Context, repo string, number int) (github.WorkflowItemSnapshot, error) {
return b.ghClient.WorkflowItemSnapshot(ctx, repo, number)
},
WorkflowRepoFile: workflowRepoFile(func() *github.Client { return b.ghClient }),
WorkflowClusterRunner: workflowClusterRunner(),
WorkflowSpecLLM: newWorkflowSpecRunner(func() *config.Config { return b.cfg }),
AgentMgr: b.agentMgr,
CruxRuntimeHealth: cruxRuntimeHealthFunc(b.cruxSupervision),
WorkflowRepoFile: workflowRepoFile(func() *github.Client { return b.ghClient }),
WorkflowProvisionLabels: workflowProvisionLabels(b.cfg, func() *github.Client { return b.ghClient }, b.logger),
WorkflowClusterRunner: workflowClusterRunner(),
WorkflowSpecLLM: newWorkflowSpecRunner(func() *config.Config { return b.cfg }),
AgentMgr: b.agentMgr,
CruxRuntimeHealth: cruxRuntimeHealthFunc(b.cruxSupervision),
// Provider gateways (#5565 slice 3): concrete openrouter/watsonx/
// linearagent adapters behind the dashboard's consumer-defined
// interfaces β€” this composition root is the only non-test place that
Expand Down
42 changes: 42 additions & 0 deletions src/cmd/hive/workflow_labels.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"context"
"fmt"
"log/slog"
"strings"

"github.com/hivecommons/hive/pkg/config"
"github.com/hivecommons/hive/pkg/github"
"github.com/hivecommons/hive/pkg/github/automerge"
)

// workflowProvisionLabels is the dashboard's WorkflowProvisionLabels
// dependency (hivecommons/hive#17620): when an owner turns workflow.enabled
// on from Settings β†’ Workflows, every bound repository's model labels are
// provisioned at once through the sweep's own memoised path
// (automerge.Engine.EnsureStageLabels over the process-shared stage engine
// options and tracker), rather than on the next PR that needs a label.
// Without a GitHub client the call reports an error and the handler
// surfaces it as a warning; the flag itself still flips.
func workflowProvisionLabels(cfg *config.Config, client func() *github.Client, logger *slog.Logger) func(ctx context.Context, repo string) error {
return func(ctx context.Context, repo string) error {
var gh *github.Client
if client != nil {
gh = client()
}
if gh == nil {
return errNoForgeClient
}
owner, name, ok := strings.Cut(config.QualifyRepo(cfg.Project.Org, repo), "/")
if !ok || owner == "" || name == "" {
return fmt.Errorf("repository %q is not owner/name", repo)
}
eng := automerge.New(gh, automerge.Options{
Logger: logger,
StageLabelPolicy: stageLabelPolicyFunc(cfg),
StageEngine: stageEngineOptions(cfg, logger),
})
return eng.EnsureStageLabels(ctx, owner, name)
}
}
28 changes: 28 additions & 0 deletions src/cmd/hive/workflow_labels_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import (
"context"
"errors"
"strings"
"testing"

"github.com/hivecommons/hive/pkg/config"
"github.com/hivecommons/hive/pkg/github"
)

func TestWorkflowProvisionLabelsWithoutClient(t *testing.T) {
cfg := &config.Config{Project: config.ProjectConfig{Org: "acme"}}
provision := workflowProvisionLabels(cfg, func() *github.Client { return nil }, nil)
if err := provision(context.Background(), "widgets"); !errors.Is(err, errNoForgeClient) {
t.Fatalf("err = %v", err)
}
}

func TestWorkflowProvisionLabelsRejectsBareRepoWithoutOrg(t *testing.T) {
cfg := &config.Config{}
provision := workflowProvisionLabels(cfg, func() *github.Client { return &github.Client{} }, nil)
err := provision(context.Background(), "widgets")
if err == nil || !strings.Contains(err.Error(), "owner/name") {
t.Fatalf("err = %v", err)
}
}
2 changes: 1 addition & 1 deletion src/docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ History point limits, timestamp cutoffs, incremental cost reads and ETag/304 beh
| Health, status, events | [`api-reference/health-status-events.md`](api-reference/health-status-events.md) | 50 |
| Snapshots and style | [`api-reference/snapshots-and-style.md`](api-reference/snapshots-and-style.md) | 5 |
| Auth and external accounts | [`api-reference/auth.md`](api-reference/auth.md) | 22 |
| Configuration | [`api-reference/configuration.md`](api-reference/configuration.md) | 105 |
| Configuration | [`api-reference/configuration.md`](api-reference/configuration.md) | 110 |
| Agents and controls | [`api-reference/agents-and-controls.md`](api-reference/agents-and-controls.md) | 36 |
| Packs and ACMM | [`api-reference/packs-and-acmm.md`](api-reference/packs-and-acmm.md) | 18 |
| Cost, tokens, telemetry | [`api-reference/cost-tokens-telemetry.md`](api-reference/cost-tokens-telemetry.md) | 13 |
Expand Down
1 change: 1 addition & 0 deletions src/docs/api-reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,4 @@ Part of the [Dashboard REST API reference](../api-reference.md); see that page f
| `PUT` | `/api/config/governor/project-observability` | Owner only | Governor Project Observability Set | `pkg/dashboard/api.go:282` |
| `GET` | `/api/config/governor/inference-auth` | Owner only | Governor Inference Auth Get | `pkg/dashboard/api.go:297` |
| `PUT` | `/api/config/governor/inference-auth` | Owner only | Governor Inference Auth Set | `pkg/dashboard/api.go:298` |
| `PUT` | `/api/workflows/enabled` | Owner only | Turn model-based stage derivation (`workflow.enabled`, [#17620](https://github.com/hivecommons/hive/issues/17620)) on or off from the dashboard, for hosted hives with no `hive.yaml` access. Body `{enabled: bool}`; persists `hive.yaml`; the stage engine and tracker read the live flag so it applies on the next derivation pass without a restart. Turning on also provisions every bound repository's model labels now (`warnings[]` lists repositories that could not be provisioned; the next sweep retries). Returns `{enabled, changed, bindings[], warnings?[]}`. Audited `workflow_enabled` / `workflow_disabled`; `400` on a non-boolean body | `pkg/dashboard/api_workflows.go:28` |
16 changes: 16 additions & 0 deletions src/docs/design/workflow-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,22 @@ and `GET /api/workflows/{name}/{version}`:
Duplicate (saves a copy under a new name at version 1, provenance `local`) and Delete; Delete is
withheld while anything is bound (the API returns 409 anyway) and the row says `bound` instead.
Export shows the model JSON in-app (copy to clipboard) for everyone.
- **Derivation switch** β€” the Library header carries an owner-only toggle, *Derive stages from
bound models* (`renderWorkflowEnabledToggle`, `PUT /api/workflows/enabled {enabled}`), so a
hosted hive with no `hive.yaml` access can turn `workflow.enabled` on or off. Off: a binding
only changes the Activity Monitor's columns. On: a bound repository's stages are derived by its
model's rules and the model's labels are provisioned. Turning on asks for confirmation (it
changes derivation for every bound repository and creates labels in them); turning off is
immediate. The handler sets `Config.Workflow.Enabled`, saves `hive.yaml`, audits
`workflow_enabled` / `workflow_disabled`, and β€” on the way on β€” calls
`Dependencies.WorkflowProvisionLabels` for each binding (cmd/hive wires it to
`automerge.Engine.EnsureStageLabels`, the sweep's memoised `ensureStageLabels` path over the
shared stage-engine options and tracker), so the bound models' labels exist at once rather than
on the next PR that needs a label write; a repository that fails is returned in `warnings[]`
and the next sweep retries. No reload hook is needed: `stageEngineWorkflowFor` and the tracker
read `cfg.Workflow.Enabled` on every call, and the hive.yaml reloader mutates the same
`*Config` in place. The Repos binding row shows *columns only β€” turn on derivation in
Workflows* when a binding exists while the flag is off.
- **Detail** β€” facts, the diagram, diagnostics, citations and the raw model/profile JSON.
`workflowDiagramSvg(model, profile)` is a pure function: the compiled profile's columns are lanes
in display order, each state is a chip carrying its padded stage number, transitions are bezier
Expand Down
1 change: 1 addition & 0 deletions src/docs/fleet-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ title is `[selfreport] <class>: <short message>`.
| `agent_cli_restart_loop` | the agent CLI crashed (bare shell) or sat on a consent screen and the harness restarted it before the kick (`agent CLI crashed or stuck on consent screen, restarting before kick`, `crux/agent/manager_kick.go`, `kick_async.go`), repeated β‰₯5 times in 10 min β€” a restart loop, not transient noise. Log-fed: same repeat threshold and idle clear as `agent_pane_timeout` | medium |
| `copilot_cli_hung` | a Copilot agent showed none of the CLI's startup chrome (input prompt, help hint, login request) 180 s after launch, outside kick delivery, so the hang detector killed its session, ran bare `copilot` to capture the error and relaunched the agent (`copilot hung with no CLI prompt, running diagnostic`, `crux/agent/manager_poll.go`), or that diagnostic saw no output before its own deadline and relaunched anyway (`diagnostic: timed out waiting for copilot error output`, `crux/agent/manager_credentials.go`; the line carries the pane's `output_tail`). The key is the message, so β‰₯5 in 10 min counts every Copilot agent on the hive together: its Copilot agents keep failing to reach their prompt. Typical causes are a stale Copilot token the CLI hangs on (the diagnostic restores or clears it when it sees an auth error), a blocked network path to the Copilot API, or a CLI build whose startup screen the detector does not recognise (`cliReadyIndicators`, `crux/agent/pane_classify.go`). Log-fed: same repeat threshold and idle clear as `agent_pane_timeout` | medium |
| `proxy_connect_dial_failed` | the hive proxy could not dial the upstream host of a CONNECT request (`proxy: CONNECT dial failed`, `crux/proxy/github_proxy_connect.go`) or of a Copilot usage-sniffed connection (`copilot sniff: upstream dial failed`, `crux/proxy/github_proxy_copilot.go`) β€” typically DNS or network unreachability of an agent-requested host (for example a dial timeout to `telemetry.enterprise.githubcopilot.com`), repeated β‰₯5 times in 10 min. Log-fed: same repeat threshold and idle clear as `agent_pane_timeout` | medium |
| `proxy_plain_forward_failed` | the proxy could not complete an agent's plain-HTTP upstream request (`proxy: plain HTTP forward failed`, `crux/proxy/github_proxy_connect.go`), returning HTTP 502. Check the requested host and logged error, including DNS and outbound connectivity; this differs from a destination refused by the proxy policy. Log-fed: β‰₯5 occurrences in 10 min, clears after 20 quiet minutes | medium |
| `proxy_tls_handshake_failed` | the hive proxy's TLS handshake with an upstream host failed (`proxy client tls handshake failed`, `transparent proxy tls handshake failed`, `copilot sniff: client tls handshake failed`, `crux/proxy/github_proxy_connect.go`, `crux/proxy/github_proxy_copilot.go`) β€” typically a certificate validation failure or encryption mismatch on an agent-requested host, repeated β‰₯5 times in 10 min. Log-fed: same repeat threshold and idle clear as `agent_pane_timeout` | medium |
| `review_evidence_write_failed` | the github-client failed to write a review evidence bundle to persistent storage (`review evidence: could not write bundle`, `pkg/github`), repeated β‰₯5 times in 10 min. Log-fed: same repeat threshold and idle clear as `agent_pane_timeout` | medium |
| `selfreport_cleared_comment_failed` | the fleet report publisher failed to post the "condition cleared" comment on a self-report issue (`fleet report: cleared comment failed`, `pkg/github`), repeated β‰₯5 times in 10 min. Log-fed: same repeat threshold and idle clear as `agent_pane_timeout` | medium |
Expand Down
11 changes: 11 additions & 0 deletions src/hive.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -1290,3 +1290,14 @@ data:
claude_sessions_dir: /data/home/.claude/projects
copilot_sessions_dir: /data/home/.copilot/session-state
agents_dir: /data/agent-configs

# Workflow models (hivecommons/hive#17620, docs/design/workflow-models.md).
# Repositories are bound to a model on Settings β†’ Repos (project.workflow_bindings).
# A binding always changes the Activity Monitor's columns for that repository;
# `enabled` decides whether the bound model's rules also derive its stages and
# whether the model's labels are provisioned in the repository. Owners can flip
# it from Settings β†’ Workflows β†’ Library (PUT /api/workflows/enabled) without
# editing this file; the change applies on the next derivation pass.
# workflow:
# enabled: false # false (default): bindings are columns only
# label_gc: true # delete labels a previous binding provisioned once nothing wears them
Loading
Loading