Conversation
fix(opencode): auto-update notifies only; latest() tracks fork release feed
- spec_git/policy.yaml: required check 'Typecheck' (dev-layer gate parity) - specgit-accept.yml: PR-to-dev acceptance evaluation - .opencode/command: /specgit-issue, /specgit-finish entry points - .opencode/hooks/specgit-merge-guard.sh: merge guard script (wired by specgit setup) - AGENTS.md/CLAUDE.md: managed specgit block Closes#353
specgit issue regenerated the harness with the repo default branch (main); delivery PRs in this repo target dev (layered gating), so the trigger must be [dev].
Generated harness assumed the SpecGit repo's own pnpm toolchain. This repo is a bun workspace without packageManager/pnpm-lock: setup-node + npm i -g specgit, minimal policy.yaml parsing without a yaml dependency.
chore(specgit): enable SpecGit delivery harness
docs(audit): add 2026-08-19 deep-dive audit report
GoalLoop's only consumer is InstanceBootstrap's serviceOption(GoalLoop.Service) .init(), which runs in the request fiber's ambient context. GoalLoop.node was listed only in AppLayer, so headless serve/web, the desktop sidecar, and non-CWD TUI directories never armed the idle-event subscription or the startup goal scan — standing goals stalled after their first turn (the same wiring class as SettingsHook/Memory in #311). Closes#340
fix(goal): wire GoalLoop.node into the server request-context app graph
The host-level deadline supervision sweep was constructed only in AppLayer; the desktop sidecar calls Server.listen without effectCmd, so AppLayer never existed there and orphaned-node supervision never ran on the desktop default path. Every serving process builds the server app graph once per listener — listing the sweep node here covers serve/web/TUI/sidecar alike. Processes that also build AppLayer get a second instance; settle is convergent (workflow lock + guardNode + conditional projector UPDATE), so the duplicate is safe. Closes#341
fix(dag): build DagSupervisionSweep in the server app graph
The window derived solely from the current persisted config; replan can lower a running node's timeout_ms while the A1/Q2 re-time gate keeps the old watcher on its old cadence, so a config-only window could be shorter than the live watcher's cycle and prematurely settle a healthy node. deadline_ms is only ever written as grant-time + timeout (spawn and each extension; escalations move only the counter), so (deadline - started_at) upper-bounds the watcher's current cadence in every shape. Window = max(config cadence, durable bound). Closes#342
fix(dag): sweep freeze window covers the live watcher's actual cadence
… a host-level settle With the owning instance torn down, checkCompletion/dag.fail/complete and the automation unregister all lived inside the dead DagLoop — a swept workflow stayed running forever with required nodes failed and its lease registration leaking (workflow rot). After a host-level settle lands, the sweep now mirrors checkCompletion's durable half: when every current-revision node is terminal it fails (required-node failure) or completes the workflow via the same workflow-lock-serialized command layer, then unregisters the dag lease. Parent wake delivery stays with the owning instance (session context) and converges through the DagLoop init drain on the next instance load; cascade skips of pending dependents likewise converge at adopt. Closes#343
fix(dag): sweep terminalizes workflows and releases their lease after a host-level settle
The handler asserted the payload as WorkflowConfig and called dag.create directly — create runs only structural checks (safe only when authoring has vetted the graph), so the checkpoint gate, output_schema obligations on gated checkpoints, worker/model/prompt asset resolution, and server-side deep-mode admission minting were all bypassed over HTTP. The handler now wraps the payload as an inline StartSpec and runs authoring.prepare(environment profile) through the same shared catalog loader the workflow tool uses (extracted to dag/environment-catalogs.ts); validation failures surface as 400 with the diagnostic list. Closes#344
The lint budget is exactly at its cap (4850); the two now-unused imports pushed CI one warning over.
fix(dag): httpapi dag.start passes Workflow Authoring
The recovery path completed a schemaless running node with undefined and
never read the child session's messages, while the live path settles with the
last assistant text — a crash between the child's final reply and the
NodeCompleted publish erased the outcome: a bare {"verdict":"replan"}
checkpoint reply lost its veto (no pause, no warning) and gated dependents
resolved no fields. Recovery now mirrors the live path via an injected
last-assistant-text reader; an explicitly unparseable workflow row (null) fails
the node loudly instead of undefined-completing past settleCapturedOutput.
Closes#345fix(dag): crash recovery preserves a schemaless node's string verdict
chore(specgit): pin the acceptance workflow's specgit CLI to ^0.5.0
fix(license): add the SPDX headers to environment-catalogs.ts
The Typecheck-only PR->dev gate let an assertion-level regression (#368, missing SPDX headers) merge and keep dev's push-triggered full run red for 75 minutes. ci-test.yml now triggers on PRs to dev (the whole matrix runs, but only Unit Tests (linux) becomes required); spec_git/policy.yaml follows so specgit finish enforces the same pair. E2E stays push-on-dev + dev->main. Closes#370
…e tool The new PR->dev unit gate caught it (#371's own run): the exerciser's CI context has no resolvable model, and the environment-profile validation made model.unavailable a blocking 400 — while the workflow tool's start action asks a question instead (an HTTP caller has no such interaction; spawn fails loudly at execution time if a model never resolves). All other diagnostic classes stay blocking.
… a model-bearing session CI (no providers) exposed two layers: the advisory filter let a graph that never compiled (prepared === undefined) through to a confusing 'no prepared graph' 400 — a non-compiling graph is now always blocking regardless of diagnostic class; and the dag.start happy-path scenario relied on the pre-#344 behavior of never resolving a model. The scenario now runs under withLlm with an explicit session model so the parent resolution chain has something to resolve in the provider-less CI environment.
…28min) The verdict waits for every policy check to reach a terminal state; with Unit Tests (linux) now required on dev PRs, the 15min job cap timed out while the sibling was still running.
…was the real timeout The job-level 45min bump was necessary but not sufficient: the sibling-wait script carries its own hardcoded 15-minute deadline and gives up while Unit Tests (linux) (~28min) is still running.
- NEW-1: spawn failure boundary rethrows interrupts (parity with the file's own catchCause discipline) instead of persisting a nodeFailed - NEW-2: recovery-pause retries twice and only abandons adoption when the durable row is genuinely terminal (mirrors the replan-verdict gate) - REC-1: pending-node stale-child cancel is cause-hardened like the running branch — a persistent failure no longer aborts the whole reconcile - BLK-02: hyphen/underscore writer-id key collisions rejected at compile time - BLK-03: a verify node serving multiple parallel-writer review routes is rejected (the contract binds ONE fingerprint) instead of silently mapping only the first aggregator - CAP-02: regex tests capped at 100k chars, uniqueItems scan capped at 1000 items, file-ref capture capped at 64MiB (inline fallback beyond) - SW-L1: sweep publishes stamp the workflow row's location so live instances' summary publishers push swept settles to the TUI - F3: TUI reconnect refreshes stored goals (a missed goal.cleared no longer leaves a stale sidebar indefinitely) - F6: dag.cancel.active added to the keybind Definitions/CommandMap - AGENTS.md: tool-call discipline rules (no duplicate fan-out queries, one watch per CI wait) SW-L2 (cancel dies without ambient instance — acknowledged design) and F4/F5 (record items on the event surface) are accepted as designed. Closes#349
… Convention CONTEXT.md claimed an engine-enforced invariant; the implementation is orchestrator guidance only (dag.create and the tool start accept a session with a live workflow; the wake model and lease tolerate multiples). The divergence was the defect (audit INV-A) — this records the truth: a modeling convention with documented bounded consequences, including the cross-workflow write-set caveat. Engine enforcement remains available as a future decision if the convention proves insufficient. Closes#348
chore(ci): raise the dev PR gate to Typecheck + Unit Tests (linux)
…s the reconcile The old test pinned the abort-on-cancel-failure behavior the audit flagged as the REC-1 defect (the workflow became unadoptable in-process until restart).
fix(dag): low-severity batch from the 2026-08-19 deep-dive audit
docs(dag): 'one objective, one live DAG' downgraded from Invariant to Convention
…view nits Two-axis review of today's 62-commit range (both axes PASS, info findings): - AGENTS.md gate prose/table updated to Typecheck + Unit Tests (linux) (#370 drift) - CONTEXT.md: Conventions section moved after the full Invariants list — the #348 edit had demoted 5 original Invariants (incl. the engine-enforced gated-checkpoint obligation) under the new header - memory-search: identical if-branches folded back to || - blocks.ts: BLK-02 collision check extracted from an IIFE into aggregatorEvidenceMapping per the Style Guide - #340's serve-mode behavioral e2e documented as a covered-by-composition delta (e2e-loop behavior tests + the wiring probe for the failure class) Closes#374
chore: post-review cleanup — docs drift, CONTEXT.md section order, review nits
main's legacy branch protection requires the SpecGit Acceptance check, but the workflow only triggered on PRs to dev — the dev->main release PR was permanently BLOCKED with all four Ruleset checks green.
chore(specgit): acceptance also runs on PRs to main
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release promotion: dev → main
What's in this batch
67 commits since graphagent-v1.0.26 (PR #339), delivered through the SpecGit harness — every PR merged with
specgit finishexit 0:Deep-dive audit fixes (issues #340–#350)
Platform & harness
Test summary
Release: on merge, run the
📦 Release · Fork Buildworkflow frommain(official, non-prerelease).