Skip to content

feat: tags field, critical-check prioritization, gc-watchdog skill - #20

Closed
ThePlenkov wants to merge 32 commits into
decouple-gascity-packfrom
feat-tags-and-watchdog
Closed

ThePlenkov wants to merge 32 commits into
decouple-gascity-packfrom
feat-tags-and-watchdog

Conversation

@ThePlenkov

@ThePlenkov ThePlenkov commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

User description

Summary

Stacked on PR #19 (decouple Gas City harness). Three additions:

  • tags field on IR PlanOperation — optional readonly string[] for prioritization, filtering, categorization
  • Critical-check prioritization in runtime topoSort — critical-tagged ops scheduled first among ready siblings (stable sort, input order preserved within groups)
  • gc-watchdog skill — project-local skill at .agents/skills/gc-watchdog/ with standalone script and exit condition

Changes

File Change
packages/ir/src/plan.ts Add tags?: readonly string[] to PlanOperation
packages/sdk/src/convert.ts Pass spec.tags through in convertOperation
packages/runtime/src/internal/topo.ts sortReadyByPriority() — critical first among ready siblings
engdocs/adr/ADR-008-tags-and-critical-prioritization.md Architectural decision record
.agents/skills/gc-watchdog/SKILL.md Watchdog skill documentation
.agents/skills/gc-watchdog/watchdog.sh Standalone script with exit condition

Tests (TDD)

  • ir/validate.test.ts: 3 tests — accepts tags, accepts no tags, accepts empty tags
  • sdk/convert.test.ts: 2 tests — passes tags from spec, omits when absent
  • runtime/topo.test.ts: 2 tests — critical first among independents, critical first among siblings after dependency

gc-watchdog exit condition

Exits when ALL true:

  1. No open real tasks (wisp/nudge filtered out)
  2. No in-progress real tasks
  3. Mayor awake, city not suspended, controller running

Does NOT exit on failure — only on clean idle.

Test plan

  • npx vitest run packages/ir/src/__tests__/validate.test.ts -t "tags" — 3 pass
  • npx vitest run packages/sdk/src/__tests__/convert.test.ts -t "tags" — 2 pass
  • npx vitest run packages/runtime/src/__tests__/topo.test.ts — 11 pass
  • npx nx run ir, sdk, runtime: typecheck — clean
  • npx nx run ir, sdk, runtime: build — clean
  • bash .agents/skills/gc-watchdog/watchdog.sh 1 — reports IDLE and exits 0

Stacked on #19

Generated with Devin


Summary by cubic

Adds tags to IR operations, prioritizes "critical" checks among ready siblings, and adds a gc-watchdog skill/script to exit cleanly when Gas City is idle. Also brings in CLI, checks, compilers, and docs; addresses Linear sv-bni by delivering the deferred critical-check prioritization from ADR-007.

  • New Features
    • IR/SDK/Runtime: PlanOperation.tags?: readonly string[]; SDK propagates spec.tags; topoSort schedules "critical" first (stable within groups).
    • Agents: .agents/skills/gc-watchdog/ with watchdog.sh (filters wisp/nudge; exits only on clean idle with healthy mayor).
    • Platform: @sverka/checks (builtin resolver + SARIF extraction), @sverka/cli (init/inspect/plan/execute/validate/baseline/doctor), compilers @sverka/compiler-github and @sverka/compiler-gitlab.
    • Docs/Tooling: ADR-007/008 and architecture/user docs (waves 03–15); ESLint 9 flat config and Codacy config updates.

Written for commit 238bef0. Summary will update on new commits.

Review in cubic


CodeAnt-AI Description

Add operation tags, prioritize critical work, and provide a Gas City watchdog

What Changed

  • Operations can now carry optional tags such as critical and security, including empty tag lists.
  • Critical-tagged operations run before non-critical operations when ready, while preserving order within each priority group.
  • Added a watchdog skill and standalone script that reports Gas City health and exits only when real work is complete and the city is healthy.
  • Added documentation describing the watchdog checks, reporting, and clean-idle exit conditions.

Impact

✅ Critical checks run sooner
✅ Tags remain available for operation filtering and categorization
✅ Clearer visibility into Gas City health and remaining work

🔄 Retrigger CodeAnt AI Review

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai

codeant-ai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 50a1c97 Aug 10, 2026 · 20:20 20:20
✅ Reviewed your PR 5ad921e Aug 10, 2026 · 12:22 12:25

@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

@ThePlenkov, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: dc42c4c9-adc1-4b2a-bdf8-920ae38dcd53

📥 Commits

Reviewing files that changed from the base of the PR and between b92ba98 and 238bef0.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • website/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (259)
  • .agents/skills/gc-watchdog/SKILL.md
  • .agents/skills/gc-watchdog/watchdog.sh
  • .codacy.yml
  • REVIEW.md
  • SECURITY.md
  • engdocs/README.md
  • engdocs/adr/ADR-007-runtime-scheduler-design.md
  • engdocs/adr/ADR-008-tags-and-critical-prioritization.md
  • engdocs/architecture/wave-03-runtime-plan.md
  • engdocs/architecture/wave-04-runtime-host-plan.md
  • engdocs/architecture/wave-05-runtime-docker-plan.md
  • engdocs/architecture/wave-06-planner-plan.md
  • engdocs/architecture/wave-07-findings-plan.md
  • engdocs/architecture/wave-08-policy-plan.md
  • engdocs/architecture/wave-09-sdk-plan.md
  • engdocs/architecture/wave-10-cli-plan.md
  • engdocs/architecture/wave-11-checks-plan.md
  • engdocs/architecture/wave-12-compiler-github-plan.md
  • engdocs/architecture/wave-13-compiler-gitlab-plan.md
  • engdocs/architecture/wave-14-website-plan.md
  • engdocs/architecture/wave-15-documentation-plan.md
  • engdocs/user/README.md
  • engdocs/user/checks/builtin.md
  • engdocs/user/cli/overview.md
  • engdocs/user/compilers/github.md
  • engdocs/user/compilers/gitlab.md
  • engdocs/user/findings/normalization.md
  • engdocs/user/getting-started/first-plan.md
  • engdocs/user/getting-started/install.md
  • engdocs/user/policy/evaluation.md
  • engdocs/user/workflow-api/overview.md
  • eslint.config.mjs
  • pack.toml
  • pack/README.md
  • pack/agents/architect/agent.toml
  • pack/agents/architect/prompt.template.md
  • pack/agents/builder/agent.toml
  • pack/agents/builder/prompt.template.md
  • pack/agents/mayor/agent.toml
  • pack/agents/mayor/prompt.template.md
  • pack/agents/reviewer/agent.toml
  • pack/agents/reviewer/prompt.template.md
  • pack/docs/agent-guide.md
  • pack/docs/agents/architect.md
  • pack/docs/agents/builder.md
  • pack/docs/agents/mayor.md
  • pack/docs/agents/reviewer.md
  • pack/formulas/address-review.toml
  • pack/formulas/bootstrap-sdd.toml
  • pack/formulas/wave.toml
  • pack/pack.toml
  • pack/skills/sverka-drill/SKILL.md
  • pack/skills/sverka-review/SKILL.md
  • pack/skills/sverka-wave/SKILL.md
  • pack/template-fragments/conventions.md
  • pack/template-fragments/review-policy.md
  • pack/template-fragments/security-policy.md
  • package.json
  • packages/checks/package.json
  • packages/checks/project.json
  • packages/checks/src/__tests__/errors.test.ts
  • packages/checks/src/__tests__/extract.test.ts
  • packages/checks/src/__tests__/helpers/fixtures.ts
  • packages/checks/src/__tests__/public-api.test.ts
  • packages/checks/src/__tests__/resolver.test.ts
  • packages/checks/src/errors.ts
  • packages/checks/src/extract.ts
  • packages/checks/src/index.ts
  • packages/checks/src/resolver.ts
  • packages/cli/package.json
  • packages/cli/project.json
  • packages/cli/src/__tests__/baseline.test.ts
  • packages/cli/src/__tests__/bin.test.ts
  • packages/cli/src/__tests__/doctor.test.ts
  • packages/cli/src/__tests__/execute.test.ts
  • packages/cli/src/__tests__/helpers/fixtures.ts
  • packages/cli/src/__tests__/init.test.ts
  • packages/cli/src/__tests__/inspect.test.ts
  • packages/cli/src/__tests__/main.test.ts
  • packages/cli/src/__tests__/output.test.ts
  • packages/cli/src/__tests__/plan.test.ts
  • packages/cli/src/__tests__/public-api.test.ts
  • packages/cli/src/__tests__/validate.test.ts
  • packages/cli/src/bin.ts
  • packages/cli/src/commands/baseline.ts
  • packages/cli/src/commands/doctor.ts
  • packages/cli/src/commands/execute.ts
  • packages/cli/src/commands/init.ts
  • packages/cli/src/commands/inspect.ts
  • packages/cli/src/commands/plan.ts
  • packages/cli/src/commands/validate.ts
  • packages/cli/src/index.ts
  • packages/cli/src/internal/paths.ts
  • packages/cli/src/internal/runtime-check.ts
  • packages/cli/src/main.ts
  • packages/cli/src/output.ts
  • packages/cli/src/types.ts
  • packages/cli/tsdown.config.ts
  • packages/cli/vitest.config.ts
  • packages/compiler-earthly/package.json
  • packages/compiler-github/package.json
  • packages/compiler-github/project.json
  • packages/compiler-github/src/__tests__/compile.test.ts
  • packages/compiler-github/src/__tests__/helpers/fixtures.ts
  • packages/compiler-github/src/__tests__/public-api.test.ts
  • packages/compiler-github/src/compile.ts
  • packages/compiler-github/src/index.ts
  • packages/compiler-github/src/types.ts
  • packages/compiler-gitlab/package.json
  • packages/compiler-gitlab/project.json
  • packages/compiler-gitlab/src/__tests__/compile.test.ts
  • packages/compiler-gitlab/src/__tests__/helpers/fixtures.ts
  • packages/compiler-gitlab/src/__tests__/public-api.test.ts
  • packages/compiler-gitlab/src/compile.ts
  • packages/compiler-gitlab/src/index.ts
  • packages/compiler-gitlab/src/types.ts
  • packages/core/package.json
  • packages/core/src/internal/plan.ts
  • packages/findings/package.json
  • packages/findings/project.json
  • packages/findings/src/__tests__/baseline.test.ts
  • packages/findings/src/__tests__/errors.test.ts
  • packages/findings/src/__tests__/fingerprint.test.ts
  • packages/findings/src/__tests__/helpers/fixtures.ts
  • packages/findings/src/__tests__/normalize.test.ts
  • packages/findings/src/__tests__/public-api.test.ts
  • packages/findings/src/__tests__/suppress.test.ts
  • packages/findings/src/baseline.ts
  • packages/findings/src/errors.ts
  • packages/findings/src/fingerprint.ts
  • packages/findings/src/index.ts
  • packages/findings/src/normalize.ts
  • packages/findings/src/suppress.ts
  • packages/findings/src/types.ts
  • packages/ir/package.json
  • packages/ir/src/__tests__/validate.test.ts
  • packages/ir/src/plan.ts
  • packages/ir/src/validate.ts
  • packages/planner/package.json
  • packages/planner/project.json
  • packages/planner/src/__tests__/discover.test.ts
  • packages/planner/src/__tests__/errors.test.ts
  • packages/planner/src/__tests__/helpers/fixtures.ts
  • packages/planner/src/__tests__/plan.test.ts
  • packages/planner/src/__tests__/public-api.test.ts
  • packages/planner/src/detect.ts
  • packages/planner/src/errors.ts
  • packages/planner/src/explain.ts
  • packages/planner/src/index.ts
  • packages/planner/src/internal/git-cli.ts
  • packages/planner/src/planner.ts
  • packages/policy/package.json
  • packages/policy/project.json
  • packages/policy/src/__tests__/errors.test.ts
  • packages/policy/src/__tests__/evaluator.test.ts
  • packages/policy/src/__tests__/helpers/fixtures.ts
  • packages/policy/src/__tests__/policy.test.ts
  • packages/policy/src/__tests__/public-api.test.ts
  • packages/policy/src/errors.ts
  • packages/policy/src/evaluator.ts
  • packages/policy/src/index.ts
  • packages/policy/src/policy.ts
  • packages/policy/src/types.ts
  • packages/runtime-docker/package.json
  • packages/runtime-docker/project.json
  • packages/runtime-docker/src/__tests__/cache.test.ts
  • packages/runtime-docker/src/__tests__/docker-executor.test.ts
  • packages/runtime-docker/src/__tests__/errors.test.ts
  • packages/runtime-docker/src/__tests__/helpers/fixtures.ts
  • packages/runtime-docker/src/__tests__/image.test.ts
  • packages/runtime-docker/src/__tests__/integration.test.ts
  • packages/runtime-docker/src/__tests__/public-api.test.ts
  • packages/runtime-docker/src/cache.ts
  • packages/runtime-docker/src/config.ts
  • packages/runtime-docker/src/docker-executor.ts
  • packages/runtime-docker/src/errors.ts
  • packages/runtime-docker/src/image.ts
  • packages/runtime-docker/src/index.ts
  • packages/runtime-docker/src/internal/docker-cli.ts
  • packages/runtime-host/package.json
  • packages/runtime-host/src/__tests__/allowlist.test.ts
  • packages/runtime-host/src/__tests__/errors.test.ts
  • packages/runtime-host/src/__tests__/helpers/fixtures.ts
  • packages/runtime-host/src/__tests__/host-executor.test.ts
  • packages/runtime-host/src/__tests__/public-api.test.ts
  • packages/runtime-host/src/allowlist.ts
  • packages/runtime-host/src/config.ts
  • packages/runtime-host/src/errors.ts
  • packages/runtime-host/src/host-executor.ts
  • packages/runtime-host/src/index.ts
  • packages/runtime-podman/package.json
  • packages/runtime-remote/package.json
  • packages/runtime/package.json
  • packages/runtime/project.json
  • packages/runtime/src/__tests__/cache.test.ts
  • packages/runtime/src/__tests__/errors.test.ts
  • packages/runtime/src/__tests__/helpers/fixtures.ts
  • packages/runtime/src/__tests__/parse.test.ts
  • packages/runtime/src/__tests__/public-api.test.ts
  • packages/runtime/src/__tests__/resource-limits.test.ts
  • packages/runtime/src/__tests__/resource-pool.test.ts
  • packages/runtime/src/__tests__/retry.test.ts
  • packages/runtime/src/__tests__/scheduler.test.ts
  • packages/runtime/src/__tests__/state-store.test.ts
  • packages/runtime/src/__tests__/topo.test.ts
  • packages/runtime/src/cache.ts
  • packages/runtime/src/errors.ts
  • packages/runtime/src/executor.ts
  • packages/runtime/src/index.ts
  • packages/runtime/src/internal/parse.ts
  • packages/runtime/src/internal/resource-pool.ts
  • packages/runtime/src/internal/topo.ts
  • packages/runtime/src/result.ts
  • packages/runtime/src/scheduler.ts
  • packages/runtime/src/state-store.ts
  • packages/sdk/package.json
  • packages/sdk/project.json
  • packages/sdk/src/__tests__/convert.test.ts
  • packages/sdk/src/__tests__/define-workflow.test.ts
  • packages/sdk/src/__tests__/errors.test.ts
  • packages/sdk/src/__tests__/execute-mode.test.ts
  • packages/sdk/src/__tests__/find-config.test.ts
  • packages/sdk/src/__tests__/helpers/fixtures.ts
  • packages/sdk/src/__tests__/load-workflow.test.ts
  • packages/sdk/src/__tests__/plan-mode.test.ts
  • packages/sdk/src/__tests__/public-api.test.ts
  • packages/sdk/src/__tests__/re-exports.test.ts
  • packages/sdk/src/__tests__/task.test.ts
  • packages/sdk/src/config.ts
  • packages/sdk/src/convert.ts
  • packages/sdk/src/errors.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/internal/plan-runtime.ts
  • packages/sdk/src/sverka.ts
  • packages/sdk/src/types.ts
  • skills/sverka/SKILL.md
  • skills/sverka/references/troubleshooting.md
  • specs/03-runtime/spec.md
  • specs/04-runtime-docker/spec.md
  • specs/05-runtime-host/spec.md
  • specs/06-planner/spec.md
  • specs/07-findings/spec.md
  • specs/08-policy/spec.md
  • specs/09-sdk/spec.md
  • specs/10-cli/spec.md
  • specs/11-checks/spec.md
  • specs/12-compiler-github/spec.md
  • specs/13-compiler-gitlab/spec.md
  • specs/15-documentation/spec.md
  • specs/16-test-harness/spec.md
  • template-fragments/project-context.md
  • website/astro.config.mjs
  • website/package.json
  • website/public/robots.txt
  • website/src/layouts/Base.astro
  • website/src/pages/404.astro
  • website/src/pages/docs.astro
  • website/src/pages/getting-started.astro
  • website/src/pages/index.astro

Comment @coderabbitai help to get the list of available commands.

@codacy-production

codacy-production Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 39 high · 39 medium · 22 minor

Alerts:
⚠ 100 issues (≤ 0 issues of at least minor severity)

Results:
100 new issues

Category Results
Compatibility 19 medium
15 high
UnusedCode 1 medium
BestPractice 1 medium
ErrorProne 24 high
Complexity 14 medium
22 minor
Performance 4 medium

View in Codacy

🟢 Metrics 895 complexity · 24 duplication

Metric Results
Complexity 895
Duplication 24

View in Codacy

AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Aug 10, 2026

@amazon-q-developer amazon-q-developer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This PR adds a tags field for operation prioritization and a gc-watchdog monitoring skill. The implementation is well-structured with comprehensive test coverage (3 IR validation tests, 2 SDK conversion tests, 2 runtime topo tests all passing).

Critical Issue

  • Shell script logic error: The regex pattern in watchdog.sh line 22 expects exactly 4 characters after sv- but attempts to filter sv-wisp-XXXX patterns that don't match, potentially causing incorrect issue counts.

Positive Aspects

  • TypeScript changes follow existing patterns with proper readonly modifiers and optional chaining
  • Critical-check prioritization uses stable sort to preserve input order within priority groups
  • Test coverage validates both positive and negative cases for the tags field
  • ADR-008 provides architectural context for the changes

The TypeScript implementation is solid. Address the shell script regex issue before merging.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Comment thread .agents/skills/gc-watchdog/watchdog.sh
@baz-reviewer

baz-reviewer Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Merger

Needs Review

PR exceeds the merge-gate context budget (317293 tokens); escalating to a human reviewer.

Commit 238bef0 · Evaluated 2026-08-11 06:32 UTC

Review this PR on Baz | Customize your next review

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

The PR successfully implements the tags field and critical task prioritization, but several reliability issues in the new gc-watchdog skill and an algorithmic inefficiency in the runtime need to be addressed before merging.

While the project remains 'up to standards' according to Codacy, the gc-watchdog script is highly susceptible to crashes due to set -o pipefail interacting with grep assignments, and it lacks any automated test coverage. Additionally, the topological sort implementation has been changed from O(V+E) to O(V^2 log V). While acceptable for small plans, a more efficient two-queue approach should be used to maintain performance as the system scales.

About this PR

  • The gc-watchdog script relies heavily on regex/awk parsing of CLI tool outputs (gc status, bd list). This is inherently fragile as any change to the CLI output format will break the watchdog's health-check logic. Combined with the lack of automated tests for this script, this poses a high maintenance risk.
1 comment outside of the diff
packages/runtime/src/internal/topo.ts

line 16 ⚪ LOW RISK
Update the documentation at the top of topoSort to reflect that 'critical' tagged operations take priority over the default input order. The current comment still claims operations are emitted in input order, which is now only true within priority groups.

Test suggestions

  • Found: Validate that the IR PlanOperation accepts present, absent, and empty tags arrays.
  • Found: Verify that the SDK correctly copies tags from the specification to the generated plan.
  • Found: Verify that critical-tagged operations are sorted ahead of non-critical siblings when both are ready.
  • Found: Verify that topological sort preserves relative input order for operations within the same priority group.
  • Missing: Verify that the gc-watchdog script correctly identifies and filters 'wisp' and 'nudge' tasks from the open work count.
  • Missing: Verify that the gc-watchdog script exits with code 0 when the city is idle and healthy, but stays running on failures.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Missing: Verify that the gc-watchdog script correctly identifies and filters 'wisp' and 'nudge' tasks from the open work count.
2. Missing: Verify that the gc-watchdog script exits with code 0 when the city is idle and healthy, but stays running on failures.

TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback

Comment thread .agents/skills/gc-watchdog/watchdog.sh
Comment thread packages/runtime/src/internal/topo.ts
Comment thread .agents/skills/gc-watchdog/watchdog.sh
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add tags field, critical-check prioritization in topoSort, gc-watchdog skill

✨ Enhancement 📝 Documentation 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Adds optional tags?: readonly string[] to IR PlanOperation for prioritization, filtering, and
 categorization.
• Passes spec.tags through from OperationSpec to PlanOperation in the SDK converter.
• Prioritizes "critical"-tagged operations among ready siblings in runtime topoSort via a new
 stable sortReadyByPriority() helper.
• Adds ADR-008 documenting the decision, and a new project-local gc-watchdog skill (SKILL.md +
 standalone script) for monitoring Gas City until idle.
• Adds TDD test coverage across IR validation, SDK conversion, and runtime topo sort.
Diagram

graph TD
  A["OperationSpec.tags"] --> B["convertOperation()"] --> C["PlanOperation.tags"]
  C --> D["topoSort()"]
  D --> E["sortReadyByPriority()"]
  E --> F["Ordered ready queue"]
  G["gc-watchdog.sh"] --> H["gc status / bd list"]
Loading
High-Level Assessment

The chosen approach—an optional string-tags array with a simple stable 'critical first' sort in topoSort—is appropriate for the stated scope. It's additive (no schema bump), backward-compatible, and the ADR explicitly evaluates and rejects a boolean critical field and a full priority-queue scheduler as over-engineered for the current need. No better alternative stands out for this scale of requirement.

Files changed (9) +303 / -2

Enhancement (3) +38 / -2
plan.tsAdd optional tags field to PlanOperation +3/-0

Add optional tags field to PlanOperation

• Adds 'readonly tags?: readonly string[]' to the PlanOperation interface for prioritization, filtering, and categorization.

packages/ir/src/plan.ts

convert.tsPass through OperationSpec.tags to PlanOperation +1/-0

Pass through OperationSpec.tags to PlanOperation

• convertOperation now copies 'spec.tags' into the resulting PlanOperation when present, omitting the field otherwise.

packages/sdk/src/convert.ts

topo.tsPrioritize critical-tagged ops in topoSort ready queue +34/-2

Prioritize critical-tagged ops in topoSort ready queue

• Introduces sortReadyByPriority(), a stable sort placing ops tagged 'critical' first among ready siblings, applied both at initial ready-queue construction and whenever new operations become ready.

packages/runtime/src/internal/topo.ts

Tests (3) +69 / -0
validate.test.tsAdd tests for tags field validation +22/-0

Add tests for tags field validation

• Adds three tests confirming validatePlan accepts operations with tags, without tags, and with an empty tags array.

packages/ir/src/tests/validate.test.ts

convert.test.tsAdd tests for tags pass-through in convertToPlan +18/-0

Add tests for tags pass-through in convertToPlan

• Adds tests verifying tags are copied from OperationSpec to PlanOperation when present and omitted when absent.

packages/sdk/src/tests/convert.test.ts

topo.test.tsAdd tests for critical-tag prioritization in topoSort +29/-0

Add tests for critical-tag prioritization in topoSort

• Adds tests confirming critical-tagged ops are scheduled first among independent ready ops and among siblings that become ready after a shared dependency completes.

packages/runtime/src/tests/topo.test.ts

Documentation (2) +126 / -0
ADR-008-tags-and-critical-prioritization.mdAdd ADR-008 for tags field and critical prioritization +60/-0

Add ADR-008 for tags field and critical prioritization

• Documents the decision to add tags to PlanOperation and prioritize critical-tagged ops in topoSort, including alternatives considered and consequences.

engdocs/adr/ADR-008-tags-and-critical-prioritization.md

SKILL.mdAdd gc-watchdog skill documentation +66/-0

Add gc-watchdog skill documentation

• New skill describing a periodic Gas City health monitor: check cycle, exit conditions, and reporting format for use by agents or as a standalone script.

.agents/skills/gc-watchdog/SKILL.md

Other (1) +70 / -0
watchdog.shAdd standalone gc-watchdog monitoring script +70/-0

Add standalone gc-watchdog monitoring script

• New bash script that polls gc status and bd list on an interval, reports mayor/session/controller health, and exits cleanly once no open or in-progress real work remains.

.agents/skills/gc-watchdog/watchdog.sh

Comment thread packages/ir/src/plan.ts
Comment thread .agents/skills/gc-watchdog/watchdog.sh
Comment thread .agents/skills/gc-watchdog/watchdog.sh
Comment thread packages/runtime/src/internal/topo.ts
@qodo-code-review

qodo-code-review Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Tags not validated 🐞 Bug ≡ Correctness
Description
topoSort now calls op.tags?.includes("critical"), but validatePlan does not validate
operations[].tags at all. A malformed plan can pass IR validation and then throw at runtime when
scheduling/toposorting.
Code

packages/runtime/src/internal/topo.ts[R38-41]

+  const isCritical = new Map<string, boolean>();
+  for (const op of ops) {
+    isCritical.set(op.id, op.tags?.includes("critical") ?? false);
+  }
Evidence
The PR introduces runtime dependence on tags.includes(...) but IR validation still treats
operations as untyped records and enumerates per-op rules that do not include tags, allowing
invalid tags values to be considered valid plans and later crash runtime.

packages/runtime/src/internal/topo.ts[37-41]
packages/ir/src/validate.ts[170-176]
packages/ir/src/validate.ts[356-360]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Runtime topoSort now evaluates `op.tags?.includes("critical")`. Optional chaining only protects `null|undefined`; if `tags` is present but not an array (e.g. `{}`), the method call can throw and crash scheduling.

## Issue Context
IR validation (`validatePlan`) is the boundary for untrusted plan JSON (via `deserializePlan`). It currently validates many per-operation fields but not `tags`.

## Fix Focus Areas
- packages/ir/src/validate.ts[170-220]
- packages/runtime/src/internal/topo.ts[37-41]

## Implementation notes
- In `validatePlan` per-operation loop, add a rule:
 - If `op.tags` is defined, require `Array.isArray(op.tags)` and every element is a string.
 - Add a `ValidationErrorDetail` with a new code (e.g. `INVALID_TAGS`) on failure.
- Optionally add a defensive check in `topoSort`:
 - `const tags = op.tags; const critical = Array.isArray(tags) && tags.includes("critical");`
- Add/extend unit tests to cover invalid `tags` shapes (object/number elements) failing validation.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. errexit breaks parsing 🐞 Bug ☼ Reliability
Description
With set -euo pipefail, the unguarded grep|awk parsing pipelines for
MAYOR/SESSIONS/SUSPENDED/CONTROLLER can terminate the watchdog whenever a line is missing or format
changes. This contradicts the intended behavior of reporting issues and continuing to monitor on
failure.
Code

.agents/skills/gc-watchdog/watchdog.sh[R11-43]

+set -euo pipefail
+
+INTERVAL="${1:-60}"
+ITER=0
+
+# Filter out ephemeral wisp/nudge beads from bd output.
+# Real issues have IDs like sv-XXXX (4 chars after sv-).
+# Wisp/nudge beads have IDs like sv-wisp-XXXX or sv-nudge-XXXX.
+count_real_issues() {
+  local status="$1"
+  bd list --status="$status" 2>/dev/null \
+    | grep -E '^\s*○ sv-[a-z0-9]{4} ' \
+    | grep -v "wisp\|nudge" \
+    | wc -l || true
+}
+
+while true; do
+  ITER=$((ITER + 1))
+  TS=$(date '+%H:%M:%S')
+
+  # 1. gc status
+  STATUS=$(timeout 15 gc status 2>/dev/null || true)
+
+  if [ -z "$STATUS" ]; then
+    echo "[$TS] #$ITER ⚠ gc status timeout/error"
+    sleep "$INTERVAL"
+    continue
+  fi
+
+  MAYOR=$(echo "$STATUS" | grep "harness.mayor" | awk '{print $2}')
+  SESSIONS=$(echo "$STATUS" | grep "Sessions:" | head -1 | sed 's/^ *//')
+  SUSPENDED=$(echo "$STATUS" | grep "Suspended:" | awk '{print $2}')
+  CONTROLLER=$(echo "$STATUS" | grep "Controller:" | grep -o "supervisor-managed\|stopped\|error" | head -1)
Evidence
The script explicitly turns on errexit+pipefail and then performs several field extractions via
grep pipelines without || true. Since grep returns non-zero on no match, the watchdog can exit
immediately instead of emitting a warning and continuing.

.agents/skills/gc-watchdog/watchdog.sh[11-43]
🌐 Explains that with set -o errexit (bash -e), a grep returning exit status 1 (no match) will cause the script to exit unless handled explicitly.

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The script enables `set -euo pipefail` but uses `grep` pipelines in command substitutions to extract fields. When `grep` finds no match it exits 1; with `pipefail` this fails the whole pipeline and with `-e` the script can exit immediately.

## Issue Context
This is especially likely during the abnormal situations the watchdog should keep running through (missing fields, partial output, format drift).

## Fix Focus Areas
- .agents/skills/gc-watchdog/watchdog.sh[11-55]

## Implementation notes
- Make each extraction non-fatal, e.g.:
 - `MAYOR=$(echo "$STATUS" | awk '/harness\.mayor/{print $2; exit}' || true)`
 - `SESSIONS=$(echo "$STATUS" | awk -F': ' '/Sessions:/{print $0; exit}' || true)`
 - `SUSPENDED=$(echo "$STATUS" | awk '/Suspended:/{print $2; exit}' || true)`
 - `CONTROLLER=$(echo "$STATUS" | awk '/Controller:/{print $2}' | grep -Eo '(supervisor-managed|stopped|error)' | head -1 || true)`
- Alternatively, temporarily disable errexit around parsing (`set +e` / `set -e`).
- Ensure downstream checks handle empty values (they already attempt to).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Watchdog miscounts work 🐞 Bug ≡ Correctness
Description
watchdog.sh uses grep -E '^\s*…' to match leading whitespace, but \s is not POSIX ERE and is
not consistently supported across grep implementations. On affected systems this can undercount
open/in-progress work and incorrectly trigger the IDLE exit condition.
Code

.agents/skills/gc-watchdog/watchdog.sh[R21-24]

+  bd list --status="$status" 2>/dev/null \
+    | grep -E '^\s*○ sv-[a-z0-9]{4} ' \
+    | grep -v "wisp\|nudge" \
+    | wc -l || true
Evidence
The script’s counting pipeline uses grep -E with \s, which is documented as not
meaningful/portable in POSIX grep regex modes; recommended portable form is [[:space:]]. This
directly affects the counts used in the exit condition.

.agents/skills/gc-watchdog/watchdog.sh[19-25]
🌐 Notes that \s is not meaningful in POSIX grep regex modes and recommends using [[:space:]] for portable whitespace matching.

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The script relies on `grep -E '^\s*…'` to match leading whitespace. `\s` is not portable in POSIX ERE/BRE, so the match can fail depending on grep version/implementation, causing counts to be wrong (often 0) and the watchdog to exit early.

## Issue Context
This impacts the core exit condition logic: `OPEN_COUNT` / `INPROG_COUNT` can be computed incorrectly.

## Fix Focus Areas
- .agents/skills/gc-watchdog/watchdog.sh[19-25]

## Implementation notes
- Replace `^\s*` with `^[[:space:]]*` (or `^ *` if you only expect spaces).
- Consider switching the subsequent alternation uses to ERE too (e.g. `grep -E -v '(wisp|nudge)'`) for consistency.
- Keep the existing `|| true` guard in `count_real_issues`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context used
✅ Web pages:
  +7 more
Review mode: ⚖️ Balanced: Behavioral changes span the IR/SDK contract, runtime scheduling, and an operational watchdog script, so a careful full review is warranted; the logic is not dense enough to justify redundant extended passes.

Grey Divider

Tip of the day
💡 Did you know, you can group findings by type and pick your Finding display, from Minimal to Full

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread packages/runtime/src/internal/topo.ts
Comment thread .agents/skills/gc-watchdog/watchdog.sh
Comment thread .agents/skills/gc-watchdog/watchdog.sh
@ThePlenkov ThePlenkov mentioned this pull request Aug 10, 2026
6 tasks done
@ThePlenkov
ThePlenkov force-pushed the feat-tags-and-watchdog branch from 5ad921e to 50a1c97 Compare August 10, 2026 20:20
@codeant-ai codeant-ai Bot added size:L This PR changes 100-499 lines, ignoring generated files and removed size:L This PR changes 100-499 lines, ignoring generated files labels Aug 10, 2026
@ThePlenkov
ThePlenkov force-pushed the decouple-gascity-pack branch 2 times, most recently from 1c91c54 to cdee22f Compare August 11, 2026 00:34
ThePlenkov and others added 5 commits August 11, 2026 08:31
Backend-agnostic runtime: Executor interface (canExecute/execute), Scheduler
with topological sort, concurrent execution within maxConcurrent + optional
CPU/memory resource pool, dependent cancellation on fatal failure,
continueOnError, StateStore persistence for resume, CacheBackend reuse,
RetryPolicy, log/artifact collection.

<details>
- 64 vitest tests pass
- typecheck clean
- build green
- fixes sv-iqe: ResourcePool now created when either totalCpu or totalMemory
  is set (independent optionals per spec), defaulting the unset dimension to
  Infinity
</details>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
HostExecutor implementation: allowlist enforcement, env/credential
passing, artifact collection, log truncation, timeout + SIGKILL grace.
47 tests pass across 4 files (allowlist, errors, host-executor, public-api).
Typecheck clean, build produces dist/index.mjs + dist/index.d.mts.
Reviewer approved (sv-gab). Spec 05 amended to match built runtime contract.

<details>
- 47 tests pass
- typecheck clean
- build green
- reviewer approved
</details>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Created eslint.config.mjs (TypeScript-aware, strict, ESM, ESLint 9 flat config)
- Added typescript-eslint dependency
- Fixed all per-package lint scripts: removed legacy --ext .ts flag (removed in ESLint 9)
- Fixed dead imports: core/plan.ts (OperationOutcome), ir/validate.ts (PlanOperation), runtime-host/host-executor.ts (HostTimeoutError)
- Relaxed no-unused-vars to warn for test files (standard practice)
- Lint now passes repo-wide

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
DockerExecutor implementation: container lifecycle, image pulling,
volume mounts, env/credential passing, artifact collection, cache
management, timeout handling. Mockable docker-cli.ts seam for unit
tests without Docker daemon. Integration tests skip if no Docker.
58 tests pass + 2 skipped (integration). Spec 04 amended to match
built runtime contract. Reviewer APPROVED after rework (sv-b3u):
collectArtifacts + mount-socket throw test added.

<details>
- 58 tests pass + 2 skipped (integration)
- typecheck clean
- build green (dist index.mjs 11.40kB + index.d.mts 4.89kB)
- lint clean
- reviewer approved (sv-1i2)
</details>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
PlannerImpl with discover() (local signals: languages, package managers,
monorepo markers, changed files) and plan() (default plan synthesis).
Standalone package (no @sverka/* deps). Mockable git-cli.ts seam.
41 tests pass (errors 5, discover 25, plan 8, public-api 3). Spec 06
trimmed to local-only discover + default plan synthesis. Reviewer
APPROVED with 3 non-blocking nits (MonorepoMarker globs, root
package.json signal, ProposedCheck.id truncation).

<details>
- 41 tests pass
- typecheck clean
- build green
- lint clean
- reviewer approved (sv-zgk)
</details>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ThePlenkov and others added 22 commits August 11, 2026 08:31
…, version extraction

- Resolve relative --config/--baseline paths against --root (not process cwd)
  via new internal/paths.ts resolveUnderRoot helper (baseline, execute, plan, validate)
- Serialize execute outcomes as plain object (Map→Object.fromEntries) for JSON output
- Forward --only-new to SDK in plan command (was silently dropped)
- Extract numeric version in doctor (regex x.y.z from "git version 2.43.0")
- Add 5s timeout to doctor runCheck (prevent hung shim blocking CLI)
- Wrap loadBaseline errors as CliError(SDK_ERROR) in baseline update/show
- Use process.exitCode instead of process.exit() in bin.ts (avoid truncating buffered I/O)
- Add tests: doctor version extraction, execute baseline path + outcomes, validate config path

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… narrowing, function order

- init: use flag:"wx" (exclusive create) when !force to close TOCTOU race
  between existsSync and writeFile; translate EEXIST to CONFIG_EXISTS
- bin.test.ts: fix it.skip() inside it() — tests silently passed when
  dist/bin.mjs was missing; use it.skipIf(!binBuilt) at describe level
- doctor.test.ts: type-narrow JSON.parse result with `as` casts (no any)
- baseline.ts: reorder helper functions before dispatcher (readability)

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
bun.lock still recorded sverka bin as ./dist/index.mjs (the library
entry, no shebang/bootstrap) while package.json declares ./dist/bin.mjs.
Regenerated lockfile entry so lockfile-based installs link the correct
executable.

Addresses qodo-code-review and cubic-dev-ai review threads on bun.lock.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Address PR #12 review feedback (qodo-code-review threads):

1. Absolute baseline path misresolved: resolveBaselinePath used path.join
   which rebases absolute --baseline paths beneath --root. Now uses
   resolveUnderRoot which preserves absolute paths.

2. Clear misses concurrent creation: baselineClear checked existsSync
   before unlink, creating a TOCTOU window. Now always calls unlink and
   catches only ENOENT, closing the race.

Tests: 74 pass (was 72, +2 new: absolute baseline path, clear without
existsSync guard). Full monorepo 16 projects green.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Address Codacy finding: spawnSync without a timeout could block
indefinitely if a binary hangs. Added timeout: 5000 to match the
reliable behavior in doctor.ts.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ion)

CheckResolver.resolve() maps ProposedCheck + ProjectContext to ResolvedCheck
(OperationSpec + CheckOutput[]). createBuiltinResolver() covers 6 checkIds
(typecheck, lint, test, clippy, vet, fmt-check) across Node/Python/Rust/Go.
extractFindings() reads SARIF artifacts via @sverka/findings.normalizeSarif.
CheckError(RESOLUTION_FAILED|EXTRACTION_FAILED) with override on cause.

SDK integration: doPlan/doExecute resolve proposed checks into operations,
extract findings from SARIF output artifacts after execution. Re-exports
added to @sverka/sdk.

32 checks tests + 3 new SDK tests (63 total). Full monorepo green (16 proj).

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Pure function compileGithubWorkflow(plan, config?) that compiles a canonical
Sverka Plan to a GitHub Actions workflow YAML string. Thin wrapper per
ADR-004: single job runs `sverka execute .sverka/plan.json`. Maps plan
credentials to job-level env block with ${{ secrets.VAR }} references.
camelCase→kebab-case conversion for permissions and triggers. Deterministic
output. No custom errors (pure function on validated Plan). 13 tests pass.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…-bun, execute cmd, interface order

Address PR #14 review feedback:

1. toKebab leading hyphen: regex added offset check so capitalized first
   chars don't get a leading hyphen (amazon-q).
2. idToken permission: removed "read" — GitHub Actions only supports
   "write" for id-token (codeant-ai).
3. sverka execute: removed .sverka/plan.json positional arg — CLI uses
   strict yargs and rejects unknown args (codeant-ai, critical).
4. setup-bun: added oven-sh/setup-bun@v2 step — ubuntu-latest doesn't
   include bun (codacy).
5. Interface ordering: moved GithubTriggers and GithubPermissions before
   GithubCompilerConfig (codacy).

Tests: 13 pass. Full monorepo 16 projects green.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
<details>
- 8 tests pass (2 files)
- typecheck clean
- build green
- reviewer approved (no nits)
</details>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…cmd, empty rules

Address PR #16 review feedback:

1. Default image: changed from node:24 to oven/bun:latest — node:24 does
   not include bun, so before_script would fail (codeant, qodo).
2. Execute command: removed .sverka/plan.json positional arg — CLI uses
   strict yargs and rejects unknown args (qodo).
3. Empty rule filtering: filter out empty rule objects {} that would
   produce invalid GitLab CI YAML (codeant).

Tests: 6 pass (was 5, +1 empty rules filtered). Full monorepo 16 proj green.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Add sitemap integration, canonical URLs, 404 page, robots.txt, and fix
all code examples to match the actual Sverka SDK API (defineWorkflow,
pipeline, task, run from @sverka/sdk). Remove references to non-existent
callback-based pipeline API and non-existent `sverka compile` CLI command.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Address PR #17 review feedback (codeant-ai):

The quick start installed only the global CLI (@sverka/cli), but
sverka init generates a config that imports @sverka/sdk. Without
a project-local SDK install, plan/execute/validate fail with a
package resolution error. Added `bun add @sverka/sdk` to both
index.astro and getting-started.astro install instructions.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Write 10 user-facing documentation pages covering:
- Getting started (install, first plan)
- Workflow API (pipeline, run, parallel, when, matrix, task, defineWorkflow)
- CLI reference (7 commands, global flags, exit codes)
- Built-in checks (6 check IDs, per-PM resolution, SARIF extraction)
- Compilation targets (GitHub Actions, GitLab CI)
- Findings normalization (normalizeSarif, fingerprints, baselines, filterOnlyNew)
- Policy evaluation (evaluatePolicy, DEFAULT_POLICY, createPolicy, verdicts)

Also updates engdocs/README.md with user docs section and
website/src/pages/docs.astro with links to GitHub paths.

All code examples verified against actual SDK exports. All internal
markdown links resolve. All code fences balanced. Website builds.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…T_POLICY, runtime SDK exports

Corrects 3 documentation accuracy issues from reviewer second pass:
- extractFindings: async, 3 positional args (outputs, artifactDir, checkId), SARIF-only
- DEFAULT_POLICY: both failOn rules (high/all + medium/onlyNew)
- workflow-api/overview.md: added Runtime SDK exports section (30 exports)

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Extract the four-role agent team (mayor/architect/builder/reviewer) and
workflow formulas (wave, address-review, bootstrap-sdd) from sverka-specific
root config into a reusable pack at pack/.

The pack is now imported under binding "harness" via [imports.harness] in
pack.toml. Project-specific context (project name, tech stack, wave plan) is
injected via append_fragments patches pointing to
template-fragments/project-context.md.

This separates three layers:
  1. Harness (pack/): reusable roles + formulas + doc templates
  2. Project docs (REVIEW.md, SECURITY.md, AGENTS.md): project-owned policy
  3. Project content (specs/, engdocs/, packages/): project-owned code

To reuse in another project: import this pack via GitHub source, create a
project-context.md fragment, copy REVIEW.md/SECURITY.md/AGENTS.md templates.

Added:
  - pack/ — sverka-gc-pack (agents, formulas, template-fragments, README)
  - REVIEW.md — sverka review policy (two-axis, verification bar, commit hygiene)
  - SECURITY.md — sverka security policy
  - template-fragments/project-context.md — sverka context injected into agents

Changed:
  - pack.toml — imports ./pack as harness, patches agents with project-context
  - agents/{mayor,architect,builder,reviewer}/ — moved to pack/agents/
  - formulas/sverka-{wave,bootstrap}.toml — moved to pack/formulas/ (renamed)

Verified: gc doctor clean, gc status shows harness.{mayor,architect,builder,
reviewer} agents loaded, formulas staged in .beads/formulas/.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Three additions to the decoupled harness:

1. Agent skills (pack/skills/) — shared by all harness agents:
   - sverka-wave: wave planning and execution cycle
   - sverka-review: two-axis review and gate commands
   - sverka-drill: failure investigation and root cause isolation

2. CLI skill (skills/sverka/) — publishable via npx skills:
   - /sverka <command>: init, inspect, plan, execute, validate, baseline, doctor
   - Install: npx skills add sverka-dev/sverka --skill sverka
   - Includes references/troubleshooting.md

3. Agent documentation (pack/docs/agent-guide.md):
   - Describes skills, formulas, roles, and project docs for harness agents

Verified: gc doctor (skill-collision ✓), gc sling harness.mayor sv-8g8 (slung
OK), all three formulas available via --formula --dry-run (wave, address-review,
bootstrap-sdd).

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Per-agent docs (pack/docs/agents/):
- mayor.md: always-on orchestrator role, skills, formulas, commands
- architect.md: on-demand designer, spec structure, design principles
- builder.md: on-demand implementer, TDD workflow, commit hygiene
- reviewer.md: on-demand gatekeeper, two-axis review, finding classification

E2E test (specs/16-test-harness/spec.md):
- Dispatched gc sling harness.mayor wave --formula
- Workflow sv-8t1i created with 4 step beads (design/implement/review/finalize)
- Dependencies correct, gc.formula_source=pack/formulas/wave.toml
- gc.var.binding_name=harness, gc.routed_to=harness.mayor
- Confirms decoupled pack works end-to-end

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Codacy's eslint-plugin-es-x rules forbid ES2015+ syntax (arrow functions,
const, import, etc.) which is inappropriate for a Node 24 / Bun / TypeScript
project. This config:

- Excludes non-source paths (tests, configs, docs, markdown, pack, etc.)
- Disables all es-x/no-* rules (ES2015+ syntax restrictions)
- Disables noisy markdownlint rules (bare URLs, heading duplication)
- Disables markdown language analysis entirely
- Keeps security and real code quality rules enabled

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Add optional `tags: readonly string[]` to PlanOperation (IR) for
prioritization, filtering, and categorization. Pass tags through from
OperationSpec in convertToPlan (SDK). Prioritize critical-tagged ops
among ready siblings in topoSort (runtime).

Changes:
- ir/plan.ts: add `tags?: readonly string[]` to PlanOperation
- sdk/convert.ts: pass `spec.tags` to PlanOperation in convertOperation
- runtime/internal/topo.ts: sortReadyByPriority() — critical ops first
  among ready siblings, then input order (stable)

Tests (TDD):
- ir: 3 tests — accepts tags, accepts no tags, accepts empty tags
- sdk: 2 tests — passes tags from spec, omits when absent
- runtime: 2 tests — critical first among independents, critical first
  among siblings after dependency completes

Closes sv-bni (P3 backlog from Wave 3 / ADR-007).

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Records the architectural decision to add `tags` to PlanOperation and
prioritize critical-tagged ops in topoSort. Resolves the deferred
critical-check prioritization from ADR-007.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Project-local skill at .agents/skills/gc-watchdog/ that monitors Gas City
health and exits when there is no more open or in-progress work.

- SKILL.md: documents check cycle, exit conditions, reporting format
- watchdog.sh: standalone script — checks gc status + bd list, filters
  out ephemeral wisp/nudge beads, exits 0 when idle

Exit condition: no open real tasks AND no in-progress real tasks AND
mayor healthy. Does NOT exit on failure (only on success).

Usage: bash .agents/skills/gc-watchdog/watchdog.sh [interval_seconds]

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@ThePlenkov
ThePlenkov force-pushed the feat-tags-and-watchdog branch from 50a1c97 to 238bef0 Compare August 11, 2026 06:32
@codeant-ai

codeant-ai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Skipping CodeAnt AI review — this PR changes more than 100 files, which usually means a migration, codemod, or vendored drop. Line-level review on diffs this large produces duplicate findings on the same rewrite pattern and drowns out anything that actually matters.

If you still want a review, comment @codeant-ai : review. For better signal, consider splitting the PR into smaller chunks.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
B Security Rating on New Code (required ≥ A)
D Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@ThePlenkov

Copy link
Copy Markdown
Contributor Author

Closing this PR because it is now superseded by the main wave stack (#7–#25). The unique features in this branch can be reopened as focused PRs against the updated main once the main wave lands.

@ThePlenkov ThePlenkov closed this Aug 11, 2026
ThePlenkov added a commit that referenced this pull request Aug 11, 2026
@ThePlenkov
ThePlenkov deleted the feat-tags-and-watchdog branch September 23, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

baz: needs review size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant