Skip to content

feat: add execution-readiness-guard skill#242

Closed
luizinhotec wants to merge 3 commits intoaibtcdev:mainfrom
luizinhotec:main
Closed

feat: add execution-readiness-guard skill#242
luizinhotec wants to merge 3 commits intoaibtcdev:mainfrom
luizinhotec:main

Conversation

@luizinhotec
Copy link
Copy Markdown

feat: add execution-readiness-guard skill

Summary

This PR introduces the execution-readiness-guard skill.

This skill evaluates whether a route is eligible for execution based on:

  • Route operator decision
  • Route health
  • Protocol health
  • Route performance (score)

Behavior

The skill returns:

  • healthy → execution allowed
  • degraded → execution blocked (risk)
  • blocked → execution strictly denied

Why this matters

This acts as a final execution gate, ensuring that:

  • Unsafe routes are never executed
  • Degraded performance is respected
  • Protocol-level risks are enforced

Files included

  • execution-readiness-guard.ts
  • SKILL.md
  • AGENT.md

Notes

This skill is designed to be composable within a multi-skill decision pipeline.

This implementation provides a function to evaluate the readiness of a route based on various conditions, including blocked and degraded statuses. It also includes a CLI for input processing and output display.
Added documentation for the Execution Readiness Guard skill, detailing its purpose, functionality, and input structure.
Copy link
Copy Markdown
Contributor

@tfireubs-ui tfireubs-ui left a comment

Choose a reason for hiding this comment

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

Clean decision-skill pattern — evaluates route readiness in strict priority order (operator → route health → protocol health → score) and returns a discriminated result. Logic is easy to trace and the three-way output (healthy/degraded/blocked) is the right abstraction.

One note: the try/catch in main() wraps only the process.stdin.on() registration calls, not the actual JSON parsing inside the 'end' handler. If JSON.parse(input) throws, it won't be caught — it'll surface as an uncaught exception instead of the {ok:false, error:'INVALID_INPUT'} response. Moving the try/catch inside the 'end' callback would fix it. Non-blocking for merge but worth a quick follow-up.

APPROVED.

Copy link
Copy Markdown
Contributor

@arc0btc arc0btc left a comment

Choose a reason for hiding this comment

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

Adds an execution-readiness-guard decision skill — a final gating step before route execution that evaluates operator decision, route health, protocol health, and score in strict priority order and returns a discriminated healthy/degraded/blocked result. Solid architecture.

What works well:

  • The decision priority chain is clear and correct: operator BLOCK → route health blocked → protocol health blocked → score degraded → healthy. Hard to misread.
  • Discriminated readiness + eligible output is the right abstraction — callers don't need to re-interpret the result.
  • Three-file structure (.ts + SKILL.md + AGENT.md) follows the skill pattern correctly.

[suggestion] try/catch doesn't cover the async callback (execution-readiness-guard.ts:78-91)

tfireubs-ui already flagged this — reinforcing it because it's the main correctness gap. The try/catch wraps the synchronous .on() registrations, but the 'end' callback runs asynchronously — errors thrown inside it (e.g. JSON.parse on malformed or empty input) escape to an uncaught exception instead of the intended {ok:false, error:'INVALID_INPUT'} response.

  process.stdin.on('end', () => {
    try {
      const parsed = JSON.parse(input);
      const result = evaluateReadiness(parsed);
      console.log(JSON.stringify(result));
    } catch (err) {
      console.error(JSON.stringify({ ok: false, error: 'INVALID_INPUT' }));
    }
  });

[suggestion] state: any loses type safety (execution-readiness-guard.ts:8)

The state field is typed as any, which gives up all compile-time guards on the shape that evaluateReadiness actually depends on. Worth defining an interface — even a loose one makes the expected contract explicit and catches integration mistakes early:

type State = {
  routeOperatorByRoute?: Record<string, { decision?: string; protocol?: string } | null>;
  routeHealthByRoute?: Record<string, { status?: string; reason?: string } | null>;
  protocolHealthByProtocol?: Record<string, { status?: string; reason?: string } | null>;
  routeScoreByRoute?: Record<string, { status?: string; reason?: string } | null>;
};

type Input = {
  route: string;
  state: State;
};

[suggestion] Output schema missing from docs

SKILL.md and AGENT.md both show the input schema but cut off before documenting the output shape (ok, route, readiness, eligible, reason). Callers integrating this skill blind will have to read the source to know what to expect — worth adding an output example to both docs.

[nit] async on main() is unused (execution-readiness-guard.ts:74)

No await inside main() — the async keyword is a no-op here and slightly misleads readers about the execution model. function main(): void is accurate.

[nit] 'use strict' is a JS-ism (execution-readiness-guard.ts:1)

TypeScript already enforces strict mode through tsconfig. This directive doesn't hurt, but it's idiomatic to omit it in .ts files.

Code quality notes:

  • || null on state lookups is redundant — optional chaining already yields undefined on a miss, which is falsy. || null normalizes to null but both are falsy, so the downstream checks behave identically. Minor readability noise.
  • routeOperator?.decision inside the block guarded by if (!routeOperator || ...) — after the null check, routeOperator is known non-null; routeOperator.decision is sufficient (no optional chain needed).

Operational note:
We route execution decisions through similar guard patterns in our x402 relay health checks (isRelayHealthy() in our sensors). The three-state output (healthy/degraded/blocked) matches how we interpret circuit breaker state — same mental model, good consistency.

Core logic is sound. The async try/catch fix is the one I'd want to see before this ships in a high-throughput path.

@whoabuddy
Copy link
Copy Markdown
Contributor

Thanks for the contribution! Reviewing the skills backlog and this PR looks like it landed outside the BFF Skills Competition pipeline, which is how community skills have been flowing through the repo.

We're working to get all BFF winners merged in order. Closing this to keep the queue focused for the upcoming sprint — if this was in fact a comp submission and routing was missed, reply here and we'll reopen and sort it out.

Appreciate the work either way.

@whoabuddy whoabuddy closed this Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants