Repository navigation
feat(cli): rules test renders prompts and templates and checks results - #251
Merged
gusfcarvalho merged 2 commits intoOct 29, 2026
Merged
Conversation
factory rules test now renders, per case, the prompt of every dispatch and the GitHub body of every notify with the dispatcher's own code (controllers.RenderEvaluation: compileTask with KeepSkills, templateData and renderBody), keeps them as goldens under <case>/rendered/, and validates a factory.run.completed run result against its TaskSpec's output schema (controllers.CheckRunResult, sharing validateResult's schema check). --coverage warns about prompts and Templates no case renders. The reference catalog's and the PoC cases' goldens are written; four fixture results that their schemas refuse are completed, and the PoC stub prompts list input keys instead of printing map values raw. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e LLD (self-review pass 1) Also a table test for CheckRunResult against resultMap's view and a fixture's data-only one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 free
to 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.
Task: IMPROVEMENTS item 8, stack A PR A2 of 3: fx/cat-a2-rules-test-render on fx/cat-a1-private-catalog.
Summary
An external catalog only gets the
factorybinary in its CI. Until nowfactory rules testchecked decisions but never ran a catalog's prompts or Templates, and never checked a Result againstoutput.schema. So a typo like{{ .run.reslt }}showed up first as a failed run in prod. Each case now also:dispatchdecision renders its TaskSpec's prompt through the dispatcher's own path:compileTaskwithKeepSkills, the task id from the decision keyevt/<event>/<rule>/<i>, and the event time as now.notifydecision renders its Template's GitHub body withtemplateDataandrenderBody. On afactory.run.completedevent, the run comes with itsresult.setwrote.<case>/rendered/<decision>-<prompt|template>-<name>.md. The normal run diffs them,--updatewrites them and removes stale ones, and a missing golden fails like a missingexpected.json.<no value>,<nil>,%!ormap[: that iscatalog_test.go'scheckRendered, and it is how text/template renders a field typo. These failures fail with--updatetoo.factory.run.completedrun result is validated against its TaskSpec'soutput.schemawithts.OutputSchema.Validate, through the same stepvalidateResultuses. The Result is rebuilt from the rules' flattenedrun.result, as the inverse ofresultMap.--coveragealso warns, without failing, about TaskSpecs (with a prompt) and Templates that no case renders.printRulesTestand--format jsonreport the rendered mismatches and failures per case, with a newfailedstatus and count.The rendering code lives in
internal/controllersas one small exported helper,render.go:RenderEvaluationandCheckRunResult. The spec allows this; the render data lives there, and controllers is the RT workstream's directory. Nothing is copied:apply's set/link step is extracted asapplyToItemandapplies;validateResult's schema step is extracted ascheckOutputSchema.catalog_test.gois unchanged.make catalognow runs the new checks over the reference catalog. It found three reference fixtures whose run results their own schemas refuse; see "For triage".Before/after: a broken placeholder
I changed
{{ .task.target.repo }}to{{ .task.target.rpo }}on line 6 ofcatalog/prompts/plan-epic.md.tmpllocally, then reverted it.Before (the A1 binary):
After (this branch):
Goldens and fixtures
go run ./cmd/factory rules test --catalog catalog --updatewrote 41 rendered goldens. Noexpected.jsonchanged.cmd/factory's tests replay (internal/rules/testdata/cases/pocagainstinternal/catalog/testdata/poc) got rendered goldens too. Two changes were needed in that test data, which the dispatcher-core workstream owns:- {{ $k }}: {{ $v }}), so map inputs rendered asmap[...]. They now list the input keys.build-stack-start's plan items lacked thetitleits schema requires. I added titles, and itsexpected.jsongains them inset planand in the state.internal/rules'sTestFixtureNamesallows the newrendered/directory.rules.FixtureRenderednames it next to the other fixture file names.cmd/factory/testdata/rules/renderis a small test catalog with two cases, one prompt and one Template, plus an unused TaskSpec and Template for the coverage warning.Size: 878 changed lines without goldens (the
rendered/files,expected.jsonand.golden).Verification
make reviewable: passes (generated-code check, lint,go test -race,make catalogwithcatalog/testdata: 66 cases, 66 ok, 0 differ, openapi-lint).gofmt -lover the repo's Go files: prints nothing.cmd/factory/rules_test.go:TestRulesTestRender: a prompt that renders; a prompt with a bad field (fails, namesTaskSpec plan); a Template that fails to execute; a changed prompt (golden diff with the first differing line); a result that fails its schema; a missing golden; a stale golden; failures under--update; the JSON report.TestRulesTestRenderUpdate:--updatewrites the goldens and removes a stale one, and a second run passes.TestRulesTestRenderCoverage: the coverage warnings.internal/controllers/render_test.go:TestCheckRunResult, againstresultMap's view and fixture-style data-only views.TestRulesTestCoverageand thechanged-rulegolden gain the new lines.TestRulesTestBaseCatalogcompares only the decision lines.Only a real external catalog can check one thing:
compliance-framework/factory-catalog's CI, which runsfactory rules test --catalog catalog --coveragewith this binary. Its fixtures will need--updateonce to write theirrendered/goldens, and any of its run results that its schemas refuse will fail.For triage
make catalogmust pass (they are undercatalog/, which the CAT workstream owns):catalog/testdata/closed-item-suppressed/event.json: animplementpr-openedresult withoutpr. Addedcompliance-framework/docs#81, the item's linked PR.catalog/testdata/dev-epic-review-changes-requested/event.jsonandcatalog/testdata/loop-cap-release-review-escalate/event.json:docs-review(-verify)done results withresult: {}, whileschemas/results/review.jsonrequiresdata.findingsanddata.prs. Added arequest-changesentry for the item's PR.catalog-poc.md:26(CAT's LLD) lists case files as{event.json,workitem.json,expected.json}. Cases now also holdrendered/. Proposed fix: addrendered/there, as this PR does inrules-engine.md.--base-catalogrenders nothing. It compares decisions only, as it already skips the goldens. A catalog PR's render failures still show in the normal run, whichmake catalogdoes.Open questions for reviewers
🤖 Generated with Claude Code