Skip to content

Instruction hardening engine: combine regex + semantic instruction review for /harden - #281

Open
RamananVr wants to merge 10 commits into
mainfrom
users/rarame/instruction-hardening-engine
Open

RamananVr wants to merge 10 commits into
mainfrom
users/rarame/instruction-hardening-engine

Conversation

@RamananVr

Copy link
Copy Markdown

Summary

  • Builds on the /harden skill scaffolding from feat(ess-maker-skills): add /harden instruction review skill #247, adding a unified instruction_engine package under solutions/ess-maker-skills/scripts/ that combines two prior efforts:
  • Adds engine.py orchestration (run()) and a python -m instruction_engine CLI (text/JSON output, --fail-on, --problems for coverage-check triage)
  • Wires /harden (SKILL.md) to call coverage-check before proposing a fix for a reported problem, distinguishing a real instruction gap (fix_proposed) from a platform limitation the skill can't reach by editing instructions (likely_platform_limitation)
  • Restores the ADK_CAPABILITIES entry, menu row, and README section for /harden that feat(ess-maker-skills): add /harden instruction review skill #247 introduced

Test plan

  • pytest tests/scripts/test_instruction_engine_engine.py tests/scripts/test_instruction_engine_cli.py -q — new engine/CLI tests pass
  • pytest tests/scripts/test_instruction_budget.py tests/test_adk_telemetry.py tests/scripts/test_agent_capabilities.py -q — wiring tests pass
  • Full-repo pytest -q — 869 passed, 14 skipped; remaining 14 failures / 37 collection errors confirmed pre-existing on main (missing defusedxml/jsonschema deps, stale onboarding/tasks.md path references — unrelated to this change)

🤖 Generated with Claude Code

RamananVr and others added 9 commits September 11, 2026 16:58
Cherry-picked only the /harden-specific files from PR #247 (harden.prompt.md,
SKILL.md, instruction-rules.md, check_instruction_budget.py,
list_agent_capabilities.py, and their tests) rather than merging the whole
branch, since pr-247 has diverged from main with unrelated evaluation-skill
changes. Capability/menu/telemetry wiring deferred to a later step.
Ported models.py, normalize.py, parser.py, and regex_rules/{coverage,antipattern}.py
from the standalone ESSAgentInstructionValidator repo into
solutions/ess-maker-skills/scripts/instruction_engine/, along with its existing
test suite adjusted to the new import path. This becomes the deterministic
regex pass that the shared engine (Step 5) will run alongside the semantic
LLM pass ported from PR #247.
Finding now carries source: "regex" | "semantic", defaulting to "regex" so
existing regex rule functions need no changes. Schema test confirms a
regex-origin and a semantic-origin Finding serialize to the same shape,
which the engine (Step 5) relies on to merge both passes' output into one
findings list.
Moves instruction-rules.md under instruction_engine/semantic_rules/ and adds
runner.py, which makes the INSTR-0xx rule pack invocable outside an
interactive skill session. Reuses evaluate_evals.py's existing LLM call
convention (GitHub Copilot chat completions API via 'gh auth token' — no new
API keys or setup), resolving the design doc's open item on LLM invocation
mechanism.

run_semantic_pass() takes a pluggable llm_client so tests stub the model
call and only verify parsing/schema-conformance. A @pytest.mark.live smoke
test exercises a real call and is skipped by default, per the repo's
existing --run-live convention.
check_coverage(instructions, reported_problem) runs the semantic pass scoped
to the reported behavior. If the pass surfaces no on-topic
contradiction/gap, an existing rule must already correctly address it and
the verdict is likely_platform_limitation instead of another rewrite
proposal. This is deliberately semantic-pass-only — an earlier version also
fell back to the unscoped regex pass, which produced false-positive
fix_proposed verdicts from keyword overlap with unrelated housekeeping
rules (AP006, COV004) on both Blackstone fixtures.

blackstone_scenario_{1,2}.json capture the real customer data (unsuppressed
'More references' panel despite citation scoping; unsuppressed follow-up
suggestion after a read-only Workday topic despite three prior instruction
attempts) as permanent regression fixtures — both expected to yield
likely_platform_limitation.
run(instructions_text, problems=None) -> EngineResult always runs the
regex pass and an unscoped semantic pass, and additionally runs
check_coverage for each ReportedProblem in problems, in order.
python -m instruction_engine --instructions FILE [--problems FILE]
[--json] [--fail-on error|warn|review] renders the engine.run() result
as text or JSON, and exits non-zero when a finding at or above --fail-on
severity is present. --problems loads a JSON list of reported-problem
records into ReportedProblem for coverage-check triage.
Step 3 now runs `python -m instruction_engine --problems ... --json`
against a maker-reported problem before proposing changes. On
likely_platform_limitation, the skill is told to say so plainly and
route to /flightcheck/escalation instead of proposing another reworded
prohibition — this is the whole point of coverage-check mode (real
Blackstone data showed re-wording an already-correct rule doesn't help).

Also updates the instruction-rules.md path reference from its old
location (src/reference/ess-docs/hardening/, moved in Step 3) to
scripts/instruction_engine/semantic_rules/, and updates the wiring test
accordingly.
Ports the capability taxonomy entry, menu row, and README section from
PR #247 that were deliberately deferred when the harden skill scaffolding
was cherry-picked in Step 0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@RamananVr

Copy link
Copy Markdown
Author

RamananVr please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree company="Microsoft"

@RamananVr RamananVr closed this Sep 14, 2026
@RamananVr

Copy link
Copy Markdown
Author

RamananVr please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree company="Microsoft"

@RamananVr RamananVr reopened this Sep 14, 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.

1 participant